Merge "Support showing alignment hint based on aligniment state of dock"
diff --git a/Android.bp b/Android.bp
index 5070b5e..e7a3efc 100644
--- a/Android.bp
+++ b/Android.bp
@@ -916,28 +916,6 @@
     ],
 }
 
-// TODO: Don't rely on this list by switching package.html into package-info.java
-frameworks_base_subdirs = [
-    "core/java",
-    "graphics/java",
-    "location/java",
-    "media/java",
-    "media/mca/effect/java",
-    "media/mca/filterfw/java",
-    "media/mca/filterpacks/java",
-    "drm/java",
-    "mms/java",
-    "opengl/java",
-    "sax/java",
-    "telecomm/java",
-    "telephony/common",
-    "telephony/java",
-    "wifi/java",
-    "lowpan/java",
-    "keystore/java",
-    "rs/java",
-]
-
 // Make the api/current.txt file available for use by modules in other
 // directories.
 filegroup {
@@ -1042,7 +1020,6 @@
         "test-runner/src/**/*.java",
     ],
     libs: framework_docs_only_libs,
-    local_sourcepaths: frameworks_base_subdirs,
     create_doc_stubs: true,
     annotations_enabled: true,
     api_levels_annotations_enabled: true,
@@ -1103,7 +1080,6 @@
         ":updatable-media-srcs",
     ],
     libs: ["framework-internal-utils"],
-    local_sourcepaths: frameworks_base_subdirs,
     installable: false,
     annotations_enabled: true,
     previous_api: ":last-released-public-api-for-metalava-annotations",
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index e74e4a9..278a786 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -516,7 +516,7 @@
     /** Creates a managed (work) profile under the current user, returning its userId. */
     private int createManagedProfile() {
         final UserInfo userInfo = mUm.createProfileForUser("TestProfile",
-                UserInfo.FLAG_MANAGED_PROFILE, mAm.getCurrentUser());
+                UserManager.USER_TYPE_PROFILE_MANAGED, /* flags */ 0, mAm.getCurrentUser());
         if (userInfo == null) {
             throw new IllegalStateException("Creating managed profile failed. Most likely there is "
                     + "already a pre-existing profile on the device.");
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobStoreManagerFrameworkInitializer.java b/apex/blobstore/framework/java/android/app/blob/BlobStoreManagerFrameworkInitializer.java
index 6e6d6ae..56c419a 100644
--- a/apex/blobstore/framework/java/android/app/blob/BlobStoreManagerFrameworkInitializer.java
+++ b/apex/blobstore/framework/java/android/app/blob/BlobStoreManagerFrameworkInitializer.java
@@ -26,7 +26,7 @@
 public class BlobStoreManagerFrameworkInitializer {
     /** Register the BlobStoreManager wrapper class */
     public static void initialize() {
-        SystemServiceRegistry.registerCachedService(
+        SystemServiceRegistry.registerContextAwareService(
                 Context.BLOB_STORE_SERVICE, BlobStoreManager.class,
                 (context, service) ->
                         new BlobStoreManager(context, IBlobStoreManager.Stub.asInterface(service)));
diff --git a/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java b/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java
deleted file mode 100644
index c264531..0000000
--- a/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java
+++ /dev/null
@@ -1,35 +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.app;
-
-import android.content.Context;
-import android.os.DeviceIdleManager;
-import android.os.IDeviceIdleController;
-
-/**
- * @hide
- */
-public class DeviceIdleFrameworkInitializer {
-    private static IDeviceIdleController sIDeviceIdleController;
-
-    public static void initialize() {
-        SystemServiceRegistry.registerCachedService(
-                Context.DEVICE_IDLE_CONTROLLER, DeviceIdleManager.class,
-                (context, b) -> new DeviceIdleManager(
-                        context, IDeviceIdleController.Stub.asInterface(b)));
-    }
-}
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java b/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
index 175e5f2..f3ec5e5 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
@@ -19,14 +19,34 @@
 import android.app.JobSchedulerImpl;
 import android.app.SystemServiceRegistry;
 import android.content.Context;
+import android.os.DeviceIdleManager;
+import android.os.IDeviceIdleController;
 
 /**
+ * Class holding initialization code for the job scheduler module.
+ *
  * @hide
  */
 public class JobSchedulerFrameworkInitializer {
-    public static void initialize() {
+    private JobSchedulerFrameworkInitializer() {
+    }
+
+    /**
+     * Called by {@link SystemServiceRegistry}'s static initializer and registers
+     * {@link JobScheduler} and other services to {@link Context}, so
+     * {@link Context#getSystemService} can return them.
+     *
+     * <p>If this is called from other places, it throws a {@link IllegalStateException).
+     *
+     * TODO Make it a system API
+     */
+    public static void registerServiceWrappers() {
         SystemServiceRegistry.registerStaticService(
                 Context.JOB_SCHEDULER_SERVICE, JobScheduler.class,
                 (b) -> new JobSchedulerImpl(IJobScheduler.Stub.asInterface(b)));
+        SystemServiceRegistry.registerContextAwareService(
+                Context.DEVICE_IDLE_CONTROLLER, DeviceIdleManager.class,
+                (context, b) -> new DeviceIdleManager(
+                        context, IDeviceIdleController.Stub.asInterface(b)));
     }
 }
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 4ee46f4..dfe7a90 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -1390,8 +1390,10 @@
     private static final int MSG_FINISH_IDLE_OP = 8;
     private static final int MSG_REPORT_TEMP_APP_WHITELIST_CHANGED = 9;
     private static final int MSG_SEND_CONSTRAINT_MONITORING = 10;
-    private static final int MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR = 11;
-    private static final int MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR = 12;
+    @VisibleForTesting
+    static final int MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR = 11;
+    @VisibleForTesting
+    static final int MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR = 12;
 
     final class MyHandler extends Handler {
         MyHandler(Looper looper) {
@@ -3327,8 +3329,7 @@
         mHandler.sendEmptyMessage(MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR);
     }
 
-    @VisibleForTesting
-    void updatePreIdleFactor() {
+    private void updatePreIdleFactor() {
         synchronized (this) {
             if (!shouldUseIdleTimeoutFactorLocked()) {
                 return;
@@ -3350,8 +3351,7 @@
         }
     }
 
-    @VisibleForTesting
-    void maybeDoImmediateMaintenance() {
+    private void maybeDoImmediateMaintenance() {
         synchronized (this) {
             if (mState == STATE_IDLE) {
                 long duration = SystemClock.elapsedRealtime() - mIdleStartTime;
@@ -3377,6 +3377,7 @@
     void setIdleStartTimeForTest(long idleStartTime) {
         synchronized (this) {
             mIdleStartTime = idleStartTime;
+            maybeDoImmediateMaintenance();
         }
     }
 
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
index a0615aa..8a00c83 100644
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
+++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
@@ -1179,7 +1179,7 @@
         long token = Binder.clearCallingIdentity();
         synchronized (this) {
             if (mTelephony == null) {
-                mTelephony = TelephonyManager.from(mContext);
+                mTelephony = mContext.getSystemService(TelephonyManager.class);
             }
         }
         if (mTelephony != null) {
diff --git a/api/current.txt b/api/current.txt
index 5d2a1bd..3361147 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2035,7 +2035,7 @@
     field public static final int fingerprint_icon_content_description = 17039384; // 0x1040018
     field public static final int httpErrorBadUrl = 17039367; // 0x1040007
     field public static final int httpErrorUnsupportedScheme = 17039368; // 0x1040008
-    field public static final int no = 17039369; // 0x1040009
+    field @Deprecated public static final int no = 17039369; // 0x1040009
     field public static final int ok = 17039370; // 0x104000a
     field public static final int paste = 17039371; // 0x104000b
     field public static final int paste_as_plain_text = 17039385; // 0x1040019
@@ -2045,7 +2045,7 @@
     field public static final int status_bar_notification_info_overflow = 17039383; // 0x1040017
     field public static final int unknownName = 17039374; // 0x104000e
     field public static final int untitled = 17039375; // 0x104000f
-    field public static final int yes = 17039379; // 0x1040013
+    field @Deprecated public static final int yes = 17039379; // 0x1040013
   }
 
   public static final class R.style {
@@ -4271,8 +4271,8 @@
     method public android.app.AlertDialog show();
   }
 
-  public class AliasActivity extends android.app.Activity {
-    ctor public AliasActivity();
+  @Deprecated public class AliasActivity extends android.app.Activity {
+    ctor @Deprecated public AliasActivity();
   }
 
   public class AppComponentFactory {
@@ -8445,6 +8445,7 @@
     method public int describeContents();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean fetchUuidsWithSdp();
     method public String getAddress();
+    method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public String getAlias();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothClass getBluetoothClass();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getBondState();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public String getName();
@@ -8456,6 +8457,7 @@
     field public static final String ACTION_ACL_CONNECTED = "android.bluetooth.device.action.ACL_CONNECTED";
     field public static final String ACTION_ACL_DISCONNECTED = "android.bluetooth.device.action.ACL_DISCONNECTED";
     field public static final String ACTION_ACL_DISCONNECT_REQUESTED = "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED";
+    field public static final String ACTION_ALIAS_CHANGED = "android.bluetooth.action.ALIAS_CHANGED";
     field public static final String ACTION_BOND_STATE_CHANGED = "android.bluetooth.device.action.BOND_STATE_CHANGED";
     field public static final String ACTION_CLASS_CHANGED = "android.bluetooth.device.action.CLASS_CHANGED";
     field public static final String ACTION_FOUND = "android.bluetooth.device.action.FOUND";
@@ -9475,6 +9477,7 @@
     method @Nullable public android.net.Uri canonicalize(@NonNull android.net.Uri);
     method @NonNull public final android.content.ContentProvider.CallingIdentity clearCallingIdentity();
     method public abstract int delete(@NonNull android.net.Uri, @Nullable String, @Nullable String[]);
+    method public int delete(@NonNull android.net.Uri, @Nullable android.os.Bundle);
     method public void dump(java.io.FileDescriptor, java.io.PrintWriter, String[]);
     method @Nullable public final String getCallingFeatureId();
     method @Nullable public final String getCallingPackage();
@@ -9485,6 +9488,7 @@
     method @Nullable public abstract String getType(@NonNull android.net.Uri);
     method @Nullable public final String getWritePermission();
     method @Nullable public abstract android.net.Uri insert(@NonNull android.net.Uri, @Nullable android.content.ContentValues);
+    method @Nullable public android.net.Uri insert(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable android.os.Bundle);
     method protected boolean isTemporary();
     method public void onConfigurationChanged(android.content.res.Configuration);
     method public abstract boolean onCreate();
@@ -9510,6 +9514,7 @@
     method public void shutdown();
     method @Nullable public android.net.Uri uncanonicalize(@NonNull android.net.Uri);
     method public abstract int update(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable String, @Nullable String[]);
+    method public int update(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable android.os.Bundle);
   }
 
   public final class ContentProvider.CallingIdentity {
@@ -9528,10 +9533,12 @@
     method @Nullable public final android.net.Uri canonicalize(@NonNull android.net.Uri) throws android.os.RemoteException;
     method public void close();
     method public int delete(@NonNull android.net.Uri, @Nullable String, @Nullable String[]) throws android.os.RemoteException;
+    method public int delete(@NonNull android.net.Uri, @Nullable android.os.Bundle) throws android.os.RemoteException;
     method @Nullable public android.content.ContentProvider getLocalContentProvider();
     method @Nullable public String[] getStreamTypes(@NonNull android.net.Uri, @NonNull String) throws android.os.RemoteException;
     method @Nullable public String getType(@NonNull android.net.Uri) throws android.os.RemoteException;
     method @Nullable public android.net.Uri insert(@NonNull android.net.Uri, @Nullable android.content.ContentValues) throws android.os.RemoteException;
+    method @Nullable public android.net.Uri insert(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable android.os.Bundle) throws android.os.RemoteException;
     method @Nullable public android.content.res.AssetFileDescriptor openAssetFile(@NonNull android.net.Uri, @NonNull String) throws java.io.FileNotFoundException, android.os.RemoteException;
     method @Nullable public android.content.res.AssetFileDescriptor openAssetFile(@NonNull android.net.Uri, @NonNull String, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException, android.os.RemoteException;
     method @Nullable public android.os.ParcelFileDescriptor openFile(@NonNull android.net.Uri, @NonNull String) throws java.io.FileNotFoundException, android.os.RemoteException;
@@ -9546,6 +9553,7 @@
     method @Deprecated public boolean release();
     method @Nullable public final android.net.Uri uncanonicalize(@NonNull android.net.Uri) throws android.os.RemoteException;
     method public int update(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable String, @Nullable String[]) throws android.os.RemoteException;
+    method public int update(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable android.os.Bundle) throws android.os.RemoteException;
   }
 
   public class ContentProviderOperation implements android.os.Parcelable {
@@ -9633,6 +9641,7 @@
     method public static void cancelSync(android.content.SyncRequest);
     method @Nullable public final android.net.Uri canonicalize(@NonNull android.net.Uri);
     method public final int delete(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable String, @Nullable String[]);
+    method public final int delete(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable android.os.Bundle);
     method @Deprecated public static android.content.SyncInfo getCurrentSync();
     method public static java.util.List<android.content.SyncInfo> getCurrentSyncs();
     method public static int getIsSyncable(android.accounts.Account, String);
@@ -9646,6 +9655,7 @@
     method @Nullable public final String getType(@NonNull android.net.Uri);
     method @NonNull public final android.content.ContentResolver.MimeTypeInfo getTypeInfo(@NonNull String);
     method @Nullable public final android.net.Uri insert(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable android.content.ContentValues);
+    method @Nullable public final android.net.Uri insert(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable android.content.ContentValues, @Nullable android.os.Bundle);
     method public static boolean isSyncActive(android.accounts.Account, String);
     method public static boolean isSyncPending(android.accounts.Account, String);
     method @NonNull public android.graphics.Bitmap loadThumbnail(@NonNull android.net.Uri, @NonNull android.util.Size, @Nullable android.os.CancellationSignal) throws java.io.IOException;
@@ -9683,6 +9693,7 @@
     method @Nullable public final android.net.Uri uncanonicalize(@NonNull android.net.Uri);
     method public final void unregisterContentObserver(@NonNull android.database.ContentObserver);
     method public final int update(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable android.content.ContentValues, @Nullable String, @Nullable String[]);
+    method public final int update(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable android.content.ContentValues, @Nullable android.os.Bundle);
     method public static void validateSyncExtrasBundle(android.os.Bundle);
     method @NonNull public static android.content.ContentResolver wrap(@NonNull android.content.ContentProvider);
     method @NonNull public static android.content.ContentResolver wrap(@NonNull android.content.ContentProviderClient);
@@ -9695,12 +9706,16 @@
     field public static final String EXTRA_TOTAL_COUNT = "android.content.extra.TOTAL_COUNT";
     field public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 2; // 0x2
     field public static final int NOTIFY_SYNC_TO_NETWORK = 1; // 0x1
+    field public static final String QUERY_ARG_GROUP_COLUMNS = "android:query-arg-group-columns";
     field public static final String QUERY_ARG_LIMIT = "android:query-arg-limit";
     field public static final String QUERY_ARG_OFFSET = "android:query-arg-offset";
     field public static final String QUERY_ARG_SORT_COLLATION = "android:query-arg-sort-collation";
     field public static final String QUERY_ARG_SORT_COLUMNS = "android:query-arg-sort-columns";
     field public static final String QUERY_ARG_SORT_DIRECTION = "android:query-arg-sort-direction";
     field public static final String QUERY_ARG_SORT_LOCALE = "android:query-arg-sort-locale";
+    field public static final String QUERY_ARG_SQL_GROUP_BY = "android:query-arg-sql-group-by";
+    field public static final String QUERY_ARG_SQL_HAVING = "android:query-arg-sql-having";
+    field public static final String QUERY_ARG_SQL_LIMIT = "android:query-arg-sql-limit";
     field public static final String QUERY_ARG_SQL_SELECTION = "android:query-arg-sql-selection";
     field public static final String QUERY_ARG_SQL_SELECTION_ARGS = "android:query-arg-sql-selection-args";
     field public static final String QUERY_ARG_SQL_SORT_ORDER = "android:query-arg-sql-sort-order";
@@ -15713,6 +15728,8 @@
 
   public final class Icon implements android.os.Parcelable {
     method public static android.graphics.drawable.Icon createWithAdaptiveBitmap(android.graphics.Bitmap);
+    method @NonNull public static android.graphics.drawable.Icon createWithAdaptiveBitmapContentUri(@NonNull String);
+    method @NonNull public static android.graphics.drawable.Icon createWithAdaptiveBitmapContentUri(@NonNull android.net.Uri);
     method public static android.graphics.drawable.Icon createWithBitmap(android.graphics.Bitmap);
     method public static android.graphics.drawable.Icon createWithContentUri(String);
     method public static android.graphics.drawable.Icon createWithContentUri(android.net.Uri);
@@ -15739,6 +15756,7 @@
     field public static final int TYPE_DATA = 3; // 0x3
     field public static final int TYPE_RESOURCE = 2; // 0x2
     field public static final int TYPE_URI = 4; // 0x4
+    field public static final int TYPE_URI_ADAPTIVE_BITMAP = 6; // 0x6
   }
 
   public static interface Icon.OnDrawableLoadedListener {
@@ -23039,17 +23057,17 @@
   }
 
   public final class GnssStatus {
-    method public float getAzimuthDegrees(int);
-    method public float getCarrierFrequencyHz(int);
-    method public float getCn0DbHz(int);
-    method public int getConstellationType(int);
-    method public float getElevationDegrees(int);
-    method public int getSatelliteCount();
-    method public int getSvid(int);
-    method public boolean hasAlmanacData(int);
-    method public boolean hasCarrierFrequencyHz(int);
-    method public boolean hasEphemerisData(int);
-    method public boolean usedInFix(int);
+    method @FloatRange(from=0, to=360) public float getAzimuthDegrees(@IntRange(from=0) int);
+    method @FloatRange(from=0) public float getCarrierFrequencyHz(@IntRange(from=0) int);
+    method @FloatRange(from=0, to=63) public float getCn0DbHz(@IntRange(from=0) int);
+    method public int getConstellationType(@IntRange(from=0) int);
+    method @FloatRange(from=0xffffffa6, to=90) public float getElevationDegrees(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getSatelliteCount();
+    method @IntRange(from=1, to=200) public int getSvid(@IntRange(from=0) int);
+    method public boolean hasAlmanacData(@IntRange(from=0) int);
+    method public boolean hasCarrierFrequencyHz(@IntRange(from=0) int);
+    method public boolean hasEphemerisData(@IntRange(from=0) int);
+    method public boolean usedInFix(@IntRange(from=0) int);
     field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
     field public static final int CONSTELLATION_GALILEO = 6; // 0x6
     field public static final int CONSTELLATION_GLONASS = 3; // 0x3
@@ -23060,10 +23078,17 @@
     field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
   }
 
+  public static final class GnssStatus.Builder {
+    ctor public GnssStatus.Builder();
+    method @NonNull public android.location.GnssStatus.Builder addSatellite(int, @IntRange(from=1, to=200) int, @FloatRange(from=0, to=63) float, @FloatRange(from=0xffffffa6, to=90) float, @FloatRange(from=0, to=360) float, boolean, boolean, boolean, boolean, @FloatRange(from=0) float);
+    method @NonNull public android.location.GnssStatus build();
+    method @NonNull public android.location.GnssStatus.Builder clearSatellites();
+  }
+
   public abstract static class GnssStatus.Callback {
     ctor public GnssStatus.Callback();
     method public void onFirstFix(int);
-    method public void onSatelliteStatusChanged(android.location.GnssStatus);
+    method public void onSatelliteStatusChanged(@NonNull android.location.GnssStatus);
     method public void onStarted();
     method public void onStopped();
   }
@@ -23079,6 +23104,7 @@
   }
 
   @Deprecated public final class GpsStatus {
+    method @Deprecated @NonNull public static android.location.GpsStatus create(@NonNull android.location.GnssStatus, int);
     method @Deprecated public int getMaxSatellites();
     method @Deprecated public Iterable<android.location.GpsSatellite> getSatellites();
     method @Deprecated public int getTimeToFirstFix();
@@ -24042,7 +24068,7 @@
     ctor public ExifInterface(@NonNull String) throws java.io.IOException;
     ctor public ExifInterface(@NonNull java.io.FileDescriptor) throws java.io.IOException;
     ctor public ExifInterface(@NonNull java.io.InputStream) throws java.io.IOException;
-    method @NonNull public static android.media.ExifInterface fromStandalone(@NonNull java.io.InputStream) throws java.io.IOException;
+    ctor public ExifInterface(@NonNull java.io.InputStream, int) throws java.io.IOException;
     method public double getAltitude(double);
     method @Nullable public String getAttribute(@NonNull String);
     method @Nullable public byte[] getAttributeBytes(@NonNull String);
@@ -24069,6 +24095,8 @@
     field public static final int ORIENTATION_TRANSPOSE = 5; // 0x5
     field public static final int ORIENTATION_TRANSVERSE = 7; // 0x7
     field public static final int ORIENTATION_UNDEFINED = 0; // 0x0
+    field public static final int STREAM_TYPE_EXIF_DATA_ONLY = 1; // 0x1
+    field public static final int STREAM_TYPE_FULL_IMAGE_DATA = 0; // 0x0
     field @Deprecated public static final String TAG_APERTURE = "FNumber";
     field public static final String TAG_APERTURE_VALUE = "ApertureValue";
     field public static final String TAG_ARTIST = "Artist";
@@ -30046,6 +30074,7 @@
     method public java.util.List<android.net.wifi.ScanResult> getScanResults();
     method public int getWifiState();
     method public boolean is5GHzBandSupported();
+    method public boolean is6GHzBandSupported();
     method @Deprecated public boolean isDeviceToApRttSupported();
     method public boolean isEasyConnectSupported();
     method public boolean isEnhancedOpenSupported();
@@ -30360,6 +30389,7 @@
   public static final class WifiAwareNetworkSpecifier.Builder {
     ctor public WifiAwareNetworkSpecifier.Builder(@NonNull android.net.wifi.aware.DiscoverySession, @NonNull android.net.wifi.aware.PeerHandle);
     method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier build();
+    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPmk(@NonNull byte[]);
     method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPort(@IntRange(from=0, to=65535) int);
     method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPskPassphrase(@NonNull String);
     method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setTransportProtocol(@IntRange(from=0, to=255) int);
@@ -30496,6 +30526,9 @@
     field public static final int GROUP_OWNER_BAND_2GHZ = 1; // 0x1
     field public static final int GROUP_OWNER_BAND_5GHZ = 2; // 0x2
     field public static final int GROUP_OWNER_BAND_AUTO = 0; // 0x0
+    field public static final int GROUP_OWNER_INTENT_AUTO = -1; // 0xffffffff
+    field public static final int GROUP_OWNER_INTENT_MAX = 15; // 0xf
+    field public static final int GROUP_OWNER_INTENT_MIN = 0; // 0x0
     field public String deviceAddress;
     field public int groupOwnerIntent;
     field public android.net.wifi.WpsInfo wps;
@@ -30516,6 +30549,7 @@
     ctor public WifiP2pDevice();
     ctor public WifiP2pDevice(android.net.wifi.p2p.WifiP2pDevice);
     method public int describeContents();
+    method @Nullable public android.net.wifi.p2p.WifiP2pWfdInfo getWfdInfo();
     method public boolean isGroupOwner();
     method public boolean isServiceDiscoveryCapable();
     method public boolean wpsDisplaySupported();
@@ -30552,6 +30586,7 @@
     method public java.util.Collection<android.net.wifi.p2p.WifiP2pDevice> getClientList();
     method public int getFrequency();
     method public String getInterface();
+    method public int getNetworkId();
     method public String getNetworkName();
     method public android.net.wifi.p2p.WifiP2pDevice getOwner();
     method public String getPassphrase();
@@ -30676,6 +30711,28 @@
     method public void onUpnpServiceAvailable(java.util.List<java.lang.String>, android.net.wifi.p2p.WifiP2pDevice);
   }
 
+  public final class WifiP2pWfdInfo implements android.os.Parcelable {
+    ctor public WifiP2pWfdInfo();
+    ctor public WifiP2pWfdInfo(@Nullable android.net.wifi.p2p.WifiP2pWfdInfo);
+    method public int describeContents();
+    method public int getControlPort();
+    method public int getDeviceType();
+    method public int getMaxThroughput();
+    method public boolean isSessionAvailable();
+    method public boolean isWfdEnabled();
+    method public void setControlPort(int);
+    method public boolean setDeviceType(int);
+    method public void setMaxThroughput(int);
+    method public void setSessionAvailable(boolean);
+    method public void setWfdEnabled(boolean);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pWfdInfo> CREATOR;
+    field public static final int DEVICE_TYPE_PRIMARY_SINK = 1; // 0x1
+    field public static final int DEVICE_TYPE_SECONDARY_SINK = 2; // 0x2
+    field public static final int DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK = 3; // 0x3
+    field public static final int DEVICE_TYPE_WFD_SOURCE = 0; // 0x0
+  }
+
 }
 
 package android.net.wifi.p2p.nsd {
@@ -38994,10 +39051,14 @@
     field public static final String ACTION_VPN_SETTINGS = "android.settings.VPN_SETTINGS";
     field public static final String ACTION_VR_LISTENER_SETTINGS = "android.settings.VR_LISTENER_SETTINGS";
     field public static final String ACTION_WEBVIEW_SETTINGS = "android.settings.WEBVIEW_SETTINGS";
+    field public static final String ACTION_WIFI_ADD_NETWORKS = "android.settings.WIFI_ADD_NETWORKS";
     field public static final String ACTION_WIFI_IP_SETTINGS = "android.settings.WIFI_IP_SETTINGS";
     field public static final String ACTION_WIFI_SETTINGS = "android.settings.WIFI_SETTINGS";
     field public static final String ACTION_WIRELESS_SETTINGS = "android.settings.WIRELESS_SETTINGS";
     field public static final String ACTION_ZEN_MODE_PRIORITY_SETTINGS = "android.settings.ZEN_MODE_PRIORITY_SETTINGS";
+    field public static final int ADD_WIFI_RESULT_ADD_OR_UPDATE_FAILED = 1; // 0x1
+    field public static final int ADD_WIFI_RESULT_ALREADY_EXISTS = 2; // 0x2
+    field public static final int ADD_WIFI_RESULT_SUCCESS = 0; // 0x0
     field public static final String AUTHORITY = "settings";
     field public static final String EXTRA_ACCOUNT_TYPES = "account_types";
     field public static final String EXTRA_AIRPLANE_MODE_ENABLED = "airplane_mode_enabled";
@@ -39010,6 +39071,8 @@
     field public static final String EXTRA_INPUT_METHOD_ID = "input_method_id";
     field public static final String EXTRA_NOTIFICATION_LISTENER_COMPONENT_NAME = "android.provider.extra.NOTIFICATION_LISTENER_COMPONENT_NAME";
     field public static final String EXTRA_SUB_ID = "android.provider.extra.SUB_ID";
+    field public static final String EXTRA_WIFI_CONFIGURATION_LIST = "android.provider.extra.WIFI_CONFIGURATION_LIST";
+    field public static final String EXTRA_WIFI_CONFIGURATION_RESULT_LIST = "android.provider.extra.WIFI_CONFIGURATION_RESULT_LIST";
     field public static final String INTENT_CATEGORY_USAGE_ACCESS_CONFIG = "android.intent.category.USAGE_ACCESS_CONFIG";
     field public static final String METADATA_USAGE_ACCESS_REASON = "android.settings.metadata.USAGE_ACCESS_REASON";
   }
@@ -45230,6 +45293,7 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.os.ParcelUuid createSubscriptionGroup(@NonNull java.util.List<java.lang.Integer>);
     method @Deprecated public static android.telephony.SubscriptionManager from(android.content.Context);
     method public java.util.List<android.telephony.SubscriptionInfo> getAccessibleSubscriptionInfoList();
+    method @Nullable public java.util.List<android.telephony.SubscriptionInfo> getActiveAndHiddenSubscriptionInfoList();
     method public static int getActiveDataSubscriptionId();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.telephony.SubscriptionInfo getActiveSubscriptionInfo(int);
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int getActiveSubscriptionInfoCount();
diff --git a/api/system-current.txt b/api/system-current.txt
index 9420a28..412e095 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -57,6 +57,7 @@
     field public static final String CHANGE_DEVICE_IDLE_TEMP_WHITELIST = "android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST";
     field public static final String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA";
     field public static final String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS";
+    field public static final String CONFIGURE_WIFI_DISPLAY = "android.permission.CONFIGURE_WIFI_DISPLAY";
     field public static final String CONNECTIVITY_INTERNAL = "android.permission.CONNECTIVITY_INTERNAL";
     field public static final String CONNECTIVITY_USE_RESTRICTED_NETWORKS = "android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS";
     field public static final String CONTROL_DISPLAY_COLOR_TRANSFORMS = "android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS";
@@ -125,8 +126,10 @@
     field public static final String NETWORK_CARRIER_PROVISIONING = "android.permission.NETWORK_CARRIER_PROVISIONING";
     field public static final String NETWORK_MANAGED_PROVISIONING = "android.permission.NETWORK_MANAGED_PROVISIONING";
     field public static final String NETWORK_SCAN = "android.permission.NETWORK_SCAN";
+    field public static final String NETWORK_SETTINGS = "android.permission.NETWORK_SETTINGS";
     field public static final String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD";
     field public static final String NETWORK_SIGNAL_STRENGTH_WAKEUP = "android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP";
+    field public static final String NETWORK_STACK = "android.permission.NETWORK_STACK";
     field public static final String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP";
     field public static final String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS";
     field public static final String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE";
@@ -1306,6 +1309,7 @@
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isEncrypted();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInSilenceMode();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean removeBond();
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean setAlias(@NonNull String);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMetadata(int, @NonNull byte[]);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPhonebookAccessPermission(int);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setSilenceMode(boolean);
@@ -2000,6 +2004,7 @@
     method @Nullable public android.hardware.display.BrightnessCorrection getCorrectionByCategory(int);
     method @Nullable public android.hardware.display.BrightnessCorrection getCorrectionByPackageName(@NonNull String);
     method public android.util.Pair<float[],float[]> getCurve();
+    method public boolean shouldCollectColorSamples();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.hardware.display.BrightnessConfiguration> CREATOR;
   }
@@ -2012,6 +2017,7 @@
     method public int getMaxCorrectionsByCategory();
     method public int getMaxCorrectionsByPackageName();
     method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setDescription(@Nullable String);
+    method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setShouldCollectColorSamples(boolean);
   }
 
   public final class BrightnessCorrection implements android.os.Parcelable {
@@ -4120,8 +4126,8 @@
     method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener);
     method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
     method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void setAirplaneMode(boolean);
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, "android.permission.NETWORK_STACK"}) public boolean shouldAvoidBadWifi();
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean);
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public boolean shouldAvoidBadWifi();
     method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle);
     method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
     method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
@@ -4829,38 +4835,62 @@
 
   public class WifiManager {
     method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void addOnWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
-    method @RequiresPermission("android.permission.NETWORK_SETTINGS") public void allowAutojoin(int, boolean);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void connect(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @Deprecated @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void forget(int, @Nullable android.net.wifi.WifiManager.ActionListener);
-    method @NonNull @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.util.Pair<android.net.wifi.WifiConfiguration,java.util.Map<java.lang.Integer,java.util.List<android.net.wifi.ScanResult>>>> getAllMatchingWifiConfigs(@NonNull java.util.List<android.net.wifi.ScanResult>);
-    method @NonNull @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,java.util.List<android.net.wifi.ScanResult>> getMatchingOsuProviders(@Nullable java.util.List<android.net.wifi.ScanResult>);
-    method @NonNull @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,android.net.wifi.hotspot2.PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(@NonNull java.util.Set<android.net.wifi.hotspot2.OsuProvider>);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoin(int, boolean);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener);
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK}) public void disableEphemeralNetwork(@NonNull String);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void enableVerboseLogging(int);
+    method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void factoryReset();
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void forget(int, @Nullable android.net.wifi.WifiManager.ActionListener);
+    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.util.Pair<android.net.wifi.WifiConfiguration,java.util.Map<java.lang.Integer,java.util.List<android.net.wifi.ScanResult>>>> getAllMatchingWifiConfigs(@NonNull java.util.List<android.net.wifi.ScanResult>);
+    method @Nullable @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public String getCountryCode();
+    method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.Network getCurrentNetwork();
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String[] getFactoryMacAddresses();
+    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,java.util.List<android.net.wifi.ScanResult>> getMatchingOsuProviders(@Nullable java.util.List<android.net.wifi.ScanResult>);
+    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,android.net.wifi.hotspot2.PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(@NonNull java.util.Set<android.net.wifi.hotspot2.OsuProvider>);
     method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks();
+    method public int getVerboseLoggingLevel();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState();
     method public boolean isApMacRandomizationSupported();
     method public boolean isConnectedMacRandomizationSupported();
     method @Deprecated public boolean isDeviceToDeviceRttSupported();
+    method public boolean isDualBandSupported();
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean isDualModeSupported();
     method public boolean isPortableHotspotSupported();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled();
     method public boolean isWifiScannerSupported();
-    method @RequiresPermission("android.permission.NETWORK_SETTINGS") public void registerSoftApCallback(@NonNull android.net.wifi.WifiManager.SoftApCallback, @Nullable java.util.concurrent.Executor);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerNetworkRequestMatchCallback(@NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerNetworkRequestMatchCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerSoftApCallback(@NonNull android.net.wifi.WifiManager.SoftApCallback);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerSoftApCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerTrafficStateCallback(@NonNull android.net.wifi.WifiManager.TrafficStateCallback);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerTrafficStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.TrafficStateCallback);
     method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void removeOnWifiUsabilityStatsListener(@NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void save(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreBackupData(@NonNull byte[]);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreSupplicantBackupData(@NonNull byte[], @NonNull byte[]);
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveBackupData();
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void save(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
     method @RequiresPermission("android.permission.WIFI_SET_DEVICE_MOBILITY_STATE") public void setDeviceMobilityState(int);
     method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsConfiguratorInitiator(@NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsEnrolleeInitiator(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startLocalOnlyHotspot(@NonNull android.net.wifi.SoftApConfiguration, @Nullable java.util.concurrent.Executor, @Nullable android.net.wifi.WifiManager.LocalOnlyHotspotCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsConfiguratorInitiator(@NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsEnrolleeInitiator(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startLocalOnlyHotspot(@NonNull android.net.wifi.SoftApConfiguration, @Nullable java.util.concurrent.Executor, @Nullable android.net.wifi.WifiManager.LocalOnlyHotspotCallback);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public boolean startScan(android.os.WorkSource);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_STACK", android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean startSoftAp(@Nullable android.net.wifi.WifiConfiguration);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startSubscriptionProvisioning(@NonNull android.net.wifi.hotspot2.OsuProvider, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.hotspot2.ProvisioningCallback);
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopEasyConnectSession();
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_STACK", android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean stopSoftAp();
-    method @RequiresPermission(anyOf={"android.permission.NETWORK_STACK", android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateInterfaceIpState(@Nullable String, int);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean startSoftAp(@Nullable android.net.wifi.WifiConfiguration);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startSubscriptionProvisioning(@NonNull android.net.wifi.hotspot2.OsuProvider, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.hotspot2.ProvisioningCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopEasyConnectSession();
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean stopSoftAp();
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterNetworkRequestMatchCallback(@NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterSoftApCallback(@NonNull android.net.wifi.WifiManager.SoftApCallback);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterTrafficStateCallback(@NonNull android.net.wifi.WifiManager.TrafficStateCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateInterfaceIpState(@Nullable String, int);
     method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void updateWifiUsabilityScore(int, int, int);
+    field public static final String ACTION_LINK_CONFIGURATION_CHANGED = "android.net.wifi.LINK_CONFIGURATION_CHANGED";
+    field public static final String ACTION_PASSPOINT_LAUNCH_OSU_VIEW = "android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW";
+    field public static final String ACTION_REQUEST_DISABLE = "android.net.wifi.action.REQUEST_DISABLE";
+    field public static final String ACTION_REQUEST_ENABLE = "android.net.wifi.action.REQUEST_ENABLE";
     field public static final int CHANGE_REASON_ADDED = 0; // 0x0
     field public static final int CHANGE_REASON_CONFIG_CHANGE = 2; // 0x2
     field public static final int CHANGE_REASON_REMOVED = 1; // 0x1
@@ -4872,8 +4902,11 @@
     field public static final int EASY_CONNECT_NETWORK_ROLE_AP = 1; // 0x1
     field public static final int EASY_CONNECT_NETWORK_ROLE_STA = 0; // 0x0
     field public static final String EXTRA_CHANGE_REASON = "changeReason";
+    field public static final String EXTRA_LINK_PROPERTIES = "android.net.wifi.extra.LINK_PROPERTIES";
     field public static final String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges";
+    field public static final String EXTRA_OSU_NETWORK = "android.net.wifi.extra.OSU_NETWORK";
     field public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state";
+    field public static final String EXTRA_URL = "android.net.wifi.extra.URL";
     field public static final String EXTRA_WIFI_AP_INTERFACE_NAME = "android.net.wifi.extra.WIFI_AP_INTERFACE_NAME";
     field public static final String EXTRA_WIFI_AP_MODE = "android.net.wifi.extra.WIFI_AP_MODE";
     field public static final String EXTRA_WIFI_AP_STATE = "wifi_state";
@@ -4886,6 +4919,8 @@
     field public static final int IFACE_IP_MODE_UNSPECIFIED = -1; // 0xffffffff
     field public static final int PASSPOINT_HOME_NETWORK = 0; // 0x0
     field public static final int PASSPOINT_ROAMING_NETWORK = 1; // 0x1
+    field public static final int SAP_START_FAILURE_GENERAL = 0; // 0x0
+    field public static final int SAP_START_FAILURE_NO_CHANNEL = 1; // 0x1
     field public static final String WIFI_AP_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_AP_STATE_CHANGED";
     field public static final int WIFI_AP_STATE_DISABLED = 11; // 0xb
     field public static final int WIFI_AP_STATE_DISABLING = 10; // 0xa
@@ -4902,14 +4937,35 @@
     method public void onSuccess();
   }
 
+  public static interface WifiManager.NetworkRequestMatchCallback {
+    method public default void onAbort();
+    method public default void onMatch(@NonNull java.util.List<android.net.wifi.ScanResult>);
+    method public default void onUserSelectionCallbackRegistration(@NonNull android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback);
+    method public default void onUserSelectionConnectFailure(@NonNull android.net.wifi.WifiConfiguration);
+    method public default void onUserSelectionConnectSuccess(@NonNull android.net.wifi.WifiConfiguration);
+  }
+
+  public static interface WifiManager.NetworkRequestUserSelectionCallback {
+    method public default void reject();
+    method public default void select(@NonNull android.net.wifi.WifiConfiguration);
+  }
+
   public static interface WifiManager.OnWifiUsabilityStatsListener {
     method public void onWifiUsabilityStats(int, boolean, @NonNull android.net.wifi.WifiUsabilityStatsEntry);
   }
 
   public static interface WifiManager.SoftApCallback {
-    method public void onConnectedClientsChanged(@NonNull java.util.List<android.net.wifi.WifiClient>);
+    method public default void onConnectedClientsChanged(@NonNull java.util.List<android.net.wifi.WifiClient>);
     method public default void onInfoChanged(@NonNull android.net.wifi.SoftApInfo);
-    method public void onStateChanged(int, int);
+    method public default void onStateChanged(int, int);
+  }
+
+  public static interface WifiManager.TrafficStateCallback {
+    method public void onStateChanged(int);
+    field public static final int DATA_ACTIVITY_IN = 1; // 0x1
+    field public static final int DATA_ACTIVITY_INOUT = 3; // 0x3
+    field public static final int DATA_ACTIVITY_NONE = 0; // 0x0
+    field public static final int DATA_ACTIVITY_OUT = 2; // 0x2
   }
 
   public class WifiNetworkConnectionStatistics implements android.os.Parcelable {
@@ -4932,6 +4988,7 @@
     method @Deprecated public void configureWifiChange(android.net.wifi.WifiScanner.WifiChangeSettings);
     method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<java.lang.Integer> getAvailableChannels(int);
     method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean getScanResults();
+    method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<android.net.wifi.ScanResult> getSingleScanResults();
     method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
     method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
     method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
@@ -5092,10 +5149,6 @@
     method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierPmk(@NonNull android.net.wifi.aware.PeerHandle, @NonNull byte[]);
   }
 
-  public static final class WifiAwareNetworkSpecifier.Builder {
-    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPmk(@NonNull byte[]);
-  }
-
   public class WifiAwareSession implements java.lang.AutoCloseable {
     method public android.net.NetworkSpecifier createNetworkSpecifierPmk(int, @NonNull byte[], @NonNull byte[]);
   }
@@ -5155,6 +5208,36 @@
 
 }
 
+package android.net.wifi.p2p {
+
+  public final class WifiP2pGroupList implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.Collection<android.net.wifi.p2p.WifiP2pGroup> getGroupList();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pGroupList> CREATOR;
+  }
+
+  public class WifiP2pManager {
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void deletePersistentGroup(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, int, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void listen(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, boolean, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public void requestPersistentGroupInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.PersistentGroupInfoListener);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setDeviceName(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull String, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(allOf={android.Manifest.permission.CONNECTIVITY_INTERNAL, android.Manifest.permission.CONFIGURE_WIFI_DISPLAY}) public void setMiracastMode(int);
+    method @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) public void setWfdInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pWfdInfo, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setWifiP2pChannels(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, int, int, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    field public static final String ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED = "android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED";
+    field public static final int MIRACAST_DISABLED = 0; // 0x0
+    field public static final int MIRACAST_SINK = 2; // 0x2
+    field public static final int MIRACAST_SOURCE = 1; // 0x1
+  }
+
+  public static interface WifiP2pManager.PersistentGroupInfoListener {
+    method public void onPersistentGroupInfoAvailable(@NonNull android.net.wifi.p2p.WifiP2pGroupList);
+  }
+
+}
+
 package android.net.wifi.rtt {
 
   public static final class RangingRequest.Builder {
@@ -7968,6 +8051,7 @@
   public final class DataSpecificRegistrationInfo implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
+    method public boolean isUsingCarrierAggregation();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
   }
@@ -8106,6 +8190,7 @@
     method @Nullable public android.telephony.CellIdentity getCellIdentity();
     method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
     method public int getDomain();
+    method public int getNrState();
     method public int getRegistrationState();
     method public int getRejectCause();
     method public int getRoamingType();
@@ -8348,6 +8433,9 @@
     method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList();
     method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int);
     method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int);
+    method public int getNrFrequencyRange();
+    method @Nullable public String getOperatorAlphaLongRaw();
+    method @Nullable public String getOperatorAlphaShortRaw();
     field public static final int ROAMING_TYPE_DOMESTIC = 2; // 0x2
     field public static final int ROAMING_TYPE_INTERNATIONAL = 3; // 0x3
     field public static final int ROAMING_TYPE_NOT_ROAMING = 0; // 0x0
@@ -8484,6 +8572,7 @@
   public class SubscriptionInfo implements android.os.Parcelable {
     method @Nullable public java.util.List<android.telephony.UiccAccessRule> getAccessRules();
     method public int getProfileClass();
+    method public boolean isGroupDisabled();
   }
 
   public class SubscriptionManager {
@@ -8566,6 +8655,7 @@
     method @Deprecated public boolean getDataEnabled();
     method @Deprecated public boolean getDataEnabled(int);
     method @Nullable public static android.content.ComponentName getDefaultRespondViaMessageApplication(@NonNull android.content.Context, boolean);
+    method @NonNull public static String getDefaultSimCountryIso();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
@@ -8597,7 +8687,9 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle();
+    method public boolean isModemEnabledForSlot(int);
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isOpportunisticNetworkEnabled();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String);
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRadioOn();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging();
@@ -8618,6 +8710,7 @@
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadioPower(boolean);
diff --git a/api/system-lint-baseline.txt b/api/system-lint-baseline.txt
index 21526d0..7eb5443 100644
--- a/api/system-lint-baseline.txt
+++ b/api/system-lint-baseline.txt
@@ -1,12 +1,30 @@
 // Baseline format: 1.0
 ActionValue: android.location.Location#EXTRA_NO_GPS_LOCATION:
     
+ActionValue: android.net.wifi.WifiManager#ACTION_LINK_CONFIGURATION_CHANGED:
+    Inconsistent action value; expected `android.net.wifi.action.LINK_CONFIGURATION_CHANGED`, was `android.net.wifi.LINK_CONFIGURATION_CHANGED`
 
 
 ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions():
     
 
 
+ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#deletePersistentGroup(android.net.wifi.p2p.WifiP2pManager.Channel, int, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+    Registration methods should have overload that accepts delivery Executor: `deletePersistentGroup`
+ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#factoryReset(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+    Registration methods should have overload that accepts delivery Executor: `factoryReset`
+ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#listen(android.net.wifi.p2p.WifiP2pManager.Channel, boolean, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+    Registration methods should have overload that accepts delivery Executor: `listen`
+ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#requestPersistentGroupInfo(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.PersistentGroupInfoListener):
+    Registration methods should have overload that accepts delivery Executor: `requestPersistentGroupInfo`
+ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#setDeviceName(android.net.wifi.p2p.WifiP2pManager.Channel, String, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+    Registration methods should have overload that accepts delivery Executor: `setDeviceName`
+ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#setWfdInfo(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pWfdInfo, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+    Registration methods should have overload that accepts delivery Executor: `setWfdInfo`
+ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#setWifiP2pChannels(android.net.wifi.p2p.WifiP2pManager.Channel, int, int, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+    Registration methods should have overload that accepts delivery Executor: `setWifiP2pChannels`
+
+
 GenericException: android.app.prediction.AppPredictor#finalize():
     
 GenericException: android.hardware.location.ContextHubClient#finalize():
@@ -17,8 +35,7 @@
     
 
 
-InterfaceConstant: android.service.storage.ExternalStorageService#SERVICE_INTERFACE:
-    
+
 
 
 KotlinKeyword: android.app.Notification#when:
@@ -198,9 +215,9 @@
 SamShouldBeLast: android.app.AlarmManager#setWindow(int, long, long, String, android.app.AlarmManager.OnAlarmListener, android.os.Handler):
     
 SamShouldBeLast: android.app.WallpaperInfo#dump(android.util.Printer, String):
-    
+
 SamShouldBeLast: android.app.admin.DevicePolicyManager#installSystemUpdate(android.content.ComponentName, android.net.Uri, java.util.concurrent.Executor, android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback):
-    
+
 SamShouldBeLast: android.content.Context#bindIsolatedService(android.content.Intent, int, String, java.util.concurrent.Executor, android.content.ServiceConnection):
     
 SamShouldBeLast: android.content.Context#bindService(android.content.Intent, int, java.util.concurrent.Executor, android.content.ServiceConnection):
@@ -332,7 +349,7 @@
 SamShouldBeLast: android.telephony.TelephonyManager#setPreferredOpportunisticDataSubscription(int, boolean, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Integer>):
     
 SamShouldBeLast: android.telephony.TelephonyManager#updateAvailableNetworks(java.util.List<android.telephony.AvailableNetworkInfo>, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Integer>):
-    
+
 SamShouldBeLast: android.view.View#postDelayed(Runnable, long):
     
 SamShouldBeLast: android.view.View#postOnAnimationDelayed(Runnable, long):
diff --git a/api/test-current.txt b/api/test-current.txt
index 44f736c..c6b02b9 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1018,6 +1018,7 @@
     method @Nullable public android.hardware.display.BrightnessCorrection getCorrectionByCategory(int);
     method @Nullable public android.hardware.display.BrightnessCorrection getCorrectionByPackageName(@NonNull String);
     method public android.util.Pair<float[],float[]> getCurve();
+    method public boolean shouldCollectColorSamples();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.hardware.display.BrightnessConfiguration> CREATOR;
   }
@@ -1030,6 +1031,7 @@
     method public int getMaxCorrectionsByCategory();
     method public int getMaxCorrectionsByPackageName();
     method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setDescription(@Nullable String);
+    method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setShouldCollectColorSamples(boolean);
   }
 
   public final class BrightnessCorrection implements android.os.Parcelable {
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index 7e278e9..59544a9 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -508,7 +508,7 @@
 
         @Override
         public void onExecute(IContentProvider provider) throws Exception {
-            provider.insert(resolveCallingPackage(), null, mUri, mContentValues);
+            provider.insert(resolveCallingPackage(), null, mUri, mContentValues, null);
         }
     }
 
@@ -522,7 +522,8 @@
 
         @Override
         public void onExecute(IContentProvider provider) throws Exception {
-            provider.delete(resolveCallingPackage(), null, mUri, mWhere, null);
+            provider.delete(resolveCallingPackage(), null, mUri,
+                    ContentResolver.createSqlQueryBundle(mWhere, null));
         }
     }
 
@@ -679,7 +680,8 @@
 
         @Override
         public void onExecute(IContentProvider provider) throws Exception {
-            provider.update(resolveCallingPackage(), null, mUri, mContentValues, mWhere, null);
+            provider.update(resolveCallingPackage(), null, mUri, mContentValues,
+                    ContentResolver.createSqlQueryBundle(mWhere, null));
         }
     }
 
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 8af925a..cf286e6 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -50,6 +50,7 @@
 
     srcs: [
         ":statsd_aidl",
+        ":ICarStatsService.aidl",
         "src/active_config_list.proto",
         "src/anomaly/AlarmMonitor.cpp",
         "src/anomaly/AlarmTracker.cpp",
@@ -64,6 +65,7 @@
         "src/config/ConfigKey.cpp",
         "src/config/ConfigListener.cpp",
         "src/config/ConfigManager.cpp",
+        "src/external/CarStatsPuller.cpp",
         "src/external/GpuStatsPuller.cpp",
         "src/external/Perfetto.cpp",
         "src/external/PowerStatsPuller.cpp",
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index c196c61..b0570fd 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -339,6 +339,7 @@
             228 [(allow_from_any_uid) = true];
         PerfettoUploaded perfetto_uploaded =
             229 [(log_from_module) = "perfetto"];
+        VmsClientConnectionStateChanged vms_client_connection_state_changed = 230;
     }
 
     // Pulled events will start at field 10000.
@@ -408,6 +409,7 @@
         SurfaceflingerStatsGlobalInfo surfaceflinger_stats_global_info = 10062;
         SurfaceflingerStatsLayerInfo surfaceflinger_stats_layer_info = 10063;
         ProcessMemorySnapshot process_memory_snapshot = 10064;
+        VmsClientStats vms_client_stats = 10065;
     }
 
     // DO NOT USE field numbers above 100,000 in AOSP.
@@ -3732,6 +3734,33 @@
     optional Result result = 9;
 }
 
+/**
+ * Logs when a Vehicle Maps Service client's connection state has changed
+ *
+ * Logged from:
+ *   packages/services/Car/service/src/com/android/car/stats/VmsClientLog.java
+ */
+message VmsClientConnectionStateChanged {
+    // The UID of the VMS client app
+    optional int32 uid = 1 [(is_uid) = true];
+
+    enum State {
+        UNKNOWN = 0;
+        // Attempting to connect to the client
+        CONNECTING = 1;
+        // Client connection established
+        CONNECTED = 2;
+        // Client connection closed unexpectedly
+        DISCONNECTED = 3;
+        // Client connection closed by VMS
+        TERMINATED = 4;
+        // Error establishing the client connection
+        CONNECTION_ERROR = 5;
+    }
+
+    optional State state  = 2;
+}
+
 //////////////////////////////////////////////////////////////////////
 // Pulled atoms below this line //
 //////////////////////////////////////////////////////////////////////
@@ -7275,3 +7304,32 @@
     optional int64 trace_uuid_lsb = 2;
     optional int64 trace_uuid_msb = 3;
 }
+
+/**
+ * Pulls client metrics on data transferred via Vehicle Maps Service.
+ * Metrics are keyed by uid + layer.
+ *
+ * Pulled from:
+ *   packages/services/Car/service/src/com/android/car/stats/CarStatsService.java
+ */
+message VmsClientStats {
+    // UID of the VMS client app
+    optional int32 uid = 1 [(is_uid) = true];
+
+    // VMS layer definition
+    optional int32 layer_type = 2;
+    optional int32 layer_channel = 3;
+    optional int32 layer_version = 4;
+
+    // Bytes and packets sent by the client for the layer
+    optional int64 tx_bytes = 5;
+    optional int64 tx_packets = 6;
+
+    // Bytes and packets received by the client for the layer
+    optional int64 rx_bytes = 7;
+    optional int64 rx_packets = 8;
+
+    // Bytes and packets dropped due to client error
+    optional int64 dropped_bytes = 9;
+    optional int64 dropped_packets = 10;
+}
diff --git a/cmds/statsd/src/external/CarStatsPuller.cpp b/cmds/statsd/src/external/CarStatsPuller.cpp
new file mode 100644
index 0000000..70c0456
--- /dev/null
+++ b/cmds/statsd/src/external/CarStatsPuller.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+#define DEBUG false
+#include "Log.h"
+
+#include <binder/IServiceManager.h>
+#include <com/android/internal/car/ICarStatsService.h>
+
+#include "CarStatsPuller.h"
+#include "logd/LogEvent.h"
+#include "stats_log_util.h"
+
+using android::binder::Status;
+using com::android::internal::car::ICarStatsService;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+static std::mutex gCarStatsMutex;
+static sp<ICarStatsService> gCarStats = nullptr;
+
+class CarStatsDeathRecipient : public android::IBinder::DeathRecipient {
+ public:
+     CarStatsDeathRecipient() = default;
+     ~CarStatsDeathRecipient() override = default;
+
+  // android::IBinder::DeathRecipient override:
+  void binderDied(const android::wp<android::IBinder>& /* who */) override {
+      ALOGE("Car service has died");
+      std::lock_guard<std::mutex> lock(gCarStatsMutex);
+      if (gCarStats) {
+          sp<IBinder> binder = IInterface::asBinder(gCarStats);
+          binder->unlinkToDeath(this);
+          gCarStats = nullptr;
+      }
+  }
+};
+
+static sp<CarStatsDeathRecipient> gDeathRecipient = new CarStatsDeathRecipient();
+
+static sp<ICarStatsService> getCarService() {
+    std::lock_guard<std::mutex> lock(gCarStatsMutex);
+    if (!gCarStats) {
+        const sp<IBinder> binder = defaultServiceManager()->checkService(String16("car_stats"));
+        if (!binder) {
+            ALOGW("Car service is unavailable");
+            return nullptr;
+        }
+        gCarStats = interface_cast<ICarStatsService>(binder);
+        binder->linkToDeath(gDeathRecipient);
+    }
+    return gCarStats;
+}
+
+CarStatsPuller::CarStatsPuller(const int tagId) : StatsPuller(tagId) {
+}
+
+bool CarStatsPuller::PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) {
+    const sp<ICarStatsService> carService = getCarService();
+    if (!carService) {
+        return false;
+    }
+
+    vector<StatsLogEventWrapper> returned_value;
+    Status status = carService->pullData(mTagId, &returned_value);
+    if (!status.isOk()) {
+        ALOGW("CarStatsPuller::pull failed for %d", mTagId);
+        return false;
+    }
+
+    data->clear();
+    for (const StatsLogEventWrapper& it : returned_value) {
+        LogEvent::createLogEvents(it, *data);
+    }
+    VLOG("CarStatsPuller::pull succeeded for %d", mTagId);
+    return true;
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/external/CarStatsPuller.h b/cmds/statsd/src/external/CarStatsPuller.h
new file mode 100644
index 0000000..ca0f1a9
--- /dev/null
+++ b/cmds/statsd/src/external/CarStatsPuller.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "StatsPuller.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+/**
+ * Pull atoms from CarService.
+ */
+class CarStatsPuller : public StatsPuller {
+public:
+    explicit CarStatsPuller(const int tagId);
+    bool PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) override;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 5a76d1f..535fcfb 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -32,6 +32,7 @@
 #include "../logd/LogEvent.h"
 #include "../stats_log_util.h"
 #include "../statscompanion_util.h"
+#include "CarStatsPuller.h"
 #include "GpuStatsPuller.h"
 #include "PowerStatsPuller.h"
 #include "ResourceHealthManagerPuller.h"
@@ -272,6 +273,10 @@
         {android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
          {.puller =
                   new SurfaceflingerStatsPuller(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO)}},
+        // VmsClientStats
+        {android::util::VMS_CLIENT_STATS,
+         {.additiveFields = {5, 6, 7, 8, 9, 10},
+          .puller = new CarStatsPuller(android::util::VMS_CLIENT_STATS)}},
 };
 
 StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
index db0bca0..a4b3058 100644
--- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java
+++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
@@ -376,7 +376,7 @@
     private void runGetMaxPhones() throws RemoteException {
         // This assumes the max number of SIMs is 2, which it currently is
         if (TelephonyManager.MULTISIM_ALLOWED
-                == mTelephonyService.isMultiSimSupported("com.android.commands.telecom")) {
+                == mTelephonyService.isMultiSimSupported("com.android.commands.telecom", null)) {
             System.out.println("2");
         } else {
             System.out.println("1");
diff --git a/core/java/Android.bp b/core/java/Android.bp
index fb27f74..9a8e130 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -7,3 +7,8 @@
     name: "IDropBoxManagerService.aidl",
     srcs: ["com/android/internal/os/IDropBoxManagerService.aidl"],
 }
+
+filegroup {
+    name: "ICarStatsService.aidl",
+    srcs: ["com/android/internal/car/ICarStatsService.aidl"],
+}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 6d63fd09..590b3db 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -70,6 +70,7 @@
 import android.util.DisplayMetrics;
 import android.util.Singleton;
 import android.util.Size;
+import android.view.IWindowContainer;
 
 import com.android.internal.app.LocalePicker;
 import com.android.internal.app.procstats.ProcessStats;
@@ -2526,6 +2527,7 @@
         // Index of the stack in the display's stack list, can be used for comparison of stack order
         @UnsupportedAppUsage
         public int position;
+        public IWindowContainer stackToken;
         /**
          * The full configuration the stack is currently running in.
          * @hide
@@ -2559,6 +2561,7 @@
             dest.writeInt(userId);
             dest.writeInt(visible ? 1 : 0);
             dest.writeInt(position);
+            dest.writeStrongInterface(stackToken);
             if (topActivity != null) {
                 dest.writeInt(1);
                 topActivity.writeToParcel(dest, 0);
@@ -2590,6 +2593,7 @@
             userId = source.readInt();
             visible = source.readInt() > 0;
             position = source.readInt();
+            stackToken = IWindowContainer.Stub.asInterface(source.readStrongBinder());
             if (source.readInt() > 0) {
                 topActivity = ComponentName.readFromParcel(source);
             }
diff --git a/core/java/android/app/AliasActivity.java b/core/java/android/app/AliasActivity.java
index 3756529..37be901 100644
--- a/core/java/android/app/AliasActivity.java
+++ b/core/java/android/app/AliasActivity.java
@@ -39,7 +39,10 @@
  * To use this activity, you should include in the manifest for the associated
  * component an entry named "android.app.alias".  It is a reference to an XML
  * resource describing an intent that launches the real application.
+ *
+ * @deprecated Use {@code <activity-alias>} or subclass Activity directly.
  */
+@Deprecated
 public class AliasActivity extends Activity {
     /**
      * This is the name under which you should store in your component the
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 5661347..0113f69 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -92,7 +92,6 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.DebugUtils;
-import android.util.IconDrawableFactory;
 import android.util.LauncherIcons;
 import android.util.Log;
 import android.view.Display;
@@ -1474,11 +1473,11 @@
 
     @Override
     public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
-        if (!isManagedProfile(user.getIdentifier())) {
+        if (!hasUserBadge(user.getIdentifier())) {
             return icon;
         }
         Drawable badge = new LauncherIcons(mContext).getBadgeDrawable(
-                com.android.internal.R.drawable.ic_corp_icon_badge_case,
+                getUserManager().getUserIconBadgeResId(user.getIdentifier()),
                 getUserBadgeColor(user));
         return getBadgedDrawable(icon, badge, null, true);
     }
@@ -1493,26 +1492,21 @@
         return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
     }
 
-    @VisibleForTesting
-    public static final int[] CORP_BADGE_LABEL_RES_ID = new int[] {
-        com.android.internal.R.string.managed_profile_label_badge,
-        com.android.internal.R.string.managed_profile_label_badge_2,
-        com.android.internal.R.string.managed_profile_label_badge_3
-    };
-
+    /** Returns the color of the user's actual badge (not the badge's shadow). */
     private int getUserBadgeColor(UserHandle user) {
-        return IconDrawableFactory.getUserBadgeColor(getUserManager(), user.getIdentifier());
+        return getUserManager().getUserBadgeColor(user.getIdentifier());
     }
 
     @Override
     public Drawable getUserBadgeForDensity(UserHandle user, int density) {
-        Drawable badgeColor = getManagedProfileIconForDensity(user,
+        // This is part of the shadow, not the main color, and is not actually corp-specific.
+        Drawable badgeColor = getProfileIconForDensity(user,
                 com.android.internal.R.drawable.ic_corp_badge_color, density);
         if (badgeColor == null) {
             return null;
         }
         Drawable badgeForeground = getDrawableForDensity(
-                com.android.internal.R.drawable.ic_corp_badge_case, density);
+                getUserManager().getUserBadgeResId(user.getIdentifier()), density);
         badgeForeground.setTint(getUserBadgeColor(user));
         Drawable badge = new LayerDrawable(new Drawable[] {badgeColor, badgeForeground });
         return badge;
@@ -1520,8 +1514,8 @@
 
     @Override
     public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
-        Drawable badge = getManagedProfileIconForDensity(user,
-                com.android.internal.R.drawable.ic_corp_badge_no_background, density);
+        Drawable badge = getProfileIconForDensity(user,
+                getUserManager().getUserBadgeNoBackgroundResId(user.getIdentifier()), density);
         if (badge != null) {
             badge.setTint(getUserBadgeColor(user));
         }
@@ -1535,8 +1529,8 @@
         return mContext.getResources().getDrawableForDensity(drawableId, density);
     }
 
-    private Drawable getManagedProfileIconForDensity(UserHandle user, int drawableId, int density) {
-        if (isManagedProfile(user.getIdentifier())) {
+    private Drawable getProfileIconForDensity(UserHandle user, int drawableId, int density) {
+        if (hasUserBadge(user.getIdentifier())) {
             return getDrawableForDensity(drawableId, density);
         }
         return null;
@@ -1544,12 +1538,7 @@
 
     @Override
     public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
-        if (isManagedProfile(user.getIdentifier())) {
-            int badge = getUserManager().getManagedProfileBadge(user.getIdentifier());
-            int resourceId = CORP_BADGE_LABEL_RES_ID[badge % CORP_BADGE_LABEL_RES_ID.length];
-            return Resources.getSystem().getString(resourceId, label);
-        }
-        return label;
+        return getUserManager().getBadgedLabelForUser(label, user);
     }
 
     @Override
@@ -2865,8 +2854,8 @@
         return drawable;
     }
 
-    private boolean isManagedProfile(int userId) {
-        return getUserManager().isManagedProfile(userId);
+    private boolean hasUserBadge(int userId) {
+        return getUserManager().hasBadge(userId);
     }
 
     /**
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 7f5350d..4cb8d93 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -58,14 +58,22 @@
     @UnsupportedAppUsage
     void setWallpaperComponent(in ComponentName name);
 
+
     /**
-     * Get the wallpaper for a given user.
+     * @deprecated Use {@link #getWallpaperWithFeature(String, IWallpaperManagerCallback, int,
+     * Bundle, int)}
      */
     @UnsupportedAppUsage
     ParcelFileDescriptor getWallpaper(String callingPkg, IWallpaperManagerCallback cb, int which,
             out Bundle outParams, int userId);
 
     /**
+     * Get the wallpaper for a given user.
+     */
+    ParcelFileDescriptor getWallpaperWithFeature(String callingPkg, String callingFeatureId,
+            IWallpaperManagerCallback cb, int which, out Bundle outParams, int userId);
+
+    /**
      * Retrieve the given user's current wallpaper ID of the given kind.
      */
     int getWallpaperIdForUser(int which, int userId);
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 1e87ab1..69c174a 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -18,6 +18,7 @@
 
 import android.accounts.AccountManager;
 import android.accounts.IAccountManager;
+import android.annotation.NonNull;
 import android.app.ContextImpl.ServiceInitializationState;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.IDevicePolicyManager;
@@ -67,7 +68,7 @@
 import android.hardware.SerialManager;
 import android.hardware.SystemSensorManager;
 import android.hardware.biometrics.BiometricManager;
-import android.hardware.biometrics.IBiometricService;
+import android.hardware.biometrics.IAuthService;
 import android.hardware.camera2.CameraManager;
 import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.DisplayManager;
@@ -171,8 +172,6 @@
 import android.telephony.TelephonyRegistryManager;
 import android.telephony.euicc.EuiccCardManager;
 import android.telephony.euicc.EuiccManager;
-import android.telephony.ims.ImsManager;
-import android.telephony.ims.RcsMessageManager;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.view.ContextThemeWrapper;
@@ -196,10 +195,9 @@
 import com.android.internal.net.INetworkWatchlistManager;
 import com.android.internal.os.IDropBoxManagerService;
 import com.android.internal.policy.PhoneLayoutInflater;
+import com.android.internal.util.Preconditions;
 
 import java.util.Map;
-import java.util.function.BiFunction;
-import java.util.function.Function;
 
 /**
  * Manages all of the system services that can be returned by {@link Context#getSystemService}.
@@ -218,6 +216,8 @@
             new ArrayMap<String, ServiceFetcher<?>>();
     private static int sServiceCacheSize;
 
+    private static volatile boolean sInitializing;
+
     // Not instantiable.
     private SystemServiceRegistry() { }
 
@@ -625,22 +625,6 @@
                 return new SubscriptionManager(ctx.getOuterContext());
             }});
 
-        registerService(Context.TELEPHONY_RCS_MESSAGE_SERVICE, RcsMessageManager.class,
-                new CachedServiceFetcher<RcsMessageManager>() {
-                    @Override
-                    public RcsMessageManager createService(ContextImpl ctx) {
-                        return new RcsMessageManager(ctx.getOuterContext());
-                    }
-                });
-
-        registerService(Context.TELEPHONY_IMS_SERVICE, ImsManager.class,
-                new CachedServiceFetcher<ImsManager>() {
-                    @Override
-                    public ImsManager createService(ContextImpl ctx) {
-                        return new ImsManager(ctx.getOuterContext());
-                    }
-                });
-
         registerService(Context.CARRIER_CONFIG_SERVICE, CarrierConfigManager.class,
                 new CachedServiceFetcher<CarrierConfigManager>() {
             @Override
@@ -963,9 +947,9 @@
                             throws ServiceNotFoundException {
                         if (BiometricManager.hasBiometrics(ctx)) {
                             final IBinder binder =
-                                    ServiceManager.getServiceOrThrow(Context.BIOMETRIC_SERVICE);
-                            final IBiometricService service =
-                                    IBiometricService.Stub.asInterface(binder);
+                                    ServiceManager.getServiceOrThrow(Context.AUTH_SERVICE);
+                            final IAuthService service =
+                                    IAuthService.Stub.asInterface(binder);
                             return new BiometricManager(ctx.getOuterContext(), service);
                         } else {
                             // Allow access to the manager when service is null. This saves memory
@@ -1310,14 +1294,28 @@
                     }});
         //CHECKSTYLE:ON IndentationCheck
 
-        JobSchedulerFrameworkInitializer.initialize();
-        DeviceIdleFrameworkInitializer.initialize();
+        sInitializing = true;
+        try {
+            // Note: the following functions need to be @SystemApis, once they become mainline
+            // modules.
 
-        BlobStoreManagerFrameworkInitializer.initialize();
+            JobSchedulerFrameworkInitializer.registerServiceWrappers();
+            BlobStoreManagerFrameworkInitializer.initialize();
+        } finally {
+            // If any of the above code throws, we're in a pretty bad shape and the process
+            // will likely crash, but we'll reset it just in case there's an exception handler...
+            sInitializing = false;
+        }
     }
 
+    /** Throws {@link IllegalStateException} if not during a static initialization. */
+    private static void ensureInitializing(String methodName) {
+        Preconditions.checkState(sInitializing, "Internal error: " + methodName
+                + " can only be called during class initialization.");
+    }
     /**
      * Creates an array which is used to cache per-Context service instances.
+     * @hide
      */
     public static Object[] createServiceCache() {
         return new Object[sServiceCacheSize];
@@ -1325,6 +1323,7 @@
 
     /**
      * Gets a system service from a given context.
+     * @hide
      */
     public static Object getSystemService(ContextImpl ctx, String name) {
         ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
@@ -1333,6 +1332,7 @@
 
     /**
      * Gets the name of the system-level service that is represented by the specified class.
+     * @hide
      */
     public static String getSystemServiceName(Class<?> serviceClass) {
         return SYSTEM_SERVICE_NAMES.get(serviceClass);
@@ -1342,41 +1342,204 @@
      * Statically registers a system service with the context.
      * This method must be called during static initialization only.
      */
-    private static <T> void registerService(String serviceName, Class<T> serviceClass,
-            ServiceFetcher<T> serviceFetcher) {
+    private static <T> void registerService(@NonNull String serviceName,
+            @NonNull Class<T> serviceClass, @NonNull ServiceFetcher<T> serviceFetcher) {
         SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
         SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
     }
 
     /**
-     * APEX modules will use it to register their service wrapper.
+     * Callback interface used as a parameter to {@link #registerStaticService(
+     * String, Class, StaticServiceProducerNoBinder)}, which generates a service wrapper instance
+     * that's not tied to any context and does not take a service binder object in the constructor.
+     *
+     * @param <TServiceClass> type of the service wrapper class.
      *
      * @hide
      */
-    public static <T> void registerStaticService(String serviceName, Class<T> serviceWrapperClass,
-            Function<IBinder, T> serviceFetcher) {
+    //@SystemApi TODO Make it a system API.
+    public interface StaticServiceProducerNoBinder<TServiceClass> {
+        /**
+         * Return a new service wrapper of type {@code TServiceClass}.
+         */
+        TServiceClass createService();
+    }
+
+    /**
+     * Callback interface used as a parameter to {@link #registerStaticService(
+     * String, Class, StaticServiceProducerWithBinder)}, which generates a service wrapper instance
+     * that's not tied to any context and takes a service binder object in the constructor.
+     *
+     * @param <TServiceClass> type of the service wrapper class.
+     *
+     * @hide
+     */
+    //@SystemApi TODO Make it a system API.
+    public interface StaticServiceProducerWithBinder<TServiceClass> {
+        /**
+         * Return a new service wrapper of type {@code TServiceClass} backed by a given
+         * service binder object.
+         */
+        TServiceClass createService(IBinder serviceBinder);
+    }
+
+    /**
+     * Callback interface used as a parameter to {@link #registerContextAwareService(
+     * String, Class, ContextAwareServiceProducerNoBinder)},
+     * which generates a service wrapper instance
+     * that's tied to a specific context and does not take a service binder object in the
+     * constructor.
+     *
+     * @param <TServiceClass> type of the service wrapper class.
+     *
+     * @hide
+     */
+    //@SystemApi TODO Make it a system API.
+    public interface ContextAwareServiceProducerNoBinder<TServiceClass> {
+        /**
+         * Return a new service wrapper of type {@code TServiceClass} tied to a given
+         * {@code context}.
+         *
+         * TODO Do we need to pass the "base context" too?
+         */
+        TServiceClass createService(Context context);
+    }
+
+    /**
+     * Callback interface used as a parameter to {@link #registerContextAwareService(
+     * String, Class, ContextAwareServiceProducerWithBinder)},
+     * which generates a service wrapper instance
+     * that's tied to a specific context and takes a service binder object in the constructor.
+     *
+     * @param <TServiceClass> type of the service wrapper class.
+     *
+     * @hide
+     */
+    //@SystemApi TODO Make it a system API.
+    public interface ContextAwareServiceProducerWithBinder<TServiceClass> {
+        /**
+         * Return a new service wrapper of type {@code TServiceClass} backed by a given
+         * service binder object that's tied to a given {@code context}.
+         *
+         * TODO Do we need to pass the "base context" too?
+         */
+        TServiceClass createService(Context context, IBinder serviceBinder);
+    }
+
+    /**
+     * Used by apex modules to register a "service wrapper" that is not tied to any {@link Context}.
+     *
+     * <p>This can only be called from the methods called by the static initializer of
+     * {@link SystemServiceRegistry}. (Otherwise it throws a {@link IllegalStateException}.)
+     *
+     * @param serviceName the name of the binder object, such as
+     *     {@link Context#JOB_SCHEDULER_SERVICE}.
+     * @param serviceWrapperClass the wrapper class, such as the class of
+     *     {@link android.app.job.JobScheduler}.
+     * @param serviceProducer Callback that takes the service binder object with the name
+     *     {@code serviceName} and returns an actual service wrapper instance.
+     *
+     * @hide
+     */
+    //@SystemApi TODO Make it a system API.
+    public static <TServiceClass> void registerStaticService(
+            @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass,
+            @NonNull StaticServiceProducerWithBinder<TServiceClass> serviceProducer) {
+        ensureInitializing("registerStaticService");
+        Preconditions.checkStringNotEmpty(serviceName);
+        Preconditions.checkNotNull(serviceWrapperClass);
+        Preconditions.checkNotNull(serviceProducer);
+
         registerService(serviceName, serviceWrapperClass,
-                new StaticServiceFetcher<T>() {
+                new StaticServiceFetcher<TServiceClass>() {
                     @Override
-                    public T createService() throws ServiceNotFoundException {
-                        IBinder b = ServiceManager.getServiceOrThrow(serviceName);
-                        return serviceFetcher.apply(b);
+                    public TServiceClass createService() throws ServiceNotFoundException {
+                        return serviceProducer.createService(
+                                ServiceManager.getServiceOrThrow(serviceName));
                     }});
     }
 
     /**
-     * APEX modules will use it to register their service wrapper.
+     * Similar to {@link #registerStaticService(String, Class, StaticServiceProducerWithBinder)},
+     * but used for a "service wrapper" that doesn't take a service binder in its constructor.
      *
      * @hide
      */
-    public static <T> void registerCachedService(String serviceName, Class<T> serviceWrapperClass,
-            BiFunction<Context, IBinder, T> serviceFetcher) {
+    //@SystemApi TODO Make it a system API.
+    public static <TServiceClass> void registerStaticService(
+            @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass,
+            @NonNull StaticServiceProducerNoBinder<TServiceClass> serviceProducer) {
+        ensureInitializing("registerStaticService");
+        Preconditions.checkStringNotEmpty(serviceName);
+        Preconditions.checkNotNull(serviceWrapperClass);
+        Preconditions.checkNotNull(serviceProducer);
+
         registerService(serviceName, serviceWrapperClass,
-                new CachedServiceFetcher<T>() {
+                new StaticServiceFetcher<TServiceClass>() {
                     @Override
-                    public T createService(ContextImpl ctx) throws ServiceNotFoundException {
-                        IBinder b = ServiceManager.getServiceOrThrow(serviceName);
-                        return serviceFetcher.apply(ctx.getOuterContext(), b);
+                    public TServiceClass createService() {
+                        return serviceProducer.createService();
+                    }});
+    }
+
+    /**
+     * Used by apex modules to register a "service wrapper" that is tied to a specific
+     * {@link Context}.
+     *
+     * <p>This can only be called from the methods called by the static initializer of
+     * {@link SystemServiceRegistry}. (Otherwise it throws a {@link IllegalStateException}.)
+     *
+     * @param serviceName the name of the binder object, such as
+     *     {@link Context#JOB_SCHEDULER_SERVICE}.
+     * @param serviceWrapperClass the wrapper class, such as the class of
+     *     {@link android.app.job.JobScheduler}.
+     * @param serviceProducer lambda that takes the service binder object with the name
+     *     {@code serviceName}, a {@link Context} and returns an actual service wrapper instance.
+     *
+     * @hide
+     */
+    //@SystemApi TODO Make it a system API.
+    public static <TServiceClass> void registerContextAwareService(
+            @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass,
+            @NonNull ContextAwareServiceProducerWithBinder<TServiceClass> serviceProducer) {
+        ensureInitializing("registerContextAwareService");
+        Preconditions.checkStringNotEmpty(serviceName);
+        Preconditions.checkNotNull(serviceWrapperClass);
+        Preconditions.checkNotNull(serviceProducer);
+
+        registerService(serviceName, serviceWrapperClass,
+                new CachedServiceFetcher<TServiceClass>() {
+                    @Override
+                    public TServiceClass createService(ContextImpl ctx)
+                            throws ServiceNotFoundException {
+                        return serviceProducer.createService(
+                                ctx.getOuterContext(),
+                                ServiceManager.getServiceOrThrow(serviceName));
+                    }});
+    }
+
+
+    /**
+     * Similar to {@link #registerContextAwareService(String, Class,
+     * ContextAwareServiceProducerWithBinder)},
+     * but used for a "service wrapper" that doesn't take a service binder in its constructor.
+     *
+     * @hide
+     */
+    //@SystemApi TODO Make it a system API.
+    public static <TServiceClass> void registerContextAwareService(
+            @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass,
+            @NonNull ContextAwareServiceProducerNoBinder<TServiceClass> serviceProducer) {
+        ensureInitializing("registerContextAwareService");
+        Preconditions.checkStringNotEmpty(serviceName);
+        Preconditions.checkNotNull(serviceWrapperClass);
+        Preconditions.checkNotNull(serviceProducer);
+
+        registerService(serviceName, serviceWrapperClass,
+                new CachedServiceFetcher<TServiceClass>() {
+                    @Override
+                    public TServiceClass createService(ContextImpl ctx) {
+                        return serviceProducer.createService(ctx.getOuterContext());
                     }});
     }
 
@@ -1535,6 +1698,7 @@
         public abstract T createService(Context applicationContext) throws ServiceNotFoundException;
     }
 
+    /** @hide */
     public static void onServiceNotFound(ServiceNotFoundException e) {
         // We're mostly interested in tracking down long-lived core system
         // components that might stumble if they obtain bad references; just
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 59ecf4a..41604ec 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -458,8 +458,9 @@
 
             try {
                 Bundle params = new Bundle();
-                ParcelFileDescriptor fd = mService.getWallpaper(context.getOpPackageName(),
-                        this, FLAG_SYSTEM, params, userId);
+                ParcelFileDescriptor fd = mService.getWallpaperWithFeature(
+                        context.getOpPackageName(), context.getFeatureId(), this, FLAG_SYSTEM,
+                        params, userId);
                 if (fd != null) {
                     try {
                         BitmapFactory.Options options = new BitmapFactory.Options();
@@ -985,8 +986,8 @@
         } else {
             try {
                 Bundle outParams = new Bundle();
-                return sGlobals.mService.getWallpaper(mContext.getOpPackageName(), null, which,
-                        outParams, userId);
+                return sGlobals.mService.getWallpaperWithFeature(mContext.getOpPackageName(),
+                        mContext.getFeatureId(), null, which, outParams, userId);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             } catch (SecurityException e) {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 9eff4b0..50adb7c 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -4101,9 +4101,17 @@
      * Make the device lock immediately, as if the lock screen timeout has expired at the point of
      * this call.
      * <p>
+     * This method secures the device in response to an urgent situation, such as a lost or stolen
+     * device. After this method is called, the device must be unlocked using strong authentication
+     * (PIN, pattern, or password). This API is intended for use only by device admins.
+     * <p>
      * The calling device admin must have requested {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK}
      * to be able to call this method; if it has not, a security exception will be thrown.
      * <p>
+     * If there's no lock type set, this method forces the device to go to sleep but doesn't lock
+     * the device. Device admins who find the device in this state can lock an otherwise-insecure
+     * device by first calling {@link #resetPassword} to set the password and then lock the device.
+     * <p>
      * This method can be called on the {@link DevicePolicyManager} instance returned by
      * {@link #getParentProfileInstance(ComponentName)} in order to lock the parent profile.
      * <p>
@@ -4120,9 +4128,17 @@
      * Make the device lock immediately, as if the lock screen timeout has expired at the point of
      * this call.
      * <p>
+     * This method secures the device in response to an urgent situation, such as a lost or stolen
+     * device. After this method is called, the device must be unlocked using strong authentication
+     * (PIN, pattern, or password). This API is intended for use only by device admins.
+     * <p>
      * The calling device admin must have requested {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK}
      * to be able to call this method; if it has not, a security exception will be thrown.
      * <p>
+     * If there's no lock type set, this method forces the device to go to sleep but doesn't lock
+     * the device. Device admins who find the device in this state can lock an otherwise-insecure
+     * device by first calling {@link #resetPassword} to set the password and then lock the device.
+     * <p>
      * This method can be called on the {@link DevicePolicyManager} instance returned by
      * {@link #getParentProfileInstance(ComponentName)} in order to lock the parent profile.
      *
@@ -8167,7 +8183,7 @@
      * Sets which system features are enabled when the device runs in lock task mode. This method
      * doesn't affect the features when lock task mode is inactive. Any system features not included
      * in {@code flags} are implicitly disabled when calling this method. By default, only
-     * {@link #LOCK_TASK_FEATURE_GLOBAL_ACTIONS} is enabled—all the other features are disabled. To
+     * {@link #LOCK_TASK_FEATURE_GLOBAL_ACTIONS} is enabled; all the other features are disabled. To
      * disable the global actions dialog, call this method omitting
      * {@link #LOCK_TASK_FEATURE_GLOBAL_ACTIONS}.
      *
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index c616044..19f42b6 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -173,13 +173,10 @@
      * changed.
      * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
-     *
-     * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @UnsupportedAppUsage
     public static final String ACTION_ALIAS_CHANGED =
-            "android.bluetooth.device.action.ALIAS_CHANGED";
+            "android.bluetooth.action.ALIAS_CHANGED";
 
     /**
      * Broadcast Action: Indicates a change in the bond state of a remote
@@ -1048,10 +1045,11 @@
      * Get the Bluetooth alias of the remote device.
      * <p>Alias is the locally modified name of a remote device.
      *
-     * @return the Bluetooth alias, or null if no alias or there was a problem
-     * @hide
+     * @return the Bluetooth alias, the friendly device name if no alias, or
+     * null if there was a problem
      */
-    @UnsupportedAppUsage(publicAlternatives = "Use {@link #getName()} instead.")
+    @Nullable
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
     public String getAlias() {
         final IBluetooth service = sService;
         if (service == null) {
@@ -1059,7 +1057,11 @@
             return null;
         }
         try {
-            return service.getRemoteAlias(this);
+            String alias = service.getRemoteAlias(this);
+            if (alias == null) {
+                return getName();
+            }
+            return alias;
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
         }
@@ -1076,8 +1078,9 @@
      * @return true on success, false on error
      * @hide
      */
-    @UnsupportedAppUsage
-    public boolean setAlias(String alias) {
+    @SystemApi
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    public boolean setAlias(@NonNull String alias) {
         final IBluetooth service = sService;
         if (service == null) {
             Log.e(TAG, "BT not enabled. Cannot set Remote Device name");
diff --git a/core/java/android/companion/BluetoothDeviceFilterUtils.java b/core/java/android/companion/BluetoothDeviceFilterUtils.java
index 75e726b..0f67f6b 100644
--- a/core/java/android/companion/BluetoothDeviceFilterUtils.java
+++ b/core/java/android/companion/BluetoothDeviceFilterUtils.java
@@ -129,7 +129,7 @@
 
     @UnsupportedAppUsage
     public static String getDeviceDisplayNameInternal(@NonNull BluetoothDevice device) {
-        return firstNotEmpty(device.getAliasName(), device.getAddress());
+        return firstNotEmpty(device.getAlias(), device.getAddress());
     }
 
     @UnsupportedAppUsage
diff --git a/core/java/android/content/ContentInterface.java b/core/java/android/content/ContentInterface.java
index 197de97..5988dd3 100644
--- a/core/java/android/content/ContentInterface.java
+++ b/core/java/android/content/ContentInterface.java
@@ -53,23 +53,22 @@
 
     public @Nullable Uri uncanonicalize(@NonNull Uri uri) throws RemoteException;
 
-    public boolean refresh(@NonNull Uri uri, @Nullable Bundle args,
+    public boolean refresh(@NonNull Uri uri, @Nullable Bundle extras,
             @Nullable CancellationSignal cancellationSignal) throws RemoteException;
 
     public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags)
             throws RemoteException;
 
-    public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues)
-            throws RemoteException;
+    public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues,
+            @Nullable Bundle extras) throws RemoteException;
 
     public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] initialValues)
             throws RemoteException;
 
-    public int delete(@NonNull Uri uri, @Nullable String selection,
-            @Nullable String[] selectionArgs) throws RemoteException;
+    public int delete(@NonNull Uri uri, @Nullable Bundle extras) throws RemoteException;
 
-    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection,
-            @Nullable String[] selectionArgs) throws RemoteException;
+    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable Bundle extras)
+            throws RemoteException;
 
     public @Nullable ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode,
             @Nullable CancellationSignal signal) throws RemoteException, FileNotFoundException;
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 17f1a07..2240823 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -299,7 +299,7 @@
 
         @Override
         public Uri insert(String callingPkg, @Nullable String featureId, Uri uri,
-                ContentValues initialValues) {
+                ContentValues initialValues, Bundle extras) {
             uri = validateIncomingUri(uri);
             int userId = getUserIdFromUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
@@ -317,7 +317,7 @@
             final Pair<String, String> original = setCallingPackage(
                     new Pair<>(callingPkg, featureId));
             try {
-                return maybeAddUserId(mInterface.insert(uri, initialValues), userId);
+                return maybeAddUserId(mInterface.insert(uri, initialValues, extras), userId);
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
@@ -403,8 +403,7 @@
         }
 
         @Override
-        public int delete(String callingPkg, @Nullable String featureId, Uri uri, String selection,
-                String[] selectionArgs) {
+        public int delete(String callingPkg, @Nullable String featureId, Uri uri, Bundle extras) {
             uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             if (enforceWritePermission(callingPkg, featureId, uri, null)
@@ -415,7 +414,7 @@
             final Pair<String, String> original = setCallingPackage(
                     new Pair<>(callingPkg, featureId));
             try {
-                return mInterface.delete(uri, selection, selectionArgs);
+                return mInterface.delete(uri, extras);
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
@@ -426,7 +425,7 @@
 
         @Override
         public int update(String callingPkg, @Nullable String featureId, Uri uri,
-                ContentValues values, String selection, String[] selectionArgs) {
+                ContentValues values, Bundle extras) {
             uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             if (enforceWritePermission(callingPkg, featureId, uri, null)
@@ -437,7 +436,7 @@
             final Pair<String, String> original = setCallingPackage(
                     new Pair<>(callingPkg, featureId));
             try {
-                return mInterface.update(uri, values, selection, selectionArgs);
+                return mInterface.update(uri, values, extras);
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             } finally {
@@ -593,7 +592,7 @@
         }
 
         @Override
-        public boolean refresh(String callingPkg, String featureId, Uri uri, Bundle args,
+        public boolean refresh(String callingPkg, String featureId, Uri uri, Bundle extras,
                 ICancellationSignal cancellationSignal) throws RemoteException {
             uri = validateIncomingUri(uri);
             uri = getUriWithoutUserId(uri);
@@ -605,7 +604,7 @@
             final Pair<String, String> original = setCallingPackage(
                     new Pair<>(callingPkg, featureId));
             try {
-                return mInterface.refresh(uri, args,
+                return mInterface.refresh(uri, extras,
                         CancellationSignal.fromTransport(cancellationSignal));
             } finally {
                 setCallingPackage(original);
@@ -1494,29 +1493,34 @@
     }
 
     /**
-     * Implement this to support refresh of content identified by {@code uri}. By default, this
-     * method returns false; providers who wish to implement this should return true to signal the
-     * client that the provider has tried refreshing with its own implementation.
+     * Implement this to support refresh of content identified by {@code uri}.
+     * By default, this method returns false; providers who wish to implement
+     * this should return true to signal the client that the provider has tried
+     * refreshing with its own implementation.
      * <p>
-     * This allows clients to request an explicit refresh of content identified by {@code uri}.
+     * This allows clients to request an explicit refresh of content identified
+     * by {@code uri}.
      * <p>
-     * Client code should only invoke this method when there is a strong indication (such as a user
-     * initiated pull to refresh gesture) that the content is stale.
+     * Client code should only invoke this method when there is a strong
+     * indication (such as a user initiated pull to refresh gesture) that the
+     * content is stale.
      * <p>
-     * Remember to send {@link ContentResolver#notifyChange(Uri, android.database.ContentObserver)}
+     * Remember to send
+     * {@link ContentResolver#notifyChange(Uri, android.database.ContentObserver)}
      * notifications when content changes.
      *
      * @param uri The Uri identifying the data to refresh.
-     * @param args Additional options from the client. The definitions of these are specific to the
-     *            content provider being called.
-     * @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if
-     *            none. For example, if you called refresh on a particular uri, you should call
-     *            {@link CancellationSignal#throwIfCanceled()} to check whether the client has
-     *            canceled the refresh request.
+     * @param extras Additional options from the client. The definitions of
+     *            these are specific to the content provider being called.
+     * @param cancellationSignal A signal to cancel the operation in progress,
+     *            or {@code null} if none. For example, if you called refresh on
+     *            a particular uri, you should call
+     *            {@link CancellationSignal#throwIfCanceled()} to check whether
+     *            the client has canceled the refresh request.
      * @return true if the provider actually tried refreshing.
      */
     @Override
-    public boolean refresh(Uri uri, @Nullable Bundle args,
+    public boolean refresh(Uri uri, @Nullable Bundle extras,
             @Nullable CancellationSignal cancellationSignal) {
         return false;
     }
@@ -1545,20 +1549,42 @@
     }
 
     /**
-     * Implement this to handle requests to insert a new row.
-     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
-     * after inserting.
-     * This method can be called from multiple threads, as described in
-     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
+     * Implement this to handle requests to insert a new row. As a courtesy,
+     * call
+     * {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver)
+     * notifyChange()} after inserting. This method can be called from multiple
+     * threads, as described in <a href="
+     * {@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
      * and Threads</a>.
+     *
      * @param uri The content:// URI of the insertion request.
      * @param values A set of column_name/value pairs to add to the database.
      * @return The URI for the newly inserted item.
      */
-    @Override
     public abstract @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues values);
 
     /**
+     * Implement this to handle requests to insert a new row. As a courtesy,
+     * call
+     * {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver)
+     * notifyChange()} after inserting. This method can be called from multiple
+     * threads, as described in <a href="
+     * {@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
+     * and Threads</a>.
+     *
+     * @param uri The content:// URI of the insertion request.
+     * @param values A set of column_name/value pairs to add to the database.
+     * @param extras A Bundle containing all additional information necessary
+     *            for the insert.
+     * @return The URI for the newly inserted item.
+     */
+    @Override
+    public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues values,
+            @Nullable Bundle extras) {
+        return insert(uri, values);
+    }
+
+    /**
      * Override this to handle requests to insert a set of new rows, or the
      * default implementation will iterate over the values and call
      * {@link #insert} on each of them.
@@ -1583,50 +1609,111 @@
     }
 
     /**
-     * Implement this to handle requests to delete one or more rows.
-     * The implementation should apply the selection clause when performing
+     * Implement this to handle requests to delete one or more rows. The
+     * implementation should apply the selection clause when performing
      * deletion, allowing the operation to affect multiple rows in a directory.
-     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
-     * after deleting.
-     * This method can be called from multiple threads, as described in
-     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
+     * As a courtesy, call
+     * {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver)
+     * notifyChange()} after deleting. This method can be called from multiple
+     * threads, as described in <a href="
+     * {@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
      * and Threads</a>.
+     * <p>
+     * The implementation is responsible for parsing out a row ID at the end of
+     * the URI, if a specific row is being deleted. That is, the client would
+     * pass in <code>content://contacts/people/22</code> and the implementation
+     * is responsible for parsing the record number (22) when creating a SQL
+     * statement.
      *
-     * <p>The implementation is responsible for parsing out a row ID at the end
-     * of the URI, if a specific row is being deleted. That is, the client would
-     * pass in <code>content://contacts/people/22</code> and the implementation is
-     * responsible for parsing the record number (22) when creating a SQL statement.
-     *
-     * @param uri The full URI to query, including a row ID (if a specific record is requested).
+     * @param uri The full URI to query, including a row ID (if a specific
+     *            record is requested).
      * @param selection An optional restriction to apply to rows when deleting.
      * @return The number of rows affected.
      * @throws SQLException
      */
-    @Override
     public abstract int delete(@NonNull Uri uri, @Nullable String selection,
             @Nullable String[] selectionArgs);
 
     /**
-     * Implement this to handle requests to update one or more rows.
-     * The implementation should update all rows matching the selection
-     * to set the columns according to the provided values map.
-     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
-     * after updating.
-     * This method can be called from multiple threads, as described in
-     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
+     * Implement this to handle requests to delete one or more rows. The
+     * implementation should apply the selection clause when performing
+     * deletion, allowing the operation to affect multiple rows in a directory.
+     * As a courtesy, call
+     * {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver)
+     * notifyChange()} after deleting. This method can be called from multiple
+     * threads, as described in <a href="
+     * {@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
+     * and Threads</a>.
+     * <p>
+     * The implementation is responsible for parsing out a row ID at the end of
+     * the URI, if a specific row is being deleted. That is, the client would
+     * pass in <code>content://contacts/people/22</code> and the implementation
+     * is responsible for parsing the record number (22) when creating a SQL
+     * statement.
+     *
+     * @param uri The full URI to query, including a row ID (if a specific
+     *            record is requested).
+     * @param extras A Bundle containing all additional information necessary
+     *            for the delete. Values in the Bundle may include SQL style
+     *            arguments.
+     * @return The number of rows affected.
+     * @throws SQLException
+     */
+    @Override
+    public int delete(@NonNull Uri uri, @Nullable Bundle extras) {
+        extras = (extras != null) ? extras : Bundle.EMPTY;
+        return delete(uri,
+                extras.getString(ContentResolver.QUERY_ARG_SQL_SELECTION),
+                extras.getStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS));
+    }
+
+    /**
+     * Implement this to handle requests to update one or more rows. The
+     * implementation should update all rows matching the selection to set the
+     * columns according to the provided values map. As a courtesy, call
+     * {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver)
+     * notifyChange()} after updating. This method can be called from multiple
+     * threads, as described in <a href="
+     * {@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
      * and Threads</a>.
      *
-     * @param uri The URI to query. This can potentially have a record ID if this
-     * is an update request for a specific record.
+     * @param uri The URI to query. This can potentially have a record ID if
+     *            this is an update request for a specific record.
      * @param values A set of column_name/value pairs to update in the database.
      * @param selection An optional filter to match rows to update.
      * @return the number of rows affected.
      */
-    @Override
     public abstract int update(@NonNull Uri uri, @Nullable ContentValues values,
             @Nullable String selection, @Nullable String[] selectionArgs);
 
     /**
+     * Implement this to handle requests to update one or more rows. The
+     * implementation should update all rows matching the selection to set the
+     * columns according to the provided values map. As a courtesy, call
+     * {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver)
+     * notifyChange()} after updating. This method can be called from multiple
+     * threads, as described in <a href="
+     * {@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
+     * and Threads</a>.
+     *
+     * @param uri The URI to query. This can potentially have a record ID if
+     *            this is an update request for a specific record.
+     * @param values A set of column_name/value pairs to update in the database.
+     * @param extras A Bundle containing all additional information necessary
+     *            for the update. Values in the Bundle may include SQL style
+     *            arguments.
+     * @return the number of rows affected.
+     */
+    @Override
+    public int update(@NonNull Uri uri, @Nullable ContentValues values,
+            @Nullable Bundle extras) {
+        extras = (extras != null) ? extras : Bundle.EMPTY;
+        return update(uri, values,
+                extras.getString(ContentResolver.QUERY_ARG_SQL_SELECTION),
+                extras.getStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS));
+    }
+
+    /**
      * Override this to handle requests to open a file blob.
      * The default implementation always throws {@link FileNotFoundException}.
      * This method can be called from multiple threads, as described in
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index d2632e7..bb65aa0 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -286,7 +286,7 @@
 
     /** See {@link ContentProvider#refresh} */
     @Override
-    public boolean refresh(Uri url, @Nullable Bundle args,
+    public boolean refresh(Uri url, @Nullable Bundle extras,
             @Nullable CancellationSignal cancellationSignal) throws RemoteException {
         Preconditions.checkNotNull(url, "url");
 
@@ -298,7 +298,7 @@
                 remoteCancellationSignal = mContentProvider.createCancellationSignal();
                 cancellationSignal.setRemote(remoteCancellationSignal);
             }
-            return mContentProvider.refresh(mPackageName, mFeatureId, url, args,
+            return mContentProvider.refresh(mPackageName, mFeatureId, url, extras,
                     remoteCancellationSignal);
         } catch (DeadObjectException e) {
             if (!mStable) {
@@ -331,14 +331,20 @@
     }
 
     /** See {@link ContentProvider#insert ContentProvider.insert} */
-    @Override
     public @Nullable Uri insert(@NonNull Uri url, @Nullable ContentValues initialValues)
             throws RemoteException {
+        return insert(url, initialValues, null);
+    }
+
+    /** See {@link ContentProvider#insert ContentProvider.insert} */
+    @Override
+    public @Nullable Uri insert(@NonNull Uri url, @Nullable ContentValues initialValues,
+            @Nullable Bundle extras) throws RemoteException {
         Preconditions.checkNotNull(url, "url");
 
         beforeRemote();
         try {
-            return mContentProvider.insert(mPackageName, mFeatureId, url, initialValues);
+            return mContentProvider.insert(mPackageName, mFeatureId, url, initialValues, extras);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
@@ -370,15 +376,19 @@
     }
 
     /** See {@link ContentProvider#delete ContentProvider.delete} */
-    @Override
     public int delete(@NonNull Uri url, @Nullable String selection,
             @Nullable String[] selectionArgs) throws RemoteException {
+        return delete(url, ContentResolver.createSqlQueryBundle(selection, selectionArgs));
+    }
+
+    /** See {@link ContentProvider#delete ContentProvider.delete} */
+    @Override
+    public int delete(@NonNull Uri url, @Nullable Bundle extras) throws RemoteException {
         Preconditions.checkNotNull(url, "url");
 
         beforeRemote();
         try {
-            return mContentProvider.delete(mPackageName, mFeatureId, url, selection,
-                    selectionArgs);
+            return mContentProvider.delete(mPackageName, mFeatureId, url, extras);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
@@ -390,15 +400,20 @@
     }
 
     /** See {@link ContentProvider#update ContentProvider.update} */
-    @Override
     public int update(@NonNull Uri url, @Nullable ContentValues values, @Nullable String selection,
             @Nullable String[] selectionArgs) throws RemoteException {
+        return update(url, values, ContentResolver.createSqlQueryBundle(selection, selectionArgs));
+    }
+
+    /** See {@link ContentProvider#update ContentProvider.update} */
+    @Override
+    public int update(@NonNull Uri url, @Nullable ContentValues values, @Nullable Bundle extras)
+            throws RemoteException {
         Preconditions.checkNotNull(url, "url");
 
         beforeRemote();
         try {
-            return mContentProvider.update(mPackageName, mFeatureId, url, values, selection,
-                    selectionArgs);
+            return mContentProvider.update(mPackageName, mFeatureId, url, values, extras);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index f082690..dfa71f8 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -153,8 +153,9 @@
                     String featureId = data.readString();
                     Uri url = Uri.CREATOR.createFromParcel(data);
                     ContentValues values = ContentValues.CREATOR.createFromParcel(data);
+                    Bundle extras = data.readBundle();
 
-                    Uri out = insert(callingPkg, featureId, url, values);
+                    Uri out = insert(callingPkg, featureId, url, values, extras);
                     reply.writeNoException();
                     Uri.writeToParcel(reply, out);
                     return true;
@@ -199,10 +200,9 @@
                     String callingPkg = data.readString();
                     String featureId = data.readString();
                     Uri url = Uri.CREATOR.createFromParcel(data);
-                    String selection = data.readString();
-                    String[] selectionArgs = data.readStringArray();
+                    Bundle extras = data.readBundle();
 
-                    int count = delete(callingPkg, featureId, url, selection, selectionArgs);
+                    int count = delete(callingPkg, featureId, url, extras);
 
                     reply.writeNoException();
                     reply.writeInt(count);
@@ -216,11 +216,9 @@
                     String featureId = data.readString();
                     Uri url = Uri.CREATOR.createFromParcel(data);
                     ContentValues values = ContentValues.CREATOR.createFromParcel(data);
-                    String selection = data.readString();
-                    String[] selectionArgs = data.readStringArray();
+                    Bundle extras = data.readBundle();
 
-                    int count = update(callingPkg, featureId, url, values, selection,
-                            selectionArgs);
+                    int count = update(callingPkg, featureId, url, values, extras);
 
                     reply.writeNoException();
                     reply.writeInt(count);
@@ -283,10 +281,10 @@
                     String authority = data.readString();
                     String method = data.readString();
                     String stringArg = data.readString();
-                    Bundle args = data.readBundle();
+                    Bundle extras = data.readBundle();
 
                     Bundle responseBundle = call(callingPkg, featureId, authority, method,
-                            stringArg, args);
+                            stringArg, extras);
 
                     reply.writeNoException();
                     reply.writeBundle(responseBundle);
@@ -370,11 +368,11 @@
                     String callingPkg = data.readString();
                     String featureId = data.readString();
                     Uri url = Uri.CREATOR.createFromParcel(data);
-                    Bundle args = data.readBundle();
+                    Bundle extras = data.readBundle();
                     ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
                             data.readStrongBinder());
 
-                    boolean out = refresh(callingPkg, featureId, url, args, signal);
+                    boolean out = refresh(callingPkg, featureId, url, extras, signal);
                     reply.writeNoException();
                     reply.writeInt(out ? 0 : -1);
                     return true;
@@ -498,7 +496,7 @@
 
     @Override
     public Uri insert(String callingPkg, @Nullable String featureId, Uri url,
-            ContentValues values) throws RemoteException
+            ContentValues values, Bundle extras) throws RemoteException
     {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -509,6 +507,7 @@
             data.writeString(featureId);
             url.writeToParcel(data, 0);
             values.writeToParcel(data, 0);
+            data.writeBundle(extras);
 
             mRemote.transact(IContentProvider.INSERT_TRANSACTION, data, reply, 0);
 
@@ -573,8 +572,8 @@
     }
 
     @Override
-    public int delete(String callingPkg, @Nullable String featureId, Uri url, String selection,
-            String[] selectionArgs) throws RemoteException {
+    public int delete(String callingPkg, @Nullable String featureId, Uri url, Bundle extras)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
@@ -583,8 +582,7 @@
             data.writeString(callingPkg);
             data.writeString(featureId);
             url.writeToParcel(data, 0);
-            data.writeString(selection);
-            data.writeStringArray(selectionArgs);
+            data.writeBundle(extras);
 
             mRemote.transact(IContentProvider.DELETE_TRANSACTION, data, reply, 0);
 
@@ -599,7 +597,7 @@
 
     @Override
     public int update(String callingPkg, @Nullable String featureId, Uri url,
-            ContentValues values, String selection, String[] selectionArgs) throws RemoteException {
+            ContentValues values, Bundle extras) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
@@ -609,8 +607,7 @@
             data.writeString(featureId);
             url.writeToParcel(data, 0);
             values.writeToParcel(data, 0);
-            data.writeString(selection);
-            data.writeStringArray(selectionArgs);
+            data.writeBundle(extras);
 
             mRemote.transact(IContentProvider.UPDATE_TRANSACTION, data, reply, 0);
 
@@ -682,7 +679,7 @@
 
     @Override
     public Bundle call(String callingPkg, @Nullable String featureId, String authority,
-            String method, String request, Bundle args) throws RemoteException {
+            String method, String request, Bundle extras) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
@@ -693,7 +690,7 @@
             data.writeString(authority);
             data.writeString(method);
             data.writeString(request);
-            data.writeBundle(args);
+            data.writeBundle(extras);
 
             mRemote.transact(IContentProvider.CALL_TRANSACTION, data, reply, 0);
 
@@ -824,7 +821,7 @@
     }
 
     @Override
-    public boolean refresh(String callingPkg, @Nullable String featureId, Uri url, Bundle args,
+    public boolean refresh(String callingPkg, @Nullable String featureId, Uri url, Bundle extras,
             ICancellationSignal signal) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -834,7 +831,7 @@
             data.writeString(callingPkg);
             data.writeString(featureId);
             url.writeToParcel(data, 0);
-            data.writeBundle(args);
+            data.writeBundle(extras);
             data.writeStrongBinder(signal != null ? signal.asBinder() : null);
 
             mRemote.transact(IContentProvider.REFRESH_TRANSACTION, data, reply, 0);
diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java
index 5c2de57..93f4287 100644
--- a/core/java/android/content/ContentProviderOperation.java
+++ b/core/java/android/content/ContentProviderOperation.java
@@ -357,11 +357,22 @@
             ContentProviderResult[] backRefs, int numBackRefs)
             throws OperationApplicationException {
         final ContentValues values = resolveValueBackReferences(backRefs, numBackRefs);
-        final Bundle extras = resolveExtrasBackReferences(backRefs, numBackRefs);
-        final String[] selectionArgs = resolveSelectionArgsBackReferences(backRefs, numBackRefs);
+
+        // If the creator requested explicit selection or selectionArgs, it
+        // should take precedence over similar values they defined in extras
+        Bundle extras = resolveExtrasBackReferences(backRefs, numBackRefs);
+        if (mSelection != null) {
+            extras = (extras != null) ? extras : new Bundle();
+            extras.putString(ContentResolver.QUERY_ARG_SQL_SELECTION, mSelection);
+        }
+        if (mSelectionArgs != null) {
+            extras = (extras != null) ? extras : new Bundle();
+            extras.putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS,
+                    resolveSelectionArgsBackReferences(backRefs, numBackRefs));
+        }
 
         if (mType == TYPE_INSERT) {
-            final Uri newUri = provider.insert(mUri, values);
+            final Uri newUri = provider.insert(mUri, values, extras);
             if (newUri != null) {
                 return new ContentProviderResult(newUri);
             } else {
@@ -375,9 +386,9 @@
 
         final int numRows;
         if (mType == TYPE_DELETE) {
-            numRows = provider.delete(mUri, mSelection, selectionArgs);
+            numRows = provider.delete(mUri, extras);
         } else if (mType == TYPE_UPDATE) {
-            numRows = provider.update(mUri, values, mSelection, selectionArgs);
+            numRows = provider.update(mUri, values, extras);
         } else if (mType == TYPE_ASSERT) {
             // Assert that all rows match expected values
             String[] projection =  null;
@@ -389,7 +400,7 @@
                 }
                 projection = projectionList.toArray(new String[projectionList.size()]);
             }
-            final Cursor cursor = provider.query(mUri, projection, mSelection, selectionArgs, null);
+            final Cursor cursor = provider.query(mUri, projection, extras, null);
             try {
                 numRows = cursor.getCount();
                 if (projection != null) {
@@ -1013,6 +1024,10 @@
 
         private void assertExtrasAllowed() {
             switch (mType) {
+                case TYPE_INSERT:
+                case TYPE_UPDATE:
+                case TYPE_DELETE:
+                case TYPE_ASSERT:
                 case TYPE_CALL:
                     break;
                 default:
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 61c8db5d..d4280f8 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -304,31 +304,61 @@
      */
     public static final String QUERY_ARG_SQL_SORT_ORDER = "android:query-arg-sql-sort-order";
 
-    /** {@hide} */
+    /**
+     * Key for an SQL style {@code GROUP BY} string that may be present in the
+     * query Bundle argument passed to
+     * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)}.
+     *
+     * <p><b>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher are strongly
+     * encourage to use structured query arguments in lieu of opaque SQL query clauses.</b>
+     *
+     * @see #QUERY_ARG_GROUP_COLUMNS
+     */
     public static final String QUERY_ARG_SQL_GROUP_BY = "android:query-arg-sql-group-by";
-    /** {@hide} */
+
+    /**
+     * Key for an SQL style {@code HAVING} string that may be present in the
+     * query Bundle argument passed to
+     * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)}.
+     *
+     * <p><b>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher are strongly
+     * encourage to use structured query arguments in lieu of opaque SQL query clauses.</b>
+     */
     public static final String QUERY_ARG_SQL_HAVING = "android:query-arg-sql-having";
-    /** {@hide} */
+
+    /**
+     * Key for an SQL style {@code LIMIT} string that may be present in the
+     * query Bundle argument passed to
+     * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)}.
+     *
+     * <p><b>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher are strongly
+     * encourage to use structured query arguments in lieu of opaque SQL query clauses.</b>
+     *
+     * @see #QUERY_ARG_LIMIT
+     * @see #QUERY_ARG_OFFSET
+     */
     public static final String QUERY_ARG_SQL_LIMIT = "android:query-arg-sql-limit";
 
     /**
-     * Specifies the list of columns against which to sort results. When first column values
-     * are identical, records are then sorted based on second column values, and so on.
-     *
-     * <p>Columns present in this list must also be included in the projection
-     * supplied to {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}.
-     *
-     * <p>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher:
-     *
+     * Specifies the list of columns (stored as a {@code String[]}) against
+     * which to sort results. When first column values are identical, records
+     * are then sorted based on second column values, and so on.
+     * <p>
+     * Columns present in this list must also be included in the projection
+     * supplied to
+     * {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}.
+     * <p>
+     * Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher:
      * <li>{@link ContentProvider} implementations: When preparing data in
-     * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)}, if sort columns
-     * is reflected in the returned Cursor, it is  strongly recommended that
-     * {@link #QUERY_ARG_SORT_COLUMNS} then be included in the array of honored arguments
-     * reflected in {@link Cursor} extras {@link Bundle} under {@link #EXTRA_HONORED_ARGS}.
-     *
-     * <li>When querying a provider, where no QUERY_ARG_SQL* otherwise exists in the
-     * arguments {@link Bundle}, the Content framework will attempt to synthesize
-     * an QUERY_ARG_SQL* argument using the corresponding QUERY_ARG_SORT* values.
+     * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)},
+     * if sort columns is reflected in the returned Cursor, it is strongly
+     * recommended that {@link #QUERY_ARG_SORT_COLUMNS} then be included in the
+     * array of honored arguments reflected in {@link Cursor} extras
+     * {@link Bundle} under {@link #EXTRA_HONORED_ARGS}.
+     * <li>When querying a provider, where no QUERY_ARG_SQL* otherwise exists in
+     * the arguments {@link Bundle}, the Content framework will attempt to
+     * synthesize an QUERY_ARG_SQL* argument using the corresponding
+     * QUERY_ARG_SORT* values.
      */
     public static final String QUERY_ARG_SORT_COLUMNS = "android:query-arg-sort-columns";
 
@@ -402,6 +432,29 @@
     public static final String QUERY_ARG_SORT_LOCALE = "android:query-arg-sort-locale";
 
     /**
+     * Specifies the list of columns (stored as a {@code String[]}) against
+     * which to group results. When column values are identical, multiple
+     * records are collapsed together into a single record.
+     * <p>
+     * Columns present in this list must also be included in the projection
+     * supplied to
+     * {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}.
+     * <p>
+     * Apps targeting {@link android.os.Build.VERSION_CODES#R} or higher:
+     * <li>{@link ContentProvider} implementations: When preparing data in
+     * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)},
+     * if group columns is reflected in the returned Cursor, it is strongly
+     * recommended that {@link #QUERY_ARG_SORT_COLUMNS} then be included in the
+     * array of honored arguments reflected in {@link Cursor} extras
+     * {@link Bundle} under {@link #EXTRA_HONORED_ARGS}.
+     * <li>When querying a provider, where no QUERY_ARG_SQL* otherwise exists in
+     * the arguments {@link Bundle}, the Content framework will attempt to
+     * synthesize an QUERY_ARG_SQL* argument using the corresponding
+     * QUERY_ARG_SORT* values.
+     */
+    public static final String QUERY_ARG_GROUP_COLUMNS = "android:query-arg-group-columns";
+
+    /**
      * Allows provider to report back to client which query keys are honored in a Cursor.
      *
      * <p>Key identifying a {@code String[]} containing all QUERY_ARG_SORT* arguments
@@ -415,6 +468,7 @@
      * @see #QUERY_ARG_SORT_DIRECTION
      * @see #QUERY_ARG_SORT_COLLATION
      * @see #QUERY_ARG_SORT_LOCALE
+     * @see #QUERY_ARG_GROUP_COLUMNS
      */
     public static final String EXTRA_HONORED_ARGS = "android.content.extra.HONORED_ARGS";
 
@@ -1127,28 +1181,31 @@
     }
 
     /**
-     * This allows clients to request an explicit refresh of content identified by {@code uri}.
+     * This allows clients to request an explicit refresh of content identified
+     * by {@code uri}.
      * <p>
-     * Client code should only invoke this method when there is a strong indication (such as a user
-     * initiated pull to refresh gesture) that the content is stale.
+     * Client code should only invoke this method when there is a strong
+     * indication (such as a user initiated pull to refresh gesture) that the
+     * content is stale.
      * <p>
      *
      * @param url The Uri identifying the data to refresh.
-     * @param args Additional options from the client. The definitions of these are specific to the
-     *            content provider being called.
-     * @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if
-     *            none. For example, if you called refresh on a particular uri, you should call
-     *            {@link CancellationSignal#throwIfCanceled()} to check whether the client has
-     *            canceled the refresh request.
+     * @param extras Additional options from the client. The definitions of
+     *            these are specific to the content provider being called.
+     * @param cancellationSignal A signal to cancel the operation in progress,
+     *            or {@code null} if none. For example, if you called refresh on
+     *            a particular uri, you should call
+     *            {@link CancellationSignal#throwIfCanceled()} to check whether
+     *            the client has canceled the refresh request.
      * @return true if the provider actually tried refreshing.
      */
     @Override
-    public final boolean refresh(@NonNull Uri url, @Nullable Bundle args,
+    public final boolean refresh(@NonNull Uri url, @Nullable Bundle extras,
             @Nullable CancellationSignal cancellationSignal) {
         Preconditions.checkNotNull(url, "url");
 
         try {
-            if (mWrapped != null) return mWrapped.refresh(url, args, cancellationSignal);
+            if (mWrapped != null) return mWrapped.refresh(url, extras, cancellationSignal);
         } catch (RemoteException e) {
             return false;
         }
@@ -1165,7 +1222,7 @@
                 remoteCancellationSignal = provider.createCancellationSignal();
                 cancellationSignal.setRemote(remoteCancellationSignal);
             }
-            return provider.refresh(mPackageName, mFeatureId, url, args,
+            return provider.refresh(mPackageName, mFeatureId, url, extras,
                     remoteCancellationSignal);
         } catch (RemoteException e) {
             // Arbitrary and not worth documenting, as Activity
@@ -1856,13 +1913,30 @@
      * @return the URL of the newly created row. May return <code>null</code> if the underlying
      *         content provider returns <code>null</code>, or if it crashes.
      */
-    @Override
     public final @Nullable Uri insert(@RequiresPermission.Write @NonNull Uri url,
                 @Nullable ContentValues values) {
+        return insert(url, values, null);
+    }
+
+    /**
+     * Inserts a row into a table at the given URL.
+     *
+     * If the content provider supports transactions the insertion will be atomic.
+     *
+     * @param url The URL of the table to insert into.
+     * @param values The initial values for the newly inserted row. The key is the column name for
+     *               the field. Passing an empty ContentValues will create an empty row.
+     * @param extras A Bundle containing all additional information necessary for the insert.
+     * @return the URL of the newly created row. May return <code>null</code> if the underlying
+     *         content provider returns <code>null</code>, or if it crashes.
+     */
+    @Override
+    public final @Nullable Uri insert(@RequiresPermission.Write @NonNull Uri url,
+            @Nullable ContentValues values, @Nullable Bundle extras) {
         Preconditions.checkNotNull(url, "url");
 
         try {
-            if (mWrapped != null) return mWrapped.insert(url, values);
+            if (mWrapped != null) return mWrapped.insert(url, values, extras);
         } catch (RemoteException e) {
             return null;
         }
@@ -1873,7 +1947,7 @@
         }
         try {
             long startTime = SystemClock.uptimeMillis();
-            Uri createdRow = provider.insert(mPackageName, mFeatureId, url, values);
+            Uri createdRow = provider.insert(mPackageName, mFeatureId, url, values, extras);
             long durationMillis = SystemClock.uptimeMillis() - startTime;
             maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */);
             return createdRow;
@@ -1977,13 +2051,27 @@
                     (excluding the WHERE itself).
      * @return The number of rows deleted.
      */
-    @Override
     public final int delete(@RequiresPermission.Write @NonNull Uri url, @Nullable String where,
             @Nullable String[] selectionArgs) {
+        return delete(url, createSqlQueryBundle(where, selectionArgs));
+    }
+
+    /**
+     * Deletes row(s) specified by a content URI.
+     *
+     * If the content provider supports transactions, the deletion will be atomic.
+     *
+     * @param url The URL of the row to delete.
+     * @param extras A Bundle containing all additional information necessary for the delete.
+     *            Values in the Bundle may include SQL style arguments.
+     * @return The number of rows deleted.
+     */
+    @Override
+    public final int delete(@RequiresPermission.Write @NonNull Uri url, @Nullable Bundle extras) {
         Preconditions.checkNotNull(url, "url");
 
         try {
-            if (mWrapped != null) return mWrapped.delete(url, where, selectionArgs);
+            if (mWrapped != null) return mWrapped.delete(url, extras);
         } catch (RemoteException e) {
             return 0;
         }
@@ -1994,10 +2082,9 @@
         }
         try {
             long startTime = SystemClock.uptimeMillis();
-            int rowsDeleted = provider.delete(mPackageName, mFeatureId, url, where,
-                    selectionArgs);
+            int rowsDeleted = provider.delete(mPackageName, mFeatureId, url, extras);
             long durationMillis = SystemClock.uptimeMillis() - startTime;
-            maybeLogUpdateToEventLog(durationMillis, url, "delete", where);
+            maybeLogUpdateToEventLog(durationMillis, url, "delete", null);
             return rowsDeleted;
         } catch (RemoteException e) {
             // Arbitrary and not worth documenting, as Activity
@@ -2021,14 +2108,32 @@
      * @return the number of rows updated.
      * @throws NullPointerException if uri or values are null
      */
-    @Override
     public final int update(@RequiresPermission.Write @NonNull Uri uri,
             @Nullable ContentValues values, @Nullable String where,
             @Nullable String[] selectionArgs) {
+        return update(uri, values, createSqlQueryBundle(where, selectionArgs));
+    }
+
+    /**
+     * Update row(s) in a content URI.
+     *
+     * If the content provider supports transactions the update will be atomic.
+     *
+     * @param uri The URI to modify.
+     * @param values The new field values. The key is the column name for the field.
+                     A null value will remove an existing field value.
+     * @param extras A Bundle containing all additional information necessary for the update.
+     *            Values in the Bundle may include SQL style arguments.
+     * @return the number of rows updated.
+     * @throws NullPointerException if uri or values are null
+     */
+    @Override
+    public final int update(@RequiresPermission.Write @NonNull Uri uri,
+            @Nullable ContentValues values, @Nullable Bundle extras) {
         Preconditions.checkNotNull(uri, "uri");
 
         try {
-            if (mWrapped != null) return mWrapped.update(uri, values, where, selectionArgs);
+            if (mWrapped != null) return mWrapped.update(uri, values, extras);
         } catch (RemoteException e) {
             return 0;
         }
@@ -2039,10 +2144,9 @@
         }
         try {
             long startTime = SystemClock.uptimeMillis();
-            int rowsUpdated = provider.update(mPackageName, mFeatureId, uri, values, where,
-                    selectionArgs);
+            int rowsUpdated = provider.update(mPackageName, mFeatureId, uri, values, extras);
             long durationMillis = SystemClock.uptimeMillis() - startTime;
-            maybeLogUpdateToEventLog(durationMillis, uri, "update", where);
+            maybeLogUpdateToEventLog(durationMillis, uri, "update", null);
             return rowsUpdated;
         } catch (RemoteException e) {
             // Arbitrary and not worth documenting, as Activity
@@ -3589,6 +3693,15 @@
      */
     public static @Nullable Bundle createSqlQueryBundle(
             @Nullable String selection,
+            @Nullable String[] selectionArgs) {
+        return createSqlQueryBundle(selection, selectionArgs, null);
+    }
+
+    /**
+     * @hide
+     */
+    public static @Nullable Bundle createSqlQueryBundle(
+            @Nullable String selection,
             @Nullable String[] selectionArgs,
             @Nullable String sortOrder) {
 
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 03b4913..392353a 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3289,6 +3289,7 @@
             WIFI_RTT_RANGING_SERVICE,
             NSD_SERVICE,
             AUDIO_SERVICE,
+            AUTH_SERVICE,
             FINGERPRINT_SERVICE,
             //@hide: FACE_SERVICE,
             BIOMETRIC_SERVICE,
@@ -4007,6 +4008,31 @@
     public static final String AUDIO_SERVICE = "audio";
 
     /**
+     * AuthService orchestrates biometric and PIN/pattern/password authentication.
+     *
+     * BiometricService was split into two services, AuthService and BiometricService, where
+     * AuthService is the high level service that orchestrates all types of authentication, and
+     * BiometricService is a lower layer responsible only for biometric authentication.
+     *
+     * Ideally we should have renamed BiometricManager to AuthManager, because it logically
+     * corresponds to AuthService. However, because BiometricManager is a public API, we kept
+     * the old name but changed the internal implementation to use AuthService.
+     *
+     * As of now, the AUTH_SERVICE constant is only used to identify the service in
+     * SystemServiceRegistry and SELinux. To obtain the manager for AUTH_SERVICE, one should use
+     * BIOMETRIC_SERVICE with {@link #getSystemService(String)} to retrieve a
+     * {@link android.hardware.biometrics.BiometricManager}
+     *
+     * Map of the two services and their managers:
+     * [Service]            [Manager]
+     * AuthService          BiometricManager
+     * BiometricService     N/A
+     *
+     * @hide
+     */
+    public static final String AUTH_SERVICE = "auth";
+
+    /**
      * Use with {@link #getSystemService(String)} to retrieve a
      * {@link android.hardware.fingerprint.FingerprintManager} for handling management
      * of fingerprints.
@@ -4040,8 +4066,8 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve a
-     * {@link android.hardware.biometrics.BiometricManager} for handling management
-     * of face authentication.
+     * {@link android.hardware.biometrics.BiometricManager} for handling
+     * biometric and PIN/pattern/password authentication.
      *
      * @see #getSystemService
      * @see android.hardware.biometrics.BiometricManager
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
index d2c97c4..1fb2958 100644
--- a/core/java/android/content/IContentProvider.java
+++ b/core/java/android/content/IContentProvider.java
@@ -48,10 +48,10 @@
             + "instead")
     public default Uri insert(String callingPkg, Uri url, ContentValues initialValues)
             throws RemoteException {
-        return insert(callingPkg, null, url, initialValues);
+        return insert(callingPkg, null, url, initialValues, null);
     }
-    public Uri insert(String callingPkg, String featureId, Uri url, ContentValues initialValues)
-            throws RemoteException;
+    public Uri insert(String callingPkg, String featureId, Uri url, ContentValues initialValues,
+            Bundle extras) throws RemoteException;
     @Deprecated
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
             + "ContentProviderClient#bulkInsert(android.net.Uri, android.content.ContentValues[])"
@@ -68,20 +68,22 @@
             + ".String[])} instead")
     public default int delete(String callingPkg, Uri url, String selection, String[] selectionArgs)
             throws RemoteException {
-        return delete(callingPkg, null, url, selection, selectionArgs);
+        return delete(callingPkg, null, url,
+                ContentResolver.createSqlQueryBundle(selection, selectionArgs));
     }
-    public int delete(String callingPkg, String featureId, Uri url, String selection,
-            String[] selectionArgs) throws RemoteException;
+    public int delete(String callingPkg, String featureId, Uri url, Bundle extras)
+            throws RemoteException;
     @Deprecated
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
             + "ContentProviderClient#update(android.net.Uri, android.content.ContentValues, java"
             + ".lang.String, java.lang.String[])} instead")
     public default int update(String callingPkg, Uri url, ContentValues values, String selection,
             String[] selectionArgs) throws RemoteException {
-        return update(callingPkg, null, url, values, selection, selectionArgs);
+        return update(callingPkg, null, url, values,
+                ContentResolver.createSqlQueryBundle(selection, selectionArgs));
     }
     public int update(String callingPkg, String featureId, Uri url, ContentValues values,
-            String selection, String[] selectionArgs) throws RemoteException;
+            Bundle extras) throws RemoteException;
 
     public ParcelFileDescriptor openFile(String callingPkg, @Nullable String featureId, Uri url,
             String mode, ICancellationSignal signal, IBinder callerToken)
@@ -119,7 +121,7 @@
             throws RemoteException;
 
     public boolean refresh(String callingPkg, @Nullable String featureId, Uri url,
-            @Nullable Bundle args, ICancellationSignal cancellationSignal) throws RemoteException;
+            @Nullable Bundle extras, ICancellationSignal cancellationSignal) throws RemoteException;
 
     // Data interchange.
     public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException;
diff --git a/core/java/android/content/LoggingContentInterface.java b/core/java/android/content/LoggingContentInterface.java
index 1df1c4f..3bd0832 100644
--- a/core/java/android/content/LoggingContentInterface.java
+++ b/core/java/android/content/LoggingContentInterface.java
@@ -178,11 +178,11 @@
     }
 
     @Override
-    public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues)
-            throws RemoteException {
-        try (Logger l = new Logger("insert", uri, initialValues)) {
+    public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues,
+            @Nullable Bundle extras) throws RemoteException {
+        try (Logger l = new Logger("insert", uri, initialValues, extras)) {
             try {
-                return l.setResult(delegate.insert(uri, initialValues));
+                return l.setResult(delegate.insert(uri, initialValues, extras));
             } catch (Exception res) {
                 l.setResult(res);
                 throw res;
@@ -204,11 +204,10 @@
     }
 
     @Override
-    public int delete(@NonNull Uri uri, @Nullable String selection,
-            @Nullable String[] selectionArgs) throws RemoteException {
-        try (Logger l = new Logger("delete", uri, selection, selectionArgs)) {
+    public int delete(@NonNull Uri uri, @Nullable Bundle extras) throws RemoteException {
+        try (Logger l = new Logger("delete", uri, extras)) {
             try {
-                return l.setResult(delegate.delete(uri, selection, selectionArgs));
+                return l.setResult(delegate.delete(uri, extras));
             } catch (Exception res) {
                 l.setResult(res);
                 throw res;
@@ -217,11 +216,11 @@
     }
 
     @Override
-    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection,
-            @Nullable String[] selectionArgs) throws RemoteException {
-        try (Logger l = new Logger("update", uri, values, selection, selectionArgs)) {
+    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable Bundle extras)
+            throws RemoteException {
+        try (Logger l = new Logger("update", uri, values, extras)) {
             try {
-                return l.setResult(delegate.update(uri, values, selection, selectionArgs));
+                return l.setResult(delegate.update(uri, values, extras));
             } catch (Exception res) {
                 l.setResult(res);
                 throw res;
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 1e88ce7..5fb17ee 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -17,6 +17,7 @@
 package android.content.pm;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.UnsupportedAppUsage;
 import android.annotation.UserIdInt;
 import android.os.Parcel;
@@ -25,6 +26,8 @@
 import android.os.UserManager;
 import android.util.DebugUtils;
 
+import com.android.server.pm.UserTypeDetails;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -32,13 +35,13 @@
  * Per-user information.
  *
  * <p>There are 3 base properties of users: {@link #FLAG_SYSTEM}, {@link #FLAG_FULL}, and
- * {@link #FLAG_MANAGED_PROFILE}. Every user must have one of the following combination of these
+ * {@link #FLAG_PROFILE}. Every user must have one of the following combination of these
  * flags:
  * <ul>
  *    <li>FLAG_SYSTEM (user {@link UserHandle#USER_SYSTEM} on a headless-user-0 device)</li>
  *    <li>FLAG_SYSTEM and FLAG_FULL (user {@link UserHandle#USER_SYSTEM} on a regular device)</li>
  *    <li>FLAG_FULL (non-profile secondary user)</li>
- *    <li>FLAG_MANAGED_PROFILE (profile users)</li>
+ *    <li>FLAG_PROFILE (profile users)</li>
  * </ul>
  * Users can have also have additional flags (such as FLAG_GUEST) as appropriate.
  *
@@ -46,9 +49,6 @@
  */
 public class UserInfo implements Parcelable {
 
-    /** 16 bits for user type */
-    public static final int FLAG_MASK_USER_TYPE = 0x0000FFFF;
-
     /**
      * *************************** NOTE ***************************
      * These flag values CAN NOT CHANGE because they are written
@@ -70,13 +70,17 @@
 
     /**
      * Indicates a guest user that may be transient.
+     * @deprecated Use {@link UserManager#USER_TYPE_FULL_GUEST} instead.
      */
+    @Deprecated
     public static final int FLAG_GUEST   = 0x00000004;
 
     /**
      * Indicates the user has restrictions in privileges, in addition to those for normal users.
      * Exact meaning TBD. For instance, maybe they can't install apps or administer WiFi access pts.
+     * @deprecated Use {@link UserManager#USER_TYPE_FULL_RESTRICTED} instead.
      */
+    @Deprecated
     public static final int FLAG_RESTRICTED = 0x00000008;
 
     /**
@@ -87,7 +91,9 @@
     /**
      * Indicates that this user is a profile of another user, for example holding a users
      * corporate data.
+     * @deprecated Use {@link UserManager#USER_TYPE_PROFILE_MANAGED} instead.
      */
+    @Deprecated
     public static final int FLAG_MANAGED_PROFILE = 0x00000020;
 
     /**
@@ -108,14 +114,16 @@
 
     /**
      * User is for demo purposes only and can be removed at any time.
+     * @deprecated Use {@link UserManager#USER_TYPE_FULL_DEMO} instead.
      */
+    @Deprecated
     public static final int FLAG_DEMO = 0x00000200;
 
     /**
      * Indicates that this user is a non-profile human user.
      *
      * <p>When creating a new (non-system) user, this flag will always be forced true unless the
-     * user is a {@link #FLAG_MANAGED_PROFILE}. If user {@link UserHandle#USER_SYSTEM} is also a
+     * user is a {@link #FLAG_PROFILE}. If user {@link UserHandle#USER_SYSTEM} is also a
      * human user, it must also be flagged as FULL.
      */
     public static final int FLAG_FULL = 0x00000400;
@@ -126,11 +134,10 @@
     public static final int FLAG_SYSTEM = 0x00000800;
 
     /**
-     * Indicates that this user is some sort of profile. Right now, the only profile type is
-     * {@link #FLAG_MANAGED_PROFILE}, but this can include other types of profiles too if any
-     * are created in the future. This is therefore not a flag, but an OR of several flags.
+     * Indicates that this user is a profile human user, such as a managed profile.
+     * Mutually exclusive with {@link #FLAG_FULL}.
      */
-    public static final int PROFILE_FLAGS_MASK = FLAG_MANAGED_PROFILE;
+    public static final int FLAG_PROFILE = 0x00001000;
 
     /**
      * @hide
@@ -147,7 +154,8 @@
             FLAG_EPHEMERAL,
             FLAG_DEMO,
             FLAG_FULL,
-            FLAG_SYSTEM
+            FLAG_SYSTEM,
+            FLAG_PROFILE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface UserInfoFlag {
@@ -170,6 +178,13 @@
     @UnsupportedAppUsage
     public long lastLoggedInTime;
     public String lastLoggedInFingerprint;
+
+    /**
+     * Type of user, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}, corresponding to
+     * {@link UserTypeDetails#getName()}.
+     */
+    public String userType;
+
     /**
      * If this user is a parent user, it would be its own user id.
      * If this user is a child user, it would be its parent user id.
@@ -178,7 +193,12 @@
     @UnsupportedAppUsage
     public int profileGroupId;
     public int restrictedProfileParentId;
-    /** Which profile badge color/label to use. */
+
+    /**
+     * Which badge color/label to use within a particular {@link UserTypeDetails}, i.e.
+     * the badgeIndex.
+     * This is an index for distinguishing different profiles with the same parent and user type.
+     */
     public int profileBadge;
 
     /** User is only partially created. */
@@ -199,21 +219,68 @@
      */
     public boolean preCreated;
 
+    /**
+     * Creates a UserInfo whose user type is determined automatically by the flags according to
+     * {@link #getDefaultUserType}; can only be used for user types handled there.
+     */
     @UnsupportedAppUsage
     public UserInfo(int id, String name, int flags) {
         this(id, name, null, flags);
     }
 
+    /**
+     * Creates a UserInfo whose user type is determined automatically by the flags according to
+     * {@link #getDefaultUserType}; can only be used for user types handled there.
+     */
     @UnsupportedAppUsage
     public UserInfo(int id, String name, String iconPath, int flags) {
+        this(id, name, iconPath, flags, getDefaultUserType(flags));
+    }
+
+    public UserInfo(int id, String name, String iconPath, int flags, String userType) {
         this.id = id;
         this.name = name;
         this.flags = flags;
+        this.userType = userType;
         this.iconPath = iconPath;
         this.profileGroupId = NO_PROFILE_GROUP_ID;
         this.restrictedProfileParentId = NO_PROFILE_GROUP_ID;
     }
 
+    /**
+     * Get the user type (such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}) that corresponds to
+     * the given {@link UserInfoFlag}s.
+
+     * <p>The userInfoFlag can contain GUEST, RESTRICTED, MANAGED_PROFILE, DEMO, or else be
+     * interpreted as a regular "secondary" user. It cannot contain more than one of these.
+     * It can contain other UserInfoFlag properties (like EPHEMERAL), which will be ignored here.
+     *
+     * @throws IllegalArgumentException if userInfoFlag is more than one type of user or if it
+     *                                  is a SYSTEM user.
+     *
+     * @hide
+     */
+    public static @NonNull String getDefaultUserType(@UserInfoFlag int userInfoFlag) {
+        if ((userInfoFlag & FLAG_SYSTEM) != 0) {
+            throw new IllegalArgumentException("Cannot getDefaultUserType for flags "
+                    + Integer.toHexString(userInfoFlag) + " because it corresponds to a "
+                    + "SYSTEM user type.");
+        }
+        final int supportedFlagTypes =
+                FLAG_GUEST | FLAG_RESTRICTED | FLAG_MANAGED_PROFILE | FLAG_DEMO;
+        switch (userInfoFlag & supportedFlagTypes) {
+            case 0 :                   return UserManager.USER_TYPE_FULL_SECONDARY;
+            case FLAG_GUEST:           return UserManager.USER_TYPE_FULL_GUEST;
+            case FLAG_RESTRICTED:      return UserManager.USER_TYPE_FULL_RESTRICTED;
+            case FLAG_MANAGED_PROFILE: return UserManager.USER_TYPE_PROFILE_MANAGED;
+            case FLAG_DEMO:            return UserManager.USER_TYPE_FULL_DEMO;
+            default:
+                throw new IllegalArgumentException("Cannot getDefaultUserType for flags "
+                        + Integer.toHexString(userInfoFlag) + " because it doesn't correspond to a "
+                        + "valid user type.");
+        }
+    }
+
     @UnsupportedAppUsage
     public boolean isPrimary() {
         return (flags & FLAG_PRIMARY) == FLAG_PRIMARY;
@@ -226,31 +293,21 @@
 
     @UnsupportedAppUsage
     public boolean isGuest() {
-        return isGuest(flags);
-    }
-
-    /**
-     * Checks if the flag denotes a guest user.
-     */
-    public static boolean isGuest(@UserInfoFlag int flags) {
-        return (flags & FLAG_GUEST) == FLAG_GUEST;
+        return UserManager.isUserTypeGuest(userType);
     }
 
     @UnsupportedAppUsage
     public boolean isRestricted() {
-        return (flags & FLAG_RESTRICTED) == FLAG_RESTRICTED;
+        return UserManager.isUserTypeRestricted(userType);
+    }
+
+    public boolean isProfile() {
+        return (flags & FLAG_PROFILE) != 0;
     }
 
     @UnsupportedAppUsage
     public boolean isManagedProfile() {
-        return isManagedProfile(flags);
-    }
-
-    /**
-     * Checks if the flag denotes a managed profile.
-     */
-    public static boolean isManagedProfile(@UserInfoFlag int flags) {
-        return (flags & FLAG_MANAGED_PROFILE) == FLAG_MANAGED_PROFILE;
+        return UserManager.isUserTypeManagedProfile(userType);
     }
 
     @UnsupportedAppUsage
@@ -271,7 +328,7 @@
     }
 
     public boolean isDemo() {
-        return (flags & FLAG_DEMO) == FLAG_DEMO;
+        return UserManager.isUserTypeDemo(userType);
     }
 
     public boolean isFull() {
@@ -304,7 +361,7 @@
             // Don't support switching to an ephemeral user with removal in progress.
             return false;
         }
-        return !isManagedProfile();
+        return !isProfile();
     }
 
     /**
@@ -316,9 +373,10 @@
         return (!hideSystemUser || id != UserHandle.USER_SYSTEM) && supportsSwitchTo();
     }
 
+    // TODO(b/142482943): Make this logic more specific and customizable. (canHaveProfile(userType))
     /* @hide */
     public boolean canHaveProfile() {
-        if (isManagedProfile() || isGuest() || isRestricted()) {
+        if (isProfile() || isGuest() || isRestricted()) {
             return false;
         }
         if (UserManager.isSplitSystemUser() || UserManager.isHeadlessSystemUserMode()) {
@@ -336,6 +394,7 @@
         iconPath = orig.iconPath;
         id = orig.id;
         flags = orig.flags;
+        userType = orig.userType;
         serialNumber = orig.serialNumber;
         creationTime = orig.creationTime;
         lastLoggedInTime = orig.lastLoggedInTime;
@@ -353,6 +412,7 @@
         return UserHandle.of(id);
     }
 
+    // TODO(b/142482943): Probably include mUserType here, which means updating TestDevice, etc.
     @Override
     public String toString() {
         // NOTE:  do not change this string, it's used by 'pm list users', which in turn is
@@ -365,6 +425,7 @@
     public String toFullString() {
         return "UserInfo[id=" + id
                 + ", name=" + name
+                + ", type=" + userType
                 + ", flags=" + flagsToString(flags)
                 + (preCreated ? " (pre-created)" : "")
                 + (partial ? " (partial)" : "")
@@ -387,6 +448,7 @@
         dest.writeString(name);
         dest.writeString(iconPath);
         dest.writeInt(flags);
+        dest.writeString(userType);
         dest.writeInt(serialNumber);
         dest.writeLong(creationTime);
         dest.writeLong(lastLoggedInTime);
@@ -415,6 +477,7 @@
         name = source.readString();
         iconPath = source.readString();
         flags = source.readInt();
+        userType = source.readString();
         serialNumber = source.readInt();
         creationTime = source.readLong();
         lastLoggedInTime = source.readLong();
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index 9d427c8..f17b3ae 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -66,7 +66,7 @@
     @interface BiometricError {}
 
     private final Context mContext;
-    private final IBiometricService mService;
+    private final IAuthService mService;
     private final boolean mHasHardware;
 
     /**
@@ -86,7 +86,7 @@
      * @param context
      * @param service
      */
-    public BiometricManager(Context context, IBiometricService service) {
+    public BiometricManager(Context context, IAuthService service) {
         mContext = context;
         mService = service;
 
diff --git a/core/java/android/hardware/biometrics/IAuthService.aidl b/core/java/android/hardware/biometrics/IAuthService.aidl
new file mode 100644
index 0000000..516a25d
--- /dev/null
+++ b/core/java/android/hardware/biometrics/IAuthService.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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.hardware.biometrics;
+
+import android.os.Bundle;
+import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
+import android.hardware.biometrics.IBiometricServiceReceiver;
+
+/**
+ * Communication channel from BiometricPrompt and BiometricManager to AuthService. The
+ * interface does not expose specific biometric modalities. The system will use the default
+ * biometric for apps. On devices with more than one, the choice is dictated by user preference in
+ * Settings.
+ * @hide
+ */
+interface IAuthService {
+    // Requests authentication. The service choose the appropriate biometric to use, and show
+    // the corresponding BiometricDialog.
+    void authenticate(IBinder token, long sessionId, int userId,
+            IBiometricServiceReceiver receiver, String opPackageName, in Bundle bundle);
+
+    // TODO(b/141025588): Make userId the first arg to be consistent with hasEnrolledBiometrics.
+    // Checks if biometrics can be used.
+    int canAuthenticate(String opPackageName, int userId);
+
+    // Checks if any biometrics are enrolled.
+    boolean hasEnrolledBiometrics(int userId, String opPackageName);
+
+    // Register callback for when keyguard biometric eligibility changes.
+    void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback);
+
+    // Explicitly set the active user.
+    void setActiveUser(int userId);
+
+    // Reset the lockout when user authenticates with strong auth (e.g. PIN, pattern or password)
+    void resetLockout(in byte [] token);
+}
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
index 06336a5..ca02421 100644
--- a/core/java/android/hardware/biometrics/IBiometricService.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -22,10 +22,7 @@
 import android.hardware.biometrics.IBiometricAuthenticator;
 
 /**
- * Communication channel from BiometricPrompt and BiometricManager to BiometricService. The
- * interface does not expose specific biometric modalities. The system will use the default
- * biometric for apps. On devices with more than one, the choice is dictated by user preference in
- * Settings.
+ * Communication channel from AuthService to BiometricService.
  * @hide
  */
 interface IBiometricService {
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index fc90096..b61b1ef 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -404,7 +404,7 @@
                             "Camera service is currently unavailable");
                     }
                     cameraUser = cameraService.connectDevice(callbacks, cameraId,
-                            mContext.getOpPackageName(), uid);
+                            mContext.getOpPackageName(), mContext.getFeatureId(), uid);
                 } else {
                     // Use legacy camera implementation for HAL1 devices
                     int id;
diff --git a/core/java/android/hardware/display/BrightnessChangeEvent.java b/core/java/android/hardware/display/BrightnessChangeEvent.java
index 21fcc63..a6a44be 100644
--- a/core/java/android/hardware/display/BrightnessChangeEvent.java
+++ b/core/java/android/hardware/display/BrightnessChangeEvent.java
@@ -79,7 +79,8 @@
     /**
      * Histogram counting how many times a pixel of a given value was displayed onscreen for the
      * Value component of HSV if the device supports color sampling, if the device does not support
-     * color sampling the value will be null.
+     * color sampling or {@link BrightnessConfiguration#shouldCollectColorSamples()} is false the
+     * value will be null.
      *
      * The buckets of the histogram are evenly weighted, the number of buckets is device specific.
      * The units are in pixels * milliseconds, with 1 pixel millisecond being 1 pixel displayed
@@ -94,7 +95,8 @@
 
     /**
      * How many milliseconds of data are contained in the colorValueBuckets, if the device does
-     * not support color sampling the value will be 0L.
+     * not support color sampling or {@link BrightnessConfiguration#shouldCollectColorSamples()} is
+     * false the value will be 0L.
      *
      * {@see #colorValueBuckets}
      */
diff --git a/core/java/android/hardware/display/BrightnessConfiguration.java b/core/java/android/hardware/display/BrightnessConfiguration.java
index 4c2e297..139be8e 100644
--- a/core/java/android/hardware/display/BrightnessConfiguration.java
+++ b/core/java/android/hardware/display/BrightnessConfiguration.java
@@ -49,26 +49,31 @@
     private static final String TAG_BRIGHTNESS_POINT = "brightness-point";
     private static final String TAG_BRIGHTNESS_CORRECTIONS = "brightness-corrections";
     private static final String TAG_BRIGHTNESS_CORRECTION = "brightness-correction";
+    private static final String TAG_BRIGHTNESS_PARAMS = "brightness-params";
     private static final String ATTR_LUX = "lux";
     private static final String ATTR_NITS = "nits";
     private static final String ATTR_DESCRIPTION = "description";
     private static final String ATTR_PACKAGE_NAME = "package-name";
     private static final String ATTR_CATEGORY = "category";
+    private static final String ATTR_COLLECT_COLOR = "collect-color";
 
     private final float[] mLux;
     private final float[] mNits;
     private final Map<String, BrightnessCorrection> mCorrectionsByPackageName;
     private final Map<Integer, BrightnessCorrection> mCorrectionsByCategory;
     private final String mDescription;
+    private final boolean mShouldCollectColorSamples;
 
     private BrightnessConfiguration(float[] lux, float[] nits,
             Map<String, BrightnessCorrection> correctionsByPackageName,
-            Map<Integer, BrightnessCorrection> correctionsByCategory, String description) {
+            Map<Integer, BrightnessCorrection> correctionsByCategory, String description,
+            boolean shouldCollectColorSamples) {
         mLux = lux;
         mNits = nits;
         mCorrectionsByPackageName = correctionsByPackageName;
         mCorrectionsByCategory = correctionsByCategory;
         mDescription = description;
+        mShouldCollectColorSamples = shouldCollectColorSamples;
     }
 
     /**
@@ -119,6 +124,14 @@
         return mDescription;
     }
 
+    /**
+     * Returns whether color samples should be collected in
+     * {@link BrightnessChangeEvent#colorValueBuckets}.
+     */
+    public boolean shouldCollectColorSamples() {
+        return mShouldCollectColorSamples;
+    }
+
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeFloatArray(mLux);
@@ -138,6 +151,7 @@
             correction.writeToParcel(dest, flags);
         }
         dest.writeString(mDescription);
+        dest.writeBoolean(mShouldCollectColorSamples);
     }
 
     @Override
@@ -167,6 +181,7 @@
         if (mDescription != null) {
             sb.append(mDescription);
         }
+        sb.append(", shouldCollectColorSamples = " + mShouldCollectColorSamples);
         sb.append("'}");
         return sb.toString();
     }
@@ -181,6 +196,7 @@
         if (mDescription != null) {
             result = result * 31 + mDescription.hashCode();
         }
+        result = result * 31 + Boolean.hashCode(mShouldCollectColorSamples);
         return result;
     }
 
@@ -196,7 +212,8 @@
         return Arrays.equals(mLux, other.mLux) && Arrays.equals(mNits, other.mNits)
                 && mCorrectionsByPackageName.equals(other.mCorrectionsByPackageName)
                 && mCorrectionsByCategory.equals(other.mCorrectionsByCategory)
-                && Objects.equals(mDescription, other.mDescription);
+                && Objects.equals(mDescription, other.mDescription)
+                && mShouldCollectColorSamples == other.mShouldCollectColorSamples;
     }
 
     public static final @android.annotation.NonNull Creator<BrightnessConfiguration> CREATOR =
@@ -224,6 +241,8 @@
 
             final String description = in.readString();
             builder.setDescription(description);
+            final boolean shouldCollectColorSamples = in.readBoolean();
+            builder.setShouldCollectColorSamples(shouldCollectColorSamples);
             return builder.build();
         }
 
@@ -252,6 +271,7 @@
             serializer.endTag(null, TAG_BRIGHTNESS_POINT);
         }
         serializer.endTag(null, TAG_BRIGHTNESS_CURVE);
+
         serializer.startTag(null, TAG_BRIGHTNESS_CORRECTIONS);
         for (Map.Entry<String, BrightnessCorrection> entry :
                 mCorrectionsByPackageName.entrySet()) {
@@ -271,6 +291,12 @@
             serializer.endTag(null, TAG_BRIGHTNESS_CORRECTION);
         }
         serializer.endTag(null, TAG_BRIGHTNESS_CORRECTIONS);
+
+        serializer.startTag(null, TAG_BRIGHTNESS_PARAMS);
+        if (mShouldCollectColorSamples) {
+            serializer.attribute(null, ATTR_COLLECT_COLOR, Boolean.toString(true));
+        }
+        serializer.endTag(null, TAG_BRIGHTNESS_PARAMS);
     }
 
     /**
@@ -293,6 +319,7 @@
         List<Float> nitsList = new ArrayList<>();
         Map<String, BrightnessCorrection> correctionsByPackageName = new HashMap<>();
         Map<Integer, BrightnessCorrection> correctionsByCategory = new HashMap<>();
+        boolean shouldCollectColorSamples = false;
         final int configDepth = parser.getDepth();
         while (XmlUtils.nextElementWithin(parser, configDepth)) {
             if (TAG_BRIGHTNESS_CURVE.equals(parser.getName())) {
@@ -307,8 +334,7 @@
                     luxList.add(lux);
                     nitsList.add(nits);
                 }
-            }
-            if (TAG_BRIGHTNESS_CORRECTIONS.equals(parser.getName())) {
+            } else if (TAG_BRIGHTNESS_CORRECTIONS.equals(parser.getName())) {
                 final int correctionsDepth = parser.getDepth();
                 while (XmlUtils.nextElementWithin(parser, correctionsDepth)) {
                     if (!TAG_BRIGHTNESS_CORRECTION.equals(parser.getName())) {
@@ -328,6 +354,9 @@
                         }
                     }
                 }
+            } else if (TAG_BRIGHTNESS_PARAMS.equals(parser.getName())) {
+                shouldCollectColorSamples =
+                        Boolean.parseBoolean(parser.getAttributeValue(null, ATTR_COLLECT_COLOR));
             }
         }
         final int n = luxList.size();
@@ -350,6 +379,7 @@
             final BrightnessCorrection correction = entry.getValue();
             builder.addCorrectionByCategory(category, correction);
         }
+        builder.setShouldCollectColorSamples(shouldCollectColorSamples);
         return builder.build();
     }
 
@@ -374,6 +404,7 @@
         private Map<String, BrightnessCorrection> mCorrectionsByPackageName;
         private Map<Integer, BrightnessCorrection> mCorrectionsByCategory;
         private String mDescription;
+        private boolean mShouldCollectColorSamples;
 
         /**
          * Constructs the builder with the control points for the brightness curve.
@@ -498,6 +529,19 @@
         }
 
         /**
+         * Control whether screen color samples should be returned in
+         * {@link BrightnessChangeEvent#colorValueBuckets} if supported by the device.
+         *
+         * @param shouldCollectColorSamples true if color samples should be collected.
+         * @return
+         */
+        @NonNull
+        public Builder setShouldCollectColorSamples(boolean shouldCollectColorSamples) {
+            mShouldCollectColorSamples = shouldCollectColorSamples;
+            return this;
+        }
+
+        /**
          * Builds the {@link BrightnessConfiguration}.
          */
         @NonNull
@@ -506,7 +550,7 @@
                 throw new IllegalStateException("A curve must be set!");
             }
             return new BrightnessConfiguration(mCurveLux, mCurveNits, mCorrectionsByPackageName,
-                    mCorrectionsByCategory, mDescription);
+                    mCorrectionsByCategory, mDescription, mShouldCollectColorSamples);
         }
 
         private static void checkMonotonic(float[] vals, boolean strictlyIncreasing, String name) {
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index 5bc9953..990c114 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -25,6 +25,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.internal.util.Preconditions;
+
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.List;
@@ -152,6 +154,7 @@
          * @return The {@link Builder} for chaining.
          */
         public @NonNull Builder setDnsServers(@NonNull Iterable<InetAddress> dnsServers) {
+            Preconditions.checkNotNull(dnsServers);
             mDnsServers = dnsServers;
             return this;
         }
@@ -175,8 +178,10 @@
             final StaticIpConfiguration config = new StaticIpConfiguration();
             config.ipAddress = mIpAddress;
             config.gateway = mGateway;
-            for (InetAddress server : mDnsServers) {
-                config.dnsServers.add(server);
+            if (mDnsServers != null) {
+                for (InetAddress server : mDnsServers) {
+                    config.dnsServers.add(server);
+                }
             }
             config.domains = mDomains;
             return config;
diff --git a/core/java/android/net/util/MultinetworkPolicyTracker.java b/core/java/android/net/util/MultinetworkPolicyTracker.java
index 4e88149..aa0f622 100644
--- a/core/java/android/net/util/MultinetworkPolicyTracker.java
+++ b/core/java/android/net/util/MultinetworkPolicyTracker.java
@@ -94,7 +94,8 @@
             }
         };
 
-        TelephonyManager.from(ctx).listen(new PhoneStateListener(handler.getLooper()) {
+        ctx.getSystemService(TelephonyManager.class).listen(
+                new PhoneStateListener(handler.getLooper()) {
             @Override
             public void onActiveDataSubscriptionIdChanged(int subId) {
                 mActiveSubId = subId;
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 400d981..89ccef6 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -161,7 +161,7 @@
         try {
             Application application = ActivityThread.currentApplication();
             String callingPackage = application != null ? application.getPackageName() : null;
-            return service.getSerialForPackage(callingPackage);
+            return service.getSerialForPackage(callingPackage, null);
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/os/IDeviceIdentifiersPolicyService.aidl b/core/java/android/os/IDeviceIdentifiersPolicyService.aidl
index 87d358f..d11aa0c 100644
--- a/core/java/android/os/IDeviceIdentifiersPolicyService.aidl
+++ b/core/java/android/os/IDeviceIdentifiersPolicyService.aidl
@@ -21,5 +21,5 @@
  */
 interface IDeviceIdentifiersPolicyService {
     String getSerial();
-    String getSerialForPackage(in String callingPackage);
-}
\ No newline at end of file
+    String getSerialForPackage(in String callingPackage, String callingFeatureId);
+}
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index e8cc73f..40048d9 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -35,77 +35,84 @@
     /*
      * DO NOT MOVE - UserManager.h depends on the ordering of this function.
      */
-    int getCredentialOwnerProfile(int userHandle);
-    int getProfileParentId(int userHandle);
+    int getCredentialOwnerProfile(int userId);
+    int getProfileParentId(int userId);
     /*
      * END OF DO NOT MOVE
      */
 
-    UserInfo createUser(in String name, int flags);
-    UserInfo preCreateUser(int flags);
-    UserInfo createProfileForUser(in String name, int flags, int userHandle,
+    UserInfo createUser(in String name, in String userType, int flags);
+    UserInfo preCreateUser(in String userType);
+    UserInfo createProfileForUser(in String name, in String userType, int flags, int userId,
             in String[] disallowedPackages);
     UserInfo createRestrictedProfile(String name, int parentUserHandle);
-    void setUserEnabled(int userHandle);
+    void setUserEnabled(int userId);
     void setUserAdmin(int userId);
-    void evictCredentialEncryptionKey(int userHandle);
-    boolean removeUser(int userHandle);
-    boolean removeUserEvenWhenDisallowed(int userHandle);
-    void setUserName(int userHandle, String name);
-    void setUserIcon(int userHandle, in Bitmap icon);
-    ParcelFileDescriptor getUserIcon(int userHandle);
+    void evictCredentialEncryptionKey(int userId);
+    boolean removeUser(int userId);
+    boolean removeUserEvenWhenDisallowed(int userId);
+    void setUserName(int userId, String name);
+    void setUserIcon(int userId, in Bitmap icon);
+    ParcelFileDescriptor getUserIcon(int userId);
     UserInfo getPrimaryUser();
     List<UserInfo> getUsers(boolean excludePartial, boolean excludeDying, boolean excludePreCreated);
-    List<UserInfo> getProfiles(int userHandle, boolean enabledOnly);
+    List<UserInfo> getProfiles(int userId, boolean enabledOnly);
     int[] getProfileIds(int userId, boolean enabledOnly);
-    boolean canAddMoreManagedProfiles(int userHandle, boolean allowedToRemoveOne);
-    UserInfo getProfileParent(int userHandle);
-    boolean isSameProfileGroup(int userHandle, int otherUserHandle);
+    boolean canAddMoreProfilesToUser(in String userType, int userId, boolean allowedToRemoveOne);
+    boolean canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne);
+    UserInfo getProfileParent(int userId);
+    boolean isSameProfileGroup(int userId, int otherUserHandle);
+    String getUserTypeForUser(int userId);
     @UnsupportedAppUsage
-    UserInfo getUserInfo(int userHandle);
-    String getUserAccount(int userHandle);
-    void setUserAccount(int userHandle, String accountName);
-    long getUserCreationTime(int userHandle);
+    UserInfo getUserInfo(int userId);
+    String getUserAccount(int userId);
+    void setUserAccount(int userId, String accountName);
+    long getUserCreationTime(int userId);
     boolean isRestricted();
-    boolean canHaveRestrictedProfile(int userHandle);
-    int getUserSerialNumber(int userHandle);
+    boolean canHaveRestrictedProfile(int userId);
+    int getUserSerialNumber(int userId);
     int getUserHandle(int userSerialNumber);
-    int getUserRestrictionSource(String restrictionKey, int userHandle);
-    List<UserManager.EnforcingUser> getUserRestrictionSources(String restrictionKey, int userHandle);
-    Bundle getUserRestrictions(int userHandle);
-    boolean hasBaseUserRestriction(String restrictionKey, int userHandle);
-    boolean hasUserRestriction(in String restrictionKey, int userHandle);
+    int getUserRestrictionSource(String restrictionKey, int userId);
+    List<UserManager.EnforcingUser> getUserRestrictionSources(String restrictionKey, int userId);
+    Bundle getUserRestrictions(int userId);
+    boolean hasBaseUserRestriction(String restrictionKey, int userId);
+    boolean hasUserRestriction(in String restrictionKey, int userId);
     boolean hasUserRestrictionOnAnyUser(in String restrictionKey);
     boolean isSettingRestrictedForUser(in String setting, int userId, in String value, int callingUid);
     void addUserRestrictionsListener(IUserRestrictionsListener listener);
-    void setUserRestriction(String key, boolean value, int userHandle);
-    void setApplicationRestrictions(in String packageName, in Bundle restrictions,
-            int userHandle);
+    void setUserRestriction(String key, boolean value, int userId);
+    void setApplicationRestrictions(in String packageName, in Bundle restrictions, int userId);
     Bundle getApplicationRestrictions(in String packageName);
-    Bundle getApplicationRestrictionsForUser(in String packageName, int userHandle);
+    Bundle getApplicationRestrictionsForUser(in String packageName, int userId);
     void setDefaultGuestRestrictions(in Bundle restrictions);
     Bundle getDefaultGuestRestrictions();
-    boolean markGuestForDeletion(int userHandle);
-    boolean isQuietModeEnabled(int userHandle);
-    void setSeedAccountData(int userHandle, in String accountName,
+    boolean markGuestForDeletion(int userId);
+    boolean isQuietModeEnabled(int userId);
+    void setSeedAccountData(int userId, in String accountName,
             in String accountType, in PersistableBundle accountOptions, boolean persist);
     String getSeedAccountName();
     String getSeedAccountType();
     PersistableBundle getSeedAccountOptions();
     void clearSeedAccountData();
     boolean someUserHasSeedAccount(in String accountName, in String accountType);
+    boolean isProfile(int userId);
     boolean isManagedProfile(int userId);
     boolean isDemoUser(int userId);
     boolean isPreCreated(int userId);
-    UserInfo createProfileForUserEvenWhenDisallowed(in String name, int flags, int userHandle,
-            in String[] disallowedPackages);
+    UserInfo createProfileForUserEvenWhenDisallowed(in String name, in String userType, int flags,
+            int userId, in String[] disallowedPackages);
     boolean isUserUnlockingOrUnlocked(int userId);
-    int getManagedProfileBadge(int userId);
+    int getUserIconBadgeResId(int userId);
+    int getUserBadgeResId(int userId);
+    int getUserBadgeNoBackgroundResId(int userId);
+    int getUserBadgeLabelResId(int userId);
+    int getUserBadgeColorResId(int userId);
+    boolean hasBadge(int userId);
     boolean isUserUnlocked(int userId);
     boolean isUserRunning(int userId);
-    boolean isUserNameSet(int userHandle);
+    boolean isUserNameSet(int userId);
     boolean hasRestrictedProfiles();
-    boolean requestQuietModeEnabled(String callingPackage, boolean enableQuietMode, int userHandle, in IntentSender target);
+    boolean requestQuietModeEnabled(String callingPackage, boolean enableQuietMode, int userId, in IntentSender target);
     String getUserName();
     long getUserStartRealtime();
     long getUserUnlockRealtime();
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index dd1f8c3..f18b4db 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -426,9 +426,15 @@
     public static final int GO_TO_SLEEP_REASON_FORCE_SUSPEND = 8;
 
     /**
+     * Go to sleep reason code: Going to sleep due to user inattentiveness.
      * @hide
      */
-    public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_FORCE_SUSPEND;
+    public static final int GO_TO_SLEEP_REASON_INATTENTIVE = 9;
+
+    /**
+     * @hide
+     */
+    public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_INATTENTIVE;
 
     /**
      * @hide
@@ -444,6 +450,7 @@
             case GO_TO_SLEEP_REASON_SLEEP_BUTTON: return "sleep_button";
             case GO_TO_SLEEP_REASON_ACCESSIBILITY: return "accessibility";
             case GO_TO_SLEEP_REASON_FORCE_SUSPEND: return "force_suspend";
+            case GO_TO_SLEEP_REASON_INATTENTIVE: return "inattentive";
             default: return Integer.toString(sleepReason);
         }
     }
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 48fc2a6..e3f6e12 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -888,7 +888,7 @@
         }
         List<SubscriptionInfo> invisibleSubs = new ArrayList<>();
         for (SubscriptionInfo sub : availableSubs) {
-            if (sub.isEmbedded() && !subscriptionManager.isSubscriptionVisible(sub)) {
+            if (sub.isEmbedded() && sub.getGroupUuid() != null && sub.isOpportunistic()) {
                 invisibleSubs.add(sub);
             }
         }
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index b096049..bb62eb2 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -18,6 +18,8 @@
 
 import android.Manifest;
 import android.accounts.AccountManager;
+import android.annotation.ColorInt;
+import android.annotation.DrawableRes;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -76,6 +78,57 @@
     private final Context mContext;
 
     private Boolean mIsManagedProfileCached;
+    private Boolean mIsProfileCached;
+
+    /**
+     * User type representing a {@link UserHandle#USER_SYSTEM system} user that is a human user.
+     * This type of user cannot be created; it can only pre-exist on first boot.
+     * @hide
+     */
+    public static final String USER_TYPE_FULL_SYSTEM = "android.os.usertype.full.SYSTEM";
+
+    /**
+     * User type representing a regular non-profile non-{@link UserHandle#USER_SYSTEM system} human
+     * user.
+     * This is sometimes called an ordinary 'secondary user'.
+     * @hide
+     */
+    public static final String USER_TYPE_FULL_SECONDARY = "android.os.usertype.full.SECONDARY";
+
+    /**
+     * User type representing a guest user that may be transient.
+     * @hide
+     */
+    public static final String USER_TYPE_FULL_GUEST = "android.os.usertype.full.GUEST";
+
+    /**
+     * User type representing a user for demo purposes only, which can be removed at any time.
+     * @hide
+     */
+    public static final String USER_TYPE_FULL_DEMO = "android.os.usertype.full.DEMO";
+
+    /**
+     * User type representing a "restricted profile" user, which is a full user that is subject to
+     * certain restrictions from a parent user. Note, however, that it is NOT technically a profile.
+     * @hide
+     */
+    public static final String USER_TYPE_FULL_RESTRICTED = "android.os.usertype.full.RESTRICTED";
+
+    /**
+     * User type representing a managed profile, which is a profile that is to be managed by a
+     * device policy controller (DPC).
+     * The intended purpose is for work profiles, which are managed by a corporate entity.
+     * @hide
+     */
+    public static final String USER_TYPE_PROFILE_MANAGED = "android.os.usertype.profile.MANAGED";
+
+    /**
+     * User type representing a {@link UserHandle#USER_SYSTEM system} user that is <b>not</b> a
+     * human user.
+     * This type of user cannot be created; it can only pre-exist on first boot.
+     * @hide
+     */
+    public static final String USER_TYPE_SYSTEM_HEADLESS = "android.os.usertype.system.HEADLESS";
 
     /**
      * @hide
@@ -1306,8 +1359,11 @@
                 mContext.getContentResolver(),
                 Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED, 0) != 0;
         boolean isSystemUserUnlocked = isUserUnlocked(UserHandle.SYSTEM);
-        boolean inCall = TelephonyManager.getDefault().getCallState()
-                != TelephonyManager.CALL_STATE_IDLE;
+        boolean inCall = false;
+        TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
+        if (telephonyManager != null) {
+            inCall = telephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE;
+        }
         boolean isUserSwitchDisallowed = hasUserRestriction(DISALLOW_USER_SWITCH);
         return (allowUserSwitchingWhenSystemUserLocked || isSystemUserUnlocked) && !inCall
                 && !isUserSwitchDisallowed;
@@ -1479,6 +1535,79 @@
     }
 
     /**
+     * Returns the calling user's user type.
+     *
+     * // TODO(b/142482943): Decide on the appropriate permission requirements.
+     *
+     * @return the name of the user type, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}.
+     * @hide
+     */
+    public @NonNull String getUserType() {
+        try {
+            return mService.getUserTypeForUser(UserHandle.myUserId());
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the given user's user type.
+     *
+     * // TODO(b/142482943): Decide on the appropriate permission requirements.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} or
+     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission, otherwise the caller
+     * must be in the same profile group of specified user.
+     *
+     * @param userHandle the user handle of the user whose type is being requested.
+     * @return the name of the user's user type, e.g. {@link UserManager#USER_TYPE_PROFILE_MANAGED},
+     *         or {@code null} if there is no such user.
+     * @hide
+     */
+    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+            android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
+    public @Nullable String getUserTypeForUser(@NonNull UserHandle userHandle) {
+        try {
+            return mService.getUserTypeForUser(userHandle.getIdentifier());
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns whether the user type is a
+     * {@link UserManager#USER_TYPE_PROFILE_MANAGED managed profile}.
+     * @hide
+     */
+    public static boolean isUserTypeManagedProfile(String userType) {
+        return USER_TYPE_PROFILE_MANAGED.equals(userType);
+    }
+
+    /**
+     * Returns whether the user type is a {@link UserManager#USER_TYPE_FULL_GUEST guest user}.
+     * @hide
+     */
+    public static boolean isUserTypeGuest(String userType) {
+        return USER_TYPE_FULL_GUEST.equals(userType);
+    }
+
+    /**
+     * Returns whether the user type is a
+     * {@link UserManager#USER_TYPE_FULL_RESTRICTED restricted user}.
+     * @hide
+     */
+    public static boolean isUserTypeRestricted(String userType) {
+        return USER_TYPE_FULL_RESTRICTED.equals(userType);
+    }
+
+    /**
+     * Returns whether the user type is a {@link UserManager#USER_TYPE_FULL_DEMO demo user}.
+     * @hide
+     */
+    public static boolean isUserTypeDemo(String userType) {
+        return USER_TYPE_FULL_DEMO.equals(userType);
+    }
+
+    /**
      * @hide
      * @deprecated Use {@link #isRestrictedProfile()}
      */
@@ -1589,6 +1718,48 @@
     }
 
     /**
+     * Checks if the calling app is running in a profile.
+     *
+     * @return whether the caller is in a profile.
+     * @hide
+     */
+    public boolean isProfile() {
+        // No need for synchronization.  Once it becomes non-null, it'll be non-null forever.
+        // Worst case we might end up calling the AIDL method multiple times but that's fine.
+        if (mIsProfileCached != null) {
+            return mIsProfileCached;
+        }
+        try {
+            mIsProfileCached = mService.isProfile(UserHandle.myUserId());
+            return mIsProfileCached;
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Checks if the specified user is a profile.
+     *
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} or
+     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission, otherwise the caller
+     * must be in the same profile group of specified user.
+     *
+     * @return whether the specified user is a profile.
+     * @hide
+     */
+    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+            android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
+    public boolean isProfile(@UserIdInt int userId) {
+        if (userId == UserHandle.myUserId()) {
+            return isProfile();
+        }
+        try {
+            return mService.isProfile(userId);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+    /**
      * Checks if the calling app is running in a managed profile.
      *
      * @return whether the caller is in a managed profile.
@@ -1612,7 +1783,8 @@
 
     /**
      * Checks if the specified user is a managed profile.
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission, otherwise the caller
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} or
+     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission, otherwise the caller
      * must be in the same profile group of specified user.
      *
      * @return whether the specified user is a managed profile.
@@ -1632,23 +1804,6 @@
     }
 
     /**
-     * Gets badge for a managed profile.
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission, otherwise the caller
-     * must be in the same profile group of specified user.
-     *
-     * @return which badge to use for the managed profile badge id will be less than
-     *         UserManagerService.getMaxManagedProfiles()
-     * @hide
-     */
-    public int getManagedProfileBadge(@UserIdInt int userId) {
-        try {
-            return mService.getManagedProfileBadge(userId);
-        } catch (RemoteException re) {
-            throw re.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Checks if the calling app is running as an ephemeral user.
      *
      * @return whether the caller is an ephemeral user.
@@ -2120,23 +2275,44 @@
 
     /**
      * Creates a user with the specified name and options. For non-admin users, default user
+     * restrictions are going to be applied.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     *
+     * @param name the user's name
+     * @param flags UserInfo flags that identify the type of user and other properties.
+     * @see UserInfo
+     *
+     * @return the UserInfo object for the created user, or null if the user could not be created.
+     * @throws IllegalArgumentException if flags do not correspond to a valid user type.
+     * @deprecated Use {@link #createUser(String, String, int)} instead.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    @Deprecated
+    public @Nullable UserInfo createUser(@Nullable String name, @UserInfoFlag int flags) {
+        return createUser(name, UserInfo.getDefaultUserType(flags), flags);
+    }
+
+    /**
+     * Creates a user with the specified name and options. For non-admin users, default user
      * restrictions will be applied.
      *
      * <p>Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      *
      * @param name the user's name
-     * @param flags UserInfo flags that identify the type of user and other properties.
+     * @param userType the type of user, such as {@link UserManager#USER_TYPE_FULL_GUEST}.
+     * @param flags UserInfo flags that specify user properties.
      * @see UserInfo
      *
      * @return the UserInfo object for the created user, or {@code null} if the user could not be
      * created.
      * @hide
      */
-    @UnsupportedAppUsage
-    public @Nullable UserInfo createUser(@Nullable String name, @UserInfoFlag int flags) {
+    public @Nullable UserInfo createUser(@Nullable String name, @NonNull String userType,
+            @UserInfoFlag int flags) {
         UserInfo user = null;
         try {
-            user = mService.createUser(name, flags);
+            user = mService.createUser(name, userType, flags);
             // TODO: Keep this in sync with
             // UserManagerService.LocalService.createUserEvenWhenDisallowed
             if (user != null && !user.isAdmin() && !user.isDemo()) {
@@ -2150,19 +2326,17 @@
     }
 
     /**
-     * Pre-creates a user with the specified name and options. For non-admin users, default user
+     * Pre-creates a user of the specified type. For non-admin users, default user
      * restrictions will be applied.
      *
      * <p>This method can be used by OEMs to "warm" up the user creation by pre-creating some users
      * at the first boot, so they when the "real" user is created (for example,
-     * by {@link #createUser(String, int)} or {@link #createGuest(Context, String)}), it takes
-     * less time.
+     * by {@link #createUser(String, String, int)} or {@link #createGuest(Context, String)}), it
+     * takes less time.
      *
      * <p>Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      *
-     * @param flags UserInfo flags that identify the type of user and other properties.
-     * @see UserInfo
-     *
+     * @param userType the type of user, such as {@link UserManager#USER_TYPE_FULL_GUEST}.
      * @return the UserInfo object for the created user, or {@code null} if the user could not be
      * created.
      *
@@ -2171,9 +2345,9 @@
      *
      * @hide
      */
-    public @Nullable UserInfo preCreateUser(@UserInfoFlag int flags) {
+    public @Nullable UserInfo preCreateUser(@NonNull String userType) {
         try {
-            return mService.preCreateUser(flags);
+            return mService.preCreateUser(userType);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -2188,7 +2362,7 @@
     public UserInfo createGuest(Context context, String name) {
         UserInfo guest = null;
         try {
-            guest = mService.createUser(name, UserInfo.FLAG_GUEST);
+            guest = mService.createUser(name, USER_TYPE_FULL_GUEST, 0);
             if (guest != null) {
                 Settings.Secure.putStringForUser(context.getContentResolver(),
                         Settings.Secure.SKIP_FIRST_USE_HINTS, "1", guest.id);
@@ -2202,6 +2376,7 @@
     /**
      * Creates a user with the specified name and options as a profile of another user.
      * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     * The type of profile must be specified using the given flags.
      *
      * @param name the user's name
      * @param flags flags that identify the type of user and other properties.
@@ -2209,20 +2384,44 @@
      *
      * @return the {@link UserInfo} object for the created user, or null if the user
      *         could not be created.
+     * @throws IllegalArgumentException if flags do not correspond to a valid user type.
+     * @deprecated Use {@link #createProfileForUser(String, String, int, int)} instead.
      * @hide
      */
     @UnsupportedAppUsage
-    public UserInfo createProfileForUser(String name, int flags, @UserIdInt int userId) {
-        return createProfileForUser(name, flags, userId, null);
+    @Deprecated
+    public UserInfo createProfileForUser(String name, @UserInfoFlag int flags,
+            @UserIdInt int userId) {
+        return createProfileForUser(name, UserInfo.getDefaultUserType(flags), flags,
+                userId, null);
     }
 
     /**
-     * Version of {@link #createProfileForUser(String, int, int)} that allows you to specify
+     * Creates a user with the specified name and options as a profile of another user.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     *
+     * @param name the user's name
+     * @param userType the type of user, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}.
+     * @param flags UserInfo flags that specify user properties.
+     * @param userId new user will be a profile of this user.
+     *
+     * @return the {@link UserInfo} object for the created user, or null if the user
+     *         could not be created.
+     * @hide
+     */
+    public UserInfo createProfileForUser(String name, @NonNull String userType,
+            @UserInfoFlag int flags, @UserIdInt int userId) {
+        return createProfileForUser(name, userType, flags, userId, null);
+    }
+
+    /**
+     * Version of {@link #createProfileForUser(String, String, int, int)} that allows you to specify
      * any packages that should not be installed in the new profile by default, these packages can
      * still be installed later by the user if needed.
      *
      * @param name the user's name
-     * @param flags flags that identify the type of user and other properties.
+     * @param userType the type of user, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}.
+     * @param flags UserInfo flags that specify user properties.
      * @param userId new user will be a profile of this user.
      * @param disallowedPackages packages that will not be installed in the profile being created.
      *
@@ -2230,28 +2429,29 @@
      *         could not be created.
      * @hide
      */
-    public UserInfo createProfileForUser(String name, int flags, @UserIdInt int userId,
-            String[] disallowedPackages) {
+    public UserInfo createProfileForUser(String name, @NonNull String userType,
+            @UserInfoFlag int flags, @UserIdInt int userId, String[] disallowedPackages) {
         try {
-            return mService.createProfileForUser(name, flags, userId, disallowedPackages);
+            return mService.createProfileForUser(name, userType, flags, userId, disallowedPackages);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
     }
 
     /**
-     * Similar to {@link #createProfileForUser(String, int, int, String[])}
+     * Similar to {@link #createProfileForUser(String, String, int, int, String[])}
      * except bypassing the checking of {@link UserManager#DISALLOW_ADD_MANAGED_PROFILE}.
      * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      *
-     * @see #createProfileForUser(String, int, int, String[])
+     * @see #createProfileForUser(String, String, int, int, String[])
      * @hide
      */
-    public UserInfo createProfileForUserEvenWhenDisallowed(String name, int flags,
-            @UserIdInt int userId, String[] disallowedPackages) {
+    public UserInfo createProfileForUserEvenWhenDisallowed(String name,
+            @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int userId,
+            String[] disallowedPackages) {
         try {
-            return mService.createProfileForUserEvenWhenDisallowed(name, flags, userId,
-                    disallowedPackages);
+            return mService.createProfileForUserEvenWhenDisallowed(name, userType, flags,
+                    userId, disallowedPackages);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -2595,6 +2795,8 @@
      * @hide
      */
     public boolean canAddMoreUsers() {
+        // TODO(b/142482943): UMS has different logic, excluding Demo and Profile from counting. Why
+        //                    not here? The logic is inconsistent. See UMS.canAddMoreManagedProfiles
         final List<UserInfo> users = getUsers(true);
         final int totalUserCount = users.size();
         int aliveUserCount = 0;
@@ -2625,6 +2827,22 @@
     }
 
     /**
+     * Checks whether it's possible to add more profiles of the given type to the given user.
+     *
+     * @param userType the type of user, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}.
+     * @return true if more profiles can be added, false if limit has been reached.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+    public boolean canAddMoreProfilesToUser(@NonNull String userType, @UserIdInt int userId) {
+        try {
+            return mService.canAddMoreProfilesToUser(userType, userId, false);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Returns list of the profiles of userId including userId itself.
      * Note that this returns both enabled and not enabled profiles. See
      * {@link #getEnabledProfiles(int)} if you need only the enabled ones.
@@ -2858,8 +3076,112 @@
     }
 
     /**
-     * If the target user is a managed profile of the calling user or the caller
-     * is itself a managed profile, then this returns a badged copy of the given
+     * Returns whether the given user has a badge (generally to put on profiles' icons).
+     *
+     * @param userId userId of the user in question
+     * @return true if the user's icons should display a badge; false otherwise.
+     *
+     * @see #getBadgedIconForUser more information about badging in general
+     * @hide
+     */
+    public boolean hasBadge(@UserIdInt int userId) {
+        if (!isProfile(userId)) {
+            // Since currently only profiles actually have badges, we can do this optimization.
+            return false;
+        }
+        try {
+            return mService.hasBadge(userId);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns whether the calling app's user has a badge (generally to put on profiles' icons).
+     *
+     * @return true if the user's icons should display a badge; false otherwise.
+     *
+     * @see #getBadgedIconForUser more information about badging in general
+     * @hide
+     */
+    public boolean hasBadge() {
+        return hasBadge(UserHandle.myUserId());
+    }
+
+    /**
+     * Returns the badge color for the given user (generally to color a profile's icon's badge).
+     *
+     * <p>To check whether a badge color is expected for the user, first call {@link #hasBadge}.
+     *
+     * @return the color (not the resource ID) to be used for the user's badge
+     * @throws Resources.NotFoundException if no valid badge color exists for this user
+     *
+     * @see #getBadgedIconForUser more information about badging in general
+     * @hide
+     */
+    public @ColorInt int getUserBadgeColor(@UserIdInt int userId) {
+        try {
+            final int resourceId = mService.getUserBadgeColorResId(userId);
+            return Resources.getSystem().getColor(resourceId, null);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the Resource ID of the user's icon badge.
+     *
+     * @return the Resource ID of the user's icon badge if it has one; otherwise
+     *         {@link Resources#ID_NULL}.
+     *
+     * @see #getBadgedIconForUser more information about badging in general
+     * @hide
+     */
+    public @DrawableRes int getUserIconBadgeResId(@UserIdInt int userId) {
+        try {
+            return mService.getUserIconBadgeResId(userId);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the Resource ID of the user's badge.
+     *
+     * @return the Resource ID of the user's badge if it has one; otherwise
+     *         {@link Resources#ID_NULL}.
+     *
+     * @see #getBadgedIconForUser more information about badging in general
+     * @hide
+     */
+    public @DrawableRes int getUserBadgeResId(@UserIdInt int userId) {
+        try {
+            return mService.getUserBadgeResId(userId);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the Resource ID of the user's badge without a background.
+     *
+     * @return the Resource ID of the user's no-background badge if it has one; otherwise
+     *         {@link Resources#ID_NULL}.
+     *
+     * @see #getBadgedIconForUser more information about badging in general
+     * @hide
+     */
+    public @DrawableRes int getUserBadgeNoBackgroundResId(@UserIdInt int userId) {
+        try {
+            return mService.getUserBadgeNoBackgroundResId(userId);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * If the target user is a profile of the calling user or the caller
+     * is itself a profile, then this returns a badged copy of the given
      * icon to be able to distinguish it from the original icon. For badging an
      * arbitrary drawable use {@link #getBadgedDrawableForUser(
      * android.graphics.drawable.Drawable, UserHandle, android.graphics.Rect, int)}.
@@ -2880,8 +3202,8 @@
     }
 
     /**
-     * If the target user is a managed profile of the calling user or the caller
-     * is itself a managed profile, then this returns a badged copy of the given
+     * If the target user is a profile of the calling user or the caller
+     * is itself a profile, then this returns a badged copy of the given
      * drawable allowing the user to distinguish it from the original drawable.
      * The caller can specify the location in the bounds of the drawable to be
      * badged where the badge should be applied as well as the density of the
@@ -2911,11 +3233,15 @@
     }
 
     /**
-     * If the target user is a managed profile of the calling user or the caller
-     * is itself a managed profile, then this returns a copy of the label with
+     * If the target user is a profile of the calling user or the caller
+     * is itself a profile, then this returns a copy of the label with
      * badging for accessibility services like talkback. E.g. passing in "Email"
      * and it might return "Work Email" for Email in the work profile.
      *
+     * <p>Requires {@link android.Manifest.permission#MANAGE_USERS} or
+     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission, otherwise the caller
+     * must be in the same profile group of specified user.
+     *
      * @param label The label to change.
      * @param user The target user.
      * @return A label that combines the original label and a badge as
@@ -2923,7 +3249,16 @@
      * @removed
      */
     public CharSequence getBadgedLabelForUser(CharSequence label, UserHandle user) {
-        return mContext.getPackageManager().getUserBadgedLabel(label, user);
+        final int userId = user.getIdentifier();
+        if (!hasBadge(userId)) {
+            return label;
+        }
+        try {
+            final int resourceId = mService.getUserBadgeLabelResId(userId);
+            return Resources.getSystem().getString(resourceId, label);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
     }
 
     /**
diff --git a/core/java/android/os/image/DynamicSystemManager.java b/core/java/android/os/image/DynamicSystemManager.java
index 0e00d5e..4c92c28 100644
--- a/core/java/android/os/image/DynamicSystemManager.java
+++ b/core/java/android/os/image/DynamicSystemManager.java
@@ -101,6 +101,19 @@
         }
     }
     /**
+     * Start DynamicSystem installation.
+     *
+     * @return true if the call succeeds
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
+    public boolean startInstallation() {
+        try {
+            return mService.startInstallation();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e.toString());
+        }
+    }
+    /**
      * Start DynamicSystem installation. This call may take an unbounded amount of time. The caller
      * may use another thread to call the getStartProgress() to get the progress.
      *
@@ -112,9 +125,9 @@
      *     true.
      */
     @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
-    public Session startInstallation(String name, long size, boolean readOnly) {
+    public Session createPartition(String name, long size, boolean readOnly) {
         try {
-            if (mService.startInstallation(name, size, readOnly)) {
+            if (mService.createPartition(name, size, readOnly)) {
                 return new Session();
             } else {
                 return null;
@@ -123,7 +136,18 @@
             throw new RuntimeException(e.toString());
         }
     }
-
+    /**
+     * Finish a previously started installation. Installations without a cooresponding
+     * finishInstallation() will be cleaned up during device boot.
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
+    public boolean finishInstallation() {
+        try {
+            return mService.finishInstallation();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e.toString());
+        }
+    }
     /**
      * Query the progress of the current installation operation. This can be called while the
      * installation is in progress.
diff --git a/core/java/android/os/image/IDynamicSystemService.aidl b/core/java/android/os/image/IDynamicSystemService.aidl
index 75f6785..69cbab2 100644
--- a/core/java/android/os/image/IDynamicSystemService.aidl
+++ b/core/java/android/os/image/IDynamicSystemService.aidl
@@ -21,15 +21,26 @@
 interface IDynamicSystemService
 {
     /**
-     * Start DynamicSystem installation. This call may take 60~90 seconds. The caller
+     * Start DynamicSystem installation.
+     * @return true if the call succeeds
+     */
+    boolean startInstallation();
+
+    /**
+     * Create a DSU partition. This call may take 60~90 seconds. The caller
      * may use another thread to call the getStartProgress() to get the progress.
-     *
      * @param name The DSU partition name
      * @param size Size of the DSU image in bytes
      * @param readOnly True if this partition is readOnly
      * @return true if the call succeeds
      */
-    boolean startInstallation(@utf8InCpp String name, long size, boolean readOnly);
+    boolean createPartition(@utf8InCpp String name, long size, boolean readOnly);
+
+    /**
+     * Finish a previously started installation. Installations without
+     * a cooresponding finishInstallation() will be cleaned up during device boot.
+     */
+    boolean finishInstallation();
 
     /**
      * Query the progress of the current installation operation. This can be called while
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index ac7a0a8..deeeddc 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1645,10 +1645,10 @@
      * Check that given app holds both permission and appop.
      * @hide
      */
-    public static boolean checkPermissionAndAppOp(Context context, boolean enforce,
-            int pid, int uid, String packageName, String permission, int op) {
-        return checkPermissionAndAppOp(context, enforce, pid, uid, packageName, permission, op,
-                true);
+    public static boolean checkPermissionAndAppOp(Context context, boolean enforce, int pid,
+            int uid, String packageName, @NonNull String featureId, String permission, int op) {
+        return checkPermissionAndAppOp(context, enforce, pid, uid, packageName, featureId,
+                permission, op, true);
     }
 
     /**
@@ -1657,16 +1657,17 @@
      */
     public static boolean checkPermissionAndCheckOp(Context context, boolean enforce,
             int pid, int uid, String packageName, String permission, int op) {
-        return checkPermissionAndAppOp(context, enforce, pid, uid, packageName, permission, op,
-                false);
+        return checkPermissionAndAppOp(context, enforce, pid, uid, packageName,
+                null /* featureId is not needed when not noting */, permission, op, false);
     }
 
     /**
      * Check that given app holds both permission and appop.
      * @hide
      */
-    private static boolean checkPermissionAndAppOp(Context context, boolean enforce,
-            int pid, int uid, String packageName, String permission, int op, boolean note) {
+    private static boolean checkPermissionAndAppOp(Context context, boolean enforce, int pid,
+            int uid, String packageName, @Nullable String featureId, String permission, int op,
+            boolean note) {
         if (context.checkPermission(permission, pid, uid) != PERMISSION_GRANTED) {
             if (enforce) {
                 throw new SecurityException(
@@ -1679,7 +1680,7 @@
         AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
         final int mode;
         if (note) {
-            mode = appOps.noteOpNoThrow(op, uid, packageName);
+            mode = appOps.noteOpNoThrow(op, uid, packageName, featureId, null);
         } else {
             try {
                 appOps.checkPackage(uid, packageName);
@@ -1711,14 +1712,15 @@
         }
     }
 
-    private boolean checkPermissionAndAppOp(boolean enforce,
-            int pid, int uid, String packageName, String permission, int op) {
-        return checkPermissionAndAppOp(mContext, enforce, pid, uid, packageName, permission, op);
+    private boolean checkPermissionAndAppOp(boolean enforce, int pid, int uid, String packageName,
+            @Nullable String featureId, String permission, int op) {
+        return checkPermissionAndAppOp(mContext, enforce, pid, uid, packageName, featureId,
+                permission, op);
     }
 
     private boolean noteAppOpAllowingLegacy(boolean enforce,
-            int pid, int uid, String packageName, int op) {
-        final int mode = mAppOps.noteOpNoThrow(op, uid, packageName);
+            int pid, int uid, String packageName, @Nullable String featureId, int op) {
+        final int mode = mAppOps.noteOpNoThrow(op, uid, packageName, featureId, null);
         switch (mode) {
             case AppOpsManager.MODE_ALLOWED:
                 return true;
@@ -1749,50 +1751,68 @@
 
     /** {@hide} */
     public boolean checkPermissionReadAudio(boolean enforce,
-            int pid, int uid, String packageName) {
-        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
-                READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false;
-        return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_READ_MEDIA_AUDIO);
+            int pid, int uid, String packageName, @Nullable String featureId) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId,
+                READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) {
+            return false;
+        }
+        return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, featureId,
+                OP_READ_MEDIA_AUDIO);
     }
 
     /** {@hide} */
     public boolean checkPermissionWriteAudio(boolean enforce,
-            int pid, int uid, String packageName) {
-        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
-                WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false;
-        return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_WRITE_MEDIA_AUDIO);
+            int pid, int uid, String packageName, @Nullable String featureId) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId,
+                WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) {
+            return false;
+        }
+        return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, featureId,
+                OP_WRITE_MEDIA_AUDIO);
     }
 
     /** {@hide} */
     public boolean checkPermissionReadVideo(boolean enforce,
-            int pid, int uid, String packageName) {
-        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
-                READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false;
-        return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_READ_MEDIA_VIDEO);
+            int pid, int uid, String packageName, @Nullable String featureId) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId,
+                READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) {
+            return false;
+        }
+        return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, featureId,
+                OP_READ_MEDIA_VIDEO);
     }
 
     /** {@hide} */
     public boolean checkPermissionWriteVideo(boolean enforce,
-            int pid, int uid, String packageName) {
-        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
-                WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false;
-        return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_WRITE_MEDIA_VIDEO);
+            int pid, int uid, String packageName, @Nullable String featureId) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId,
+                WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) {
+            return false;
+        }
+        return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, featureId,
+                OP_WRITE_MEDIA_VIDEO);
     }
 
     /** {@hide} */
     public boolean checkPermissionReadImages(boolean enforce,
-            int pid, int uid, String packageName) {
-        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
-                READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false;
-        return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_READ_MEDIA_IMAGES);
+            int pid, int uid, String packageName, @Nullable String featureId) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId,
+                READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) {
+            return false;
+        }
+        return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, featureId,
+                OP_READ_MEDIA_IMAGES);
     }
 
     /** {@hide} */
     public boolean checkPermissionWriteImages(boolean enforce,
-            int pid, int uid, String packageName) {
-        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
-                WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false;
-        return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_WRITE_MEDIA_IMAGES);
+            int pid, int uid, String packageName, @Nullable String featureId) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId,
+                WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) {
+            return false;
+        }
+        return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, featureId,
+                OP_WRITE_MEDIA_IMAGES);
     }
 
     /** {@hide} */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ac53f1b..3ac7deb 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7707,6 +7707,20 @@
         public static final String SLEEP_TIMEOUT = "sleep_timeout";
 
         /**
+         * The timeout in milliseconds before the device goes to sleep due to user inattentiveness,
+         * even if the system is holding wakelocks. It should generally be longer than {@code
+         * config_attentiveWarningDuration}, as otherwise the device will show the attentive
+         * warning constantly. Small timeouts are discouraged, as they will cause the device to
+         * go to sleep quickly after waking up.
+         * <p>
+         * Use -1 to disable this timeout.
+         * </p>
+         *
+         * @hide
+         */
+        public static final String ATTENTIVE_TIMEOUT = "attentive_timeout";
+
+        /**
          * Controls whether double tap to wake is enabled.
          * @hide
          */
@@ -14085,6 +14099,77 @@
                 "android.settings.panel.action.VOLUME";
     }
 
+    /**
+     * Activity Action: Show setting page to process the addition of Wi-Fi networks to the user's
+     * saved network list. The app should send a new intent with an extra that holds a maximum of
+     * five {@link android.net.wifi.WifiConfiguration} that specify credentials for the networks to
+     * be added to the user's database. The Intent should be sent via the {@link
+     * android.app.Activity#startActivityForResult(Intent, int)} API.
+     * <p>
+     * Note: The app sending the Intent to add the credentials doesn't get any ownership over the
+     * newly added network(s). For the Wi-Fi stack, these networks will look like the user
+     * manually added them from the Settings UI.
+     * <p>
+     * Input: The app should put parcelable array list to
+     * {@link android.net.wifi.WifiConfiguration} into the
+     * {@link #EXTRA_WIFI_CONFIGURATION_LIST} extra.
+     * <p>
+     * Output: After {@link android.app.Activity#startActivityForResult(Intent, int)}, the
+     * callback {@link android.app.Activity#onActivityResult(int, int, Intent)} will have a
+     * result code {@link android.app.Activity#RESULT_OK} to indicate user pressed the save
+     * button to save the networks or {@link android.app.Activity#RESULT_CANCELED} to indicate
+     * that the user rejected the request. Additionally, an integer array list, stored in
+     * {@link #EXTRA_WIFI_CONFIGURATION_RESULT_LIST}, will indicate the process result of
+     * each network.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_WIFI_ADD_NETWORKS =
+            "android.settings.WIFI_ADD_NETWORKS";
+
+    /**
+     * A bundle extra of {@link #ACTION_WIFI_ADD_NETWORKS} intent action that indicates all the
+     * {@link android.net.wifi.WifiConfiguration} that would be saved.
+     */
+    public static final String EXTRA_WIFI_CONFIGURATION_LIST =
+            "android.provider.extra.WIFI_CONFIGURATION_LIST";
+
+    /**
+     * A bundle extra of the result of {@link #ACTION_WIFI_ADD_NETWORKS} intent action that
+     * indicates the action result of the saved {@link android.net.wifi.WifiConfiguration}. It's
+     * value of AddWifiResult interface, and will be 1:1 mapping to the element in {@link
+     * #EXTRA_WIFI_CONFIGURATION_LIST}.
+     */
+    public static final String EXTRA_WIFI_CONFIGURATION_RESULT_LIST =
+            "android.provider.extra.WIFI_CONFIGURATION_RESULT_LIST";
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"ADD_WIFI_RESULT_"}, value = {
+            ADD_WIFI_RESULT_SUCCESS,
+            ADD_WIFI_RESULT_ADD_OR_UPDATE_FAILED,
+            ADD_WIFI_RESULT_ALREADY_EXISTS
+    })
+    public @interface AddWifiResult {
+    }
+
+    /**
+     * A result of {@link #ACTION_WIFI_ADD_NETWORKS} intent action that saving or updating the
+     * corresponding Wi-Fi network was successful.
+     */
+    public static final int ADD_WIFI_RESULT_SUCCESS = 0;
+
+    /**
+     * A result of {@link #ACTION_WIFI_ADD_NETWORKS} intent action that saving the corresponding
+     * Wi-Fi network failed.
+     */
+    public static final int ADD_WIFI_RESULT_ADD_OR_UPDATE_FAILED = 1;
+
+    /**
+     * A result of {@link #ACTION_WIFI_ADD_NETWORKS} intent action that indicates the Wi-Fi network
+     * already exists.
+     */
+    public static final int ADD_WIFI_RESULT_ALREADY_EXISTS = 2;
+
     private static final String[] PM_WRITE_SETTINGS = {
         android.Manifest.permission.WRITE_SETTINGS
     };
diff --git a/telephony/java/android/telephony/Rlog.java b/core/java/android/telephony/Rlog.java
similarity index 100%
rename from telephony/java/android/telephony/Rlog.java
rename to core/java/android/telephony/Rlog.java
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 64d6124..a080091 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -15,7 +15,6 @@
  */
 package android.telephony;
 
-import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.content.Context;
@@ -23,8 +22,6 @@
 import android.net.NetworkCapabilities;
 import android.os.Binder;
 import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerExecutor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.telephony.Annotation.ApnType;
@@ -37,19 +34,12 @@
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SimActivationState;
 import android.telephony.Annotation.SrvccState;
-import android.telephony.CallQuality;
-import android.telephony.CellInfo;
-import android.telephony.DisconnectCause;
-import android.telephony.PhoneCapability;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
 import android.telephony.ims.ImsReasonInfo;
 import android.util.Log;
 
-import com.android.internal.telephony.ITelephonyRegistry;
 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
+import com.android.internal.telephony.ITelephonyRegistry;
 
 import java.util.HashMap;
 import java.util.List;
@@ -120,7 +110,8 @@
         };
         mSubscriptionChangedListenerMap.put(listener, callback);
         try {
-            sRegistry.addOnSubscriptionsChangedListener(mContext.getOpPackageName(), callback);
+            sRegistry.addOnSubscriptionsChangedListener(mContext.getOpPackageName(),
+                    mContext.getFeatureId(), callback);
         } catch (RemoteException ex) {
             // system server crash
         }
@@ -179,7 +170,7 @@
         mOpportunisticSubscriptionChangedListenerMap.put(listener, callback);
         try {
             sRegistry.addOnOpportunisticSubscriptionsChangedListener(mContext.getOpPackageName(),
-                    callback);
+                    mContext.getFeatureId(), callback);
         } catch (RemoteException ex) {
             // system server crash
         }
diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java
index df54209..993bbe8 100644
--- a/core/java/android/text/util/Linkify.java
+++ b/core/java/android/text/util/Linkify.java
@@ -663,11 +663,8 @@
     private static void gatherTelLinks(ArrayList<LinkSpec> links, Spannable s,
             @Nullable Context context) {
         PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
-        final TelephonyManager tm = (context == null)
-                ? TelephonyManager.getDefault()
-                : TelephonyManager.from(context);
         Iterable<PhoneNumberMatch> matches = phoneUtil.findNumbers(s.toString(),
-                tm.getSimCountryIso().toUpperCase(Locale.US),
+                TelephonyManager.getDefaultSimCountryIso().toUpperCase(Locale.US),
                 Leniency.POSSIBLE, Long.MAX_VALUE);
         for (PhoneNumberMatch match : matches) {
             LinkSpec spec = new LinkSpec();
diff --git a/core/java/android/util/IconDrawableFactory.java b/core/java/android/util/IconDrawableFactory.java
index d90b65e..d86ebf3 100644
--- a/core/java/android/util/IconDrawableFactory.java
+++ b/core/java/android/util/IconDrawableFactory.java
@@ -26,8 +26,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 
-import com.android.internal.annotations.VisibleForTesting;
-
 /**
  * Utility class to load app drawables with appropriate badging.
  *
@@ -78,10 +76,10 @@
                     com.android.internal.R.drawable.ic_instant_icon_badge_bolt,
                     badgeColor);
         }
-        if (mUm.isManagedProfile(userId)) {
+        if (mUm.hasBadge(userId)) {
             icon = mLauncherIcons.getBadgedDrawable(icon,
-                    com.android.internal.R.drawable.ic_corp_icon_badge_case,
-                    getUserBadgeColor(mUm, userId));
+                    mUm.getUserIconBadgeResId(userId),
+                    mUm.getUserBadgeColor(userId));
         }
         return icon;
     }
@@ -93,23 +91,6 @@
         return mLauncherIcons.wrapIconDrawableWithShadow(icon);
     }
 
-    // Should have enough colors to cope with UserManagerService.getMaxManagedProfiles()
-    @VisibleForTesting
-    public static final int[] CORP_BADGE_COLORS = new int[] {
-            com.android.internal.R.color.profile_badge_1,
-            com.android.internal.R.color.profile_badge_2,
-            com.android.internal.R.color.profile_badge_3
-    };
-
-    public static int getUserBadgeColor(UserManager um, @UserIdInt int userId) {
-        int badge = um.getManagedProfileBadge(userId);
-        if (badge < 0) {
-            badge = 0;
-        }
-        int resourceId = CORP_BADGE_COLORS[badge % CORP_BADGE_COLORS.length];
-        return Resources.getSystem().getColor(resourceId, null);
-    }
-
     @UnsupportedAppUsage
     public static IconDrawableFactory newInstance(Context context) {
         return new IconDrawableFactory(context, true);
diff --git a/core/java/android/util/LauncherIcons.java b/core/java/android/util/LauncherIcons.java
index 8501eb5..e652e17 100644
--- a/core/java/android/util/LauncherIcons.java
+++ b/core/java/android/util/LauncherIcons.java
@@ -106,9 +106,11 @@
         Resources overlayableRes =
                 ActivityThread.currentActivityThread().getApplication().getResources();
 
+        // ic_corp_icon_badge_shadow is not work-profile-specific.
         Drawable badgeShadow = overlayableRes.getDrawable(
                 com.android.internal.R.drawable.ic_corp_icon_badge_shadow);
 
+        // ic_corp_icon_badge_color is not work-profile-specific.
         Drawable badgeColor = overlayableRes.getDrawable(
                 com.android.internal.R.drawable.ic_corp_icon_badge_color)
                 .getConstantState().newDrawable().mutate();
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 6a099d57..9e914d4 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.Point;
 import android.os.Build;
 import android.os.RemoteException;
 import android.provider.Settings;
@@ -397,7 +398,11 @@
         mWindowTouchSlop = (int) (sizeAndDensity * WINDOW_TOUCH_SLOP + 0.5f);
 
         // Size of the screen in bytes, in ARGB_8888 format
-        mMaximumDrawingCacheSize = 4 * metrics.heightPixels * metrics.widthPixels;
+        final WindowManager win = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
+        final Display display = win.getDefaultDisplay();
+        final Point size = new Point();
+        display.getRealSize(size);
+        mMaximumDrawingCacheSize = 4 * size.x * size.y;
 
         mOverscrollDistance = (int) (sizeAndDensity * OVERSCROLL_DISTANCE + 0.5f);
         mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f);
@@ -837,7 +842,6 @@
      * The maximum drawing cache size expressed in bytes.
      *
      * @return the maximum size of View's drawing cache expressed in bytes
-     *
      */
     public int getScaledMaximumDrawingCacheSize() {
         return mMaximumDrawingCacheSize;
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 36daa5c..a62ba63 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -415,6 +415,11 @@
     private static final String REMOTE_COMMAND_CAPTURE = "CAPTURE";
     private static final String REMOTE_COMMAND_DUMP = "DUMP";
     private static final String REMOTE_COMMAND_DUMP_THEME = "DUMP_THEME";
+    /**
+     * Similar to REMOTE_COMMAND_DUMP but uses ViewHierarchyEncoder instead of flat text
+     * @hide
+     */
+    public static final String REMOTE_COMMAND_DUMP_ENCODED = "DUMP_ENCODED";
     private static final String REMOTE_COMMAND_INVALIDATE = "INVALIDATE";
     private static final String REMOTE_COMMAND_REQUEST_LAYOUT = "REQUEST_LAYOUT";
     private static final String REMOTE_PROFILE = "PROFILE";
@@ -527,7 +532,6 @@
     @UnsupportedAppUsage
     static void dispatchCommand(View view, String command, String parameters,
             OutputStream clientStream) throws IOException {
-
         // Paranoid but safe...
         view = view.getRootView();
 
@@ -535,6 +539,8 @@
             dump(view, false, true, clientStream);
         } else if (REMOTE_COMMAND_DUMP_THEME.equalsIgnoreCase(command)) {
             dumpTheme(view, clientStream);
+        } else if (REMOTE_COMMAND_DUMP_ENCODED.equalsIgnoreCase(command)) {
+            dumpEncoded(view, clientStream);
         } else if (REMOTE_COMMAND_CAPTURE_LAYERS.equalsIgnoreCase(command)) {
             captureLayers(view, new DataOutputStream(clientStream));
         } else {
@@ -1198,6 +1204,18 @@
         encoder.endStream();
     }
 
+    private static void dumpEncoded(@NonNull final View view, @NonNull OutputStream out)
+            throws IOException {
+        ByteArrayOutputStream baOut = new ByteArrayOutputStream();
+
+        final ViewHierarchyEncoder encoder = new ViewHierarchyEncoder(baOut);
+        encoder.addProperty("window:left", view.mAttachInfo.mWindowLeft);
+        encoder.addProperty("window:top", view.mAttachInfo.mWindowTop);
+        view.encode(encoder);
+        encoder.endStream();
+        out.write(baOut.toByteArray());
+    }
+
     /**
      * Dumps the theme attributes from the given View.
      * @hide
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 8ee7a0e..2ea3b63 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -5402,11 +5402,10 @@
                 mTranslator.translateEventInScreenToAppWindow(event);
             }
 
-            // Enter touch mode on down or scroll, if it is coming from a touch screen device,
-            // exit otherwise.
+            // Enter touch mode if event is coming from a touch screen device.
             final int action = event.getAction();
-            if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_SCROLL) {
-                ensureTouchMode(event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN));
+            if (event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN)) {
+                ensureTouchMode(true);
             }
 
             if (action == MotionEvent.ACTION_DOWN) {
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index b33fdbb..a389555 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -4590,10 +4590,6 @@
          * @param label The label for the new AccessibilityAction.
          */
         public AccessibilityAction(int actionId, @Nullable CharSequence label) {
-            if ((actionId & ACTION_TYPE_MASK) == 0 && Integer.bitCount(actionId) != 1) {
-                throw new IllegalArgumentException("Invalid standard action id");
-            }
-
             mActionId = actionId;
             mLabel = label;
         }
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index 090e19f..ae2fb8e 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -211,6 +211,10 @@
      *        If this is greater than the number of existing characters between the cursor and
      *        the end of the text, then this method does not fail but deletes all the characters in
      *        that range.
+     *
+     * @return {@code true} when selected text is deleted, {@code false} when either the
+     *         selection is invalid or not yet attached (i.e. selection start or end is -1),
+     *         or the editable text is {@code null}.
      */
     public boolean deleteSurroundingText(int beforeLength, int afterLength) {
         if (DEBUG) Log.v(TAG, "deleteSurroundingText " + beforeLength
@@ -229,6 +233,12 @@
             b = tmp;
         }
 
+        // Skip when the selection is not yet attached.
+        if (a == -1 || b == -1) {
+            endBatchEdit();
+            return false;
+        }
+
         // Ignore the composing text.
         int ca = getComposingSpanStart(content);
         int cb = getComposingSpanEnd(content);
@@ -247,8 +257,12 @@
         if (beforeLength > 0) {
             int start = a - beforeLength;
             if (start < 0) start = 0;
-            content.delete(start, a);
-            deleted = a - start;
+
+            final int numDeleteBefore = a - start;
+            if (a >= 0 && numDeleteBefore > 0) {
+                content.delete(start, a);
+                deleted = numDeleteBefore;
+            }
         }
 
         if (afterLength > 0) {
@@ -257,7 +271,10 @@
             int end = b + afterLength;
             if (end > content.length()) end = content.length();
 
-            content.delete(b, end);
+            final int numDeleteAfter = end - b;
+            if (b >= 0 && numDeleteAfter > 0) {
+                content.delete(b, end);
+            }
         }
 
         endBatchEdit();
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index e81db16..2650a67 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -655,14 +655,14 @@
                             } catch (RemoteException e) {
                             }
                         }
-                        // Check focus again in case that "onWindowFocus" is called before
-                        // handling this message.
-                        if (mServedView != null && canStartInput(mServedView)) {
-                            if (checkFocusNoStartInput(mRestartOnNextWindowFocus)) {
-                                final int reason = active ? StartInputReason.ACTIVATED_BY_IMMS
-                                        : StartInputReason.DEACTIVATED_BY_IMMS;
-                                startInputInner(reason, null, 0, 0, 0);
-                            }
+                    }
+                    // Check focus again in case that "onWindowFocus" is called before
+                    // handling this message.
+                    if (mServedView != null && canStartInput(mServedView)) {
+                        if (checkFocusNoStartInput(mRestartOnNextWindowFocus)) {
+                            final int reason = active ? StartInputReason.ACTIVATED_BY_IMMS
+                                    : StartInputReason.DEACTIVATED_BY_IMMS;
+                            startInputInner(reason, null, 0, 0, 0);
                         }
                     }
                     return;
@@ -1225,6 +1225,10 @@
      */
     void clearBindingLocked() {
         if (DEBUG) Log.v(TAG, "Clearing binding!");
+        if (mWindowFocusGainFuture != null) {
+            mWindowFocusGainFuture.cancel(false /* mayInterruptIfRunning */);
+            mWindowFocusGainFuture = null;
+        }
         clearConnectionLocked();
         setInputChannelLocked(null);
         mBindSequence = -1;
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 9fbd48e..6c372e4 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -96,10 +96,7 @@
 import android.view.ViewGroup.LayoutParams;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
-import android.widget.AbsListView;
-import android.widget.BaseAdapter;
 import android.widget.ImageView;
-import android.widget.ListView;
 import android.widget.TextView;
 import android.widget.Toast;
 
@@ -118,6 +115,8 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.ImageUtils;
+import com.android.internal.widget.GridLayoutManager;
+import com.android.internal.widget.RecyclerView;
 import com.android.internal.widget.ResolverDrawerLayout;
 
 import com.google.android.collect.Lists;
@@ -167,6 +166,7 @@
 
     @VisibleForTesting
     public static final int LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS = 250;
+    private static final int SINGLE_CELL_SPAN_SIZE = 1;
 
     private boolean mIsAppPredictorComponentAvailable;
     private AppPredictor mAppPredictor;
@@ -222,8 +222,9 @@
     private long mQueriedTargetServicesTimeMs;
     private long mQueriedSharingShortcutsTimeMs;
 
+    private RecyclerView mRecyclerView;
     private ChooserListAdapter mChooserListAdapter;
-    private ChooserRowAdapter mChooserRowAdapter;
+    private ChooserGridAdapter mChooserGridAdapter;
     private int mChooserRowServiceSpacing;
 
     private int mCurrAvailableWidth = 0;
@@ -351,8 +352,8 @@
                 Log.i(TAG, "Hiding image preview area. Timed out waiting for preview to load"
                         + " within " + mImageLoadTimeoutMillis + "ms.");
                 collapseParentView();
-                if (mChooserRowAdapter != null) {
-                    mChooserRowAdapter.hideContentPreview();
+                if (mChooserGridAdapter != null) {
+                    mChooserGridAdapter.hideContentPreview();
                 }
                 mHideParentOnFail = false;
             }
@@ -671,14 +672,14 @@
             final float chooserHeaderScrollElevation =
                     getResources().getDimensionPixelSize(R.dimen.chooser_header_scroll_elevation);
 
-            mAdapterView.setOnScrollListener(new AbsListView.OnScrollListener() {
-                public void onScrollStateChanged(AbsListView view, int scrollState) {
+            mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
+                public void onScrollStateChanged(RecyclerView view, int scrollState) {
                 }
 
-                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
-                        int totalItemCount) {
+                public void onScrolled(RecyclerView view, int dx, int dy) {
                     if (view.getChildCount() > 0) {
-                        if (firstVisibleItem > 0 || view.getChildAt(0).getTop() < 0) {
+                        View child = view.getLayoutManager().findViewByPosition(0);
+                        if (child == null || child.getTop() < 0) {
                             chooserHeader.setElevation(chooserHeaderScrollElevation);
                             return;
                         }
@@ -847,10 +848,7 @@
     }
 
     private ViewGroup displayContentPreview(@ContentPreviewType int previewType,
-            Intent targetIntent, LayoutInflater layoutInflater, ViewGroup convertView,
-            ViewGroup parent) {
-        if (convertView != null) return convertView;
-
+            Intent targetIntent, LayoutInflater layoutInflater, ViewGroup parent) {
         ViewGroup layout = null;
 
         switch (previewType) {
@@ -1213,16 +1211,30 @@
     }
 
     @Override
-    public void onPrepareAdapterView(AbsListView adapterView, ResolverListAdapter adapter) {
-        final ListView listView = adapterView instanceof ListView ? (ListView) adapterView : null;
+    public void onPrepareAdapterView(ResolverListAdapter adapter, boolean isVisible) {
+        mRecyclerView = findViewById(R.id.resolver_list);
+        if (!isVisible) {
+            mRecyclerView.setVisibility(View.GONE);
+            return;
+        }
+        mRecyclerView.setVisibility(View.VISIBLE);
         if (mCallerChooserTargets != null && mCallerChooserTargets.length > 0) {
             mChooserListAdapter.addServiceResults(null, Lists.newArrayList(mCallerChooserTargets),
                     TARGET_TYPE_DEFAULT);
         }
-        mChooserRowAdapter = new ChooserRowAdapter(mChooserListAdapter);
-        if (listView != null) {
-            listView.setItemsCanFocus(true);
-        }
+        mChooserGridAdapter = new ChooserGridAdapter(mChooserListAdapter);
+        GridLayoutManager glm = (GridLayoutManager) mRecyclerView.getLayoutManager();
+        glm.setSpanCount(mChooserGridAdapter.getMaxTargetsPerRow());
+        glm.setSpanSizeLookup(
+                new GridLayoutManager.SpanSizeLookup() {
+                    @Override
+                    public int getSpanSize(int position) {
+                        return mChooserGridAdapter.getItemViewType(position)
+                                == ChooserGridAdapter.VIEW_TYPE_NORMAL
+                                ? SINGLE_CELL_SPAN_SIZE
+                                : glm.getSpanCount();
+                    }
+                });
     }
 
     @Override
@@ -1996,8 +2008,8 @@
     }
 
     private void handleScroll(View view, int x, int y, int oldx, int oldy) {
-        if (mChooserRowAdapter != null) {
-            mChooserRowAdapter.handleScroll(view, y, oldy);
+        if (mChooserGridAdapter != null) {
+            mChooserGridAdapter.handleScroll(view, y, oldy);
         }
     }
 
@@ -2008,35 +2020,37 @@
      */
     private void handleLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
             int oldTop, int oldRight, int oldBottom) {
-        if (mChooserRowAdapter == null || mAdapterView == null) {
+        if (mChooserGridAdapter == null || mRecyclerView == null) {
             return;
         }
 
         final int availableWidth = right - left - v.getPaddingLeft() - v.getPaddingRight();
-        if (mChooserRowAdapter.consumeLayoutRequest()
-                || mChooserRowAdapter.calculateChooserTargetWidth(availableWidth)
-                || mAdapterView.getAdapter() == null
+        if (mChooserGridAdapter.consumeLayoutRequest()
+                || mChooserGridAdapter.calculateChooserTargetWidth(availableWidth)
+                || mRecyclerView.getAdapter() == null
                 || availableWidth != mCurrAvailableWidth) {
             mCurrAvailableWidth = availableWidth;
-            mAdapterView.setAdapter(mChooserRowAdapter);
+            mRecyclerView.setAdapter(mChooserGridAdapter);
+            ((GridLayoutManager) mRecyclerView.getLayoutManager())
+                    .setSpanCount(mChooserGridAdapter.getMaxTargetsPerRow());
 
             getMainThreadHandler().post(() -> {
-                if (mResolverDrawerLayout == null || mChooserRowAdapter == null) {
+                if (mResolverDrawerLayout == null || mChooserGridAdapter == null) {
                     return;
                 }
 
                 final int bottomInset = mSystemWindowInsets != null
                                             ? mSystemWindowInsets.bottom : 0;
                 int offset = bottomInset;
-                int rowsToShow = mChooserRowAdapter.getContentPreviewRowCount()
-                        + mChooserRowAdapter.getProfileRowCount()
-                        + mChooserRowAdapter.getServiceTargetRowCount()
-                        + mChooserRowAdapter.getCallerAndRankedTargetRowCount();
+                int rowsToShow = mChooserGridAdapter.getContentPreviewRowCount()
+                        + mChooserGridAdapter.getProfileRowCount()
+                        + mChooserGridAdapter.getServiceTargetRowCount()
+                        + mChooserGridAdapter.getCallerAndRankedTargetRowCount();
 
                 // then this is most likely not a SEND_* action, so check
                 // the app target count
                 if (rowsToShow == 0) {
-                    rowsToShow = mChooserRowAdapter.getCount();
+                    rowsToShow = mChooserGridAdapter.getRowCount();
                 }
 
                 // still zero? then use a default height and leave, which
@@ -2050,15 +2064,22 @@
 
                 int directShareHeight = 0;
                 rowsToShow = Math.min(4, rowsToShow);
-                for (int i = 0; i < Math.min(rowsToShow, mAdapterView.getChildCount()); i++) {
-                    View child = mAdapterView.getChildAt(i);
+                for (int i = 0, childCount = mRecyclerView.getChildCount();
+                        i < childCount && rowsToShow > 0; i++) {
+                    View child = mRecyclerView.getChildAt(i);
+                    if (((GridLayoutManager.LayoutParams)
+                            child.getLayoutParams()).getSpanIndex() != 0) {
+                        continue;
+                    }
                     int height = child.getHeight();
                     offset += height;
 
-                    if (child.getTag() != null
-                            && (child.getTag() instanceof DirectShareViewHolder)) {
+                    if (mChooserGridAdapter.getTargetType(
+                            mRecyclerView.getChildAdapterPosition(child))
+                            == mChooserListAdapter.TARGET_SERVICE) {
                         directShareHeight = height;
                     }
+                    rowsToShow--;
                 }
 
                 boolean isExpandable = getResources().getConfiguration().orientation
@@ -2107,7 +2128,9 @@
 
     @Override // ChooserListCommunicator
     public int getMaxRankedTargets() {
-        return mChooserRowAdapter == null ? 4 : mChooserRowAdapter.getMaxTargetsPerRow();
+        return mChooserGridAdapter == null
+                ? ChooserGridAdapter.MAX_TARGETS_PER_ROW_PORTRAIT
+                : mChooserGridAdapter.getMaxTargetsPerRow();
     }
 
     @Override // ChooserListCommunicator
@@ -2175,7 +2198,40 @@
         return false;
     }
 
-    class ChooserRowAdapter extends BaseAdapter {
+    /**
+     * Used to bind types of individual item including
+     * {@link ChooserGridAdapter#VIEW_TYPE_NORMAL},
+     * {@link ChooserGridAdapter#VIEW_TYPE_CONTENT_PREVIEW},
+     * {@link ChooserGridAdapter#VIEW_TYPE_PROFILE},
+     * and {@link ChooserGridAdapter#VIEW_TYPE_AZ_LABEL}.
+     */
+    final class ItemViewHolder extends RecyclerView.ViewHolder {
+        ResolverListAdapter.ViewHolder mWrappedViewHolder;
+        int mListPosition = ChooserListAdapter.NO_POSITION;
+
+        ItemViewHolder(View itemView, boolean isClickable) {
+            super(itemView);
+            mWrappedViewHolder = new ResolverListAdapter.ViewHolder(itemView);
+            if (isClickable) {
+                itemView.setOnClickListener(v -> startSelected(mListPosition,
+                        false/* always */, true/* filterd */));
+                itemView.setOnLongClickListener(v -> {
+                    showTargetDetails(
+                            mChooserListAdapter.resolveInfoForPosition(
+                                    mListPosition, true/* filtered */));
+                    return true;
+                });
+            }
+        }
+    }
+
+    /**
+     * Adapter for all types of items and targets in ShareSheet.
+     * Note that ranked sections like Direct Share - while appearing grid-like - are handled on the
+     * row level by this adapter but not on the item level. Individual targets within the row are
+     * handled by {@link ChooserListAdapter}
+     */
+    final class ChooserGridAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
         private ChooserListAdapter mChooserListAdapter;
         private final LayoutInflater mLayoutInflater;
 
@@ -2191,13 +2247,15 @@
         private static final int VIEW_TYPE_CONTENT_PREVIEW = 2;
         private static final int VIEW_TYPE_PROFILE = 3;
         private static final int VIEW_TYPE_AZ_LABEL = 4;
+        private static final int VIEW_TYPE_CALLER_AND_RANK = 5;
 
         private static final int MAX_TARGETS_PER_ROW_PORTRAIT = 4;
         private static final int MAX_TARGETS_PER_ROW_LANDSCAPE = 8;
 
         private static final int NUM_EXPANSIONS_TO_HIDE_AZ_LABEL = 20;
 
-        public ChooserRowAdapter(ChooserListAdapter wrappedAdapter) {
+        ChooserGridAdapter(ChooserListAdapter wrappedAdapter) {
+            super();
             mChooserListAdapter = wrappedAdapter;
             mLayoutInflater = LayoutInflater.from(ChooserActivity.this);
 
@@ -2213,7 +2271,7 @@
                 @Override
                 public void onInvalidated() {
                     super.onInvalidated();
-                    notifyDataSetInvalidated();
+                    notifyDataSetChanged();
                 }
             });
         }
@@ -2229,7 +2287,7 @@
                 return false;
             }
 
-            int newWidth =  width / getMaxTargetsPerRow();
+            int newWidth = width / getMaxTargetsPerRow();
             if (newWidth != mChooserTargetWidth) {
                 mChooserTargetWidth = newWidth;
                 return true;
@@ -2259,22 +2317,7 @@
             return oldValue;
         }
 
-        @Override
-        public boolean areAllItemsEnabled() {
-            return false;
-        }
-
-        @Override
-        public boolean isEnabled(int position) {
-            int viewType = getItemViewType(position);
-            if (viewType == VIEW_TYPE_CONTENT_PREVIEW || viewType == VIEW_TYPE_AZ_LABEL) {
-                return false;
-            }
-            return true;
-        }
-
-        @Override
-        public int getCount() {
+        public int getRowCount() {
             return (int) (
                     getContentPreviewRowCount()
                             + getProfileRowCount()
@@ -2326,42 +2369,50 @@
         }
 
         @Override
-        public Object getItem(int position) {
-            // We have nothing useful to return here.
-            return position;
+        public int getItemCount() {
+            return (int) (
+                    getContentPreviewRowCount()
+                            + getProfileRowCount()
+                            + getServiceTargetRowCount()
+                            + getCallerAndRankedTargetRowCount()
+                            + getAzLabelRowCount()
+                            + mChooserListAdapter.getAlphaTargetCount()
+            );
         }
 
         @Override
-        public long getItemId(int position) {
-            return position;
+        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+            switch (viewType) {
+                case VIEW_TYPE_CONTENT_PREVIEW:
+                    return new ItemViewHolder(createContentPreviewView(parent), false);
+                case VIEW_TYPE_PROFILE:
+                    return new ItemViewHolder(createProfileView(parent), false);
+                case VIEW_TYPE_AZ_LABEL:
+                    return new ItemViewHolder(createAzLabelView(parent), false);
+                case VIEW_TYPE_NORMAL:
+                    return new ItemViewHolder(mChooserListAdapter.createView(parent), true);
+                case VIEW_TYPE_DIRECT_SHARE:
+                case VIEW_TYPE_CALLER_AND_RANK:
+                    return createItemGroupViewHolder(viewType, parent);
+                default:
+                    // Since we catch all possible viewTypes above, no chance this is being called.
+                    return null;
+            }
         }
 
         @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            final RowViewHolder holder;
+        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
             int viewType = getItemViewType(position);
-
-            if (viewType == VIEW_TYPE_CONTENT_PREVIEW) {
-                return createContentPreviewView(convertView, parent);
+            switch (viewType) {
+                case VIEW_TYPE_DIRECT_SHARE:
+                case VIEW_TYPE_CALLER_AND_RANK:
+                    bindItemGroupViewHolder(position, (ItemGroupViewHolder) holder);
+                    break;
+                case VIEW_TYPE_NORMAL:
+                    bindItemViewHolder(position, (ItemViewHolder) holder);
+                    break;
+                default:
             }
-
-            if (viewType == VIEW_TYPE_PROFILE) {
-                return createProfileView(convertView, parent);
-            }
-
-            if (viewType == VIEW_TYPE_AZ_LABEL) {
-                return createAzLabelView(parent);
-            }
-
-            if (convertView == null) {
-                holder = createViewHolder(viewType, parent);
-            } else {
-                holder = (RowViewHolder) convertView.getTag();
-            }
-
-            bindViewHolder(position, holder);
-
-            return holder.getViewGroup();
         }
 
         @Override
@@ -2378,7 +2429,7 @@
             if (count > 0 && position < countSum) return VIEW_TYPE_DIRECT_SHARE;
 
             countSum += (count = getCallerAndRankedTargetRowCount());
-            if (count > 0 && position < countSum) return VIEW_TYPE_NORMAL;
+            if (count > 0 && position < countSum) return VIEW_TYPE_CALLER_AND_RANK;
 
             countSum += (count = getAzLabelRowCount());
             if (count > 0 && position < countSum) return VIEW_TYPE_AZ_LABEL;
@@ -2386,27 +2437,22 @@
             return VIEW_TYPE_NORMAL;
         }
 
-        @Override
-        public int getViewTypeCount() {
-            return 5;
+        public int getTargetType(int position) {
+            return mChooserListAdapter.getPositionTargetType(getListPosition(position));
         }
 
-        private ViewGroup createContentPreviewView(View convertView, ViewGroup parent) {
+        private ViewGroup createContentPreviewView(ViewGroup parent) {
             Intent targetIntent = getTargetIntent();
             int previewType = findPreferredContentPreview(targetIntent, getContentResolver());
 
-            if (convertView == null) {
-                getMetricsLogger().write(new LogMaker(MetricsEvent.ACTION_SHARE_WITH_PREVIEW)
+            getMetricsLogger().write(new LogMaker(MetricsEvent.ACTION_SHARE_WITH_PREVIEW)
                         .setSubtype(previewType));
-            }
 
-            return displayContentPreview(previewType, targetIntent, mLayoutInflater,
-                    (ViewGroup) convertView, parent);
+            return displayContentPreview(previewType, targetIntent, mLayoutInflater, parent);
         }
 
-        private View createProfileView(View convertView, ViewGroup parent) {
-            View profileRow = convertView != null ? convertView : mLayoutInflater.inflate(
-                    R.layout.chooser_profile_row, parent, false);
+        private View createProfileView(ViewGroup parent) {
+            View profileRow = mLayoutInflater.inflate(R.layout.chooser_profile_row, parent, false);
             profileRow.setBackground(
                     getResources().getDrawable(R.drawable.chooser_row_layer_list, null));
             mProfileView = profileRow.findViewById(R.id.profile_button);
@@ -2419,7 +2465,7 @@
             return mLayoutInflater.inflate(R.layout.chooser_az_label_row, parent, false);
         }
 
-        private RowViewHolder loadViewsIntoRow(RowViewHolder holder) {
+        private ItemGroupViewHolder loadViewsIntoGroup(ItemGroupViewHolder holder) {
             final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
             final int exactSpec = MeasureSpec.makeMeasureSpec(mChooserTargetWidth,
                     MeasureSpec.EXACTLY);
@@ -2445,7 +2491,7 @@
                         return true;
                     }
                 });
-                ViewGroup row = holder.addView(i, v);
+                holder.addView(i, v);
 
                 // Force Direct Share to be 2 lines and auto-wrap to second line via hoz scroll =
                 // false. TextView#setHorizontallyScrolling must be reset after #setLines. Must be
@@ -2490,7 +2536,7 @@
             }
         }
 
-        RowViewHolder createViewHolder(int viewType, ViewGroup parent) {
+        ItemGroupViewHolder createItemGroupViewHolder(int viewType, ViewGroup parent) {
             if (viewType == VIEW_TYPE_DIRECT_SHARE) {
                 ViewGroup parentGroup = (ViewGroup) mLayoutInflater.inflate(
                         R.layout.chooser_row_direct_share, parent, false);
@@ -2503,14 +2549,14 @@
 
                 mDirectShareViewHolder = new DirectShareViewHolder(parentGroup,
                         Lists.newArrayList(row1, row2), getMaxTargetsPerRow());
-                loadViewsIntoRow(mDirectShareViewHolder);
+                loadViewsIntoGroup(mDirectShareViewHolder);
 
                 return mDirectShareViewHolder;
             } else {
                 ViewGroup row = (ViewGroup) mLayoutInflater.inflate(R.layout.chooser_row, parent,
                         false);
-                RowViewHolder holder = new SingleRowViewHolder(row, getMaxTargetsPerRow());
-                loadViewsIntoRow(holder);
+                ItemGroupViewHolder holder = new SingleRowViewHolder(row, getMaxTargetsPerRow());
+                loadViewsIntoGroup(holder);
 
                 return holder;
             }
@@ -2538,19 +2584,20 @@
             return positionType;
         }
 
-        void bindViewHolder(int rowPosition, RowViewHolder holder) {
-            final int start = getFirstRowPosition(rowPosition);
-            final int startType = getRowType(start);
-            final int lastStartType = getRowType(getFirstRowPosition(rowPosition - 1));
+        void bindItemViewHolder(int position, ItemViewHolder holder) {
+            View v = holder.itemView;
+            int listPosition = getListPosition(position);
+            holder.mListPosition = listPosition;
+            mChooserListAdapter.bindView(listPosition, v);
+        }
 
-            final ViewGroup row = holder.getViewGroup();
-
-            if (startType != lastStartType
-                    || rowPosition == getContentPreviewRowCount() + getProfileRowCount()) {
-                row.setForeground(
+        void bindItemGroupViewHolder(int position, ItemGroupViewHolder holder) {
+            final ViewGroup viewGroup = (ViewGroup) holder.itemView;
+            int start = getListPosition(position);
+            int startType = getRowType(start);
+            if (viewGroup.getForeground() == null) {
+                viewGroup.setForeground(
                         getResources().getDrawable(R.drawable.chooser_row_layer_list, null));
-            } else {
-                row.setForeground(null);
             }
 
             int columnCount = holder.getColumnCount();
@@ -2560,7 +2607,7 @@
             }
 
             if (end == start && mChooserListAdapter.getItem(start) instanceof EmptyTargetInfo) {
-                final TextView textView = row.findViewById(R.id.chooser_row_text_option);
+                final TextView textView = viewGroup.findViewById(R.id.chooser_row_text_option);
 
                 if (textView.getVisibility() != View.VISIBLE) {
                     textView.setAlpha(0.0f);
@@ -2597,27 +2644,28 @@
             }
         }
 
-        int getFirstRowPosition(int row) {
-            row -= getContentPreviewRowCount() + getProfileRowCount();
+        int getListPosition(int position) {
+            position -= getContentPreviewRowCount() + getProfileRowCount();
 
             final int serviceCount = mChooserListAdapter.getServiceTargetCount();
             final int serviceRows = (int) Math.ceil((float) serviceCount
                     / ChooserListAdapter.MAX_SERVICE_TARGETS);
-            if (row < serviceRows) {
-                return row * getMaxTargetsPerRow();
+            if (position < serviceRows) {
+                return position * getMaxTargetsPerRow();
             }
 
+            position -= serviceRows;
+
             final int callerAndRankedCount = mChooserListAdapter.getCallerTargetCount()
                                                  + mChooserListAdapter.getRankedTargetCount();
             final int callerAndRankedRows = getCallerAndRankedTargetRowCount();
-            if (row < callerAndRankedRows + serviceRows) {
-                return serviceCount + (row - serviceRows) * getMaxTargetsPerRow();
+            if (position < callerAndRankedRows) {
+                return serviceCount + position * getMaxTargetsPerRow();
             }
 
-            row -= getAzLabelRowCount();
+            position -= getAzLabelRowCount() + callerAndRankedRows;
 
-            return callerAndRankedCount + serviceCount
-                    + (row - callerAndRankedRows - serviceRows) * getMaxTargetsPerRow();
+            return callerAndRankedCount + serviceCount + position;
         }
 
         public void handleScroll(View v, int y, int oldy) {
@@ -2631,18 +2679,24 @@
                     && !isInMultiWindowMode();
 
             if (mDirectShareViewHolder != null && canExpandDirectShare) {
-                mDirectShareViewHolder.handleScroll(mAdapterView, y, oldy, getMaxTargetsPerRow());
+                mDirectShareViewHolder.handleScroll(mRecyclerView, y, oldy, getMaxTargetsPerRow());
             }
         }
     }
 
-    abstract class RowViewHolder {
+    /**
+     * Used to bind types for group of items including:
+     * {@link ChooserGridAdapter#VIEW_TYPE_DIRECT_SHARE},
+     * and {@link ChooserGridAdapter#VIEW_TYPE_CALLER_AND_RANK}.
+     */
+    abstract class ItemGroupViewHolder extends RecyclerView.ViewHolder {
         protected int mMeasuredRowHeight;
         private int[] mItemIndices;
         protected final View[] mCells;
         private final int mColumnCount;
 
-        RowViewHolder(int cellCount) {
+        ItemGroupViewHolder(int cellCount, View itemView) {
+            super(itemView);
             this.mCells = new View[cellCount];
             this.mItemIndices = new int[cellCount];
             this.mColumnCount = cellCount;
@@ -2685,11 +2739,11 @@
         }
     }
 
-    class SingleRowViewHolder extends RowViewHolder {
+    class SingleRowViewHolder extends ItemGroupViewHolder {
         private final ViewGroup mRow;
 
         SingleRowViewHolder(ViewGroup row, int cellCount) {
-            super(cellCount);
+            super(cellCount, row);
 
             this.mRow = row;
         }
@@ -2719,7 +2773,7 @@
         }
     }
 
-    class DirectShareViewHolder extends RowViewHolder {
+    class DirectShareViewHolder extends ItemGroupViewHolder {
         private final ViewGroup mParent;
         private final List<ViewGroup> mRows;
         private int mCellCountPerRow;
@@ -2732,7 +2786,7 @@
         private final boolean[] mCellVisibility;
 
         DirectShareViewHolder(ViewGroup parent, List<ViewGroup> rows, int cellCountPerRow) {
-            super(rows.size() * cellCountPerRow);
+            super(rows.size() * cellCountPerRow, parent);
 
             this.mParent = parent;
             this.mRows = rows;
@@ -2767,7 +2821,7 @@
 
             mDirectShareMinHeight = getRow(0).getMeasuredHeight();
             mDirectShareCurrHeight = mDirectShareCurrHeight > 0
-                                         ? mDirectShareCurrHeight : mDirectShareMinHeight;
+                    ? mDirectShareCurrHeight : mDirectShareMinHeight;
             mDirectShareMaxHeight = 2 * mDirectShareMinHeight;
         }
 
@@ -2800,7 +2854,7 @@
             }
         }
 
-        public void handleScroll(AbsListView view, int y, int oldy, int maxTargetsPerRow) {
+        public void handleScroll(RecyclerView view, int y, int oldy, int maxTargetsPerRow) {
             // only exit early if fully collapsed, otherwise onListRebuilt() with shifting
             // targets can lock us into an expanded mode
             boolean notExpanded = mDirectShareCurrHeight == mDirectShareMinHeight;
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index 38f4c64..4eccf21 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -49,6 +49,7 @@
     private static final String TAG = "ChooserListAdapter";
     private static final boolean DEBUG = false;
 
+    public static final int NO_POSITION = -1;
     public static final int TARGET_BAD = -1;
     public static final int TARGET_CALLER = 0;
     public static final int TARGET_SERVICE = 1;
@@ -189,7 +190,7 @@
     }
 
     @Override
-    public View onCreateView(ViewGroup parent) {
+    View onCreateView(ViewGroup parent) {
         return mInflater.inflate(
                 com.android.internal.R.layout.resolve_grid_item, parent, false);
     }
@@ -321,6 +322,10 @@
      */
     @Override
     public TargetInfo targetInfoForPosition(int position, boolean filtered) {
+        if (position == NO_POSITION) {
+            return null;
+        }
+
         int offset = 0;
 
         // Direct share targets
diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java
index c11089b..49f77e1 100644
--- a/core/java/com/android/internal/app/LocaleStore.java
+++ b/core/java/com/android/internal/app/LocaleStore.java
@@ -194,7 +194,7 @@
     private static Set<String> getSimCountries(Context context) {
         Set<String> result = new HashSet<>();
 
-        TelephonyManager tm = TelephonyManager.from(context);
+        TelephonyManager tm = context.getSystemService(TelephonyManager.class);
 
         if (tm != null) {
             String iso = tm.getSimCountryIso().toUpperCase(Locale.US);
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 3b352a9..0997cf8 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -97,7 +97,7 @@
     @UnsupportedAppUsage
     protected ResolverListAdapter mAdapter;
     private boolean mSafeForwardingMode;
-    protected AbsListView mAdapterView;
+    private AbsListView mAdapterView;
     private Button mAlwaysButton;
     private Button mOnceButton;
     protected View mProfileView;
@@ -1075,7 +1075,6 @@
             mLayoutId = getLayoutResource();
         }
         setContentView(mLayoutId);
-        mAdapterView = findViewById(R.id.resolver_list);
         return postRebuildList(rebuildCompleted);
     }
 
@@ -1114,26 +1113,37 @@
             }
         }
 
+        boolean isAdapterViewVisible = true;
         if (count == 0 && mAdapter.getPlaceholderCount() == 0) {
             final TextView emptyView = findViewById(R.id.empty);
             emptyView.setVisibility(View.VISIBLE);
-            mAdapterView.setVisibility(View.GONE);
-        } else {
-            mAdapterView.setVisibility(View.VISIBLE);
-            onPrepareAdapterView(mAdapterView, mAdapter);
+            isAdapterViewVisible = false;
         }
+
+        onPrepareAdapterView(mAdapter, isAdapterViewVisible);
         return false;
     }
 
-    public void onPrepareAdapterView(AbsListView adapterView, ResolverListAdapter adapter) {
+    /**
+     * Prepare the scrollable view which consumes data in the list adapter.
+     * @param adapter The adapter used to provide data to item views.
+     * @param isVisible True if the scrollable view should be visible; false, otherwise.
+     */
+    public void onPrepareAdapterView(ResolverListAdapter adapter, boolean isVisible) {
+        mAdapterView = findViewById(R.id.resolver_list);
+        if (!isVisible) {
+            mAdapterView.setVisibility(View.GONE);
+            return;
+        }
+        mAdapterView.setVisibility(View.VISIBLE);
         final boolean useHeader = adapter.hasFilteredItem();
-        final ListView listView = adapterView instanceof ListView ? (ListView) adapterView : null;
+        final ListView listView = mAdapterView instanceof ListView ? (ListView) mAdapterView : null;
 
-        adapterView.setAdapter(mAdapter);
+        mAdapterView.setAdapter(mAdapter);
 
         final ItemClickListener listener = new ItemClickListener();
-        adapterView.setOnItemClickListener(listener);
-        adapterView.setOnItemLongClickListener(listener);
+        mAdapterView.setOnItemClickListener(listener);
+        mAdapterView.setOnItemLongClickListener(listener);
 
         if (mSupportsAlwaysUseOption || mUseLayoutForBrowsables) {
             listView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index 0286aa6..4570c6f 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -491,7 +491,7 @@
         return view;
     }
 
-    public View onCreateView(ViewGroup parent) {
+    View onCreateView(ViewGroup parent) {
         return mInflater.inflate(
                 com.android.internal.R.layout.resolve_list_item, parent, false);
     }
diff --git a/core/java/com/android/internal/car/ICarStatsService.aidl b/core/java/com/android/internal/car/ICarStatsService.aidl
new file mode 100644
index 0000000..170b448
--- /dev/null
+++ b/core/java/com/android/internal/car/ICarStatsService.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.car;
+
+import android.os.StatsLogEventWrapper;
+
+/**
+ * Interface for pulling statsd atoms from automotive devices.
+ *
+ * @hide
+ */
+interface ICarStatsService {
+    /**
+     * Pull the specified atom. Results will be sent to statsd when complete.
+     */
+    StatsLogEventWrapper[] pullData(int atomId);
+}
diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl
index 5857642..045a680 100644
--- a/core/java/com/android/internal/compat/IPlatformCompat.aidl
+++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl
@@ -133,7 +133,7 @@
     boolean isChangeEnabledByUid(long changeId, int uid);
 
     /**
-     * Add overrides to compatibility changes.
+     * Add overrides to compatibility changes. Kills the app to allow the changes to take effect.
      *
      * @param overrides Parcelable containing the compat change overrides to be applied.
      * @param packageName The package name of the app whose changes will be overridden.
@@ -142,7 +142,28 @@
     void setOverrides(in CompatibilityChangeConfig overrides, in String packageName);
 
     /**
-     * Revert overrides to compatibility changes.
+     * Add overrides to compatibility changes. Doesn't kill the app, to be only used in tests.
+     *
+     * @param overrides Parcelable containing the compat change overrides to be applied.
+     * @param packageName The package name of the app whose changes will be overridden.
+     *
+     */
+    void setOverridesForTest(in CompatibilityChangeConfig overrides, in String packageName);
+
+    /**
+     * Removes an override previously added via {@link #setOverrides(CompatibilityChangeConfig,
+     * String)}. This restores the default behaviour for the given change and app, once any app
+     * processes have been restarted.
+     * Kills the app to allow the changes to take effect.
+     *
+     * @param changeId    The ID of the change that was overridden.
+     * @param packageName The app package name that was overridden.
+     * @return {@code true} if an override existed;
+     */
+    boolean clearOverride(long changeId, String packageName);
+
+    /**
+     * Revert overrides to compatibility changes. Kills the app to allow the changes to take effect.
      *
      * @param packageName The package name of the app whose overrides will be cleared.
      *
diff --git a/core/java/com/android/internal/package-info.java b/core/java/com/android/internal/package-info.java
new file mode 100644
index 0000000..8a226db
--- /dev/null
+++ b/core/java/com/android/internal/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * @hide
+ */
+package com.android.internal;
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 73f549a..20706bb 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -188,4 +188,14 @@
      * @param types the internal insets types of the bars are about to abort the transient state.
      */
     void abortTransient(int displayId, in int[] types);
+
+    /**
+     * Show a warning that the device is about to go to sleep due to user inactivity.
+     */
+    void showInattentiveSleepWarning();
+
+    /**
+     * Dismiss the warning that the device is about to go to sleep due to user inactivity.
+     */
+    void dismissInattentiveSleepWarning();
 }
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 3f08710..76235a4 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -113,4 +113,14 @@
     void onBiometricError(int modality, int error, int vendorCode);
     // Used to hide the authentication dialog, e.g. when the application cancels authentication
     void hideAuthenticationDialog();
+
+    /**
+     * Show a warning that the device is about to go to sleep due to user inactivity.
+     */
+    void showInattentiveSleepWarning();
+
+    /**
+     * Dismiss the warning that the device is about to go to sleep due to user inactivity.
+     */
+    void dismissInattentiveSleepWarning();
 }
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index d7a7af1..9ae0ba5 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -32,16 +32,22 @@
 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
 
 interface ITelephonyRegistry {
-    void addOnSubscriptionsChangedListener(String pkg,
+    void addOnSubscriptionsChangedListener(String pkg, String featureId,
             IOnSubscriptionsChangedListener callback);
-    void addOnOpportunisticSubscriptionsChangedListener(String pkg,
+    void addOnOpportunisticSubscriptionsChangedListener(String pkg, String featureId,
             IOnSubscriptionsChangedListener callback);
     void removeOnSubscriptionsChangedListener(String pkg,
             IOnSubscriptionsChangedListener callback);
+    /**
+      * @deprecated Use {@link #listenWithFeature(String, String, IPhoneStateListener, int,
+      * boolean) instead
+      */
     @UnsupportedAppUsage
     void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow);
-    void listenForSubscriber(in int subId, String pkg, IPhoneStateListener callback, int events,
+    void listenWithFeature(String pkg, String featureId, IPhoneStateListener callback, int events,
             boolean notifyNow);
+    void listenForSubscriber(in int subId, String pkg, String featureId,
+            IPhoneStateListener callback, int events, boolean notifyNow);
     @UnsupportedAppUsage
     void notifyCallStateForAllSubs(int state, String incomingNumber);
     void notifyCallState(in int phoneId, in int subId, int state, String incomingNumber);
diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java
index cac691c..f6f187f 100644
--- a/core/java/com/android/internal/util/ScreenshotHelper.java
+++ b/core/java/com/android/internal/util/ScreenshotHelper.java
@@ -6,6 +6,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.net.Uri;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
@@ -58,7 +59,7 @@
      */
     public void takeScreenshot(final int screenshotType, final boolean hasStatus,
             final boolean hasNav, @NonNull Handler handler,
-            @Nullable Consumer<Boolean> completionConsumer) {
+            @Nullable Consumer<Uri> completionConsumer) {
         takeScreenshot(screenshotType, hasStatus, hasNav, SCREENSHOT_TIMEOUT_MS, handler,
                 completionConsumer);
     }
@@ -88,7 +89,7 @@
      */
     public void takeScreenshot(final int screenshotType, final boolean hasStatus,
             final boolean hasNav, long timeoutMs, @NonNull Handler handler,
-            @Nullable Consumer<Boolean> completionConsumer) {
+            @Nullable Consumer<Uri> completionConsumer) {
         synchronized (mScreenshotLock) {
             if (mScreenshotConnection != null) {
                 return;
@@ -108,7 +109,7 @@
                         }
                     }
                     if (completionConsumer != null) {
-                        completionConsumer.accept(false);
+                        completionConsumer.accept(null);
                     }
                 }
             };
@@ -135,7 +136,7 @@
                                     }
                                 }
                                 if (completionConsumer != null) {
-                                    completionConsumer.accept(true);
+                                    completionConsumer.accept((Uri) msg.obj);
                                 }
                             }
                         };
@@ -148,7 +149,7 @@
                         } catch (RemoteException e) {
                             Log.e(TAG, "Couldn't take screenshot: " + e);
                             if (completionConsumer != null) {
-                                completionConsumer.accept(false);
+                                completionConsumer.accept(null);
                             }
                         }
                     }
diff --git a/core/java/com/android/internal/widget/DecorCaptionView.java b/core/java/com/android/internal/widget/DecorCaptionView.java
index 4014c45..b5d787c2 100644
--- a/core/java/com/android/internal/widget/DecorCaptionView.java
+++ b/core/java/com/android/internal/widget/DecorCaptionView.java
@@ -123,6 +123,8 @@
     private void init(Context context) {
         mDragSlop = ViewConfiguration.get(context).getScaledTouchSlop();
         mGestureDetector = new GestureDetector(context, this);
+        setContentDescription(context.getString(R.string.accessibility_freeform_caption,
+                context.getPackageManager().getApplicationLabel(context.getApplicationInfo())));
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/GridLayoutManager.java b/core/java/com/android/internal/widget/GridLayoutManager.java
new file mode 100644
index 0000000..e0502f1
--- /dev/null
+++ b/core/java/com/android/internal/widget/GridLayoutManager.java
@@ -0,0 +1,1065 @@
+/*
+ * 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.widget;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.SparseIntArray;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import java.util.Arrays;
+
+/**
+ * Note: This GridLayoutManager widget may lack of latest fix because it is ported from
+ * oc-dr1-release version of android.support.v7.widget.GridLayoutManager due to compatibility
+ * concern with other internal widgets, like {@link RecyclerView} and {@link LinearLayoutManager},
+ * and is merely used for {@link com.android.internal.app.ChooserActivity}.
+ *
+ * A {@link RecyclerView.LayoutManager} implementations that lays out items in a grid.
+ * <p>
+ * By default, each item occupies 1 span. You can change it by providing a custom
+ * {@link SpanSizeLookup} instance via {@link #setSpanSizeLookup(SpanSizeLookup)}.
+ */
+public class GridLayoutManager extends LinearLayoutManager {
+    private static final boolean DEBUG = false;
+    private static final String TAG = "GridLayoutManager";
+    public static final int DEFAULT_SPAN_COUNT = -1;
+    /**
+     * Span size have been changed but we've not done a new layout calculation.
+     */
+    boolean mPendingSpanCountChange = false;
+    int mSpanCount = DEFAULT_SPAN_COUNT;
+    /**
+     * Right borders for each span.
+     * <p>For <b>i-th</b> item start is {@link #mCachedBorders}[i-1] + 1
+     * and end is {@link #mCachedBorders}[i].
+     */
+    int[] mCachedBorders;
+    /**
+     * Temporary array to keep views in layoutChunk method
+     */
+    View[] mSet;
+    final SparseIntArray mPreLayoutSpanSizeCache = new SparseIntArray();
+    final SparseIntArray mPreLayoutSpanIndexCache = new SparseIntArray();
+    SpanSizeLookup mSpanSizeLookup = new DefaultSpanSizeLookup();
+    // re-used variable to acquire decor insets from RecyclerView
+    final Rect mDecorInsets = new Rect();
+
+    /**
+     * Constructor used when layout manager is set in XML by RecyclerView attribute
+     * "layoutManager". If spanCount is not specified in the XML, it defaults to a
+     * single column.
+     *
+     */
+    public GridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        Properties properties = getProperties(context, attrs, defStyleAttr, defStyleRes);
+        setSpanCount(properties.spanCount);
+    }
+
+    /**
+     * Creates a vertical GridLayoutManager
+     *
+     * @param context   Current context, will be used to access resources.
+     * @param spanCount The number of columns in the grid
+     */
+    public GridLayoutManager(Context context, int spanCount) {
+        super(context);
+        setSpanCount(spanCount);
+    }
+
+    /**
+     * @param context       Current context, will be used to access resources.
+     * @param spanCount     The number of columns or rows in the grid
+     * @param orientation   Layout orientation. Should be {@link #HORIZONTAL} or {@link
+     *                      #VERTICAL}.
+     * @param reverseLayout When set to true, layouts from end to start.
+     */
+    public GridLayoutManager(Context context, int spanCount, int orientation,
+            boolean reverseLayout) {
+        super(context, orientation, reverseLayout);
+        setSpanCount(spanCount);
+    }
+
+    /**
+     * stackFromEnd is not supported by GridLayoutManager. Consider using
+     * {@link #setReverseLayout(boolean)}.
+     */
+    @Override
+    public void setStackFromEnd(boolean stackFromEnd) {
+        if (stackFromEnd) {
+            throw new UnsupportedOperationException(
+                    "GridLayoutManager does not support stack from end."
+                            + " Consider using reverse layout");
+        }
+        super.setStackFromEnd(false);
+    }
+
+    @Override
+    public int getRowCountForAccessibility(RecyclerView.Recycler recycler,
+            RecyclerView.State state) {
+        if (mOrientation == HORIZONTAL) {
+            return mSpanCount;
+        }
+        if (state.getItemCount() < 1) {
+            return 0;
+        }
+        // Row count is one more than the last item's row index.
+        return getSpanGroupIndex(recycler, state, state.getItemCount() - 1) + 1;
+    }
+
+    @Override
+    public int getColumnCountForAccessibility(RecyclerView.Recycler recycler,
+            RecyclerView.State state) {
+        if (mOrientation == VERTICAL) {
+            return mSpanCount;
+        }
+        if (state.getItemCount() < 1) {
+            return 0;
+        }
+        // Column count is one more than the last item's column index.
+        return getSpanGroupIndex(recycler, state, state.getItemCount() - 1) + 1;
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfoForItem(RecyclerView.Recycler recycler,
+            RecyclerView.State state, View host, AccessibilityNodeInfo info) {
+        ViewGroup.LayoutParams lp = host.getLayoutParams();
+        if (!(lp instanceof LayoutParams)) {
+            super.onInitializeAccessibilityNodeInfoForItem(host, info);
+            return;
+        }
+        LayoutParams glp = (LayoutParams) lp;
+        int spanGroupIndex = getSpanGroupIndex(recycler, state, glp.getViewLayoutPosition());
+        if (mOrientation == HORIZONTAL) {
+            info.setCollectionItemInfo(AccessibilityNodeInfo.CollectionItemInfo.obtain(
+                    glp.getSpanIndex(), glp.getSpanSize(),
+                    spanGroupIndex, 1,
+                    mSpanCount > 1 && glp.getSpanSize() == mSpanCount, false));
+        } else { // VERTICAL
+            info.setCollectionItemInfo(AccessibilityNodeInfo.CollectionItemInfo.obtain(
+                    spanGroupIndex, 1,
+                    glp.getSpanIndex(), glp.getSpanSize(),
+                    mSpanCount > 1 && glp.getSpanSize() == mSpanCount, false));
+        }
+    }
+
+    @Override
+    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
+        if (state.isPreLayout()) {
+            cachePreLayoutSpanMapping();
+        }
+        super.onLayoutChildren(recycler, state);
+        if (DEBUG) {
+            validateChildOrder();
+        }
+        clearPreLayoutSpanMappingCache();
+    }
+
+    @Override
+    public void onLayoutCompleted(RecyclerView.State state) {
+        super.onLayoutCompleted(state);
+        mPendingSpanCountChange = false;
+    }
+
+    private void clearPreLayoutSpanMappingCache() {
+        mPreLayoutSpanSizeCache.clear();
+        mPreLayoutSpanIndexCache.clear();
+    }
+
+    private void cachePreLayoutSpanMapping() {
+        final int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final LayoutParams lp = (LayoutParams) getChildAt(i).getLayoutParams();
+            final int viewPosition = lp.getViewLayoutPosition();
+            mPreLayoutSpanSizeCache.put(viewPosition, lp.getSpanSize());
+            mPreLayoutSpanIndexCache.put(viewPosition, lp.getSpanIndex());
+        }
+    }
+
+    @Override
+    public void onItemsAdded(RecyclerView recyclerView, int positionStart, int itemCount) {
+        mSpanSizeLookup.invalidateSpanIndexCache();
+    }
+
+    @Override
+    public void onItemsChanged(RecyclerView recyclerView) {
+        mSpanSizeLookup.invalidateSpanIndexCache();
+    }
+
+    @Override
+    public void onItemsRemoved(RecyclerView recyclerView, int positionStart, int itemCount) {
+        mSpanSizeLookup.invalidateSpanIndexCache();
+    }
+
+    @Override
+    public void onItemsUpdated(RecyclerView recyclerView, int positionStart, int itemCount,
+            Object payload) {
+        mSpanSizeLookup.invalidateSpanIndexCache();
+    }
+
+    @Override
+    public void onItemsMoved(RecyclerView recyclerView, int from, int to, int itemCount) {
+        mSpanSizeLookup.invalidateSpanIndexCache();
+    }
+
+    @Override
+    public RecyclerView.LayoutParams generateDefaultLayoutParams() {
+        if (mOrientation == HORIZONTAL) {
+            return new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+                    ViewGroup.LayoutParams.MATCH_PARENT);
+        } else {
+            return new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+                    ViewGroup.LayoutParams.WRAP_CONTENT);
+        }
+    }
+
+    @Override
+    public RecyclerView.LayoutParams generateLayoutParams(Context c, AttributeSet attrs) {
+        return new LayoutParams(c, attrs);
+    }
+
+    @Override
+    public RecyclerView.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
+        if (lp instanceof ViewGroup.MarginLayoutParams) {
+            return new LayoutParams((ViewGroup.MarginLayoutParams) lp);
+        } else {
+            return new LayoutParams(lp);
+        }
+    }
+
+    @Override
+    public boolean checkLayoutParams(RecyclerView.LayoutParams lp) {
+        return lp instanceof LayoutParams;
+    }
+
+    /**
+     * Sets the source to get the number of spans occupied by each item in the adapter.
+     *
+     * @param spanSizeLookup {@link SpanSizeLookup} instance to be used to query number of spans
+     *                       occupied by each item
+     */
+    public void setSpanSizeLookup(SpanSizeLookup spanSizeLookup) {
+        mSpanSizeLookup = spanSizeLookup;
+    }
+
+    /**
+     * Returns the current {@link SpanSizeLookup} used by the GridLayoutManager.
+     *
+     * @return The current {@link SpanSizeLookup} used by the GridLayoutManager.
+     */
+    public SpanSizeLookup getSpanSizeLookup() {
+        return mSpanSizeLookup;
+    }
+
+    private void updateMeasurements() {
+        int totalSpace;
+        if (getOrientation() == VERTICAL) {
+            totalSpace = getWidth() - getPaddingRight() - getPaddingLeft();
+        } else {
+            totalSpace = getHeight() - getPaddingBottom() - getPaddingTop();
+        }
+        calculateItemBorders(totalSpace);
+    }
+
+    @Override
+    public void setMeasuredDimension(Rect childrenBounds, int wSpec, int hSpec) {
+        if (mCachedBorders == null) {
+            super.setMeasuredDimension(childrenBounds, wSpec, hSpec);
+        }
+        final int width, height;
+        final int horizontalPadding = getPaddingLeft() + getPaddingRight();
+        final int verticalPadding = getPaddingTop() + getPaddingBottom();
+        if (mOrientation == VERTICAL) {
+            final int usedHeight = childrenBounds.height() + verticalPadding;
+            height = chooseSize(hSpec, usedHeight, getMinimumHeight());
+            width = chooseSize(wSpec, mCachedBorders[mCachedBorders.length - 1] + horizontalPadding,
+                    getMinimumWidth());
+        } else {
+            final int usedWidth = childrenBounds.width() + horizontalPadding;
+            width = chooseSize(wSpec, usedWidth, getMinimumWidth());
+            height = chooseSize(hSpec, mCachedBorders[mCachedBorders.length - 1] + verticalPadding,
+                    getMinimumHeight());
+        }
+        setMeasuredDimension(width, height);
+    }
+
+    /**
+     * @param totalSpace Total available space after padding is removed
+     */
+    private void calculateItemBorders(int totalSpace) {
+        mCachedBorders = calculateItemBorders(mCachedBorders, mSpanCount, totalSpace);
+    }
+
+    /**
+     * @param cachedBorders The out array
+     * @param spanCount     number of spans
+     * @param totalSpace    total available space after padding is removed
+     * @return The updated array. Might be the same instance as the provided array if its size
+     * has not changed.
+     */
+    static int[] calculateItemBorders(int[] cachedBorders, int spanCount, int totalSpace) {
+        if (cachedBorders == null || cachedBorders.length != spanCount + 1
+                || cachedBorders[cachedBorders.length - 1] != totalSpace) {
+            cachedBorders = new int[spanCount + 1];
+        }
+        cachedBorders[0] = 0;
+        int sizePerSpan = totalSpace / spanCount;
+        int sizePerSpanRemainder = totalSpace % spanCount;
+        int consumedPixels = 0;
+        int additionalSize = 0;
+        for (int i = 1; i <= spanCount; i++) {
+            int itemSize = sizePerSpan;
+            additionalSize += sizePerSpanRemainder;
+            if (additionalSize > 0 && (spanCount - additionalSize) < sizePerSpanRemainder) {
+                itemSize += 1;
+                additionalSize -= spanCount;
+            }
+            consumedPixels += itemSize;
+            cachedBorders[i] = consumedPixels;
+        }
+        return cachedBorders;
+    }
+
+    int getSpaceForSpanRange(int startSpan, int spanSize) {
+        if (mOrientation == VERTICAL && isLayoutRTL()) {
+            return mCachedBorders[mSpanCount - startSpan]
+                    - mCachedBorders[mSpanCount - startSpan - spanSize];
+        } else {
+            return mCachedBorders[startSpan + spanSize] - mCachedBorders[startSpan];
+        }
+    }
+
+    @Override
+    void onAnchorReady(RecyclerView.Recycler recycler, RecyclerView.State state,
+            AnchorInfo anchorInfo, int itemDirection) {
+        super.onAnchorReady(recycler, state, anchorInfo, itemDirection);
+        updateMeasurements();
+        if (state.getItemCount() > 0 && !state.isPreLayout()) {
+            ensureAnchorIsInCorrectSpan(recycler, state, anchorInfo, itemDirection);
+        }
+        ensureViewSet();
+    }
+
+    private void ensureViewSet() {
+        if (mSet == null || mSet.length != mSpanCount) {
+            mSet = new View[mSpanCount];
+        }
+    }
+
+    @Override
+    public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
+            RecyclerView.State state) {
+        updateMeasurements();
+        ensureViewSet();
+        return super.scrollHorizontallyBy(dx, recycler, state);
+    }
+
+    @Override
+    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
+            RecyclerView.State state) {
+        updateMeasurements();
+        ensureViewSet();
+        return super.scrollVerticallyBy(dy, recycler, state);
+    }
+
+    private void ensureAnchorIsInCorrectSpan(RecyclerView.Recycler recycler,
+            RecyclerView.State state, AnchorInfo anchorInfo, int itemDirection) {
+        final boolean layingOutInPrimaryDirection =
+                itemDirection == LayoutState.ITEM_DIRECTION_TAIL;
+        int span = getSpanIndex(recycler, state, anchorInfo.mPosition);
+        if (layingOutInPrimaryDirection) {
+            // choose span 0
+            while (span > 0 && anchorInfo.mPosition > 0) {
+                anchorInfo.mPosition--;
+                span = getSpanIndex(recycler, state, anchorInfo.mPosition);
+            }
+        } else {
+            // choose the max span we can get. hopefully last one
+            final int indexLimit = state.getItemCount() - 1;
+            int pos = anchorInfo.mPosition;
+            int bestSpan = span;
+            while (pos < indexLimit) {
+                int next = getSpanIndex(recycler, state, pos + 1);
+                if (next > bestSpan) {
+                    pos += 1;
+                    bestSpan = next;
+                } else {
+                    break;
+                }
+            }
+            anchorInfo.mPosition = pos;
+        }
+    }
+
+    @Override
+    View findReferenceChild(RecyclerView.Recycler recycler, RecyclerView.State state,
+            int start, int end, int itemCount) {
+        ensureLayoutState();
+        View invalidMatch = null;
+        View outOfBoundsMatch = null;
+        final int boundsStart = mOrientationHelper.getStartAfterPadding();
+        final int boundsEnd = mOrientationHelper.getEndAfterPadding();
+        final int diff = end > start ? 1 : -1;
+        for (int i = start; i != end; i += diff) {
+            final View view = getChildAt(i);
+            final int position = getPosition(view);
+            if (position >= 0 && position < itemCount) {
+                final int span = getSpanIndex(recycler, state, position);
+                if (span != 0) {
+                    continue;
+                }
+                if (((RecyclerView.LayoutParams) view.getLayoutParams()).isItemRemoved()) {
+                    if (invalidMatch == null) {
+                        invalidMatch = view; // removed item, least preferred
+                    }
+                } else if (mOrientationHelper.getDecoratedStart(view) >= boundsEnd
+                        || mOrientationHelper.getDecoratedEnd(view) < boundsStart) {
+                    if (outOfBoundsMatch == null) {
+                        outOfBoundsMatch = view; // item is not visible, less preferred
+                    }
+                } else {
+                    return view;
+                }
+            }
+        }
+        return outOfBoundsMatch != null ? outOfBoundsMatch : invalidMatch;
+    }
+
+    private int getSpanGroupIndex(RecyclerView.Recycler recycler, RecyclerView.State state,
+            int viewPosition) {
+        if (!state.isPreLayout()) {
+            return mSpanSizeLookup.getSpanGroupIndex(viewPosition, mSpanCount);
+        }
+        final int adapterPosition = recycler.convertPreLayoutPositionToPostLayout(viewPosition);
+        if (adapterPosition == -1) {
+            if (DEBUG) {
+                throw new RuntimeException("Cannot find span group index for position "
+                        + viewPosition);
+            }
+            Log.w(TAG, "Cannot find span size for pre layout position. " + viewPosition);
+            return 0;
+        }
+        return mSpanSizeLookup.getSpanGroupIndex(adapterPosition, mSpanCount);
+    }
+
+    private int getSpanIndex(RecyclerView.Recycler recycler, RecyclerView.State state, int pos) {
+        if (!state.isPreLayout()) {
+            return mSpanSizeLookup.getCachedSpanIndex(pos, mSpanCount);
+        }
+        final int cached = mPreLayoutSpanIndexCache.get(pos, -1);
+        if (cached != -1) {
+            return cached;
+        }
+        final int adapterPosition = recycler.convertPreLayoutPositionToPostLayout(pos);
+        if (adapterPosition == -1) {
+            if (DEBUG) {
+                throw new RuntimeException("Cannot find span index for pre layout position. It is"
+                        + " not cached, not in the adapter. Pos:" + pos);
+            }
+            Log.w(TAG, "Cannot find span size for pre layout position. It is"
+                    + " not cached, not in the adapter. Pos:" + pos);
+            return 0;
+        }
+        return mSpanSizeLookup.getCachedSpanIndex(adapterPosition, mSpanCount);
+    }
+
+    private int getSpanSize(RecyclerView.Recycler recycler, RecyclerView.State state, int pos) {
+        if (!state.isPreLayout()) {
+            return mSpanSizeLookup.getSpanSize(pos);
+        }
+        final int cached = mPreLayoutSpanSizeCache.get(pos, -1);
+        if (cached != -1) {
+            return cached;
+        }
+        final int adapterPosition = recycler.convertPreLayoutPositionToPostLayout(pos);
+        if (adapterPosition == -1) {
+            if (DEBUG) {
+                throw new RuntimeException("Cannot find span size for pre layout position. It is"
+                        + " not cached, not in the adapter. Pos:" + pos);
+            }
+            Log.w(TAG, "Cannot find span size for pre layout position. It is"
+                    + " not cached, not in the adapter. Pos:" + pos);
+            return 1;
+        }
+        return mSpanSizeLookup.getSpanSize(adapterPosition);
+    }
+
+    @Override
+    void collectPrefetchPositionsForLayoutState(RecyclerView.State state, LayoutState layoutState,
+            LayoutPrefetchRegistry layoutPrefetchRegistry) {
+        int remainingSpan = mSpanCount;
+        int count = 0;
+        while (count < mSpanCount && layoutState.hasMore(state) && remainingSpan > 0) {
+            final int pos = layoutState.mCurrentPosition;
+            layoutPrefetchRegistry.addPosition(pos, Math.max(0, layoutState.mScrollingOffset));
+            final int spanSize = mSpanSizeLookup.getSpanSize(pos);
+            remainingSpan -= spanSize;
+            layoutState.mCurrentPosition += layoutState.mItemDirection;
+            count++;
+        }
+    }
+
+    @Override
+    void layoutChunk(RecyclerView.Recycler recycler, RecyclerView.State state,
+            LayoutState layoutState, LayoutChunkResult result) {
+        final int otherDirSpecMode = mOrientationHelper.getModeInOther();
+        final boolean flexibleInOtherDir = otherDirSpecMode != View.MeasureSpec.EXACTLY;
+        final int currentOtherDirSize = getChildCount() > 0 ? mCachedBorders[mSpanCount] : 0;
+        // if grid layout's dimensions are not specified, let the new row change the measurements
+        // This is not perfect since we not covering all rows but still solves an important case
+        // where they may have a header row which should be laid out according to children.
+        if (flexibleInOtherDir) {
+            updateMeasurements(); //  reset measurements
+        }
+        final boolean layingOutInPrimaryDirection =
+                layoutState.mItemDirection == LayoutState.ITEM_DIRECTION_TAIL;
+        int count = 0;
+        int consumedSpanCount = 0;
+        int remainingSpan = mSpanCount;
+        if (!layingOutInPrimaryDirection) {
+            int itemSpanIndex = getSpanIndex(recycler, state, layoutState.mCurrentPosition);
+            int itemSpanSize = getSpanSize(recycler, state, layoutState.mCurrentPosition);
+            remainingSpan = itemSpanIndex + itemSpanSize;
+        }
+        while (count < mSpanCount && layoutState.hasMore(state) && remainingSpan > 0) {
+            int pos = layoutState.mCurrentPosition;
+            final int spanSize = getSpanSize(recycler, state, pos);
+            if (spanSize > mSpanCount) {
+                throw new IllegalArgumentException("Item at position " + pos + " requires "
+                        + spanSize + " spans but GridLayoutManager has only " + mSpanCount
+                        + " spans.");
+            }
+            remainingSpan -= spanSize;
+            if (remainingSpan < 0) {
+                break; // item did not fit into this row or column
+            }
+            View view = layoutState.next(recycler);
+            if (view == null) {
+                break;
+            }
+            consumedSpanCount += spanSize;
+            mSet[count] = view;
+            count++;
+        }
+        if (count == 0) {
+            result.mFinished = true;
+            return;
+        }
+        int maxSize = 0;
+        float maxSizeInOther = 0; // use a float to get size per span
+        // we should assign spans before item decor offsets are calculated
+        assignSpans(recycler, state, count, consumedSpanCount, layingOutInPrimaryDirection);
+        for (int i = 0; i < count; i++) {
+            View view = mSet[i];
+            if (layoutState.mScrapList == null) {
+                if (layingOutInPrimaryDirection) {
+                    addView(view);
+                } else {
+                    addView(view, 0);
+                }
+            } else {
+                if (layingOutInPrimaryDirection) {
+                    addDisappearingView(view);
+                } else {
+                    addDisappearingView(view, 0);
+                }
+            }
+            calculateItemDecorationsForChild(view, mDecorInsets);
+            measureChild(view, otherDirSpecMode, false);
+            final int size = mOrientationHelper.getDecoratedMeasurement(view);
+            if (size > maxSize) {
+                maxSize = size;
+            }
+            final LayoutParams lp = (LayoutParams) view.getLayoutParams();
+            final float otherSize = 1f * mOrientationHelper.getDecoratedMeasurementInOther(view)
+                    / lp.mSpanSize;
+            if (otherSize > maxSizeInOther) {
+                maxSizeInOther = otherSize;
+            }
+        }
+        if (flexibleInOtherDir) {
+            // re-distribute columns
+            guessMeasurement(maxSizeInOther, currentOtherDirSize);
+            // now we should re-measure any item that was match parent.
+            maxSize = 0;
+            for (int i = 0; i < count; i++) {
+                View view = mSet[i];
+                measureChild(view, View.MeasureSpec.EXACTLY, true);
+                final int size = mOrientationHelper.getDecoratedMeasurement(view);
+                if (size > maxSize) {
+                    maxSize = size;
+                }
+            }
+        }
+        // Views that did not measure the maxSize has to be re-measured
+        // We will stop doing this once we introduce Gravity in the GLM layout params
+        for (int i = 0; i < count; i++) {
+            final View view = mSet[i];
+            if (mOrientationHelper.getDecoratedMeasurement(view) != maxSize) {
+                final LayoutParams lp = (LayoutParams) view.getLayoutParams();
+                final Rect decorInsets = lp.mDecorInsets;
+                final int verticalInsets = decorInsets.top + decorInsets.bottom
+                        + lp.topMargin + lp.bottomMargin;
+                final int horizontalInsets = decorInsets.left + decorInsets.right
+                        + lp.leftMargin + lp.rightMargin;
+                final int totalSpaceInOther = getSpaceForSpanRange(lp.mSpanIndex, lp.mSpanSize);
+                final int wSpec;
+                final int hSpec;
+                if (mOrientation == VERTICAL) {
+                    wSpec = getChildMeasureSpec(totalSpaceInOther, View.MeasureSpec.EXACTLY,
+                            horizontalInsets, lp.width, false);
+                    hSpec = View.MeasureSpec.makeMeasureSpec(maxSize - verticalInsets,
+                            View.MeasureSpec.EXACTLY);
+                } else {
+                    wSpec = View.MeasureSpec.makeMeasureSpec(maxSize - horizontalInsets,
+                            View.MeasureSpec.EXACTLY);
+                    hSpec = getChildMeasureSpec(totalSpaceInOther, View.MeasureSpec.EXACTLY,
+                            verticalInsets, lp.height, false);
+                }
+                measureChildWithDecorationsAndMargin(view, wSpec, hSpec, true);
+            }
+        }
+        result.mConsumed = maxSize;
+        int left = 0, right = 0, top = 0, bottom = 0;
+        if (mOrientation == VERTICAL) {
+            if (layoutState.mLayoutDirection == LayoutState.LAYOUT_START) {
+                bottom = layoutState.mOffset;
+                top = bottom - maxSize;
+            } else {
+                top = layoutState.mOffset;
+                bottom = top + maxSize;
+            }
+        } else {
+            if (layoutState.mLayoutDirection == LayoutState.LAYOUT_START) {
+                right = layoutState.mOffset;
+                left = right - maxSize;
+            } else {
+                left = layoutState.mOffset;
+                right = left + maxSize;
+            }
+        }
+        for (int i = 0; i < count; i++) {
+            View view = mSet[i];
+            LayoutParams params = (LayoutParams) view.getLayoutParams();
+            if (mOrientation == VERTICAL) {
+                if (isLayoutRTL()) {
+                    right = getPaddingLeft() + mCachedBorders[mSpanCount - params.mSpanIndex];
+                    left = right - mOrientationHelper.getDecoratedMeasurementInOther(view);
+                } else {
+                    left = getPaddingLeft() + mCachedBorders[params.mSpanIndex];
+                    right = left + mOrientationHelper.getDecoratedMeasurementInOther(view);
+                }
+            } else {
+                top = getPaddingTop() + mCachedBorders[params.mSpanIndex];
+                bottom = top + mOrientationHelper.getDecoratedMeasurementInOther(view);
+            }
+            // We calculate everything with View's bounding box (which includes decor and margins)
+            // To calculate correct layout position, we subtract margins.
+            layoutDecoratedWithMargins(view, left, top, right, bottom);
+            if (DEBUG) {
+                Log.d(TAG, "laid out child at position " + getPosition(view) + ", with l:"
+                        + (left + params.leftMargin) + ", t:" + (top + params.topMargin) + ", r:"
+                        + (right - params.rightMargin) + ", b:" + (bottom - params.bottomMargin)
+                        + ", span:" + params.mSpanIndex + ", spanSize:" + params.mSpanSize);
+            }
+            // Consume the available space if the view is not removed OR changed
+            if (params.isItemRemoved() || params.isItemChanged()) {
+                result.mIgnoreConsumed = true;
+            }
+            result.mFocusable |= view.hasFocusable();
+        }
+        Arrays.fill(mSet, null);
+    }
+
+    /**
+     * Measures a child with currently known information. This is not necessarily the child's final
+     * measurement. (see fillChunk for details).
+     *
+     * @param view                   The child view to be measured
+     * @param otherDirParentSpecMode The RV measure spec that should be used in the secondary
+     *                               orientation
+     * @param alreadyMeasured        True if we've already measured this view once
+     */
+    private void measureChild(View view, int otherDirParentSpecMode, boolean alreadyMeasured) {
+        final LayoutParams lp = (LayoutParams) view.getLayoutParams();
+        final Rect decorInsets = lp.mDecorInsets;
+        final int verticalInsets = decorInsets.top + decorInsets.bottom
+                + lp.topMargin + lp.bottomMargin;
+        final int horizontalInsets = decorInsets.left + decorInsets.right
+                + lp.leftMargin + lp.rightMargin;
+        final int availableSpaceInOther = getSpaceForSpanRange(lp.mSpanIndex, lp.mSpanSize);
+        final int wSpec;
+        final int hSpec;
+        if (mOrientation == VERTICAL) {
+            wSpec = getChildMeasureSpec(availableSpaceInOther, otherDirParentSpecMode,
+                    horizontalInsets, lp.width, false);
+            hSpec = getChildMeasureSpec(mOrientationHelper.getTotalSpace(), getHeightMode(),
+                    verticalInsets, lp.height, true);
+        } else {
+            hSpec = getChildMeasureSpec(availableSpaceInOther, otherDirParentSpecMode,
+                    verticalInsets, lp.height, false);
+            wSpec = getChildMeasureSpec(mOrientationHelper.getTotalSpace(), getWidthMode(),
+                    horizontalInsets, lp.width, true);
+        }
+        measureChildWithDecorationsAndMargin(view, wSpec, hSpec, alreadyMeasured);
+    }
+
+    /**
+     * This is called after laying out a row (if vertical) or a column (if horizontal) when the
+     * RecyclerView does not have exact measurement specs.
+     * <p>
+     * Here we try to assign a best guess width or height and re-do the layout to update other
+     * views that wanted to MATCH_PARENT in the non-scroll orientation.
+     *
+     * @param maxSizeInOther      The maximum size per span ratio from the measurement of the
+     *                            children.
+     * @param currentOtherDirSize The size before this layout chunk. There is no reason to go below.
+     */
+    private void guessMeasurement(float maxSizeInOther, int currentOtherDirSize) {
+        final int contentSize = Math.round(maxSizeInOther * mSpanCount);
+        // always re-calculate because borders were stretched during the fill
+        calculateItemBorders(Math.max(contentSize, currentOtherDirSize));
+    }
+
+    private void measureChildWithDecorationsAndMargin(View child, int widthSpec, int heightSpec,
+            boolean alreadyMeasured) {
+        RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) child.getLayoutParams();
+        final boolean measure;
+        if (alreadyMeasured) {
+            measure = shouldReMeasureChild(child, widthSpec, heightSpec, lp);
+        } else {
+            measure = shouldMeasureChild(child, widthSpec, heightSpec, lp);
+        }
+        if (measure) {
+            child.measure(widthSpec, heightSpec);
+        }
+    }
+
+    private void assignSpans(RecyclerView.Recycler recycler, RecyclerView.State state, int count,
+            int consumedSpanCount, boolean layingOutInPrimaryDirection) {
+        // spans are always assigned from 0 to N no matter if it is RTL or not.
+        // RTL is used only when positioning the view.
+        int span, start, end, diff;
+        // make sure we traverse from min position to max position
+        if (layingOutInPrimaryDirection) {
+            start = 0;
+            end = count;
+            diff = 1;
+        } else {
+            start = count - 1;
+            end = -1;
+            diff = -1;
+        }
+        span = 0;
+        for (int i = start; i != end; i += diff) {
+            View view = mSet[i];
+            LayoutParams params = (LayoutParams) view.getLayoutParams();
+            params.mSpanSize = getSpanSize(recycler, state, getPosition(view));
+            params.mSpanIndex = span;
+            span += params.mSpanSize;
+        }
+    }
+
+    /**
+     * Returns the number of spans laid out by this grid.
+     *
+     * @return The number of spans
+     * @see #setSpanCount(int)
+     */
+    public int getSpanCount() {
+        return mSpanCount;
+    }
+
+    /**
+     * Sets the number of spans to be laid out.
+     * <p>
+     * If {@link #getOrientation()} is {@link #VERTICAL}, this is the number of columns.
+     * If {@link #getOrientation()} is {@link #HORIZONTAL}, this is the number of rows.
+     *
+     * @param spanCount The total number of spans in the grid
+     * @see #getSpanCount()
+     */
+    public void setSpanCount(int spanCount) {
+        if (spanCount == mSpanCount) {
+            return;
+        }
+        mPendingSpanCountChange = true;
+        if (spanCount < 1) {
+            throw new IllegalArgumentException("Span count should be at least 1. Provided "
+                    + spanCount);
+        }
+        mSpanCount = spanCount;
+        mSpanSizeLookup.invalidateSpanIndexCache();
+        requestLayout();
+    }
+
+    /**
+     * A helper class to provide the number of spans each item occupies.
+     * <p>
+     * Default implementation sets each item to occupy exactly 1 span.
+     *
+     * @see GridLayoutManager#setSpanSizeLookup(SpanSizeLookup)
+     */
+    public abstract static class SpanSizeLookup {
+        final SparseIntArray mSpanIndexCache = new SparseIntArray();
+        private boolean mCacheSpanIndices = false;
+
+        /**
+         * Returns the number of span occupied by the item at <code>position</code>.
+         *
+         * @param position The adapter position of the item
+         * @return The number of spans occupied by the item at the provided position
+         */
+        public abstract int getSpanSize(int position);
+
+        /**
+         * Sets whether the results of {@link #getSpanIndex(int, int)} method should be cached or
+         * not. By default these values are not cached. If you are not overriding
+         * {@link #getSpanIndex(int, int)}, you should set this to true for better performance.
+         *
+         * @param cacheSpanIndices Whether results of getSpanIndex should be cached or not.
+         */
+        public void setSpanIndexCacheEnabled(boolean cacheSpanIndices) {
+            mCacheSpanIndices = cacheSpanIndices;
+        }
+
+        /**
+         * Clears the span index cache. GridLayoutManager automatically calls this method when
+         * adapter changes occur.
+         */
+        public void invalidateSpanIndexCache() {
+            mSpanIndexCache.clear();
+        }
+
+        /**
+         * Returns whether results of {@link #getSpanIndex(int, int)} method are cached or not.
+         *
+         * @return True if results of {@link #getSpanIndex(int, int)} are cached.
+         */
+        public boolean isSpanIndexCacheEnabled() {
+            return mCacheSpanIndices;
+        }
+
+        int getCachedSpanIndex(int position, int spanCount) {
+            if (!mCacheSpanIndices) {
+                return getSpanIndex(position, spanCount);
+            }
+            final int existing = mSpanIndexCache.get(position, -1);
+            if (existing != -1) {
+                return existing;
+            }
+            final int value = getSpanIndex(position, spanCount);
+            mSpanIndexCache.put(position, value);
+            return value;
+        }
+
+        /**
+         * Returns the final span index of the provided position.
+         * <p>
+         * If you have a faster way to calculate span index for your items, you should override
+         * this method. Otherwise, you should enable span index cache
+         * ({@link #setSpanIndexCacheEnabled(boolean)}) for better performance. When caching is
+         * disabled, default implementation traverses all items from 0 to
+         * <code>position</code>. When caching is enabled, it calculates from the closest cached
+         * value before the <code>position</code>.
+         * <p>
+         * If you override this method, you need to make sure it is consistent with
+         * {@link #getSpanSize(int)}. GridLayoutManager does not call this method for
+         * each item. It is called only for the reference item and rest of the items
+         * are assigned to spans based on the reference item. For example, you cannot assign a
+         * position to span 2 while span 1 is empty.
+         * <p>
+         * Note that span offsets always start with 0 and are not affected by RTL.
+         *
+         * @param position  The position of the item
+         * @param spanCount The total number of spans in the grid
+         * @return The final span position of the item. Should be between 0 (inclusive) and
+         * <code>spanCount</code>(exclusive)
+         */
+        public int getSpanIndex(int position, int spanCount) {
+            int positionSpanSize = getSpanSize(position);
+            if (positionSpanSize == spanCount) {
+                return 0; // quick return for full-span items
+            }
+            int span = 0;
+            int startPos = 0;
+            // If caching is enabled, try to jump
+            if (mCacheSpanIndices && mSpanIndexCache.size() > 0) {
+                int prevKey = findReferenceIndexFromCache(position);
+                if (prevKey >= 0) {
+                    span = mSpanIndexCache.get(prevKey) + getSpanSize(prevKey);
+                    startPos = prevKey + 1;
+                }
+            }
+            for (int i = startPos; i < position; i++) {
+                int size = getSpanSize(i);
+                span += size;
+                if (span == spanCount) {
+                    span = 0;
+                } else if (span > spanCount) {
+                    // did not fit, moving to next row / column
+                    span = size;
+                }
+            }
+            if (span + positionSpanSize <= spanCount) {
+                return span;
+            }
+            return 0;
+        }
+
+        int findReferenceIndexFromCache(int position) {
+            int lo = 0;
+            int hi = mSpanIndexCache.size() - 1;
+            while (lo <= hi) {
+                final int mid = (lo + hi) >>> 1;
+                final int midVal = mSpanIndexCache.keyAt(mid);
+                if (midVal < position) {
+                    lo = mid + 1;
+                } else {
+                    hi = mid - 1;
+                }
+            }
+            int index = lo - 1;
+            if (index >= 0 && index < mSpanIndexCache.size()) {
+                return mSpanIndexCache.keyAt(index);
+            }
+            return -1;
+        }
+
+        /**
+         * Returns the index of the group this position belongs.
+         * <p>
+         * For example, if grid has 3 columns and each item occupies 1 span, span group index
+         * for item 1 will be 0, item 5 will be 1.
+         *
+         * @param adapterPosition The position in adapter
+         * @param spanCount       The total number of spans in the grid
+         * @return The index of the span group including the item at the given adapter position
+         */
+        public int getSpanGroupIndex(int adapterPosition, int spanCount) {
+            int span = 0;
+            int group = 0;
+            int positionSpanSize = getSpanSize(adapterPosition);
+            for (int i = 0; i < adapterPosition; i++) {
+                int size = getSpanSize(i);
+                span += size;
+                if (span == spanCount) {
+                    span = 0;
+                    group++;
+                } else if (span > spanCount) {
+                    // did not fit, moving to next row / column
+                    span = size;
+                    group++;
+                }
+            }
+            if (span + positionSpanSize > spanCount) {
+                group++;
+            }
+            return group;
+        }
+    }
+
+    @Override
+    public boolean supportsPredictiveItemAnimations() {
+        return mPendingSavedState == null && !mPendingSpanCountChange;
+    }
+
+    /**
+     * Default implementation for {@link SpanSizeLookup}. Each item occupies 1 span.
+     */
+    public static final class DefaultSpanSizeLookup extends SpanSizeLookup {
+        @Override
+        public int getSpanSize(int position) {
+            return 1;
+        }
+
+        @Override
+        public int getSpanIndex(int position, int spanCount) {
+            return position % spanCount;
+        }
+    }
+
+    /**
+     * LayoutParams used by GridLayoutManager.
+     * <p>
+     * Note that if the orientation is {@link #VERTICAL}, the width parameter is ignored and if the
+     * orientation is {@link #HORIZONTAL} the height parameter is ignored because child view is
+     * expected to fill all of the space given to it.
+     */
+    public static class LayoutParams extends RecyclerView.LayoutParams {
+        /**
+         * Span Id for Views that are not laid out yet.
+         */
+        public static final int INVALID_SPAN_ID = -1;
+        int mSpanIndex = INVALID_SPAN_ID;
+        int mSpanSize = 0;
+
+        public LayoutParams(Context c, AttributeSet attrs) {
+            super(c, attrs);
+        }
+
+        public LayoutParams(int width, int height) {
+            super(width, height);
+        }
+
+        public LayoutParams(ViewGroup.MarginLayoutParams source) {
+            super(source);
+        }
+
+        public LayoutParams(ViewGroup.LayoutParams source) {
+            super(source);
+        }
+
+        public LayoutParams(RecyclerView.LayoutParams source) {
+            super(source);
+        }
+
+        /**
+         * Returns the current span index of this View. If the View is not laid out yet, the return
+         * value is <code>undefined</code>.
+         * <p>
+         * Starting with RecyclerView <b>24.2.0</b>, span indices are always indexed from position 0
+         * even if the layout is RTL. In a vertical GridLayoutManager, <b>leftmost</b> span is span
+         * 0 if the layout is <b>LTR</b> and <b>rightmost</b> span is span 0 if the layout is
+         * <b>RTL</b>. Prior to 24.2.0, it was the opposite which was conflicting with
+         * {@link SpanSizeLookup#getSpanIndex(int, int)}.
+         * <p>
+         * If the View occupies multiple spans, span with the minimum index is returned.
+         *
+         * @return The span index of the View.
+         */
+        public int getSpanIndex() {
+            return mSpanIndex;
+        }
+
+        /**
+         * Returns the number of spans occupied by this View. If the View not laid out yet, the
+         * return value is <code>undefined</code>.
+         *
+         * @return The number of spans occupied by this View.
+         */
+        public int getSpanSize() {
+            return mSpanSize;
+        }
+    }
+}
diff --git a/core/java/com/android/server/pm/UserTypeDetails.java b/core/java/com/android/server/pm/UserTypeDetails.java
new file mode 100644
index 0000000..5fc3ba1
--- /dev/null
+++ b/core/java/com/android/server/pm/UserTypeDetails.java
@@ -0,0 +1,388 @@
+/*
+ * 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.pm;
+
+import android.annotation.ColorRes;
+import android.annotation.DrawableRes;
+import android.annotation.NonNull;
+import android.annotation.StringRes;
+import android.content.pm.UserInfo;
+import android.content.pm.UserInfo.UserInfoFlag;
+import android.content.res.Resources;
+import android.os.UserManager;
+
+import com.android.internal.util.Preconditions;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Contains the details about a multiuser "user type", such as a
+ * {@link UserManager#USER_TYPE_PROFILE_MANAGED}.
+ *
+ * Tests are located in UserManagerServiceUserTypeTest.java.
+ * @hide
+ */
+public final class UserTypeDetails {
+
+    /** Indicates that there is no limit to the number of users allowed. */
+    public static final int UNLIMITED_NUMBER_OF_USERS = -1;
+
+    /** Name of the user type, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}. */
+    private final @NonNull String mName;
+
+    // TODO(b/142482943): Currently unused. Hook this up.
+    private final boolean mEnabled;
+
+    // TODO(b/142482943): Currently unused and not set. Hook this up.
+    private final int mLabel;
+
+    /**
+     * Maximum number of this user type allowed on the device.
+     * Use {@link #UNLIMITED_NUMBER_OF_USERS} to indicate that there is no hard limit.
+     */
+    private final int mMaxAllowed;
+
+    /**
+     * Maximum number of this user type allowed per parent (for user types, like profiles, that
+     * have parents).
+     * Use {@link #UNLIMITED_NUMBER_OF_USERS} to indicate that there is no hard limit.
+     */
+    // TODO(b/142482943): Should this also apply to restricted profiles?
+    private final int mMaxAllowedPerParent;
+
+    // TODO(b/143784345): Update doc when we clean up UserInfo.
+    /** The {@link UserInfo.UserInfoFlag} representing the base type of this user. */
+    private final @UserInfoFlag int mBaseType;
+
+    // TODO(b/143784345): Update doc/name when we clean up UserInfo.
+    /** The {@link UserInfo.UserInfoFlag}s that all users of this type will automatically have. */
+    private final @UserInfoFlag int mDefaultUserInfoPropertyFlags;
+
+    // TODO(b/142482943): Hook these up to something and set them for each type.
+    private final List<String> mDefaultRestrictions;
+
+
+    // Fields for profiles only, controlling the nature of their badges.
+    // All badge information should be set if {@link #hasBadge()} is true.
+
+    /** Resource ID of the badge put on icons. */
+    private @DrawableRes final int mIconBadge;
+    /** Resource ID of the badge. Should be set if mIconBadge is set. */
+    private @DrawableRes final int mBadgePlain;
+    /** Resource ID of the badge without a background. Should be set if mIconBadge is set. */
+    private @DrawableRes final int mBadgeNoBackground;
+
+    /**
+     * Resource ID ({@link StringRes}) of the of the labels to describe badged apps; should be the
+     * same format as com.android.internal.R.color.profile_badge_1. These are used for accessibility
+     * services.
+     *
+     * <p>This is an array because, in general, there may be multiple users of the same user type.
+     * In this case, the user is indexed according to its {@link UserInfo#profileBadge}.
+     *
+     * <p>Must be set if mIconBadge is set.
+     */
+    private final int[] mBadgeLabels;
+
+    /**
+     * Resource ID ({@link ColorRes}) of the colors badge put on icons.
+     * (The value is a resource ID referring to the color; it is not the color value itself).
+     *
+     * <p>This is an array because, in general, there may be multiple users of the same user type.
+     * In this case, the user is indexed according to its {@link UserInfo#profileBadge}.
+     *
+     * <p>Must be set if mIconBadge is set.
+     */
+    private final int[] mBadgeColors;
+
+    private UserTypeDetails(@NonNull String name, boolean enabled, int maxAllowed,
+            @UserInfoFlag int baseType, @UserInfoFlag int defaultUserInfoPropertyFlags, int label,
+            int maxAllowedPerParent,
+            int iconBadge, int badgePlain, int badgeNoBackground,
+            int[] badgeLabels, int[] badgeColors,
+            ArrayList<String> defaultRestrictions) {
+        this.mName = name;
+        this.mEnabled = enabled;
+        this.mMaxAllowed = maxAllowed;
+        this.mMaxAllowedPerParent = maxAllowedPerParent;
+        this.mBaseType = baseType;
+        this.mDefaultUserInfoPropertyFlags = defaultUserInfoPropertyFlags;
+        this.mDefaultRestrictions =
+                Collections.unmodifiableList(new ArrayList<>(defaultRestrictions));
+
+        this.mIconBadge = iconBadge;
+        this.mBadgePlain = badgePlain;
+        this.mBadgeNoBackground = badgeNoBackground;
+        this.mLabel = label;
+        this.mBadgeLabels = badgeLabels;
+        this.mBadgeColors = badgeColors;
+    }
+
+    /**
+     * Returns the name of the user type, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}.
+     */
+    public String getName() {
+        return mName;
+    }
+
+    // TODO(b/142482943) Hook this up or delete it.
+    public boolean isEnabled() {
+        return mEnabled;
+    }
+
+    /**
+     * Returns the maximum number of this user type allowed on the device.
+     * <p>Returns {@link #UNLIMITED_NUMBER_OF_USERS} to indicate that there is no hard limit.
+     */
+    public int getMaxAllowed() {
+        return mMaxAllowed;
+    }
+
+    /**
+     * Returns the maximum number of this user type allowed per parent (for user types, like
+     * profiles, that have parents).
+     * <p>Returns {@link #UNLIMITED_NUMBER_OF_USERS} to indicate that there is no hard limit.
+     */
+    public int getMaxAllowedPerParent() {
+        return mMaxAllowedPerParent;
+    }
+
+    // TODO(b/143784345): Update comment when UserInfo is reorganized.
+    /** The {@link UserInfo.UserInfoFlag}s that all users of this type will automatically have. */
+    public int getDefaultUserInfoFlags() {
+        return mDefaultUserInfoPropertyFlags | mBaseType;
+    }
+
+    // TODO(b/142482943) Hook this up; it is currently unused.
+    public int getLabel() {
+        return mLabel;
+    }
+
+    /** Returns whether users of this user type should be badged. */
+    public boolean hasBadge() {
+        return mIconBadge != Resources.ID_NULL;
+    }
+
+    /** Resource ID of the badge put on icons. */
+    public @DrawableRes int getIconBadge() {
+        return mIconBadge;
+    }
+
+    /** Resource ID of the badge. Used for {@link UserManager#getUserBadgeResId(int)}. */
+    public @DrawableRes int getBadgePlain() {
+        return mBadgePlain;
+    }
+
+    /** Resource ID of the badge without a background. */
+    public @DrawableRes int getBadgeNoBackground() {
+        return mBadgeNoBackground;
+    }
+
+    /**
+     * Returns the Resource ID of the badgeIndexth badge label, where the badgeIndex is expected
+     * to be the {@link UserInfo#profileBadge} of the user.
+     * If badgeIndex exceeds the number of labels, returns the label for the highest index.
+     */
+    public @StringRes int getBadgeLabel(int badgeIndex) {
+        if (mBadgeLabels == null || mBadgeLabels.length == 0 || badgeIndex < 0) {
+            return Resources.ID_NULL;
+        }
+        return mBadgeLabels[Math.min(badgeIndex, mBadgeLabels.length - 1)];
+    }
+
+    /**
+     * Returns the Resource ID of the badgeIndexth badge color, where the badgeIndex is expected
+     * to be the {@link UserInfo#profileBadge} of the user.
+     * If badgeIndex exceeds the number of colors, returns the color for the highest index.
+     */
+    public @ColorRes int getBadgeColor(int badgeIndex) {
+        if (mBadgeColors == null || mBadgeColors.length == 0 || badgeIndex < 0) {
+            return Resources.ID_NULL;
+        }
+        return mBadgeColors[Math.min(badgeIndex, mBadgeColors.length - 1)];
+    }
+
+    public boolean isProfile() {
+        return (mBaseType & UserInfo.FLAG_PROFILE) != 0;
+    }
+
+    // TODO(b/142482943): Hook this up and don't return the original.
+    public List<String> getDefaultRestrictions() {
+        return mDefaultRestrictions;
+    }
+
+    /** Dumps details of the UserTypeDetails. Do not parse this. */
+    public void dump(PrintWriter pw) {
+        final String prefix = "        ";
+        pw.print(prefix); pw.print("mName: "); pw.println(mName);
+        pw.print(prefix); pw.print("mBaseType: "); pw.println(UserInfo.flagsToString(mBaseType));
+        pw.print(prefix); pw.print("mEnabled: "); pw.println(mEnabled);
+        pw.print(prefix); pw.print("mMaxAllowed: "); pw.println(mMaxAllowed);
+        pw.print(prefix); pw.print("mMaxAllowedPerParent: "); pw.println(mMaxAllowedPerParent);
+        pw.print(prefix); pw.print("mDefaultUserInfoFlags: ");
+        pw.println(UserInfo.flagsToString(mDefaultUserInfoPropertyFlags));
+        pw.print(prefix); pw.print("mLabel: "); pw.println(mLabel);
+        pw.print(prefix); pw.print("mDefaultRestrictions: "); pw.println(mDefaultRestrictions);
+        pw.print(prefix); pw.print("mIconBadge: "); pw.println(mIconBadge);
+        pw.print(prefix); pw.print("mBadgePlain: "); pw.println(mBadgePlain);
+        pw.print(prefix); pw.print("mBadgeNoBackground: "); pw.println(mBadgeNoBackground);
+        pw.print(prefix); pw.print("mBadgeLabels.length: ");
+        pw.println(mBadgeLabels != null ? mBadgeLabels.length : "0(null)");
+        pw.print(prefix); pw.print("mBadgeColors.length: ");
+        pw.println(mBadgeColors != null ? mBadgeColors.length : "0(null)");
+    }
+
+    /** Builder for a {@link UserTypeDetails}; see that class for documentation. */
+    public static final class Builder {
+        // UserTypeDetails properties and their default values.
+        private String mName; // This MUST be explicitly set.
+        private int mBaseType; // This MUST be explicitly set.
+        private int mMaxAllowed = UNLIMITED_NUMBER_OF_USERS;
+        private int mMaxAllowedPerParent = UNLIMITED_NUMBER_OF_USERS;
+        private int mDefaultUserInfoPropertyFlags = 0;
+        private ArrayList<String> mDefaultRestrictions = new ArrayList<>();
+        private boolean mEnabled = true;
+        private int mLabel = Resources.ID_NULL;
+        private int[] mBadgeLabels = null;
+        private int[] mBadgeColors = null;
+        private int mIconBadge = Resources.ID_NULL;
+        private int mBadgePlain = Resources.ID_NULL;
+        private int mBadgeNoBackground = Resources.ID_NULL;
+
+        public Builder setName(String name) {
+            mName = name;
+            return this;
+        }
+
+        public Builder setEnabled(boolean enabled) {
+            mEnabled = enabled;
+            return this;
+        }
+
+        public Builder setMaxAllowed(int maxAllowed) {
+            mMaxAllowed = maxAllowed;
+            return this;
+        }
+
+        public Builder setMaxAllowedPerParent(int maxAllowedPerParent) {
+            mMaxAllowedPerParent = maxAllowedPerParent;
+            return this;
+        }
+
+        public Builder setBaseType(@UserInfoFlag int baseType) {
+            mBaseType = baseType;
+            return this;
+        }
+
+        public Builder setDefaultUserInfoPropertyFlags(@UserInfoFlag int flags) {
+            mDefaultUserInfoPropertyFlags = flags;
+            return this;
+        }
+
+        public Builder setBadgeLabels(int ... badgeLabels) {
+            mBadgeLabels = badgeLabels;
+            return this;
+        }
+
+        public Builder setBadgeColors(int ... badgeColors) {
+            mBadgeColors = badgeColors;
+            return this;
+        }
+
+        public Builder setIconBadge(int badgeIcon) {
+            mIconBadge = badgeIcon;
+            return this;
+        }
+
+        public Builder setBadgePlain(int badgePlain) {
+            mBadgePlain = badgePlain;
+            return this;
+        }
+
+        public Builder setBadgeNoBackground(int badgeNoBackground) {
+            mBadgeNoBackground = badgeNoBackground;
+            return this;
+        }
+
+        public Builder setLabel(int label) {
+            mLabel = label;
+            return this;
+        }
+
+        public Builder setDefaultRestrictions(ArrayList<String> restrictions) {
+            mDefaultRestrictions = restrictions;
+            return this;
+        }
+
+        public UserTypeDetails createUserTypeDetails() {
+            Preconditions.checkArgument(mName != null,
+                    "Cannot create a UserTypeDetails with no name.");
+            Preconditions.checkArgument(hasValidBaseType(),
+                    "UserTypeDetails " + mName + " has invalid baseType: " + mBaseType);
+            Preconditions.checkArgument(hasValidPropertyFlags(),
+                    "UserTypeDetails " + mName + " has invalid flags: "
+                            + Integer.toHexString(mDefaultUserInfoPropertyFlags));
+            if (hasBadge()) {
+                Preconditions.checkArgument(mBadgeLabels != null && mBadgeLabels.length != 0,
+                        "UserTypeDetails " + mName + " has badge but no badgeLabels.");
+                Preconditions.checkArgument(mBadgeColors != null && mBadgeColors.length != 0,
+                        "UserTypeDetails " + mName + " has badge but no badgeColors.");
+            }
+
+            return new UserTypeDetails(mName, mEnabled, mMaxAllowed, mBaseType,
+                    mDefaultUserInfoPropertyFlags, mLabel, mMaxAllowedPerParent,
+                    mIconBadge, mBadgePlain, mBadgeNoBackground, mBadgeLabels, mBadgeColors,
+                    mDefaultRestrictions);
+        }
+
+        private boolean hasBadge() {
+            return mIconBadge != Resources.ID_NULL;
+        }
+
+        // TODO(b/143784345): Refactor this when we clean up UserInfo.
+        private boolean hasValidBaseType() {
+            return mBaseType == UserInfo.FLAG_FULL
+                    || mBaseType == UserInfo.FLAG_PROFILE
+                    || mBaseType == UserInfo.FLAG_SYSTEM
+                    || mBaseType == (UserInfo.FLAG_FULL | UserInfo.FLAG_SYSTEM);
+        }
+
+        // TODO(b/143784345): Refactor this when we clean up UserInfo.
+        private boolean hasValidPropertyFlags() {
+            final int forbiddenMask =
+                    UserInfo.FLAG_PRIMARY |
+                    UserInfo.FLAG_ADMIN |
+                    UserInfo.FLAG_INITIALIZED |
+                    UserInfo.FLAG_QUIET_MODE |
+                    UserInfo.FLAG_FULL |
+                    UserInfo.FLAG_SYSTEM |
+                    UserInfo.FLAG_PROFILE;
+            return (mDefaultUserInfoPropertyFlags & forbiddenMask) == 0;
+        }
+    }
+
+    /**
+     * Returns whether the user type is a managed profile
+     * (i.e. {@link UserManager#USER_TYPE_PROFILE_MANAGED}).
+     */
+    public boolean isManagedProfile() {
+        return UserManager.isUserTypeManagedProfile(mName);
+    }
+}
diff --git a/core/java/com/android/server/pm/UserTypeFactory.java b/core/java/com/android/server/pm/UserTypeFactory.java
new file mode 100644
index 0000000..43bbab1
--- /dev/null
+++ b/core/java/com/android/server/pm/UserTypeFactory.java
@@ -0,0 +1,168 @@
+/*
+ * 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.pm;
+
+import static android.content.pm.UserInfo.FLAG_DEMO;
+import static android.content.pm.UserInfo.FLAG_EPHEMERAL;
+import static android.content.pm.UserInfo.FLAG_FULL;
+import static android.content.pm.UserInfo.FLAG_GUEST;
+import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
+import static android.content.pm.UserInfo.FLAG_PROFILE;
+import static android.content.pm.UserInfo.FLAG_RESTRICTED;
+import static android.content.pm.UserInfo.FLAG_SYSTEM;
+import static android.os.UserManager.USER_TYPE_FULL_DEMO;
+import static android.os.UserManager.USER_TYPE_FULL_GUEST;
+import static android.os.UserManager.USER_TYPE_FULL_RESTRICTED;
+import static android.os.UserManager.USER_TYPE_FULL_SECONDARY;
+import static android.os.UserManager.USER_TYPE_FULL_SYSTEM;
+import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
+import static android.os.UserManager.USER_TYPE_SYSTEM_HEADLESS;
+
+import static com.android.server.pm.UserTypeDetails.UNLIMITED_NUMBER_OF_USERS;
+
+import android.content.res.Resources;
+import android.os.UserManager;
+import android.util.ArrayMap;
+
+/**
+ * Class for creating all {@link UserTypeDetails} on the device.
+ *
+ * Tests are located in UserManagerServiceUserTypeTest.java.
+ * @hide
+ */
+public final class UserTypeFactory {
+
+    /** This is a utility class, so no instantiable constructor. */
+    private UserTypeFactory() {}
+
+    /**
+     * Obtains the user types (built-in and customized) for this device.
+     *
+     * @return mapping from the name of each user type to its {@link UserTypeDetails} object
+     */
+    public static ArrayMap<String, UserTypeDetails> getUserTypes() {
+        final ArrayMap<String, UserTypeDetails> map = new ArrayMap<>();
+        // TODO(b/142482943): Read an xml file for OEM customized types.
+        //                    Remember to disallow "android." namespace
+        // TODO(b/142482943): Read an xml file to get any overrides for the built-in types.
+        final int maxManagedProfiles = 1;
+        map.put(USER_TYPE_PROFILE_MANAGED,
+                getDefaultTypeProfileManaged().setMaxAllowedPerParent(maxManagedProfiles)
+                        .createUserTypeDetails());
+        map.put(USER_TYPE_FULL_SYSTEM, getDefaultTypeSystemFull().createUserTypeDetails());
+        map.put(USER_TYPE_FULL_SECONDARY, getDefaultTypeFullSecondary().createUserTypeDetails());
+        map.put(USER_TYPE_FULL_GUEST, getDefaultTypeFullGuest().createUserTypeDetails());
+        map.put(USER_TYPE_FULL_DEMO, getDefaultTypeFullDemo().createUserTypeDetails());
+        map.put(USER_TYPE_FULL_RESTRICTED, getDefaultTypeFullRestricted().createUserTypeDetails());
+        map.put(USER_TYPE_SYSTEM_HEADLESS, getDefaultTypeSystemHeadless().createUserTypeDetails());
+        return map;
+    }
+
+    /**
+     * Returns the Builder for the default {@link UserManager#USER_TYPE_PROFILE_MANAGED}
+     * configuration.
+     */
+    private static UserTypeDetails.Builder getDefaultTypeProfileManaged() {
+        return new UserTypeDetails.Builder()
+                .setName(USER_TYPE_PROFILE_MANAGED)
+                .setBaseType(FLAG_PROFILE)
+                .setDefaultUserInfoPropertyFlags(FLAG_MANAGED_PROFILE)
+                .setMaxAllowedPerParent(1)
+                .setLabel(0)
+                .setIconBadge(com.android.internal.R.drawable.ic_corp_icon_badge_case)
+                .setBadgePlain(com.android.internal.R.drawable.ic_corp_badge_case)
+                .setBadgeNoBackground(com.android.internal.R.drawable.ic_corp_badge_no_background)
+                .setBadgeLabels(
+                        com.android.internal.R.string.managed_profile_label_badge,
+                        com.android.internal.R.string.managed_profile_label_badge_2,
+                        com.android.internal.R.string.managed_profile_label_badge_3)
+                .setBadgeColors(
+                        com.android.internal.R.color.profile_badge_1,
+                        com.android.internal.R.color.profile_badge_2,
+                        com.android.internal.R.color.profile_badge_3);
+    }
+
+    /**
+     * Returns the Builder for the default {@link UserManager#USER_TYPE_FULL_SECONDARY}
+     * configuration.
+     */
+    private static UserTypeDetails.Builder getDefaultTypeFullSecondary() {
+        return new UserTypeDetails.Builder()
+                .setName(USER_TYPE_FULL_SECONDARY)
+                .setBaseType(FLAG_FULL)
+                .setMaxAllowed(UNLIMITED_NUMBER_OF_USERS);
+    }
+
+    /**
+     * Returns the Builder for the default {@link UserManager#USER_TYPE_FULL_GUEST} configuration.
+     */
+    private static UserTypeDetails.Builder getDefaultTypeFullGuest() {
+        final boolean ephemeralGuests = Resources.getSystem()
+                .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
+        final int flags = FLAG_GUEST | (ephemeralGuests ? FLAG_EPHEMERAL : 0);
+
+        // TODO(b/142482943): Put UMS.initDefaultGuestRestrictions() here; then fetch them from here
+
+        return new UserTypeDetails.Builder()
+                .setName(USER_TYPE_FULL_GUEST)
+                .setBaseType(FLAG_FULL)
+                .setDefaultUserInfoPropertyFlags(flags)
+                .setMaxAllowed(1);
+    }
+
+    /**
+     * Returns the Builder for the default {@link UserManager#USER_TYPE_FULL_DEMO} configuration.
+     */
+    private static UserTypeDetails.Builder getDefaultTypeFullDemo() {
+        return new UserTypeDetails.Builder()
+                .setName(USER_TYPE_FULL_DEMO)
+                .setBaseType(FLAG_FULL)
+                .setDefaultUserInfoPropertyFlags(FLAG_DEMO)
+                .setMaxAllowed(UNLIMITED_NUMBER_OF_USERS);
+    }
+
+    /**
+     * Returns the Builder for the default {@link UserManager#USER_TYPE_FULL_RESTRICTED}
+     * configuration.
+     */
+    private static UserTypeDetails.Builder getDefaultTypeFullRestricted() {
+        return new UserTypeDetails.Builder()
+                .setName(USER_TYPE_FULL_RESTRICTED)
+                .setBaseType(FLAG_FULL)
+                .setDefaultUserInfoPropertyFlags(FLAG_RESTRICTED)
+                .setMaxAllowed(UNLIMITED_NUMBER_OF_USERS);
+    }
+
+    /**
+     * Returns the Builder for the default {@link UserManager#USER_TYPE_FULL_SYSTEM} configuration.
+     */
+    private static UserTypeDetails.Builder getDefaultTypeSystemFull() {
+        return new UserTypeDetails.Builder()
+                .setName(USER_TYPE_FULL_SYSTEM)
+                .setBaseType(FLAG_SYSTEM | FLAG_FULL);
+    }
+
+    /**
+     * Returns the Builder for the default {@link UserManager#USER_TYPE_SYSTEM_HEADLESS}
+     * configuration.
+     */
+    private static UserTypeDetails.Builder getDefaultTypeSystemHeadless() {
+        return new UserTypeDetails.Builder()
+                .setName(USER_TYPE_SYSTEM_HEADLESS)
+                .setBaseType(FLAG_SYSTEM);
+    }
+}
diff --git a/core/proto/android/server/powermanagerservice.proto b/core/proto/android/server/powermanagerservice.proto
index 091e1c2..c039570 100644
--- a/core/proto/android/server/powermanagerservice.proto
+++ b/core/proto/android/server/powermanagerservice.proto
@@ -172,6 +172,8 @@
     repeated SuspendBlockerProto suspend_blockers = 48;
     optional WirelessChargerDetectorProto wireless_charger_detector = 49;
     optional BatterySaverStateMachineProto battery_saver_state_machine = 50;
+    // Attentive timeout in ms. The timeout is disabled if it is set to -1.
+    optional sint32 attentive_timeout_ms = 51;
 }
 
 // A com.android.server.power.PowerManagerService.SuspendBlockerImpl object.
@@ -310,6 +312,12 @@
     optional bool is_vr_mode_enabled = 35;
     // True if Sidekick is controlling the display and we shouldn't change its power mode.
     optional bool draw_wake_lock_override_from_sidekick = 36;
+    // The attentive timeout setting value in milliseconds. Default value is -1.
+    optional sint32 attentive_timeout_setting_ms = 37;
+    // The attentive timeout config value in milliseconds.
+    optional sint32 attentive_timeout_config_ms = 38;
+    // The attentive warning duration config value in milliseconds.
+    optional sint32 attentive_warning_duration_config_ms = 39;
 }
 
 message BatterySaverStateMachineProto {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9f77407..e1ca1f6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -142,7 +142,7 @@
     <protected-broadcast android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.device.action.UUID" />
     <protected-broadcast android:name="android.bluetooth.device.action.MAS_INSTANCE" />
-    <protected-broadcast android:name="android.bluetooth.device.action.ALIAS_CHANGED" />
+    <protected-broadcast android:name="android.bluetooth.action.ALIAS_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.device.action.FOUND" />
     <protected-broadcast android:name="android.bluetooth.device.action.CLASS_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.device.action.ACL_CONNECTED" />
@@ -375,7 +375,7 @@
     <protected-broadcast android:name="android.net.wifi.p2p.THIS_DEVICE_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.p2p.PEERS_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.p2p.CONNECTION_STATE_CHANGE" />
-    <protected-broadcast android:name="android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED" />
+    <protected-broadcast android:name="android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED" />
     <protected-broadcast android:name="android.net.conn.TETHER_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.conn.INET_CONDITION_ACTION" />
     <protected-broadcast android:name="android.net.conn.NETWORK_CONDITIONS_MEASURED" />
@@ -660,7 +660,6 @@
         android:icon="@drawable/perm_group_contacts"
         android:label="@string/permgrouplab_contacts"
         android:description="@string/permgroupdesc_contacts"
-        android:request="@string/permgrouprequest_contacts"
         android:priority="100" />
 
     <!-- Allows an application to read the user's contacts data.
@@ -691,7 +690,6 @@
         android:icon="@drawable/perm_group_calendar"
         android:label="@string/permgrouplab_calendar"
         android:description="@string/permgroupdesc_calendar"
-        android:request="@string/permgrouprequest_calendar"
         android:priority="200" />
 
     <!-- Allows an application to read the user's calendar data.
@@ -722,7 +720,6 @@
         android:icon="@drawable/perm_group_sms"
         android:label="@string/permgrouplab_sms"
         android:description="@string/permgroupdesc_sms"
-        android:request="@string/permgrouprequest_sms"
         android:priority="300" />
 
     <!-- Allows an application to send SMS messages.
@@ -841,7 +838,6 @@
         android:icon="@drawable/perm_group_storage"
         android:label="@string/permgrouplab_storage"
         android:description="@string/permgroupdesc_storage"
-        android:request="@string/permgrouprequest_storage"
         android:priority="900" />
 
     <!-- Allows an application to read from external storage.
@@ -930,10 +926,6 @@
         android:icon="@drawable/perm_group_location"
         android:label="@string/permgrouplab_location"
         android:description="@string/permgroupdesc_location"
-        android:request="@string/permgrouprequest_location"
-        android:requestDetail="@string/permgrouprequestdetail_location"
-        android:backgroundRequest="@string/permgroupbackgroundrequest_location"
-        android:backgroundRequestDetail="@string/permgroupbackgroundrequestdetail_location"
         android:priority="400" />
 
     <!-- Allows an app to access precise location.
@@ -985,7 +977,6 @@
         android:icon="@drawable/perm_group_call_log"
         android:label="@string/permgrouplab_calllog"
         android:description="@string/permgroupdesc_calllog"
-        android:request="@string/permgrouprequest_calllog"
         android:priority="450" />
 
     <!-- Allows an application to access the IMS call service: making and
@@ -1074,7 +1065,6 @@
         android:icon="@drawable/perm_group_phone_calls"
         android:label="@string/permgrouplab_phone"
         android:description="@string/permgroupdesc_phone"
-        android:request="@string/permgrouprequest_phone"
         android:priority="500" />
 
     <!-- Allows read only access to phone state, including the phone number of the device,
@@ -1195,7 +1185,6 @@
         android:icon="@drawable/perm_group_microphone"
         android:label="@string/permgrouplab_microphone"
         android:description="@string/permgroupdesc_microphone"
-        android:request="@string/permgrouprequest_microphone"
         android:priority="600" />
 
     <!-- Allows an application to record audio.
@@ -1217,7 +1206,6 @@
         android:icon="@drawable/perm_group_activity_recognition"
         android:label="@string/permgrouplab_activityRecognition"
         android:description="@string/permgroupdesc_activityRecognition"
-        android:request="@string/permgrouprequest_activityRecognition"
         android:priority="1000" />
 
     <!-- Allows an application to recognize physical activity.
@@ -1260,7 +1248,6 @@
         android:icon="@drawable/perm_group_camera"
         android:label="@string/permgrouplab_camera"
         android:description="@string/permgroupdesc_camera"
-        android:request="@string/permgrouprequest_camera"
         android:priority="700" />
 
     <!-- Required to be able to access the camera device.
@@ -1299,7 +1286,6 @@
         android:icon="@drawable/perm_group_sensors"
         android:label="@string/permgrouplab_sensors"
         android:description="@string/permgroupdesc_sensors"
-        android:request="@string/permgrouprequest_sensors"
         android:priority="800" />
 
     <!-- Allows an application to access data from sensors that the user uses to
@@ -1615,6 +1601,7 @@
 
     <!-- Allows network stack services (Connectivity and Wifi) to coordinate
          <p>Not for use by third-party or privileged applications.
+         @SystemApi
          @hide This should only be used by Connectivity and Wifi Services.
     -->
     <permission android:name="android.permission.NETWORK_STACK"
@@ -1622,6 +1609,7 @@
 
     <!-- Allows Settings and SystemUI to call methods in Networking services
          <p>Not for use by third-party or privileged applications.
+         @SystemApi
          @hide This should only be used by Settings and SystemUI.
     -->
     <permission android:name="android.permission.NETWORK_SETTINGS"
@@ -3583,7 +3571,8 @@
         android:protectionLevel="signature" />
 
     <!-- Allows an application to configure and connect to Wifi displays
-         @hide -->
+         @hide
+         @SystemApi -->
     <permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY"
         android:protectionLevel="signature" />
 
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
index 17b5f50..6807f9a 100644
--- a/core/res/res/layout/chooser_grid.xml
+++ b/core/res/res/layout/chooser_grid.xml
@@ -55,15 +55,14 @@
                   android:layout_centerHorizontal="true"/>
     </RelativeLayout>
 
-    <ListView
+    <com.android.internal.widget.RecyclerView
         android:layout_width="match_parent"
         android:layout_height="match_parent"
+        android:layoutManager="com.android.internal.widget.GridLayoutManager"
         android:id="@+id/resolver_list"
         android:clipToPadding="false"
         android:background="?attr/colorBackgroundFloating"
         android:scrollbars="none"
-        android:listSelector="@color/transparent"
-        android:divider="@null"
         android:elevation="1dp"
         android:nestedScrollingEnabled="true"/>
 
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 485162c..c8ced192 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Gee &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toegang tot hierdie toestel se ligging?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Die program sal net toegang tot die ligging hê terwyl jy die program gebruik"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Laat &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toe om &lt;b&gt;enige tyd&lt;/b&gt; toegang tot jou toestel se ligging te kry?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Program kan tans net toegang tot ligging kry terwyl jy die program gebruik"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"by jou kalender in te gaan"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Gee &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toegang tot jou kalender?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Tik om te kyk wat geblokkeer word."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Stelsel"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Instellings"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Bystandmodus"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Die Android TV-toestel sal binnekort afskakel; druk \'n knoppie om dit aan te hou."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Die toestel gaan binnekort afskakel; druk om dit aan te hou."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofoon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"wys tans bo-oor ander programme op jou skerm"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Regstreekse deling is nie beskikbaar nie"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Programmelys"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Opneemtoestemming is nie aan hierdie program verleen nie, maar dit kan oudio deur hierdie USB-toestel opneem."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Tuis"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Terug"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Onlangse programme"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Kennisgewings"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Kitsinstellings"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Kragdialoog"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Wissel verdeelde skerm"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Sluitskerm"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Skermkiekie"</string>
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index f0a4307..eff754c 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; የዚህ መሣሪያ አካባቢን እንዲደርስ ይፈቀድለት?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"መተግበሪያው እርስዎ ሲጠቀሙበት ብቻ ነው የአካባቢው መዳረሻ የሚኖረው"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"የዚህን መሣሪያ መገኛ አካባቢ &lt;b&gt;ሁልጊዜ&lt;/b&gt; መድረስ እንዲችል ለ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ይፈቀድ?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"እርስዎ መተግበሪያውን እየተጠቀሙ እያሉ መተግበሪያ አሁን ላይ የመገኛ አካባቢን መድረስ ይችላል"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"ይህ እርስዎ መተግበሪያውን በማይጠቀሙበት ጊዜ እንኳ የእርስዎን መገኛ አካባቢ ሁልጊዜ መድረስ ሊፈልግ ይችል ይሆናል። በ"<annotation id="link">"ቅንብሮች"</annotation>" ውስጥ ይፍቀዱ።"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ቀን መቁጠሪያ"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"የእርስዎን ቀን መቁጠሪያ ይድረሱበት"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ቀን መቁጠሪያዎን እንዲደርስ ይፈቀድለት?"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"ምን እንደታገደ ለመፈተሽ መታ ያድርጉ።"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"ሥርዓት"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"ቅንብሮች"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"ተጠባባቂ"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"የAndroid TV መሣሪያው በቅርቡ ይጠፋል፣ እንደበራ ለማቆየት ይጫኑ።"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"መሣሪያው በቅርቡ ይጠፋል፤ እንደበራ ለማቆየት ይጫኑ።"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"ካሜራ"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"ማይክሮፎን"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"በማያዎ ላይ በሌሎች መተግበሪያዎች ላይ በማሳየት ላይ"</string>
@@ -2006,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"ቀጥታ ማጋራት አይገኝም"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"የመተግበሪያዎች ዝርዝር"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"ይህ መተግበሪያ የመቅረጽ ፈቃድ አልተሰጠውም፣ ነገር ግን በዚህ ዩኤስቢ መሣሪያ በኩል ኦዲዮን መቅረጽ ይችላል።"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"መነሻ"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"ተመለስ"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"የቅርብ ጊዜ መተግበሪያዎች"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"ማሳወቂያዎች"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"ፈጣን ቅንብሮች"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"የኃይል መገናኛ"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"የተከፈለ ማያን ቀያይር"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"የማያ ገጽ ቁልፍ"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"ቅጽበታዊ ገጽ እይታ"</string>
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 4ecf6e7..7f75fad 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -298,7 +298,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"‏هل تريد السماح لتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بالوصول إلى الموقع الجغرافي لهذا الجهاز؟"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"لن يكون بإمكان التطبيق الوصول إلى الموقع الجغرافي إلا عند استخدامك لهذا التطبيق."</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"‏هل تريد السماح للتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بالوصول إلى الموقع الجغرافي لهذا الجهاز &lt;b&gt;طوال الوقت&lt;/b&gt;؟"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"لا يمكن للتطبيقات الآن معرفة الموقع الجغرافي إلا عند استخدامك للتطبيق."</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"التقويم"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"الوصول تقويمك"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"‏هل تريد السماح لتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بالدخول إلى التقويم؟"</string>
@@ -2095,9 +2096,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"انقر للاطّلاع على ما تم حظره."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"النظام"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"الإعدادات"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"وضع الاستعداد"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"‏سيتم إيقاف جهاز Android TV قريبًا، اضغط على أحد الأزرار لمواصلة تشغيله."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"سيتم إيقاف الجهاز قريبًا، اضغط لمواصلة تشغيله."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"كاميرا"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"ميكروفون"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"العرض فوق التطبيقات الأخرى على شاشتك"</string>
@@ -2142,22 +2140,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"لا تتوفّر إمكانية المشاركة المباشرة."</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"قائمة التطبيقات"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"‏لم يتم منح هذا التطبيق إذن تسجيل، ولكن يمكنه تسجيل الصوت من خلال جهاز USB هذا."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"الشاشة الرئيسية"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"رجوع"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"التطبيقات المستخدمة مؤخرًا"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"الإشعارات"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"الإعدادات السريعة"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"مربّع حوار الطاقة"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"تبديل \"تقسيم الشاشة\""</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"شاشة القفل"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"لقطة شاشة"</string>
 </resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 81a04b7..31604ef 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ক এই ডিভাইচটোৰ অৱস্থান জানিবলৈ অনুমতি দিবনে?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"আপুনি এই এপ্ ব্যৱহাৰ কৰি থকাৰ সময়তহে ই আপোনাৰ অৱস্থান এক্সেছ কৰিব পাৰে"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&amp;gtক এই ডিভাইচটোৰ অৱস্থান &lt;b&gt;সকলো সময়তে&lt;/b&gt; এক্সেছ কৰিবলৈ দিবনে?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"আপুনি কোনো এপ্ ব্যৱহাৰ কৰি থকাৰ সময়তহে সেই এপ্‌টোৱে অৱস্থান এক্সেছ কৰিব পাৰিব"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"কেলেণ্ডাৰ"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"আপোনাৰ কেলেণ্ডাৰ ব্যৱহাৰ কৰিব পাৰে"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ক আপোনাৰ কেলেণ্ডাৰ চাবলৈ অনুমতি দিবনে?"</string>
@@ -1771,10 +1772,8 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"আপোনাৰ প্ৰশাসকে আপেডট কৰিছে"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"আপোনাৰ প্ৰশাসকে মচিছে"</string>
     <string name="confirm_battery_saver" msgid="639106420541753635">"ঠিক আছে"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (1002571337088673987) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (2307555792915978653) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="1002571337088673987">"বেটাৰীৰ জীৱনকাল বৃদ্ধি কৰিবলৈ, বেটাৰি সঞ্চয়কাৰীয়ে:\n·গাঢ় ৰঙৰ থীম অন কৰে\n·নেপথ্যৰ কাৰ্যকলাপ, কিছুমান ভিজুৱেল প্ৰভাৱ আৰু “Hey Google”ৰ দৰে অন্য সুবিধাসমূহ অফ কৰে অথবা সেইবোৰ সীমাবদ্ধ কৰে\n\n"<annotation id="url">"অধিক জানক"</annotation></string>
+    <string name="battery_saver_description" msgid="2307555792915978653">"বেটাৰীৰ জীৱনকাল বৃদ্ধি কৰিবলৈ, বেটাৰি সঞ্চয়কাৰীয়ে:\n·গাঢ় ৰঙৰ থীম অন কৰে\n·নেপথ্যৰ কাৰ্যকলাপ, কিছুমান ভিজুৱেল প্ৰভাৱ আৰু “Hey Google”ৰ দৰে অন্য সুবিধাসমূহ অফ কৰে অথবা সেইবোৰ সীমাবদ্ধ কৰে"</string>
     <string name="data_saver_description" msgid="6015391409098303235">"ডেটা ব্য়ৱহাৰ মাত্ৰা কম কৰিবৰ বাবে ডেটা সঞ্চয়কাৰীয়ে কিছুমান এপক নেপথ্য়ত ডেটা প্ৰেৰণ বা সংগ্ৰহ কৰাত বাধা প্ৰদান কৰে। আপুনি বৰ্তমান ব্য়ৱহাৰ কৰি থকা এটা এপে ডেটা ব্য়ৱহাৰ কৰিব পাৰে, কিন্তু সঘনাই এই কার্য কৰিব নোৱাৰিব পাৰে। ইয়াৰ অৰ্থ এইয়ে হ\'ব পাৰে যে, উদাহৰণস্বৰূপে, আপুনি নিটিপা পর্যন্ত প্ৰতিচ্ছবিসমূহ দেখুওৱা নহ’ব।"</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"ডেটা সঞ্চয়কাৰী অন কৰিবনে?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"অন কৰক"</string>
@@ -1965,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"কি কি অৱৰোধ কৰা হৈছে জানিবলৈ টিপক।"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"ছিষ্টেম"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"ছেটিংসমূহ"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"ষ্টেণ্ডবাই"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV ডিভাইচটো অতি সোনকালে অফ হ\'ব, এইটো অন ৰাখিবলৈ যিকোনো এটা বুটাম টিপক।"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"এই ডিভাইচটো অতি সোনকালে অফ হ\'ব, এইটো অন ৰাখিবলৈ টিপক।"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"কেমেৰা"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"মাইক্ৰ\'ফ\'ন"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"স্ক্ৰীণত অইন এপৰ ওপৰত দেখুৱাওক"</string>
@@ -2008,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"পোনপটীয়া শ্বেয়াৰৰ সুবিধা নাই"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"এপ্‌সমূহৰ সূচী"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"এই এপ্‌টোক ৰেকর্ড কৰাৰ অনুমতি দিয়া হোৱা নাই কিন্তু ই এই ইউএছবি ডিভাইচটোৰ জৰিয়তে অডিঅ\' ৰেকর্ড কৰিব পাৰে।"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"গৃহ"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"উভতি যাওক"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"শেহতীয়া এপ্‌সমূহ"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"জাননীসমূহ"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"ক্ষিপ্ৰ ছেটিংসমূহ"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"পাৱাৰ ডায়লগ"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"বিভাজিত স্ক্ৰীন ট’গল কৰক"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"লক স্ক্ৰীন"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"স্ক্ৰীণশ্বট"</string>
 </resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 9f43c36..40f5201 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinə bu cihazın məkanına daxil olmaq icazəsi verilsin?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Tətbiq yalnız ondan istifadə etiyiniz zaman məkanı əldə edə bilər"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqin bu cihazın məkanına daxil olmasına icazə verilsin&lt;b&gt;all the time&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Tətbiq yalnız ondan istifadə etdiyiniz zaman məkana daxil ola biləcək"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Təqvim"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"təqvimə daxil olun"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinə təqvimə daxil olmaq icazəsi verilsin?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Nəyin blok edildiyini yoxlamaq üçün klikləyin."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Ayarlar"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Gözləmə rejimi"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV cihazı tezliklə sönəcək; aktiv saxlamaq üçün düyməyə basın."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Cihaz tezliklə sönəcək; aktiv saxlamaq üçün basın."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"ekrandakı digər tətbiqlərdə göstərin"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Birbaşa paylaşım əlçatan deyil"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Tətbiq siyahısı"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Bu tətbiqə yazmaq icazəsi verilməyib, lakin, bu USB vasitəsilə səs yaza bilər."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Əsas səhifə"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Geri"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Son Tətbiqlər"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Bildirişlər"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Sürətli Ayarlar"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Yandırıb-söndürmə dialoqu"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Bölünmüş Ekrana keçid"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Kilid Ekranı"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Ekran şəkli"</string>
 </resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index a6ad733..5e56c64 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -289,7 +289,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Želite li da omogućite da &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pristupa lokaciji ovog uređaja?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Aplikacija će imati pristup lokaciji samo dok koristite aplikaciju"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Želite li da dozvolite da &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pristupa lokaciji uređaja &lt;b&gt;u bilo kom trenutku&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Aplikacija trenutno može da pristupa lokaciji samo kada koristite aplikaciju"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"Ova aplikacija možda želi da pristupa lokaciji sve vreme, čak i kada ne koristite aplikaciju. Omogućite u "<annotation id="link">"podešavanjima"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"pristupi kalendaru"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Želite li da omogućite da &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pristupa kalendaru?"</string>
@@ -1996,9 +1996,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Dodirnite da biste proverili šta je blokirano."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Podešavanja"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Stanje pripravnosti"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV će se uskoro isključiti. Pritisnite dugme da bi ostao uključen."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Uređaj će se uskoro isključiti. Pritisnite da bi ostao uključen."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"prikazuje se na ekranu dok koristite druge aplikacije"</string>
@@ -2040,22 +2037,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Direktno deljenje nije dostupno"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Lista aplikacija"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Ova aplikacija nema dozvolu za snimanje, ali bi mogla da snima zvuk pomoću ovog USB uređaja."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Početak"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Nazad"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Nedavne aplikacije"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Obaveštenja"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Brza podešavanja"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Dijalog napajanja"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Uključite/isključite podeljeni ekran"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Zaključani ekran"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Snimak ekrana"</string>
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 92cad08..6e22721 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -292,7 +292,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Дазволіць праграме &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ да звестак аб месцазнаходжанні гэтай прылады?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Праграма будзе мець доступ да звестак пра месцазнаходжанне толькі падчас карыстання ёю"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Дазволіць праграме &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ да даных пра месцазнаходжанне гэтай прылады &lt;b&gt;ўвесь час&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Цяпер праграма можа мець доступ да звестак пра месцазнаходжанне, толькі калі яна выкарыстоўваецца"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Каляндар"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"атрымліваць доступ да вашага календара"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Дазволіць праграме &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ да вашага календара?"</string>
@@ -2029,9 +2030,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Націсніце, каб паглядзець заблакіраванае."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Сістэма"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Налады"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Рэжым чакання"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Прылада Android TV неўзабаве выключыцца. Каб пакінуць яе ўключанай, націсніце кнопку."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Прылада неўзабаве выключыцца. Націсніце, каб пакінуць яе ўключанай."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Камера"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Мікрафон"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"паказваецца паверх іншых праграм на экране"</string>
@@ -2074,22 +2072,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Непасрэднае абагульванне недаступнае"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Спіс праграм"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"У гэтай праграмы няма дазволу на запіс, аднак яна зможа запісваць аўдыя праз гэту USB-прыладу."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Галоўная старонка"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Назад"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Нядаўнія праграмы"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Апавяшчэнні"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Хуткія налады"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Дыялогавае акно сілкавання"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Пераключальнік падзеленага экрана"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Экран блакіроўкі"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Здымак экрана"</string>
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 9a4ca0c..00e2cb7 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Да се разреши ли на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да осъществява достъп до местоположението на това устройство?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Само когато използвате приложението, то ще има достъп до местоположението"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Да се разреши ли на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; достъп до местоположението на това устройство &lt;b&gt;по всяко време&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Понастоящем приложението има достъп до местоположението само когато се използва"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"има достъп до календара ви"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Да се разреши ли на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да осъществява достъп до календара ви?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Докоснете, за да проверите какво е блокирано."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Система"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Настройки"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Режим на готовност"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Устройството с Android TV скоро ще се изключи. Натиснете бутон, за да остане включено."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Устройството скоро ще се изключи. Натиснете, за да остане включено."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Камера"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Микрофон"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"се показва върху други приложения на екрана"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Няма възможност за директно споделяне"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Списък с приложения"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Приложението няма разрешение за записване, но може да записва звук чрез това USB устройство."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Начало"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Назад"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Скорошни приложения"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Известия"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Бързи настройки"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Диалогов прозорец за захранването"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Превключване на разделения екран"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Заключен екран"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Екранна снимка"</string>
 </resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 4dc5f5c..00974d7 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; অ্যাপকে এই ডিভাইসের লোকেশন অ্যাক্সেস করতে দেবেন?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"আপনি এই অ্যাপ ব্যবহার করার সময়েই শুধু সেটি আপনার লোকেশন অ্যাক্সেস করতে পারবে"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; অ্যাপকে এই ডিভাইসের লোকেশন &lt;b&gt;সব সময়&lt;/b&gt; অ্যাক্সেস করার অনুমতি দিতে চান?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"আপনি যখন অ্যাপটি ব্যবহার করবেন শুধুমাত্র তখনই অ্যাপটি বর্তমান লোকেশন অ্যাক্সেস করতে পারবে।"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ক্যালেন্ডার"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"আপনার ক্যালেন্ডারে অ্যাক্সেস"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-কে আপনার ক্যালেন্ডারে অ্যাক্সেস দেবেন?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"কী কী ব্লক করা আছে তা দেখতে ট্যাপ করুন।"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"সিস্টেম"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"সেটিংস"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"স্ট্যান্ডবাই"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV ডিভাইস শীঘ্রই বন্ধ হয়ে যাবে, চালু রাখতে বোতাম প্রেস করুন।"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"ডিভাইস শীঘ্রই বন্ধ হয়ে যাবে, চালু রাখতে প্রেস করুন।"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"ক্যামেরা"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"মাইক্রোফোন"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"স্ক্রিনে অন্যান্য অ্যাপের উপরে দেখানো হচ্ছে"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"সরাসরি শেয়ার করার সুবিধা নেই"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"অ্যাপের তালিকা"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"এই অ্যাপকে রেকর্ড করার অনুমতি দেওয়া হয়নি কিন্তু USB ডিভাইসের মাধ্যমে সেটি অডিও রেকর্ড করতে পারে।"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"হোম স্ক্রিন"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"ফিরে যান"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"সাম্প্রতিক অ্যাপ"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"বিজ্ঞপ্তি"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"দ্রুত সেটিংস"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"পাওয়ার ডায়লগ"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"স্প্লিট স্ক্রিন টগল করুন"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"লক স্ক্রিন"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"স্ক্রিনশট"</string>
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index ea4d209..b426cdc 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -289,7 +289,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Dozvoliti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; da pristupi lokaciji ovog uređaja?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Aplikacija će imati pristup lokaciji isključivo dok je koristite"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Dozvoliti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pristup lokaciji uređaja &lt;b&gt;sve vrijeme&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Aplikacija trenutno može pristupati lokaciji isključivo dok je koristite"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"Moguće je da će aplikacija željeti pristup vašoj lokaciji sve vrijeme, čak i kada je ne budete koristili. Dozvolite u "<annotation id="link">"postavkama"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"pristupa vašem kalendaru"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Dozvoliti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; da pristupi vašem kalendaru?"</string>
@@ -1796,8 +1796,8 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Ažurirao je vaš administrator"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Izbrisao je vaš administrator"</string>
     <string name="confirm_battery_saver" msgid="639106420541753635">"Uredu"</string>
-    <string name="battery_saver_description_with_learn_more" msgid="1002571337088673987">"Da bi se produljilo trajanje baterije, Štednja baterije:\n·Uključuje Tamnu temu.\n·Isključuje ili ograničava aktivnosti u pozadini, neke vizualne efekte i druge značajke kao što je \"Hey Google\".\n\n"<annotation id="url">"Saznajte više"</annotation></string>
-    <string name="battery_saver_description" msgid="2307555792915978653">"Da bi se produljilo trajanje baterije, Štednja baterije:\n·Uključuje Tamnu temu.\n·Isključuje ili ograničava aktivnosti u pozadini, neke vizualne efekte i druge značajke kao što je \"Hey Google\"."</string>
+    <string name="battery_saver_description_with_learn_more" msgid="1002571337088673987">"Radi produženja vijeka trajanja baterije, Ušteda baterije:\n·Uključuje Tamnu temu\n·Isključuje ili ograničava aktivnosti u pozadini, određene vizuelne efekte i druge funkcije kao što je \"Hej Google\"\n\n"<annotation id="url">"Saznajte više"</annotation></string>
+    <string name="battery_saver_description" msgid="2307555792915978653">"Radi produženja vijeka trajanja baterije, Ušteda baterije:\n·Uključuje Tamnu temu\n·Isključuje ili ograničava aktivnosti u pozadini, određene vizuelne efekte i druge funkcije kao što je \"Hej Google\""</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Da bi se smanjio prijenos podataka, Ušteda podataka sprečava da neke aplikacije šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može pristupiti podacima, ali će to činiti rjeđe. To može značiti, naprimjer, da se slike ne prikazuju sve dok ih ne dodirnete."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Uključiti Uštedu podataka?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Uključi"</string>
@@ -1998,9 +1998,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Dodirnite da provjerite šta je blokirano."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Postavke"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Stanje mirovanja"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV uređaj će se uskoro isključiti. Pritisnite dugme da ostane uključen."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Uređaj će se uskoro isključiti. Pritisnite da ostane uključen."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"prikazivanje preko drugih aplikacija na ekranu"</string>
@@ -2042,22 +2039,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Direktno dijeljenje nije dostupno"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Spisak aplikacija"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Ovoj aplikaciji nije dato odobrenje za snimanje, ali može snimati zvuk putem ovog USB uređaja."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Početna stranica"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Nazad"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Nedavne aplikacije"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Obavještenja"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Brze postavke"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Dijaloški okvir za napajanje"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Uključi/isključi podijeljeni ekran"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Zaključavanje ekrana"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Snimak ekrana"</string>
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 4f9eeb8..02a78dd 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Vols permetre que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; accedeixi a la ubicació del dispositiu?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"L\'aplicació només tindrà accés a la ubicació quan l\'estiguis utilitzant"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Vols permetre que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; accedeixi sempre &lt;b&gt;sempre&lt;/b&gt; a la ubicació d\'aquest dispositiu?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Actualment l\'aplicació només pot accedir a la ubicació quan l\'estàs utilitzant"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendari"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accedir al calendari"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Vols permetre que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; accedeixi al calendari?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Toca per consultar què s\'ha bloquejat."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Configuració"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"En espera"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"El dispositiu Android TV s\'apagarà aviat; prem un botó per mantenir-lo encès."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"El dispositiu s\'apagarà aviat; prem per mantenir-lo encès."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Càmera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Micròfon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"es mostra sobre altres aplicacions a la pantalla"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"La compartició directa no està disponible"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Llista d\'aplicacions"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Aquesta aplicació no té permís de gravació, però pot capturar àudio a través d\'aquest dispositiu USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Inici"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Torna"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Aplicacions recents"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notificacions"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Configuració ràpida"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Quadre de diàleg d\'engegada"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Commuta Pantalla dividida"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Pantalla de bloqueig"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Captura de pantalla"</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 502a7a8..39b197d 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -292,7 +292,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Povolit aplikaci &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; přístup k poloze tohoto zařízení?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Aplikace bude mít přístup k poloze, pouze když ji budete používat"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Povolit aplikaci &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; přístup k poloze zařízení &lt;b&gt;po celou dobu&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Aplikace má přístup k poloze, pouze když ji používáte"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendář"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"přístup ke kalendáři"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Povolit aplikaci &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; přístup ke kalendáři?"</string>
@@ -2029,9 +2030,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Klepnutím zkontrolujete, co je blokováno."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Systém"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Nastavení"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Pohotovostní režim"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Zařízení Android TV se brzy vypne, stisknutím tlačítka ho ponecháte zapnuté."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Zařízení se brzy vypne, stisknutím ho ponecháte zapnuté."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Fotoaparát"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"zobrazení přes ostatní aplikace na obrazovce"</string>
@@ -2074,22 +2072,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Přímé sdílení není k dispozici"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Seznam aplikací"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Tato aplikace nemá oprávnění k nahrávání, ale může zaznamenávat zvuk prostřednictvím tohoto zařízení USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Plocha"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Zpět"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Nedávné aplikace"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Oznámení"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Rychlé nastavení"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Dialogové okno k napájení"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Přepnout rozdělenou obrazovku"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Obrazovka uzamčení"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Snímek obrazovky"</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index d347e35..6d16732 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Vil du give &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; adgang til enhedens placering?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Appen har kun adgang til placeringen, når du bruger appen"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Skal &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; &lt;b&gt;altid&lt;/b&gt; have adgang til denne enheds placering?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Appen kan i øjeblikket kun få adgang til placeringen, mens du bruger appen"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"have adgang til din kalender"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Vil du give &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; adgang til din kalender?"</string>
@@ -1079,7 +1080,7 @@
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Markér alt"</string>
     <string name="cut" msgid="3092569408438626261">"Klip"</string>
-    <string name="copy" msgid="2681946229533511987">"Kopier"</string>
+    <string name="copy" msgid="2681946229533511987">"Kopiér"</string>
     <string name="failed_to_copy_to_clipboard" msgid="1833662432489814471">"Der kunne ikke kopieres til udklipsholderen"</string>
     <string name="paste" msgid="5629880836805036433">"Indsæt"</string>
     <string name="paste_as_plain_text" msgid="5427792741908010675">"Indsæt som almindelig tekst"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Tryk for at se, hvad der er blokeret."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"System"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Indstillinger"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Standby"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV-enheden slukker snart. Tryk på en knap for at holde den tændt."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Enheden slukker snart. Tryk for at holde den tændt."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"vises over andre apps på din skærm"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Det er ikke muligt at dele direkte"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Liste over apps"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Denne app har ikke fået tilladelse til at optage, men optager muligvis lyd via denne USB-enhed."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Hjem"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Tilbage"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Seneste apps"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notifikationer"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Kvikmenu"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Dialogboks om strøm"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Slå Opdelt skærm til eller fra"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Låseskærm"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Screenshot"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index b4b40ea..cbcb4a3 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Zulassen, dass die App &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; den Gerätestandort abruft?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Die App hat nur Zugriff auf den Gerätestandort, solange du sie verwendest"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Zulassen, dass &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; &lt;b&gt;ständig&lt;/b&gt; auf deinen Standort zugreift?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Die App hat gegenwärtig nur dann Zugriff auf den Gerätestandort, wenn du sie verwendest"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"auf deinen Kalender zugreifen"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Zulassen, dass &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; auf deinen Kalender zugreift?"</string>
@@ -1771,10 +1772,8 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Von deinem Administrator aktualisiert"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Von deinem Administrator gelöscht"</string>
     <string name="confirm_battery_saver" msgid="639106420541753635">"Ok"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (1002571337088673987) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (2307555792915978653) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="1002571337088673987">"Der Energiesparmodus sorgt für eine längere Akkulaufzeit:\n·Das dunkle Design wird aktiviert\n·Hintergrundaktivitäten, einige optische Effekte und weitere Funktionen wie \"Ok Google\" werden abgeschaltet oder eingeschränkt\n\n"<annotation id="url">"Weitere Informationen"</annotation></string>
+    <string name="battery_saver_description" msgid="2307555792915978653">"Der Energiesparmodus sorgt für eine längere Akkulaufzeit:\n Das dunkle Design wird aktiviert\n·Hintergrundaktivitäten, einige optische Effekte und weitere Funktionen wie \"Ok Google\" werden abgeschaltet oder eingeschränkt"</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Der Datensparmodus verhindert zum einen, dass Apps im Hintergrund Daten senden oder empfangen, sodass weniger Daten verbraucht werden. Zum anderen werden die Datenzugriffe der gerade aktiven App eingeschränkt, was z. B. dazu führen kann, dass Bilder erst angetippt werden müssen, bevor sie sichtbar werden."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Datensparmodus aktivieren?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Aktivieren"</string>
@@ -1965,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Tippe, um zu überprüfen, welche Inhalte blockiert werden."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"System"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Einstellungen"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Standby"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Das Android TV-Gerät wird demnächst abgeschaltet. Drücke eine Taste, damit es eingeschaltet bleibt."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Das Gerät wird demnächst abgeschaltet. Drücke beispielsweise eine Taste oder berühre den Bildschirm, damit es eingeschaltet bleibt."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"wird über anderen Apps auf dem Bildschirm angezeigt"</string>
@@ -2008,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Direct Share nicht verfügbar"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Liste der Apps"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Diese App hat noch keine Berechtigung zum Aufnehmen erhalten, könnte aber Audioaufnahmen über dieses USB-Gerät machen."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Startseite"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Zurück"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Letzte Apps"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Benachrichtigungen"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Schnelleinstellungen"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Kleines Fenster für Akkustand"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"\"Bildschirm teilen\" ein-/ausschalten"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Sperrbildschirm"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Screenshot"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 73828a1..c017495 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Να επιτρέπεται στην εφαρμογή &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; να έχει πρόσβαση στην τοποθεσία αυτής της συσκευής;"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Η εφαρμογή θα έχει πρόσβαση στην τοποθεσία μόνο κατά τη διάρκεια χρήσης της εφαρμογής"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Να επιτρέπεται η πρόσβαση της εφαρμογής &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; στην τοποθεσία της συσκευής&lt;b&gt;διαρκώς&lt;/b&gt;;"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Οι εφαρμογές μπορούν αυτήν τη στιγμή να έχουν πρόσβαση στην τοποθεσία μόνο κατά τη χρήση της εφαρμογής"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"Αυτή η εφαρμογή θέλει να έχει συνεχώς πρόσβαση στην τοποθεσία σας, ακόμη και όταν δεν χρησιμοποιείτε την εφαρμογή. Εγκρίνετε το αίτημα στις "<annotation id="link">"ρυθμίσεις"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Ημερολόγιο"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"έχει πρόσβαση στο ημερολόγιό σας"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Να επιτρέπεται στην εφαρμογή &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; να έχει πρόσβαση στο ημερολόγιό σας;"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Πατήστε για να ελέγξετε το περιεχόμενο που έχει αποκλειστεί."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Σύστημα"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Ρυθμίσεις"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Κατάσταση αναμονής"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Η συσκευή Android TV σύντομα θα απενεργοποιηθεί. Πατήστε ένα κουμπί για να την κρατήσετε ενεργοποιημένη."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Η συσκευή σύντομα θα απενεργοποιηθεί. Πατήστε για να την κρατήσετε ενεργοποιημένη."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Κάμερα"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Μικρόφωνο"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"εμφανίζεται πάνω σε άλλες εφαρμογές στην οθόνη σας"</string>
@@ -2006,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Η άμεση κοινοποίηση δεν είναι διαθέσιμη"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Λίστα εφαρμογών"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Δεν έχει εκχωρηθεί άδεια εγγραφής σε αυτήν την εφαρμογή, αλλά μέσω αυτής της συσκευής USB θα μπορεί να εγγράφει ήχο."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Αρχική οθόνη"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Επιστροφή"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Πρόσφατες εφαρμογές"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Ειδοποιήσεις"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Γρήγορες ρυθμίσεις"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Παράθυρο διαλόγου λειτουργίας συσκευής"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Εναλλαγή διαχωρισμού οθόνης"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Οθόνη κλειδώματος"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Στιγμιότυπο οθόνης"</string>
 </resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 9163214..8c42b04 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device\'s location?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"The app will only have access to the location while you’re using the app"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device’s location &lt;b&gt;all the time&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"App currently can access location only while you’re using the app"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"This app may want to access your location all the time, even when you’re not using the app. Allow in "<annotation id="link">"settings"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your calendar?"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Tap to check what\'s blocked."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"System"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Settings"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Standby"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"The Android TV device will soon turn off; press a button to keep it on."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"The device will soon turn off; press to keep it on."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Camera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Microphone"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"displaying over other apps on your screen"</string>
@@ -2006,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Direct share not available"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Apps list"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"This app has not been granted record permission but could capture audio through this USB device."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Home"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Back"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Recent Apps"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notifications"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Quick Settings"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Power Dialogue"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Toggle Split Screen"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Lock Screen"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Screenshot"</string>
 </resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index dff558f..2efffbb 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device\'s location?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"The app will only have access to the location while you’re using the app"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device’s location &lt;b&gt;all the time&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"App currently can access location only while you’re using the app"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"This app may want to access your location all the time, even when you’re not using the app. Allow in "<annotation id="link">"settings"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your calendar?"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Tap to check what\'s blocked."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"System"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Settings"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Standby"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"The Android TV device will soon turn off; press a button to keep it on."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"The device will soon turn off; press to keep it on."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Camera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Microphone"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"displaying over other apps on your screen"</string>
@@ -2006,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Direct share not available"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Apps list"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"This app has not been granted record permission but could capture audio through this USB device."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Home"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Back"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Recent Apps"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notifications"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Quick Settings"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Power Dialogue"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Toggle Split Screen"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Lock Screen"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Screenshot"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 9163214..8c42b04 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device\'s location?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"The app will only have access to the location while you’re using the app"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device’s location &lt;b&gt;all the time&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"App currently can access location only while you’re using the app"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"This app may want to access your location all the time, even when you’re not using the app. Allow in "<annotation id="link">"settings"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your calendar?"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Tap to check what\'s blocked."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"System"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Settings"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Standby"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"The Android TV device will soon turn off; press a button to keep it on."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"The device will soon turn off; press to keep it on."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Camera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Microphone"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"displaying over other apps on your screen"</string>
@@ -2006,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Direct share not available"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Apps list"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"This app has not been granted record permission but could capture audio through this USB device."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Home"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Back"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Recent Apps"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notifications"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Quick Settings"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Power Dialogue"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Toggle Split Screen"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Lock Screen"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Screenshot"</string>
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 9163214..8c42b04 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device\'s location?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"The app will only have access to the location while you’re using the app"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device’s location &lt;b&gt;all the time&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"App currently can access location only while you’re using the app"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"This app may want to access your location all the time, even when you’re not using the app. Allow in "<annotation id="link">"settings"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your calendar?"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Tap to check what\'s blocked."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"System"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Settings"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Standby"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"The Android TV device will soon turn off; press a button to keep it on."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"The device will soon turn off; press to keep it on."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Camera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Microphone"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"displaying over other apps on your screen"</string>
@@ -2006,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Direct share not available"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Apps list"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"This app has not been granted record permission but could capture audio through this USB device."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Home"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Back"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Recent Apps"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notifications"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Quick Settings"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Power Dialogue"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Toggle Split Screen"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Lock Screen"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Screenshot"</string>
 </resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 7519ad6..d32edab 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‎‏‏‎Allow &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; to access this device\'s location?‎‏‎‎‏‎"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‏‎‎The app will only have access to the location while you’re using the app‎‏‎‎‏‎"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‏‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‎‎‏‏‎Allow &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; to access this device’s location &lt;b&gt;all the time&lt;/b&gt;?‎‏‎‎‏‎"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‎App currently can access location only while you’re using the app‎‏‎‎‏‎"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‏‏‎‏‎‎‏‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎This app may want to access your location all the time, even when you’re not using the app. Allow in ‎‏‎‎‏‏‎"<annotation id="link">"‎‏‎‎‏‏‏‎settings‎‏‎‎‏‏‎"</annotation>"‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎Calendar‎‏‎‎‏‎"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‏‎‎access your calendar‎‏‎‎‏‎"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎Allow &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; to access your calendar?‎‏‎‎‏‎"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‎‎‎‎‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎Tap to check what\'s blocked.‎‏‎‎‏‎"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‎‎‏‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‎System‎‏‎‎‏‎"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎‏‎Settings‎‏‎‎‏‎"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎Standby‎‏‎‎‏‎"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‎The Android TV device will soon turn off; press a button to keep it on.‎‏‎‎‏‎"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‎‎The device will soon turn off; press to keep it on.‎‏‎‎‏‎"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‎‏‏‎‏‎‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‏‏‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎Camera‎‏‎‎‏‎"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‎‎‏‎‏‎‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎Microphone‎‏‎‎‏‎"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎‎‏‎‎‏‎‎‎‏‏‎‏‎‎‎‏‎‎‏‎displaying over other apps on your screen‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 0381249..ad59833 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"¿Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda a la ubicación de este dispositivo?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"La app solo tendrá acceso a la ubicación cuando esté en uso"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"¿Quieres permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda a la ubicación de este dispositivo &lt;b&gt;todo el tiempo&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Actualmente, la app puede acceder a la ubicación solo cuando está en uso"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceder al calendario"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"¿Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda a tu calendario?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Presiona para consultar lo que está bloqueado."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Configuración"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"En espera"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Pronto se apagará el dispositivo Android TV; presiona un botón para mantenerlo encendido."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Pronto se apagará el dispositivo; presiona para mantenerlo encendido."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Cámara"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Micrófono"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"se superpone a otras apps en tu pantalla"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"No está disponible el uso compartido directo"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Lista de apps"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Aunque no se le otorgó permiso de grabación a esta app, puede capturar audio con este dispositivo USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Página principal"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Atrás"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Apps recientes"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notificaciones"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Configuración rápida"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Diálogo de encendido"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Activar o desactivar pantalla dividida"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Bloquear pantalla"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Captura de pantalla"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 7f152e1..7071263 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"¿Quieres permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda a la ubicación de este dispositivo?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"La aplicación solo podrá acceder a la ubicación cuando la estés usando"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"¿Quieres permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda siempre &lt;b&gt;a la ubicación de tu dispositivo&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Actualmente la aplicación puede acceder a la ubicación solo cuando la estés usando"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"Es posible que esta aplicación quiera acceder a tu ubicación siempre, aunque no la estés usando. Puedes darle permiso en "<annotation id="link">"Ajustes"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceder a tu calendario"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"¿Quieres permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda a tu calendario?"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Toca para consultar lo que se está bloqueando."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Ajustes"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Inactividad"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"El dispositivo Android TV pronto se apagará, pulsa un botón para evitarlo."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"El dispositivo pronto se apagará si no interactúas con él para evitarlo."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Cámara"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Micrófono"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"se muestra sobre otras aplicaciones que haya en la pantalla"</string>
@@ -2006,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"No se puede compartir directamente"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Lista de aplicaciones"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Esta aplicación no tiene permiso para grabar, pero podría registrar audio con este dispositivo USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Inicio"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Atrás"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Aplicaciones recientes"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notificaciones"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Ajustes rápidos"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Abrir cuadro de diálogo"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Activar o desactivar la pantalla dividida"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Pantalla de bloqueo"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Captura de pantalla"</string>
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index a48c482..0bf37ce 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Kas lubada rakendusele &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; juurdepääs selle seadme asukohale?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Rakendusel on juurdepääs asukohale vaid sel ajal, kui rakendust kasutate"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Kas lubada rakendusel &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; &lt;b&gt;alati&lt;/b&gt; seadme asukohale juurde pääseda?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Rakendusel on praegu juurdepääs asukohale vaid sel ajal, kui rakendust kasutate."</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"juurdepääs kalendrile"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Kas lubada rakendusele &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; juurdepääs teie kalendrile?"</string>
@@ -789,7 +790,7 @@
     <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Elukaaslane"</string>
     <string name="relationTypeFather" msgid="5228034687082050725">"Isa"</string>
     <string name="relationTypeFriend" msgid="7313106762483391262">"Sõber"</string>
-    <string name="relationTypeManager" msgid="6365677861610137895">"Haldur"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Juht"</string>
     <string name="relationTypeMother" msgid="4578571352962758304">"Ema"</string>
     <string name="relationTypeParent" msgid="4755635567562925226">"Vanem"</string>
     <string name="relationTypePartner" msgid="7266490285120262781">"Partner"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Puudutage, et kontrollida, mis on blokeeritud."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Süsteem"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Seaded"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Ooterežiim"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV seade lülitub varsti välja; selle aktiivsena hoidmiseks vajutage nuppu."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Seade lülitub värsti välja; selle aktiivsena hoidmiseks vajutage nuppu."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kaamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"teie ekraanil muude rakenduste peal kuvamine"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Vahetu jagamine ei ole saadaval"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Rakenduste loend"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Sellele rakendusele pole antud salvestamise luba, kuid see saab heli jäädvustada selle USB-seadme kaudu."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Avakuva"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Tagasi"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Hiljutised rakendused"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Märguanded"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Kiirseaded"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Energiasäästja dialoog"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Vaheta jagatud ekraanikuva"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Lukustuskuva"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Ekraanipilt"</string>
 </resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 805df6e..1985c77 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Gailuaren kokapena atzitzeko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Hura erabiltzen ari zarenean soilik atzituko du aplikazioak kokapena"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Gailuaren kokapena &lt;b&gt;beti&lt;/b&gt; atzitzeko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Aplikazioak hura darabilzunean atzi dezake kokapena"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Egutegia"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"atzitu egutegia"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Egutegia atzitzeko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Sakatu zer dagoen blokeatuta ikusteko."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Ezarpenak"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Egonean"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV gailua laster itzaliko da; sakatu botoi bat piztuta mantentzeko."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Gailua laster itzaliko da; sakatu piztuta mantentzeko."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofonoa"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"pantailako beste aplikazioen gainean bistaratzen"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Zuzenean partekatzeko aukera ez dago erabilgarri"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Aplikazioen zerrenda"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Aplikazioak ez du grabatzeko baimenik, baina baliteke audioa grabatzea USB bidezko gailu horren bidez."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Pantaila nagusia"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Atzera"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Erabilitako azken aplikazioak"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Jakinarazpenak"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Ezarpen bizkorrak"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Piztu edo itzaltzeko leihoa"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Aktibatu/Desaktibatu pantaila zatitua"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Pantaila blokeatua"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Pantaila-argazkia"</string>
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 98044c6..97c889d 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"‏به &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; اجازه داده شود به مکان این دستگاه دسترسی پیدا کند؟"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"این برنامه فقط وقتی از آن استفاده می‌کنید، به مکان دسترسی خواهد داشت"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"‏به &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; اجازه می‌دهید &lt;b&gt;همیشه&lt;/b&gt; به مکان این دستگاه دسترسی یابد؟"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"درحال‌حاضر برنامه، فقط وقتی از آن استفاده می‌کنید، می‌تواند به مکان دسترسی یابد"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"تقویم"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"دسترسی به تقویم شما"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"‏به &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; اجازه داده شود به تقویم شما دسترسی پیدا کند؟"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"برای بررسی موارد مسدودشده ضربه بزنید."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"سیستم"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"تنظیمات"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"آماده‌به‌کار"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"‏دستگاه Android TV به‌زودی خاموش می‌شود، برای روشن نگه‌داشتن آن، دکمه‌ای را فشار دهید."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"دستگاه به‌زودی خاموش می‌شود، برای روشن نگه‌داشتن آن فشار دهید."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"دوربین"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"میکروفون"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"نمایش روی برنامه‌های دیگر در صفحه‌نمایش"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"اشتراک‌گذاری مستقیم دردسترس نیست"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"فهرست برنامه‌ها"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"‏مجوز ضبط به این برنامه داده نشده است اما می‌تواند صدا را ازطریق این دستگاه USB ضبط کند."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"صفحه اصلی"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"برگشت"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"برنامه‌های اخیر"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"اعلان‌ها"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"تنظیمات سریع"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"کادر گفتگوی روشن/خاموش"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"تغییر وضعیت صفحهٔ دونیمه"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"صفحه قفل"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"عکس صفحه‌نمایش"</string>
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 3476bf5..9d44aad 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Saako &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; oikeuden nähdä tämän laitteen sijainnin?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Sovellus saa sijainnin käyttöoikeuden vain silloin, kun käytät sovellusta"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Saako &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; käyttää laitteen sijaintia &lt;b&gt;aina&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Sovellus saa tällä hetkellä sijainnin käyttöoikeuden vain, jos käytät sovellusta"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalenteri"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"käyttää kalenteria"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Saako &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; kalenterisi käyttöoikeuden?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Napauta niin näet, mitä on estetty."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Järjestelmä"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Asetukset"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Säästötila"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV ‑laite sammuu pian. Pidä se päällä painamalla painiketta."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Laite sammuu pian. Pidä se päällä painamalla."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofoni"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"näkyy näytöllä muiden sovellusten päällä"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Suora jakaminen ei käytettävissä"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Sovellusluettelo"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Sovellus ei ole saanut tallennuslupaa mutta voi tallentaa ääntä tämän USB-laitteen avulla."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Aloitusnäyttö"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Takaisin"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Viimeisimmät sovellukset"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Ilmoitukset"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Pika-asetukset"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Virran valintaikkuna"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Jaettu näyttö päälle/pois"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Lukitusnäyttö"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Kuvakaappaus"</string>
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 702ecc0..273ae5c 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Autoriser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à accéder à la position de cet appareil?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"L\'application aura uniquement accès à la position lorsque vous l\'utilisez"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Autoriser « <xliff:g id="APP_NAME">%1$s</xliff:g> » à accéder à la position de cet appareil en tout temps?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Pour le moment, l\'application peut uniquement accéder à la position lorsque vous l\'utilisez"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accéder à votre agenda"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Autoriser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à accéder à votre agenda?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Touchez l\'écran pour vérifier ce qui est bloqué."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Système"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Paramètres"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Veille"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"L\'appareil Android TV va bientôt s\'éteindre. Appuyez sur un bouton pour le laisser allumé."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"L\'appareil va bientôt s\'éteindre. Interagissez avec lui pour le laisser allumé."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Appareil photo"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Microphone"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"superpose du contenu par-dessus d\'autres applications à l\'écran"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Le partage direct n\'est pas disponible"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Liste des applications"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Cette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait capturer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Accueil"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Retour"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Applications récentes"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notifications"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Paramètres rapides"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Boîte de dialogue sur l\'alimentation"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Basculer l\'écran partagé"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Écran de verrouillage"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Capture d\'écran"</string>
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index eb199de..8d8b365 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Autoriser l\'appli &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à accéder à la position de cet appareil ?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"L\'application n\'a accès à la position de l\'appareil que lorsqu\'elle est ouverte"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Autoriser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à accéder &lt;b&gt;en permanence&lt;/b&gt; à la position de cet appareil ?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"L\'application peut actuellement accéder à la position uniquement pendant que vous l\'utilisez"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accéder à votre agenda"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Permettre à &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; d\'accéder à votre agenda ?"</string>
@@ -1965,9 +1966,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Appuyez pour vérifier les contenus bloqués."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Système"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Paramètres"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Mode Veille imminent"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"L\'appareil Android TV va bientôt passer en mode Veille. Appuyez sur un bouton pour qu\'il reste allumé."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"L\'appareil va bientôt passer en mode Veille. Appuyez dessus pour qu\'il reste allumé."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Caméra"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Micro"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"se superpose aux autres applications sur l\'écran"</string>
@@ -2008,22 +2006,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Le partage direct n\'est pas disponible"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Liste des applications"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Cette application n\'a pas reçu l\'autorisation d\'enregistrer des contenus audio, mais peut le faire via ce périphérique USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Accueil"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Retour"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Applications récentes"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notifications"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Configuration rapide"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Boîte de dialogue Marche/Arrêt"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Activer/Désactiver l\'écran partagé"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Verrouiller l\'écran"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Capture d\'écran"</string>
 </resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 9659973..d3a6840 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Permitir que a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda á localización deste dispositivo?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"A aplicación só terá acceso á localización mentres a esteas utilizando"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Queres permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda á localización deste dispositivo &lt;b&gt;sempre&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Actualmente, a aplicación pode acceder á localización só mentres a utilices"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceder ao teu calendario"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Queres permitir que a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda ao teu calendario?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Toca para comprobar o contido bloqueado."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Configuración"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Modo de espera"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Pronto se apagará o dispositivo Android TV. Preme un botón para mantelo acendido."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Pronto se apagará o teléfono. Tócao para mantelo acendido."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Cámara"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Micrófono"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"mostrando outras aplicacións na pantalla"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Non está dispoñible a función de compartir directamente"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Lista de aplicacións"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Esta aplicación non está autorizada a realizar gravacións, pero pode capturar audio a través deste dispositivo USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Inicio"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Volver"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Aplicacións recentes"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notificacións"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Configuración rápida"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Diálogo sobre a enerxía"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Activar/desactivar pantalla dividida"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Pantalla de bloqueo"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Captura de pantalla"</string>
 </resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 6dab622..5750c85 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને આ ડિવાઇસના સ્થાનને ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"જ્યારે તમે ઍપનો ઉપયોગ કરી રહ્યા હશો માત્ર ત્યારે જ ઍપ સ્થાનને ઍક્સેસ કરી શકશે"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને આ ડિવાઇસનું સ્થાન &lt;b&gt;હંમેશાં&lt;/b&gt; ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"હાલમાં માત્ર જ્યારે તમે ઍપનો ઉપયોગ કરી રહ્યા હશો હોય ત્યારે જ ઍપ સ્થાનને ઍક્સેસ કરી શકશે"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"કૅલેન્ડર"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"તમારા કેલેન્ડરને ઍક્સેસ કરવાની"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને તમારા કૅલેન્ડરને ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
@@ -1342,7 +1343,7 @@
     <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"અન્ય ઍપથી ઉપર બતાવો"</string>
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> અન્ય ઍપ્લિકેશનોની ઉપર પ્રદર્શિત થઈ રહ્યું છે"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> અન્ય ઍપ્લિકેશનો પર દેખાઈ છે"</string>
-    <string name="alert_windows_notification_message" msgid="8917232109522912560">"જો તમે નથી ઇચ્છતા કે <xliff:g id="NAME">%s</xliff:g> આ સુવિધાનો ઉપયોગ કરે, તો સેટિંગ્સ ખોલવા માટે ટૅપ કરો અને તેને બંધ કરો."</string>
+    <string name="alert_windows_notification_message" msgid="8917232109522912560">"જો તમે નથી ઇચ્છતા કે <xliff:g id="NAME">%s</xliff:g> આ સુવિધાનો ઉપયોગ કરે, તો સેટિંગ ખોલવા માટે ટૅપ કરો અને તેને બંધ કરો."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"બંધ કરો"</string>
     <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g> તપાસી રહ્યાં છીએ…"</string>
     <string name="ext_media_checking_notification_message" msgid="410185170877285434">"હાલના કન્ટેન્ટને રિવ્યૂ કરવું"</string>
@@ -1888,7 +1889,7 @@
     <string name="app_category_image" msgid="4867854544519846048">"ફોટો અને છબીઓ"</string>
     <string name="app_category_social" msgid="5842783057834965912">"સામાજિક અને સંચાર"</string>
     <string name="app_category_news" msgid="7496506240743986873">"સમાચાર અને સામાયિકો"</string>
-    <string name="app_category_maps" msgid="5878491404538024367">"નકશા અને નેવિગેશન"</string>
+    <string name="app_category_maps" msgid="5878491404538024367">"Maps અને નેવિગેશન"</string>
     <string name="app_category_productivity" msgid="3742083261781538852">"ઉત્પાદકતા"</string>
     <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"ડિવાઇસ સ્ટૉરેજ"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"USB ડિબગિંગ"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"શું બ્લૉક કરેલ છે તે તપાસવા માટે ટૅપ કરો."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"સિસ્ટમ"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"સેટિંગ"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"સ્ટૅન્ડબાય"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android ટીવી ડિવાઇસ ટૂંક સમયમાં બંધ થશે; તેને ચાલુ રાખવા માટે બટન દબાવો."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"ડિવાઇસ ટૂંક સમયમાં બંધ થશે; તેને ચાલુ રાખવા માટે દબાવો."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"કૅમેરા"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"માઇક્રોફોન"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"આ તમારી સ્ક્રીન પર અન્ય ઍપની ઉપર દેખાશે"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"ડાયરેક્ટ શેર કરવાનું ઉપલબ્ધ નથી"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"ઍપની સૂચિ"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"આ ઍપને રેકૉર્ડ કરવાની પરવાનગી આપવામાં આવી નથી પરંતુ તે આ USB ડિવાઇસ મારફતે ઑડિયો કૅપ્ચર કરી શકે છે."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"હોમ"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"પાછળ"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"તાજેતરની ઍપ"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"નોટિફિકેશન"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"ઝડપી સેટિંગ"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"પાવર સંવાદ"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"સ્ક્રીનને વિભાજિત કરવાની ક્રિયા ટૉગલ કરો"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"લૉક સ્ક્રીન"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"સ્ક્રીનશૉટ"</string>
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 1a082b9..16a6031 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; को इस डिवाइस की \'जगह की जानकारी\' ऐक्सेस करने की अनुमति देना चाहते हैं?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"ऐप्लिकेशन, डिवाइस की जगह की जानकारी सिर्फ़ तभी देख पाएगा जब आप इसका इस्तेमाल कर रहे हों"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"क्या आप <xliff:g id="APP_NAME">%1$s</xliff:g> को हमेशा के लिए जगह की जानकारी ऐक्सेस करने की अनुमति देना चाहते हैं?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"इस समय ऐप्लिकेशन, डिवाइस की \'जगह की जानकारी\' सिर्फ़ तभी देख पाएगा जब आप इसका इस्तेमाल कर रहे हों"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"कैलेंडर"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"अपने कैलेंडर को ऐक्सेस करने"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; को अपना कैलेंडर देखने की अनुमति देना चाहते हैं?"</string>
@@ -1087,7 +1088,7 @@
     <string name="delete" msgid="6098684844021697789">"मिटाएं"</string>
     <string name="copyUrl" msgid="2538211579596067402">"यूआरएल को कॉपी करें"</string>
     <string name="selectTextMode" msgid="1018691815143165326">"लेख को चुनें"</string>
-    <string name="undo" msgid="7905788502491742328">"वापस लाएं"</string>
+    <string name="undo" msgid="7905788502491742328">"पहले जैसा करें"</string>
     <string name="redo" msgid="7759464876566803888">"फिर से करें"</string>
     <string name="autofill" msgid="3035779615680565188">"ऑटोमैटिक भरना"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"टेक्स्ट चुनें"</string>
@@ -1771,8 +1772,8 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"आपके व्यवस्थापक ने अपडेट किया है"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"आपके व्यवस्थापक ने हटा दिया है"</string>
     <string name="confirm_battery_saver" msgid="639106420541753635">"ठीक है"</string>
-    <string name="battery_saver_description_with_learn_more" msgid="1002571337088673987">"बैटरी लाइफ़ बढ़ाने के लिए बैटरी सेवर:\n·गहरे रंग वाली थीम चालू करता है\n·बैकग्राउंड की गतिविधि, कुछ विज़ुअल इफ़ेक्ट, और दूसरी सुविधाएं, जैसे कि \"Hey Google\" को इस्तेमाल करने से रोकता है या बंद करता है\n\n"<annotation id="url">"ज़्यादा जानें"</annotation></string>
-    <string name="battery_saver_description" msgid="2307555792915978653">"बैटरी लाइफ़ बढ़ाने के लिए बैटरी सेवर:\n गहरे रंग वाली थीम चालू करता है\nबैकग्राउंड की गतिविधि, कुछ विज़ुअल इफ़ेक्ट, और दूसरी सुविधाएं, जैसे कि \"Hey Google\" को इस्तेमाल करने से रोकता है या बंद करता है"</string>
+    <string name="battery_saver_description_with_learn_more" msgid="1002571337088673987">"बैटरी लाइफ़ बढ़ाने के लिए बैटरी सेवर:\n·गहरे रंग वाली थीम चालू करता है\n·बैकग्राउंड की गतिविधि, कुछ विज़ुअल इफ़ेक्ट, और \"Hey Google\" जैसी दूसरी सुविधाएं इस्तेमाल करने से रोकता है या बंद करता है\n\n"<annotation id="url">"ज़्यादा जानें"</annotation></string>
+    <string name="battery_saver_description" msgid="2307555792915978653">"बैटरी लाइफ़ बढ़ाने के लिए, बैटरी सेवर:\n गहरे रंग वाली थीम चालू करता है\nबैकग्राउंड की गतिविधि, कुछ विज़ुअल इफ़ेक्ट, और \"Hey Google\" जैसी दूसरी सुविधाएं इस्तेमाल करने से रोकता है या बंद करता है"</string>
     <string name="data_saver_description" msgid="6015391409098303235">"डेटा खर्च, कम करने के लिए डेटा सेवर कुछ ऐप्लिकेशन को बैकग्राउंड में डेटा भेजने या डेटा पाने से रोकता है. आप फ़िलहाल जिस ऐप्लिकेशन का इस्तेमाल कर रहे हैं वह डेटा तक पहुंच सकता है लेकिन ऐसा कभी-कभी ही हो पाएगा. उदाहरण के लिए, इमेज तब तक दिखाई नहीं देंगी जब तक कि आप उन्हें टैप नहीं करते."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"डेटा बचाने की सेटिंग चालू करें?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"चालू करें"</string>
@@ -1888,7 +1889,7 @@
     <string name="app_category_image" msgid="4867854544519846048">"फ़ोटो और तस्वीरें"</string>
     <string name="app_category_social" msgid="5842783057834965912">"सामाजिक और संचार"</string>
     <string name="app_category_news" msgid="7496506240743986873">"समाचार और पत्रिकाएं"</string>
-    <string name="app_category_maps" msgid="5878491404538024367">"मैप और मार्गदर्शक"</string>
+    <string name="app_category_maps" msgid="5878491404538024367">"Maps और नेविगेशन ऐप्लिकेशन"</string>
     <string name="app_category_productivity" msgid="3742083261781538852">"उत्पादकता"</string>
     <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"डिवाइस में जगह"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"USB डीबग करना"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"टैप करके देखें कि किन चीज़ों पर रोक लगाई गई है."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"सिस्टम"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"सेटिंग"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"स्टैंडबाई"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV डिवाइस जल्द ही बंद हो जाएगा. इसे चालू रखने के लिए किसी बटन को दबाएं."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"डिवाइस जल्द ही बंद हो जाएगा. इसे चालू रखने के लिए स्क्रीन पर टैप करें या किसी बटन को दबाएं."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"कैमरा"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"माइक्रोफ़ोन"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"आपकी स्क्रीन पर, इस्तेमाल हो रहे दूसरे ऐप्लिकेशन के ऊपर दिखाया जा रहा है"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"सीधे शेयर नहीं किया जा सकता"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"ऐप्लिकेशन की सूची"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"इस ऐप्लिकेशन को रिकॉर्ड करने की अनुमति नहीं दी गई है. हालांकि, ऐप्लिकेशन इस यूएसबी डिवाइस से ऐसा कर सकता है."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"होम"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"वापस जाएं"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन दिखाएं"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"सूचनाएं खोलें"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"फटाफट सेटिंग खोलें"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"पावर डायलॉग खोलें"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"स्प्लिट स्क्रीन पर टॉगल करें"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"स्क्रीन लॉक करें"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"स्क्रीनशॉट लें"</string>
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 56d5b20..745401d 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -289,7 +289,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Želite li dopustiti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; da pristupa lokaciji ovog uređaja?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Aplikacija će imati pristup lokaciji samo dok upotrebljavate aplikaciju"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Želite li dopustiti da &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pristupa lokaciji ovog uređaja &lt;b&gt;cijelo vrijeme&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Aplikacija trenutačno može pristupiti lokaciji samo dok upotrebljavate aplikaciju"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"Ova aplikacija možda će uvijek htjeti imati pristup vašoj lokaciji, čak i kad je ne koristite. Dopustite u "<annotation id="link">"postavkama"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"pristupati kalendaru"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Želite li dopustiti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; da pristupa vašem kalendaru?"</string>
@@ -1996,9 +1996,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Dodirnite da biste provjerili što je blokirano."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sustav"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Postavke"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Stanje mirovanja"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Uređaj Android TV uskoro će se isključiti. Pritisnite gumb da bi ostao uključen."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Uređaj će se uskoro isključiti. Pritisnite da bi ostao uključen."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Fotoaparat"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"prikazuje se preko drugih aplikacija na zaslonu"</string>
@@ -2040,22 +2037,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Izravno dijeljenje nije dostupno"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Popis aplikacija"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Ta aplikacija nema dopuštenje za snimanje, no mogla bi primati zvuk putem ovog USB uređaja."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Početni zaslon"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Natrag"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Nedavne aplikacije"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Obavijesti"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Brze postavke"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Dijalog napajanja"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Uključite ili isključite podijeljeni zaslon"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Zaključajte zaslon"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Snimka zaslona"</string>
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 184b66a..5df3da7 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Engedélyezi a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; számára, hogy hozzáférjen az eszköz helyadataihoz?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Az alkalmazás csak akkor férhet hozzá a helyadatokhoz, amikor Ön használja az alkalmazást"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Engedélyezi a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; számára, hogy &lt;b&gt;mindig&lt;/b&gt; hozzáférjen az eszköz helyadataihoz?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Az alkalmazás jelenleg csak akkor férhet hozzá a helyadatokhoz, amikor Ön használja az alkalmazást."</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Naptár"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"hozzáférés a naptárhoz"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Engedélyezi a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; számára, hogy hozzáférjen a naptárhoz?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Koppintson a letiltott elemek megtekintéséhez."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Rendszer"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Beállítások"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Készenléti mód"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Az Android TV eszköz hamarosan kikapcsol. Nyomja meg valamelyik gombot, hogy bekapcsolva tarthassa."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Az eszköz hamarosan kikapcsol. Nyomja meg, hogy bekapcsolva tarthassa."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"megjelenítés a képernyőn lévő egyéb alkalmazások előtt"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"A közvetlen megosztás nem áll rendelkezésre"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Alkalmazások listája"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Ez az alkalmazás nem rendelkezik rögzítési engedéllyel, de ezzel az USB-eszközzel képes a hangfelvételre."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Kezdőképernyő"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Vissza"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Legutóbbi alkalmazások"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Értesítések"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Gyorsbeállítások"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Akkumulátorral kapcsolatos párbeszédpanel"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Osztott képernyő be- vagy kikapcsolása"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Lezárási képernyő"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Képernyőkép"</string>
 </resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index fef6f4e..b4b34b5 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Թույլատրե՞լ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածին օգտագործել այս սարքի տեղադրության տվյալները"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Տեղադրության տվյալները հասանելի կլինեն հավելվածին, միայն երբ այն օգտագործելիս լինեք"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;Միշտ&lt;/b&gt; հասանելի դարձնե՞լ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածին ձեր սարքի տեղադրությունը"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Տեղադրության տվյալները հասանելի կլինեն հավելվածին, միայն երբ այն օգտագործելիս լինեք"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Օրացույց"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"օգտագործել օրացույցը"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Թույլատրե՞լ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածին օգտագործել ձեր օրացույցը:"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Հպեք՝ տեսնելու, թե ինչ է արգելափակվել:"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Համակարգ"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Կարգավորումներ"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Սպասման ռեժիմ"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV սարքը շուտով կանջատվի: Սեղմեք որևէ կոճակ՝ միացրած թողնելու համար:"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Սարքը շուտով կանջատվի: Սեղմեք՝ միացրած թողնելու համար:"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Տեսախցիկ"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Խոսափող"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"ցուցադրվում է մյուս հավելվածների վրայից"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Direct Share գործառույթը հասանելի չէ"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Հավելվածների ցանկ"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Հավելվածը ձայնագրելու թույլտվություն չունի, սակայն կկարողանա գրանցել ձայնն այս USB սարքի միջոցով։"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Սկիզբ"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Հետ"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Վերջին օգտագործած հավելվածները"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Ծանուցումներ"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Արագ կարգավորումներ"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Սնուցման պատուհան"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Միացնել/անջատել էկրանի տրոհումը"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Կողպէկրան"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Սքրինշոթ"</string>
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 87a8804..bc44c02 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Izinkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses lokasi perangkat ini?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Aplikasi ini hanya akan memiliki akses ke lokasi selagi Anda menggunakan aplikasi"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Izinkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses lokasi perangkat ini &lt;b&gt;sepanjang waktu&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Saat ini aplikasi hanya dapat mengakses lokasi selagi Anda menggunakan aplikasi tersebut"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"Aplikasi ini mungkin ingin selalu mengakses lokasi, meski tidak sedang digunakan. Izinkan di "<annotation id="link">"setelan"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"mengakses kalender"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Izinkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses kalender?"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Ketuk untuk memeriksa item yang diblokir."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Setelan"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Siaga"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Perangkat Android TV akan segera dimatikan; tekan tombol untuk terus menyalakannya."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Perangkat akan segera dimatikan, tekan untuk terus menyalakannya."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"ditampilkan di atas aplikasi lain di layar"</string>
@@ -2006,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Berbagi langsung tidak tersedia"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Daftar aplikasi"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Aplikasi ini tidak diberi izin merekam, tetapi dapat merekam audio melalui perangkat USB ini."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Beranda"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Kembali"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Aplikasi Baru-Baru Ini"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notifikasi"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Setelan Cepat"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Dialog Power"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Aktifkan Layar Terpisah"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Layar Kunci"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Screenshot"</string>
 </resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index a37eda6..3e76ed1 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Viltu veita &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aðgang að staðsetningu þessa tækis?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Forritið hefur aðeins aðgang að staðsetningunni á meðan þú notar forritið"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Viltu leyfa að &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; hafi &lt;b&gt;alltaf&lt;/b&gt; aðgang að upplýsingum um staðsetningu þessa tækis?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Forritið hefur sem stendur aðeins aðgang að staðsetningu þinni á meðan þú notar forritið"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Dagatal"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"fá aðgang að dagatalinu þínu"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Viltu veita &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aðgang að dagatalinu þínu?"</string>
@@ -1771,10 +1772,8 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Kerfisstjóri uppfærði"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Kerfisstjóri eyddi"</string>
     <string name="confirm_battery_saver" msgid="639106420541753635">"Í lagi"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (1002571337088673987) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (2307555792915978653) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="1002571337088673987">"Til að auka rafhlöðuendingu gerir rafhlöðusparnaður eftirfarandi:\n·Kveikir á dökku þema\n·Slekkur á eða takmarkar bakgrunnsvirkni, tilteknar myndbrellur og aðra eiginleika eins og „Hei Google“.\n\n"<annotation id="url">"Frekari upplýsingar"</annotation></string>
+    <string name="battery_saver_description" msgid="2307555792915978653">"Til að auka rafhlöðuendingu gerir rafhlöðusparnaður eftirfarandi:\n·Kveikir á dökku þema\n·Slekkur á eða takmarkar bakgrunnsvirkni, tilteknar myndbrellur og aðra eiginleika eins og „Hei Google“."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Gagnasparnaður getur hjálpað til við að draga úr gagnanotkun með því að hindra forrit í að senda eða sækja gögn í bakgrunni. Forrit sem er í notkun getur náð í gögn, en gerir það kannski sjaldnar. Niðurstaðan gæti verið, svo dæmi sé tekið, að myndir séu ekki birtar fyrr en þú ýtir á þær."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Kveikja á gagnasparnaði?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Kveikja"</string>
@@ -1965,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Ýttu til að skoða hvað lokað hefur verið á."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Kerfi"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Stillingar"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Biðstaða"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV tækið slekkur á sér fljótlega. Ýttu á takka til að það slokkni ekki á því."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Tækið slekkur á sér fljótlega. Ýttu á takka til að það slokkni ekki á því."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Myndavél"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Hljóðnemi"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"birt yfir öðrum forritum á skjánum"</string>
@@ -2008,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Bein deiling er ekki tiltæk"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Forritalisti"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Þetta forrit hefur ekki fengið heimild fyrir upptöku en gæti tekið upp hljóð í gegnum þetta USB-tæki."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Heim"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Til baka"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Nýleg forrit"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Tilkynningar"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Flýtistillingar"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Gluggi til að slökkva/endurræsa"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Breyta skjáskiptingu"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Lásskjár"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Skjámynd"</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 2b780d0..ddc0f68 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Consentire a &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; di accedere alla posizione del dispositivo?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"L\'app avrà accesso alla posizione soltanto quando la usi"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Consentire a &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; di accedere &lt;b&gt;sempre&lt;/b&gt; alla posizione di questo dispositivo?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"L\'app al momento può accedere alla posizione soltanto mentre la usi"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accedere al calendario"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Consentire all\'app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; di accedere al tuo calendario?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Tocca per controllare le notifiche bloccate."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Impostazioni"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Standby"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Presto il dispositivo Android TV si spegnerà. Premi un pulsante per tenerlo acceso."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Presto il dispositivo si spegnerà. Premi per tenerlo acceso."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Fotocamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Microfono"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"si sovrappone ad altre app sullo schermo"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Condivisione diretta non disponibile"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Elenco di app"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"A questa app non è stata concessa l\'autorizzazione di registrazione, ma l\'app potrebbe acquisire l\'audio tramite questo dispositivo USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Home"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Indietro"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"App recenti"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notifiche"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Impostazioni rapide"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Finestra di dialogo Alimentazione"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Attiva/disattiva schermo diviso"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Schermata di blocco"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Screenshot"</string>
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index dfbf834..c3a8ceb 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -292,7 +292,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"‏לתת לאפליקציה &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; הרשאת גישה למיקום המכשיר?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"לאפליקציה תהיה גישה אל נתוני המיקום רק בזמן השימוש באפליקציה"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"‏להתיר ל-&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; לגשת אל מיקום המכשיר הזה &lt;b&gt;כל הזמן&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"האפליקציה יכולה כרגע לגשת אל המיקום רק כשנעשה בה שימוש"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"יומן"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"גישה אל היומן"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"‏לתת לאפליקציה &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; הרשאת גישה ליומן?"</string>
@@ -2029,9 +2030,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"יש להקיש כדי לבדוק מה חסום."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"מערכת"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"הגדרות"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"המתנה"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"‏מכשיר Android TV ייכבה בקרוב. יש ללחוץ על לחצן כלשהו כדי שהוא ימשיך לפעול."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"המכשיר ייכבה בקרוב, יש ללחוץ כדי שהוא ימשיך לפעול."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"מצלמה"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"מיקרופון"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"תצוגה מעל אפליקציות אחרות במסך"</string>
@@ -2074,22 +2072,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"שיתוף ישיר אינו זמין"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"רשימת האפליקציות"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"‏לאפליקציה זו לא ניתנה הרשאת הקלטה, אבל אפשר להקליט אודיו באמצעות התקן ה-USB הזה."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"בית"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"חזרה"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"אפליקציות אחרונות"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"התראות"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"הגדרות מהירות"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"תיבת דו-שיח לגבי הסוללה"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"החלפת מצב של מסך מפוצל"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"מסך הנעילה"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"צילום מסך"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 4776980..0e30b182 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"このデバイスの位置情報へのアクセスを「&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;」に許可しますか?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"このアプリは、ユーザーがアプリを使用している間のみ位置情報にアクセスできます"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"このデバイスの位置情報に&lt;b&gt;常に&lt;/b&gt;?アクセスすることを &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; に許可します"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"現在、アプリは、ユーザーがアプリを使用している場合のみ位置情報にアクセスできます"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"このアプリは、未使用時も含め、常に位置情報にアクセスしようとすることがあります。["<annotation id="link">"設定"</annotation>"] で許可してください。"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"カレンダー"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"カレンダーへのアクセス"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"カレンダーへのアクセスを「&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;」に許可しますか?"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"タップしてブロック対象をご確認ください。"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"システム"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"設定"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"スタンバイ"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV デバイスはまもなく OFF になります。ON 状態を維持するには、ボタンを押してください。"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"このデバイスはまもなく OFF になります。ON 状態を維持するには、ボタンを押してください。"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"カメラ"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"マイク"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"画面の他のアプリの上に重ねて表示"</string>
@@ -2006,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"ダイレクト シェアは利用できません"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"アプリのリスト"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"このアプリに録音権限は付与されていませんが、この USB デバイスから音声を収集できるようになります。"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"ホーム"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"戻る"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"最近使ったアプリ"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"通知"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"クイック設定"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"電源ダイアログ"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"分割画面の切り替え"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"ロック画面"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"スクリーンショット"</string>
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 7f06b01..552a60f 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"გსურთ, მიანიჭოთ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ს&lt;/b&gt; ამ მოწყობილობის მდებარეობაზე წვდომის ნებართვა?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"ამ აპს მდებარეობაზე წვდომა მხოლოდ მაშინ ექნება, როცა თქვენ მას გამოიყენებთ"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"გსურთ, &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-ს &lt;b&gt;ყოველთვის&lt;/b&gt; ჰქონდეს წვდომა ამ მოწყობილობის მდებარეობაზე?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"ამჟამად აპს მდებარეობაზე წვდომა მხოლოდ მაშინ აქვს, როცა თქვენ მას იყენებთ"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"აპი ითხოვს თქვენს მდებარეობაზე წვდომას ნებისმიერ დროს, მაშინაც კი, როცა თქვენ მას არ იყენებთ. უფლების მიცემა შეგიძლიათ  "<annotation id="link">"პარამეტრებში"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"კალენდარი"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"თქვენს კალენდარზე წვდომა"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"გსურთ, მიანიჭოთ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ს&lt;/b&gt; თქვენს კალენდარზე წვდომის ნებართვა?"</string>
@@ -1771,10 +1771,8 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"განახლებულია თქვენი ადმინისტრატორის მიერ"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"წაიშალა თქვენი ადმინისტრატორის მიერ"</string>
     <string name="confirm_battery_saver" msgid="639106420541753635">"კარგი"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (1002571337088673987) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (2307555792915978653) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="1002571337088673987">"ელემენტის მუშაობის განრძლივობის მიზნით, ელემენტის დამზოგველი:\n·ირთვება ბნელ თემაზე\n·თიშავს ან ზღუდავს ფონის აქტივობებს, გარკვეულ ვიზუალურ ეფექტებს და სახვა შესაძლებლობებს, როგორიც არის “Hey Google”\n\n"<annotation id="url">"შეიტყვეთ მეტი"</annotation></string>
+    <string name="battery_saver_description" msgid="2307555792915978653">"ელემენტის მუშაობის განრძლივობის მიზნით, ელემენტის დამზოგველი:\n·ირთვება ბნელ თემაზე\n·თიშავს ან ზღუდავს ფონის აქტივობებს, გარკვეულ ვიზუალურ ეფექტებს და სახვა შესაძლებლობებს, როგორიც არის “Hey Google”"</string>
     <string name="data_saver_description" msgid="6015391409098303235">"მობილური ინტერნეტის მოხმარების შემცირების მიზნით, მონაცემთა დამზოგველი ზოგიერთ აპს ფონურ რეჟიმში მონაცემთა გაგზავნასა და მიღებას შეუზღუდავს. თქვენ მიერ ამჟამად გამოყენებული აპი მაინც შეძლებს მობილურ ინტერნეტზე წვდომას, თუმცა ამას ნაკლები სიხშირით განახორციელებს. ეს ნიშნავს, რომ, მაგალითად, სურათები არ გამოჩნდება მანამ, სანამ მათ საგანგებოდ არ შეეხებით."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"ჩაირთოს მონაცემთა დამზოგველი?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"ჩართვა"</string>
@@ -1965,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"შეეხეთ იმის სანახავად, თუ რა არის დაბლოკილი."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"სისტემა"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"პარამეტრები"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"მოლოდინის რეჟიმი"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV მოწყობილობა მალე გამოირთვება, დააჭირეთ ღილაკს, რომ ჩართული დარჩეს."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"მოწყობილობა მალე გამოირთვება, დააჭირეთ, რომ ჩართული დარჩეს."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"კამერა"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"მიკროფონი"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"სხვა აპების გადაფარვით ჩანს თქვენს ეკრანზე"</string>
@@ -2008,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"პირდაპირი გაზიარება მიუწვდომელია"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"აპების სია"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"ამ აპს არ აქვს მინიჭებული ჩაწერის ნებართვა, მაგრამ შეუძლია ჩაიწეროს აუდიო ამ USB მოწყობილობის მეშვეობით."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"მთავარი"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"დაბრუნება"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"ბოლოდროინდელი აპები"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"შეტყობინებები"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"სწრაფი პარამეტრები"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"ელკვების დიალოგი"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"გაყოფილი ეკრანის გადართვა"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"ჩაკეტილი ეკრანი"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"ეკრანის ანაბეჭდი"</string>
 </resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 65da546..e398e73 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; қолданбасына құрылғының орналасқан жері туралы мәліметтерді пайдалануға рұқсат берілсін бе?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Қолданбаны пайдалану кезінде ғана оған геодеректеріңізді көруге рұқсат етіледі."</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; қолданбасына құрылғының геодеректері &lt;b&gt;үнемі&lt;/b&gt; көрсетіліп тұрсын ба?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Қолданба геодеректерді тек жұмыс кезінде ғана пайдалана алады."</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Күнтізбе"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"күнтізбеге кіру"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; қолданбасына күнтізбеге кіруге рұқсат берілсін бе?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Түймені түртіп, неге тыйым салынатынын көріңіз."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Жүйе"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Параметрлер"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Күту режимі"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV құрылғысы жақын арада өшеді. Оны қосулы ұстау үшін басыңыз."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Құрылғы жақын арада өшеді. Оны қосулы ұстау үшін басыңыз."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Камера"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Микрофон"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"экранда басқа қолданбалардың үстінен көрсету"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Тікелей бөлісу мүмкін емес."</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Қолданбалар тізімі"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Қолданбаға жазу рұқсаты берілмеді, бірақ ол осы USB құрылғысы арқылы дыбыс жаза алады."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Негізгі экран"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Артқа"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Соңғы пайдаланылған қолданбалар"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Хабарландырулар"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Жылдам параметрлер"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Қуат диалогтік терезесі"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Экранды бөлу мүмкіндігін қосу/өшіру"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Құлып экраны"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Скриншот"</string>
 </resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 32b3ee1..3ce723c 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"អនុញ្ញាតឱ្យ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ចូលប្រើ​ទីតាំងរបស់ឧបករណ៍នេះ?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"កម្មវិធីនេះ​នឹងមាន​សិទ្ធិ​ចូលប្រើ​ទីតាំង នៅពេល​អ្នកកំពុង​ប្រើ​កម្មវិធីនេះ​តែ​ប៉ុណ្ណោះ"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"អនុញ្ញាតឱ្យ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ចូលប្រើ​ទីតាំងរបស់​ឧបករណ៍​នេះ&lt;b&gt;គ្រប់ពេល&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"បច្ចុប្បន្ន​ កម្មវិធី​អាច​ចូលប្រើ​ទីតាំង នៅពេលដែលអ្នកកំពុង​ប្រើប្រាស់​កម្មវិធី​នោះប៉ុណ្ណោះ"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"កម្មវិធីនេះ​ប្រហែលជា​ចង់ប្រើ​ទីតាំង​របស់អ្នក​គ្រប់ពេល ទោះបីជា​អ្នកមិនកំពុងប្រើ​កម្មវិធីនេះ​ក៏ដោយ។ អនុញ្ញាត​នៅក្នុង"<annotation id="link">"ការកំណត់"</annotation>"។"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ប្រតិទិន"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ចូលប្រើប្រិតិទិនរបស់អ្នក"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"អនុញ្ញាតឱ្យ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ចូលប្រើ​ប្រតិទិនរបស់អ្នក?"</string>
@@ -1965,9 +1965,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"សូមចុច​ដើម្បី​មើល​ថា​​បានទប់ស្កាត់អ្វីខ្លះ។"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"ប្រព័ន្ធ"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"ការកំណត់"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"ផ្អាក​ដំណើរការ"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"ឧបករណ៍ Android TV នឹង​បិទ​ក្នុងពេល​ឆាប់ៗនេះ សូមចុច​ប៊ូតុង​ដើម្បី​បន្ត​បើក​ឧបករណ៍។"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"ឧបករណ៍​នឹង​បិទ​ក្នុងពេល​ឆាប់ៗនេះ សូមចុច​ដើម្បី​បន្ត​បើក​ឧបករណ៍។"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"កាមេរ៉ា"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"មីក្រូហ្វូន"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"កំពុងបង្ហាញ​ពីលើកម្មវិធីផ្សេងទៀត​នៅលើអេក្រង់​របស់អ្នក"</string>
@@ -2008,22 +2005,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"មិនមាន​ការចែករំលែក​ដោយផ្ទាល់ទេ"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"បញ្ជីកម្មវិធី"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"កម្មវិធីនេះ​មិនទាន់បាន​ទទួលសិទ្ធិ​ថតសំឡេង​នៅឡើយទេ ប៉ុន្តែអាច​ថតសំឡេង​តាមរយៈ​ឧបករណ៍ USB នេះបាន។"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"ទំព័រដើម"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"ថយក្រោយ"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"កម្មវិធី​ថ្មីៗ"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"ការជូនដំណឹង"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"ការកំណត់រហ័ស"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"ប្រអប់​ថាមពល"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"បិទ/បើក​មុខងារ​បំបែកអេក្រង់"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"អេក្រង់ចាក់សោ"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"រូបថតអេក្រង់"</string>
 </resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 0fab683..94d6836 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"ಈ ಸಾಧನದ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಲು &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ಬಳಸುವಾಗ, ಆ್ಯಪ್ ಮಾತ್ರ ಸ್ಥಳಕ್ಕೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತದೆ"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;ಎಲ್ಲಾ ಸಮಯದಲ್ಲೂ&lt;/b&gt; ಈ ಸಾಧನದ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಲು &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುವುದೇ?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ಬಳಸುವಾಗ ಮಾತ್ರ, ಅದು ಪ್ರಸ್ತುತವಾಗಿ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ಕ್ಯಾಲೆಂಡರ್"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಲು"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಲು &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string>
@@ -1340,9 +1341,9 @@
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"ಇತರ ಅಪ್ಲಿಕೇಶನ್ ಮೇಲೆ ಡಿಸ್‌ಪ್ಲೇ"</string>
-    <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> ಇತರ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಮೂಲಕ ಪ್ರದರ್ಶಿಸುತ್ತಿದೆ"</string>
-    <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ಇತರವುಗಳ ಮೇಲೆ ಪ್ರದರ್ಶಿಸುತ್ತಿದೆ"</string>
-    <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ಈ ವೈಶಿಷ್ಟ್ಯ ಬಳಸುವುದನ್ನು ನೀವು ಬಯಸದಿದ್ದರೆ, ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆದು, ಅದನ್ನು ಆಫ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+    <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> ಇತರೆ ಆ್ಯಪ್‌ಗಳ ಮೇಲೆ ಡಿಸ್‌ಪ್ಲೇ ಆಗುತ್ತದೆ"</string>
+    <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ಇತರೆ ಆ್ಯಪ್‌ಗಳ ಮೇಲೆ ಡಿಸ್‌ಪ್ಲೇ ಆಗುತ್ತದೆ"</string>
+    <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ಈ ವೈಶಿಷ್ಟ್ಯ ಬಳಸುವುದನ್ನು ನೀವು ಬಯಸದಿದ್ದರೆ, ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಲು ಮತ್ತು ಅದನ್ನು ಆಫ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"ಆಫ್ ಮಾಡಿ"</string>
     <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g> ಅನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ…"</string>
     <string name="ext_media_checking_notification_message" msgid="410185170877285434">"ಪ್ರಸ್ತುತ ವಿಷಯವನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ"</string>
@@ -1888,7 +1889,7 @@
     <string name="app_category_image" msgid="4867854544519846048">"ಫೋಟೋಗಳು ಮತ್ತು ಚಿತ್ರಗಳು"</string>
     <string name="app_category_social" msgid="5842783057834965912">"ಸಾಮಾಜಿಕ ಮತ್ತು ಸಂವಹನ"</string>
     <string name="app_category_news" msgid="7496506240743986873">"ಸುದ್ದಿ ಮತ್ತು ನಿಯತಕಾಲಿಕೆಗಳು"</string>
-    <string name="app_category_maps" msgid="5878491404538024367">"ನಕ್ಷೆಗಳು ಮತ್ತು ನ್ಯಾವಿಗೇಶನ್"</string>
+    <string name="app_category_maps" msgid="5878491404538024367">"Maps ಮತ್ತು ನ್ಯಾವಿಗೇಶನ್"</string>
     <string name="app_category_productivity" msgid="3742083261781538852">"ಉತ್ಪಾದಕತೆ"</string>
     <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"ಸಾಧನ ಸಂಗ್ರಹಣೆ"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"ಏನನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ ಎಂಬುದನ್ನು ಪರೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"ಸಿಸ್ಟಂ"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"ಸ್ಟ್ಯಾಂಡ್‌ಬೈ"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"ಈ Android TV ಸಾಧನವು ಶೀಘ್ರವೇ ಆಫ್ ಆಗುತ್ತದೆ; ಇದನ್ನು ಆನ್‌ನಲ್ಲಿಡಲು ಬಟನ್ ಅನ್ನು ಒತ್ತಿರಿ."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"ಈ ಸಾಧನವು ಶೀಘ್ರವೇ ಆಫ್ ಆಗುತ್ತದೆ; ಇದನ್ನು ಆನ್‌ನಲ್ಲಿಡಲು ಒತ್ತಿರಿ."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"ಕ್ಯಾಮರಾ"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"ಮೈಕ್ರೋಫೋನ್‌"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ಇತರ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಮೂಲಕ ಪ್ರದರ್ಶಿಸಲಾಗುತ್ತಿದೆ"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"ನೇರ ಹಂಚಿಕೆ ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"ಆ್ಯಪ್‌ಗಳ ಪಟ್ಟಿ"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"ಈ ಆ್ಯಪ್‌ಗೆ ರೆಕಾರ್ಡ್ ಅನುಮತಿಯನ್ನು ನೀಡಲಾಗಿಲ್ಲ, ಆದರೆ ಈ USB ಸಾಧನದ ಮೂಲಕ ಆಡಿಯೊವನ್ನು ಸೆರೆಹಿಡಿಯಬಲ್ಲದು."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"ಹೋಮ್"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"ಹಿಂದಕ್ಕೆ"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳು"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"ಅಧಿಸೂಚನೆಗಳು"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳು"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"ಪವರ್ ಡೈಲಾಗ್"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"ಸ್ಪ್ಲಿಟ್-ಸ್ಕ್ರೀನ್ ಟಾಗಲ್ ಮಾಡಿ"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"ಲಾಕ್ ಸ್ಕ್ರೀನ್"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್"</string>
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index f42a928..c58d36c 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;에서 내 기기 위치에 액세스하도록 허용하시겠습니까?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"앱을 사용할 때만 앱에서 위치에 액세스합니다."</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; 앱이 이 기기의 위치에 &lt;b&gt;항상&lt;/b&gt; 액세스하도록 허용하시겠습니까?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"현재 앱을 사용 중일 때만 앱에서 위치에 액세스할 수 있습니다."</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"캘린더"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"캘린더에 액세스"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;에서 내 캘린더에 액세스하도록 허용하시겠습니까?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"차단된 항목을 확인하려면 탭하세요."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"시스템"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"설정"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"대기"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV가 곧 꺼집니다. 계속 사용하려면 버튼을 누르세요."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"기기가 곧 꺼집니다. 계속 사용하려면 누르세요."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"카메라"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"마이크"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"화면에서 다른 앱 위에 표시"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"직접 공유가 지원되지 않음"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"앱 목록"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"이 앱에는 녹음 권한이 부여되지 않았지만, 이 USB 기기를 통해 오디오를 녹음할 수 있습니다."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"홈"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"뒤로"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"최근 앱"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"알림"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"빠른 설정"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"전원 대화상자"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"화면 분할 모드 전환"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"잠금 화면"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"스크린샷"</string>
 </resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 82064b2..f7095a7 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосу бул түзмөктүн кайда жүргөнүн көрүп турсунбу?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Колдонмону колдонуп жаткан маалда гана, ал сиздин кайда жүргөнүңүздү билип турат."</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосу бул түзмөктүн жүргөн жерин &lt;b&gt;ар дайым&lt;/b&gt; билип турсунбу?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Колдонмону пайдаланып жаткан учурда гана ал жайгашкан жерди көрө алат"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Жылнаама"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"жылнаамаңызды пайдалануу"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосуна жылнаамаңызды пайдаланууга уруксат берилсинби?"</string>
@@ -1964,9 +1965,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Бөгөттөлгөн нерселерди көрүү үчүн таптаңыз."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Тутум"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Жөндөөлөр"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Көшүү режими"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV түзмөгү жакында өчүрүлөт, аны күйүк боюнча калтыруу үчүн баскычты басыңыз."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Түзмөк жакында өчүрүлөт, күйүк боюнча калтыруу үчүн басып коюңуз."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Камера"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Микрофон"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"экрандагы башка терезелердин үстүнөн көрсөтүлүүдө"</string>
@@ -2007,22 +2005,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Түздөн-түз бөлүшүүгө болбойт"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Колдонмолордун тизмеси"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Бул колдонмонун жаздырууга уруксаты жок, бирок бул USB түзмөгү аркылуу аудиону жаздыра алат."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Башкы бет"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Артка"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Акыркы колдонмолор"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Билдирмелер"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Ыкчам жөндөөлөр"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Кубат диалогу"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Экранды бөлүүнү күйгүзүү же өчүрүү"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Кулпуланган экран"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Скриншот"</string>
 </resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 3aa786e..63b1437 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"ອະນຸຍາດ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ໃຫ້ເຂົ້າເຖິງສະຖານທີ່ຂອງອຸປະກອນບໍ?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"ແອັບຈະມີສິດເຂົ້າເຖິງສະຖານທີ່ໃນເວລາທີ່ທ່ານກຳລັງໃຊ້ແອັບຢູ່ເທົ່ານັ້ນ"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"ອະນຸຍາດໃຫ້ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ເຂົ້າເຖິງສະຖານທີ່ຂອງອຸປະກອນໄດ້ &lt;b&gt;ຕະຫຼອດເວລາ&lt;/b&gt; ບໍ?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"ຕອນນີ້ແອັບສາມາດເຂົ້າເຖິງສະຖານທີ່ໄດ້ສະເພາະເວລາທີ່ທ່ານໃຊ້ແອັບເທົ່ານັ້ນ"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"ແອັບນີ້ອາດຕ້ອງການເຂົ້າເຖິງສະຖານທີ່ຂອງທ່ານຕະຫຼອດເວລາ, ເຖິງແມ່ນວ່າທ່ານຈະບໍ່ໄດ້ໃຊ້ແອັບຢູ່ກໍຕາມ. ອະນຸຍາດໃນ "<annotation id="link">"ການຕັ້ງຄ່າ"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ປະຕິທິນ"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ເຂົ້າ​ຫາ​ປະ​ຕິ​ທິນ​ຂອງ​ທ່ານ"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"ອະນຸຍາດ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ໃຫ້ເຂົ້າເຖິງປະຕິທິນຂອງທ່ານບໍ?"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"ແຕະເພື່ອກວດສອບວ່າມີຫຍັງຖືກບລັອກໄວ້ແດ່."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"ລະບົບ"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"ການຕັ້ງຄ່າ"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"ສະແຕນບາຍ"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"ອຸປະກອນ Android TV ຈະປິດໃນອີກບໍ່ດົນ, ກົດປຸ່ມໃດໜຶ່ງເພື່ອເປີດມັນໄວ້ຕໍ່."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"ອຸປະກອນຈະປິດໃນອີກບໍ່ດົນ, ກົດເພື່ອເປີດມັນໄວ້ຕໍ່."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"ກ້ອງ"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"ໄມໂຄຣໂຟນ"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"ສະແດງຜົນບັງແອັບອື່ນຢູ່ໜ້າຈໍຂອງທ່ານ"</string>
@@ -2006,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"ບໍ່ສາມາດແບ່ງປັນໂດຍກົງໄດ້"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"ລາຍຊື່ແອັບ"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"ແອັບນີ້ບໍ່ໄດ້ຮັບສິດອະນຸຍາດໃນການບັນທຶກ ແຕ່ສາມາດບັນທຶກສຽງໄດ້ຜ່ານອຸປະກອນ USB ນີ້."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"ເຮືອນ"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"ກັບຄືນ"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"ແອັບຫຼ້າສຸດ"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"ການແຈ້ງເຕືອນ"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"ການຕັ້ງຄ່າດ່ວນ"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"ກ່ອງໂຕ້ຕອບການເປີດປິດ"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"ເປີດ/ປິດການແບ່ງໜ້າຈໍ"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"ໜ້າຈໍລັອກ"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"ຮູບໜ້າຈໍ"</string>
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index d4d19f4..180497e 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -292,7 +292,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Suteikti &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; galimybę pasiekti įrenginio vietovę?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Programa galės pasiekti vietovę, tik kai ją naudosite"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Leisti &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pasiekti šio įrenginio vietovę &lt;b&gt;visą laiką&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Šiuo metu programa gali pasiekti vietovę, tik kai ją naudojate"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendorius"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"pasiekti kalendorių"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Suteikti &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; galimybę pasiekti kalendorių?"</string>
@@ -2029,9 +2030,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Palieskite, kad patikrintumėte, kas blokuojama."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Nustatymai"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Budėjimo laikas"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"„Android TV“ įrenginys netrukus išsijungs. Paspauskite mygtuką, kad įrenginys liktų įjungtas."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Įrenginys netrukus išsijungs. Paspauskite, kad jis liktų įjungtas."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Fotoaparatas"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofonas"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"rodo virš kitų programų jūsų ekrane"</string>
@@ -2074,22 +2072,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Tiesioginio bendrinimo funkcija nepasiekiama"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Programų sąrašas"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Šiai programai nebuvo suteiktas leidimas įrašyti, bet ji gali užfiksuoti garsą per šį USB įrenginį."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Pagrindinis"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Atgal"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Naujausios programos"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Pranešimai"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Spartieji nustatymai"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Maitinimo dialogo langas"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Perjungti išskaidyto ekrano režimą"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Užrakinimo ekranas"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Ekrano kopija"</string>
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 89a98dd..ef428a9 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -289,7 +289,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Vai atļaut lietotnei &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; piekļūt šīs ierīces atrašanās vietai?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Lietotne varēs piekļūt atrašanās vietai tikai tad, kad izmantosiet šo lietotni"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Vai &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; drīkst piekļūt ierīces atrašanās vietai &lt;b&gt;vienmēr&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Pašlaik lietotne var piekļūt atrašanās vietai tikai tad, kad izmantojat šo lietotni"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendārs"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"piekļūt jūsu kalendāram"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Vai atļaut lietotnei &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; piekļūt jūsu kalendāram?"</string>
@@ -1996,9 +1997,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Pieskarieties, lai uzzinātu, kas tiek bloķēts."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistēma"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Iestatījumi"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Gaidstāve"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV ierīce drīz izslēgsies. Nospiediet pogu, lai tā paliktu ieslēgta."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Ierīce drīz izslēgsies. Nospiediet, lai tā paliktu ieslēgta."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofons"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"rāda pāri citām lietotnēm jūsu ekrānā"</string>
@@ -2040,22 +2038,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Tiešā kopīgošana nav pieejama"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Lietotņu saraksts"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Šai lietotnei nav piešķirta ierakstīšanas atļauja, taču tā varētu tvert audio, izmantojot šo USB ierīci."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Sākums"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Atpakaļ"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Nesen izmantotās lietotnes"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Paziņojumi"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Ātrie iestatījumi"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Barošanas dialoglodziņš"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Pārslēgt ekrāna sadalīšanu"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Bloķēt ekrānu"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Ekrānuzņēmums"</string>
 </resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 4396c08..896942f 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Дали да се дозволи &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да пристапува до локацијата на уредов?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Апликацијата ќе има пристап до локацијата само додека ја користите"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Да се дозволи &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да пристапува до локацијата на уредов &lt;b&gt;во секое време&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Апликацијата во моментов може да пристапува до локацијата само додека ја користите"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"пристапува до календарот"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Дали да се дозволи &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да пристапува до календарот?"</string>
@@ -1965,9 +1966,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Допрете за да проверите што е блокирано."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Систем"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Поставки"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Подготвеност"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Уредот со Android TV наскоро ќе се исклучи, притиснете копче за да остане вклучен."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Уредот наскоро ќе се исклучи, притиснете за да остане вклучен."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Камера"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Микрофон"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"се прикажува преку други апликации на вашиот екран"</string>
@@ -2008,22 +2006,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Не е достапно директно споделување"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Список со апликации"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"На апликацијава не ѝ е доделена дозвола за снимање, но може да снима аудио преку овој USB-уред."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Почеток"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Назад"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Неодамнешни апликации"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Известувања"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Брзи поставки"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Дијалог за напојување"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Вклучи/исклучи поделен екран"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Заклучен екран"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Слика од екранот"</string>
 </resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 0b33971..f75d2d6 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"ഈ ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ആക്‌സസ് ചെയ്യാൻ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ആപ്പിനെ അനുവദിക്കണോ?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"നിങ്ങൾ ആപ്പ് ഉപയോഗിക്കുമ്പോൾ മാത്രമേ അതിന് ലൊക്കേഷൻ ആക്‌സസ് ലഭിക്കൂ."</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിനെ ഈ ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ആക്‌സസ് ചെയ്യാൻ എപ്പോഴും അനുവദിക്കണോ?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"നിലവിൽ, ഉപയോഗിക്കുമ്പോൾ മാത്രം ആപ്പിന് ലൊക്കേഷൻ ആക്‌സസ് ചെയ്യാം"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"കലണ്ടർ"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"നിങ്ങളുടെ കലണ്ടർ ആക്‌സസ്സ് ചെയ്യുക"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"നിങ്ങളുടെ കലണ്ടർ ആക്‌സസ് ചെയ്യാൻ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ആപ്പിനെ അനുവദിക്കണോ?"</string>
@@ -1340,9 +1341,9 @@
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"മറ്റ് ആപ്‌സിന് മുകളിൽ പ്രദർശിപ്പിക്കുക"</string>
-    <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> മറ്റ് ആപ്പുകൾക്ക് മുകളിൽ പ്രദർശിപ്പിക്കുന്നു"</string>
-    <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> മറ്റ് ആപ്പുകൾക്ക് മുകളിൽ പ്രദർശിപ്പിക്കുന്നു"</string>
-    <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ഈ ഫീച്ചർ ഉപയോഗിക്കുന്നതിൽ നിങ്ങൾക്ക് താൽപ്പര്യമില്ലെങ്കിൽ, ടാപ്പുചെയ്‌ത് ക്രമീകരണം തുറന്ന് അത് ഓഫാക്കുക."</string>
+    <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> മറ്റ് ആപ്പുകൾക്ക് മുകളിൽ കാണിക്കുന്നു"</string>
+    <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> മറ്റ് ആപ്പുകൾക്ക് മേലെയാണ്"</string>
+    <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ഈ ഫീച്ചർ ഉപയോഗിക്കേണ്ടെങ്കിൽ, ടാപ്പ് ചെയ്‌ത് ക്രമീകരണം തുറന്ന് അത് ഓഫാക്കുക."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"ഓഫാക്കുക"</string>
     <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g> പരിശോധിക്കുന്നു…"</string>
     <string name="ext_media_checking_notification_message" msgid="410185170877285434">"നിലവിലെ ഉള്ളടക്കം അവലോകനം ചെയ്യുന്നു"</string>
@@ -1888,7 +1889,7 @@
     <string name="app_category_image" msgid="4867854544519846048">"ഫോട്ടോകളും ചിത്രങ്ങളും"</string>
     <string name="app_category_social" msgid="5842783057834965912">"സാമൂഹിക ആപ്സുകളും ആശയവിനിമയവും"</string>
     <string name="app_category_news" msgid="7496506240743986873">"വാർത്തകളും മാസികകളും"</string>
-    <string name="app_category_maps" msgid="5878491404538024367">"മാപ്സും നാവിഗേഷനും"</string>
+    <string name="app_category_maps" msgid="5878491404538024367">"മാപ്പുകളും നാവിഗേഷനും"</string>
     <string name="app_category_productivity" msgid="3742083261781538852">"ഉല്‍‌പ്പാദനക്ഷമത"</string>
     <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"ഉപകരണ സ്റ്റോറേജ്"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"USB ഡീബഗ്ഗിംഗ്"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"എന്തിനെയാണ് ബ്ലോക്ക് ചെയ്‌തതെന്ന് പരിശോധിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"സിസ്റ്റം"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"ക്രമീകരണം"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"സ്‌റ്റാൻഡ്‌ബൈ"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android ടിവി ഉടൻ ഓഫാകും, ഓണാക്കി നിർത്താൻ ഒരു ബട്ടൺ അമർത്തുക."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"ഉപകരണം ഉടൻ ഓഫാകും, ഓണാക്കി നിർത്താൻ അമർത്തുക."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"ക്യാമറ"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"മൈക്രോഫോൺ"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"നിങ്ങളുടെ സ്‌ക്രീനിലെ മറ്റ് ആപ്പുകൾക്ക് മുകളിൽ പ്രദർശിപ്പിക്കുന്നു"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"നേരിട്ടുള്ള പങ്കിടൽ ലഭ്യമല്ല"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"ആപ്പുകളുടെ ലിസ്‌റ്റ്"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"ഈ ആപ്പിന് റെക്കോർഡ് അനുമതി നൽകിയിട്ടില്ല, എന്നാൽ ഈ USB ഉപകരണത്തിലൂടെ ഓഡിയോ ക്യാപ്‌ചർ ചെയ്യാനാവും."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"ഹോം"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"തിരികെ പോകുക"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"സമീപകാലത്തെ ആപ്പുകൾ"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"അറിയിപ്പുകൾ"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"ദ്രുത ക്രമീകരണം"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"പവർ ഡയലോഗ്"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"സ്‌ക്രീൻ വിഭജന മോഡ് മാറ്റുക"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"ലോക്ക് സ്‌ക്രീൻ"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"സ്ക്രീൻഷോട്ട്"</string>
 </resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 990a4d0..1791d0c 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-д энэ төхөөрөмжийн байршилд хандахыг зөвшөөрөх үү?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Та тухайн аппыг ашиглаж байгаа үед энэ нь зөвхөн байршилд хандах эрхтэй болно"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-д энэ төхөөрөмжийн байршилд &lt;b&gt;хүссэн үедээ&lt;/b&gt; хандахыг зөвшөөрөх үү?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Та зөвхөн тухайн аппыг ашиглаж байгаа үед энэ нь одоогоор байршилд хандах эрхтэй"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Хуанли"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"Хуанли руу хандах"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-д таны календарьт хандахыг зөвшөөрөх үү?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Блоклосон зүйлийг шалгахын тулд товшино уу."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Систем"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Тохиргоо"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Зогсолтын горим"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Андройд ТВ төхөөрөмж удахгүй унтрах тул асаалттай хэвээр байлгахын тулд дарна уу."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Төхөөрөмж удахгүй унтрах тул асаалттай хэвээр байлгахын тулд дарна уу."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Камер"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Микрофон"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"таны дэлгэцэд бусад аппын дээр харуулж байна"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Шууд хуваалцах боломжгүй"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Аппын жагсаалт"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Энэ апликейшнд бичих зөвшөөрөл олгогдоогүй ч энэ USB төхөөрөмжөөр дамжуулан аудио бичиж чадсан."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Нүүр"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Буцах"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Сүүлд хандсан аппууд"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Мэдэгдэл"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Шуурхай тохиргоо"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Тэжээлийн харилцах цонх"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Дэлгэц хуваахыг унтраах/асаах"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Дэлгэцийг түгжих"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Дэлгэцийн зураг дарах"</string>
 </resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index edc89a4..f4becc9 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला या डिव्हाइसचे स्थान अ‍ॅक्सेस करू द्यायचे?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"तुम्ही अ‍ॅप वापरत असताना अ‍ॅपला फक्त स्थानाचा अ‍ॅक्सेस असेल"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला &lt;b&gt;प्रत्येक वेळी&lt;/b&gt; या डिव्हाइसच्या स्थानाचा अ‍ॅक्सेस द्यायचा?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"अ‍ॅप सध्या फक्त तुम्ही अ‍ॅप वापरत असतानाच स्थान अ‍ॅक्सेस करू शकते"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"कॅलेंडर"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"आपल्या कॅलेंडरवर प्रवेश"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला तुमचे कॅलेंडर अ‍ॅक्सेस करू द्यायचे?"</string>
@@ -1340,9 +1341,9 @@
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"इतर अ‍ॅप्सवर दाखवा"</string>
-    <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> इतर ॲप्सवर प्रदर्शित करत आहे"</string>
-    <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> अन्‍य ॲप्सवर प्रदर्शित करत आहे"</string>
-    <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ने हे वैशिष्ट्य वापरू नये असे तुम्ही इच्छित असल्यास, सेटिंग्ज उघडण्यासाठी टॅप करा आणि ते बंद करा."</string>
+    <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"अन्‍य ॲप्सवर <xliff:g id="NAME">%s</xliff:g> दाखवत आहे"</string>
+    <string name="alert_windows_notification_title" msgid="3697657294867638947">"अन्‍य ॲप्सवर <xliff:g id="NAME">%s</xliff:g> दाखवत आहे"</string>
+    <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ने हे वैशिष्ट्य वापरू नये असे तुम्हाला वाटत असल्यास, टॅप करून सेटिंग्ज उघडा आणि ते बंद करा."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"बंद करा"</string>
     <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g> तपासत आहे…"</string>
     <string name="ext_media_checking_notification_message" msgid="410185170877285434">"सध्याच्या आशयाचे पुनरावलोकन करत आहे"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"काय ब्लॉक केले आहे हे तपासण्यासाठी टॅप करा."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"सिस्टम"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"सेटिंग्ज"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"स्टँडबाय"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV डिव्हाइस लवकरच बंद होणार आहे; सुरू ठेवण्यासाठी बटण दाबा."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"डिव्हाइस लवकरच बंद होणार आहे; सुरू ठेवण्यासाठी दाबा."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"कॅमेरा"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"मायक्रोफोन"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"तुमच्‍या स्‍क्रीनवर इतर ॲप्‍सवर डिस्‍प्‍ले करत आहे"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"थेट शेअर करणे उपलब्ध नाही"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"अ‍ॅप्स सूची"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"या अ‍ॅपला रेकॉर्ड करण्याची परवानगी दिली गेली नाही पण हे USB डिव्हाइस वापरून ऑडिओ कॅप्चर केला जाऊ शकतो."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"होम"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"मागे जा"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"अलीकडील ॲप्स"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"सूचना"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"क्विक सेटिंग्ज"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"पॉवर डायलॉग"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"विभाजित स्क्रीन टॉगल करा"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"स्‍क्रीन लॉक करा"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"स्क्रीनशॉट"</string>
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 0c881c5..5caf29f 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Benarkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses lokasi peranti ini?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Apl ini hanya dapat mengakses lokasi semasa anda menggunakan apl tersebut"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Benarkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses lokasi peranti ini &lt;b&gt;pada sepanjang masa&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Pada masa ini, apl hanya boleh mengakses lokasi semasa anda menggunakan apl itu"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"mengakses kalendar"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Benarkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses kalendar anda?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Ketik untuk menyemak item yang disekat."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Tetapan"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Tunggu sedia"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Peranti Android TV akan mati tidak lama lagi; tekan butang untuk memastikan peranti terus hidup."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Peranti akan mati tidak lama lagi; tekan untuk memastikan peranti terus hidup."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"dipaparkan di atas apl lain pada skrin anda"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Perkongsian langsung tidak tersedia"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Senarai apl"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Apl ini belum diberikan kebenaran merakam tetapi dapat merakam audio melalui peranti USB ini."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Skrin Utama"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Kembali"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Apl Terbaharu"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Pemberitahuan"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Tetapan Pantas"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Dialog Kuasa"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Togol Skrin Pisah"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Skrin Kunci"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Tangkapan skrin"</string>
 </resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index f5745b5..7ab0282 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား ဤစက်ပစ္စည်း၏တည်နေရာကို သုံးခွင့်ပေးလိုပါသလား။"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"အက်ပ်ကိုအသုံးပြုသည့် အချိန်တွင်သာ ၎င်းကတည်နေရာကို အသုံးပြုခွင့်ရပါမည်"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား ဤစက်ပစ္စည်း၏ တည်နေရာကို &lt;b&gt;အမြဲတမ်း&lt;/b&gt; ဝင်သုံးခွင့်ပေးလိုပါသလား။"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"အက်ပ်ကိုအသုံးပြုသည့် အချိန်တွင်သာ ၎င်းကတည်နေရာကို အသုံးပြုခွင့်ရပါသည်"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ပြက္ခဒိန်"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"သင့်ပြက္ခဒိန်အား ဝင်ရောက်သုံးရန်"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား သင်၏ပြက္ခဒိန်ကို သုံးခွင့်ပေးလိုပါသလား။"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"ပိတ်ထားသည့်အရာများကို ကြည့်ရန် တို့ပါ။"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"စနစ်"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"ဆက်တင်များ"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"အသင့်အနေအထား"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV စက်သည် မကြာမီ ပိတ်သွားပါမည်၊ ဆက်ဖွင့်ထားရန် ခလုတ်တစ်ခုနှိပ်ပါ။"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"စက်သည် အကြာမီ ပိတ်သွားပါမည်၊ ဆက်ဖွင့်ထားပါ။"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"ကင်မရာ"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"မိုက်ခရိုဖုန်း"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"သင့်မျက်နှာပြင်ပေါ်ရှိ အခြားအက်ပ်များပေါ်တွင် ပြသခြင်း"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"တိုက်ရိုက်မျှဝေ၍ မရပါ"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"အက်ပ်စာရင်း"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"ဤအက်ပ်ကို အသံဖမ်းခွင့် ပေးမထားသော်လည်း ၎င်းသည် ဤ USB စက်ပစ္စည်းမှတစ်ဆင့် အသံများကို ဖမ်းယူနိုင်ပါသည်။"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"ပင်မစာမျက်နှာ"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"နောက်သို့"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"လတ်တလောသုံး အက်ပ်များ"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"အကြောင်းကြားချက်များ"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"အမြန် ဆက်တင်များ"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"ပါဝါ ဒိုင်ယာလော့"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းကို နှိပ်ပါ"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"လော့ခ်မျက်နှာပြင်"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 0359779..aecbea6 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Vil du gi &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tilgang til denne enhetens posisjon?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Appen får bare tilgang til posisjonen når du bruker appen"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Vil du gi &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tilgang til enhetens posisjon &lt;b&gt;til enhver tid&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Appen har nå bare tilgang til posisjonen når du bruker den"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"åpne kalenderen din"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Vil du gi &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tilgang til kalenderen din?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Trykk for å sjekke hva som er blokkert."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"System"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Innstillinger"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Ventemodus"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV-enheten slås snart av. Trykk på en knapp for å holde den på."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Enheten slås snart av. Trykk for å holde den på."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"vises over andre apper på skjermen"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Direktedeling er ikke tilgjengelig"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Appliste"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Denne appen har ikke fått tillatelse til å spille inn, men kan ta opp lyd med denne USB-enheten."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Start"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Tilbake"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Nylige apper"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Varsler"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Hurtiginnstillinger"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Dialogboks for å slå av/på"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Slå delt skjerm av/på"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Låseskjerm"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Skjermdump"</string>
 </resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 2617086..a6f37dd 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; लाई यो यन्त्रको स्थानमाथि पहुँच राख्न दिने हो?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"तपाईंले अनुप्रयोग प्रयोग गरिरहेका बेला मात्र उक्त अनुप्रयोगले स्थानमाथि पहुँच राख्न सक्ने छ"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; लाई यस यन्त्रको स्थानमाथि &lt;b&gt;जुनसुकै बेला&lt;/b&gt; पहुँच गर्न दिने हो?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"तपाईंले अनुप्रयोग प्रयोग गरिरहँदा मात्र उक्त अनुप्रयोगले हाल स्थानमाथि मात्र पहुँच गर्न सक्छ"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"पात्रो"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"तपाईंको पात्रोमाथि पहुँच गर्नुहोस्"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; लाई आफ्नो पात्रोमाथि पहुँच राख्न दिने हो?"</string>
@@ -1777,10 +1778,8 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"तपाईंका प्रशासकले अद्यावधिक गर्नुभएको"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"तपाईंका प्रशासकले मेट्नुभएको"</string>
     <string name="confirm_battery_saver" msgid="639106420541753635">"ठिक छ"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (1002571337088673987) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (2307555792915978653) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="1002571337088673987">"ब्याट्रीको आयु लामो बनाउन ब्याट्री सेभरले:\n·अँध्यारो विषयवस्तु सक्रिय गर्छ\n·पृष्ठभूमिका गतिविधि, कतिपय भिजुअल प्रभाव तथा “Hey Google” जस्ता अन्य सुविधाहरू निष्क्रिय वा सीमित पार्छ।\n\n"<annotation id="url">"थप जान्नुहोस्"</annotation></string>
+    <string name="battery_saver_description" msgid="2307555792915978653">"ब्याट्रीको आयु लामो बनाउन ब्याट्री सेभरले:\n·अँध्यारो विषयवस्तु सक्रिय गर्छ\n·पृष्ठभूमिका गतिविधि, कतिपय भिजुअल प्रभाव तथा “Hey Google” जस्ता अन्य सुविधाहरू निष्क्रिय वा सीमित पार्छ।"</string>
     <string name="data_saver_description" msgid="6015391409098303235">"डेटाको प्रयोगलाई कम गर्नमा मद्दतका लागि डेटा सर्भरले केही अनुप्रयोगहरूलाई पृष्ठभूमिमा डेटा पठाउन वा प्राप्त गर्नबाट रोक्दछ। तपाईँले हाल प्रयोग गरिरहनुभएको अनु्प्रयोगले डेटामाथि पहुँच राख्न सक्छ, तर त्यसले यो काम थोरै पटक गर्न सक्छ। उदाहरणका लागि यसको मतलब यो हुन सक्छ: तपाईँले छविहरूलाई ट्याप नगरेसम्म ती प्रदर्शन हुँदैनन्।"</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"डेटा सेभरलाई सक्रिय गर्ने हो?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"सक्रिय गर्नुहोस्"</string>
@@ -1971,9 +1970,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"रोक लगाइएका कुराहरू जाँच गर्न ट्याप गर्नुहोस्‌।"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"प्रणाली"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"सेटिङहरू"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"स्ट्यान्डबाई"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV यन्त्र चाँडै निष्क्रिय हुने छ; सक्रिय राख्न कुनै बटन थिच्नुहोस्।"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"यो यन्त्र चाँडै निष्क्रिय हुने छ; सक्रिय राख्न थिच्नुहोस्।"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"क्यामेरा"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"माइक्रोफोन"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"तपाईंको स्क्रिनका अन्य अनुप्रयोगहरूमा प्रदर्शन गरिँदै छ"</string>
@@ -2014,22 +2010,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"सीधै आदान प्रदान गर्ने सुविधा उपलब्ध छैन"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"अनुप्रयोगहरूको सूची"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"यो अनुप्रयोगलाई रेकर्ड गर्ने अनुमति प्रदान गरिएको छैन तर यसले यो USB यन्त्रमार्फत अडियो क्याप्चर गर्न सक्छ।"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"गृहपृष्ठ"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"पछाडि फर्कनुहोस्"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"हालसालैका अनुप्रयोगहरू"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"सूचनाहरू"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"द्रुत सेटिङहरू"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"पावर संवाद"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"विभाजित स्क्रिन टगल गर्नुहोस्"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"लक स्क्रिन"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"स्क्रिनसट"</string>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 43b4ede..684ea94 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toegang geven tot de locatie van dit apparaat?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"De app heeft alleen toegang tot de locatie wanneer je de app gebruikt"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Wil je &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; &lt;b&gt;altijd&lt;/b&gt; toegang geven tot de locatie van dit apparaat?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"De app heeft momenteel alleen toegang tot de locatie wanneer je de app gebruikt"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"Deze app wil mogelijk altijd toegang tot je locatie, ook als je de app niet gebruikt. Je kunt dit toestaan via de "<annotation id="link">"instellingen"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"toegang krijgen tot je agenda"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toegang geven tot je agenda?"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Tik om te controleren wat er is geblokkeerd."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Systeem"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Instellingen"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Stand-by"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Het Android TV-apparaat wordt binnenkort uitgeschakeld. Druk op een knop om het ingeschakeld te houden."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Het apparaat wordt binnenkort uitgeschakeld. Druk om het ingeschakeld te houden."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Camera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Microfoon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"wordt weergegeven vóór andere apps op je scherm"</string>
@@ -2006,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Rechtstreeks delen is niet beschikbaar"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Lijst met apps"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Deze app heeft geen opnamerechten gekregen, maar zou audio kunnen vastleggen via dit USB-apparaat."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Homepage"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Terug"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Recente apps"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Meldingen"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Snelle instellingen"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Voedingsdialoogvenster"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Gesplitst scherm schakelen"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Scherm vergrendelen"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Screenshot"</string>
 </resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 68b76c8..6c53e16 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;କୁ ଏହି ଡିଭାଇସ୍‌ର ଲୋକେସନ୍‍ ଆକ୍ସେସ୍‍ କରିବା ପାଇଁ ଅନୁମତି ଦେବେ କି?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"ଆପଣ ଆପ୍ ବ୍ୟବହାର କରୁଥିବା ବେଳେ କେବଳ ଲୋକେସନ୍‍କୁ ଆପ୍‍ର ଆକ୍ସେସ୍‍ ରହିବ।"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;କୁ ଏହି ଡିଭାଇସ୍‌ର ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରିବାକୁ &lt;b&gt;ସର୍ବଦା&lt;/b&gt; ଅନୁମତି ଦେବେ କି?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"ବର୍ତ୍ତମାନ ଆପଣ କେବଳ ଆପ୍‍ ବ୍ୟବହାର କରୁଥିବା ବେଳେ ଆପ୍ ଆପଣଙ୍କ ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରିପାରିବ"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"କ୍ୟାଲେଣ୍ଡର୍"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର୍‍ ଆକ୍ସେସ୍‍ କରେ"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;କୁ ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର୍‌କୁ ଆକ୍ସେସ୍‍ କରିବା ପାଇଁ ଅନୁମତି ଦେବେ କି?"</string>
@@ -1771,10 +1772,8 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"ଆପଣଙ୍କ ଆଡମିନ୍‌‌ ଅପଡେଟ୍‍ କରିଛନ୍ତି"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"ଆପଣଙ୍କ ଆଡମିନ୍‌‌ ଡିଲିଟ୍‍ କରିଛନ୍ତି"</string>
     <string name="confirm_battery_saver" msgid="639106420541753635">"ଠିକ୍ ଅଛି"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (1002571337088673987) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (2307555792915978653) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="1002571337088673987">"ବ୍ୟାଟେରୀ ଜୀବନ ବଢ଼ାଇବାକୁ ବ୍ୟାଟେରୀ ସେଭର୍:\n·ଗାଢା ଥିମ୍‌ ଚାଲୁ କରେ\n·ପୃଷ୍ଟପଟ କାର୍ଯ୍ୟକଳାପକୁ, କିଛି ଭିଜୁଆଲ୍ ପ୍ରଭାବଗୁଡ଼ିକୁ ଏବଂ “ହେ Google” ପରି ଅନ୍ୟ ଫିଚର୍‌କୁ ବନ୍ଦ ରଖେ କିମ୍ବା ପ୍ରତିବନ୍ଧିତ କରିଥାଏ\n\n"<annotation id="url">"ଅଧିକ ଜାଣନ୍ତୁ"</annotation></string>
+    <string name="battery_saver_description" msgid="2307555792915978653">"ବ୍ୟାଟେରୀ ଜୀବନ ବଢ଼ାଇବାକୁ ବ୍ୟାଟେରୀ ସେଭର୍:\n·ଗାଢା ଥିମ୍‌ ଚାଲୁ କରେ\n·ପୃଷ୍ଟପଟ କାର୍ଯ୍ୟକଳାପକୁ, କିଛି ଭିଜୁଆଲ୍ ପ୍ରଭାବଗୁଡ଼ିକୁ ଏବଂ “ହେ Google” ପରି ଅନ୍ୟ ଫିଚର୍‌କୁ ବନ୍ଦ ରଖେ କିମ୍ବା ପ୍ରତିବନ୍ଧିତ କରିଥାଏ"</string>
     <string name="data_saver_description" msgid="6015391409098303235">"ଡାଟା ବ୍ୟବହାର କମ୍‍ କରିବାରେ ସାହାଯ୍ୟ କରିବାକୁ, ଡାଟା ସେଭର୍‍ ବ୍ୟାକ୍‌ଗ୍ରାଉଣ୍ଡରେ ଡାଟା ପଠାଇବା କିମ୍ବା ପ୍ରାପ୍ତ କରିବାକୁ କିଛି ଆପ୍‍କୁ ବାରଣ କରେ। ଆପଣ ବର୍ତ୍ତମାନ ବ୍ୟବହାର କରୁଥିବା ଆପ୍‍, ଡାଟା ଆକ୍ସେସ୍‍ କରିପାରେ, କିନ୍ତୁ ଏହା କମ୍‍ ଥର କରିପାରେ। ଏହାର ଅର୍ଥ ହୋଇପାରେ, ଯେପରି, ଆପଣ ଟାପ୍‍ ନକରିବା ପର୍ଯ୍ୟନ୍ତ ଯେଉଁ ଇମେଜ୍‍ ଦେଖାଯାଏ ନାହିଁ।"</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"ଡାଟା ସେଭର୍‌ ଅନ୍ କରିବେ?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"ଅନ୍ କରନ୍ତୁ"</string>
@@ -1965,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"କ’ଣ ଅବରୋଧ ହୋଇଛି ଯାଞ୍ଚ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"ସିଷ୍ଟମ୍‌"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"ସେଟିଙ୍ଗ"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"ଷ୍ଟାଣ୍ଡବାଏ"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android ଟିଭି ଡିଭାଇସ୍ ଶୀଘ୍ର ବନ୍ଦ ହୋଇଯିବ; ଏହା ଚାଲୁ ରଖିବା ପାଇଁ ଏକ ବଟନ୍ ଦବାନ୍ତୁ।"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"ଡିଭାଇସ୍ ଶୀଘ୍ର ବନ୍ଦ ହୋଇଯିବ; ଚାଲୁ ରଖିବା ପାଇଁ ଦବାନ୍ତୁ।"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"କ୍ୟାମେରା"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"ମାଇକ୍ରୋଫୋନ୍"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"ଆପଣଙ୍କ ସ୍କ୍ରୀନ୍ ଉପରେ ଥିବା ଅନ୍ୟ ଆପ୍‌ ଉପରେ ଦେଖାଦେବ"</string>
@@ -2008,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"ସିଧାସଳଖ ସେୟାର୍ ସୁବିଧା ଉପଲବ୍ଧ ନାହିଁ"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"ଆପ୍ସ ତାଲିକା"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"ଏହି ଆପ୍‌କୁ ରେକର୍ଡ କରିବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ କିନ୍ତୁ ଏହି USB ଡିଭାଇସ୍ ଜରିଆରେ ଅଡିଓ କ୍ୟାପ୍‍ଚର୍‍ କରିପାରିବ।"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"ମୂଳପୃଷ୍ଠା"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"ପଛକୁ ଫେରନ୍ତୁ"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"ବର୍ତ୍ତମାନର ଆପ୍‌ଗୁଡ଼ିକ"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଖୋଲନ୍ତୁ"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"କ୍ୱିକ୍ ସେଟିଂସ୍ ଖୋଲନ୍ତୁ"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"ପାୱାର ଡାୟଲଗ୍ ଖୋଲନ୍ତୁ"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"ଦୁଇଟି ସ୍କ୍ରିନ୍ ମଧ୍ୟରେ ଟୋଗଲ୍ କରନ୍ତୁ"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"ସ୍କ୍ରିନ୍ ଲକ୍ କରନ୍ତୁ"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"ସ୍କ୍ରି‍ନ୍‍ସଟ୍ ନିଅନ୍ତୁ"</string>
 </resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 63b5f53..0f27133 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"ਕੀ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਇਸ ਡੀਵਾਈਸ ਦੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਐਪ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਹੀ ਐਪ ਕੋਲ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਹੋਵੇਗੀ"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"ਕੀ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਹਰ ਵੇਲੇ &lt;b&gt;ਇਸ ਡੀਵਾਈਸ ਦੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਐਪ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਹੀ ਐਪ ਹੁਣ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕੇਗੀ"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ਕੈਲੰਡਰ"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"ਕੀ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨੀ ਦੇਣੀ ਹੈ?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"ਟੈਪ ਕਰਕੇ ਦੋਖੋ ਕਿ ਕਿਹੜੀਆਂ ਚੀਜ਼ਾਂ ਬਲਾਕ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ।"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"ਸਿਸਟਮ"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"ਸੈਟਿੰਗਾਂ"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"ਸਟੈਂਡਬਾਈ"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV ਡੀਵਾਈਸ ਜਲਦ ਹੀ ਬੰਦ ਹੋ ਜਾਵੇਗਾ; ਇਸਨੂੰ ਚਾਲੂ ਰੱਖਣ ਲਈ ਕੋਈ ਬਟਨ ਦਬਾਓ।"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"ਡੀਵਾਈਸ ਜਲਦ ਹੀ ਬੰਦ ਹੋ ਜਾਵੇਗਾ, ਇਸਨੂੰ ਚਾਲੂ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"ਕੈਮਰਾ"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਹੋਰਾਂ ਐਪਾਂ ਉੱਪਰ ਦਿਖਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"ਸਿੱਧਾ ਸਾਂਝਾ ਕਰਨ ਦੀ ਸੁਵਿਧਾ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"ਐਪ ਸੂਚੀ"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"ਇਸ ਐਪ ਨੂੰ ਰਿਕਾਰਡ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਪਰ ਇਹ USB ਡੀਵਾਈਸ ਰਾਹੀਂ ਆਡੀਓ ਕੈਪਚਰ ਕਰ ਸਕਦੀ ਹੈ।"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"ਹੋਮ"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"ਪਿੱਛੇ"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"ਹਾਲੀਆ ਐਪਾਂ"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"ਸੂਚਨਾਵਾਂ"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"ਪਾਵਰ ਵਿੰਡੋ"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਨੂੰ ਟੌਗਲ ਕਰੋ"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"ਲਾਕ ਸਕ੍ਰੀਨ"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index bd695a9..38b982a 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -292,7 +292,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Zezwolić aplikacji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na dostęp do lokalizacji urządzenia?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Aplikacja będzie mieć dostęp do lokalizacji tylko wtedy, gdy będzie używana"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Zezwolić aplikacji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na &lt;b&gt;ciągły&lt;/b&gt; dostęp do lokalizacji tego urządzenia?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Aplikacja obecnie ma dostęp do lokalizacji tylko wtedy, gdy jest używana"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"Aplikacja chce mieć stały dostęp do Twojej lokalizacji, nawet gdy nie jest używana. Zezwól w "<annotation id="link">"ustawieniach"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendarz"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"dostęp do kalendarza"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Zezwolić aplikacji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na dostęp do kalendarza?"</string>
@@ -566,7 +566,7 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Zezwala na aktywowanie przez aplikację metody dodawania i usuwania szablonów twarzy."</string>
     <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"używanie sprzętu do rozpoznawania twarzy"</string>
     <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Zezwala na używanie przez aplikację sprzętu do rozpoznawania twarzy w uwierzytelniania"</string>
-    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Rozpoznanie twarzy"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Rozpoznawanie twarzy"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Zarejestruj swoją twarz ponownie"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Aby poprawić rozpoznawanie, ponownie zarejestruj swoją twarz"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Nie udało się zarejestrować danych twarzy. Spróbuj ponownie."</string>
@@ -595,12 +595,12 @@
     <string name="face_error_timeout" msgid="981512090365729465">"Spróbuj rozpoznania twarzy ponownie."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Nie można przechowywać nowych danych twarzy. Usuń stare."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Analiza twarzy została anulowana."</string>
-    <string name="face_error_user_canceled" msgid="5317030072349668946">"Użytkownik anulował rozpoznanie twarzy."</string>
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Użytkownik anulował rozpoznawanie twarzy."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Zbyt wiele prób. Spróbuj ponownie później."</string>
-    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Zbyt wiele prób. Rozpoznanie twarzy zostało wyłączone."</string>
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Zbyt wiele prób. Rozpoznawanie twarzy zostało wyłączone."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Nie można zweryfikować twarzy. Spróbuj ponownie."</string>
-    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Rozpoznanie twarzy nie jest skonfigurowane."</string>
-    <string name="face_error_hw_not_present" msgid="8302690289757559738">"To urządzenie nie obsługuje rozpoznania twarzy."</string>
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Rozpoznawanie twarzy nie jest skonfigurowane."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"To urządzenie nie obsługuje rozpoznawania twarzy."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Twarz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -899,7 +899,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Rozwiń obszar odblokowania."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Odblokowanie przesunięciem."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Odblokowanie wzorem."</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Rozpoznanie twarzy"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Rozpoznawanie twarzy"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Odblokowanie kodem PIN."</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"Odblokowanie kodu PIN karty SIM."</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"Odblokowanie kodu PUK karty SIM."</string>
@@ -932,7 +932,7 @@
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
     <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
-    <string name="autofill_province" msgid="2231806553863422300">"Województwo"</string>
+    <string name="autofill_province" msgid="2231806553863422300">"Region"</string>
     <string name="autofill_postal_code" msgid="4696430407689377108">"Kod pocztowy"</string>
     <string name="autofill_state" msgid="6988894195520044613">"Stan"</string>
     <string name="autofill_zip_code" msgid="8697544592627322946">"Kod pocztowy"</string>
@@ -2029,9 +2029,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Kliknij, by sprawdzić, co jest zablokowane."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"System"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Ustawienia"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Tryb gotowości"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Urządzenie z Androidem TV za chwilę się wyłączy. Naciśnij przycisk, by pozostało włączone."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Urządzenie za chwilę się wyłączy. Naciśnij, by pozostało włączone."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Aparat"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"wyświetla się nad innymi aplikacjami na ekranie"</string>
@@ -2074,22 +2071,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Udostępnianie bezpośrednie jest niedostępne"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Lista aplikacji"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Ta aplikacja nie ma uprawnień do nagrywania, ale może rejestrować dźwięk za pomocą tego urządzenia USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Ekran główny"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Wstecz"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Ostatnie aplikacje"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Powiadomienia"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Szybkie ustawienia"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Okno opcji zasilania"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Przełącz podzielony ekran"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Ekran blokady"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Zrzut ekranu"</string>
 </resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 45a2abd2..4d68520 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Permitir que o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse o local deste dispositivo?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"O app só terá acesso ao local enquanto estiver sendo usado"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Permitir que o &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse o local do dispositivo &lt;b&gt;o tempo todo&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"No momento, o app só pode acessar o local enquanto estiver sendo usado"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acesse sua agenda"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse sua agenda?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Toque para verificar o que está bloqueado."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Configurações"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Espera"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"O dispositivo Android TV entrará no modo de espera em breve. Pressione um botão para mantê-lo ativado."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"O dispositivo entrará no modo de espera em breve. Pressione para mantê-lo ativado."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Câmera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Microfone"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"exibindo sobre outros apps na sua tela"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Compartilhamento direto indisponível"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Lista de apps"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Este app não tem permissão de gravação, mas pode capturar áudio pelo dispositivo USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Início"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Voltar"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Apps recentes"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notificações"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Configurações rápidas"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Caixa de diálogo de liga/desliga"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Ativar tela dividida"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Bloquear tela"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Capturar tela"</string>
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 0fd303f..42aa191 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Pretende permitir que a aplicação &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aceda à localização deste dispositivo?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"A aplicação tem acesso à localização apenas enquanto a estiver a utilizar"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Pretende permitir que a aplicação &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aceda &lt;b&gt;sempre&lt;/b&gt; à localização deste dispositivo?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Atualmente, a aplicação pode aceder à localização apenas enquanto estiver a ser utilizada"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendário"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"aceder ao calendário"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Pretende permitir que a aplicação &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aceda ao calendário?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Toque para verificar o que está bloqueado."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Definições"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Modo de espera"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"O dispositivo Android TV irá desligar-se brevemente. Prima um botão para o manter ligado."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"O dispositivo irá desligar-se brevemente. Prima para o manter ligado."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Câmara"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Microfone"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"sobrepõe-se a outras aplicações no ecrã"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"A partilha direta não está disponível."</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Lista de aplicações"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Esta aplicação não recebeu autorização de gravação, mas pode capturar áudio através deste dispositivo USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Página inicial"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Anterior"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Aplicações recentes"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notificações"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Definições rápidas"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Caixa de diálogo de energia"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Ativar/desativar o ecrã dividido"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Ecrã de bloqueio"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Captura de ecrã"</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 45a2abd2..4d68520 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Permitir que o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse o local deste dispositivo?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"O app só terá acesso ao local enquanto estiver sendo usado"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Permitir que o &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse o local do dispositivo &lt;b&gt;o tempo todo&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"No momento, o app só pode acessar o local enquanto estiver sendo usado"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acesse sua agenda"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse sua agenda?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Toque para verificar o que está bloqueado."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Configurações"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Espera"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"O dispositivo Android TV entrará no modo de espera em breve. Pressione um botão para mantê-lo ativado."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"O dispositivo entrará no modo de espera em breve. Pressione para mantê-lo ativado."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Câmera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Microfone"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"exibindo sobre outros apps na sua tela"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Compartilhamento direto indisponível"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Lista de apps"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Este app não tem permissão de gravação, mas pode capturar áudio pelo dispositivo USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Início"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Voltar"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Apps recentes"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notificações"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Configurações rápidas"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Caixa de diálogo de liga/desliga"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Ativar tela dividida"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Bloquear tela"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Capturar tela"</string>
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index a878628..8fc87d8 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -289,7 +289,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Permiteți &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să acceseze locația acestui dispozitiv?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Aplicația va avea acces la locație doar atunci când o folosiți"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Permiteți aplicației &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să acceseze locația dispozitivului &lt;b&gt;tot timpul&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Aplicația poate accesa locația numai când folosiți aplicația"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"Este posibil ca aplicația să dorească să vă acceseze în permanență locația, chiar și când nu o folosiți. Acordați această permisiune din "<annotation id="link">"setări"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceseze calendarul"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Permiteți &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să vă acceseze calendarul?"</string>
@@ -1996,9 +1996,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Atingeți pentru a verifica ce este blocat."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Setări"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Standby"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Dispozitivul Android TV se va opri în curând. Apăsați un buton pentru a-l menține pornit."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Dispozitivul se va opri în curând. Apăsați pentru a-l menține pornit."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Cameră foto"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Microfon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"se afișează peste alte aplicații de pe ecran"</string>
@@ -2040,22 +2037,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Trimiterea directă nu este disponibilă"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Lista de aplicații"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Permisiunea de înregistrare nu a fost acordată aplicației, dar aceasta poate să înregistreze conținut audio prin intermediul acestui dispozitiv USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Pornire"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Înapoi"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Aplicații recente"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Notificări"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Setări rapide"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Power Dialog"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Activați ecranul împărțit"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Ecran de blocare"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Captură de ecran"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index aa94aa6..ce206d0 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -292,7 +292,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Разрешить приложению &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ к данным о местоположении устройства?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Доступ к местоположению будет открыт, только пока вы пользуетесь приложением."</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Разрешить приложению \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" постоянный доступ к местоположению устройства?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Сейчас у приложения есть доступ к местоположению только во время его использования."</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Календарь"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"доступ к календарю"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Разрешить приложению &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ к календарю?"</string>
@@ -2029,9 +2030,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Нажмите, чтобы проверить настройки."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Система"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Настройки"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Переход в режим ожидания"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Устройство Android TV скоро выключится. Чтобы этого не произошло, нажмите любую кнопку."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Устройство скоро выключится. Чтобы этого не произошло, нажмите любую кнопку или коснитесь экрана."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Камера"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Микрофон"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"показ поверх других окон"</string>
@@ -2074,22 +2072,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Функция Direct Share недоступна."</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Список приложений"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Приложению не разрешено записывать звук, однако оно может делать это с помощью этого USB-устройства."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Главный экран"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Назад"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Недавние приложения"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Уведомления"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Быстрые настройки"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Диалоговое окно питания"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Включить или выключить разделение экрана"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Заблокированный экран"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Скриншот"</string>
 </resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index ee261a54..d48d78e 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;b&gt; වෙත මෙම උපාංගයේ ස්ථානය ලබා ගැනීමට ඉඩ දෙන්නද?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"ඔබ යෙදුම භාවිත කරන විට පමණක් යෙදුමට ස්ථානය වෙත ප්‍රවේශය ඇත"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; හට ඔබේ උපාංයේ ස්ථානය වෙත &lt;b&gt;සැම විටම&lt;/b&gt; ප්‍රවේශ වීමට ඉඩ දෙන්නේද?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"යෙදුමට දැනට ඔබ යෙදුම භාවිත කරන විට පමණක් ස්ථානය වෙත ප්‍රවේශ විය හැක"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"දින දර්ශනය"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ඔබේ දින දර්ශනයට පිවිසෙන්න"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;b&gt; වෙත ඔබගේ දින දර්ශනය ප්‍රවේශ කිරීමට ඉඩ දෙන්නද?"</string>
@@ -1965,9 +1966,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"අවහිර කර ඇති දේ පරීක්ෂා කිරීමට තට්ටු කරන්න."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"පද්ධතිය"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"සැකසීම්"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"පොරොත්තු"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV උපාංගය ඉක්මනින් ක්‍රියා විරහිත වනු ඇත; එය දිගටම ක්‍රියාත්මක කර තැබීමට බොත්තමක් ඔබන්න."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"උපාංගය ඉක්මනින් ක්‍රියා විරහිත වනු ඇත; එය දිගටම ක්‍රියාත්මක කර තැබීමට ඔබන්න."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"කැමරාව"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"මයික්‍රෆෝනය"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"ඔබගේ තිරය මත වෙනත් යෙදුම්වලට උඩින් සංදර්ශනය කරමින්"</string>
@@ -2008,22 +2006,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"ඍජු බෙදා ගැනීම නොලැබේ"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"යෙදුම් ලැයිස්තුව"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"මෙම යෙදුමට පටිගත කිරීම් අවසරයක් ලබා දී නොමැති නමුත් මෙම USB උපාංගය හරහා ශ්‍රව්‍ය ග්‍රහණය කර ගත හැකිය."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"මුල් පිටුව"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"ආපසු"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"මෑත යෙදුම්"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"දැනුම්දීම්"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"ඉක්මන් සැකසීම්"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"බල සංවාදය"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"බෙදුම් තිරය ටොගල කරන්න"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"අගුලු තිරය"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"තිර රුව"</string>
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index ed4f68c..7123dba 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -292,7 +292,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; prístup k polohe tohto zariadenia?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Aplikácia bude mať prístup k polohe iba vtedy, keď ju budete používať"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Chcete povoliť aplikácii <xliff:g id="APP_NAME">%1$s</xliff:g> prístup k polohe tohto zariadenia po celý čas?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Aplikácia má momentálne prístup k polohe iba vtedy, keď ju budete používať"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendár"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"prístup ku kalendáru"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; prístup ku kalendáru?"</string>
@@ -2029,9 +2030,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Klepnutím skontrolujete, čo je blokované."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Systém"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Nastavenia"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Pohotovostný režim"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Zariadenie Android TV sa čoskoro vypne. Ak ho chcete ponechať zapnuté, stlačte ľubovoľné tlačidlo."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Zariadenie sa čoskoro vypne. Ak ho chcete ponechať zapnuté, stlačte ľubovoľné tlačidlo."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Fotoaparát"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofón"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"sa zobrazuje cez ďalšie aplikácie na obrazovke"</string>
@@ -2074,22 +2072,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Priame zdieľanie nie je k dispozícii"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Zoznam aplikácií"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Tejto aplikácii nebolo udelené povolenie na nahrávanie, ale môže nasnímať zvuk cez toto zariadenie USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Domov"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Späť"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Nedávne aplikácie"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Upozornenia"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Rýchle nastavenia"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Dialógové okno napájania"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Prepnúť rozdelenú obrazovku"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Uzamknúť obrazovku"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Snímka obrazovky"</string>
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index dc162a8..852073e 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -292,7 +292,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Dovolite aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; dostop do lokacije te naprave?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Aplikacija bo imela dostop do lokacije samo, ko aplikacijo uporabljate"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Dovolite aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;, da &lt;b&gt;ves čas&lt;/b&gt; dostopa do lokacije te naprave?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Trenutno lahko aplikacija dostopa do lokacije samo, ko aplikacijo uporabljate"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"Ta aplikacija bo morda želela imeti stalen dostop do vaše lokacije, tudi ko aplikacije ne boste uporabljali. Omogočite v "<annotation id="link">"nastavitvah"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Koledar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"dostop do koledarja"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Dovolite aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; dostop do koledarja?"</string>
@@ -2029,9 +2029,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Dotaknite se, da preverite, kaj je blokirano."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Nastavitve"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Stanje pripravljenosti"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Naprava Android TV se bo kmalu izklopila. Če tega ne želite, pritisnite poljuben gumb."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Naprava se bo kmalu izklopila. Če tega ne želite, pritisnite."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Fotoaparat"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"prekriva druge aplikacije na zaslonu"</string>
@@ -2074,22 +2071,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Neposredna skupna raba ni na voljo"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Seznam aplikacij"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Ta aplikacija sicer nima dovoljenja za snemanje, vendar bi lahko zajemala zvok prek te naprave USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Začetni zaslon"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Nazaj"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Nedavne aplikacije"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Obvestila"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Hitre nastavitve"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Pogovorno okno o porabi energije"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Preklop razdeljenega zaslona"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Zaklenjen zaslon"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Posnetek zaslona"</string>
 </resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 4973f9f..26b5932 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Të lejohet që &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; të ketë qasje te vendndodhja e kësaj pajisjeje?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Aplikacioni do të ketë qasje te vendndodhja vetëm kur po e përdor aplikacionin"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Të lejohet që &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; të qaset te vendndodhja e kësaj pajisjeje &lt;b&gt;gjatë të gjithë kohës&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Aplikacioni aktualisht mund të qaset te vendndodhja vetëm kur ti e përdor aplikacionin"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendari"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"qasje te kalendari yt"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Të lejohet që &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; të ketë qasje te kalendari yt?"</string>
@@ -1771,10 +1772,8 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Përditësuar nga administratori"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Fshirë nga administratori"</string>
     <string name="confirm_battery_saver" msgid="639106420541753635">"Në rregull"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (1002571337088673987) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (2307555792915978653) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="1002571337088673987">"Për të rritur kohëzgjatjen e baterisë, \"Kursyesi i baterisë\":\n·Aktivizon \"Temën e errët\"\n·Çaktivizon ose kufizon aktivitetin në sfond, disa efekte vizuale dhe veçori të tjera si “Ok Google”\n\n"<annotation id="url">"Mëso më shumë"</annotation></string>
+    <string name="battery_saver_description" msgid="2307555792915978653">"Për të rritur kohëzgjatjen e baterisë, \"Kursyesi i baterisë\":\n·Aktivizon \"Temën e errët\"\n·Çaktivizon ose kufizon aktivitetin në sfond, disa efekte vizuale dhe veçori të tjera si “Ok Google”"</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Për të ndihmuar në reduktimin e përdorimit të të dhënave, \"Kursyesi i të dhënave\" pengon që disa aplikacione të dërgojnë apo të marrin të dhëna në sfond. Një aplikacion që po përdor aktualisht mund të ketë qasje te të dhënat, por këtë mund ta bëjë më rrallë. Kjo mund të nënkuptojë, për shembull, se imazhet nuk shfaqen kur troket mbi to."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Të aktivizohet \"Kursyesi i të dhënave\"?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Aktivizo"</string>
@@ -1965,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Trokit për të shënuar atë që është bllokuar"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistemi"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Cilësimet"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Në gatishmëri"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Pajisja Android TV së shpejti do të fiket. Shtyp një buton për ta mbajtur të ndezur."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Pajisja së shpejti do të fiket. Shtype për ta mbajtur të ndezur."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofoni"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"po shfaqet mbi aplikacionet e tjera në ekranin tënd"</string>
@@ -2008,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Ndarja e drejtpërdrejtë nuk ofrohet"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Lista e aplikacioneve"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Këtij aplikacioni nuk i është dhënë leje për regjistrim, por mund të regjistrojë audio përmes kësaj pajisjeje USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Ekrani bazë"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Prapa"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Aplikacionet e fundit"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Njoftimet"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Cilësimet e shpejta"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Dialogu i energjisë"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Kalo tek ekrani i ndarë"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Ekrani i kyçjes"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Pamja e ekranit"</string>
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 48658bb..f314601 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -289,7 +289,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Желите ли да омогућите да &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; приступа локацији овог уређаја?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Апликација ће имати приступ локацији само док користите апликацију"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Желите ли да дозволите да &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; приступа локацији уређаја &lt;b&gt;у било ком тренутку&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Апликација тренутно може да приступа локацији само када користите апликацију"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"Ова апликација можда жели да приступа локацији све време, чак и када не користите апликацију. Омогућите у "<annotation id="link">"подешавањима"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"приступи календару"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Желите ли да омогућите да &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; приступа календару?"</string>
@@ -1996,9 +1996,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Додирните да бисте проверили шта је блокирано."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Систем"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Подешавања"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Стање приправности"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV ће се ускоро искључити. Притисните дугме да би остао укључен."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Уређај ће се ускоро искључити. Притисните да би остао укључен."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Камера"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Микрофон"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"приказује се на екрану док користите друге апликације"</string>
@@ -2040,22 +2037,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Директно дељење није доступно"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Листа апликација"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Ова апликација нема дозволу за снимање, али би могла да снима звук помоћу овог USB уређаја."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Почетак"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Назад"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Недавне апликације"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Обавештења"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Брза подешавања"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Дијалог напајања"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Укључите/искључите подељени екран"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Закључани екран"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Снимак екрана"</string>
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 09a2513..d67ffa2 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Vill du ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; åtkomst till enhetens plats?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Appen får endast åtkomst till din plats när du använder den"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Vill du tillåta att &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; alltid får åtkomst till platsen för den här &lt;b&gt;enheten&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Appen har för närvarande endast åtkomst till din plats när du använder den"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"få tillgång till din kalender"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Vill du ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; åtkomst till din kalender?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Tryck om du vill se vad som blockeras."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"System"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Inställningar"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Viloläge"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV-enheten stängs snart av. Tryck på en knapp för att behålla den på."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Enheten stängs snart av. Tryck för att behålla den på."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"visar över andra appar på mobilen"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Dela direkt är inte tillgängligt"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Applista"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Appen har inte fått inspelningsbehörighet men kan spela in ljud via denna USB-enhet."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Startsida"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Tillbaka"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Senaste apparna"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Aviseringar"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Snabbinställningar"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Dialogruta för ström"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Aktivera och inaktivera delad skärm"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Låsskärm"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Skärmdump"</string>
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 483c39f..5713ef1 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Ungependa kuiruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; itambue mahali kifaa kilipo?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Programu itafikia data ya mahali ulipo unapoitumia tu"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Je, ungependa kuruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ifikie kifaa cha mahali &lt;b&gt;kila wakati&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Programu sasa inaweza kufikia data ya mahali wakati unapoitumia tu"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"Huenda programu hii ikataka kufikia maelezo ya mahali ulipo kila wakati, hata wakati huitumii. Iruhusu katika "<annotation id="link">"mipangilio"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalenda"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ifikie kalenda yako"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Ungependa kuiruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ifikie kalenda yako?"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Gusa ili uangalie kipengee ambacho kimezuiwa."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Mfumo"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Mipangilio"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Hali tuli"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Kifaa cha Android TV kitazima hivi karibuni; bonyeza kitufe ili kisizime."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Kifaa kitazima hivi karibuni; bonyeza ili kisizime."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Maikrofoni"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"inachomoza kwenye programu zingine katika skrini yako"</string>
@@ -2006,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Huwezi kushiriki moja kwa moja"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Orodha ya programu"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Programu hii haijapewa ruhusa ya kurekodi lakini inaweza kurekodi sauti kupitia kifaa hiki cha USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Mwanzo"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Rudi nyuma"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Programu za Hivi Karibuni"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Arifa"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Mipangilio ya Haraka"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Kidirisha cha Nishati"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Geuza Skrini Iliyogawanywa"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Skrini Iliyofungwa"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Picha ya skrini"</string>
 </resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 0c4e20e..cae06c3 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; இந்தச் சாதனத்தின் இருப்பிடத்தை அணுகுவதற்கு அனுமதிக்கவா?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"இந்த ஆப்ஸை நீங்கள் உபயோகிக்கும்போது மட்டுமே இருப்பிடத்தை அணுகும்"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ஆப்ஸிற்கு &lt;b&gt;எப்போதும்&lt;/b&gt; இந்தச் சாதனத்தின் இருப்பிட அணுகலை அனுமதிக்கவா?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"நீங்கள் ஆப்ஸை உபயோகிக்கும்போது மட்டுமே அது இருப்பிடத்தை அணுக முடியும்"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"கேலெண்டர்"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"கேலெண்டரை அணுகலாம்"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"கேலெண்டரை அணுகுவதற்கு &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ஆப்ஸை அனுமதிக்கவா?"</string>
@@ -1342,7 +1343,7 @@
     <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"பிற ஆப்ஸின் மேலே காட்டு"</string>
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> பிற ஆப்ஸின் மீது தோன்றுகிறது"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> பிற ஆப்ஸின் மீது தோன்றுகிறது"</string>
-    <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> இந்த அம்சத்தைப் பயன்படுத்த வேண்டாம் என நினைத்தால், அமைப்புகளைத் திறந்து அதை முடக்க, தட்டவும்."</string>
+    <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> இந்த அம்சத்தைப் பயன்படுத்த வேண்டாம் என நினைத்தால் இங்கு தட்டி அமைப்புகளைத் திறந்து இதை முடக்கவும்."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"ஆஃப் செய்"</string>
     <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g>ஐச் சரிபார்க்கிறது…"</string>
     <string name="ext_media_checking_notification_message" msgid="410185170877285434">"தற்போதைய உள்ளடக்கத்தை மதிப்பாய்வு செய்கிறது"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"எவற்றையெல்லாம் தடுக்கிறது என்பதைப் பார்க்க, தட்டவும்."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"சிஸ்டம்"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"அமைப்புகள்"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"இயக்க நேரம்"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV விரைவில் ஆஃப் ஆகலாம். இதைத் தொடர்ந்து ஆனில் வைக்க ஒரு பட்டனைத் தட்டவும்."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"இந்தச் சாதனம் விரைவில் ஆஃப் ஆகலாம். இதைத் தொடர்ந்து ஆனில் வைக்கத் தட்டவும்."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"கேமரா"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"மைக்ரோஃபோன்"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"உங்கள் திரையில் உள்ள பிற ஆப்ஸின் மேல் காட்டுகிறது"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"நேரடிப் பகிர்வு இல்லை"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"ஆப்ஸ் பட்டியல்"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"இந்த ஆப்ஸிற்கு ரெக்கார்டு செய்வதற்கான அனுமதி வழங்கப்படவில்லை, எனினும் இந்த USB சாதனம் மூலம் ஆடியோவைப் பதிவுசெய்ய முடியும்."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"முகப்பு"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"பின் செல்"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"சமீபத்திய ஆப்ஸ்"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"அறிவிப்புகள்"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"விரைவு அமைப்புகள்"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"பவர் உரையாடல்"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"திரைப் பிரிப்பை நிலைமாற்று"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"பூட்டுத் திரை"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"ஸ்கிரீன்ஷாட்"</string>
 </resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 1b3df6e..167cc9b 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"ఈ పరికరం యొక్క లొకేషన్‌ను యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను అనుమతించాలా?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"మీరు యాప్‌ను ఉపయోగిస్తున్నప్పుడు మాత్రమే స్థానానికి యాప్ యాక్సెస్ కలిగి ఉంటుంది"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"ఈ పరికరం యొక్క లొకేషన్‌ను &lt;b&gt;అన్ని సమయాలలో&lt;/b&gt; యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను అనుమతించాలా?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"యాప్ ప్రస్తుతం మీరు ఆ యాప్‌ను ఉపయోగిస్తున్నప్పుడు మాత్రమే స్థానాన్ని యాక్సెస్ చేయగలుగుతుంది"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"ఈ యాప్‌నకు మీ లొకేషన్ యాక్సెస్ అన్ని సమయాలలో, అంటే యాప్‌ను ఉపయోగించనప్పుడు కూడా, అవసరం ఉండవచ్చు. అనుమతిని ఇక్కడ ఇవ్వండి: "<annotation id="link">"సెట్టింగ్‌లు"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"క్యాలెండర్"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"మీ క్యాలెండర్‌ను యాక్సెస్ చేయడానికి"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"మీ క్యాలెండర్‌ని యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ని అనుమతించాలా?"</string>
@@ -1340,9 +1340,9 @@
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"ఇతర యాప్‌ల ఎగువన ప్రదర్శన"</string>
-    <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> ఇతర అనువర్తనాలలో చూపబడుతోంది"</string>
-    <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ఇతర అనువర్తనాలలో చూపబడుతోంది"</string>
-    <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ఈ లక్షణాన్ని ఉపయోగించకూడదు అని మీరు అనుకుంటే, సెట్టింగ్‌లను తెరవడానికి నొక్కి, దీన్ని ఆఫ్ చేయండి."</string>
+    <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> ఇతర యాప్‌లలో చూపబడుతోంది"</string>
+    <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ఇతర యాప్‌లలో చూపబడుతోంది"</string>
+    <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ఈ లక్షణాన్ని ఉపయోగించకూడదు అని మీరు అనుకుంటే, సెట్టింగ్‌లను తెరవడానికి ట్యాప్ చేసి, దీన్ని ఆఫ్ చేయండి."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"ఆఫ్ చేయి"</string>
     <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"<xliff:g id="NAME">%s</xliff:g>ని తనిఖీ చేస్తోంది…"</string>
     <string name="ext_media_checking_notification_message" msgid="410185170877285434">"ప్రస్తుత కంటెంట్ సమీక్షించబడుతోంది"</string>
@@ -1771,10 +1771,8 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"మీ నిర్వాహకులు నవీకరించారు"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"మీ నిర్వాహకులు తొలగించారు"</string>
     <string name="confirm_battery_saver" msgid="639106420541753635">"సరే"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (1002571337088673987) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (2307555792915978653) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="1002571337088673987">"బ్యాటరీ జీవితకాలాన్ని పెంచడానికి, బ్యాటరీ సేవర్:\n ముదురు రంగు·థీమ్‌ను ఆన్ చేస్తుంది\n·నేపథ్య కార్యకలాపం, కొన్ని విజువల్ ఎఫెక్ట్స్ మరియు “Hey Google” వంటి ఇతర ఫీచర్‌లను ఆపివేస్తుంది లేదా పరిమితం చేస్తుంది\n\n"<annotation id="url">"మరింత తెలుసుకోండి"</annotation></string>
+    <string name="battery_saver_description" msgid="2307555792915978653">"బ్యాటరీ జీవితకాలాన్ని పెంచడానికి, బ్యాటరీ సేవర్:\n ముదురు రంగు·థీమ్‌ను ఆన్ చేస్తుంది\n·నేపథ్య కార్యకలాపం, కొన్ని విజువల్ ఎఫెక్ట్స్ మరియు “Hey Google” వంటి ఇతర ఫీచర్‌లను ఆపివేస్తుంది లేదా పరిమితం చేస్తుంది"</string>
     <string name="data_saver_description" msgid="6015391409098303235">"డేటా వినియోగాన్ని తగ్గించడంలో డేటా సేవర్ సహాయకరంగా ఉంటుంది. బ్యాక్‌గ్రౌండ్‌లో కొన్ని యాప్‌లు డేటాను పంపకుండా లేదా స్వీకరించకుండా నిరోధిస్తుంది. మీరు ప్రస్తుతం ఉపయోగిస్తోన్న యాప్‌ డేటాను యాక్సెస్ చేయగలదు. కానీ అలా అరుదుగా చేయవచ్చు. ఉదాహరణకు, మీరు చిత్రాలను నొక్కే వరకు అవి ప్రదర్శించబడవు."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"డేటా సేవర్‌ను ఆన్ చేయాలా?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"ఆన్ చేయి"</string>
@@ -1890,7 +1888,7 @@
     <string name="app_category_image" msgid="4867854544519846048">"ఫోటోలు &amp; చిత్రాలు"</string>
     <string name="app_category_social" msgid="5842783057834965912">"సామాజికం &amp; కమ్యూనికేషన్"</string>
     <string name="app_category_news" msgid="7496506240743986873">"వార్తలు &amp; వార్తాపత్రికలు"</string>
-    <string name="app_category_maps" msgid="5878491404538024367">"మ్యాప్స్ &amp; నావిగేషన్"</string>
+    <string name="app_category_maps" msgid="5878491404538024367">"Maps &amp; నావిగేషన్"</string>
     <string name="app_category_productivity" msgid="3742083261781538852">"ఉత్పాదకత"</string>
     <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"పరికర నిల్వ"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"USB డీబగ్గింగ్"</string>
@@ -1965,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"బ్లాక్ చేయబడిన దాన్ని తనిఖీ చేయడానికి నొక్కండి."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"సిస్టమ్"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"సెట్టింగ్‌లు"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"స్టాండ్‌బై"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV పరికరం త్వరలో ఆపివేయబడుతుంది; దాన్ని ఆన్‌లో ఉంచడానికి బటన్‌ను నొక్కండి."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"పరికరం త్వరలో ఆపివేయబడుతుంది; దీన్ని ఆన్‌లో ఉంచడానికి నొక్కండి."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"కెమెరా"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"మైక్రోఫోన్"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"మీ స్క్రీన్‌పై ఇతర యాప్‌ల ద్వారా ప్రదర్శించబడుతోంది"</string>
@@ -2008,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"డైరెక్ట్ షేర్ అందుబాటులో లేదు"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"యాప్‌ల జాబితా"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"ఈ యాప్‌కు రికార్డ్ చేసే అనుమతి మంజూరు కాలేదు, అయినా ఈ USB పరికరం ద్వారా ఆడియోను క్యాప్చర్ చేయగలదు."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"హోమ్"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"వెనుకకు"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"ఇటీవలి యాప్‌లు"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"నోటిఫికేషన్‌లు"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"శీఘ్ర సెట్టింగ్‌లు"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"పవర్ డైలాగ్‌ను తెరువు"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"స్క్రీన్ విభజనను టోగుల్ చేయి"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"స్క్రీన్‌ను లాక్ చేయి"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"స్క్రీన్‌షాట్"</string>
 </resources>
diff --git a/core/res/res/values-television/config.xml b/core/res/res/values-television/config.xml
index 3ecb1dd..655d4dd 100644
--- a/core/res/res/values-television/config.xml
+++ b/core/res/res/values-television/config.xml
@@ -42,4 +42,8 @@
 
     <!-- Allow SystemUI to show the shutdown dialog -->
     <bool name="config_showSysuiShutdown">true</bool>
+
+    <!-- The time in milliseconds of prolonged user inactivity after which device goes to sleep,
+         even if wakelocks are held. On TVs, this defaults to 4 hours. -->
+    <integer name="config_attentiveTimeout">14400000</integer>
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index ff1ea21..ab35008 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"อนุญาตให้&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;เข้าถึงตำแหน่งของอุปกรณ์นี้ไหม"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"แอปจะมีสิทธิ์เข้าถึงตำแหน่งในขณะที่คุณใช้แอปเท่านั้น"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; เข้าถึงตำแหน่งของอุปกรณ์นี้&lt;b&gt;ตลอดเวลา&lt;/b&gt;ไหม"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"ปัจจุบันแอปมีสิทธิ์เข้าถึงตำแหน่งในขณะที่คุณใช้แอปเท่านั้น"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ปฏิทิน"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"เข้าถึงปฏิทิน"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; เข้าถึงปฏิทินไหม"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"แตะเพื่อดูรายการที่ถูกบล็อก"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"ระบบ"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"การตั้งค่า"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"สแตนด์บาย"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"อุปกรณ์ Android TV จะปิดเครื่องในอีกไม่ช้า กดปุ่มเพื่อเปิดอุปกรณ์ต่อไป"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"อุปกรณ์จะปิดเครื่องในอีกไม่ช้า กดเพื่อเปิดอุปกรณ์ต่อไป"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"กล้อง"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"ไมโครโฟน"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"แสดงทับแอปอื่นๆ บนหน้าจอ"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"การแชร์โดยตรงไม่พร้อมใช้งาน"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"รายชื่อแอป"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"แอปนี้ไม่ได้รับอนุญาตให้บันทึกเสียงแต่จะบันทึกเสียงผ่านอุปกรณ์ USB นี้ได้"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"หน้าแรก"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"กลับ"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"แอปล่าสุด"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"การแจ้งเตือน"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"การตั้งค่าด่วน"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"กล่องโต้ตอบพลังงาน"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"เปิด/ปิดการแบ่งหน้าจอ"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"หน้าจอล็อก"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"ภาพหน้าจอ"</string>
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 79c040f..0dccb4b 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Payagan ang &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na i-access ang lokasyon ng device na ito?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Magkakaroon lang ang app ng access sa lokasyon habang ginagamit mo ang app"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Payagan ang &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na &lt;b&gt;palaging&lt;/b&gt; i-access ang lokasyon ng device na ito?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Kasalukuyang maa-access ng app ang lokasyon habang ginagamit mo lang ang app"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendaryo"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"i-access ang iyong kalendaryo"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Payagan ang &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na i-access ang iyong kalendaryo?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"I-tap para tingnan kung ano ang naka-block."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"System"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Mga Setting"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Standby"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Mag-o-off na ang Android TV device; pumindot ng button para panatilihin itong naka-on."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Mag-o-off na ang device; pumindot para panatilihin itong naka-on."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Camera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikropono"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"ipinapakita sa ibabaw ng ibang app sa iyong screen"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Hindi available ang direktang pagbabahagi"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Listahan ng mga app"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Hindi nabigyan ng pahintulot ang app na ito para mag-record pero nakakapag-capture ito ng audio sa pamamagitan ng USB device na ito."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Home"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Bumalik"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Mga Kamakailang Apps"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Mga Notification"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Mga Mabilisang Setting"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Dialog ng Power"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"I-toggle ang Split Screen"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Lock Screen"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Screenshot"</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index d6841f0..0a0e64d 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uygulamasının bu cihazın konumuna erişmesine izin verilsin mi?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Bu uygulama konum bilgisine yalnızca kullanıldığı sırada erişebilecektir"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uygulamasının bu cihazın konumuna &lt;b&gt;her zaman&lt;/b&gt; erişmesine izin verilsin mi?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Uygulama şu anda yalnızca siz kullanırken konuma erişebilir"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Takvim"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"takviminize erişme"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uygulamasının takviminize erişmesine izin verilsin mi?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Nelerin engellendiğini kontrol etmek için dokunun."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Ayarlar"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Beklemeye alınıyor"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV cihazı kısa süre içinde kapanacak; açık tutmak için bir düğmeye basın."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Cihaz kısa süre içinde kapanacak; açık tutmak için düğmeye basın."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"ekranınızdaki diğer uygulamaların üzerinde görüntüleniyor"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Doğrudan paylaşım mevcut değil"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Uygulama listesi"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Bu uygulamaya ses kaydetme izni verilmedi ancak bu USB cihazı üzerinden sesleri yakalayabilir."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Ana Ekran"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Geri"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Son Uygulamalar"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Bildirimler"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Hızlı Ayarlar"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Güç İletişim Kutusu"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Bölünmüş Ekranı aç/kapat"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Kilit Ekranı"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Ekran görüntüsü"</string>
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 3412eb2..7cc5857 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -292,7 +292,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Надати додатку &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ до геоданих пристрою?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Додаток матиме доступ до геоданих, лише коли ви ним користуєтеся"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Дозволити додатку &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; &lt;b&gt;завжди&lt;/b&gt; отримувати доступ до геоданих цього пристрою?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Зараз додаток має доступ до геоданих, лише коли ви ним користуєтеся"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"отримувати доступ до календаря"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Надати додатку &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ до календаря?"</string>
@@ -2029,9 +2030,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Торкніться, щоб перевірити, що заблоковано."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Система"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Налаштування"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Режим очікування"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Незабаром пристрій Android TV буде вимкнено. Натисніть кнопку, щоб цього не сталося."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Незабаром пристрій буде вимкнено. Натисніть, щоб цього не сталося."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Камера"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Мікрофон"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"показ поверх інших додатків на екрані"</string>
@@ -2074,22 +2072,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Прямий обмін даними недоступний"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Список додатків"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Цей додаток не має дозволу на запис, але він може фіксувати звук через цей USB-пристрій."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"На головний екран"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Назад"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Нещодавні додатки"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Сповіщення"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Швидкі налаштування"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Відкрити вікно"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Розділити екран"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Заблокувати екран"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Знімок екрана"</string>
 </resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 003fd54..51895ae 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; کو اس آلہ کے مقام تک رسائی کی اجازت دیں؟"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"جب آپ ایپ استعمال کریں گے تبھی ایپ کو مقام تک رسائی حاصل ہوگی"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"‏‎&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;‎ کو اس آلہ کے مقام تک ‎&lt;b&gt;‎ہر وقت‎&lt;/b&gt;‎ رسائی حاصل کرنے کی اجازت دیں؟"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"ایپ کو فی الحال صرف اسی صورت میں مقام تک رسائی حاصل ہو سکتی ہے جب ایپ آپ کے زير استعمال ہو"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"کیلنڈر"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"اپنے کیلنڈر تک رسائی حاصل کریں"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; کو آپ کے کیلنڈر تک رسائی کی اجازت دیں؟"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"مسدود کی گئی چیزوں کو چیک کرنے کے لیے تھپتھپائیں۔"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"سسٹم"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"ترتیبات"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"اسٹینڈ بائی"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"‏Android TV آلہ جلد ہی بند ہوجائے گا آن رکھنے کے ليے بٹن دبائیں۔"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"آلہ جلد ہی بند ہوجائے گا اسے آن رکھنے کے ليے دبائیں۔"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"کیمرا"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"مائیکروفون"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"آپ کی اسکرین پر دیگر ایپس پر دکھایا جا رہا ہے"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"بلاواسطہ اشتراک دستیاب نہیں ہے"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"ایپس کی فہرست"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"‏اس ایپ کو ریکارڈ کرنے کی اجازت عطا نہیں کی گئی ہے مگر اس USB آلہ کے ذریعے آڈیو کیپچر کر سکتی ہے۔"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"گھر"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"پیچھے"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"حالیہ ایپس"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"اطلاعات"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"فوری ترتیبات"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"پاور ڈائیلاگ"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"اسپلٹ اسکرین ٹوگل کریں"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"مقفل اسکرین"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"اسکرین شاٹ"</string>
 </resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 83e99b9..5640c4d 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uchun bu qurilmaning joylashuvi haqidagi axborotdan foydalanish ruxsati berilsinmi?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Bu ilovadan foydalanilayotdangina u joylashuv axborotidan foydalana oladi"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uchun bu qurilmaning joylashuvi haqidagi axborotdan &lt;b&gt;doim&lt;/b&gt; foydalanish ruxsati berilsinmi?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Ilova hozirda joylashuv axborotidan faqat ilova ishlatilayotgandagina foydalana oladi"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"Bu ilova ishlamaganda ham joylashuvingiz axborotidan har doim foydalanmoqchi. Bunga "<annotation id="link">"sozlamalar"</annotation>" orqali ruxsat bering."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Taqvim"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"taqvimingizga kirish"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uchun taqvimingizga ruxsat berilsinmi?"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Nimalar bloklanganini tekshirish uchun bosing"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Tizim"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Sozlamalar"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Kutib turing"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV qurilmasi oʻchish arafasida, yoniq qolishi uchun istalgan tugmani bosing."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Qurilma oʻchish arafasida, yoniq qolishi uchun istalgan tugmani bosing"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"ekranda boshqa ilovalar ustidan ochiladi"</string>
@@ -2006,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Bevosita ulashuv ishlamaydi"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Ilovalar roʻyxati"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Bu ilovaga yozib olish ruxsati berilmagan, lekin shu USB orqali ovozlarni yozib olishi mumkin."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Bosh sahifa"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Orqaga"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Yaqinda ishlatilgan ilovalar"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Bildirishnomalar"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Tezkor sozlamalar"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Quvvat muloqot oynasi"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Ekranni ikkiga ajratish tugmasi"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Ekran qulfi"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Skrinshot"</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 7b17de7..9bf7729 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Cho phép &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; truy cập vào vị trí của thiết bị này?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Ứng dụng này sẽ chỉ có quyền truy cập vào vị trí khi bạn đang sử dụng ứng dụng này"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Bạn muốn cho phép &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; truy cập vào vị trí của thiết bị này &lt;b&gt;trong mọi trường hợp&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Hiện tại, ứng dụng này chỉ có thể truy cập vào vị trí trong khi bạn dùng"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Lịch"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"truy cập lịch của bạn"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Cho phép &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; truy cập vào lịch của bạn?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Nhấn để xem những thông báo bị chặn."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Hệ thống"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Cài đặt"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Chế độ chờ"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Thiết bị Android TV sẽ sớm tắt. Hãy nhấn vào một nút để thiết bị vẫn bật."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Thiết bị sẽ sớm tắt. Hãy nhấn vào một nút để thiết bị vẫn bật."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Máy ảnh"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Micrô"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"hiển thị qua các ứng dụng khác trên màn hình của bạn"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Không thể chia sẻ trực tiếp"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Danh sách ứng dụng"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Ứng dụng này chưa được cấp quyền ghi âm nhưng vẫn có thể ghi âm thông qua thiết bị USB này."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Màn hình chính"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Quay lại"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Ứng dụng gần đây"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Thông báo"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Cài đặt nhanh"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Hộp thoại thao tác với nguồn"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Bật/tắt chế độ chia đôi màn hình"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Khóa màn hình"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Chụp ảnh màn hình"</string>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index e29898f..7da1a07 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"要允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”获取此设备的位置信息吗?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"只有当您使用该应用时,该应用才有权访问位置信息"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"要&lt;b&gt;一律允许&lt;/b&gt;允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;访问此设备的位置信息吗?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"目前只有当您使用该应用时,该应用才能访问位置信息"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"日历"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"访问您的日历"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;访问您的日历吗?"</string>
@@ -1771,10 +1772,8 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"已由您的管理员更新"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"已由您的管理员删除"</string>
     <string name="confirm_battery_saver" msgid="639106420541753635">"确定"</string>
-    <!-- no translation found for battery_saver_description_with_learn_more (1002571337088673987) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (2307555792915978653) -->
-    <skip />
+    <string name="battery_saver_description_with_learn_more" msgid="1002571337088673987">"为了延长电池续航时间,省电模式会执行以下操作:\n开启深色主题\n关闭或限制后台活动、部分视觉效果和其他功能,例如“Ok Google”\n\n"<annotation id="url">"了解详情"</annotation></string>
+    <string name="battery_saver_description" msgid="2307555792915978653">"为了延长电池续航时间,省电模式会执行以下操作:\n开启深色主题\n关闭或限制后台活动、部分视觉效果和其他功能,例如“Ok Google”"</string>
     <string name="data_saver_description" msgid="6015391409098303235">"为了减少流量消耗,流量节省程序会阻止某些应用在后台收发数据。您当前使用的应用可以收发数据,但频率可能会降低。举例而言,这可能意味着图片只有在您点按之后才会显示。"</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"要开启流量节省程序吗?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"开启"</string>
@@ -1965,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"点按即可查看屏蔽内容。"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"系统"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"设置"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"待机"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV 设备即将关闭;按一下相应的按钮即可让设备保持开启状态。"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"设备即将关闭;按一下即可让设备保持开启状态。"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"相机"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"麦克风"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"显示在屏幕上其他应用的上层"</string>
@@ -2008,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"无法使用直接分享功能"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"应用列表"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"此应用未获得录音权限,但能通过此 USB 设备录制音频。"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"主屏幕"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"返回"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"最近用过的应用"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"通知"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"快捷设置"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"电源对话框"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"开启/关闭分屏"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"锁定屏幕"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"屏幕截图"</string>
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 40f0c94..0640953 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;b&gt;&lt;/b&gt;存取此裝置的位置資訊嗎?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"只有在您使用此應用程式時,應用程式才能存取位置資訊"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"要允許&lt;b&gt;「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;/b&gt;&lt;b&gt;長期&lt;/b&gt;存取此裝置的位置資訊嗎?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"只有在您使用此應用程式時,應用程式才能存取位置資訊"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"日曆"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"存取您的日曆"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;b&gt;&lt;/b&gt;存取您的日曆嗎?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"輕按即可查看封鎖內容。"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"系統"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"設定"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"待機"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV 裝置即將關閉,按下按鈕即可保持開啟。"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"裝置即將關閉,輕按即可保持開啟。"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"相機"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"麥克風"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"顯示在畫面上的其他應用程式上層"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"無法直接分享"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"應用程式清單"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"此應用程式尚未獲授予錄音權限,但可透過此 USB 裝置記錄音訊。"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"主頁"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"返回"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"最近使用的應用程式"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"通知"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"快速設定"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"電源對話框"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"切換分割螢幕"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"將畫面上鎖"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"螢幕截圖"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 2fb155e..0263426 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -286,7 +286,8 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」存取這個裝置的位置資訊嗎?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"該應用程式只有在你使用時,才能存取位置資訊"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"要&lt;b&gt;一律允許&lt;/b&gt;「<xliff:g id="APP_NAME">%1$s</xliff:g>」存取這個裝置的位置資訊嗎?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"目前應用程式只有在你使用時,才能存取位置資訊"</string>
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (6969122401786527350) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"日曆"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"存取你的日曆"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」存取你的日曆嗎?"</string>
@@ -1963,9 +1964,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"輕觸即可查看遭封鎖的項目。"</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"系統"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"設定"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"待機"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Android TV 裝置即將關閉。如要讓裝置保持開啟狀態,請按下任一按鈕。"</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"裝置即將關閉。輕觸螢幕或按下按鈕即可讓裝置保持開啟狀態。"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"相機"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"麥克風"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"顯示在畫面上的其他應用程式上層"</string>
@@ -2006,22 +2004,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"無法使用直接分享功能"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"應用程式清單"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"這個應用程式未取得錄製內容的權限,但可以透過這部 USB 裝置錄製音訊。"</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"主螢幕"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"返回"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"最近使用的應用程式"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"通知"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"快速設定"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"開啟電源對話方塊"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"切換分割畫面模式"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"螢幕鎖定"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"擷取螢幕畫面"</string>
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 2ecc835..bc02215 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -286,7 +286,7 @@
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Vumela i-&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ukuthi ingene kundawo yale divayisi?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Uhlelo lokusebenza luzoba nokufinyelela kuphela kundawo ngenkathi usebenzisa uhlelo lokusebenza"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Vumela i-&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ukuze ifinyelele indawo yale divayisi &lt;b&gt;ngaso sonke isikhathi&lt;/b&gt;?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Uhlelo lokusebenza manje lungafinyelela kundawo kuphela ngenkathi usebenzisa uhlelo lokusebenza"</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="6969122401786527350">"Lolu hlelo lokusebenza lungafuna ukufinyelela indawo yakho ngaso sonke isikhathi, ngisho noma ungasebenzisi uhlelo lokusebenza. Vumela kokuthi "<annotation id="link">"izilungiselelo"</annotation>"."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Ikhalenda"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"finyelela kukhalenda yakho"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Vumela i-&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ukuthi ifinyelele kukhalenda yakho?"</string>
@@ -1963,9 +1963,6 @@
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Thepha ukuze uhlole ukuthi yini evinjelwe."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Isistimu"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Izilungiselelo"</string>
-    <string name="standby_warning_title" msgid="9221585425153642453">"Ilindile"</string>
-    <string name="standby_warning_message" product="tv" msgid="6373301881876406323">"Idivayisi ye-Android TV maduze izovalwa, cindezela inkinobho ukuze uyigcine ivuliwe."</string>
-    <string name="standby_warning_message" product="default" msgid="5222741828239073484">"Idivayisi maduze izovalwa, cindezela ukuze uyigcine ivuliwe."</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Ikhamera"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"Imakrofoni"</string>
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"iboniswa ngaphezulu kwezinye izinhlelo zokusebenza kusikrini sakho"</string>
@@ -2006,22 +2003,13 @@
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"Ukwabelana okuqondile akutholakali"</string>
     <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"Uhlu lwezinhlelo zokusebenza"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="5701272284724577469">"Lolu hlelo lokusebenza alunikeziwe imvume yokurekhoda kodwa lungathwebula umsindo ngale divayisi ye-USB."</string>
-    <!-- no translation found for accessibility_system_action_home_label (6089400419441597916) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_back_label (8986628898117178971) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_recents_label (7607601657790855723) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_notifications_label (1578681904050072545) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_quick_settings_label (3885565587471448947) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_power_dialog_label (2299530700682199873) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_toggle_split_screen_label (2853334443686935668) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_lock_screen_label (2377933717780192594) -->
-    <skip />
-    <!-- no translation found for accessibility_system_action_screenshot_label (1933564892301816480) -->
-    <skip />
+    <string name="accessibility_system_action_home_label" msgid="6089400419441597916">"Ikhaya"</string>
+    <string name="accessibility_system_action_back_label" msgid="8986628898117178971">"Emuva"</string>
+    <string name="accessibility_system_action_recents_label" msgid="7607601657790855723">"Izinhlelo zokusebenza zakamuva"</string>
+    <string name="accessibility_system_action_notifications_label" msgid="1578681904050072545">"Izaziso"</string>
+    <string name="accessibility_system_action_quick_settings_label" msgid="3885565587471448947">"Izilungiselelo ezisheshayo"</string>
+    <string name="accessibility_system_action_power_dialog_label" msgid="2299530700682199873">"Ibhokisi lamandla"</string>
+    <string name="accessibility_system_action_toggle_split_screen_label" msgid="2853334443686935668">"Guqula ukuhlukanisa isikrini"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="2377933717780192594">"Khiya isikrini"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="1933564892301816480">"Isithombe-skrini"</string>
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index cb0b599..e6f038a 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -959,6 +959,14 @@
          The default is false. -->
     <bool name="config_suspendWhenScreenOffDueToProximity">false</bool>
 
+    <!-- The time in milliseconds of prolonged user inactivity after which device goes to sleep,
+         even if wakelocks are held. -->
+    <integer name="config_attentiveTimeout">-1</integer>
+
+    <!-- How long to show a warning message to user before the device goes to sleep after prolonged
+         user inactivity. -->
+    <integer name="config_attentiveWarningDuration">30000</integer>
+
     <!-- Control the behavior when the user long presses the power button.
             0 - Nothing
             1 - Global actions menu
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2cab446..0f650e3 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -704,96 +704,57 @@
     <string name="permgrouplab_contacts">Contacts</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_contacts">access your contacts</string>
-    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
-    <string name="permgrouprequest_contacts">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your contacts?</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_location">Location</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_location">access this device\'s location</string>
-    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
-    <string name="permgrouprequest_location">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access this device\'s location?</string>
-    <!-- Subtitle of the message shown to the user when the apps requests permission to use the location only while app is in foreground [CHAR LIMIT=150]-->
-    <string name="permgrouprequestdetail_location">The app will only have access to the location while you\u2019re using the app</string>
-    <!-- Message shown to the user when the apps requests permission to use the location while app is in foreground and background. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
-    <string name="permgroupbackgroundrequest_location">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access this device\u2019s location &lt;b>all the time&lt;/b>?</string>
-    <!-- Subtitle of the message shown to the user when the apps requests permission to use the location while app is in foreground and background [CHAR LIMIT=150] -->
-    <string name="permgroupbackgroundrequestdetail_location">App currently can access location only while you\u2019re using the app</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_calendar">Calendar</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_calendar">access your calendar</string>
-    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
-    <string name="permgrouprequest_calendar">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your calendar?</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_sms">SMS</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_sms">send and view SMS messages</string>
-    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
-    <string name="permgrouprequest_sms">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to send and view SMS messages?</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_storage">Storage</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_storage">access photos, media, and files on your device</string>
-    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
-    <string name="permgrouprequest_storage">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access photos, media, and files on your device?</string>
 
     <!-- Title of a category of application permissioncds, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_microphone">Microphone</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_microphone">record audio</string>
-    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
-    <string name="permgrouprequest_microphone">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to record audio?</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=40]-->
     <string name="permgrouplab_activityRecognition">Physical activity</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=40]-->
     <string name="permgroupdesc_activityRecognition">access your physical activity</string>
-    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
-    <string name="permgrouprequest_activityRecognition">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your physical activity?</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_camera">Camera</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_camera">take pictures and record video</string>
-    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
-    <string name="permgrouprequest_camera">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to take pictures and record video?</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_calllog">Call logs</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_calllog">read and write phone call log</string>
-    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
-    <string name="permgrouprequest_calllog">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your phone call logs?</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_phone">Phone</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_phone">make and manage phone calls</string>
     <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
-    <string name="permgrouprequest_phone">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to make and manage phone calls?</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_sensors">Body sensors</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_sensors">access sensor data about your vital signs</string>
-    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
-    <string name="permgrouprequest_sensors">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access sensor data about your vital signs?</string>
 
     <!-- Title for the capability of an accessibility service to retrieve window content. -->
     <string name="capability_title_canRetrieveWindowContent">Retrieve window content</string>
@@ -3064,9 +3025,9 @@
     <string name="ok">OK</string>
     <!-- Preference framework strings. -->
     <string name="cancel">Cancel</string>
-    <!-- Preference framework strings. -->
+    <!-- Preference framework strings. {@deprecated Do not use. Incorrectly matches android.R.string.ok rather than "yes".} -->
     <string name="yes">OK</string>
-    <!-- Preference framework strings. -->
+    <!-- Preference framework strings. {@deprecated Do not use. Incorrectly matches android.R.string.cancel rather than "no".} -->
     <string name="no">Cancel</string>
     <!-- This is the generic "attention" string to be used in attention dialogs.  Typically
          combined with setIconAttribute(android.R.attr.alertDialogIcon)
@@ -5238,13 +5199,6 @@
     <!-- Application name displayed in notifications [CHAR LIMIT=60] -->
     <string name="notification_app_name_settings">Settings</string>
 
-    <!-- Title of the overlay warning the user to interact with the device or it will go into standby. [CHAR LIMIT=25] -->
-    <string name="standby_warning_title">Standby</string>
-    <!-- Message of the overlay warning the user to interact with the device or it will go into standby. [CHAR LIMIT=NONE] -->
-    <string name="standby_warning_message" product="tv">The Android TV device will soon turn off; press a button to keep it on.</string>
-    <!-- Message of the overlay warning the user to interact with the device or it will go into standby. [CHAR LIMIT=NONE] -->
-    <string name="standby_warning_message" product="default">The device will soon turn off; press to keep it on.</string>
-
     <!-- Active Permission - accessibility support -->
     <!-- Content description of the camera icon in the notification. [CHAR LIMIT=NONE] -->
     <string name="notification_appops_camera_active">Camera</string>
@@ -5366,4 +5320,7 @@
     <string name="accessibility_system_action_lock_screen_label">Lock Screen</string>
     <!-- Label for taking screenshot action [CHAR LIMIT=NONE] -->
     <string name="accessibility_system_action_screenshot_label">Screenshot</string>
+
+    <!-- Accessibility description of caption view -->
+    <string name="accessibility_freeform_caption"><xliff:g id="app_name">%1$s</xliff:g> app in Pop-up window.</string>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 28809da..23402c1 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2117,6 +2117,8 @@
   <java-symbol type="integer" name="config_minimumScreenOffTimeout" />
   <java-symbol type="integer" name="config_maximumScreenDimDuration" />
   <java-symbol type="fraction" name="config_maximumScreenDimRatio" />
+  <java-symbol type="integer" name="config_attentiveTimeout" />
+  <java-symbol type="integer" name="config_attentiveWarningDuration" />
   <java-symbol type="string" name="config_customAdbPublicKeyConfirmationComponent" />
   <java-symbol type="string" name="config_customAdbPublicKeyConfirmationSecondaryUserComponent" />
   <java-symbol type="string" name="config_customVpnConfirmDialogComponent" />
@@ -3761,4 +3763,6 @@
   <java-symbol type="string" name="accessibility_system_action_recents_label" />
   <java-symbol type="string" name="accessibility_system_action_screenshot_label" />
   <java-symbol type="string" name="accessibility_system_action_toggle_split_screen_label" />
+
+  <java-symbol type="string" name="accessibility_freeform_caption" />
 </resources>
diff --git a/core/tests/coretests/src/android/content/ManagedUserContentResolverTest.java b/core/tests/coretests/src/android/content/ManagedUserContentResolverTest.java
index 22b2314..1bc46a7 100644
--- a/core/tests/coretests/src/android/content/ManagedUserContentResolverTest.java
+++ b/core/tests/coretests/src/android/content/ManagedUserContentResolverTest.java
@@ -19,6 +19,7 @@
 import android.content.pm.UserInfo;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.os.UserManager;
 
 import androidx.test.filters.LargeTest;
 
@@ -40,6 +41,6 @@
     @Override
     protected UserInfo createUser() throws RemoteException {
         return mUm.createProfileForUser("Managed user",
-                UserInfo.FLAG_MANAGED_PROFILE, UserHandle.myUserId());
+                UserManager.USER_TYPE_PROFILE_MANAGED, /* flags */ 0, UserHandle.myUserId());
     }
 }
diff --git a/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java b/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
index 823fca5..85aa118 100644
--- a/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
+++ b/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
@@ -23,13 +23,23 @@
 
 import android.os.Parcel;
 import android.util.Pair;
+import android.util.Xml;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.util.FastXmlSerializer;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 
 @SmallTest
@@ -104,11 +114,15 @@
         });
     }
 
-
     @Test
     public void testParceledConfigIsEquivalent() {
         BrightnessConfiguration.Builder builder =
                 new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
+        builder.setShouldCollectColorSamples(true);
+        builder.addCorrectionByCategory(3,
+                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
+        builder.addCorrectionByPackageName("a.package.name",
+                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
         BrightnessConfiguration config = builder.build();
         Parcel p = Parcel.obtain();
         p.writeParcelable(config, 0 /*flags*/);
@@ -119,12 +133,49 @@
     }
 
     @Test
+    public void testWriteReadXml() throws IOException, XmlPullParserException {
+        BrightnessConfiguration.Builder builder =
+                new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
+        builder.setShouldCollectColorSamples(true);
+        builder.addCorrectionByCategory(3,
+                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
+        builder.addCorrectionByPackageName("a.package.name",
+                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
+        BrightnessConfiguration config = builder.build();
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        XmlSerializer out = new FastXmlSerializer();
+        out.setOutput(baos, StandardCharsets.UTF_8.name());
+        out.startDocument(null, true);
+        config.saveToXml(out);
+        out.endDocument();
+        baos.flush();
+
+        ByteArrayInputStream input = new ByteArrayInputStream(baos.toByteArray());
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(input, StandardCharsets.UTF_8.name());
+        BrightnessConfiguration loadedConfig = BrightnessConfiguration.loadFromXml(parser);
+
+        assertEquals(config, loadedConfig);
+    }
+
+    @Test
     public void testEquals() {
         BrightnessConfiguration.Builder builder =
                 new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
+        builder.setShouldCollectColorSamples(true);
+        builder.addCorrectionByCategory(3,
+                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
+        builder.addCorrectionByPackageName("a.package.name",
+                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
         BrightnessConfiguration baseConfig = builder.build();
 
         builder = new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
+        builder.setShouldCollectColorSamples(true);
+        builder.addCorrectionByCategory(3,
+                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
+        builder.addCorrectionByPackageName("a.package.name",
+                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
         BrightnessConfiguration identicalConfig = builder.build();
         assertEquals(baseConfig, identicalConfig);
         assertEquals("hashCodes must be equal for identical configs",
@@ -133,14 +184,37 @@
         float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
         lux[lux.length - 1] = lux[lux.length - 1] * 2;
         builder = new BrightnessConfiguration.Builder(lux, NITS_LEVELS);
+        builder.setShouldCollectColorSamples(true);
+        builder.addCorrectionByCategory(3,
+                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
+        builder.addCorrectionByPackageName("a.package.name",
+                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
         BrightnessConfiguration luxDifferConfig = builder.build();
         assertNotEquals(baseConfig, luxDifferConfig);
 
         float[] nits = Arrays.copyOf(NITS_LEVELS, NITS_LEVELS.length);
         nits[nits.length - 1] = nits[nits.length - 1] * 2;
         builder = new BrightnessConfiguration.Builder(LUX_LEVELS, nits);
+        builder.setShouldCollectColorSamples(true);
+        builder.addCorrectionByCategory(3,
+                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
+        builder.addCorrectionByPackageName("a.package.name",
+                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
         BrightnessConfiguration nitsDifferConfig = builder.build();
         assertNotEquals(baseConfig, nitsDifferConfig);
+
+        builder = new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
+        builder.addCorrectionByCategory(3,
+                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
+        builder.addCorrectionByPackageName("a.package.name",
+                BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f));
+        BrightnessConfiguration colorCollectionDiffers = builder.build();
+        assertNotEquals(baseConfig, colorCollectionDiffers);
+
+        builder = new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
+        builder.setShouldCollectColorSamples(true);
+        BrightnessConfiguration correctionsDiffer = builder.build();
+        assertNotEquals(baseConfig, correctionsDiffer);
     }
 
     private static void assertArrayEquals(float[] expected, float[] actual, String name) {
diff --git a/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java
index 8483645..e16d1ca 100644
--- a/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java
+++ b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java
@@ -19,7 +19,7 @@
 import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
 import static android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION;
 
-import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.fail;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -80,8 +80,8 @@
         CountDownLatch lock = new CountDownLatch(1);
         mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, false, false, timeoutMs,
                 mHandler,
-                worked -> {
-                    assertFalse(worked);
+                uri -> {
+                    assertNull(uri);
                     lock.countDown();
                 });
 
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 3658f89..c2e3c64 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -92,11 +92,17 @@
      * @see #getType
      */
     public static final int TYPE_ADAPTIVE_BITMAP = 5;
+    /**
+     * An icon that was created using {@link Icon#createWithAdaptiveBitmapContentUri}.
+     * @see #getType
+     */
+    public static final int TYPE_URI_ADAPTIVE_BITMAP = 6;
 
     /**
      * @hide
      */
-    @IntDef({TYPE_BITMAP, TYPE_RESOURCE, TYPE_DATA, TYPE_URI, TYPE_ADAPTIVE_BITMAP})
+    @IntDef({TYPE_BITMAP, TYPE_RESOURCE, TYPE_DATA, TYPE_URI, TYPE_ADAPTIVE_BITMAP,
+            TYPE_URI_ADAPTIVE_BITMAP})
     public @interface IconType {
     }
 
@@ -113,12 +119,14 @@
     // based on the value of mType.
 
     // TYPE_BITMAP: Bitmap
+    // TYPE_ADAPTIVE_BITMAP: Bitmap
     // TYPE_RESOURCE: Resources
     // TYPE_DATA: DataBytes
     private Object          mObj1;
 
     // TYPE_RESOURCE: package name
     // TYPE_URI: uri string
+    // TYPE_URI_ADAPTIVE_BITMAP: uri string
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     private String          mString1;
 
@@ -141,7 +149,8 @@
     }
 
     /**
-     * @return The {@link android.graphics.Bitmap} held by this {@link #TYPE_BITMAP} Icon.
+     * @return The {@link android.graphics.Bitmap} held by this {@link #TYPE_BITMAP} or
+     * {@link #TYPE_ADAPTIVE_BITMAP} Icon.
      * @hide
      */
     @UnsupportedAppUsage
@@ -243,11 +252,12 @@
     }
 
     /**
-     * @return The URI (as a String) for this {@link #TYPE_URI} Icon.
+     * @return The URI (as a String) for this {@link #TYPE_URI} or {@link #TYPE_URI_ADAPTIVE_BITMAP}
+     * Icon.
      * @hide
      */
     public String getUriString() {
-        if (mType != TYPE_URI) {
+        if (mType != TYPE_URI && mType != TYPE_URI_ADAPTIVE_BITMAP) {
             throw new IllegalStateException("called getUriString() on " + this);
         }
         return mString1;
@@ -256,7 +266,7 @@
     /**
      * Gets the uri used to create this icon.
      * <p>
-     * Only valid for icons of type {@link #TYPE_URI}.
+     * Only valid for icons of type {@link #TYPE_URI} and {@link #TYPE_URI_ADAPTIVE_BITMAP}.
      * Note: This uri may not be available in the future, and it is
      * up to the caller to ensure safety if this uri is re-used and/or persisted.
      */
@@ -272,6 +282,7 @@
             case TYPE_DATA: return "DATA";
             case TYPE_RESOURCE: return "RESOURCE";
             case TYPE_URI: return "URI";
+            case TYPE_URI_ADAPTIVE_BITMAP: return "URI_MASKABLE";
             default: return "UNKNOWN";
         }
     }
@@ -380,28 +391,39 @@
                     BitmapFactory.decodeByteArray(getDataBytes(), getDataOffset(), getDataLength())
                 );
             case TYPE_URI:
-                final Uri uri = getUri();
-                final String scheme = uri.getScheme();
-                InputStream is = null;
-                if (ContentResolver.SCHEME_CONTENT.equals(scheme)
-                        || ContentResolver.SCHEME_FILE.equals(scheme)) {
-                    try {
-                        is = context.getContentResolver().openInputStream(uri);
-                    } catch (Exception e) {
-                        Log.w(TAG, "Unable to load image from URI: " + uri, e);
-                    }
-                } else {
-                    try {
-                        is = new FileInputStream(new File(mString1));
-                    } catch (FileNotFoundException e) {
-                        Log.w(TAG, "Unable to load image from path: " + uri, e);
-                    }
-                }
+                InputStream is = getUriInputStream(context);
                 if (is != null) {
                     return new BitmapDrawable(context.getResources(),
                             BitmapFactory.decodeStream(is));
                 }
                 break;
+            case TYPE_URI_ADAPTIVE_BITMAP:
+                is = getUriInputStream(context);
+                if (is != null) {
+                    return new AdaptiveIconDrawable(null, new BitmapDrawable(context.getResources(),
+                            BitmapFactory.decodeStream(is)));
+                }
+                break;
+        }
+        return null;
+    }
+
+    private InputStream getUriInputStream(Context context) {
+        final Uri uri = getUri();
+        final String scheme = uri.getScheme();
+        if (ContentResolver.SCHEME_CONTENT.equals(scheme)
+                || ContentResolver.SCHEME_FILE.equals(scheme)) {
+            try {
+                return context.getContentResolver().openInputStream(uri);
+            } catch (Exception e) {
+                Log.w(TAG, "Unable to load image from URI: " + uri, e);
+            }
+        } else {
+            try {
+                return new FileInputStream(new File(mString1));
+            } catch (FileNotFoundException e) {
+                Log.w(TAG, "Unable to load image from path: " + uri, e);
+            }
         }
         return null;
     }
@@ -475,6 +497,7 @@
                 dataStream.writeInt(getResId());
                 break;
             case TYPE_URI:
+            case TYPE_URI_ADAPTIVE_BITMAP:
                 dataStream.writeUTF(getUriString());
                 break;
         }
@@ -513,6 +536,9 @@
                 case TYPE_URI:
                     final String uriOrPath = inputStream.readUTF();
                     return createWithContentUri(uriOrPath);
+                case TYPE_URI_ADAPTIVE_BITMAP:
+                    final String uri = inputStream.readUTF();
+                    return createWithAdaptiveBitmapContentUri(uri);
             }
         }
         return null;
@@ -545,6 +571,7 @@
                 return getResId() == otherIcon.getResId()
                         && Objects.equals(getResPackage(), otherIcon.getResPackage());
             case TYPE_URI:
+            case TYPE_URI_ADAPTIVE_BITMAP:
                 return Objects.equals(getUriString(), otherIcon.getUriString());
         }
         return false;
@@ -665,12 +692,40 @@
         if (uri == null) {
             throw new IllegalArgumentException("Uri must not be null.");
         }
-        final Icon rep = new Icon(TYPE_URI);
-        rep.mString1 = uri.toString();
+        return createWithContentUri(uri.toString());
+    }
+
+    /**
+     * Create an Icon pointing to an image file specified by URI. Image file should follow the icon
+     * design guideline defined by {@link AdaptiveIconDrawable}.
+     *
+     * @param uri A uri referring to local content:// or file:// image data.
+     */
+    @NonNull
+    public static Icon createWithAdaptiveBitmapContentUri(@NonNull String uri) {
+        if (uri == null) {
+            throw new IllegalArgumentException("Uri must not be null.");
+        }
+        final Icon rep = new Icon(TYPE_URI_ADAPTIVE_BITMAP);
+        rep.mString1 = uri;
         return rep;
     }
 
     /**
+     * Create an Icon pointing to an image file specified by URI. Image file should follow the icon
+     * design guideline defined by {@link AdaptiveIconDrawable}.
+     *
+     * @param uri A uri referring to local content:// or file:// image data.
+     */
+    @NonNull
+    public static Icon createWithAdaptiveBitmapContentUri(@NonNull Uri uri) {
+        if (uri == null) {
+            throw new IllegalArgumentException("Uri must not be null.");
+        }
+        return createWithAdaptiveBitmapContentUri(uri.toString());
+    }
+
+    /**
      * Store a color to use whenever this Icon is drawn.
      *
      * @param tint a color, as in {@link Drawable#setTint(int)}
@@ -758,6 +813,7 @@
                 }
                 break;
             case TYPE_URI:
+            case TYPE_URI_ADAPTIVE_BITMAP:
                 sb.append(" uri=").append(getUriString());
                 break;
         }
@@ -809,6 +865,7 @@
                 mObj1 = a;
                 break;
             case TYPE_URI:
+            case TYPE_URI_ADAPTIVE_BITMAP:
                 final String uri = in.readString();
                 mString1 = uri;
                 break;
@@ -840,6 +897,7 @@
                 dest.writeBlob(getDataBytes(), getDataOffset(), getDataLength());
                 break;
             case TYPE_URI:
+            case TYPE_URI_ADAPTIVE_BITMAP:
                 dest.writeString(getUriString());
                 break;
         }
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index b363686..2f1eeda 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -16,15 +16,21 @@
 
 package android.location;
 
+import android.annotation.FloatRange;
 import android.annotation.IntDef;
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 
 /**
- * This class represents the current state of the GNSS engine.
- * This class is used in conjunction with the {@link GnssStatus.Callback}.
+ * This class represents the current state of the GNSS engine and is used in conjunction with
+ * {@link GnssStatus.Callback}.
+ *
+ * @see LocationManager#registerGnssStatusCallback
+ * @see GnssStatus.Callback
  */
 public final class GnssStatus {
 
@@ -52,75 +58,88 @@
     /** @hide */
     public static final int CONSTELLATION_COUNT = 8;
 
-    /** @hide */
-    public static final int GNSS_SV_FLAGS_NONE = 0;
-    /** @hide */
-    public static final int GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA = (1 << 0);
-    /** @hide */
-    public static final int GNSS_SV_FLAGS_HAS_ALMANAC_DATA = (1 << 1);
-    /** @hide */
-    public static final int GNSS_SV_FLAGS_USED_IN_FIX = (1 << 2);
-    /** @hide */
-    public static final int GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY = (1 << 3);
+    private static final int SVID_FLAGS_NONE = 0;
+    private static final int SVID_FLAGS_HAS_EPHEMERIS_DATA = (1 << 0);
+    private static final int SVID_FLAGS_HAS_ALMANAC_DATA = (1 << 1);
+    private static final int SVID_FLAGS_USED_IN_FIX = (1 << 2);
+    private static final int SVID_FLAGS_HAS_CARRIER_FREQUENCY = (1 << 3);
 
-    /** @hide */
-    public static final int SVID_SHIFT_WIDTH = 8;
-    /** @hide */
-    public static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 4;
-    /** @hide */
-    public static final int CONSTELLATION_TYPE_MASK = 0xf;
+    private static final int SVID_SHIFT_WIDTH = 8;
+    private static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 4;
+    private static final int CONSTELLATION_TYPE_MASK = 0xf;
 
     /**
      * Used for receiving notifications when GNSS events happen.
+     *
+     * @see LocationManager#registerGnssStatusCallback
      */
     public static abstract class Callback {
         /**
          * Called when GNSS system has started.
          */
-        public void onStarted() {}
+        public void onStarted() {
+        }
 
         /**
          * Called when GNSS system has stopped.
          */
-        public void onStopped() {}
+        public void onStopped() {
+        }
 
         /**
          * Called when the GNSS system has received its first fix since starting.
+         *
          * @param ttffMillis the time from start to first fix in milliseconds.
          */
-        public void onFirstFix(int ttffMillis) {}
+        public void onFirstFix(int ttffMillis) {
+        }
 
         /**
          * Called periodically to report GNSS satellite status.
+         *
          * @param status the current status of all satellites.
          */
-        public void onSatelliteStatusChanged(GnssStatus status) {}
+        public void onSatelliteStatusChanged(@NonNull GnssStatus status) {
+        }
     }
 
     /**
      * Constellation type.
+     *
      * @hide
      */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({CONSTELLATION_UNKNOWN, CONSTELLATION_GPS, CONSTELLATION_SBAS, CONSTELLATION_GLONASS,
             CONSTELLATION_QZSS, CONSTELLATION_BEIDOU, CONSTELLATION_GALILEO, CONSTELLATION_IRNSS})
-    public @interface ConstellationType {}
-
-    final int[] mSvidWithFlags;
-    final float[] mCn0DbHz;
-    final float[] mElevations;
-    final float[] mAzimuths;
-    final int mSvCount;
-    final float[] mCarrierFrequencies;
+    public @interface ConstellationType {
+    }
 
     /**
+     * Create a GnssStatus that wraps the given arguments without any additional overhead. Callers
+     * are responsible for guaranteeing that the arguments are never modified after calling this
+     * method.
+     *
      * @hide
      */
-    public GnssStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations,
+    @NonNull
+    public static GnssStatus wrap(int svCount, int[] svidWithFlags, float[] cn0DbHzs,
+            float[] elevations, float[] azimuths, float[] carrierFrequencies) {
+        return new GnssStatus(svCount, svidWithFlags, cn0DbHzs, elevations, azimuths,
+                carrierFrequencies);
+    }
+
+    private final int mSvCount;
+    private final int[] mSvidWithFlags;
+    private final float[] mCn0DbHzs;
+    private final float[] mElevations;
+    private final float[] mAzimuths;
+    private final float[] mCarrierFrequencies;
+
+    private GnssStatus(int svCount, int[] svidWithFlags, float[] cn0DbHzs, float[] elevations,
             float[] azimuths, float[] carrierFrequencies) {
         mSvCount = svCount;
         mSvidWithFlags = svidWithFlags;
-        mCn0DbHz = cn0s;
+        mCn0DbHzs = cn0DbHzs;
         mElevations = elevations;
         mAzimuths = azimuths;
         mCarrierFrequencies = carrierFrequencies;
@@ -129,6 +148,7 @@
     /**
      * Gets the total number of satellites in satellite list.
      */
+    @IntRange(from = 0)
     public int getSatelliteCount() {
         return mSvCount;
     }
@@ -136,11 +156,11 @@
     /**
      * Retrieves the constellation type of the satellite at the specified index.
      *
-     * @param satIndex the index of the satellite in the list.
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
      */
     @ConstellationType
-    public int getConstellationType(int satIndex) {
-        return ((mSvidWithFlags[satIndex] >> CONSTELLATION_TYPE_SHIFT_WIDTH)
+    public int getConstellationType(@IntRange(from = 0) int satelliteIndex) {
+        return ((mSvidWithFlags[satelliteIndex] >> CONSTELLATION_TYPE_SHIFT_WIDTH)
                 & CONSTELLATION_TYPE_MASK);
     }
 
@@ -158,110 +178,113 @@
      * <li>SBAS: 120-151, 183-192</li>
      * <li>GLONASS: One of: OSN, or FCN+100
      * <ul>
-     *   <li>1-24 as the orbital slot number (OSN) (preferred, if known)</li>
-     *   <li>93-106 as the frequency channel number (FCN) (-7 to +6) plus 100.
-     *   i.e. encode FCN of -7 as 93, 0 as 100, and +6 as 106</li>
+     * <li>1-24 as the orbital slot number (OSN) (preferred, if known)</li>
+     * <li>93-106 as the frequency channel number (FCN) (-7 to +6) plus 100.
+     * i.e. encode FCN of -7 as 93, 0 as 100, and +6 as 106</li>
      * </ul></li>
      * <li>QZSS: 193-200</li>
      * <li>Galileo: 1-36</li>
      * <li>Beidou: 1-37</li>
      * </ul>
      *
-     * @param satIndex the index of the satellite in the list.
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
      */
-    public int getSvid(int satIndex) {
-        return mSvidWithFlags[satIndex] >> SVID_SHIFT_WIDTH;
+    @IntRange(from = 1, to = 200)
+    public int getSvid(@IntRange(from = 0) int satelliteIndex) {
+        return mSvidWithFlags[satelliteIndex] >> SVID_SHIFT_WIDTH;
     }
 
     /**
      * Retrieves the carrier-to-noise density at the antenna of the satellite at the specified index
      * in dB-Hz.
      *
-     * @param satIndex the index of the satellite in the list.
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
      */
-    public float getCn0DbHz(int satIndex) {
-        return mCn0DbHz[satIndex];
+    @FloatRange(from = 0, to = 63)
+    public float getCn0DbHz(@IntRange(from = 0) int satelliteIndex) {
+        return mCn0DbHzs[satelliteIndex];
     }
 
     /**
      * Retrieves the elevation of the satellite at the specified index.
      *
-     * @param satIndex the index of the satellite in the list.
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
      */
-    public float getElevationDegrees(int satIndex) {
-        return mElevations[satIndex];
+    @FloatRange(from = -90, to = 90)
+    public float getElevationDegrees(@IntRange(from = 0) int satelliteIndex) {
+        return mElevations[satelliteIndex];
     }
 
     /**
      * Retrieves the azimuth the satellite at the specified index.
      *
-     * @param satIndex the index of the satellite in the list.
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
      */
-    public float getAzimuthDegrees(int satIndex) {
-        return mAzimuths[satIndex];
+    @FloatRange(from = 0, to = 360)
+    public float getAzimuthDegrees(@IntRange(from = 0) int satelliteIndex) {
+        return mAzimuths[satelliteIndex];
     }
 
     /**
      * Reports whether the satellite at the specified index has ephemeris data.
      *
-     * @param satIndex the index of the satellite in the list.
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
      */
-    public boolean hasEphemerisData(int satIndex) {
-        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0;
+    public boolean hasEphemerisData(@IntRange(from = 0) int satelliteIndex) {
+        return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_HAS_EPHEMERIS_DATA) != 0;
     }
 
     /**
      * Reports whether the satellite at the specified index has almanac data.
      *
-     * @param satIndex the index of the satellite in the list.
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
      */
-    public boolean hasAlmanacData(int satIndex) {
-        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0;
+    public boolean hasAlmanacData(@IntRange(from = 0) int satelliteIndex) {
+        return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_HAS_ALMANAC_DATA) != 0;
     }
 
     /**
      * Reports whether the satellite at the specified index was used in the calculation of the most
      * recent position fix.
      *
-     * @param satIndex the index of the satellite in the list.
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
      */
-    public boolean usedInFix(int satIndex) {
-        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_USED_IN_FIX) != 0;
+    public boolean usedInFix(@IntRange(from = 0) int satelliteIndex) {
+        return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_USED_IN_FIX) != 0;
     }
 
     /**
-     * Reports whether a valid {@link #getCarrierFrequencyHz(int satIndex)} is available.
+     * Reports whether a valid {@link #getCarrierFrequencyHz(int satelliteIndex)} is available.
      *
-     * @param satIndex the index of the satellite in the list.
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
      */
-    public boolean hasCarrierFrequencyHz(int satIndex) {
-        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) != 0;
+    public boolean hasCarrierFrequencyHz(@IntRange(from = 0) int satelliteIndex) {
+        return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_HAS_CARRIER_FREQUENCY) != 0;
     }
 
     /**
      * Gets the carrier frequency of the signal tracked.
      *
-     * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz,
-     * L5 = 1176.45 MHz, varying GLO channels, etc. If the field is not set, it is the primary
+     * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60
+     * MHz, L5 = 1176.45 MHz, varying GLO channels, etc. If the field is not set, it is the primary
      * common use central frequency, e.g. L1 = 1575.45 MHz for GPS.
      *
      * For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two measurements
-     * will be reported for this same satellite, in one all the values related to L1 will be filled,
-     * and in the other all of the values related to L5 will be filled.
+     * will be reported for this same satellite, in one all the values related to L1 will be
+     * filled, and in the other all of the values related to L5 will be filled.
      *
-     * <p>The value is only available if {@link #hasCarrierFrequencyHz(int satIndex)} is {@code true}.
+     * <p>The value is only available if {@link #hasCarrierFrequencyHz(int satelliteIndex)} is
+     * {@code true}.
      *
-     * @param satIndex the index of the satellite in the list.
-     *
-     * @return the carrier frequency of the signal tracked in Hz.
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
      */
-    public float getCarrierFrequencyHz(int satIndex) {
-        return mCarrierFrequencies[satIndex];
+    @FloatRange(from = 0)
+    public float getCarrierFrequencyHz(@IntRange(from = 0) int satelliteIndex) {
+        return mCarrierFrequencies[satelliteIndex];
     }
 
     /**
-     * Returns the string representation of a constellation type. For example,
-     * {@link #CONSTELLATION_GPS} is represented by the string GPS.
+     * Returns the string representation of a constellation type.
      *
      * @param constellationType the constellation type.
      * @return the string representation.
@@ -290,4 +313,108 @@
                 return Integer.toString(constellationType);
         }
     }
+
+    /**
+     * Builder class to help create new GnssStatus instances.
+     */
+    public static final class Builder {
+
+        private final ArrayList<GnssSvInfo> mSatellites = new ArrayList<>();
+
+        /**
+         * Adds a new satellite to the Builder.
+         *
+         * @param constellationType one of the CONSTELLATION_* constants
+         * @param svid the space vehicle identifier
+         * @param cn0DbHz carrier-to-noise density at the antenna in dB-Hz
+         * @param elevation satellite elevation in degrees
+         * @param azimuth satellite azimuth in degrees
+         * @param hasEphemeris whether the satellite has ephemeris data
+         * @param hasAlmanac whether the satellite has almanac data
+         * @param usedInFix whether the satellite was used in the most recent location fix
+         * @param hasCarrierFrequency whether carrier frequency data is available
+         * @param carrierFrequency satellite carrier frequency in Hz
+         */
+        @NonNull
+        public Builder addSatellite(@ConstellationType int constellationType,
+                @IntRange(from = 1, to = 200) int svid,
+                @FloatRange(from = 0, to = 63) float cn0DbHz,
+                @FloatRange(from = -90, to = 90) float elevation,
+                @FloatRange(from = 0, to = 360) float azimuth,
+                boolean hasEphemeris,
+                boolean hasAlmanac,
+                boolean usedInFix,
+                boolean hasCarrierFrequency,
+                @FloatRange(from = 0) float carrierFrequency) {
+            mSatellites.add(new GnssSvInfo(constellationType, svid, cn0DbHz, elevation, azimuth,
+                    hasEphemeris, hasAlmanac, usedInFix, hasCarrierFrequency, carrierFrequency));
+            return this;
+        }
+
+        /**
+         * Clears all satellites in the Builder.
+         */
+        @NonNull
+        public Builder clearSatellites() {
+            mSatellites.clear();
+            return this;
+        }
+
+        /**
+         * Builds a new GnssStatus based on the satellite information in the Builder.
+         */
+        @NonNull
+        public GnssStatus build() {
+            int svCount = mSatellites.size();
+            int[] svidWithFlags = new int[svCount];
+            float[] cn0DbHzs = new float[svCount];
+            float[] elevations = new float[svCount];
+            float[] azimuths = new float[svCount];
+            float[] carrierFrequencies = new float[svCount];
+
+            for (int i = 0; i < svidWithFlags.length; i++) {
+                svidWithFlags[i] = mSatellites.get(i).mSvidWithFlags;
+            }
+            for (int i = 0; i < cn0DbHzs.length; i++) {
+                cn0DbHzs[i] = mSatellites.get(i).mCn0DbHz;
+            }
+            for (int i = 0; i < elevations.length; i++) {
+                elevations[i] = mSatellites.get(i).mElevation;
+            }
+            for (int i = 0; i < azimuths.length; i++) {
+                azimuths[i] = mSatellites.get(i).mAzimuth;
+            }
+            for (int i = 0; i < carrierFrequencies.length; i++) {
+                carrierFrequencies[i] = mSatellites.get(i).mCarrierFrequency;
+            }
+
+            return wrap(svCount, svidWithFlags, cn0DbHzs, elevations, azimuths,
+                    carrierFrequencies);
+        }
+    }
+
+    private static class GnssSvInfo {
+
+        private final int mSvidWithFlags;
+        private final float mCn0DbHz;
+        private final float mElevation;
+        private final float mAzimuth;
+        private final float mCarrierFrequency;
+
+        private GnssSvInfo(int constellationType, int svid, float cn0DbHz,
+                float elevation, float azimuth, boolean hasEphemeris, boolean hasAlmanac,
+                boolean usedInFix, boolean hasCarrierFrequency, float carrierFrequency) {
+            mSvidWithFlags = (svid << SVID_SHIFT_WIDTH)
+                    | ((constellationType & CONSTELLATION_TYPE_MASK)
+                    << CONSTELLATION_TYPE_SHIFT_WIDTH)
+                    | (hasEphemeris ? SVID_FLAGS_HAS_EPHEMERIS_DATA : SVID_FLAGS_NONE)
+                    | (hasAlmanac ? SVID_FLAGS_HAS_ALMANAC_DATA : SVID_FLAGS_NONE)
+                    | (usedInFix ? SVID_FLAGS_USED_IN_FIX : SVID_FLAGS_NONE)
+                    | (hasCarrierFrequency ? SVID_FLAGS_HAS_CARRIER_FREQUENCY : SVID_FLAGS_NONE);
+            mCn0DbHz = cn0DbHz;
+            mElevation = elevation;
+            mAzimuth = azimuth;
+            mCarrierFrequency = carrierFrequency;
+        }
+    }
 }
diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java
index 609a15e..496885c 100644
--- a/location/java/android/location/GpsStatus.java
+++ b/location/java/android/location/GpsStatus.java
@@ -16,8 +16,7 @@
 
 package android.location;
 
-import android.annotation.UnsupportedAppUsage;
-import android.os.Build;
+import android.annotation.NonNull;
 import android.util.SparseArray;
 
 import java.util.Iterator;
@@ -25,20 +24,18 @@
 
 
 /**
- * This class represents the current state of the GPS engine.
+ * This class represents the current state of the GPS engine and is used in conjunction with {@link
+ * GpsStatus.Listener}.
  *
- * <p>This class is used in conjunction with the {@link Listener} interface.
- *
- * @deprecated use {@link GnssStatus} and {@link GnssStatus.Callback}.
+ * @deprecated Use {@link GnssStatus} instead.
  */
 @Deprecated
 public final class GpsStatus {
-    private static final int NUM_SATELLITES = 255;
+    private static final int MAX_SATELLITES = 255;
     private static final int GLONASS_SVID_OFFSET = 64;
     private static final int BEIDOU_SVID_OFFSET = 200;
     private static final int SBAS_SVID_OFFSET = -87;
 
-    /* These package private values are modified by the LocationManager class */
     private int mTimeToFirstFix;
     private final SparseArray<GpsSatellite> mSatellites = new SparseArray<>();
 
@@ -80,12 +77,7 @@
         }
     }
 
-    private Iterable<GpsSatellite> mSatelliteList = new Iterable<GpsSatellite>() {
-        @Override
-        public Iterator<GpsSatellite> iterator() {
-            return new SatelliteIterator();
-        }
-    };
+    private Iterable<GpsSatellite> mSatelliteList = SatelliteIterator::new;
 
     /**
      * Event sent when the GPS system has started.
@@ -111,7 +103,8 @@
 
     /**
      * Used for receiving notifications when GPS status has changed.
-     * @deprecated use {@link GnssStatus.Callback} instead.
+     *
+     * @deprecated Use {@link GnssStatus.Callback} instead.
      */
     @Deprecated
     public interface Listener {
@@ -148,17 +141,31 @@
         void onNmeaReceived(long timestamp, String nmea);
     }
 
-    // For API-compat a public ctor() is not available
-    GpsStatus() {}
+    /**
+     * Builds a GpsStatus from the given GnssStatus.
+     */
+    @NonNull
+    public static GpsStatus create(@NonNull GnssStatus gnssStatus, int timeToFirstFix) {
+        GpsStatus status = new GpsStatus();
+        status.setStatus(gnssStatus, timeToFirstFix);
+        return status;
+    }
 
-    private void setStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations,
-            float[] azimuths) {
-        clearSatellites();
-        for (int i = 0; i < svCount; i++) {
-            final int constellationType =
-                    (svidWithFlags[i] >> GnssStatus.CONSTELLATION_TYPE_SHIFT_WIDTH)
-                    & GnssStatus.CONSTELLATION_TYPE_MASK;
-            int prn = svidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH;
+    private GpsStatus() {
+    }
+
+    /**
+     * @hide
+     */
+    void setStatus(GnssStatus status, int timeToFirstFix) {
+        for (int i = 0; i < mSatellites.size(); i++) {
+            mSatellites.valueAt(i).mValid = false;
+        }
+
+        mTimeToFirstFix = timeToFirstFix;
+        for (int i = 0; i < status.getSatelliteCount(); i++) {
+            int constellationType = status.getConstellationType(i);
+            int prn = status.getSvid(i);
             // Other satellites passed through these APIs before GnssSvStatus was availble.
             // GPS, SBAS & QZSS can pass through at their nominally
             // assigned prn number (as long as it fits in the valid 0-255 range below.)
@@ -175,45 +182,27 @@
                     (constellationType != GnssStatus.CONSTELLATION_QZSS)) {
                 continue;
             }
-            if (prn > 0 && prn <= NUM_SATELLITES) {
-                GpsSatellite satellite = mSatellites.get(prn);
-                if (satellite == null) {
-                    satellite = new GpsSatellite(prn);
-                    mSatellites.put(prn, satellite);
-                }
-
-                satellite.mValid = true;
-                satellite.mSnr = cn0s[i];
-                satellite.mElevation = elevations[i];
-                satellite.mAzimuth = azimuths[i];
-                satellite.mHasEphemeris =
-                        (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0;
-                satellite.mHasAlmanac =
-                        (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0;
-                satellite.mUsedInFix =
-                        (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0;
+            if (prn <= 0 || prn > MAX_SATELLITES) {
+                continue;
             }
+
+            GpsSatellite satellite = mSatellites.get(prn);
+            if (satellite == null) {
+                satellite = new GpsSatellite(prn);
+                mSatellites.put(prn, satellite);
+            }
+
+            satellite.mValid = true;
+            satellite.mSnr = status.getCn0DbHz(i);
+            satellite.mElevation = status.getElevationDegrees(i);
+            satellite.mAzimuth = status.getAzimuthDegrees(i);
+            satellite.mHasEphemeris = status.hasEphemerisData(i);
+            satellite.mHasAlmanac = status.hasAlmanacData(i);
+            satellite.mUsedInFix = status.usedInFix(i);
         }
     }
 
     /**
-     * Copies GPS satellites information from GnssStatus object.
-     * Since this method is only used within {@link LocationManager#getGpsStatus},
-     * it does not need to be synchronized.
-     * @hide
-     */
-    void setStatus(GnssStatus status, int timeToFirstFix) {
-        mTimeToFirstFix = timeToFirstFix;
-        setStatus(status.mSvCount, status.mSvidWithFlags, status.mCn0DbHz, status.mElevations,
-                status.mAzimuths);
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    void setTimeToFirstFix(int ttff) {
-        mTimeToFirstFix = ttff;
-    }
-
-    /**
      * Returns the time required to receive the first fix since the most recent
      * restart of the GPS engine.
      *
@@ -240,14 +229,7 @@
      * @return the maximum number of satellites
      */
     public int getMaxSatellites() {
-        return NUM_SATELLITES;
+        return mSatellites.size();
     }
 
-    private void clearSatellites() {
-        int satellitesCount = mSatellites.size();
-        for (int i = 0; i < satellitesCount; i++) {
-            GpsSatellite satellite = mSatellites.valueAt(i);
-            satellite.mValid = false;
-        }
-    }
 }
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 5030e66..75e1cd4 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1818,15 +1818,14 @@
             Log.w(TAG, ex);
         }
 
-        if (status == null) {
-            status = new GpsStatus();
-        }
-        // When mGnssStatus is null, that means that this method is called outside
-        // onGpsStatusChanged().  Return an empty status to maintain backwards compatibility.
         GnssStatus gnssStatus = mGnssStatusListenerManager.getGnssStatus();
         int ttff = mGnssStatusListenerManager.getTtff();
         if (gnssStatus != null) {
-            status.setStatus(gnssStatus, ttff);
+            if (status == null) {
+                status = GpsStatus.create(gnssStatus, ttff);
+            } else {
+                status.setStatus(gnssStatus, ttff);
+            }
         }
         return status;
     }
@@ -2820,8 +2819,8 @@
             @Override
             public void onSvStatusChanged(int svCount, int[] svidWithFlags, float[] cn0s,
                     float[] elevations, float[] azimuths, float[] carrierFreqs) {
-                GnssStatus localStatus = new GnssStatus(svCount, svidWithFlags, cn0s, elevations,
-                        azimuths, carrierFreqs);
+                GnssStatus localStatus = GnssStatus.wrap(svCount, svidWithFlags, cn0s,
+                        elevations, azimuths, carrierFreqs);
                 mGnssStatus = localStatus;
                 execute((callback) -> callback.onSatelliteStatusChanged(localStatus));
             }
diff --git a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
index 07bfe02..e0bff74 100644
--- a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
+++ b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
@@ -188,22 +188,18 @@
 
     /**
     * Logs sv status data
-    *
-    * @param svCount
-    * @param svidWithFlags
-    * @param svCarrierFreqs
     */
-    public void logSvStatus(int svCount, int[] svidWithFlags, float[] svCarrierFreqs) {
+    public void logSvStatus(GnssStatus status) {
         boolean isL5 = false;
         // Calculate SvStatus Information
-        for (int i = 0; i < svCount; i++) {
-            if ((svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) != 0) {
+        for (int i = 0; i < status.getSatelliteCount(); i++) {
+            if (status.hasCarrierFrequencyHz(i)) {
                 mNumSvStatus++;
-                isL5 = isL5Sv(svCarrierFreqs[i]);
+                isL5 = isL5Sv(status.getCarrierFrequencyHz(i));
                 if (isL5) {
                     mNumL5SvStatus++;
                 }
-                if ((svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
+                if (status.usedInFix(i)) {
                     mNumSvStatusUsedInFix++;
                     if (isL5) {
                         mNumL5SvStatusUsedInFix++;
@@ -211,15 +207,10 @@
                 }
             }
         }
-        return;
     }
 
     /**
     * Logs CN0 when at least 4 SVs are available L5 Only
-    *
-    * @param svCount
-    * @param cn0s
-    * @param svCarrierFreqs
     */
     private void logCn0L5(int svCount, float[] cn0s, float[] svCarrierFreqs) {
         if (svCount == 0 || cn0s == null || cn0s.length == 0 || cn0s.length < svCount
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index da8e402..5ac6f7f 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -506,6 +506,26 @@
     public static final int WHITEBALANCE_AUTO = 0;
     public static final int WHITEBALANCE_MANUAL = 1;
 
+    /**
+     * Constant used to indicate that the input stream contains the full image data.
+     * <p>
+     * The format of the image data should follow one of the image formats supported by this class.
+     */
+    public static final int STREAM_TYPE_FULL_IMAGE_DATA = 0;
+    /**
+     * Constant used to indicate that the input stream contains only Exif data.
+     * <p>
+     * The format of the Exif-only data must follow the below structure:
+     *     Exif Identifier Code ("Exif\0\0") + TIFF header + IFD data
+     * See JEITA CP-3451C Section 4.5.2 and 4.5.4 specifications for more details.
+     */
+    public static final int STREAM_TYPE_EXIF_DATA_ONLY = 1;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({STREAM_TYPE_FULL_IMAGE_DATA, STREAM_TYPE_EXIF_DATA_ONLY})
+    public @interface ExifStreamType {}
+
     // Maximum size for checking file type signature (see image_type_recognition_lite.cc)
     private static final int SIGNATURE_CHECK_SIZE = 5000;
 
@@ -1416,7 +1436,7 @@
     private AssetManager.AssetInputStream mAssetInputStream;
     private boolean mIsInputStream;
     private int mMimeType;
-    private boolean mIsStandalone;
+    private boolean mIsExifDataOnly;
     @UnsupportedAppUsage
     private final HashMap[] mAttributes = new HashMap[EXIF_TAGS.length];
     private Set<Integer> mHandledIfdOffsets = new HashSet<>(EXIF_TAGS.length);
@@ -1444,6 +1464,11 @@
 
     /**
      * Reads Exif tags from the specified image file.
+     *
+     * @param file the file of the image data
+     * @throws NullPointerException if file is null
+     * @throws IOException if an I/O error occurs while retrieving file descriptor via
+     *         {@link FileInputStream#getFD()}.
      */
     public ExifInterface(@NonNull File file) throws IOException {
         if (file == null) {
@@ -1454,6 +1479,11 @@
 
     /**
      * Reads Exif tags from the specified image file.
+     *
+     * @param filename the name of the file of the image data
+     * @throws NullPointerException if file name is null
+     * @throws IOException if an I/O error occurs while retrieving file descriptor via
+     *         {@link FileInputStream#getFD()}.
      */
     public ExifInterface(@NonNull String filename) throws IOException {
         if (filename == null) {
@@ -1466,6 +1496,11 @@
      * Reads Exif tags from the specified image file descriptor. Attribute mutation is supported
      * for writable and seekable file descriptors only. This constructor will not rewind the offset
      * of the given file descriptor. Developers should close the file descriptor after use.
+     *
+     * @param fileDescriptor the file descriptor of the image data
+     * @throws NullPointerException if file descriptor is null
+     * @throws IOException if an error occurs while duplicating the file descriptor via
+     *         {@link Os#dup(FileDescriptor)}.
      */
     public ExifInterface(@NonNull FileDescriptor fileDescriptor) throws IOException {
         if (fileDescriptor == null) {
@@ -1504,45 +1539,46 @@
     /**
      * Reads Exif tags from the specified image input stream. Attribute mutation is not supported
      * for input streams. The given input stream will proceed from its current position. Developers
-     * should close the input stream after use.
+     * should close the input stream after use. This constructor is not intended to be used with an
+     * input stream that performs any networking operations.
+     *
+     * @param inputStream the input stream that contains the image data
+     * @throws NullPointerException if the input stream is null
      */
     public ExifInterface(@NonNull InputStream inputStream) throws IOException {
         this(inputStream, false);
     }
 
     /**
-     * Reads Exif tags from the specified standalone input stream. Standalone data refers to Exif
-     * data that exists by itself and is not contained in a file format such as jpeg or png.
-     * The format of the standalone data must follow the below structure:
-     *     Exif Identifier Code ("Exif\0\0") + TIFF header + IFD data
-     * See JEITA CP-3451C Section 4.5.2 and 4.5.4 specifications for more details.
-     * <p>
-     * Attribute mutation is not supported for this constructor. The given input stream will proceed
-     * from its current position. Developers should close the input stream after use. This
-     * constructor is not intended to be used with an input stream that performs any networking
-     * operations.
+     * Reads Exif tags from the specified image input stream based on the stream type. Attribute
+     * mutation is not supported for input streams. The given input stream will proceed from its
+     * current position. Developers should close the input stream after use. This constructor is not
+     * intended to be used with an input stream that performs any networking operations.
      *
-     * @throws IOException if the data does not follow the aforementioned structure.
+     * @param inputStream the input stream that contains the image data
+     * @param streamType the type of input stream
+     * @throws NullPointerException if the input stream is null
+     * @throws IOException if an I/O error occurs while retrieving file descriptor via
+     *         {@link FileInputStream#getFD()}.
      */
-    @NonNull
-    public static ExifInterface fromStandalone(@NonNull InputStream inputStream)
+    public ExifInterface(@NonNull InputStream inputStream, @ExifStreamType int streamType)
             throws IOException {
-        if (isStandalone(inputStream)) {
-            return new ExifInterface(inputStream, true);
-        }
-        throw new IOException("Given data does not follow the structure of a standalone exif "
-                + "data.");
+        this(inputStream, (streamType == STREAM_TYPE_EXIF_DATA_ONLY) ? true : false);
     }
 
-    private ExifInterface(@NonNull InputStream inputStream, boolean isFromStandalone)
+    private ExifInterface(@NonNull InputStream inputStream, boolean shouldBeExifDataOnly)
             throws IOException {
         if (inputStream == null) {
             throw new NullPointerException("inputStream cannot be null");
         }
         mFilename = null;
 
-        if (isFromStandalone) {
-            mIsStandalone = true;
+        if (shouldBeExifDataOnly) {
+            if (!isExifDataOnly(inputStream)) {
+                Log.w(TAG, "Given data does not follow the structure of an Exif-only data.");
+                return;
+            }
+            mIsExifDataOnly = true;
             mAssetInputStream = null;
             mSeekableFileDescriptor = null;
         } else {
@@ -1880,10 +1916,9 @@
 
     /**
      * This function decides which parser to read the image data according to the given input stream
-     * type and the content of the input stream. In each case, it reads the first three bytes to
-     * determine whether the image data format is JPEG or not.
+     * type and the content of the input stream.
      */
-    private void loadAttributes(@NonNull InputStream in) throws IOException {
+    private void loadAttributes(@NonNull InputStream in) {
         if (in == null) {
             throw new NullPointerException("inputstream shouldn't be null");
         }
@@ -1894,7 +1929,7 @@
             }
 
             // Check file type
-            if (!mIsStandalone) {
+            if (!mIsExifDataOnly) {
                 in = new BufferedInputStream(in, SIGNATURE_CHECK_SIZE);
                 mMimeType = getMimeType((BufferedInputStream) in);
             }
@@ -1902,7 +1937,7 @@
             // Create byte-ordered input stream
             ByteOrderedDataInputStream inputStream = new ByteOrderedDataInputStream(in);
 
-            if (!mIsStandalone) {
+            if (!mIsExifDataOnly) {
                 switch (mMimeType) {
                     case IMAGE_TYPE_JPEG: {
                         getJpegAttributes(inputStream, 0, IFD_TYPE_PRIMARY); // 0 is offset
@@ -1969,11 +2004,14 @@
         }
     }
 
-    private static boolean isSeekableFD(FileDescriptor fd) throws IOException {
+    private static boolean isSeekableFD(FileDescriptor fd) {
         try {
             Os.lseek(fd, 0, OsConstants.SEEK_CUR);
             return true;
         } catch (ErrnoException e) {
+            if (DEBUG) {
+                Log.d(TAG, "The file descriptor for the given input is not seekable");
+            }
             return false;
         }
     }
@@ -2239,7 +2277,7 @@
         }
 
         if (mHasThumbnail) {
-            if (mIsStandalone) {
+            if (mIsExifDataOnly) {
                 return new long[] { mThumbnailOffset + mExifOffset, mThumbnailLength };
             }
             return new long[] { mThumbnailOffset, mThumbnailLength };
@@ -2703,16 +2741,20 @@
         return true;
     }
 
-    private static boolean isStandalone(InputStream inputStream) throws IOException {
-        byte[] signatureCheckBytes = new byte[IDENTIFIER_EXIF_APP1.length];
-        inputStream.read(signatureCheckBytes);
-
-        for (int i = 0; i < IDENTIFIER_EXIF_APP1.length; i++) {
-            if (signatureCheckBytes[i] != IDENTIFIER_EXIF_APP1[i]) {
-                return false;
+    private static boolean isExifDataOnly(InputStream inputStream) {
+        try {
+            byte[] signatureCheckBytes = new byte[IDENTIFIER_EXIF_APP1.length];
+            inputStream.read(signatureCheckBytes);
+            if (Arrays.equals(signatureCheckBytes, IDENTIFIER_EXIF_APP1)) {
+                return true;
+            }
+        } catch (IOException e) {
+            if (DEBUG) {
+                Log.w(TAG,
+                        "Encountered error while checking whether input stream is Exif data only");
             }
         }
-        return true;
+        return false;
     }
 
     /**
diff --git a/media/java/android/media/tv/OWNER b/media/java/android/media/tv/OWNER
deleted file mode 100644
index 64c0bb5..0000000
--- a/media/java/android/media/tv/OWNER
+++ /dev/null
@@ -1,5 +0,0 @@
-amyjojo@google.com
-nchalko@google.com
-shubang@google.com
-quxiangfang@google.com
-
diff --git a/media/java/android/media/tv/OWNERS b/media/java/android/media/tv/OWNERS
index 4a03b3c..64c0bb5 100644
--- a/media/java/android/media/tv/OWNERS
+++ b/media/java/android/media/tv/OWNERS
@@ -1,2 +1,5 @@
+amyjojo@google.com
 nchalko@google.com
+shubang@google.com
+quxiangfang@google.com
 
diff --git a/media/java/android/media/tv/tuner/FrontendSettings.java b/media/java/android/media/tv/tuner/FrontendSettings.java
new file mode 100644
index 0000000..3782cc6
--- /dev/null
+++ b/media/java/android/media/tv/tuner/FrontendSettings.java
@@ -0,0 +1,274 @@
+/*
+ * 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 android.media.tv.tuner;
+
+import android.media.tv.tuner.TunerConstants.FrontendSettingsType;
+
+import java.util.List;
+
+/**
+ * @hide
+ */
+public abstract class FrontendSettings {
+    protected int mFrequency;
+
+    /**
+     * Returns the frontend type.
+     */
+    @FrontendSettingsType
+    public abstract int getType();
+
+    public int getFrequency() {
+        return mFrequency;
+    }
+
+    // TODO: use hal constants for enum fields
+    // TODO: javaDoc
+    // TODO: add builders and getters for other settings type
+
+    /**
+     * Frontend settings for analog.
+     */
+    public static class FrontendAnalogSettings extends FrontendSettings {
+        private int mAnalogType;
+        private int mSifStandard;
+
+        @Override
+        public int getType() {
+            return TunerConstants.FRONTEND_TYPE_ANALOG;
+        }
+
+        public int getAnalogType() {
+            return mAnalogType;
+        }
+
+        public int getSifStandard() {
+            return mSifStandard;
+        }
+
+        /**
+         * Creates a new builder object.
+         */
+        public static Builder newBuilder() {
+            return new Builder();
+        }
+
+        private FrontendAnalogSettings(int frequency, int analogType, int sifStandard) {
+            mFrequency = frequency;
+            mAnalogType = analogType;
+            mSifStandard = sifStandard;
+        }
+
+        /**
+         * Builder for FrontendAnalogSettings.
+         */
+        public static class Builder {
+            private int mFrequency;
+            private int mAnalogType;
+            private int mSifStandard;
+
+            private Builder() {}
+
+            /**
+             * Sets frequency.
+             */
+            public Builder setFrequency(int frequency) {
+                mFrequency = frequency;
+                return this;
+            }
+
+            /**
+             * Sets analog type.
+             */
+            public Builder setAnalogType(int analogType) {
+                mAnalogType = analogType;
+                return this;
+            }
+
+            /**
+             * Sets sif standard.
+             */
+            public Builder setSifStandard(int sifStandard) {
+                mSifStandard = sifStandard;
+                return this;
+            }
+
+            /**
+             * Builds a FrontendAnalogSettings instance.
+             */
+            public FrontendAnalogSettings build() {
+                return new FrontendAnalogSettings(mFrequency, mAnalogType, mSifStandard);
+            }
+        }
+    }
+
+    /**
+     * Frontend settings for ATSC.
+     */
+    public static class FrontendAtscSettings extends FrontendSettings {
+        public int modulation;
+
+        @Override
+        public int getType() {
+            return TunerConstants.FRONTEND_TYPE_ATSC;
+        }
+    }
+
+    /**
+     * Frontend settings for ATSC-3.
+     */
+    public static class FrontendAtsc3Settings extends FrontendSettings {
+        public int bandwidth;
+        public byte demodOutputFormat;
+        public List<FrontendAtsc3PlpSettings> plpSettings;
+
+        @Override
+        public int getType() {
+            return TunerConstants.FRONTEND_TYPE_ATSC3;
+        }
+    }
+
+    /**
+     * Frontend settings for DVBS.
+     */
+    public static class FrontendDvbsSettings extends FrontendSettings {
+        public int modulation;
+        public FrontendDvbsCodeRate coderate;
+        public int symbolRate;
+        public int rolloff;
+        public int pilot;
+        public int inputStreamId;
+        public byte standard;
+
+        @Override
+        public int getType() {
+            return TunerConstants.FRONTEND_TYPE_DVBS;
+        }
+    }
+
+    /**
+     * Frontend settings for DVBC.
+     */
+    public static class FrontendDvbcSettings extends FrontendSettings {
+        public int modulation;
+        public long fec;
+        public int symbolRate;
+        public int outerFec;
+        public byte annex;
+        public int spectralInversion;
+
+        @Override
+        public int getType() {
+            return TunerConstants.FRONTEND_TYPE_DVBC;
+        }
+    }
+
+    /**
+     * Frontend settings for DVBT.
+     */
+    public static class FrontendDvbtSettings extends FrontendSettings {
+        public int transmissionMode;
+        public int bandwidth;
+        public int constellation;
+        public int hierarchy;
+        public int hpCoderate;
+        public int lpCoderate;
+        public int guardInterval;
+        public boolean isHighPriority;
+        public byte standard;
+        public boolean isMiso;
+        public int plpMode;
+        public byte plpId;
+        public byte plpGroupId;
+
+        @Override
+        public int getType() {
+            return TunerConstants.FRONTEND_TYPE_DVBT;
+        }
+    }
+
+    /**
+     * Frontend settings for ISDBS.
+     */
+    public static class FrontendIsdbsSettings extends FrontendSettings {
+        public int streamId;
+        public int streamIdType;
+        public int modulation;
+        public int coderate;
+        public int symbolRate;
+        public int rolloff;
+
+        @Override
+        public int getType() {
+            return TunerConstants.FRONTEND_TYPE_ISDBS;
+        }
+    }
+
+    /**
+     * Frontend settings for ISDBS-3.
+     */
+    public static class FrontendIsdbs3Settings extends FrontendSettings {
+        public int streamId;
+        public int streamIdType;
+        public int modulation;
+        public int coderate;
+        public int symbolRate;
+        public int rolloff;
+
+        @Override
+        public int getType() {
+            return TunerConstants.FRONTEND_TYPE_ISDBS3;
+        }
+    }
+
+    /**
+     * Frontend settings for ISDBT.
+     */
+    public static class FrontendIsdbtSettings extends FrontendSettings {
+        public int modulation;
+        public int bandwidth;
+        public int coderate;
+        public int guardInterval;
+        public int serviceAreaId;
+
+        @Override
+        public int getType() {
+            return TunerConstants.FRONTEND_TYPE_ISDBT;
+        }
+    }
+
+    /**
+     * PLP settings for ATSC-3.
+     */
+    public static class FrontendAtsc3PlpSettings {
+        public byte plpId;
+        public int modulation;
+        public int interleaveMode;
+        public int codeRate;
+        public int fec;
+    }
+
+    /**
+     * Code rate for DVBS.
+     */
+    public static class FrontendDvbsCodeRate {
+        public long fec;
+        public boolean isLinear;
+        public boolean isShortFrames;
+        public int bitsPer1000Symbol;
+    }
+}
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index c91325a..82cef2e 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -16,6 +16,7 @@
 
 package android.media.tv.tuner;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.media.tv.tuner.TunerConstants.DemuxPidType;
 import android.os.Handler;
@@ -78,6 +79,7 @@
      * Native method to open frontend of the given ID.
      */
     private native Frontend nativeOpenFrontendById(int id);
+    private native int nativeTune(int type, FrontendSettings settings);
 
     private native Filter nativeOpenFilter(int type, int subType, int bufferSize);
 
@@ -207,6 +209,13 @@
         }
     }
 
+    /**
+     * Tunes the frontend to using the settings given.
+     */
+    public int tune(@NonNull FrontendSettings settings) {
+        return nativeTune(settings.getType(), settings);
+    }
+
     private List<Integer> getFrontendIds() {
         mFrontendIds = nativeGetFrontendIds();
         return mFrontendIds;
diff --git a/media/java/android/media/tv/tuner/TunerConstants.java b/media/java/android/media/tv/tuner/TunerConstants.java
index 01f9367..458cb16 100644
--- a/media/java/android/media/tv/tuner/TunerConstants.java
+++ b/media/java/android/media/tv/tuner/TunerConstants.java
@@ -75,6 +75,21 @@
     public static final int DEMUX_T_PID = 1;
     public static final int DEMUX_MMPT_PID = 2;
 
+    @IntDef({FRONTEND_SETTINGS_ANALOG, FRONTEND_SETTINGS_ATSC, FRONTEND_SETTINGS_ATSC3,
+            FRONTEND_SETTINGS_DVBS, FRONTEND_SETTINGS_DVBC, FRONTEND_SETTINGS_DVBT,
+            FRONTEND_SETTINGS_ISDBS, FRONTEND_SETTINGS_ISDBS3, FRONTEND_SETTINGS_ISDBT})
+    public @interface FrontendSettingsType {}
+
+    public static final int FRONTEND_SETTINGS_ANALOG = 1;
+    public static final int FRONTEND_SETTINGS_ATSC = 2;
+    public static final int FRONTEND_SETTINGS_ATSC3 = 3;
+    public static final int FRONTEND_SETTINGS_DVBS = 4;
+    public static final int FRONTEND_SETTINGS_DVBC = 5;
+    public static final int FRONTEND_SETTINGS_DVBT = 6;
+    public static final int FRONTEND_SETTINGS_ISDBS = 7;
+    public static final int FRONTEND_SETTINGS_ISDBS3 = 8;
+    public static final int FRONTEND_SETTINGS_ISDBT = 9;
+
     private TunerConstants() {
     }
 }
diff --git a/media/jni/android_media_MediaDataSource.cpp b/media/jni/android_media_MediaDataSource.cpp
index 9705b91..0cb4b2d 100644
--- a/media/jni/android_media_MediaDataSource.cpp
+++ b/media/jni/android_media_MediaDataSource.cpp
@@ -26,7 +26,6 @@
 #include <nativehelper/JNIHelp.h>
 
 #include <binder/MemoryDealer.h>
-#include <drm/drm_framework_common.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <nativehelper/ScopedLocalRef.h>
 
@@ -161,8 +160,4 @@
     return String8::format("JMediaDataSource(pid %d, uid %d)", getpid(), getuid());
 }
 
-sp<DecryptHandle> JMediaDataSource::DrmInitialization(const char * /* mime */) {
-    return NULL;
-}
-
 }  // namespace android
diff --git a/media/jni/android_media_MediaDataSource.h b/media/jni/android_media_MediaDataSource.h
index 39405d2..378baf4 100644
--- a/media/jni/android_media_MediaDataSource.h
+++ b/media/jni/android_media_MediaDataSource.h
@@ -47,7 +47,6 @@
     virtual void close();
     virtual uint32_t getFlags();
     virtual String8 toString();
-    virtual sp<DecryptHandle> DrmInitialization(const char *mime);
 
 private:
     // Protect all member variables with mLock because this object will be
diff --git a/media/jni/android_media_MediaDrm.h b/media/jni/android_media_MediaDrm.h
index 3cfa65d..b1f544c 100644
--- a/media/jni/android_media_MediaDrm.h
+++ b/media/jni/android_media_MediaDrm.h
@@ -47,7 +47,7 @@
                         const ListenerArgs *args) = 0;
 };
 
-struct JDrm : public BnDrmClient {
+struct JDrm : public IDrmClient {
     static status_t IsCryptoSchemeSupported(const uint8_t uuid[16],
                                             const String8 &mimeType,
                                             DrmPlugin::SecurityLevel level,
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index f5202fc..5216906 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -31,6 +31,9 @@
 using ::android::hardware::tv::tuner::V1_0::DemuxMmtpPid;
 using ::android::hardware::tv::tuner::V1_0::DemuxTpid;
 using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
+using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSettings;
+using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSifStandard;
+using ::android::hardware::tv::tuner::V1_0::FrontendAnalogType;
 using ::android::hardware::tv::tuner::V1_0::ITuner;
 using ::android::hardware::tv::tuner::V1_0::Result;
 
@@ -263,6 +266,15 @@
             id);
 }
 
+int JTuner::tune(const FrontendSettings& settings) {
+    if (mFe == NULL) {
+        ALOGE("frontend is not initialized");
+        return (int)Result::INVALID_STATE;
+    }
+    Result result = mFe->tune(settings);
+    return (int)result;
+}
+
 bool JTuner::openDemux() {
     if (mTuner == nullptr) {
         return false;
@@ -417,6 +429,32 @@
     return demuxPid;
 }
 
+static FrontendSettings getFrontendSettings(JNIEnv *env, int type, jobject settings) {
+    FrontendSettings frontendSettings;
+    jclass clazz = env->FindClass("android/media/tv/tuner/FrontendSettings");
+    jfieldID freqField = env->GetFieldID(clazz, "frequency", "I");
+    uint32_t freq = static_cast<uint32_t>(env->GetIntField(clazz, freqField));
+
+    // TODO: handle the other 8 types of settings
+    if (type == 1) {
+        // analog
+        clazz = env->FindClass("android/media/tv/tuner/FrontendSettings$FrontendAnalogSettings");
+        FrontendAnalogType analogType =
+                static_cast<FrontendAnalogType>(
+                        env->GetIntField(settings, env->GetFieldID(clazz, "mAnalogType", "I")));
+        FrontendAnalogSifStandard sifStandard =
+                static_cast<FrontendAnalogSifStandard>(
+                        env->GetIntField(settings, env->GetFieldID(clazz, "mSifStandard", "I")));
+        FrontendAnalogSettings frontendAnalogSettings {
+                .frequency = freq,
+                .type = analogType,
+                .sifStandard = sifStandard,
+        };
+        frontendSettings.analog(frontendAnalogSettings);
+    }
+    return frontendSettings;
+}
+
 static sp<IFilter> getFilter(JNIEnv *env, jobject filter) {
     return (IFilter *)env->GetLongField(filter, gFields.filterContext);
 }
@@ -476,6 +514,11 @@
     return tuner->openFrontendById(id);
 }
 
+static int android_media_tv_Tuner_tune(JNIEnv *env, jobject thiz, jint type, jobject settings) {
+    sp<JTuner> tuner = getTuner(env, thiz);
+    return tuner->tune(getFrontendSettings(env, type, settings));
+}
+
 static jobject android_media_tv_Tuner_get_lnb_ids(JNIEnv *env, jobject thiz) {
     sp<JTuner> tuner = getTuner(env, thiz);
     return tuner->getLnbIds();
@@ -612,6 +655,8 @@
             (void *)android_media_tv_Tuner_get_frontend_ids },
     { "nativeOpenFrontendById", "(I)Landroid/media/tv/tuner/Tuner$Frontend;",
             (void *)android_media_tv_Tuner_open_frontend_by_id },
+    { "nativeTune", "(ILandroid/media/tv/tuner/FrontendSettings;)I",
+            (void *)android_media_tv_Tuner_tune },
     { "nativeOpenFilter", "(III)Landroid/media/tv/tuner/Tuner$Filter;",
             (void *)android_media_tv_Tuner_open_filter },
     { "nativeGetLnbIds", "()Ljava/util/List;",
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index 3bf6ec8..f856791 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -34,6 +34,7 @@
 using ::android::hardware::tv::tuner::V1_0::FrontendId;
 using ::android::hardware::tv::tuner::V1_0::FrontendScanMessage;
 using ::android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
+using ::android::hardware::tv::tuner::V1_0::FrontendSettings;
 using ::android::hardware::tv::tuner::V1_0::IDemux;
 using ::android::hardware::tv::tuner::V1_0::IDescrambler;
 using ::android::hardware::tv::tuner::V1_0::IDvr;
@@ -95,6 +96,7 @@
     sp<ITuner> getTunerService();
     jobject getFrontendIds();
     jobject openFrontendById(int id);
+    int tune(const FrontendSettings& settings);
     jobject getLnbIds();
     jobject openLnbById(int id);
     jobject openFilter(DemuxFilterType type, int bufferSize);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index 87a59df..f979fdd 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -284,11 +284,12 @@
             ICameraDeviceCallbacks dummyCallbacks = new DummyCameraDeviceCallbacks();
 
             String clientPackageName = getContext().getPackageName();
+            String clientFeatureId = getContext().getFeatureId();
 
             ICameraDeviceUser cameraUser =
                     mUtils.getCameraService().connectDevice(
                         dummyCallbacks, String.valueOf(cameraId),
-                        clientPackageName,
+                        clientPackageName, clientFeatureId,
                         ICameraService.USE_CALLING_UID);
             assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
index 30561ba..466c5f4 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -238,11 +238,12 @@
         ICameraDeviceCallbacks.Stub dummyCallbacks = new DummyCameraDeviceCallbacks();
 
         String clientPackageName = getContext().getPackageName();
+        String clientFeatureId = getContext().getFeatureId();
 
         mMockCb = spy(dummyCallbacks);
 
         mCameraUser = mUtils.getCameraService().connectDevice(mMockCb, mCameraId,
-                clientPackageName, ICameraService.USE_CALLING_UID);
+                clientPackageName, clientFeatureId, ICameraService.USE_CALLING_UID);
         assertNotNull(String.format("Camera %s was null", mCameraId), mCameraUser);
         mHandlerThread = new HandlerThread(TAG);
         mHandlerThread.start();
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
index 240e7d1..d0f7c78 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
@@ -82,6 +82,11 @@
     public static final String CATEGORY_SPECIAL =
             "com.android.mediarouteprovider.CATEGORY_SPECIAL";
 
+    // system routes
+    private static final String DEFAULT_ROUTE_ID = "DEFAULT_ROUTE";
+    private static final String CATEGORY_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO";
+    private static final String CATEGORY_LIVE_VIDEO = "android.media.intent.category.LIVE_VIDEO";
+
     private static final int TIMEOUT_MS = 5000;
 
     private Context mContext;
@@ -90,13 +95,17 @@
     private Executor mExecutor;
     private String mPackageName;
 
-    private static final List<String> CONTROL_CATEGORIES_ALL = new ArrayList();
-    private static final List<String> CONTROL_CATEGORIES_SPECIAL = new ArrayList();
+    private static final List<String> CATEGORIES_ALL = new ArrayList();
+    private static final List<String> CATEGORIES_SPECIAL = new ArrayList();
+    private static final List<String> CATEGORIES_LIVE_AUDIO = new ArrayList<>();
     static {
-        CONTROL_CATEGORIES_ALL.add(CATEGORY_SAMPLE);
-        CONTROL_CATEGORIES_ALL.add(CATEGORY_SPECIAL);
+        CATEGORIES_ALL.add(CATEGORY_SAMPLE);
+        CATEGORIES_ALL.add(CATEGORY_SPECIAL);
+        CATEGORIES_ALL.add(CATEGORY_LIVE_AUDIO);
 
-        CONTROL_CATEGORIES_SPECIAL.add(CATEGORY_SPECIAL);
+        CATEGORIES_SPECIAL.add(CATEGORY_SPECIAL);
+
+        CATEGORIES_LIVE_AUDIO.add(CATEGORY_LIVE_AUDIO);
     }
 
     @Before
@@ -153,7 +162,7 @@
         mRouter2.registerCallback(mExecutor, routerCallback);
 
         Map<String, MediaRoute2Info> routes =
-                waitAndGetRoutesWithManager(CONTROL_CATEGORIES_ALL);
+                waitAndGetRoutesWithManager(CATEGORIES_ALL);
 
         CountDownLatch latch = new CountDownLatch(1);
         MediaRouter2Manager.Callback callback = new MediaRouter2Manager.Callback() {
@@ -187,7 +196,7 @@
         mManager.registerCallback(mExecutor, mockCallback);
 
         Map<String, MediaRoute2Info> routes =
-                waitAndGetRoutesWithManager(CONTROL_CATEGORIES_SPECIAL);
+                waitAndGetRoutesWithManager(CATEGORIES_SPECIAL);
 
         Assert.assertEquals(1, routes.size());
         Assert.assertNotNull(routes.get(ROUTE_ID_SPECIAL_CATEGORY));
@@ -203,7 +212,7 @@
         MediaRouter2.Callback mockCallback = mock(MediaRouter2.Callback.class);
         mRouter2.registerCallback(mExecutor, mockCallback);
 
-        Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CONTROL_CATEGORIES_SPECIAL);
+        Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CATEGORIES_SPECIAL);
 
         Assert.assertEquals(1, routes.size());
         Assert.assertNotNull(routes.get(ROUTE_ID_SPECIAL_CATEGORY));
@@ -219,7 +228,7 @@
         mManager.registerCallback(mExecutor, managerCallback);
         mRouter2.registerCallback(mExecutor, routerCallback);
 
-        Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(CONTROL_CATEGORIES_ALL);
+        Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(CATEGORIES_ALL);
 
         MediaRoute2Info routeToSelect = routes.get(ROUTE_ID1);
         assertNotNull(routeToSelect);
@@ -242,7 +251,7 @@
 
         mRouter2.registerCallback(mExecutor, routerCallback);
 
-        Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(CONTROL_CATEGORIES_ALL);
+        Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(CATEGORIES_ALL);
 
         awaitOnRouteChangedManager(
                 () -> mManager.selectRoute(mPackageName, routes.get(ROUTE_ID1)),
@@ -264,7 +273,7 @@
 
     @Test
     public void testControlVolumeWithRouter() throws Exception {
-        Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CONTROL_CATEGORIES_ALL);
+        Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CATEGORIES_ALL);
 
         MediaRoute2Info volRoute = routes.get(ROUTE_ID_VARIABLE_VOLUME);
         int originalVolume = volRoute.getVolume();
@@ -286,7 +295,7 @@
         MediaRouter2.Callback mockCallback = mock(MediaRouter2.Callback.class);
 
         mRouter2.registerCallback(mExecutor, mockCallback);
-        Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(CONTROL_CATEGORIES_ALL);
+        Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(CATEGORIES_ALL);
 
         MediaRoute2Info volRoute = routes.get(ROUTE_ID_VARIABLE_VOLUME);
         int originalVolume = volRoute.getVolume();
@@ -309,7 +318,7 @@
     public void testVolumeHandling() throws Exception {
         MediaRouter2.Callback mockCallback = mock(MediaRouter2.Callback.class);
         mRouter2.registerCallback(mExecutor, mockCallback);
-        Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CONTROL_CATEGORIES_ALL);
+        Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CATEGORIES_ALL);
 
         MediaRoute2Info fixedVolumeRoute = routes.get(ROUTE_ID_FIXED_VOLUME);
         MediaRoute2Info variableVolumeRoute = routes.get(ROUTE_ID_VARIABLE_VOLUME);
@@ -321,6 +330,13 @@
         mRouter2.unregisterCallback(mockCallback);
     }
 
+    @Test
+    public void testDefaultRoute() throws Exception {
+        Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CATEGORIES_LIVE_AUDIO);
+
+        assertNotNull(routes.get(DEFAULT_ROUTE_ID));
+    }
+
     Map<String, MediaRoute2Info> waitAndGetRoutes(List<String> controlCategories) throws Exception {
         CountDownLatch latch = new CountDownLatch(1);
         MediaRouter2.Callback callback = new MediaRouter2.Callback() {
@@ -417,6 +433,7 @@
     static Map<String, MediaRoute2Info> createRouteMap(List<MediaRoute2Info> routes) {
         Map<String, MediaRoute2Info> routeMap = new HashMap<>();
         for (MediaRoute2Info route : routes) {
+            // intentionally not route.getUniqueId() for convenience.
             routeMap.put(route.getId(), route);
         }
         return routeMap;
diff --git a/packages/CarSystemUI/res/layout/car_ongoing_privacy_chip.xml b/packages/CarSystemUI/res/layout/car_ongoing_privacy_chip.xml
deleted file mode 100644
index 918abd9..0000000
--- a/packages/CarSystemUI/res/layout/car_ongoing_privacy_chip.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     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.
--->
-
-<com.android.systemui.statusbar.car.privacy.OngoingPrivacyChip
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/car_privacy_chip"
-    android:layout_width="wrap_content"
-    android:layout_height="match_parent"
-    android:layout_margin="@dimen/ongoing_appops_chip_margin"
-    android:layout_toStartOf="@+id/clock_container"
-    android:focusable="true"
-    android:gravity="center_vertical|end"
-    android:orientation="horizontal"
-    android:paddingEnd="@dimen/ongoing_appops_chip_side_padding"
-    android:paddingStart="@dimen/ongoing_appops_chip_side_padding"
-    android:visibility="visible">
-
-    <LinearLayout
-        android:id="@+id/icons_container"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:gravity="center_vertical|start"/>
-</com.android.systemui.statusbar.car.privacy.OngoingPrivacyChip>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml
index 7299ddf..ce0d31c 100644
--- a/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml
+++ b/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml
@@ -65,8 +65,6 @@
             />
         </FrameLayout>
 
-        <include layout="@layout/car_ongoing_privacy_chip"/>
-
         <FrameLayout
             android:id="@+id/clock_container"
             android:layout_width="wrap_content"
diff --git a/packages/CarSystemUI/res/values/dimens.xml b/packages/CarSystemUI/res/values/dimens.xml
index e2da91b..ee79653 100644
--- a/packages/CarSystemUI/res/values/dimens.xml
+++ b/packages/CarSystemUI/res/values/dimens.xml
@@ -59,18 +59,6 @@
     <dimen name="car_keyline_1">24dp</dimen>
     <dimen name="car_keyline_2">96dp</dimen>
     <dimen name="car_keyline_3">128dp</dimen>
-    <dimen name="privacy_chip_icon_height">36dp</dimen>
-    <dimen name="privacy_chip_icon_padding_left">0dp</dimen>
-    <dimen name="privacy_chip_icon_padding_right">0dp</dimen>
-    <dimen name="privacy_chip_icon_padding_top">0dp</dimen>
-    <dimen name="privacy_chip_icon_padding_bottom">0dp</dimen>
-
-    <dimen name="privacy_chip_text_padding_left">0dp</dimen>
-    <dimen name="privacy_chip_text_padding_right">0dp</dimen>
-    <dimen name="privacy_chip_text_padding_top">0dp</dimen>
-    <dimen name="privacy_chip_text_padding_bottom">0dp</dimen>
-
-    <dimen name="privacy_chip_icon_max_height">100dp</dimen>
 
     <!-- Height of icons in Ongoing App Ops dialog. Both App Op icon and application icon -->
     <dimen name="ongoing_appops_dialog_icon_height">48dp</dimen>
@@ -86,16 +74,6 @@
     <dimen name="ongoing_appops_chip_bg_padding">4dp</dimen>
     <!-- Radius of Ongoing App Ops chip corners -->
     <dimen name="ongoing_appops_chip_bg_corner_radius">12dp</dimen>
-    <!-- Start padding for the app icon displayed in the dialog -->
-    <dimen name="privacy_dialog_app_icon_padding_start">40dp</dimen>
-    <!-- End padding for the app opps icon displayed in the dialog -->
-    <dimen name="privacy_dialog_app_ops_icon_padding_end">40dp</dimen>
-    <!-- Top padding for the list of application displayed in the dialog -->
-    <dimen name="privacy_dialog_app_list_padding_top">20dp</dimen>
-    <!-- Top padding for the dialog container-->
-    <dimen name="privacy_dialog_container_padding_top">10dp</dimen>
-    <!-- Top padding for the dialog title-->
-    <dimen name="privacy_dialog_title_padding_start">10dp</dimen>
 
     <!-- Car volume dimens. -->
     <dimen name="car_volume_item_icon_size">@dimen/car_primary_icon_size</dimen>
diff --git a/packages/CarSystemUI/res/values/integers_car.xml b/packages/CarSystemUI/res/values/integers_car.xml
index d6c16cb..e53446e 100644
--- a/packages/CarSystemUI/res/values/integers_car.xml
+++ b/packages/CarSystemUI/res/values/integers_car.xml
@@ -20,11 +20,6 @@
     <!-- Full screen user switcher column number TODO: move to support library-->
     <integer name="user_fullscreen_switcher_num_col">3</integer>
 
-    <!-- Number of milliseconds user can spend driving with the keyguard up. After that, we switch to Guest. -->
-    <!-- If the number is negative, the feature is disabled.
-         If it's zero, we switch to guest immediately as we start driving. -->
-    <integer name="driving_on_keyguard_timeout_ms">-1</integer>
-
     <!--Percentage of the screen height, from the bottom, that a notification panel being
     partially closed at will result in it remaining open if released-->
     <integer name="notification_settle_open_percentage">20</integer>
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index 818fdea..bffc6b9 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -26,6 +26,7 @@
 import com.android.systemui.dagger.SystemUIRootComponent;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dock.DockManagerImpl;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.EnhancedEstimates;
 import com.android.systemui.power.EnhancedEstimatesImpl;
 import com.android.systemui.recents.Recents;
@@ -38,10 +39,13 @@
 import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.volume.CarVolumeDialogComponent;
 import com.android.systemui.volume.VolumeDialogComponent;
 
@@ -84,6 +88,17 @@
 
     @Singleton
     @Provides
+    static HeadsUpManagerPhone provideHeadsUpManagerPhone(Context context,
+            StatusBarStateController statusBarStateController,
+            KeyguardBypassController bypassController) {
+        return new HeadsUpManagerPhone(context, statusBarStateController, bypassController);
+    }
+
+    @Binds
+    abstract HeadsUpManager bindHeadsUpManagerPhone(HeadsUpManagerPhone headsUpManagerPhone);
+
+    @Singleton
+    @Provides
     @Named(LEAK_REPORT_EMAIL_NAME)
     static String provideLeakReportEmail() {
         return "buganizer-system+181579@google.com";
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 10527b2..bef769d 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -24,7 +24,6 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.car.Car;
-import android.car.drivingstate.CarDrivingStateEvent;
 import android.car.drivingstate.CarUxRestrictionsManager;
 import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
 import android.content.Context;
@@ -96,12 +95,12 @@
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.NewNotifPipeline;
 import com.android.systemui.statusbar.notification.NotificationAlertingManager;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.collection.init.NewNotifPipeline;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.phone.AutoHideController;
@@ -114,6 +113,7 @@
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 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.NotificationGroupAlertTransferHelper;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -121,6 +121,7 @@
 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.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -153,7 +154,10 @@
     private static final float FLING_ANIMATION_MAX_TIME = 0.5f;
     // acceleration rate for the fling animation
     private static final float FLING_SPEED_UP_FACTOR = 0.6f;
+
     private final ScrimController mScrimController;
+    private final StatusBarWindowViewController mStatusBarWindowViewController;
+    private final LockscreenLockIconController mLockscreenLockIconController;
 
     private float mOpeningVelocity = DEFAULT_FLING_VELOCITY;
     private float mClosingVelocity = DEFAULT_FLING_VELOCITY;
@@ -175,10 +179,8 @@
     private final CarServiceProvider mCarServiceProvider;
 
     private DeviceProvisionedController mDeviceProvisionedController;
-    private DrivingStateHelper mDrivingStateHelper;
     private PowerManagerHelper mPowerManagerHelper;
     private FlingAnimationUtils mFlingAnimationUtils;
-    private SwitchToGuestTimer mSwitchToGuestTimer;
     private NotificationDataManager mNotificationDataManager;
     private NotificationClickHandlerFactory mNotificationClickHandlerFactory;
     private ScreenLifecycle mScreenLifecycle;
@@ -287,7 +289,8 @@
             NotificationListener notificationListener,
             ConfigurationController configurationController,
             StatusBarWindowController statusBarWindowController,
-            StatusBarWindowViewController.Builder statusBarWindowViewControllerBuild,
+            StatusBarWindowViewController statusBarWindowViewController,
+            LockscreenLockIconController lockscreenLockIconController,
             DozeParameters dozeParameters,
             ScrimController scrimController,
             Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
@@ -304,6 +307,8 @@
             Optional<Divider> dividerOptional,
             SuperStatusBarViewFactory superStatusBarViewFactory,
             LightsOutNotifController lightsOutNotifController,
+            StatusBarNotificationActivityStarter.Builder
+                    statusBarNotificationActivityStarterBuilder,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             ViewMediatorCallback viewMediatorCallback,
             DismissCallbackRegistry dismissCallbackRegistry,
@@ -363,7 +368,8 @@
                 notificationListener,
                 configurationController,
                 statusBarWindowController,
-                statusBarWindowViewControllerBuild,
+                statusBarWindowViewController,
+                lockscreenLockIconController,
                 dozeParameters,
                 scrimController,
                 null /* keyguardLiftController */,
@@ -380,11 +386,14 @@
                 remoteInputUriController,
                 dividerOptional,
                 lightsOutNotifController,
+                statusBarNotificationActivityStarterBuilder,
                 superStatusBarViewFactory,
                 statusBarKeyguardViewManager,
                 viewMediatorCallback,
                 dismissCallbackRegistry);
         mScrimController = scrimController;
+        mStatusBarWindowViewController = statusBarWindowViewController;
+        mLockscreenLockIconController = lockscreenLockIconController;
         mDeviceProvisionedController = deviceProvisionedController;
         mCarServiceProvider = carServiceProvider;
         mDrivingStateHelperLazy = drivingStateHelperLazy;
@@ -400,22 +409,22 @@
         mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
         mScreenLifecycle.addObserver(mScreenObserver);
 
-      	// Notification bar related setup.
+        // Notification bar related setup.
         mInitialBackgroundAlpha = (float) mContext.getResources().getInteger(
-            R.integer.config_initialNotificationBackgroundAlpha) / 100;
+                R.integer.config_initialNotificationBackgroundAlpha) / 100;
         if (mInitialBackgroundAlpha < 0 || mInitialBackgroundAlpha > 100) {
             throw new RuntimeException(
-              "Unable to setup notification bar due to incorrect initial background alpha"
-                      + " percentage");
+                    "Unable to setup notification bar due to incorrect initial background alpha"
+                            + " percentage");
         }
         float finalBackgroundAlpha = Math.max(
-            mInitialBackgroundAlpha,
-            (float) mContext.getResources().getInteger(
-                R.integer.config_finalNotificationBackgroundAlpha) / 100);
+                mInitialBackgroundAlpha,
+                (float) mContext.getResources().getInteger(
+                        R.integer.config_finalNotificationBackgroundAlpha) / 100);
         if (finalBackgroundAlpha < 0 || finalBackgroundAlpha > 100) {
             throw new RuntimeException(
-              "Unable to setup notification bar due to incorrect final background alpha"
-                      + " percentage");
+                    "Unable to setup notification bar due to incorrect final background alpha"
+                            + " percentage");
         }
         mBackgroundAlphaDiff = finalBackgroundAlpha - mInitialBackgroundAlpha;
 
@@ -432,15 +441,6 @@
         createBatteryController();
         mCarBatteryController.startListening();
 
-        // Used by onDrivingStateChanged and it can be called inside
-        // DrivingStateHelper.connectToCarService()
-        mSwitchToGuestTimer = new SwitchToGuestTimer(mContext);
-
-        // Register a listener for driving state changes.
-        mDrivingStateHelper = mDrivingStateHelperLazy.get();
-        mDrivingStateHelper.setCarDrivingStateEventListener(this::onDrivingStateChanged);
-        mDrivingStateHelper.connectToCarService();
-
         mPowerManagerHelper = mPowerManagerHelperLazy.get();
         mPowerManagerHelper.setCarPowerStateListener(mCarPowerStateListener);
         mPowerManagerHelper.connectToCarService();
@@ -560,13 +560,6 @@
         });
         CarNotificationListener carNotificationListener = new CarNotificationListener();
         mCarUxRestrictionManagerWrapper = new CarUxRestrictionManagerWrapper();
-        mCarServiceProvider.addListener(car -> {
-            CarUxRestrictionsManager carUxRestrictionsManager =
-                    (CarUxRestrictionsManager)
-                            car.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
-            mCarUxRestrictionManagerWrapper.setCarUxRestrictionsManager(
-                    carUxRestrictionsManager);
-        });
 
         mNotificationDataManager = new NotificationDataManager();
         mNotificationDataManager.setOnUnseenCountUpdateListener(
@@ -681,14 +674,21 @@
                 return handled || isTracking;
             }
         });
+        mCarServiceProvider.addListener(car -> {
+            CarUxRestrictionsManager carUxRestrictionsManager =
+                    (CarUxRestrictionsManager)
+                            car.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
+            mCarUxRestrictionManagerWrapper.setCarUxRestrictionsManager(
+                    carUxRestrictionsManager);
 
-        mNotificationViewController = new NotificationViewController(
-                mNotificationView,
-                PreprocessingManager.getInstance(mContext),
-                carNotificationListener,
-                mCarUxRestrictionManagerWrapper,
-                mNotificationDataManager);
-        mNotificationViewController.enable();
+                    mNotificationViewController = new NotificationViewController(
+                            mNotificationView,
+                            PreprocessingManager.getInstance(mContext),
+                            carNotificationListener,
+                            mCarUxRestrictionManagerWrapper,
+                            mNotificationDataManager);
+                    mNotificationViewController.enable();
+        });
     }
 
     /**
@@ -906,20 +906,6 @@
         }
     }
 
-    private void onDrivingStateChanged(CarDrivingStateEvent notUsed) {
-        // Check if we need to start the timer every time driving state changes.
-        startSwitchToGuestTimerIfDrivingOnKeyguard();
-    }
-
-    private void startSwitchToGuestTimerIfDrivingOnKeyguard() {
-        if (mDrivingStateHelper.isCurrentlyDriving() && mState != StatusBarState.SHADE) {
-            // We're driving while keyguard is up.
-            mSwitchToGuestTimer.start();
-        } else {
-            mSwitchToGuestTimer.cancel();
-        }
-    }
-
     @Override
     protected void createUserSwitcher() {
         UserSwitcherController userSwitcherController =
@@ -945,8 +931,6 @@
     public void onStateChanged(int newState) {
         super.onStateChanged(newState);
 
-        startSwitchToGuestTimerIfDrivingOnKeyguard();
-
         if (newState != StatusBarState.FULLSCREEN_USER_SWITCHER) {
             hideUserSwitcher();
         } else {
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 5418ebe..6529868 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
@@ -56,12 +56,12 @@
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.NewNotifPipeline;
 import com.android.systemui.statusbar.notification.NotificationAlertingManager;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.collection.init.NewNotifPipeline;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.phone.AutoHideController;
@@ -73,12 +73,14 @@
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 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.NotificationGroupAlertTransferHelper;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.ScrimController;
 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.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -160,7 +162,8 @@
             NotificationListener notificationListener,
             ConfigurationController configurationController,
             StatusBarWindowController statusBarWindowController,
-            StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder,
+            StatusBarWindowViewController statusBarWindowViewController,
+            LockscreenLockIconController lockscreenLockIconController,
             DozeParameters dozeParameters,
             ScrimController scrimController,
             Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
@@ -177,6 +180,8 @@
             Optional<Divider> dividerOptional,
             SuperStatusBarViewFactory superStatusBarViewFactory,
             LightsOutNotifController lightsOutNotifController,
+            StatusBarNotificationActivityStarter.Builder
+                    statusBarNotificationActivityStarterBuilder,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             ViewMediatorCallback viewMediatorCallback,
             DismissCallbackRegistry dismissCallbackRegistry,
@@ -235,7 +240,8 @@
                 notificationListener,
                 configurationController,
                 statusBarWindowController,
-                statusBarWindowViewControllerBuilder,
+                statusBarWindowViewController,
+                lockscreenLockIconController,
                 dozeParameters,
                 scrimController,
                 lockscreenWallpaperLazy,
@@ -252,6 +258,7 @@
                 dividerOptional,
                 superStatusBarViewFactory,
                 lightsOutNotifController,
+                statusBarNotificationActivityStarterBuilder,
                 statusBarKeyguardViewManager,
                 viewMediatorCallback,
                 dismissCallbackRegistry,
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java
deleted file mode 100644
index 0c91cba..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.car;
-
-import android.car.userlib.CarUserManagerHelper;
-import android.content.Context;
-import android.os.CountDownTimer;
-import android.util.Log;
-
-import androidx.annotation.GuardedBy;
-
-import com.android.systemui.R;
-
-/**
- * Wrapper for a countdown timer that switches to Guest if the user has been driving with
- * the keyguard up for configurable number of seconds.
- */
-public class SwitchToGuestTimer {
-    private static final String TAG = "SwitchToGuestTimer";
-
-    // After how many ms CountdownTimer.onTick gets triggered.
-    private static final int COUNTDOWN_INTERVAL_MS = 1000;
-
-    private final CarUserManagerHelper mCarUserManagerHelper;
-    private final Object mTimerLock;
-    private final String mGuestName;
-    private final int mTimeoutMs;
-    private final boolean mEnabled;
-
-    @GuardedBy("mTimerLock")
-    private CountDownTimer mSwitchToGuestTimer;
-
-    public SwitchToGuestTimer(Context context) {
-        mCarUserManagerHelper = new CarUserManagerHelper(context);
-        mGuestName = context.getResources().getString(R.string.car_guest);
-        mTimeoutMs = context.getResources().getInteger(R.integer.driving_on_keyguard_timeout_ms);
-
-        // Lock prevents multiple timers being started.
-        mTimerLock = new Object();
-
-        // If milliseconds to switch is a negative number, the feature is disabled.
-        mEnabled = mTimeoutMs >= 0;
-    }
-
-    /**
-     * Starts the timer if it's not already running.
-     */
-    public void start() {
-        if (!mEnabled) {
-            logD("Switching to guest after driving on keyguard is disabled.");
-            return;
-        }
-
-        synchronized (mTimerLock) {
-            if (mSwitchToGuestTimer != null) {
-                logD("Timer is already running.");
-                return;
-            }
-
-            mSwitchToGuestTimer = new CountDownTimer(mTimeoutMs, COUNTDOWN_INTERVAL_MS) {
-                @Override
-                public void onTick(long msUntilFinished) {
-                    logD("Ms until switching to guest: " + Long.toString(msUntilFinished));
-                }
-
-                @Override
-                public void onFinish() {
-                    mCarUserManagerHelper.startGuestSession(mGuestName);
-                    cancel();
-                }
-            };
-
-            logI("Starting timer");
-            mSwitchToGuestTimer.start();
-        }
-    }
-
-    /**
-     * Cancels the running timer.
-     */
-    public void cancel() {
-        synchronized (mTimerLock) {
-            if (mSwitchToGuestTimer != null) {
-                logI("Cancelling timer");
-                mSwitchToGuestTimer.cancel();
-                mSwitchToGuestTimer = null;
-            }
-        }
-    }
-
-    private void logD(String message) {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, message);
-        }
-    }
-
-    private void logI(String message) {
-        if (Log.isLoggable(TAG, Log.INFO)) {
-            Log.i(TAG, message);
-        }
-    }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java
deleted file mode 100644
index 88d641e..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java
+++ /dev/null
@@ -1,225 +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.car.privacy;
-
-import android.app.ActivityManager;
-import android.app.AppOpsManager;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.R;
-import com.android.systemui.appops.AppOpItem;
-import com.android.systemui.appops.AppOpsController;
-import com.android.systemui.plugins.ActivityStarter;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-/**
- * Layout defining the privacy chip that will be displayed in CarStatusRar with the information for
- * which applications are using AppOpps permission fpr camera, mic and location.
- */
-public class OngoingPrivacyChip extends LinearLayout implements View.OnClickListener {
-
-    private Context mContext;
-    private Handler mHandler;
-
-    private LinearLayout mIconsContainer;
-    private List<PrivacyItem> mPrivacyItems;
-    private static AppOpsController sAppOpsController;
-    private UserManager mUserManager;
-    private int mCurrentUser;
-    private List<Integer> mCurrentUserIds;
-    private boolean mListening = false;
-    PrivacyDialogBuilder mPrivacyDialogBuilder;
-    private LinearLayout mPrivacyChip;
-    private ActivityStarter mActivityStarter;
-
-    protected static final int[] OPS = new int[]{
-            AppOpsManager.OP_CAMERA,
-            AppOpsManager.OP_RECORD_AUDIO,
-            AppOpsManager.OP_COARSE_LOCATION,
-            AppOpsManager.OP_FINE_LOCATION
-    };
-
-    public OngoingPrivacyChip(Context context) {
-        super(context, null);
-        init(context);
-    }
-
-    public OngoingPrivacyChip(Context context, AttributeSet attr) {
-        super(context, attr);
-        init(context);
-    }
-
-    public OngoingPrivacyChip(Context context, AttributeSet attr, int defStyle) {
-        super(context, attr, defStyle);
-        init(context);
-    }
-
-    public OngoingPrivacyChip(Context context, AttributeSet attr, int defStyle, int a) {
-        super(context, attr, defStyle, a);
-        init(context);
-    }
-
-    private void init(Context context) {
-        mContext = context;
-        mHandler = new Handler(Looper.getMainLooper());
-        mPrivacyItems = new ArrayList<>();
-        sAppOpsController = Dependency.get(AppOpsController.class);
-        mUserManager = mContext.getSystemService(UserManager.class);
-        mActivityStarter = Dependency.get(ActivityStarter.class);
-        mCurrentUser = ActivityManager.getCurrentUser();
-        mCurrentUserIds = mUserManager.getProfiles(mCurrentUser).stream().map(
-                userInfo -> userInfo.id).collect(Collectors.toList());
-
-        mPrivacyDialogBuilder = new PrivacyDialogBuilder(context, mPrivacyItems);
-    }
-
-    private AppOpsController.Callback mCallback = new AppOpsController.Callback() {
-
-        @Override
-        public void onActiveStateChanged(int code, int uid, String packageName, boolean active) {
-            int userId = UserHandle.getUserId(uid);
-            if (mCurrentUserIds.contains(userId)) {
-                updatePrivacyList();
-            }
-        }
-    };
-
-    @Override
-    public void onFinishInflate() {
-        mIconsContainer = findViewById(R.id.icons_container);
-        mPrivacyChip = (LinearLayout) findViewById(R.id.car_privacy_chip);
-        if (mPrivacyChip != null) {
-            mPrivacyChip.setOnClickListener(this);
-            setListening(true);
-        }
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        if (mPrivacyChip != null) {
-            setListening(false);
-        }
-        super.onDetachedFromWindow();
-    }
-
-    @Override
-    public void onClick(View v) {
-        updatePrivacyList();
-        mHandler.post(() -> {
-            mActivityStarter.postStartActivityDismissingKeyguard(
-                    new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0);
-        });
-    }
-
-    private void setListening(boolean listen) {
-        if (mListening == listen) {
-            return;
-        }
-        mListening = listen;
-        if (mListening) {
-            sAppOpsController.addCallback(OPS, mCallback);
-            updatePrivacyList();
-        } else {
-            sAppOpsController.removeCallback(OPS, mCallback);
-        }
-    }
-
-    private void updatePrivacyList() {
-        List<PrivacyItem> privacyItems = mCurrentUserIds.stream()
-                .flatMap(item -> sAppOpsController.getActiveAppOpsForUser(item).stream())
-                .filter(Objects::nonNull)
-                .map(item -> toPrivacyItem(item))
-                .filter(Objects::nonNull)
-                .collect(Collectors.toList());
-        if (!privacyItems.equals(mPrivacyItems)) {
-            mPrivacyItems = privacyItems;
-            mPrivacyDialogBuilder = new PrivacyDialogBuilder(mContext, mPrivacyItems);
-            mHandler.post(this::updateView);
-        }
-    }
-
-    private PrivacyItem toPrivacyItem(AppOpItem appOpItem) {
-        PrivacyType type;
-        switch (appOpItem.getCode()) {
-            case AppOpsManager.OP_CAMERA:
-                type = PrivacyType.TYPE_CAMERA;
-                break;
-            case AppOpsManager.OP_COARSE_LOCATION:
-                type = PrivacyType.TYPE_LOCATION;
-                break;
-            case AppOpsManager.OP_FINE_LOCATION:
-                type = PrivacyType.TYPE_LOCATION;
-                break;
-            case AppOpsManager.OP_RECORD_AUDIO:
-                type = PrivacyType.TYPE_MICROPHONE;
-                break;
-            default:
-                return null;
-        }
-        PrivacyApplication app = new PrivacyApplication(appOpItem.getPackageName(), mContext);
-        return new PrivacyItem(type, app, appOpItem.getTimeStarted());
-    }
-
-    // Should only be called if the mPrivacyDialogBuilder icons or app changed
-    private void updateView() {
-        if (mPrivacyItems.isEmpty()) {
-            mPrivacyChip.setVisibility(GONE);
-            return;
-        }
-        mPrivacyChip.setVisibility(VISIBLE);
-        setIcons(mPrivacyDialogBuilder);
-
-        requestLayout();
-    }
-
-    private void setIcons(PrivacyDialogBuilder dialogBuilder) {
-        mIconsContainer.removeAllViews();
-        dialogBuilder.generateIcons().forEach(item -> {
-            int size = mContext.getResources().getDimensionPixelSize(
-                    R.dimen.privacy_chip_icon_height);
-            ImageView image = new ImageView(mContext);
-            image.setImageDrawable(item);
-            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(size, size);
-
-            int leftPadding = mContext.getResources().getDimensionPixelSize(
-                    R.dimen.privacy_chip_icon_padding_left);
-            int topPadding = mContext.getResources().getDimensionPixelSize(
-                    R.dimen.privacy_chip_icon_padding_top);
-            int rightPadding = mContext.getResources().getDimensionPixelSize(
-                    R.dimen.privacy_chip_icon_padding_right);
-            int bottomPadding = mContext.getResources().getDimensionPixelSize(
-                    R.dimen.privacy_chip_icon_padding_bottom);
-            image.setLayoutParams(layoutParams);
-            image.setPadding(leftPadding, topPadding, rightPadding, bottomPadding);
-            mIconsContainer.addView(image);
-        });
-    }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java
deleted file mode 100644
index a5d3bf7..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java
+++ /dev/null
@@ -1,78 +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.car.privacy;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.util.Log;
-
-import java.util.Objects;
-
-/**
- * Class to hold the data for the applications that are using the AppOps permissions.
- */
-public class PrivacyApplication {
-    private static final String TAG = "PrivacyApplication";
-
-    private String mPackageName;
-    private Drawable mIcon;
-    private String mApplicationName;
-
-    public PrivacyApplication(String packageName, Context context) {
-        mPackageName = packageName;
-        try {
-            ApplicationInfo app = context.getPackageManager()
-                    .getApplicationInfoAsUser(packageName, 0,
-                            ActivityManager.getCurrentUser());
-            mIcon = context.getPackageManager().getApplicationIcon(app);
-            mApplicationName = context.getPackageManager().getApplicationLabel(app).toString();
-        } catch (PackageManager.NameNotFoundException e) {
-            mApplicationName = packageName;
-            Log.e(TAG, "Failed to to find package name", e);
-        }
-    }
-
-    /**
-     * Gets the application name.
-     */
-    public Drawable getIcon() {
-        return mIcon;
-    }
-
-    /**
-     * Gets the application name.
-     */
-    public String getApplicationName() {
-        return mApplicationName;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        PrivacyApplication that = (PrivacyApplication) o;
-        return mPackageName.equals(that.mPackageName);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mPackageName);
-    }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyDialogBuilder.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyDialogBuilder.java
deleted file mode 100644
index 3b83e7c..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyDialogBuilder.java
+++ /dev/null
@@ -1,59 +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.car.privacy;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-/**
- * Helper class to build the {@link OngoingPrivacyDialog}
- */
-public class PrivacyDialogBuilder {
-
-    private Map<PrivacyType, List<PrivacyItem>> mItemsByType;
-    private PrivacyApplication mApplication;
-    private Context mContext;
-
-    public PrivacyDialogBuilder(Context context, List<PrivacyItem> itemsList) {
-        mContext = context;
-        mItemsByType = itemsList.stream().filter(Objects::nonNull).collect(
-                Collectors.groupingBy(PrivacyItem::getPrivacyType));
-        List<PrivacyApplication> apps = itemsList.stream().filter(Objects::nonNull).map(
-                PrivacyItem::getPrivacyApplication).distinct().collect(Collectors.toList());
-        mApplication = apps.size() == 1 ? apps.get(0) : null;
-    }
-
-    /**
-     * Gets the icon id for all the {@link PrivacyItem} in the same order as of itemList.
-     */
-    public List<Drawable> generateIcons() {
-        return mItemsByType.keySet().stream().map(item -> item.getIconId(mContext)).collect(
-                Collectors.toList());
-    }
-
-    /**
-     * Gets the application object.
-     */
-    public PrivacyApplication getApplication() {
-        return mApplication;
-    }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java
deleted file mode 100644
index d3e123e..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java
+++ /dev/null
@@ -1,62 +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.car.privacy;
-
-import java.util.Objects;
-
-/**
- * Class for holding the data of each privacy item displayed in {@link OngoingPrivacyDialog}
- */
-public class PrivacyItem {
-
-    private PrivacyType mPrivacyType;
-    private PrivacyApplication mPrivacyApplication;
-
-    public PrivacyItem(PrivacyType privacyType, PrivacyApplication privacyApplication,
-            long timeStarted) {
-        this.mPrivacyType = privacyType;
-        this.mPrivacyApplication = privacyApplication;
-    }
-
-    /**
-     * Gets the application object.
-     */
-    public PrivacyApplication getPrivacyApplication() {
-        return mPrivacyApplication;
-    }
-
-    /**
-     * Gets the privacy type for the application.
-     */
-    public PrivacyType getPrivacyType() {
-        return mPrivacyType;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        PrivacyItem that = (PrivacyItem) o;
-        return mPrivacyType == that.mPrivacyType
-                && mPrivacyApplication.equals(that.mPrivacyApplication);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mPrivacyType, mPrivacyApplication);
-    }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyType.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyType.java
deleted file mode 100644
index 8955c87..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyType.java
+++ /dev/null
@@ -1,53 +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.car.privacy;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-
-import com.android.systemui.R;
-
-/**
- * Enum for storing data for camera, mic and location.
- */
-public enum PrivacyType {
-    TYPE_CAMERA(R.string.privacy_type_camera, com.android.internal.R.drawable.ic_camera),
-    TYPE_LOCATION(R.string.privacy_type_location, R.drawable.stat_sys_location),
-    TYPE_MICROPHONE(R.string.privacy_type_microphone, R.drawable.ic_mic_white);
-
-    private int mNameId;
-    private int mIconId;
-
-    PrivacyType(int nameId, int iconId) {
-        mNameId = nameId;
-        mIconId = iconId;
-    }
-
-    /**
-     * Get the icon Id.
-     */
-    public Drawable getIconId(Context context) {
-        return context.getResources().getDrawable(mIconId, null);
-    }
-
-    /**
-     * Get the name Id.
-     */
-    public String getNameId(Context context) {
-        return context.getResources().getString(mNameId);
-    }
-}
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
index 738c425..19ae970 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
@@ -102,9 +102,10 @@
             Thread thread =
                     new Thread(
                             () -> {
-                                mDynSystem.startInstallation("userdata", mUserdataSize, false);
+                                mDynSystem.startInstallation();
+                                mDynSystem.createPartition("userdata", mUserdataSize, false);
                                 mInstallationSession =
-                                        mDynSystem.startInstallation("system", mSystemSize, true);
+                                        mDynSystem.createPartition("system", mSystemSize, true);
                             });
 
             thread.start();
@@ -157,6 +158,7 @@
                     reportedInstalledSize = installedSize;
                 }
             }
+            mDynSystem.finishInstallation();
             return null;
 
         } catch (Exception e) {
diff --git a/packages/SettingsLib/HelpUtils/Android.bp b/packages/SettingsLib/HelpUtils/Android.bp
index af60185..285131d 100644
--- a/packages/SettingsLib/HelpUtils/Android.bp
+++ b/packages/SettingsLib/HelpUtils/Android.bp
@@ -4,6 +4,10 @@
     srcs: ["src/**/*.java"],
     resource_dirs: ["res"],
 
+    libs: [
+        "androidx.annotation_annotation",
+    ],
+
     sdk_version: "system_current",
     min_sdk_version: "21",
 }
diff --git a/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java b/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
index 2d13b73..a77683d 100644
--- a/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
+++ b/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
@@ -33,6 +33,8 @@
 import android.view.MenuItem;
 import android.view.MenuItem.OnMenuItemClickListener;
 
+import androidx.annotation.VisibleForTesting;
+
 import com.android.settingslib.widget.R;
 
 import java.net.URISyntaxException;
@@ -45,7 +47,8 @@
 public class HelpUtils {
     private final static String TAG = HelpUtils.class.getSimpleName();
 
-    private static final int MENU_HELP = Menu.FIRST + 100;
+    @VisibleForTesting
+    static final int MENU_HELP = Menu.FIRST + 100;
 
     /**
      * Help URL query parameter key for the preferred language.
@@ -68,11 +71,16 @@
      */
     private static String sCachedVersionCode = null;
 
-    /** Static helper that is not instantiable*/
-    private HelpUtils() { }
+    /** Static helper that is not instantiable */
+    private HelpUtils() {
+    }
 
     public static boolean prepareHelpMenuItem(Activity activity, Menu menu, String helpUri,
             String backupContext) {
+        // menu contains help item, skip it
+        if (menu.findItem(MENU_HELP) != null) {
+            return false;
+        }
         MenuItem helpItem = menu.add(0, MENU_HELP, 0, R.string.help_feedback_label);
         helpItem.setIcon(R.drawable.ic_help_actionbar);
         return prepareHelpMenuItem(activity, helpItem, helpUri, backupContext);
@@ -80,6 +88,10 @@
 
     public static boolean prepareHelpMenuItem(Activity activity, Menu menu, int helpUriResource,
             String backupContext) {
+        // menu contains help item, skip it
+        if (menu.findItem(MENU_HELP) != null) {
+            return false;
+        }
         MenuItem helpItem = menu.add(0, MENU_HELP, 0, R.string.help_feedback_label);
         helpItem.setIcon(R.drawable.ic_help_actionbar);
         return prepareHelpMenuItem(activity, helpItem, activity.getString(helpUriResource),
@@ -90,11 +102,12 @@
      * Prepares the help menu item by doing the following.
      * - If the helpUrlString is empty or null, the help menu item is made invisible.
      * - Otherwise, this makes the help menu item visible and sets the intent for the help menu
-     *   item to view the URL.
+     * item to view the URL.
      *
      * @return returns whether the help menu item has been made visible.
      */
-    public static boolean prepareHelpMenuItem(final Activity activity, MenuItem helpMenuItem,
+    @VisibleForTesting
+    static boolean prepareHelpMenuItem(final Activity activity, MenuItem helpMenuItem,
             String helpUriString, String backupContext) {
         if (Global.getInt(activity.getContentResolver(), Global.DEVICE_PROVISIONED, 0) == 0) {
             return false;
@@ -117,10 +130,10 @@
                         /**
                          * TODO: Enable metrics logger for @SystemApi (b/111552654)
                          *
-                        MetricsLogger.action(activity,
-                            MetricsEvent.ACTION_SETTING_HELP_AND_FEEDBACK,
-                            intent.getStringExtra(EXTRA_CONTEXT));
-                        */
+                         MetricsLogger.action(activity,
+                         MetricsEvent.ACTION_SETTING_HELP_AND_FEEDBACK,
+                         intent.getStringExtra(EXTRA_CONTEXT));
+                         */
                         try {
                             activity.startActivityForResult(intent, 0);
                         } catch (ActivityNotFoundException exc) {
@@ -212,6 +225,7 @@
     /**
      * Adds two query parameters into the Uri, namely the language code and the version code
      * of the app's package as gotten via the context.
+     *
      * @return the uri with added query parameters
      */
     private static Uri uriWithAddedParameters(Context context, Uri baseUri) {
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 97b2cb5..3ff5cf4 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Middelmatig"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Vinnig"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Baie vinnig"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Verval"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Ontkoppel"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ontkoppel tans…"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 62d5dca..264d8de 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"መካከለኛ"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"ፈጣን"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"እጅግ በጣም ፈጣን"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ጊዜው አልፏል"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"ተለያይቷል"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"በመለያየት ላይ..."</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index c786e09..c230236 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"متوسطة"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"سريعة"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"سريعة جدًا"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"منتهية الصلاحية"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"غير متصل"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"جارٍ قطع الاتصال..."</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 552fbb8..ab0ed29 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"মধ্যমীয়া"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"দ্ৰুত"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"অতি দ্ৰুত"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ম্যাদ উকলিছে"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"সংযোগ বিচ্ছিন্ন কৰা হ’ল"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"সংযোগ বিচ্ছিন্ন কৰি থকা হৈছে…"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 3af2e25..fe62d31 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Orta"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Sürətli"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Çox Sürətli"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vaxtı keçib"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Ayrıldı"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ayrılır..."</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 8a76242..1619584 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Srednja"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Brza"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Veoma brza"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Isteklo"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Veza je prekinuta"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prekidanje veze..."</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 5ed4495..0f2df49 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Сярэдняя"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Хуткая"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Вельмі хуткая"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Тэрмін скончыўся"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Адключана"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Адключэнне..."</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index f7a7153..a3be2812 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Средна"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Бърза"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Много бърза"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Изтекло"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Изкл."</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Изключва се..."</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index f4c677f..743de50 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"মাঝারি"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"দ্রুত"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"খুব দ্রুত"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"মেয়াদ শেষ হয়ে গেছে"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"ডিসকানেক্ট করা হয়েছে"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"ডিসকানেক্ট হচ্ছে..."</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index fc653b7..75a4047 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Srednja brzina"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Brzo"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Veoma brzo"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Istekao"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Isključen"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prekidanje veze…"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index f79375e..8627cf3 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Mitjana"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Ràpida"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Molt ràpida"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducat"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconnectat"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"S\'està desconnectant..."</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 64400a4..6fef07a 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Střední"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rychlá"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Velmi rychlá"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Platnost vypršela"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Odpojeno"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Odpojování..."</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index de7a228..80ee95e 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Middel"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Hurtig"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Meget hurtig"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Udløbet"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> – <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Afbrudt"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Afbryder ..."</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index eafe9d0..7dee120 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Μέτρια"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Γρήγορη"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Πολύ γρήγορη"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Έληξε"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Αποσυνδέθηκε"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Αποσύνδεση..."</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 840f5ee..41c817e 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Muy rápida"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vencido"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index c86eb34..897eaa3 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Muy rápida"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducado"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index f59b96a..9b94222 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Keskmine"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Kiire"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Väga kiire"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Aegunud"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Ühendus katkestatud"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ühenduse katkestamine ..."</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 9648139..b0e4b26 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Tartekoa"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Bizkorra"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Oso bizkorra"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Iraungita"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Deskonektatuta"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Deskonektatzen…"</string>
@@ -455,7 +454,7 @@
     <string name="cancel" msgid="5665114069455378395">"Utzi"</string>
     <string name="okay" msgid="949938843324579502">"Ados"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktibatu"</string>
-    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktibatu \"Ez molestatu\" modua"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktibatu ez molestatzeko modua"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Inoiz ez"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Lehentasuna dutenak soilik"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 3e8de97..7298826 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"متوسط"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"سریع"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"خیلی سریع"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"منقضی‌شده"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"اتصال قطع شد"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"در حال قطع اتصال..."</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 68ddf7d..6f58f03 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Kohtuullinen"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Nopea"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Hyvin nopea"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vanhentunut"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Yhteys katkaistu"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Katkaistaan yhteyttä..."</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index ef4800c..a5526f3 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Moyenne"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Élevée"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Très rapide"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expiré"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> : <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Déconnecté"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Déconnexion…"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 256ea03a..eaab027 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Moi rápida"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducou"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando..."</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index ed50f4b..00fd024 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"મધ્યમ"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"ઝડપી"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"ખૂબ ઝડપી"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"સમય સમાપ્ત થયો"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"ડિસ્કનેક્ટ કર્યું"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"ડિસ્કનેક્ટ થઈ રહ્યું છે..."</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 550eaf8..96aec94 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"मध्यम"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"तेज़"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"अत्‍यधिक तेज़"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"समयसीमा खत्म हो गई"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"डिसकनेक्ट किया गया"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"डिस्‍कनेक्‍ट हो रहा है..."</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 18ea1de..6df46ca 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Srednje"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Brzo"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Vrlo brzo"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Isteklo"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Niste povezani"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Isključivanje…"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 7baa044..6b5b05e 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Közepes"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Gyors"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Nagyon gyors"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Lejárt"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Szétkapcsolva"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Szétkapcsolás..."</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index a5b03ea..c4002b9 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Միջին"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Արագ"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Շատ արագ"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Սպառվել է"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Անջատված է"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Անջատվում է..."</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index dea51a8..753f225 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Sedang"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Cepat"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Sangat Cepat"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Sudah tidak berlaku"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Sambungan terputus"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Memutus sambungan..."</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 0a85d06..b1d40bf 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Miðlungshratt"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Hratt"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Mjög hratt"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Útrunninn"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Aftengt"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Aftengist…"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 980bdf9..7f2bd3e 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Veloce"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Molto veloce"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Scaduto"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Disconnesso"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Disconnessione..."</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 77fd156..bdd1bab 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"בינונית"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"מהירה"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"מהירה מאוד"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"התוקף פג"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"מנותק"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"מתנתק..."</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 1d6b3d5..a6192a4 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"普通"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"速い"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"非常に速い"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"期限切れ"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"切断"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"切断中..."</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index a69713a..a3633f6 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"საშუალო"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"სწრაფი"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"ძალიან სწრაფი"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ვადაგასულია"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"კავშირი გაწყვეტილია"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"მიმდინარეობს გათიშვა…"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 380d648..0962e55 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Орташа"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Жылдам"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Өте жылдам"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Мерзімі өтті."</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Ажыратылған"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ажыратылуда…"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 478e036..45620e8 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"មធ្យម"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"លឿន"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"លឿន​ណាស់"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ផុតកំណត់"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"បាន​ផ្ដាច់"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"កំពុង​ផ្ដាច់…"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 73aa998..1fc2e4a 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"ಮಧ್ಯಮ"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"ವೇಗ"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"ತುಂಬಾ ವೇಗವಾಗಿದೆ"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ಅವಧಿ ಮುಕ್ತಾಯವಾಗಿದೆ"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗುತ್ತಿದೆ..."</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 3ecde32..8e7c697 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"보통"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"빠름"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"매우 빠름"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"만료됨"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"연결 끊김"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"연결을 끊는 중…"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index ca8992f..18a1468 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Орто"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Ылдам"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Абдан ылдам"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Мөөнөтү бүткөн"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Ажыратылган"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ажыратылууда…"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index b8a9322..808d5a7 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"ປານກາງ"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"ໄວ"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"ໄວຫຼາຍ"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ໝົດອາຍຸແລ້ວ"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"ຕັດການເຊື່ອມຕໍ່ແລ້ວ"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"ກຳລັງຢຸດການເຊື່ອມຕໍ່..."</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 3d6dfbb..78d1b1b 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Vidutinis"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Greitas"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Labai greitas"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Baigėsi galiojimo laikas"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Atsijungęs (-usi)"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Atjungiama..."</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index bf0c97d..0ae10aa 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Vidējs"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Ātrs"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Ļoti ātrs"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Beidzies derīguma termiņš"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Atvienots"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Notiek atvienošana..."</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 53b0d4c..9850ac5 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Средна"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Брза"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Многу брза"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Истечено"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Исклучено"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Се исклучува..."</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 66ff005..2692a30 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"ഇടത്തരം"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"വേഗത്തിൽ"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"വളരെ വേഗത്തിൽ"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"കാലഹരണപ്പെട്ടത്"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"വിച്ഛേദിച്ചു"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"വിച്‌ഛേദിക്കുന്നു..."</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 75633ab..966cdff 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"मध्‍यम"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"जलद"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"खूप जलद"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"मुदत संपली"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"डिस्कनेक्ट केले"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"डिस्कनेक्ट करत आहे..."</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index fad37fe..88d7c7d 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Sederhana"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Laju"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Sangat Laju"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Tamat tempoh"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Diputuskan sambungan"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Memutuskan sambungan..."</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index fd626f6c..6dfd290 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"အတော်အသင့်"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"မြန်"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"အလွန်မြန်"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"သက်တမ်းကုန်သွားပါပြီ"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"ချိတ်ဆက်မှုပြတ်တောက်သည်"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"အဆက်အသွယ်ဖြတ်တောက်သည်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index baf3c64..760c409 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Middels"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rask"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Veldig rask"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Utløpt"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Frakoblet"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Kobler fra…"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 00a3022..77f87ff 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"मध्यम"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"छिटो"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"धेरै छिटो"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"म्याद सकियो"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"विच्छेदन गरियो"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"जडान हटाइँदै ..."</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 533b0f2..55f56d9 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Gemiddeld"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Snel"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Zeer snel"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Verlopen"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Verbinding verbroken"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Verbinding verbreken..."</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 4a2ab80..98c302d 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"ମଧ୍ୟମ"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"ଦ୍ରୁତ"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"ଅତି ଦ୍ରୁତ"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ମିଆଦ ଶେଷ ହୋଇଯାଇଛି"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"ବିଛିନ୍ନ ହେଲା"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"ବିଚ୍ଛିନ୍ନ କରୁଛି…"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 62da49b..525ad2e 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"ਔਸਤ"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"ਤੇਜ਼"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"ਬਹੁਤ ਤੇਜ਼"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ਮਿਆਦ ਮੁੱਕ ਗਈ"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"ਡਿਸਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"ਡਿਸਕਨੈਕਟ ਕਰ ਰਿਹਾ ਹੈ..."</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 027afc3..69ebc59 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Średnia"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Szybka"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Bardzo szybka"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Ważność wygasła"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Rozłączona"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Rozłączanie..."</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 9259c03..62017f1 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Média"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirado"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 0961b27..8304768 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Média"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirado"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desligado"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"A desligar..."</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 9259c03..62017f1 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Média"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirado"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 1fc1d35..50ea4a0 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Medie"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Rapidă"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Foarte rapidă"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirat"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Deconectat"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"În curs de deconectare..."</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index c3baea2..0582a0c 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Средняя"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Быстрая"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Очень быстрая"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Срок действия истек"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Нет подключения"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Отключение..."</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index f8d2d08..43a4978 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"මධ්‍යම"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"වේගවත්"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"ඉතා වේගවත්"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"කල් ඉකුත් විය"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"විසන්ධි වුණි"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"විසන්ධි වෙමින්…"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 0d576b4..3a3958f 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Stredná"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Vysoká"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Veľmi vysoká"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Platnosť vypršala"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Odpojený"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prebieha odpájanie..."</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 7c62d52..068f221 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Srednje hitra"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Hitra"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Zelo hitra"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Poteklo"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Prekinjena povezava"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prekinjanje povezave ..."</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 7a1bdb5..54d4637 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Mesatare"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"E shpejtë"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Shumë e shpejtë"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Skaduar"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Shkëputur"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Po shkëputet..."</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index e809ab9..ab081ae 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Средња"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Брза"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Веома брза"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Истекло"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Веза је прекинута"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Прекидање везе..."</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 52a82db..cab971f 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Medelsnabb"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Snabb"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Mycket snabb"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Har upphört att gälla"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Kopplas ifrån"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Kopplar ifrån…"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index c83388a..df71b82 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Wastani"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Haraka"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Haraka Sana"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Muda umeisha"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Haijaunganishwa"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Inatenganisha..."</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 856fd4f..084ec16 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"நடுத்தரம்"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"வேகம்"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"மிகவும் வேகமானது"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"காலாவதியாகிவிட்டது"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"தொடர்பு துண்டிக்கப்பட்டது"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"துண்டிக்கிறது..."</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index cc17247..cbcaf1a 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"మధ్యస్థం"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"వేగవంతం"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"చాలా వేగవంతం"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"గడువు ముగిసింది"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"డిస్‌కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"డిస్‌కనెక్ట్ చేస్తోంది..."</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 4feb0d6..fa8caa1 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"ปานกลาง"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"เร็ว"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"เร็วมาก"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"หมดอายุแล้ว"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"ตัดการเชื่อมต่อ"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"กำลังตัดการเชื่อมต่อ..."</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index e6963b9..21fe58c 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Katamtaman"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Mabilis"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Napakabilis"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Nag-expire na"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Hindi nakakonekta"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Nadidiskonekta..."</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index bd457d3..4e7f38d 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Orta"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Hızlı"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Çok Hızlı"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Süresi sona erdi"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Bağlantı kesildi"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Bağlantı kesiliyor…"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 36a82ea..9807417 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Середня"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Швидка"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Дуже швидка"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Термін дії минув"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>: <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Роз’єднано"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Відключення..."</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 50dc72e..e17b0b0 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"متوسط"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"تیز"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"بہت تیز"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"میعاد ختم ہو گئی"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"منقطع"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"منقطع کیا جارہا ہے…"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 38edb6d0..ea51eba 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"O‘rtacha"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Tez"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Juda tez"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Muddati tugagan"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Uzildi"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Uzilyapti…"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index e0798aa..0b71a8c 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Trung bình"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Nhanh"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Rất nhanh"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Đã hết hạn"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Đã ngắt kết nối"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Đang ngắt kết nối…"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 4303615..1805694 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"适中"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"快"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"很快"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"已失效"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"已断开连接"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"正在断开连接..."</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index f3b8653..1d217b5 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"適中"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"快"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"非常快"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"已過期"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"已中斷連線"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"正在中斷連線..."</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 53b54c4..ee68665 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"適中"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"快"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"非常快"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"已失效"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"已中斷連線"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"正在中斷連線…"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 249e73c..820aa77 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -61,8 +61,7 @@
     <string name="speed_label_medium" msgid="9078405312828606976">"Okumaphakathi"</string>
     <string name="speed_label_fast" msgid="2677719134596044051">"Sheshayo"</string>
     <string name="speed_label_very_fast" msgid="8215718029533182439">"Kushesha kakhulu"</string>
-    <!-- no translation found for wifi_passpoint_expired (6540867261754427561) -->
-    <skip />
+    <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Iphelelwe isikhathi"</string>
     <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="7739366554710388701">"Ayixhunyiwe"</string>
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Inqamula uxhumano kwi-inthanethi..."</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index a1ef831..80240af 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -609,6 +609,9 @@
     <string name="bluetooth_select_a2dp_codec_sample_rate">Bluetooth Audio Sample Rate</string>
     <!-- UI debug setting: Trigger Bluetooth Audio Codec Selection: Sample Rate -->
     <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title">Trigger Bluetooth Audio Codec\u000ASelection: Sample Rate</string>
+    <!-- UI debug setting: Label for unsupported Bluetooth Audio Codec. [CHAR LIMIT=none] -->
+    <string name="bluetooth_select_a2dp_codec_type_help_info">Gray-out means not supported by phone
+        or headset</string>
 
     <!-- UI debug setting: Trigger Bluetooth Audio Bits Per Sample Selection -->
     <string name="bluetooth_select_a2dp_codec_bits_per_sample">Bluetooth Audio Bits Per Sample</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 2507a34..0095692 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -442,12 +442,12 @@
 
     /**
      * Get name from remote device
-     * @return {@link BluetoothDevice#getAliasName()} if
-     * {@link BluetoothDevice#getAliasName()} is not null otherwise return
+     * @return {@link BluetoothDevice#getAlias()} if
+     * {@link BluetoothDevice#getAlias()} is not null otherwise return
      * {@link BluetoothDevice#getAddress()}
      */
     public String getName() {
-        final String aliasName = mDevice.getAliasName();
+        final String aliasName = mDevice.getAlias();
         return TextUtils.isEmpty(aliasName) ? getAddress() : aliasName;
     }
 
@@ -505,7 +505,7 @@
      * @return true if device's alias name is not null nor empty, false otherwise
      */
     public boolean hasHumanReadableName() {
-        return !TextUtils.isEmpty(mDevice.getAliasName());
+        return !TextUtils.isEmpty(mDevice.getAlias());
     }
 
     /**
@@ -652,7 +652,7 @@
         }
 
         if (BluetoothUtils.D) {
-            Log.e(TAG, "updating profiles for " + mDevice.getAliasName() + ", " + mDevice);
+            Log.e(TAG, "updating profiles for " + mDevice.getAlias() + ", " + mDevice);
             BluetoothClass bluetoothClass = mDevice.getBluetoothClass();
 
             if (bluetoothClass != null) Log.v(TAG, "Class: " + bluetoothClass.toString());
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index 9f71033..cca9cfa 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -168,7 +168,7 @@
             return cachedDevice.getName();
         }
 
-        String name = device.getAliasName();
+        String name = device.getAlias();
         if (name != null) {
             return name;
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java
index a5f4036..4c3e605 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java
@@ -44,7 +44,7 @@
     private static final String[] CONNECTIVITY_INTENTS = {
             BluetoothAdapter.ACTION_STATE_CHANGED,
             ConnectivityManager.CONNECTIVITY_ACTION,
-            WifiManager.LINK_CONFIGURATION_CHANGED_ACTION,
+            WifiManager.ACTION_LINK_CONFIGURATION_CHANGED,
             WifiManager.NETWORK_STATE_CHANGED_ACTION,
     };
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java
index 24da72e..3bb3a0c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java
@@ -42,7 +42,7 @@
 
     private static final String[] CONNECTIVITY_INTENTS = {
             ConnectivityManager.CONNECTIVITY_ACTION,
-            WifiManager.LINK_CONFIGURATION_CHANGED_ACTION,
+            WifiManager.ACTION_LINK_CONFIGURATION_CHANGED,
             WifiManager.NETWORK_STATE_CHANGED_ACTION,
     };
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java
index 097c028..b5f275b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java
@@ -44,7 +44,7 @@
 
     private static final String[] CONNECTIVITY_INTENTS = {
             ConnectivityManager.CONNECTIVITY_ACTION,
-            WifiManager.LINK_CONFIGURATION_CHANGED_ACTION,
+            WifiManager.ACTION_LINK_CONFIGURATION_CHANGED,
             WifiManager.NETWORK_STATE_CHANGED_ACTION,
     };
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java b/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
index 274696b..69487d5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
@@ -39,6 +39,7 @@
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
+import android.os.UserManager;
 
 import com.android.settingslib.R;
 
@@ -176,8 +177,8 @@
             boolean isManaged = context.getSystemService(DevicePolicyManager.class)
                     .getProfileOwnerAsUser(userId) != null;
             if (isManaged) {
-                badge = getDrawableForDisplayDensity(
-                        context, com.android.internal.R.drawable.ic_corp_badge_case);
+                badge = getDrawableForDisplayDensity(context,
+                        context.getSystemService(UserManager.class).getUserBadgeResId(userId));
             }
         }
         return setBadge(badge);
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index ea3c1d9..092cbf3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -222,7 +222,8 @@
             }
         }
 
-        return TelephonyManager.from(mContext).createForSubscriptionId(subscriptionId);
+        return mContext.getSystemService(
+                TelephonyManager.class).createForSubscriptionId(subscriptionId);
     }
 
     public void setMobileDataEnabled(boolean enabled) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index ab274b5..9518f5c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -748,20 +748,7 @@
                 || (mConfig != null && mConfig.shared != config.shared)) {
             return false;
         }
-
-        final int configSecurity = getSecurity(config);
-        final WifiManager wifiManager = getWifiManager();
-        switch (security) {
-            case SECURITY_PSK_SAE_TRANSITION:
-                return configSecurity == SECURITY_PSK
-                        || (wifiManager.isWpa3SaeSupported() && configSecurity == SECURITY_SAE);
-            case SECURITY_OWE_TRANSITION:
-                return configSecurity == SECURITY_NONE
-                        || (wifiManager.isEnhancedOpenSupported()
-                                && configSecurity == SECURITY_OWE);
-            default:
-                return security == configSecurity;
-        }
+        return security == getSecurity(config);
     }
 
     public WifiConfiguration getConfig() {
@@ -1334,34 +1321,10 @@
         mAccessPointListener = listener;
     }
 
-    private static final String sPskSuffix = "," + String.valueOf(SECURITY_PSK);
-    private static final String sSaeSuffix = "," + String.valueOf(SECURITY_SAE);
-    private static final String sPskSaeSuffix = "," + String.valueOf(SECURITY_PSK_SAE_TRANSITION);
-    private static final String sOweSuffix = "," + String.valueOf(SECURITY_OWE);
-    private static final String sOpenSuffix = "," + String.valueOf(SECURITY_NONE);
-    private static final String sOweTransSuffix = "," + String.valueOf(SECURITY_OWE_TRANSITION);
-
     private boolean isKeyEqual(String compareTo) {
         if (mKey == null) {
             return false;
         }
-
-        if (compareTo.endsWith(sPskSuffix) || compareTo.endsWith(sSaeSuffix)) {
-            if (mKey.endsWith(sPskSaeSuffix)) {
-                // Special handling for PSK-SAE transition mode. If the AP has advertised both,
-                // we compare the key with both PSK and SAE for a match.
-                return TextUtils.equals(mKey.substring(0, mKey.lastIndexOf(',')),
-                        compareTo.substring(0, compareTo.lastIndexOf(',')));
-            }
-        }
-        if (compareTo.endsWith(sOpenSuffix) || compareTo.endsWith(sOweSuffix)) {
-            if (mKey.endsWith(sOweTransSuffix)) {
-                // Special handling for OWE/Open networks. If AP advertises OWE in transition mode
-                // and we have an Open network saved, allow this connection to be established.
-                return TextUtils.equals(mKey.substring(0, mKey.lastIndexOf(',')),
-                        compareTo.substring(0, compareTo.lastIndexOf(',')));
-            }
-        }
         return mKey.equals(compareTo);
     }
 
@@ -1698,8 +1661,6 @@
     private static int getSecurity(ScanResult result) {
         if (result.capabilities.contains("WEP")) {
             return SECURITY_WEP;
-        } else if (result.capabilities.contains("PSK+SAE")) {
-            return SECURITY_PSK_SAE_TRANSITION;
         } else if (result.capabilities.contains("SAE")) {
             return SECURITY_SAE;
         } else if (result.capabilities.contains("PSK")) {
@@ -1708,8 +1669,6 @@
             return SECURITY_EAP_SUITE_B;
         } else if (result.capabilities.contains("EAP")) {
             return SECURITY_EAP;
-        } else if (result.capabilities.contains("OWE_TRANSITION")) {
-            return SECURITY_OWE_TRANSITION;
         } else if (result.capabilities.contains("OWE")) {
             return SECURITY_OWE;
         }
@@ -1756,10 +1715,6 @@
             return "SUITE_B";
         } else if (security == SECURITY_OWE) {
             return "OWE";
-        } else if (security == SECURITY_PSK_SAE_TRANSITION) {
-            return "PSK+SAE";
-        } else if (security == SECURITY_OWE_TRANSITION) {
-            return "OWE_TRANSITION";
         }
         return "NONE";
     }
@@ -1937,4 +1892,16 @@
             }
         }
     }
+
+    /**
+     * Lets the caller know if the network was cloned from another network
+     *
+     * @return true if the network is cloned
+     */
+    public boolean isCloned() {
+        if (mConfig == null) {
+            return false;
+        }
+        return mConfig.clonedNetworkConfigKey != null;
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS b/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS
index d5d2e9e..f506b7c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS
@@ -1,7 +1,7 @@
 # Default reviewers for this and subdirectories.
+qal@google.com
+arcwang@google.com
+govenliu@google.com
 asapperstein@google.com
-asargent@google.com
-dling@google.com
-zhfan@google.com
 
 # Emergency approvers in case the above are not available
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index d3bab5f..97fddc0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -180,7 +180,7 @@
         filter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
         filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
         filter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
-        filter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
+        filter.addAction(WifiManager.ACTION_LINK_CONFIGURATION_CHANGED);
         filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
         filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
 
@@ -866,7 +866,7 @@
 
                 fetchScansAndConfigsAndUpdateAccessPoints();
             } else if (WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action)
-                    || WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) {
+                    || WifiManager.ACTION_LINK_CONFIGURATION_CHANGED.equals(action)) {
                 fetchScansAndConfigsAndUpdateAccessPoints();
             } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
                 // TODO(sghuman): Refactor these methods so they cannot result in duplicate
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index 7fac812..942ee4f 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -902,7 +902,7 @@
         tracker.mReceiver.onReceive(
                 mContext, new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
         tracker.mReceiver.onReceive(
-                mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION));
+                mContext, new Intent(WifiManager.ACTION_LINK_CONFIGURATION_CHANGED));
 
 
         verify(mockWifiListener, never()).onAccessPointsChanged();
@@ -920,7 +920,7 @@
         tracker.mReceiver.onReceive(
                 mContext, new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
         tracker.mReceiver.onReceive(
-                mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION));
+                mContext, new Intent(WifiManager.ACTION_LINK_CONFIGURATION_CHANGED));
 
         verify(mockWifiListener, never()).onAccessPointsChanged();
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
index 4d76331..4811d950 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
@@ -16,11 +16,15 @@
 
 package com.android.settingslib;
 
+import static com.android.settingslib.HelpUtils.MENU_HELP;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -35,6 +39,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.provider.Settings;
+import android.view.Menu;
 import android.view.MenuItem;
 
 import org.junit.Before;
@@ -171,4 +176,34 @@
         verify(item).setVisible(true);
         verify(item).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
     }
+
+    @Test
+    public void prepareHelpMenuItem_noItem_addItem() {
+        final Menu item = mock(Menu.class);
+        when(item.findItem(MENU_HELP)).thenReturn(null);
+        when(item.add(0, MENU_HELP, 0,
+                com.android.settingslib.widget.R.string.help_feedback_label)).thenReturn(
+                mock(MenuItem.class));
+
+        HelpUtils.prepareHelpMenuItem(mActivity, item, TEST_HELP_URL, "backup_url");
+        HelpUtils.prepareHelpMenuItem(mActivity, item, 0, "backup_url");
+
+        verify(item, times(2)).add(0, MENU_HELP, 0,
+                com.android.settingslib.widget.R.string.help_feedback_label);
+    }
+
+    @Test
+    public void prepareHelpMenuItem_hasItem_notAddItem() {
+        final Menu item = mock(Menu.class);
+        when(item.findItem(MENU_HELP)).thenReturn(mock(MenuItem.class));
+        when(item.add(0, MENU_HELP, 0,
+                com.android.settingslib.widget.R.string.help_feedback_label)).thenReturn(
+                mock(MenuItem.class));
+
+        HelpUtils.prepareHelpMenuItem(mActivity, item, TEST_HELP_URL, "backup_url");
+        HelpUtils.prepareHelpMenuItem(mActivity, item, 0, "backup_url");
+
+        verify(item, never()).add(0, MENU_HELP, 0,
+                com.android.settingslib.widget.R.string.help_feedback_label);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index aef7fae..2c4f57f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -92,9 +92,9 @@
         when(mDevice1.getName()).thenReturn(DEVICE_NAME_1);
         when(mDevice2.getName()).thenReturn(DEVICE_NAME_2);
         when(mDevice3.getName()).thenReturn(DEVICE_NAME_3);
-        when(mDevice1.getAliasName()).thenReturn(DEVICE_ALIAS_1);
-        when(mDevice2.getAliasName()).thenReturn(DEVICE_ALIAS_2);
-        when(mDevice3.getAliasName()).thenReturn(DEVICE_ALIAS_3);
+        when(mDevice1.getAlias()).thenReturn(DEVICE_ALIAS_1);
+        when(mDevice2.getAlias()).thenReturn(DEVICE_ALIAS_2);
+        when(mDevice3.getAlias()).thenReturn(DEVICE_ALIAS_3);
         when(mDevice1.getBluetoothClass()).thenReturn(DEVICE_CLASS_1);
         when(mDevice2.getBluetoothClass()).thenReturn(DEVICE_CLASS_2);
         when(mDevice3.getBluetoothClass()).thenReturn(DEVICE_CLASS_2);
@@ -240,7 +240,7 @@
         assertThat(cachedDevice1.getName()).isEqualTo(DEVICE_ALIAS_1);
 
         final String newAliasName = "NewAliasName";
-        when(mDevice1.getAliasName()).thenReturn(newAliasName);
+        when(mDevice1.getAlias()).thenReturn(newAliasName);
         mCachedDeviceManager.onDeviceNameUpdated(mDevice1);
         assertThat(cachedDevice1.getName()).isEqualTo(newAliasName);
     }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 5c89a01..53ff1a1 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -702,7 +702,7 @@
 
     @Test
     public void deviceName_testAliasNameAvailable() {
-        when(mDevice.getAliasName()).thenReturn(DEVICE_ALIAS);
+        when(mDevice.getAlias()).thenReturn(DEVICE_ALIAS);
         when(mDevice.getName()).thenReturn(DEVICE_NAME);
         CachedBluetoothDevice cachedBluetoothDevice =
                 new CachedBluetoothDevice(mContext, mProfileManager, mDevice);
@@ -725,7 +725,7 @@
     @Test
     public void deviceName_testRenameDevice() {
         final String[] alias = {DEVICE_ALIAS};
-        doAnswer(invocation -> alias[0]).when(mDevice).getAliasName();
+        doAnswer(invocation -> alias[0]).when(mDevice).getAlias();
         doAnswer(invocation -> {
             alias[0] = (String) invocation.getArguments()[0];
             return true;
@@ -842,14 +842,14 @@
 
     @Test
     public void getName_aliasNameNotNull_returnAliasName() {
-        when(mDevice.getAliasName()).thenReturn(DEVICE_NAME);
+        when(mDevice.getAlias()).thenReturn(DEVICE_NAME);
 
         assertThat(mCachedDevice.getName()).isEqualTo(DEVICE_NAME);
     }
 
     @Test
     public void getName_aliasNameIsNull_returnAddress() {
-        when(mDevice.getAliasName()).thenReturn(null);
+        when(mDevice.getAlias()).thenReturn(null);
 
         assertThat(mCachedDevice.getName()).isEqualTo(DEVICE_ADDRESS);
     }
@@ -857,7 +857,7 @@
     @Test
     public void setName_setDeviceNameIsNotNull() {
         final String name = "test name";
-        when(mDevice.getAliasName()).thenReturn(DEVICE_NAME);
+        when(mDevice.getAlias()).thenReturn(DEVICE_NAME);
 
         mCachedDevice.setName(name);
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
index 2b5466c..7be176a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
@@ -75,8 +75,8 @@
         when(mDevice2.getAddress()).thenReturn(DEVICE_ADDRESS_2);
         when(mDevice1.getName()).thenReturn(DEVICE_NAME_1);
         when(mDevice2.getName()).thenReturn(DEVICE_NAME_2);
-        when(mDevice1.getAliasName()).thenReturn(DEVICE_ALIAS_1);
-        when(mDevice2.getAliasName()).thenReturn(DEVICE_ALIAS_2);
+        when(mDevice1.getAlias()).thenReturn(DEVICE_ALIAS_1);
+        when(mDevice2.getAlias()).thenReturn(DEVICE_ALIAS_2);
         when(mDevice1.getBluetoothClass()).thenReturn(DEVICE_CLASS);
         when(mDevice2.getBluetoothClass()).thenReturn(DEVICE_CLASS);
         when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java
index 76a26d9..a83d7e0 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java
@@ -63,7 +63,7 @@
                 new ConcreteIpAddressPreferenceController(mContext, mLifecycle);
         final List<String> expectedIntents = Arrays.asList(
                 ConnectivityManager.CONNECTIVITY_ACTION,
-                WifiManager.LINK_CONFIGURATION_CHANGED_ACTION,
+                WifiManager.ACTION_LINK_CONFIGURATION_CHANGED,
                 WifiManager.NETWORK_STATE_CHANGED_ACTION);
 
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java
index 7c2f0a8..40b9b13 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java
@@ -84,7 +84,7 @@
     public void testHasIntentFilters() {
         final List<String> expectedIntents = Arrays.asList(
                 ConnectivityManager.CONNECTIVITY_ACTION,
-                WifiManager.LINK_CONFIGURATION_CHANGED_ACTION,
+                WifiManager.ACTION_LINK_CONFIGURATION_CHANGED,
                 WifiManager.NETWORK_STATE_CHANGED_ACTION);
 
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
index 3da5e76..f7bee30 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
@@ -75,7 +75,7 @@
     public void setUp() throws RemoteException {
         MockitoAnnotations.initMocks(this);
         when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
-        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+        when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
         when(mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE))
                 .thenReturn(mSubscriptionManager);
         when(mContext.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 10d990a..289ac80 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -605,6 +605,7 @@
                  Settings.Secure.ASSIST_GESTURE_SETUP_COMPLETE,
                  Settings.Secure.ASSIST_SCREENSHOT_ENABLED,
                  Settings.Secure.ASSIST_STRUCTURE_ENABLED,
+                 Settings.Secure.ATTENTIVE_TIMEOUT,
                  Settings.Secure.AUTOFILL_FEATURE_FIELD_CLASSIFICATION,
                  Settings.Secure.AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT,
                  Settings.Secure.AUTOFILL_USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE,
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index cd64a388..ab433d2 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -232,9 +232,6 @@
     <!-- to read and change hvac values in a car -->
     <uses-permission android:name="android.car.permission.CONTROL_CAR_CLIMATE" />
 
-    <!-- to be able to detect the driving state in a car-->
-    <uses-permission android:name="android.car.permission.CAR_DRIVING_STATE" />
-
     <!-- Permission necessary to change car audio volume through CarAudioManager -->
     <uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME" />
 
diff --git a/packages/SystemUI/README.md b/packages/SystemUI/README.md
index a4dbf38..f170a11 100644
--- a/packages/SystemUI/README.md
+++ b/packages/SystemUI/README.md
@@ -24,12 +24,6 @@
 ConfigurationController). They also receive a callback for onBootCompleted
 since these objects may be started before the device has finished booting.
 
-SystemUI and SystemUIApplication also have methods for putComponent and
-getComponent which were existing systems to get a hold of other parts of
-sysui before Dependency existed. Generally new things should not be added
-to putComponent, instead Dependency and other refactoring is preferred to
-make sysui structure cleaner.
-
 Each SystemUI service is expected to be a major part of system ui and the
 goal is to minimize communication between them. So in general they should be
 relatively silo'd.
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java
new file mode 100644
index 0000000..bd86407
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java
@@ -0,0 +1,60 @@
+/*
+ * 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.plugins;
+
+import android.graphics.Point;
+import android.view.MotionEvent;
+import android.view.WindowManager;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/** Plugin to handle navigation edge gestures for Back. */
+@ProvidesInterface(
+        action = NavigationEdgeBackPlugin.ACTION,
+        version = NavigationEdgeBackPlugin.VERSION)
+public interface NavigationEdgeBackPlugin extends Plugin {
+    String ACTION = "com.android.systemui.action.PLUGIN_NAVIGATION_EDGE_BACK_ACTION";
+    int VERSION = 1;
+
+
+    /** Specifies if the UI should be rendered on the left side of the screen. */
+    void setIsLeftPanel(boolean isLeftPanel);
+
+    /** Sets the insets for the gesture handling area. */
+    void setInsets(int leftInset, int rightInset);
+
+    /** Sets the display size. */
+    void setDisplaySize(Point displaySize);
+
+    /** Sets the callback that should be invoked when a Back gesture is detected. */
+    void setBackCallback(BackCallback callback);
+
+    /** Sets the base LayoutParams for the UI. */
+    void setLayoutParams(WindowManager.LayoutParams layoutParams);
+
+    /** Updates the UI based on the motion events passed in device coordinates. */
+    void onMotionEvent(MotionEvent motionEvent);
+
+    /** Callback to let the system react to the detected back gestures. */
+    interface BackCallback {
+        /** Indicates that a Back gesture was recognized and the system should go back. */
+        void triggerBack();
+
+        /** Indicates that the gesture was cancelled and the system should not go back. */
+        void cancelBack();
+    }
+}
diff --git a/packages/SystemUI/res/layout-television/inattentive_sleep_warning.xml b/packages/SystemUI/res/layout-television/inattentive_sleep_warning.xml
new file mode 100644
index 0000000..eb21c43
--- /dev/null
+++ b/packages/SystemUI/res/layout-television/inattentive_sleep_warning.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/sleep_warning_dialog_container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:theme="@android:style/Theme.DeviceDefault.Dialog"
+    android:focusable="true">
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@android:color/black"
+        android:alpha="?android:backgroundDimAmount" />
+    <LinearLayout
+        android:layout_width="380dp"
+        android:layout_height="wrap_content"
+        android:background="@drawable/rounded_bg_full"
+        android:padding="16dp"
+        android:layout_margin="32dp"
+        android:layout_gravity="bottom|right"
+        android:orientation="vertical">
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/inattentive_sleep_warning_title"
+            android:layout_marginBottom="8dp"
+            android:textColor="?android:attr/textColorPrimary"
+            android:textAppearance="@android:style/TextAppearance.DeviceDefault.Large"/>
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/inattentive_sleep_warning_message"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textAppearance="@android:style/TextAppearance.DeviceDefault"/>
+    </LinearLayout>
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/inattentive_sleep_warning.xml b/packages/SystemUI/res/layout/inattentive_sleep_warning.xml
new file mode 100644
index 0000000..f1f9b1f
--- /dev/null
+++ b/packages/SystemUI/res/layout/inattentive_sleep_warning.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/sleep_warning_dialog_container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:theme="@android:style/Theme.Material.Dialog"
+    android:focusable="true">
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@android:color/black"
+        android:alpha="?android:backgroundDimAmount" />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@drawable/rounded_bg_full"
+        android:layout_margin="8dp"
+        android:padding="16dp"
+        android:layout_gravity="top"
+        android:orientation="vertical">
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/inattentive_sleep_warning_title"
+            android:layout_marginBottom="8dp"
+            android:textColor="?android:attr/textColorPrimary"
+            android:textAppearance="@android:style/TextAppearance.Material.Large"/>
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/inattentive_sleep_warning_message"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textAppearance="@android:style/TextAppearance.Material"/>
+    </LinearLayout>
+</FrameLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 66a8ade..ed8117c 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Hou aan om kennisgewings van hierdie program af te wys?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Stil"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Waarskuwings"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Borrel"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Help jou om te fokus sonder klank of vibrasie."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Kry jou aandag met klank of vibrasie."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Hou jou aandag met \'n swewende kortpad na hierdie inhoud toe."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Hierdie kennisgewings kan nie gewysig word nie."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Hierdie groep kennisgewings kan nie hier opgestel word nie"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Instaanbediener-kennisgewing"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Maak toe"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Stelselnavigasie is opgedateer. Gaan na Instellings toe om veranderinge te maak."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Gaan na Instellings toe om stelselnavigasie op te dateer"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Bystandmodus"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Die Android TV-toestel gaan binnekort afskakel; druk \'n knoppie om dit aan te hou."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Die toestel gaan binnekort afskakel; druk om dit aan te hou."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 3f02c95..025031f 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ከዚህ መተግበሪያ ማሳወቂያዎችን ማሳየት ይቀጥል?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"ፀጥ ያለ"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"ማንቃት"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"አረፋ"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"ያለ ድምፅ ወይም ንዝረት እርስዎ ትኩረት እንዲያደርጉ ያግዛል።"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"ከድምፅ ወይም ንዝረት ጋር የእርስዎን ትኩረት ይስባል።"</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"ለዚህ ይዞታ ከተንሳፋፊ አቋራጭ ጋር የእርስዎን ትኩረት ያቆያል።"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"እነዚህ ማሳወቂያዎች ሊሻሻሉ አይችሉም።"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"የማሳወቂያዎች ይህ ቡድን እዚህ ላይ ሊዋቀር አይችልም"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ተኪ ማሳወቂያ"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"አሰናብት"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"የስርዓት ዳሰሳ ተዘምኗል። ለውጦችን ለማድረግ ወደ ቅንብሮች ይሂዱ።"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"የስርዓት ዳሰሳን ለማዘመን ወደ ቅንብሮች ይሂዱ"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"ተጠባባቂ"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"የAndroid TV መሣሪያው በቅርቡ ይጠፋል፣ እንደበራ ለማቆየት ይጫኑ።"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"መሣሪያው በቅርቡ ይጠፋል፤ እንደበራ ለማቆየት ይጫኑ።"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 8c765ac..767343b 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -673,8 +673,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"هل تريد الاستمرار في تلقي إشعارات من هذا التطبيق؟"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"إشعار صامت"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"إشعار مصحوب بتنبيه صوتي"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"يساعدك هذا الإشعار على التركيز بدون صوت أو اهتزاز."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"يلفت هذا الإشعار انتباهك باستخدام الصوت والاهتزاز."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"يتعذّر تعديل هذه الإشعارات."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"يتعذّر ضبط مجموعة الإشعارات هذه هنا."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"إشعار مستند إلى خادم وكيل"</string>
@@ -966,4 +970,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"تجاهل"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"تم تحديث التنقل داخل النظام. لإجراء التغييرات، يُرجى الانتقال إلى \"الإعدادات\"."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"الانتقال إلى \"الإعدادات\" لتعديل التنقل داخل النظام"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"وضع الاستعداد"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"‏سيتم إيقاف جهاز Android TV قريبًا، اضغط على أحد الأزرار لمواصلة تشغيله."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"سيتم إيقاف الجهاز قريبًا، اضغط لمواصلة تشغيله."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 87be3eb..3197d4f 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"এই এপটোৰ জাননী দেখুওৱাই থাকিব লাগিবনে?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"নীৰৱ"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"সতৰ্ক কৰক"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"কোনো ধ্বনি অথবা কম্পন অবিহনে আপোনাক মনোযোগ দিয়াত সহায় কৰে।"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"ধ্বনি অথবা কম্পনৰ জৰিয়তে আপোনাৰ মনোযোগ আকৰ্ষণ কৰে।"</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"এই জাননীসমূহ সংশোধন কৰিব নোৱাৰি।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"এই ধৰণৰ জাননীবোৰ ইয়াত কনফিগাৰ কৰিব পৰা নাযায়"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"প্ৰক্সি হিচাপে পঠিওৱা জাননী"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"অগ্ৰাহ্য কৰক"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰা হ’ল। সলনি কৰিবলৈ ছেটিংসমূহ-লৈ যাওক।"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰিবলৈ ছেটিংসমূহ-লৈ যাওক"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"ষ্টেণ্ডবাই"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV ডিভাইচটো অতি সোনকালে অফ হ\'ব, এইটো অন ৰাখিবলৈ যিকোনো এটা বুটাম টিপক।"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"এই ডিভাইচটো অতি সোনকালে অফ হ\'ব, এইটো অন ৰাখিবলৈ টিপক।"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index a756ac0..6ad64be 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Bu tətbiqin bildirişləri göstərilməyə davam edilsin?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Səssiz"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Siqnal"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Səs və ya vibrasiya olmadan fokuslanmağınıza kömək edir."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Səs və ya vibrasiya ilə diqqətinizi çəkir."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Bu bildirişlər dəyişdirilə bilməz."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Bu bildiriş qrupunu burada konfiqurasiya etmək olmaz"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proksi bildirişi"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Kənarlaşdırın"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Sistem naviqasiyası yeniləndi. Dəyişiklik etmək üçün Ayarlara daxil olun."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Sistem naviqasiyasını yeniləmək üçün Ayarlara keçin"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Gözləmə rejimi"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV cihazı tezliklə sönəcək; aktiv saxlamaq üçün düyməyə basın."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Cihaz tezliklə sönəcək; aktiv saxlamaq üçün basın."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index a3232e1..1bc7121 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -664,8 +664,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Želite li da se obaveštenja iz ove aplikacije i dalje prikazuju?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Nečujno"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Upozoravanje"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Oblačić"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomaže vam da se koncentrišete bez zvuka ili vibracije."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Privlači vam pažnju pomoću zvuka ili vibracije."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Privlači vam pažnju pomoću plutajuće prečice do ovog sadržaja."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ova obaveštenja ne mogu da se menjaju."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ova grupa obaveštenja ne može da se konfiguriše ovde"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Obaveštenje preko proksija"</string>
@@ -951,4 +953,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Odbaci"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigacija sistema je ažurirana. Da biste uneli izmene, idite u Podešavanja."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Idite u Podešavanja da biste ažurirali navigaciju sistema"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Stanje pripravnosti"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV će se uskoro isključiti. Pritisnite dugme da bi ostao uključen."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Uređaj će se uskoro isključiti. Pritisnite da bi ostao uključen."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index ec90354..52d2848 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -669,8 +669,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Працягваць паказваць апавяшчэнні гэтай праграмы?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Бязгучны рэжым"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Абвесткі"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Не адцягвае ўвагу дзякуючы выключаным гуку і вібрацыі."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Прыцягвае ўвагу гукам і вібрацыяй."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Гэтыя апавяшчэнні нельга змяніць."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Тут канфігурыраваць гэту групу апавяшчэнняў забаронена"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Праксіраванае апавяшчэнне"</string>
@@ -958,4 +962,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Адхіліць"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Навігацыя ў сістэме абноўлена. Каб унесці змяненні, перайдзіце ў Налады."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Перайдзіце ў Налады, каб абнавіць параметры навігацыі ў сістэме"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Рэжым чакання"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Прылада Android TV неўзабаве выключыцца. Каб пакінуць яе ўключанай, націсніце кнопку."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Прылада неўзабаве выключыцца. Націсніце, каб пакінуць яе ўключанай."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 856c020..5429f84 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Да продължат ли да се показват известията от това приложение?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Тих режим"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Сигнализиране"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Помага ви да се фокусирате без звук или вибриране."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Привлича вниманието ви със звук или вибриране."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Тези известия не могат да бъдат променяни."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Тази група от известия не може да бъде конфигурирана тук"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Известие, получено чрез делегиране"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Отхвърляне"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Режимът за навигиране в системата е актуализиран. За да извършите промени, отворете настройките."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Отворете настройките, за да актуализирате режима за навигиране в системата"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Режим на готовност"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Устройството с Android TV скоро ще се изключи. Натиснете бутон, за да остане включено."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Устройството скоро ще се изключи. Натиснете, за да остане включено."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 7c3f250f..0aa4ee9 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"এই অ্যাপের বিজ্ঞপ্তি পরেও দেখে যেতে চান?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"সাইলেন্ট"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"সতর্ক করুন"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"সাউন্ড বা ভাইব্রেশন ছাড়া ফোকাস করতে আপনাকে সাহায্য করে।"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"সাউন্ড বা ভাইব্রেশনের সাহায্যে দৃষ্টি আকর্ষণ করে।"</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"এই বিজ্ঞপ্তিগুলি পরিবর্তন করা যাবে না।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"এই সমস্ত বিজ্ঞপ্তিকে এখানে কনফিগার করা যাবে না"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"প্রক্সি করা বিজ্ঞপ্তি"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"খারিজ করুন"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"সিস্টেম নেভিগেশন আপডেট হয়েছে। পরিবর্তন করার জন্য সেটিংসে যান।"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"সিস্টেম নেভিগেশন আপডেট করতে সেটিংসে যান"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"স্ট্যান্ডবাই"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV ডিভাইস শীঘ্রই বন্ধ হয়ে যাবে, চালু রাখতে বোতাম প্রেস করুন।"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"ডিভাইস শীঘ্রই বন্ধ হয়ে যাবে, চালু রাখতে প্রেস করুন।"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 62cb309..a97e463 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -666,8 +666,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Nastaviti prikazivanje obavještenja iz ove aplikacije?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Nečujno"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Upozorenja"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Oblačić"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomaže vam da se koncentrirate bez zvuka ili vibracije."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Privlači vašu pažnju pomoću zvuka ili vibracije."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Privlači vašu pažnju pomoću plutajuće prečice do ovog sadržaja."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ta obavještenja se ne mogu izmijeniti."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ovdje nije moguće konfigurirati ovu grupu obavještenja"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Obavještenje preko proksi servera"</string>
@@ -953,4 +955,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Odbaci"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigiranje sistemom je ažurirano. Da izvršite promjene, idite u Postavke."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Idite u Postavke da ažurirate navigiranje sistemom"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Stanje mirovanja"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV uređaj će se uskoro isključiti. Pritisnite dugme da ostane uključen."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Uređaj će se uskoro isključiti. Pritisnite da ostane uključen."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 18dbd2c..4f65a6e 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vols continuar rebent notificacions d\'aquesta aplicació?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Silenci"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Alertes"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Bombolla"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"T\'ajuda a concentrar-te sense so ni vibració."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Atrau la teva atenció amb so i vibració."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Atrau la teva atenció amb una drecera flotant a aquest contingut."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Aquestes notificacions no es poden modificar."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Aquest grup de notificacions no es pot configurar aquí"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificació mitjançant aplicació intermediària"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Omet"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"S\'ha actualitzat el sistema de navegació. Per fer canvis, ves a Configuració."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Ves a Configuració per actualitzar el sistema de navegació"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"En espera"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"El dispositiu Android TV s\'apagarà aviat; prem un botó per mantenir-lo encès."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"El dispositiu s\'apagarà aviat; prem per mantenir-lo encès."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 68800f0..803d576 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -667,8 +667,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Mají se oznámení z této aplikace nadále zobrazovat?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Ticho"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Upozornění"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomáhá vám soustředit se vypnutím zvuku a vibrací."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Upozorňuje vás pomocí zvuku a vibrací."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Tato oznámení nelze upravit."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Tuto skupinu oznámení tady nelze nakonfigurovat"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Zprostředkované oznámení"</string>
@@ -956,4 +960,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Zavřít"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systémová navigace byla aktualizována. Chcete-li provést změny, přejděte do Nastavení."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Přejděte do Nastavení a aktualizujte systémovou navigaci"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Pohotovostní režim"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Zařízení Android TV se brzy vypne, stisknutím tlačítka ho ponecháte zapnuté."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Zařízení se brzy vypne, stisknutím ho ponecháte zapnuté."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index d3dbc6e..7b33b32 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vil du fortsætte med at se notifikationer fra denne app?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Lydløs"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Underretninger"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Boble"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ingen lyde eller vibrationer, der forstyrrer dig."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Fanger din opmærksomhed med lyd eller vibration."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Fastholder din opmærksomhed med en svævende genvej til indholdet."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Disse notifikationer kan ikke redigeres."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Du kan ikke konfigurere denne gruppe notifikationer her"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxyforbundet notifikation"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Afvis"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systemnavigationen blev opdateret. Gå til Indstillinger for at foretage ændringer."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Gå til Indstillinger for at opdatere systemnavigationen"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Standby"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV-enheden slukker snart. Tryk på en knap for at holde den tændt."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Enheden slukker snart. Tryk for at holde den tændt."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 15f7876..46d36b2 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -665,8 +665,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Benachrichtigungen dieser App weiterhin anzeigen?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Lautlos"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Benachrichtigen"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Benachrichtigungen werden ohne Ton oder Vibration angekündigt, um deine Konzentration nicht zu stören."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Benachrichtigungen werden mit einem Ton oder einer Vibration angekündigt."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Diese Benachrichtigungen können nicht geändert werden."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Die Benachrichtigungsgruppe kann hier nicht konfiguriert werden"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Weitergeleitete Benachrichtigung"</string>
@@ -950,4 +954,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Schließen"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systemsteuerungseinstellungen wurden angepasst. Änderungen kannst du in den Einstellungen vornehmen."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Gehe zu den Einstellungen, um die Systemsteuerung anzupassen"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Standby"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Das Android TV-Gerät wird demnächst abgeschaltet. Drücke eine Taste, damit es eingeschaltet bleibt."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Das Gerät wird demnächst abgeschaltet. Drücke beispielsweise eine Taste oder berühre den Bildschirm, damit es eingeschaltet bleibt."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index d30aec9..ebfc0eb 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Να συνεχίσουν να εμφανίζονται ειδοποιήσεις από αυτήν την εφαρμογή;"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Σίγαση"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Ειδοποίηση"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Φούσκα"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Σας βοηθά να συγκεντρωθείτε χωρίς ήχο και δόνηση."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Τραβά την προσοχή σας με ήχο ή δόνηση."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Κρατάει την προσοχή σας με μια κινούμενη συντόμευση προς αυτό το περιεχόμενο."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Δεν είναι δυνατή η τροποποίηση αυτών των ειδοποιήσεων"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Δεν είναι δυνατή η διαμόρφωση αυτής της ομάδας ειδοποιήσεων εδώ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Ειδοποίηση μέσω διακομιστή μεσολάβησης"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Παράβλεψη"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Η πλοήγηση συστήματος ενημερώθηκε. Για να κάνετε αλλαγές, μεταβείτε στις Ρυθμίσεις."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Μεταβείτε στις Ρυθμίσεις για να ενημερώσετε την πλοήγηση συστήματος"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Κατάσταση αναμονής"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Η συσκευή Android TV σύντομα θα απενεργοποιηθεί. Πατήστε ένα κουμπί για να την κρατήσετε ενεργοποιημένη."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Η συσκευή σύντομα θα απενεργοποιηθεί. Πατήστε για να την κρατήσετε ενεργοποιημένη."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 1e50b5a..c7c5833 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Silent"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Alerting"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Bubble"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helps you focus without sound or vibration."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Gets your attention with sound or vibration."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Keeps your attention with a floating shortcut to this content."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxied notification"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dismiss"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"System navigation updated. To make changes, go to Settings."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Go to Settings to update system navigation"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Standby"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"The Android TV device will soon turn off; press a button to keep it on."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"The device will soon turn off; press to keep it on."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index b2a6e6a..c89abab 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Silent"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Alerting"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Bubble"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helps you focus without sound or vibration."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Gets your attention with sound or vibration."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Keeps your attention with a floating shortcut to this content."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxied notification"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dismiss"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"System navigation updated. To make changes, go to Settings."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Go to Settings to update system navigation"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Standby"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"The Android TV device will soon turn off; press a button to keep it on."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"The device will soon turn off; press to keep it on."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 1e50b5a..c7c5833 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Silent"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Alerting"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Bubble"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helps you focus without sound or vibration."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Gets your attention with sound or vibration."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Keeps your attention with a floating shortcut to this content."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxied notification"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dismiss"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"System navigation updated. To make changes, go to Settings."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Go to Settings to update system navigation"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Standby"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"The Android TV device will soon turn off; press a button to keep it on."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"The device will soon turn off; press to keep it on."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 1e50b5a..c7c5833 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Silent"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Alerting"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Bubble"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helps you focus without sound or vibration."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Gets your attention with sound or vibration."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Keeps your attention with a floating shortcut to this content."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxied notification"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dismiss"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"System navigation updated. To make changes, go to Settings."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Go to Settings to update system navigation"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Standby"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"The Android TV device will soon turn off; press a button to keep it on."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"The device will soon turn off; press to keep it on."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 568fdb5..a561001 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎Keep showing notifications from this app?‎‏‎‎‏‎"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‎‏‏‎‎‏‎Silent‎‏‎‎‏‎"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎Alerting‎‏‎‎‏‎"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‏‎‏‎‎‎Bubble‎‏‎‎‏‎"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎Helps you focus without sound or vibration.‎‏‎‎‏‎"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎Gets your attention with sound or vibration.‎‏‎‎‏‎"</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‏‎‏‎‏‏‎Keeps your attention with a floating shortcut to this content.‎‏‎‎‏‎"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‎‏‎‎‎‎‎‎‎‏‏‎‎These notifications can\'t be modified.‎‏‎‎‏‎"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‎This group of notifications cannot be configured here‎‏‎‎‏‎"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‎Proxied notification‎‏‎‎‏‎"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎Dismiss‎‏‎‎‏‎"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‏‏‎‏‎‎‏‏‏‎‎‎System navigation updated. To make changes, go to Settings.‎‏‎‎‏‎"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎Go to Settings to update system navigation‎‏‎‎‏‎"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‏‎‎Standby‎‏‎‎‏‎"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎The Android TV device will soon turn off; press a button to keep it on.‎‏‎‎‏‎"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎The device will soon turn off; press to keep it on.‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 46b402e..bc51e06 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"¿Quieres seguir viendo las notificaciones de esta app?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Silencio"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Alertas"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Cuadro"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Te ayuda a concentrarte sin sonar ni vibrar."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Capta tu atención con sonido o vibración."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Retiene tu atención con un acceso directo flotante a este contenido."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"No se pueden modificar estas notificaciones."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"No se puede configurar aquí este grupo de notificaciones"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificación almacenada en proxy"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignorar"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Se actualizó el sistema de navegación. Para hacer cambios, ve a Configuración."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Ve a Configuración para actualizar la navegación del sistema"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"En espera"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Pronto se apagará el dispositivo Android TV; presiona un botón para mantenerlo encendido."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Pronto se apagará el dispositivo; presiona para mantenerlo encendido."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index d45bf9f..99fac8c 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"¿Quieres seguir viendo las notificaciones de esta aplicación?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Silencio"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Alertas"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Burbuja"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Te ayuda a concentrarte sin sonido ni vibración."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Llama tu atención con sonido o vibración."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Llama tu atención con un acceso directo flotante a este contenido."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Estas notificaciones no se pueden modificar."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Este grupo de notificaciones no se puede configurar aquí"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificación mediante proxy"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Cerrar"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Se ha actualizado la navegación del sistema. Para hacer cambios, ve a Ajustes."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Ve a Ajustes para actualizar la navegación del sistema"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"En espera"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"El dispositivo Android TV pronto se apagará; pulsa un botón para evitarlo."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"El dispositivo pronto se apagará si no interactúas con él."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 3f7c835..b2b7152 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Kas jätkata selle rakenduse märguannete kuvamist?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Hääletu"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Teavitamine"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Aitab teil keskenduda (heli või vibreerimine puudub)."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Haarab heli või vibreerimisega teie tähelepanu."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Neid märguandeid ei saa muuta."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Seda märguannete rühma ei saa siin seadistada"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Puhvriga märguanne"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Loobu"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Süsteemis navigeerimine on värskendatud. Muutmiseks avage jaotis Seaded."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Süsteemi navigeerimise värskendamiseks avage jaotis Seaded"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Ooterežiim"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV seade lülitub varsti välja; selle aktiivsena hoidmiseks vajutage nuppu."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Seade lülitub värsti välja; selle aktiivsena hoidmiseks vajutage nuppu."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 841abde..4eb57db 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -239,9 +239,9 @@
     <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Hegaldi modua aktibatu egin da."</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"isiltasun osoa"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"alarmak soilik"</string>
-    <string name="accessibility_quick_settings_dnd" msgid="5555155552520665891">"Ez molestatu."</string>
-    <string name="accessibility_quick_settings_dnd_changed_off" msgid="2757071272328547807">"Desaktibatu egin da \"Ez molestatu\" eginbidea."</string>
-    <string name="accessibility_quick_settings_dnd_changed_on" msgid="6808220653747701059">"Aktibatu egin da \"Ez molestatu\" modua."</string>
+    <string name="accessibility_quick_settings_dnd" msgid="5555155552520665891">"Ez molestatzeko modua."</string>
+    <string name="accessibility_quick_settings_dnd_changed_off" msgid="2757071272328547807">"Desaktibatu egin da ez molestatzeko modua."</string>
+    <string name="accessibility_quick_settings_dnd_changed_on" msgid="6808220653747701059">"Aktibatu egin da ez molestatzeko modua."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth-a."</string>
     <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth konexioa desaktibatuta dago."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth konexioa aktibatuta dago."</string>
@@ -306,7 +306,7 @@
     <string name="start_dreams" msgid="5640361424498338327">"Pantaila-babeslea"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Aukera gehiago ikusteko, eduki sakatuta ikonoak"</string>
-    <string name="quick_settings_dnd_label" msgid="7112342227663678739">"Ez molestatu"</string>
+    <string name="quick_settings_dnd_label" msgid="7112342227663678739">"Ez molestatzeko modua"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Lehentasunezkoak soilik"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alarmak soilik"</string>
     <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Isiltasun osoa"</string>
@@ -469,7 +469,7 @@
     <string name="manage_notifications_text" msgid="2386728145475108753">"Kudeatu"</string>
     <string name="notification_section_header_gentle" msgid="4372438504154095677">"Soinurik gabeko jakinarazpenak"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Garbitu soinurik gabeko jakinarazpen guztiak"</string>
-    <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\"Ez molestatu\" moduak pausatu egin ditu jakinarazpenak"</string>
+    <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Ez molestatzeko moduak pausatu egin ditu jakinarazpenak"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Hasi"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ez dago jakinarazpenik"</string>
     <string name="profile_owned_footer" msgid="8021888108553696069">"Baliteke profila kontrolatuta egotea"</string>
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Aplikazio honen jakinarazpenak erakusten jarraitzea nahi duzu?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Isila"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Ohartarazlea"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Burbuila"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ez du egiten soinu edo dardararik, arretarik gal ez dezazun."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Arreta erakartzen du soinua eta dardara eginda."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Eduki honetarako lasterbide gainerakor bat eskaintzen dizu, arretarik gal ez dezazun."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Jakinarazpen horiek ezin dira aldatu."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Jakinarazpen talde hau ezin da konfiguratu hemen"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxy bidezko jakinarazpena"</string>
@@ -745,9 +747,9 @@
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendar"</string>
     <string name="tuner_full_zen_title" msgid="4540823317772234308">"Erakutsi bolumena kontrolatzeko aukerekin"</string>
-    <string name="volume_and_do_not_disturb" msgid="1750270820297253561">"Ez molestatu"</string>
+    <string name="volume_and_do_not_disturb" msgid="1750270820297253561">"Ez molestatzeko modua"</string>
     <string name="volume_dnd_silent" msgid="4363882330723050727">"Bolumen-botoietarako lasterbidea"</string>
-    <string name="volume_up_silent" msgid="7545869833038212815">"Irten \"Ez molestatu\" egoeratik bolumena igotzean"</string>
+    <string name="volume_up_silent" msgid="7545869833038212815">"Irten ez molestatzeko modutik bolumena igotzean"</string>
     <string name="battery" msgid="7498329822413202973">"Bateria"</string>
     <string name="clock" msgid="7416090374234785905">"Erlojua"</string>
     <string name="headset" msgid="4534219457597457353">"Mikrofonodun entzungailua"</string>
@@ -891,10 +893,10 @@
     <string name="mobile_carrier_text_format" msgid="3241721038678469804">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> (<xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>)"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi konexioa desaktibatuta dago"</string>
     <string name="bt_is_off" msgid="2640685272289706392">"Bluetooth konexioa desaktibatuta dago"</string>
-    <string name="dnd_is_off" msgid="6167780215212497572">"\"Ez molestatu\" modua desaktibatuta dago"</string>
-    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"\"Ez molestatu\" modua aktibatu du arau automatiko batek (<xliff:g id="ID_1">%s</xliff:g>)."</string>
-    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"\"Ez molestatu\" modua aktibatu du aplikazio batek (<xliff:g id="ID_1">%s</xliff:g>)."</string>
-    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"\"Ez molestatu\" modua aktibatu du arau automatiko edo aplikazio batek."</string>
+    <string name="dnd_is_off" msgid="6167780215212497572">"Ez molestatzeko modua desaktibatuta dago"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"Ez molestatzeko modua aktibatu du arau automatiko batek (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"Ez molestatzeko modua aktibatu du aplikazio batek (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"Ez molestatzeko modua aktibatu du arau automatiko edo aplikazio batek."</string>
     <string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> arte"</string>
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Utzi bere horretan"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Ordeztu"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Baztertu"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Eguneratu da sistemaren nabigazioa. Aldaketak egiteko, joan Ezarpenak atalera."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Sistemaren nabigazioa eguneratzeko, joan Ezarpenak atalera"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Egonean"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV gailua laster itzaliko da; sakatu botoi bat piztuta mantentzeko."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Gailua laster itzaliko da; sakatu piztuta mantentzeko."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 4f04220..5b7ab56 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"نمایش اعلان از این برنامه ادامه یابد؟"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"بی‌صدا"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"هشدار دادن"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"حباب"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"به شما کمک می‌کند بدون صدا یا لرزش تمرکز کنید."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"با صدا یا لرزش توجه شما را جلب می‌کند."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"با میان‌بری شناور به این محتوا، توجه‌تان را جلب می‌کند."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"این اعلان‌ها قابل اصلاح نیستند."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"نمی‌توانید این گروه اعلان‌ها را در اینجا پیکربندی کنید"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"اعلان‌های دارای پراکسی"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"رد کردن"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"پیمایش سیستم به‌روزرسانی شد. برای انجام تغییرات به «تنظیمات» بروید."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"برای به‌روزرسانی پیمایش سیستم، به «تنظیمات» بروید"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"آماده‌به‌کار"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"‏دستگاه Android TV به‌زودی خاموش می‌شود، برای روشن نگه‌داشتن آن، دکمه‌ای را فشار دهید."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"دستگاه به‌زودی خاموش می‌شود، برای روشن نگه‌داشتن آن فشار دهید."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 63bc925..30e687c 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Jatketaanko ilmoitusten näyttämistä tästä sovelluksesta?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Äänetön"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Hälyttää"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Kupla"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Keskittyminen on helpompaa ilman ääntä tai värinää."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Kiinnittää huomion äänellä tai värinällä"</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Kelluva sisällön pikakuvake säilyttää huomiosi"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Näitä ilmoituksia ei voi muokata"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Tätä ilmoitusryhmää ei voi määrittää tässä"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Välitetty ilmoitus"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ohita"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Järjestelmän navigointitapa vaihdettu. Voit muuttaa sitä asetuksista."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Vaihda järjestelmän navigointitapaa asetuksista"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Virransäästötila"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV ‑laite sammuu pian. Pidä se päällä painamalla painiketta."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Laite sammuu pian. Pidä se päällä painamalla jotakin."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index df8b8e4..205cf27 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuer à afficher les notifications de cette application?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Mode silencieux"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Alertes"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Vous aider à vous concentrer, sans son ni vibration."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Attire votre attention à l\'aide de sons et de vibrations."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ces notifications ne peuvent pas être modifiées"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ce groupe de notifications ne peut pas être configuré ici"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notification par mandataire"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Fermer"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"La navigation système a été mise à jour. Pour apporter des modifications, accédez au menu Paramètres."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Accédez au menu Paramètres pour mettre à jour la navigation système"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Veille"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"L\'appareil Android TV va bientôt s\'éteindre. Appuyez sur un bouton pour le laisser allumé."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"L\'appareil va bientôt s\'éteindre. Interagissez avec lui pour le laisser allumé."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 90a6987..9fdda0c 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuer d\'afficher les notifications de cette application ?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Silencieux"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Alertes"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Sans sons ni vibrations, vous aide à vous concentrer."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Attire votre attention à l\'aide de sons ou de vibrations."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Impossible de modifier ces notifications."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Vous ne pouvez pas configurer ce groupe de notifications ici"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notification de proxy"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignorer"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigation système mise à jour. Pour apporter des modifications, accédez aux paramètres."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Accédez aux paramètres pour mettre à jour la navigation système"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Mode Veille imminent"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"L\'appareil Android TV va bientôt passer en mode Veille. Appuyez sur un bouton pour qu\'il reste allumé."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"L\'appareil va bientôt passer en mode Veille. Appuyez dessus pour qu\'il reste allumé."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index a029e19..9edaf5d 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Queres seguir mostrando as notificacións desta aplicación?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Silenciosas"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Con alertas"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Axúdache a centrarte sen son nin vibración."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Chama a túa atención con son ou vibración."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Estas notificacións non se poden modificar."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Aquí non se pode configurar este grupo de notificacións"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificación mediante proxy"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignorar"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Actualizouse a navegación do sistema. Para facer cambios, vai a Configuración."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Para actualizar a navegación do sistema, vai a Configuración"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Modo de espera"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Pronto se apagará o dispositivo Android TV. Preme un botón para mantelo acendido."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Pronto se apagará o teléfono. Tócao para mantelo acendido."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 95d7f41..79d67a1 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"આ ઍપમાંથી નોટિફિકેશન બતાવવાનું ચાલુ રાખીએ?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"સાઇલન્ટ"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"અલર્ટ કરવાનું ચાલુ રાખો"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"તમને સાઉન્ડ અથવા વાઇબ્રેશન વિના ફોકસ કરવામાં સહાય કરે છે."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"સાઉન્ડ અથવા વાઇબ્રેશન વિના તમારું ધ્યાન દોરે છે."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"આ નોટિફિકેશનમાં કોઈ ફેરફાર થઈ શકશે નહીં."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"નોટિફિકેશનના આ ગ્રૂપની ગોઠવણી અહીં કરી શકાશે નહીં"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"પ્રૉક્સી નોટિફિકેશન"</string>
@@ -846,7 +850,7 @@
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"છોડી દેવા માટે નીચે ખેંચો"</string>
     <string name="pip_menu_title" msgid="4707292089961887657">"મેનૂ"</string>
     <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ચિત્રમાં-ચિત્રની અંદર છે"</string>
-    <string name="pip_notification_message" msgid="5619512781514343311">"જો તમે નથી ઈચ્છતા કે <xliff:g id="NAME">%s</xliff:g> આ સુવિધાનો ઉપયોગ કરે, તો સેટિંગ્સ ખોલવા માટે ટૅપ કરો અને તે સુવિધાને બંધ કરો."</string>
+    <string name="pip_notification_message" msgid="5619512781514343311">"જો તમે નથી ઇચ્છતા કે <xliff:g id="NAME">%s</xliff:g> આ સુવિધાનો ઉપયોગ કરે, તો સેટિંગ ખોલવા માટે ટૅપ કરો અને તેને બંધ કરો."</string>
     <string name="pip_play" msgid="1417176722760265888">"ચલાવો"</string>
     <string name="pip_pause" msgid="8881063404466476571">"થોભાવો"</string>
     <string name="pip_skip_to_next" msgid="1948440006726306284">"આગલા પર જાઓ"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"છોડી દો"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"સિસ્ટમ નૅવિગેશન અપડેટ કર્યું. ફેરફારો કરવા માટે, સેટિંગ પર જાઓ."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"સિસ્ટમ નૅવિગેશનને અપડેટ કરવા માટે સેટિંગ પર જાઓ"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"સ્ટૅન્ડબાય"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android ટીવી ડિવાઇસ ટૂંક સમયમાં બંધ થશે; તેને ચાલુ રાખવા માટે બટન દબાવો."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"ડિવાઇસ ટૂંક સમયમાં બંધ થશે; તેને ચાલુ રાખવા માટે દબાવો."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 4c6edc1..aa163ab 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"इस ऐप्लिकेशन से जुड़ी सूचनाएं दिखाना जारी रखें?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"आवाज़ के बिना सूचनाएं दिखाएं"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"चेतावनी वाली सूचनाएं"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"आवाज़ या वाइब्रेशन न होने की वजह से आप काम में ध्यान लगा पाते हैं."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"आवाज़ या वाइब्रेशन होने की वजह से आपका ध्यान सूचनाओं पर जाता है."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ये सूचनाएं नहीं बदली जा सकती हैं."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"सूचनाओं के इस समूह को यहां कॉन्फ़िगर नहीं किया जा सकता"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"प्रॉक्सी सूचना"</string>
@@ -845,7 +849,7 @@
     <string name="pip_phone_settings" msgid="8080777499521528521">"सेटिंग"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"खारिज करने के लिए नीचे खींचें और छोड़ें"</string>
     <string name="pip_menu_title" msgid="4707292089961887657">"मेन्यू"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> पिक्चर में पिक्चर के अंदर है"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> \"पिक्चर में पिक्चर\" के अंदर है"</string>
     <string name="pip_notification_message" msgid="5619512781514343311">"अगर आप नहीं चाहते कि <xliff:g id="NAME">%s</xliff:g> इस सुविधा का उपयोग करे, तो सेटिंग खोलने के लिए टैप करें और उसे बंद करें ."</string>
     <string name="pip_play" msgid="1417176722760265888">"चलाएं"</string>
     <string name="pip_pause" msgid="8881063404466476571">"रोकें"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"खारिज करें"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"सिस्टम नेविगेशन अपडेट हो गया. बदलाव करने के लिए \'सेटिंग\' पर जाएं."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"सिस्टम नेविगेशन अपडेट करने के लिए \'सेटिंग\' में जाएं"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"स्टैंडबाई"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV डिवाइस जल्द ही बंद हो जाएगा. इसे चालू रखने के लिए किसी बटन को दबाएं."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"डिवाइस जल्द ही बंद हो जाएगा. इसे चालू रखने के लिए स्क्रीन पर टैप करें या किसी बटन को दबाएं."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index e633878..4943dc6 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -664,8 +664,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Želite li da se obavijesti te aplikacije nastave prikazivati?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Bešumno"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Upozoravanje"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Oblačić"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomaže vam da se usredotočite bez zvučnih signala i vibracija."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Privlači vašu pažnju zvučnim signalima ili vibracijama."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Održava vam pozornost pomoću plutajućeg prečaca ovom sadržaju."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Te se obavijesti ne mogu izmijeniti."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ta se grupa obavijesti ne može konfigurirati ovdje"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Obavijest poslana putem proxyja"</string>
@@ -951,4 +953,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Odbaci"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Ažurirana je navigacija sustavom. Možete je promijeniti u Postavkama."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Navigaciju sustavom možete ažurirati u Postavkama"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Stanje mirovanja"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Uređaj Android TV uskoro će se isključiti. Pritisnite gumb da bi ostao uključen."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Uređaj će se uskoro isključiti. Pritisnite da bi ostao uključen."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 299e318..f2233cd 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Továbbra is megjelenjenek az alkalmazás értesítései?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Néma"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Figyelemfelkeltő"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Hangjelzés és rezgés nélkül segít a koncentrálásban."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Figyelemfelkeltő a hangjelzésnek és rezgésnek köszönhetően."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ezeket az értesítéseket nem lehet módosítani."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Az értesítések jelen csoportját itt nem lehet beállítani"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Továbbított értesítés"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Elvetés"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"A rendszer-navigáció módja megváltozott. Módosításához nyissa meg a Beállításokat."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"A rendszer-navigációs lehetőségeket a Beállításokban módosíthatja"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Készenléti mód"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Az Android TV eszköz hamarosan kikapcsol. Nyomja meg valamelyik gombot, hogy bekapcsolva tarthassa."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Az eszköz hamarosan kikapcsol. Nyomja meg, hogy bekapcsolva tarthassa."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 6291d5d..bbc5ef4 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Ցուցադրե՞լ ծանուցումներ այս հավելվածից։"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Անձայն"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Ծանուցումներ"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ծանուցումները գալիս են առանց ձայնի և թրթռոցի։"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Ծանուցումները գալիս են ձայնով կամ թրթռոցով։"</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Այս ծանուցումները չեն կարող փոփոխվել:"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ծանուցումների տվյալ խումբը հնարավոր չէ կարգավորել այստեղ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Ծանուցումն ուղարկվել է պրոքսի սերվերի միջոցով"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Փակել"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Համակարգի նավիգացիան թարմացվեց: Փոփոխություններ անելու համար անցեք կարգավորումներ:"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Թարմացրեք համակարգի նավիգացիան կարգավորումներում"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Սպասման ռեժիմ"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV սարքը շուտով կանջատվի: Սեղմեք որևէ կոճակ՝ միացրած թողնելու համար:"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Սարքը շուտով կանջատվի: Սեղմեք՝ միացրած թողնելու համար:"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index b9eaddf..e17e5f9 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Terus tampilkan notifikasi dari aplikasi ini?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Senyap"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Pemberitahuan"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Balon"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Membantu Anda tetap fokus tanpa suara atau getaran."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Menarik perhatian Anda dengan suara atau getaran."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Menjaga perhatian dengan pintasan floating ke konten ini."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Notifikasi ini tidak dapat diubah."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Grup notifikasi ini tidak dapat dikonfigurasi di sini"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notifikasi proxy"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Tutup"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigasi sistem diupdate. Untuk melakukan perubahan, buka Setelan."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Buka Setelan untuk mengupdate navigasi sistem"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Siaga"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Perangkat Android TV akan segera dinonaktifkan; tekan tombol untuk terus menyalakannya."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Perangkat akan segera dinonaktifkan, tekan untuk terus menyalakannya."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index f98b943..00776a9 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Sýna áfram tilkynningar frá þessu forriti?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Hljóðlaust"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Viðvörun"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Blaðra"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Auðveldar þér að einbeita þér án hljóðs eða titrings."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Fangar athygli þína með hljóði eða titringi."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Fangar athygli þína með fljótandi flýtileið á þetta efni."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ekki er hægt að breyta þessum tilkynningum."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ekki er hægt að stilla þessar tilkynningar hér"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Staðgengilstilkynning"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Hunsa"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Kerfisstjórnun uppfærð. Þú getur breytt þessu í stillingunum."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Farðu í stillingar til að uppfæra kerfisstjórnun"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Biðstaða"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV tækið slekkur á sér fljótlega. Ýttu á takka til að það slokkni ekki á því."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Tækið slekkur á sér fljótlega. Ýttu á takka til að það slokkni ekki á því."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index c08cdd3..2c27009 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuare a ricevere notifiche da questa app?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Modalità silenziosa"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Avvisi"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Fumetto"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Favorisce la tua concentrazione grazie all\'assenza di suono o vibrazione."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Richiama la tua attenzione con suono o vibrazione."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Mantiene la tua attenzione con una scorciatoia mobile a questi contenuti."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Impossibile modificare queste notifiche."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Qui non è possibile configurare questo gruppo di notifiche"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notifica inviata al proxy"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignora"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigazione del sistema aggiornata. Per apportare modifiche, usa le Impostazioni."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Usa le Impostazioni per aggiornare la navigazione del sistema"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Standby"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"A breve il dispositivo Android TV si spegnerà. Premi un pulsante per tenerlo acceso."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"A breve il dispositivo si spegnerà. Premi per tenerlo acceso."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index fc0c640..64074a8 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -667,8 +667,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"שנמשיך להציג לך התראות מהאפליקציה הזאת?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"שקט"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"שליחת התראות"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"עוזרת להתרכז ללא צלילים או רטט."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"מעוררת תשומת לב באמצעות צלילים או רטט."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"לא ניתן לשנות את ההתראות האלה."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"לא ניתן להגדיר כאן את קבוצת ההתראות הזו"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"‏התראה דרך שרת proxy"</string>
@@ -956,4 +960,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"סגירה"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"הניווט במערכת עודכן. אפשר לערוך שינויים דרך ההגדרות."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"יש לעבור להגדרות כדי לעדכן את הניווט במערכת"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"המתנה"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"‏מכשיר Android TV ייכבה בקרוב. יש ללחוץ על לחצן כלשהו כדי שהוא ימשיך לפעול."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"המכשיר ייכבה בקרוב, יש ללחוץ כדי שהוא ימשיך לפעול."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 351ace80..684c16e 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"このアプリからの通知を今後も表示しますか?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"サイレント"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"アラートを受け取る"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"バブル"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"音やバイブレーションが作動しないため、通知に煩わされずに済みます。"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"音やバイブレーションで通知をお知らせします。"</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"このコンテンツのフローティング ショートカットで通知をお知らせします。"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"これらの通知は変更できません。"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"このグループの通知はここでは設定できません"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"代理通知"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"閉じる"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"システム ナビゲーションを更新しました。変更するには [設定] に移動してください。"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"システム ナビゲーションを更新するには [設定] に移動してください"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"スタンバイ"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV デバイスはまもなく OFF になります。ON 状態を維持するには、ボタンを押してください。"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"このデバイスはまもなく OFF になります。ON 状態を維持するには、ボタンを押してください。"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 8c10ea4..e205586 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"გაგრძელდეს შეტყობინებათა ჩვენება ამ აპიდან?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"ჩუმი"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"გამაფრთხილებელი"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"ბუშტი"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"გეხმარებათ ფოკუსირებაში ხმის ან ვიბრაციის უქონლობის გამო."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"იპყრობს თქვენს ყურადღებას ხმით ან ვიბრაციით."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"იპყრობს თქვენს ყურადღებას ამ კონტენტის მოლივლივე მალსახმობით."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ამ შეტყობინებების შეცვლა შეუძლებელია."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"შეტყობინებების ამ ჯგუფის კონფიგურირება აქ შეუძლებელია"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"პროქსირებული შეტყობინება"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"დახურვა"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"სისტემური ნავიგაცია განახლდა. ცვლილებების შესატანად გადადით პარამეტრებზე."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"სისტემური ნავიგაციის გასაახლებლად გადადით პარამეტრებზე"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"მოლოდინის რეჟიმი"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV მოწყობილობა მალე გამოირთვება, დააჭირეთ ღილაკს, რომ ჩართული დარჩეს."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"მოწყობილობა მალე გამოირთვება, დააჭირეთ, რომ ჩართული დარჩეს."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index c646715..1c288f1 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Осы қолданбаның хабарландырулары көрсетілсін бе?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Дыбыссыз"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Ескертулер"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Көпіршік"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Хабарландырулар келгенде, дыбыс шықпайды не дірілдемейді"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Хабарландырулар келгенде, дыбыс шығады не дірілдейді"</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Осы мазмұнға бекітілген қалқымалы таңбашамен назарыңызды өзіне тартады."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Бұл хабарландыруларды өзгерту мүмкін емес."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Мұндай хабарландырулар бұл жерде конфигурацияланбайды."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Прокси-сервер арқылы жіберілген хабарландыру"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Жабу"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Жүйе навигациясы жаңартылды. Өзгерту енгізу үшін \"Параметрлер\" бөліміне өтіңіз."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Жүйе навигациясын жаңарту үшін \"Параметрлер\" бөліміне өтіңіз."</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Күту режимі"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV құрылғысы жақын арада өшеді. Оны қосулы қалдыру үшін басыңыз."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Құрылғы жақын арада өшеді. Оны қосулы қалдыру үшін басыңыз."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 042ffd8..dd28931 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"បន្ត​បង្ហាញ​ការជូនដំណឹង​ពីកម្មវិធីនេះ?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"ស្ងាត់"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"បញ្ចេញ​សំឡេង"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"ពពុះ"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"ជួយឱ្យ​អ្នក​ផ្តោតអារម្មណ៍ ដោយមិនឮសំឡេង ឬ​ការញ័រ។"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"ធ្វើឱ្យ​អ្នក​ចាប់អារម្មណ៍​តាមរយៈ​សំឡេង ឬ​ការញ័រ។"</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"ធ្វើឱ្យអ្នក​ចាប់អារម្មណ៍​ដោយប្រើ​ផ្លូវកាត់​អណ្ដែត​សម្រាប់ខ្លឹមសារនេះ។"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"មិនអាច​កែប្រែ​ការជូនដំណឹង​ទាំងនេះ​បានទេ។"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"មិនអាច​កំណត់​រចនាសម្ព័ន្ធ​ក្រុមការជូនដំណឹងនេះ​នៅទីនេះ​បានទេ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ការជូនដំណឹង​ជា​ប្រូកស៊ី"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ច្រានចោល"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"បានធ្វើ​បច្ចុប្បន្នភាព​ការរុករកក្នុង​ប្រព័ន្ធ។ ដើម្បីធ្វើការផ្លាស់ប្ដូរ សូមចូលទៅ​កាន់ការកំណត់។"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ចូល​ទៅកាន់​ការកំណត់ ដើម្បី​ធ្វើបច្ចុប្បន្នភាព​ការរុករក​ក្នុង​ប្រព័ន្ធ"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"ផ្អាក​ដំណើរការ"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"ឧបករណ៍ Android TV នឹង​បិទ​ក្នុងពេល​ឆាប់ៗនេះ សូមចុច​ប៊ូតុង​ដើម្បី​បន្ត​បើក​ឧបករណ៍។"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"ឧបករណ៍​នឹង​បិទ​ក្នុងពេល​ឆាប់ៗនេះ សូមចុច​ដើម្បី​បន្ត​បើក​ឧបករណ៍។"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index f208298..3a4918b 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ಈ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸುತ್ತಲೇ ಇರಬೇಕೆ?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"ನಿಶ್ಶಬ್ದ"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"ಎಚ್ಚರಿಸಲಾಗುತ್ತಿದೆ"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"ಶಬ್ದ ಅಥವಾ ವೈಬ್ರೇಷನ್ ಇರದಂತೆ ನಿಮಗೆ ಗಮನಹರಿಸಲು ಸಹಾಯ ಮಾಡುತ್ತದೆ."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"ಧ್ವನಿ ಅಥವಾ ವೈಬ್ರೇಷನ್ ಮೂಲಕ ನಿಮ್ಮ ಗಮನವನ್ನು ಸೆಳೆಯುತ್ತದೆ."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ಈ ಗುಂಪಿನ ಅಧಿಸೂಚನೆಗಳನ್ನು ಇಲ್ಲಿ ಕಾನ್ಫಿಗರ್‌ ಮಾಡಲಾಗಿರುವುದಿಲ್ಲ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ಪ್ರಾಕ್ಸಿ ಮಾಡಿದ ಅಧಿಸೂಚನೆಗಳು"</string>
@@ -845,7 +849,7 @@
     <string name="pip_phone_settings" msgid="8080777499521528521">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"ವಜಾಗೊಳಿಸಲು ಕೆಳಕ್ಕೆ ಡ್ರ್ಯಾಗ್ ಮಾಡಿ"</string>
     <string name="pip_menu_title" msgid="4707292089961887657">"ಮೆನು"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ಚಿತ್ರದಲ್ಲಿನ ಚಿತ್ರದಲ್ಲಿದೆ"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರವಾಗಿದೆ"</string>
     <string name="pip_notification_message" msgid="5619512781514343311">"<xliff:g id="NAME">%s</xliff:g> ಈ ವೈಶಿಷ್ಟ್ಯ ಬಳಸುವುದನ್ನು ನೀವು ಬಯಸದಿದ್ದರೆ, ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಲು ಮತ್ತು ಅದನ್ನು ಆಫ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="pip_play" msgid="1417176722760265888">"ಪ್ಲೇ"</string>
     <string name="pip_pause" msgid="8881063404466476571">"ವಿರಾಮಗೊಳಿಸಿ"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ವಜಾಗೊಳಿಸಿ"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ ಅಪ್‌ಡೇಟ್ ಮಾಡಲಾಗಿದೆ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಲು, ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ಹೋಗಿ."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ್ ಅಪ್‌ಡೇಟ್ ಮಾಡಲು ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ಹೋಗಿ"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"ಸ್ಟ್ಯಾಂಡ್‌ಬೈ"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"ಈ Android TV ಸಾಧನವು ಶೀಘ್ರವೇ ಆಫ್ ಆಗುತ್ತದೆ; ಇದನ್ನು ಆನ್‌ನಲ್ಲಿಡಲು ಬಟನ್ ಅನ್ನು ಒತ್ತಿರಿ."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"ಈ ಸಾಧನವು ಶೀಘ್ರವೇ ಆಫ್ ಆಗುತ್ತದೆ; ಇದನ್ನು ಆನ್‌ನಲ್ಲಿಡಲು ಒತ್ತಿರಿ."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index c57d98f..2848a49 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"이 앱의 알림을 계속 표시하시겠습니까?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"무음"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"주의를 끄는 알림"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"소리나 진동 없이 집중할 수 있도록 도와줍니다"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"소리나 진동으로 알립니다."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"이 알림은 수정할 수 없습니다."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"이 알림 그룹은 여기에서 설정할 수 없습니다."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"프록시를 통한 알림"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"닫기"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"시스템 탐색이 업데이트되었습니다. 변경하려면 설정으로 이동하세요."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"설정으로 이동하여 시스템 탐색을 업데이트하세요."</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"대기"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV가 곧 꺼집니다. 계속 사용하려면 버튼을 누르세요."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"기기가 곧 꺼집니다. 계속 사용하려면 누르세요."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index b712d62..7a5e568 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Бул колдонмонун эскертмелери көрсөтүлө берсинби?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Үнсүз"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Шашылыш билдирүү"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Үн же дирилдөөсүз ой топтоого жардам берет."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Билдирүүдөн үн чыгат же дирилдейт."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Бул билдирмелерди өзгөртүүгө болбойт."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Бул билдирмелердин тобун бул жерде конфигурациялоого болбойт"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Прокси билдирмеси"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Жабуу"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Тутум чабыттоосу жаңыртылды. Өзгөртүү үчүн, Жөндөөлөргө өтүңүз."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Тутум чабыттоосун жаңыртуу үчүн Жөндөөлөргө өтүңүз"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Көшүү режими"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV түзмөгү жакында өчүрүлөт, аны күйүк боюнча калтыруу үчүн баскычты басыңыз."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Түзмөк жакында өчүрүлөт, күйүк боюнча калтыруу үчүн басып коюңуз."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 7440be7..550923c 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ສະແດງການແຈ້ງເຕືອນຈາກແອັບນີ້ຕໍ່ໄປບໍ?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"ປິດສຽງ"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"ການເຕືອນ"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"ຟອງ"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"ຊ່ວຍທ່ານມີສະມາທິໂດຍບໍ່ໃຊ້ສຽງ ຫຼື ການສັ່ນເຕືອນ."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"ດຶງຄວາມສົນໃຈຂອງທ່ານດ້ວຍສຽງ ຫຼື ການສັ່ນເຕືອນ."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"ເອົາໃຈໃສ່ທາງລັດແບບລອຍໄປຫາເນື້ອຫານີ້."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ບໍ່ສາມາດແກ້ໄຂການແຈ້ງເຕືອນເຫຼົ່ານີ້ໄດ້."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ບໍ່ສາມາດຕັ້ງຄ່າກຸ່ມການແຈ້ງເຕືອນນີ້ຢູ່ບ່ອນນີ້ໄດ້"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ການແຈ້ງເຕືອນແບບພຣັອກຊີ"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ປິດໄວ້"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ອັບເດດການນຳທາງລະບົບແລ້ວ. ເພື່ອປ່ຽນແປງ, ກະລຸນາໄປທີ່ການຕັ້ງຄ່າ."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ໄປທີ່ການຕັ້ງຄ່າເພື່ອອັບເດດການນຳທາງລະບົບ"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"ສະແຕນບາຍ"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"ອຸປະກອນ Android TV ຈະປິດໃນອີກບໍ່ດົນ, ກົດປຸ່ມໃດໜຶ່ງເພື່ອເປີດມັນໄວ້ຕໍ່."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"ອຸປະກອນຈະປິດໃນອີກບໍ່ດົນ, ກົດເພື່ອເປີດມັນໄວ້ຕໍ່."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 4a2281d..584f5db 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -667,8 +667,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Toliau rodyti iš šios programos gautus pranešimus?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Tylūs"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Įspėti"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Debesėlis"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Padeda atkreipti dėmesį be garso arba vibravimo."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Atkreipia dėmesį garsu arba vibravimu."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Naudojant slankųjį spartųjį klavišą lengviau sutelkti dėmesį į šį turinį."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Šių pranešimų keisti negalima."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Šios grupės pranešimai čia nekonfigūruojami"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Per tarpinį serverį gautas pranešimas"</string>
@@ -956,4 +958,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Atmesti"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Sistemos naršymo funkcijos atnaujintos. Jei norite pakeisti, eikite į skiltį „Nustatymai“."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Eikite į skiltį „Nustatymai“, kad atnaujintumėte sistemos naršymo funkcijas"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Budėjimo laikas"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"„Android TV“ įrenginys netrukus išsijungs. Paspauskite mygtuką, kad jis liktų įjungtas."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Įrenginys netrukus išsijungs. Paspauskite, kad jis liktų įjungtas."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 2505636..807a0d8 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -664,8 +664,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vai turpināt rādīt paziņojumus no šīs lietotnes?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Klusums"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Brīdinājumu saņemšana"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Palīdz jums koncentrēties, nenovēršot uzmanību ar skaņu vai vibrāciju."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Jūsu uzmanība tiek piesaistīta ar skaņas vai vibrācijas signālu."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Šos paziņojumus nevar modificēt."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Šeit nevar konfigurēt šo paziņojumu grupu."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Starpniekservera paziņojums"</string>
@@ -951,4 +955,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Nerādīt"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Sistēmas navigācija ir atjaunināta. Lai veiktu izmaiņas, atveriet iestatījumus."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Atveriet iestatījumus, lai atjauninātu sistēmas navigāciju"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Gaidstāve"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV ierīce drīz izslēgsies. Nospiediet pogu, lai tā paliktu ieslēgta."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Ierīce drīz izslēgsies. Nospiediet, lai tā paliktu ieslēgta."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index d2eab61..8b10719 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Дали да продолжат да се прикажуваат известувања од апликацијава?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Тивко"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Предупредувај"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Балонче"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ви помага да се концентрирате без звук или вибрации."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Ви го привлекува вниманието со звук или вибрации."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Ви го задржува вниманието со лебдечка кратенка на содржинава."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Овие известувања не може да се изменат"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Оваа група известувања не може да се конфигурира тука"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Известување преку прокси"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Отфрли"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Навигацијата на системот е ажурирана. За да извршите промени, одете во „Поставки“."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Одете во „Поставки“ за да ја ажурирате навигацијата на системот"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Подготвеност"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Уредот со Android TV наскоро ќе се исклучи, притиснете копче за да остане вклучен."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Уредот наскоро ќе се исклучи, притиснете за да остане вклучен."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index ca79e12..a013409 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ഈ ആപ്പിൽ നിന്നുള്ള അറിയിപ്പുകൾ തുടർന്നും കാണിക്കണോ?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"നിശബ്‌ദം"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"മുന്നറിയിപ്പ് നൽകൽ"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"ശബ്‌ദമോ വൈബ്രേഷനോ ഇല്ലാതെ ശ്രദ്ധ കേന്ദ്രീകരിക്കാൻ നിങ്ങളെ സഹായിക്കുന്നു."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"ശബ്‌ദമോ വെെബ്രേഷനോ ഉപയോഗിച്ച് നിങ്ങളുടെ ശ്രദ്ധ ക്ഷണിക്കുന്നു."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ഈ അറിയിപ്പുകൾ പരിഷ്ക്കരിക്കാനാവില്ല."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"അറിയിപ്പുകളുടെ ഈ ഗ്രൂപ്പ് ഇവിടെ കോണ്‍ഫിഗര്‍ ചെയ്യാൻ കഴിയില്ല"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"പ്രോക്‌സി അറിയിപ്പ്"</string>
@@ -845,8 +849,8 @@
     <string name="pip_phone_settings" msgid="8080777499521528521">"ക്രമീകരണം"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"തള്ളിക്കളയാൻ താഴേക്ക് വലിച്ചിടുക"</string>
     <string name="pip_menu_title" msgid="4707292089961887657">"മെനു"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ചിത്രത്തിനുള്ളിലെ ചിത്രത്തിലാണ്"</string>
-    <string name="pip_notification_message" msgid="5619512781514343311">"<xliff:g id="NAME">%s</xliff:g> ഈ ഫീച്ചർ ഉപയോഗിക്കുന്നതിൽ നിങ്ങൾക്ക് താൽപ്പര്യമില്ലെങ്കിൽ, ടാപ്പുചെയ്‌ത് ക്രമീകരണം തുറന്ന് അത് ഓഫാക്കുക."</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ചിത്രത്തിനുള്ളിൽ ചിത്രം രീതിയിലാണ്"</string>
+    <string name="pip_notification_message" msgid="5619512781514343311">"<xliff:g id="NAME">%s</xliff:g> ഈ ഫീച്ചർ ഉപയോഗിക്കേണ്ടെങ്കിൽ, ടാപ്പ് ചെയ്‌ത് ക്രമീകരണം തുറന്ന് അത് ഓഫാക്കുക."</string>
     <string name="pip_play" msgid="1417176722760265888">"പ്ലേ ചെയ്യുക"</string>
     <string name="pip_pause" msgid="8881063404466476571">"താൽക്കാലികമായി നിർത്തുക"</string>
     <string name="pip_skip_to_next" msgid="1948440006726306284">"അടുത്തതിലേക്ക് പോകുക"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ഡിസ്‌മിസ് ചെയ്യുക"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"സിസ്‌റ്റം നാവിഗേഷൻ അപ്‌ഡേറ്റ് ചെയ്‌തു. മാറ്റങ്ങൾ വരുത്താൻ ക്രമീകരണത്തിലേക്ക് പോവുക."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"സിസ്‌റ്റം നാവിഗേഷൻ അപ്‌ഡേറ്റ് ചെയ്യാൻ ക്രമീകരണത്തിലേക്ക് പോവുക"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"സ്‌റ്റാൻഡ്‌ബൈ"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android ടിവി ഉടൻ ഓഫാകും, ഓണാക്കി നിർത്താൻ ഒരു ബട്ടൺ അമർത്തുക."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"ഉപകരണം ഉടൻ ഓഫാകും, ഓണാക്കി നിർത്താൻ അമർത്തുക."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 50bb578..fc07a8a 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Энэ аппаас мэдэгдэл харуулсан хэвээр байх уу?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Чимээгүй"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Дуутай"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Дуу эсвэл чичиргээгүйгээр танд төвлөрөхөд тусална."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Дуу эсвэл чичиргээгүйгээр таны анхаарлыг татна."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Эдгээр мэдэгдлийг өөрчлөх боломжгүй."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Энэ бүлэг мэдэгдлийг энд тохируулах боломжгүй байна"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Прокси хийсэн мэдэгдэл"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Үл хэрэгсэх"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Системийн навигацыг шинэчиллээ. Өөрчлөхийн тулд Тохиргоо руу очно уу."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Системийн навигацыг шинэчлэхийн тулд Тохиргоо руу очно уу"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Зогсолтын горим"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Андройд ТВ төхөөрөмж удахгүй унтрах тул асаалттай хэвээр байлгахын тулд дарна уу."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Төхөөрөмж удахгүй унтрах тул асаалттай хэвээр байлгахын тулд дарна уу."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index d6a54f8..e41ac3b 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"या अ‍ॅपकडील सूचना दाखवणे सुरू ठेवायचे?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"सायलंट"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"सूचना देत आहे"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"आवाज किंवा व्हायब्रेशनशिवाय तुम्हाला लक्ष केंद्रित करण्यास मदत करते."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"आवाज किंवा व्हायब्रेशनने तुमचे लक्ष वेधून घेते."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"या सूचनांमध्ये सुधारणा केली जाऊ शकत नाही."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"या सूचनांचा संच येथे कॉन्फिगर केला जाऊ शकत नाही"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"प्रॉक्सी केलेल्या सूचना"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"डिसमिस करा"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"सिस्टम नेव्हिगेशन अपडेट केले. बदल करण्यासाठी, सेटिंग्जवर जा."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"सिस्टम नेव्हिगेशन अपडेट करण्यासाठी सेटिंग्जवर जा"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"स्टँडबाय"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV डिव्हाइस लवकरच बंद होणार आहे; सुरू ठेवण्यासाठी बटण दाबा."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"डिव्हाइस लवकरच बंद होणार आहे; सुरू ठेवण्यासाठी दाबा."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 0faaa5f..880a4d9 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Terus tunjukkan pemberitahuan daripada apl ini?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Senyap"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Memaklumi"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Gelembung"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Membantu anda fokus tanpa bunyi atau getaran."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Menarik perhatian anda dengan bunyi atau getaran."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Memastikan anda memberikan perhatian dengan pintasan terapung ke kandungan ini."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Pemberitahuan ini tidak boleh diubah suai."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Kumpulan pemberitahuan ini tidak boleh dikonfigurasikan di sini"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Pemberitahuan berproksi"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ketepikan"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigasi sistem dikemas kini. Untuk membuat perubahan, pergi ke Tetapan."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Pergi ke Tetapan untuk mengemas kini navigasi sistem"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Tunggu sedia"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Peranti Android TV akan mati tidak lama lagi; tekan butang untuk memastikan peranti terus hidup."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Peranti akan mati tidak lama lagi; tekan untuk memastikan peranti terus hidup."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 566dc66..2b7dab7 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ဤအက်ပ်ထံမှ အကြောင်းကြားချက်များကို ဆက်ပြလိုပါသလား။"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"အသံတိတ်ရန်"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"သတိပေးခြင်း"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"အသံ သို့မဟုတ် တုန်ခါမှု မပါဘဲ အာရုံစိုက်နိုင်စေရန် ကူညီပေးသည်။"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"အသံ သို့မဟုတ် တုန်ခါမှုဖြင့် အာရုံစိုက်လာအောင် ပြုလုပ်သည်။"</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ဤအကြောင်းကြားချက်များကို ပြုပြင်၍ မရပါ။"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ဤအကြောင်းကြားချက်အုပ်စုကို ဤနေရာတွင် စီစဉ်သတ်မှတ်၍ မရပါ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ပရောက်စီထည့်ထားသော အကြောင်းကြားချက်"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ပယ်ရန်"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ပြီးပါပြီ။ အပြောင်းအလဲများ ပြုလုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ။"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"အသင့်အနေအထား"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV စက်သည် မကြာမီ ပိတ်သွားပါမည်၊ ဆက်ဖွင့်ထားရန် ခလုတ်တစ်ခုနှိပ်ပါ။"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"စက်သည် အကြာမီ ပိတ်သွားပါမည်၊ ဆက်ဖွင့်ထားပါ။"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index aabdd8b9..e76b9e2 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vil du fortsette å vise varsler fra denne appen?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Lydløs"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Varsling"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Boble"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Hjelper deg med å fokusere uten lyd eller vibrering."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Får oppmerksomheten din med lyd eller vibrering."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Holder deg oppmerksom med en svevende snarvei til dette innholdet."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Disse varslene kan ikke endres."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Denne varselgruppen kan ikke konfigureres her"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Omdirigert varsel"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Avvis"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systemnavigeringen er oppdatert. For å gjøre endringer, gå til Innstillinger."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Gå til Innstillinger for å oppdatere systemnavigeringen"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Ventemodus"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV-enheten slås snart av. Trykk på en knapp for å holde den på."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Enheten slås snart av. Trykk for å holde den på."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index ebffa2f..86b6d76 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"यो अनुप्रयोगका सूचनाहरू देखाउने क्रम जारी राख्ने हो?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"मौन"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"सतर्क गराउँदै"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"तपाईंलाई आवाज वा कम्पनविना ध्यान केन्द्रित गर्न मद्दत गर्छ।"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"ध्वनि वा कम्पनमार्फत तपाईंको ध्यान आकर्षित गर्छ।"</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"यी सूचनाहरू परिमार्जन गर्न मिल्दैन।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"यहाँबाट सूचनाहरूको यो समूह कन्फिगर गर्न सकिँदैन"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"प्रोक्सीमार्फत आउने सूचना"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"हटाउनुहोस्"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"प्रणालीको नेभिगेसन अद्यावधिक गरियो। परिवर्तन गर्न सेटिङमा जानुहोस्।"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"प्रणालीको नेभिगेसन अद्यावधिक गर्न सेटिङमा जानुहोस्"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"स्ट्यान्डबाई"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV यन्त्र चाँडै निष्क्रिय हुने छ; सक्रिय राख्न कुनै बटन थिच्नुहोस्।"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"यो यन्त्र चाँडै निष्क्रिय हुने छ; सक्रिय राख्न थिच्नुहोस्।"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index aa68dce..527af29 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Meldingen van deze app blijven weergeven?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Stil"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Waarschuwen"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Bubbel"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helpt je focussen zonder geluid of trilling."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Trekt je aandacht met geluid of trillingen."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Trekt de aandacht met een zwevende snelkoppeling naar deze content."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Deze meldingen kunnen niet worden aangepast."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Deze groep meldingen kan hier niet worden geconfigureerd"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Melding via proxy"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Sluiten"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systeemnavigatie geüpdatet. Als je wijzigingen wilt aanbrengen, ga je naar Instellingen."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Ga naar Instellingen om de systeemnavigatie te updaten"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Stand-by"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Het Android TV-apparaat wordt binnenkort uitgeschakeld. Druk op een knop om het ingeschakeld te houden."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Het apparaat wordt binnenkort uitgeschakeld. Druk om het ingeschakeld te houden."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 0985196..c401d75 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ଏହି ଆପ୍‌ରୁ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଦେଖାଇବା ଜାରି ରଖିବେ?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"ନୀରବ"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"ଆଲର୍ଟ କରିବା"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"ବିନା ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍‌ରେ ଆପଣଙ୍କୁ ଫୋକସ୍ କରିବାରେ ସାହାଯ୍ୟ କରେ।"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍ ମାଧ୍ୟମରେ ଆପଣଙ୍କର ଧ୍ୟାନ ଆକର୍ଷିତ କରିଥାଏ।"</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପରିବର୍ତ୍ତନ କରିହେବ ନାହିଁ।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ଏଠାରେ ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଗ୍ରୁପ୍ କନଫ୍ୟୁଗର୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ବିଜ୍ଞପ୍ତି ପ୍ରକ୍ସୀ ହୋଇଛି"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ଖାରଜ କରନ୍ତୁ"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍‌ଡେଟ୍ ହୋଇଛି। ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ, ସେଟିଂସ୍‌କୁ ଯାଆନ୍ତୁ।"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍‌ଡେଟ୍ କରିବା ପାଇଁ ସେଟିଂସ୍‍କୁ ଯାଆନ୍ତୁ"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"ଷ୍ଟାଣ୍ଡବାଏ"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android ଟିଭି ଡିଭାଇସ୍ ଶୀଘ୍ର ବନ୍ଦ ହୋଇଯିବ; ଏହା ଚାଲୁ ରଖିବା ପାଇଁ ଏକ ବଟନ୍ ଦବାନ୍ତୁ।"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"ଡିଭାଇସ୍ ଶୀଘ୍ର ବନ୍ଦ ହୋଇଯିବ; ଚାଲୁ ରଖିବା ପାଇଁ ଦବାନ୍ତୁ।"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index cf7f3e9..fc5aea3 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ਕੀ ਇਸ ਐਪ ਤੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਦਿਖਾਉਣਾ ਜਾਰੀ ਰੱਖਣਾ ਹੈ?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"ਸ਼ਾਂਤ"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"ਸੁਚੇਤਨਾ"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"ਤੁਹਾਨੂੰ ਬਿਨਾਂ ਧੁਨੀ ਅਤੇ ਥਰਥਰਾਹਟ ਦੇ ਫੋਕਸ ਕਰਨ ਵਿੱਚ ਮਦਦ ਕਰਦਾ ਹੈ।"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"ਧੁਨੀ ਅਤੇ ਥਰਥਰਾਹਟ ਨਾਲ ਤੁਹਾਡਾ ਧਿਆਨ ਖਿੱਚਦੀ ਹੈ।"</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ਇਹ ਸੂਚਨਾਵਾਂ ਦਾ ਗਰੁੱਪ ਇੱਥੇ ਸੰਰੂਪਿਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ਇੱਕ ਐਪ ਦੀ ਥਾਂ \'ਤੇ ਦੂਜੀ ਐਪ ਰਾਹੀਂ ਦਿੱਤੀ ਗਈ ਸੂਚਨਾ"</string>
@@ -845,7 +849,7 @@
     <string name="pip_phone_settings" msgid="8080777499521528521">"ਸੈਟਿੰਗਾਂ"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"ਖਾਰਜ ਕਰਨ ਲਈ ਹੇਠਾਂ ਘਸੀਟੋ"</string>
     <string name="pip_menu_title" msgid="4707292089961887657">"ਮੀਨੂ"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ਤਸਵੀਰ-ਵਿੱਚ-ਤਸਵੀਰ \'ਚ ਹੈ"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ਤਸਵੀਰ-ਅੰਦਰ-ਤਸਵੀਰ ਵਿੱਚ ਹੈ"</string>
     <string name="pip_notification_message" msgid="5619512781514343311">"ਜੇਕਰ ਤੁਸੀਂ ਨਹੀਂ ਚਾਹੁੰਦੇ ਕਿ <xliff:g id="NAME">%s</xliff:g> ਐਪ ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਦੀ ਵਰਤੋਂ ਕਰੇ, ਤਾਂ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹਣ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਇਸਨੂੰ ਬੰਦ ਕਰੋ।"</string>
     <string name="pip_play" msgid="1417176722760265888">"ਚਲਾਓ"</string>
     <string name="pip_pause" msgid="8881063404466476571">"ਵਿਰਾਮ ਦਿਓ"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ਖਾਰਜ ਕਰੋ"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਅੱਪਡੇਟ ਹੋ ਗਿਆ। ਤਬਦੀਲੀਆਂ ਕਰਨ ਲਈ, ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ।"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"ਸਟੈਂਡਬਾਈ"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV ਡੀਵਾਈਸ ਜਲਦ ਹੀ ਬੰਦ ਹੋ ਜਾਵੇਗਾ; ਇਸਨੂੰ ਚਾਲੂ ਰੱਖਣ ਲਈ ਕੋਈ ਬਟਨ ਦਬਾਓ।"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"ਡੀਵਾਈਸ ਜਲਦ ਹੀ ਬੰਦ ਹੋ ਜਾਵੇਗਾ, ਇਸਨੂੰ ਚਾਲੂ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index dc79963..3360a6e 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -388,7 +388,7 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Do wschodu słońca"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Włącz o <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Ciemny motyw"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tryb ciemny"</string>
     <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Ciemny motyw\nOszczędzanie baterii"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"Komunikacja NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"Komunikacja NFC jest wyłączona"</string>
@@ -667,8 +667,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Nadal pokazywać powiadomienia z tej aplikacji?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Bez dźwięku"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Alert"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Dymek"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomaga Ci się skupić, nie sygnalizując niczego dźwiękiem ani wibracjami."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Przyciąga uwagę dźwiękiem lub wibracjami."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Przyciąga uwagę dzięki pływającym skrótom do treści."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Tych powiadomień nie można zmodyfikować."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Tej grupy powiadomień nie można tu skonfigurować"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Powiadomienie w zastępstwie"</string>
@@ -956,4 +958,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Zamknij"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Nawigacja w systemie została zaktualizowana. Aby wprowadzić zmiany, otwórz Ustawienia."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Otwórz Ustawienia, by zaktualizować nawigację w systemie"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Tryb gotowości"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Urządzenie z Androidem TV za chwilę się wyłączy. Naciśnij przycisk, by pozostało włączone."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Urządzenie za chwilę się wyłączy. Naciśnij, by pozostało włączone."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index a9a0309..dbe9bdc 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuar mostrando notificações desse app?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Silenciosa"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Alertar"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Bolha"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ajuda você a manter o foco sem som ou vibração."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Chama sua atenção com som ou vibração."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Mantém sua atenção com um atalho flutuante para esse conteúdo."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Não é possível modificar essas notificações."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Não é possível configurar esse grupo de notificações aqui"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificação salva no proxy"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dispensar"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navegação no sistema atualizada. Se quiser alterá-la, acesse as configurações."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Acesse as configurações para atualizar a navegação no sistema"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Em espera"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"O dispositivo Android TV entrará no modo de espera em breve. Pressione um botão para mantê-lo ativado."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"O dispositivo entrará no modo de espera em breve. Pressione para mantê-lo ativado."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index ef59a5e..7e2ed70 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Pretende continuar a ver notificações desta aplicação?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Silencioso"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Alertar"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Balão"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ajuda-o a focar-se sem som ou vibração."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Chama a sua atenção com som ou vibração."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Mantém a sua atenção com um atalho flutuante para este conteúdo."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Não é possível modificar estas notificações."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Não é possível configurar este grupo de notificações aqui."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificação de aplicação proxy"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignorar"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"A navegação no sistema foi atualizada. Para efetuar alterações, aceda às Definições."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Aceda às Definições para atualizar a navegação no sistema."</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Modo de espera"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"O dispositivo Android TV irá desligar-se brevemente. Prima um botão para o manter ligado."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"O dispositivo irá desligar-se brevemente. Prima para o manter ligado."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index a9a0309..dbe9bdc 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuar mostrando notificações desse app?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Silenciosa"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Alertar"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Bolha"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ajuda você a manter o foco sem som ou vibração."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Chama sua atenção com som ou vibração."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Mantém sua atenção com um atalho flutuante para esse conteúdo."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Não é possível modificar essas notificações."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Não é possível configurar esse grupo de notificações aqui"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificação salva no proxy"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dispensar"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navegação no sistema atualizada. Se quiser alterá-la, acesse as configurações."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Acesse as configurações para atualizar a navegação no sistema"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Em espera"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"O dispositivo Android TV entrará no modo de espera em breve. Pressione um botão para mantê-lo ativado."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"O dispositivo entrará no modo de espera em breve. Pressione para mantê-lo ativado."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index a4618d3..1822acf 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -664,8 +664,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Doriți să continuați afișarea notificărilor de la această aplicație?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Silențios"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Alertare"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Balon"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Vă ajută să vă concentrați fără sunet sau vibrare."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Vă atrage atenția fără sunet sau vibrare."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Vă atrage atenția printr-o comandă rapidă flotantă la acest conținut."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Aceste notificări nu pot fi modificate."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Acest grup de notificări nu poate fi configurat aici"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificare prin proxy"</string>
@@ -951,4 +953,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Închideți"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigarea în sistem a fost actualizată. Pentru a face modificări, accesați Setările."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Accesați Setările pentru a actualiza navigarea în sistem"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Standby"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Dispozitivul Android TV se va opri în curând. Apăsați un buton pentru a-l menține pornit."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Dispozitivul se va opri în curând. Apăsați pentru a-l menține pornit."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 9574f0c..681986c 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -667,8 +667,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Показывать уведомления от этого приложения?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Без звука"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Оповещения"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Всплывающая подсказка"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Уведомления приходят без звука и вибрации"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Уведомления приходят со звуком или вибрацией"</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Привлекает ваше внимание к контенту с помощью плавающего ярлыка"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Эти уведомления нельзя изменить."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Эту группу уведомлений нельзя настроить здесь."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Уведомление отправлено через прокси-сервер."</string>
@@ -956,4 +958,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Закрыть"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Параметры навигации в системе обновлены. Чтобы изменить их, перейдите в настройки."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Чтобы обновить параметры навигации в системе, перейдите в настройки."</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Переход в режим ожидания"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Устройство Android TV скоро выключится. Чтобы этого не произошло, нажмите любую кнопку."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Устройство скоро выключится. Чтобы этого не произошло, нажмите любую кнопку или коснитесь экрана."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 2876eb9..5aaae53 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"මෙම යෙදුම වෙතින් දැනුම්දීම් පෙන්වමින් තබන්නද?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"නිහඬ"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"ඇඟවීම"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"ඔබට ශබ්දය හෝ කම්පනය නොමැතිව අවධානය යොමු කිරීමට උදවු කරයි."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"ශබ්දය හෝ කම්පනය සමඟ ඔබේ අවධානය ලබා ගනී."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"මෙම දැනුම්දීම් වෙනස් කළ නොහැක."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"මෙම දැනුම්දීම් සමූහය මෙහි වින්‍යාස කළ නොහැක"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ප්‍රොක්සි කළ දැනුම්දීම"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ඉවතලන්න"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"පද්ධති සංචලනය යාවත්කාලීන කළා. වෙනස්කම් සිදු කිරීමට, සැකසීම් වෙත යන්න."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"පද්ධති සංචලනය යාවත්කාලීන කිරීමට සැකසීම් වෙත යන්න"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"පොරොත්තු"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV උපාංගය ඉක්මනින් ක්‍රියා විරහිත වනු ඇත; එය දිගටම ක්‍රියාත්මක කර තැබීමට බොත්තමක් ඔබන්න."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"උපාංගය ඉක්මනින් ක්‍රියා විරහිත වනු ඇත; එය දිගටම ක්‍රියාත්මක කර තැබීමට ඔබන්න."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index a969932..034827a 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -667,8 +667,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Majú sa upozornenia z tejto aplikácie naďalej zobrazovať?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Tiché"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Varovné"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Bublina"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomáha vám sústrediť sa bez zvukov či vibrácií."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Upúta vás zvukom alebo vibráciami."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Upúta vás plávajúcim odkazom na tento obsah."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Tieto upozornenia sa nedajú upraviť."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Túto skupinu upozornení nejde na tomto mieste konfigurovať"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Približné upozornenie"</string>
@@ -956,4 +958,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Zavrieť"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigácia v systéme bola aktualizovaná. Ak chcete vykonať zmeny, prejdite do Nastavení."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Prejdite do Nastavení a aktualizujte navigáciu v systéme"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Pohotovostný režim"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Zariadenie Android TV sa čoskoro vypne. Ak ho chcete ponechať zapnuté, stlačte ľubovoľné tlačidlo."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Zariadenie sa čoskoro vypne. Ak ho chcete ponechať zapnuté, stlačte ľubovoľné tlačidlo."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 9e4045f..f02a038b 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -667,8 +667,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Želite, da so obvestila te aplikacije še naprej prikazana?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Tiho"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Z opozorilom"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Mehurček"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Nemoteč prikaz brez zvoka ali vibriranja"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Pritegne vašo pozornost z zvokom ali vibriranjem"</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Zadrži vašo pozornost z lebdečo bližnjico do te vsebine."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Za ta obvestila ni mogoče spremeniti nastavitev."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Te skupine obvestil ni mogoče konfigurirati tukaj"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Posredovano obvestilo"</string>
@@ -956,4 +958,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Opusti"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Krmarjenje po sistemu je posodobljeno. Če želite opraviti spremembe, odprite nastavitve."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Če želite posodobiti krmarjenje po sistemu, odprite nastavitve"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Stanje pripravljenosti"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Naprava Android TV se bo kmalu izklopila. Če tega ne želite, pritisnite poljuben gumb."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Naprava se bo kmalu izklopila. Če tega ne želite, pritisnite poljuben gumb."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 6ce621c..41ecccc 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -222,7 +222,7 @@
     <skip />
     <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Njoftimi është hequr."</string>
     <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Streha e njoftimeve."</string>
-    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Cilësime të shpejta."</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Cilësimet e shpejta."</string>
     <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Ekrani i kyçjes."</string>
     <string name="accessibility_desc_settings" msgid="3417884241751434521">"Cilësimet"</string>
     <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Përmbledhja."</string>
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Do të vazhdosh t\'i shfaqësh njoftimet nga ky aplikacion?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Në heshtje"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Sinjalizimi"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Flluskë"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Të ndihmon të fokusohesh pa tinguj ose dridhje."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Të tërheq vëmendjen me tinguj ose dridhje."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Mbaje vëmendjen tënde me një shkurtore pluskuese te kjo përmbajtje."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Këto njoftime nuk mund të modifikohen."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ky grup njoftimesh nuk mund të konfigurohet këtu"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Njoftim i dërguar me përfaqësues"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Hiq"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigimi i sistemit u përditësua. Për të bërë ndryshime, shko te \"Cilësimet\"."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Shko te \"Cilësimet\" për të përditësuar navigimin e sistemit"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Në gatishmëri"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Pajisja Android TV së shpejti do të fiket. Shtyp një buton për ta mbajtur të ndezur."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Pajisja së shpejti do të fiket. Shtype për ta mbajtur të ndezur."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 50775d9..e87d406 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -664,8 +664,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Желите ли да се обавештења из ове апликације и даље приказују?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Нечујно"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Упозоравање"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Облачић"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Помаже вам да се концентришете без звука или вибрације."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Привлачи вам пажњу помоћу звука или вибрације."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Привлачи вам пажњу помоћу плутајуће пречице до овог садржаја."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ова обавештења не могу да се мењају."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ова група обавештења не може да се конфигурише овде"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Обавештење преко проксија"</string>
@@ -951,4 +953,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Одбаци"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Навигација система је ажурирана. Да бисте унели измене, идите у Подешавања."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Идите у Подешавања да бисте ажурирали навигацију система"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Стање приправности"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV ће се ускоро искључити. Притисните дугме да би остао укључен."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Уређај ће се ускоро искључити. Притисните да би остао укључен."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index c7fb27c..70b89a6 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vill du fortsätta visa aviseringar för den här appen?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Tyst"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Påkallar uppmärksamhet"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Bubbla"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Inga ljud eller vibrationer som stör koncentrationen."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Påkallar uppmärksamhet med ljud eller vibrationer."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Behåller din uppmärksamhet med en flytande genväg till innehållet."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Det går inte att ändra de här aviseringarna."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Den här aviseringsgruppen kan inte konfigureras här"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Avisering via proxy"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Stäng"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systemnavigeringen har uppdaterats. Öppna inställningarna om du vill ändra något."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Öppna inställningarna och uppdatera systemnavigeringen"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Viloläge"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV-enheten stängs snart av. Tryck på en knapp för att behålla den på."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Enheten stängs snart av. Tryck för att behålla den på."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 12851eb..b6568f4 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Ungependa kuendelea kuonyesha arifa kutoka programu hii?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Kimya"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Kutoa arifa"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Kiputo"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Hukusaidia kuwa makini bila sauti au mtetemo."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Hupata umakinifu wako kwa sauti na mtetemo."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Huweka umakinifu wako kwenye maudhui haya kwa kutumia njia ya mkato ya kuelea."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Arifa hizi haziwezi kubadilishwa."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Kikundi hiki cha arifa hakiwezi kuwekewa mipangilio hapa"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Arifa wakilishi"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ondoa"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Umesasisha usogezaji kwenye mfumo. Ili ufanye mabadiliko, nenda kwenye Mipangilio."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Nenda kwenye mipangilio ili usasishe usogezaji kwenye mfumo"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Hali tuli"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Kifaa cha Android TV kitazima hivi karibuni; bonyeza kitufe ili kisizime."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Kifaa kitazima hivi karibuni; bonyeza ili kisizime."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 0d49f27..92fb88a 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"இந்த ஆப்ஸின் அறிவிப்புகளைத் தொடர்ந்து காட்டவா?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"நிசப்தம்"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"விழிப்பூட்டல்"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"ஒலியோ அதிர்வோ இல்லாமல் முழு கவனம் செலுத்த உதவும்."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"ஒலியோ அதிர்வோ ஏற்படுத்தி உங்கள் கவனத்தை ஈர்க்கும்."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"இந்த அறிவிப்புகளை மாற்ற இயலாது."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"இந்த அறிவுப்புக் குழுக்களை இங்கே உள்ளமைக்க இயலாது"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ப்ராக்ஸியான அறிவிப்பு"</string>
@@ -846,7 +850,7 @@
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"நிராகரிக்க, கீழே இழுக்கவும்"</string>
     <string name="pip_menu_title" msgid="4707292089961887657">"மெனு"</string>
     <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> தற்போது பிக்ச்சர்-இன்-பிக்ச்சரில் உள்ளது"</string>
-    <string name="pip_notification_message" msgid="5619512781514343311">"<xliff:g id="NAME">%s</xliff:g> இந்த அம்சத்தைப் பயன்படுத்த வேண்டாம் என நினைத்தால், அமைப்புகளைத் திறந்து அதை முடக்க, தட்டவும்."</string>
+    <string name="pip_notification_message" msgid="5619512781514343311">"<xliff:g id="NAME">%s</xliff:g> இந்த அம்சத்தைப் பயன்படுத்த வேண்டாம் என நினைத்தால் இங்கு தட்டி அமைப்புகளைத் திறந்து இதை முடக்கவும்."</string>
     <string name="pip_play" msgid="1417176722760265888">"இயக்கு"</string>
     <string name="pip_pause" msgid="8881063404466476571">"இடைநிறுத்து"</string>
     <string name="pip_skip_to_next" msgid="1948440006726306284">"அடுத்ததற்குச் செல்"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"மூடுக"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"சிஸ்டம் நேவிகேஷன் மாற்றப்பட்டது. மாற்றங்களைச் செய்ய ‘அமைப்புகளுக்குச்’ செல்லவும்."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"சிஸ்டம் நேவிகேஷனை மாற்ற ’அமைப்புகளுக்குச்’ செல்லவும்"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"இயக்க நேரம்"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV விரைவில் ஆஃப் ஆகலாம். இதைத் தொடர்ந்து ஆனில் வைக்க ஒரு பட்டனைத் தட்டவும்."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"இந்தச் சாதனம் விரைவில் ஆஃப் ஆகலாம். இதைத் தொடர்ந்து ஆனில் வைக்கத் தட்டவும்."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 1600df7..f5933a4 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ఈ యాప్ నుండి నోటిఫికేషన్‌లను చూపిస్తూ ఉండాలా?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"నిశ్శబ్దం"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"హెచ్చరించడం"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"బబుల్"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"శబ్దం లేదా వైబ్రేషన్ లేకుండా దృష్టి కేంద్రీకరించడానికి మీకు సహాయపడుతుంది."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"శబ్దం లేదా వైబ్రేషన్‌తో మీరు దృష్టి సారించేలా చేస్తుంది."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"ఫ్లోటింగ్ షార్ట్‌కట్‌తో మీ దృష్టిని ఈ కంటెంట్‌పై నిలిపి ఉంచుతుంది."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ఈ నోటిఫికేషన్‌లను సవరించడం వీలుపడదు."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ఈ నోటిఫికేషన్‌ల సమూహాన్ని ఇక్కడ కాన్ఫిగర్ చేయలేము"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ప్రాక్సీ చేయబడిన నోటిఫికేషన్"</string>
@@ -846,7 +848,7 @@
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"తీసివేయడానికి కిందికి లాగండి"</string>
     <string name="pip_menu_title" msgid="4707292089961887657">"మెను"</string>
     <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> చిత్రంలో చిత్రం రూపంలో ఉంది"</string>
-    <string name="pip_notification_message" msgid="5619512781514343311">"<xliff:g id="NAME">%s</xliff:g> ఈ లక్షణాన్ని ఉపయోగించకూడదు అని మీరు అనుకుంటే, సెట్టింగ్‌లను తెరవడానికి నొక్కి, దీన్ని ఆఫ్ చేయండి."</string>
+    <string name="pip_notification_message" msgid="5619512781514343311">"<xliff:g id="NAME">%s</xliff:g> ఈ లక్షణాన్ని ఉపయోగించకూడదు అని మీరు అనుకుంటే, సెట్టింగ్‌లను తెరవడానికి ట్యాప్ చేసి, దీన్ని ఆఫ్ చేయండి."</string>
     <string name="pip_play" msgid="1417176722760265888">"ప్లే చేయి"</string>
     <string name="pip_pause" msgid="8881063404466476571">"పాజ్ చేయి"</string>
     <string name="pip_skip_to_next" msgid="1948440006726306284">"దాటవేసి తర్వాత దానికి వెళ్లు"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"విస్మరించు"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"సిస్టమ్ నావిగేషన్ అప్‌డేట్ చేయబడింది. మార్పులు చేయడానికి, సెట్టింగ్‌లకు వెళ్లండి."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"సిస్టమ్ నావిగేషన్‌ను అప్‌డేట్ చేయడానికి సెట్టింగ్‌లకు వెళ్లండి"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"స్టాండ్‌బై"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV పరికరం త్వరలో ఆఫ్ అయిపోతుంది; దాన్ని ఆన్‌లో ఉంచడానికి బటన్‌ను నొక్కండి."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"పరికరం త్వరలో ఆఫ్ అయిపోతుంది; దీన్ని ఆన్‌లో ఉంచడానికి నొక్కండి."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 554009e..9df8f32 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"แสดงการแจ้งเตือนจากแอปนี้ต่อไปไหม"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"เงียบ"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"แจ้งเตือน"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"ช่วยรักษาสมาธิของคุณด้วยการไม่ส่งเสียงหรือสั่น"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"ดึงความสนใจของคุณด้วยเสียงและการสั่น"</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"แก้ไขการแจ้งเตือนเหล่านี้ไม่ได้"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"การแจ้งเตือนกลุ่มนี้กำหนดค่าที่นี่ไม่ได้"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"การแจ้งเตือนที่ผ่านพร็อกซี"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ปิด"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"อัปเดตการไปยังส่วนต่างๆ ของระบบแล้ว หากต้องการเปลี่ยนแปลง ให้ไปที่การตั้งค่า"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ไปที่การตั้งค่าเพื่ออัปเดตการไปยังส่วนต่างๆ ของระบบ"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"สแตนด์บาย"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"อุปกรณ์ Android TV จะปิดเครื่องในอีกไม่ช้า กดปุ่มเพื่อเปิดอุปกรณ์ต่อไป"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"อุปกรณ์จะปิดเครื่องในอีกไม่ช้า กดเพื่อเปิดอุปกรณ์ต่อไป"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 309265a..a3a7986 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Patuloy na ipakita ang mga notification mula sa app na ito?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Naka-silent"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Mag-alerto"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Nakakatulong sa iyong tumuon nang walang tunog o pag-vibrate."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Kinukuha ang iyong atensyon sa pamamagitan ng tunog o pag-vibrate."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Hindi puwedeng baguhin ang mga notification na ito."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Hindi mako-configure dito ang pangkat na ito ng mga notification"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Na-proxy na notification"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"I-dismiss"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Na-update na ang pag-navigate ng system. Para gumawa ng mga pagbabago, pumunta sa Mga Setting."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Pumunta sa Mga Setting para i-update ang pag-navigate sa system"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Standby"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Mag-o-off na ang Android TV device; pumindot ng button para panatilihin itong naka-on."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Mag-o-off na ang device; pumindot para panatilihin itong naka-on."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index b200ac6..f176f17 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Bu uygulamadan gelen bildirimler gösterilmeye devam edilsin mi?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Sessiz"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Uyarı"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ses veya titreşim olmadan odaklanmanıza yardımcı olur."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Ses veya titreşimle dikkatinizi çeker."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Bu bildirimler değiştirilemez."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Bu bildirim grubu burada yapılandırılamaz"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxy uygulanan bildirim"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Kapat"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Sistemde gezinme yöntemi güncellendi. Değişiklik yapmak için Ayarlar\'a gidin."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Sistemde gezinme yöntemini güncellemek için Ayarlar\'a gidin"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Beklemeye alınıyor"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV cihazı kısa süre içinde kapanacak; açık tutmak için bir düğmeye basın."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Cihaz kısa süre içinde kapanacak; açık tutmak için düğmeye basın."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 39b4deb..e1eeb4a 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -667,8 +667,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Чи показувати сповіщення з цього додатка надалі?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Без звуку"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Зі звуком"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Спливаюче сповіщення"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Не відволікає увагу звуковим сигналом або вібрацією."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Привертає увагу звуковим сигналом або вібрацією."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Привертає увагу до контенту плаваючим ярликом."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ці сповіщення не можна змінити."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Цю групу сповіщень не можна налаштувати тут"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Проксі-сповіщення"</string>
@@ -956,4 +958,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Закрити"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Навігацію в системі оновлено. Щоб внести зміни, перейдіть у налаштування."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Перейдіть у налаштування, щоб оновити навігацію в системі"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Режим очікування"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Незабаром пристрій Android TV буде вимкнено. Натисніть кнопку, щоб цього не сталося."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Незабаром пристрій буде вимкнено. Натисніть, щоб цього не сталося."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index aa261da..5fcb8d1 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"اس ایپ کی طرف سے اطلاعات دکھانا جاری رکھیں؟"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"خاموش"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"الرٹ کرنا"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"بغیر آواز یا وائبریشن کے آپ کو فوکس کرنے میں مدد کرتا ہے۔"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"آواز اور وائبریشن کے ذریعے آپ کی توجہ حاصل کرتا ہے۔"</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ان اطلاعات کی ترمیم نہیں کی جا سکتی۔"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"اطلاعات کے اس گروپ کو یہاں کنفیگر نہیں کیا جا سکتا"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"پراکسی اطلاع"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"برخاست کریں"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"سسٹم نیویگیشن اپ ڈیٹ کیا گیا۔ تبدیلیاں کرنے کے لیے، ترتیبات پر جائیں۔"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"سسٹم نیویگیشن اپ ڈیٹ کرنے کے لیے ترتیبات پر جائیں"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"اسٹینڈ بائی"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"‏Android TV آلہ جلد ہی بند ہوجائے گا آن رکھنے کے ليے بٹن دبائیں۔"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"آلہ جلد ہی بند ہوجائے گا اسے آن رکھنے کے ليے دبائیں۔"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 8d3697e..46734f3 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Bu ilovadan keladigan bildirishnomalar chiqaversinmi?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Tovushsiz"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Bildirishnoma yuborish"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Pufaklar"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Bildirishnomalar tovush va tebranishsiz keladi."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Bildirishnomalar tovush va tebranish bilan keladi."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Bu kontentni ochuvchi erkin yorliq diqqatingizda boʻladi."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Bu bildirishnomalarni tahrirlash imkonsiz."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ushbu bildirishnomalar guruhi bu yerda sozlanmaydi"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Ishonchli bildirishnoma"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Yopish"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Tizim navigatsiyasi yangilandi. Buni Sozlamalar orqali oʻzgartirishingiz mumkin."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Tizim navigatsiyasini yangilash uchun Sozlamalarni oching"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Kutib turing"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV qurilmasi oʻchish arafasida, yoniq qolishi uchun istalgan tugmani bosing."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Qurilma oʻchish arafasida, yoniq qolishi uchun istalgan tugmani bosing."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 78bf627..ca0a794 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Tiếp tục hiển thị các thông báo từ ứng dụng này?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Im lặng"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Cảnh báo"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Giúp bạn tập trung bằng cách tắt tiếng hoặc không rung."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Thu hút sự chú ý của bạn bằng cách bật tiếng hoặc rung."</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Không thể sửa đổi các thông báo này."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Không thể định cấu hình nhóm thông báo này tại đây"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Thông báo đã xử lý qua máy chủ proxy"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Loại bỏ"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Đã cập nhật chế độ di chuyển trên hệ thống. Để thay đổi, hãy chuyển đến phần Cài đặt."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Chuyển đến phần Cài đặt để cập nhật chế độ di chuyển trên hệ thống"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Chế độ chờ"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Thiết bị Android TV sẽ sớm tắt. Hãy nhấn vào một nút để thiết bị vẫn bật."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Thiết bị sẽ sớm tắt. Hãy nhấn vào một nút để thiết bị vẫn bật."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index de6ad78..6a607e2 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"要继续显示来自此应用的通知吗?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"静音"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"提醒"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"不会发出提示音或振动,可帮助您保持专注。"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"通过提示音或振动吸引您的注意。"</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"无法修改这些通知。"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"您无法在此处配置这组通知"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"代理通知"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"关闭"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"系统导航已更新。要进行更改,请转到“设置”。"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"转到“设置”即可更新系统导航"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"待机"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV 设备即将关闭;按一下相应的按钮即可让设备保持开启状态。"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"设备即将关闭;按一下即可让设备保持开启状态。"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 0bf6fbf..706c9ee 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"要繼續顯示此應用程式的通知嗎?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"靜音"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"發出提醒"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"助您保持專注,不會發出聲音或震動。"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"發出聲音或震動來吸引您的注意。"</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"無法修改這些通知。"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"無法在此設定這組通知"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"代理通知"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"關閉"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"系統導覽已更新。如需變更,請前往「設定」。"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"前往「設定」更新系統導覽"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"待機"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV 裝置即將關閉,按下按鈕即可保持開啟。"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"裝置即將關閉,輕按即可保持開啟。"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 9b3aeb2..6202ce2 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -661,8 +661,12 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"要繼續顯示這個應用程式的通知嗎?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"靜音"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"快訊"</string>
+    <!-- no translation found for notification_bubble_title (6826478461954949364) -->
+    <skip />
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"協助你不受音效或震動干擾。"</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"發出音效或震動吸引你的注意力。"</string>
+    <!-- no translation found for notification_channel_summary_bubble (4269580628050629291) -->
+    <skip />
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"無法修改這些通知。"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"無法在這裡設定這個通知群組"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"經過 Proxy 處理的通知"</string>
@@ -946,4 +950,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"關閉"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"系統操作機制已更新。如要進行變更,請前往「設定」。"</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"請前往「設定」更新系統操作機制"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"待機"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Android TV 裝置即將關閉。如要讓裝置保持開啟狀態,請按下任一按鈕。"</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"裝置即將關閉。輕觸螢幕或按下按鈕即可讓裝置保持開啟狀態。"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 9cf9313..462910f 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -661,8 +661,10 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Qhubeka nokubonisa izaziso kusuka kulolu hlelo lokusebenza?"</string>
     <string name="notification_silence_title" msgid="5763240612242137433">"Kuthulile"</string>
     <string name="notification_alert_title" msgid="8031196611815490340">"Iyazisa"</string>
+    <string name="notification_bubble_title" msgid="6826478461954949364">"Ibhamuza"</string>
     <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ikusiza ukuthi ugxile ngaphandle komsindo noma ukudlidliza."</string>
     <string name="notification_channel_summary_default" msgid="5994062840431965586">"Ithola ukunaka kwakho ngomsindo noma ukudlidliza."</string>
+    <string name="notification_channel_summary_bubble" msgid="4269580628050629291">"Igcina ukunaka kwakho ngesinqamuleli esintantayo kulokhu okuqukethwe."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Lezi zaziso azikwazi ukushintshwa."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Leli qembu lezaziso alikwazi ukulungiselelwa lapha"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Isaziso sommeli"</string>
@@ -946,4 +948,7 @@
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Cashisa"</string>
     <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Ukuzulazula kwesistimu kubuyekeziwe. Ukuze wenze ushintsho, hamba kokuthi Izilungiselelo."</string>
     <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Hamba kuzilungiselelo ukuze ubuyekeze ukuzulazula kwesistimu"</string>
+    <string name="inattentive_sleep_warning_title" msgid="7695119731872371794">"Ilindile"</string>
+    <string name="inattentive_sleep_warning_message" product="tv" msgid="4279125516592217099">"Idivayisi ye-Android TV maduze izovalwa, cindezela inkinobho ukuze uyigcine ivuliwe."</string>
+    <string name="inattentive_sleep_warning_message" product="default" msgid="3128565462954884260">"Idivayisi maduze izovalwa, cindezela ukuze uyigcine ivuliwe."</string>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index dff21cf..c3f410e 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -281,6 +281,7 @@
         <item>com.android.systemui.statusbar.phone.StatusBar</item>
         <item>com.android.systemui.usb.StorageNotification</item>
         <item>com.android.systemui.power.PowerUI</item>
+        <item>com.android.systemui.power.InattentiveSleepWarningController</item>
         <item>com.android.systemui.media.RingtonePlayer</item>
         <item>com.android.systemui.keyboard.KeyboardUI</item>
         <item>com.android.systemui.pip.PipUI</item>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 858b838..cce4008 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2513,4 +2513,11 @@
     <!-- Notification content text when switching to a default launcher that supports gesture navigation [CHAR LIMIT=NONE] -->
     <string name="notification_content_gesture_nav_available">Go to Settings to update system navigation</string>
 
+    <!-- Title of the overlay warning the user to interact with the device or it will go to sleep. [CHAR LIMIT=25] -->
+    <string name="inattentive_sleep_warning_title">Standby</string>
+    <!-- Message of the overlay warning the user to interact with the device or it will go to sleep. [CHAR LIMIT=NONE] -->
+    <string name="inattentive_sleep_warning_message" product="tv">The Android TV device will soon turn off; press a button to keep it on.</string>
+    <!-- Message of the overlay warning the user to interact with the device or it will go to sleep. [CHAR LIMIT=NONE] -->
+    <string name="inattentive_sleep_warning_message" product="default">The device will soon turn off; press to keep it on.</string>
+
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ActivityIntentHelper.java b/packages/SystemUI/src/com/android/systemui/ActivityIntentHelper.java
index 2b62e04..63840bc 100644
--- a/packages/SystemUI/src/com/android/systemui/ActivityIntentHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ActivityIntentHelper.java
@@ -24,14 +24,20 @@
 
 import java.util.List;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /**
  * Contains useful methods for querying properties of an Activity Intent.
  */
+@Singleton
 public class ActivityIntentHelper {
 
     private final Context mContext;
 
+    @Inject
     public ActivityIntentHelper(Context context) {
+        // TODO: inject a package manager, not a context.
         mContext = context;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/SysUiServiceProvider.java b/packages/SystemUI/src/com/android/systemui/SysUiServiceProvider.java
deleted file mode 100644
index ff4b7cb..0000000
--- a/packages/SystemUI/src/com/android/systemui/SysUiServiceProvider.java
+++ /dev/null
@@ -1,29 +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.content.Context;
-
-/**
- * The interface for getting core components of SysUI. Exists for Testability
- * since tests don't have SystemUIApplication as their ApplicationContext.
- */
-public interface SysUiServiceProvider {
-    <T> T getComponent(Class<T> interfaceType);
-
-    public static <T> T getComponent(Context context, Class<T> interfaceType) {
-        return ((SysUiServiceProvider) context.getApplicationContext()).getComponent(interfaceType);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUI.java b/packages/SystemUI/src/com/android/systemui/SystemUI.java
index 7570037..f795faf 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUI.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUI.java
@@ -23,11 +23,9 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.Map;
 
-public abstract class SystemUI implements SysUiServiceProvider {
+public abstract class SystemUI {
     protected final Context mContext;
-    public Map<Class<?>, Object> mComponents;
 
     public SystemUI(Context context) {
         mContext = context;
@@ -44,17 +42,6 @@
     protected void onBootCompleted() {
     }
 
-    @SuppressWarnings("unchecked")
-    public <T> T getComponent(Class<T> interfaceType) {
-        return (T) (mComponents != null ? mComponents.get(interfaceType) : null);
-    }
-
-    public <T, C extends T> void putComponent(Class<T> interfaceType, C component) {
-        if (mComponents != null) {
-            mComponents.put(interfaceType, component);
-        }
-    }
-
     public static void overrideNotificationAppName(Context context, Notification.Builder n,
             boolean system) {
         final Bundle extras = new Bundle();
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 4b28e4a..f0317b4 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -36,13 +36,11 @@
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.util.HashMap;
-import java.util.Map;
 
 /**
  * Application class for SystemUI.
  */
-public class SystemUIApplication extends Application implements SysUiServiceProvider,
+public class SystemUIApplication extends Application implements
         SystemUIAppComponentFactory.ContextInitializer {
 
     public static final String TAG = "SystemUIService";
@@ -56,7 +54,6 @@
     private SystemUI[] mServices;
     private boolean mServicesStarted;
     private boolean mBootCompleted;
-    private final Map<Class<?>, Object> mComponents = new HashMap<>();
     private SystemUIAppComponentFactory.ContextAvailableCallback mContextAvailableCallback;
 
     public SystemUIApplication() {
@@ -199,7 +196,6 @@
                 throw new RuntimeException(ex);
             }
 
-            mServices[i].mComponents = mComponents;
             if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
             mServices[i].start();
             log.traceEnd();
@@ -232,11 +228,6 @@
         }
     }
 
-    @SuppressWarnings("unchecked")
-    public <T> T getComponent(Class<T> interfaceType) {
-        return (T) mComponents.get(interfaceType);
-    }
-
     public SystemUI[] getServices() {
         return mServices;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyBinder.java
index 7007f9d..6744d74 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyBinder.java
@@ -35,7 +35,6 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
 import com.android.systemui.statusbar.phone.DozeServiceHost;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.ManagedProfileController;
 import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -51,7 +50,6 @@
 import com.android.systemui.statusbar.policy.ExtensionControllerImpl;
 import com.android.systemui.statusbar.policy.FlashlightController;
 import com.android.systemui.statusbar.policy.FlashlightControllerImpl;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.HotspotController;
 import com.android.systemui.statusbar.policy.HotspotControllerImpl;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -259,7 +257,4 @@
     @Binds
     public abstract VolumeComponent provideVolumeComponent(
             VolumeDialogComponent volumeDialogComponent);
-    /** */
-    @Binds
-    public abstract HeadsUpManager bindHeadsUpManager(HeadsUpManagerPhone headsUpManagerPhone);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 741c95f..e31e44e 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -33,7 +33,6 @@
 import android.view.LayoutInflater;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -103,14 +102,12 @@
         return Looper.getMainLooper();
     }
 
-    @Singleton
     @Provides
     @BgHandler
     public Handler provideBgHandler(@BgLooper Looper bgLooper) {
         return new Handler(bgLooper);
     }
 
-    @Singleton
     @Provides
     @MainHandler
     public Handler provideMainHandler(@MainLooper Looper mainLooper) {
@@ -143,13 +140,6 @@
         return new DisplayMetrics();
     }
 
-    @Singleton
-    @Provides
-    public IStatusBarService provideIStatusBarService() {
-        return IStatusBarService.Stub.asInterface(
-                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
-    }
-
     /** */
     @Singleton
     @Provides
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
index fffba8c..0d4cc01 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
@@ -22,6 +22,7 @@
 import android.app.AlarmManager;
 import android.app.IActivityManager;
 import android.app.IWallpaperManager;
+import android.app.KeyguardManager;
 import android.app.WallpaperManager;
 import android.content.Context;
 import android.content.res.Resources;
@@ -30,10 +31,13 @@
 import android.os.PowerManager;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.service.dreams.DreamService;
+import android.service.dreams.IDreamManager;
 import android.view.IWindowManager;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 
+import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.LatencyTracker;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.systemui.dagger.qualifiers.BgHandler;
@@ -64,6 +68,20 @@
     }
 
     @Provides
+    @Singleton
+    static IDreamManager provideIDreamManager() {
+        return IDreamManager.Stub.asInterface(
+                ServiceManager.checkService(DreamService.DREAM_SERVICE));
+    }
+
+    @Singleton
+    @Provides
+    static IStatusBarService provideIStatusBarService() {
+        return IStatusBarService.Stub.asInterface(
+                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+    }
+
+    @Provides
     @Nullable
     static IWallpaperManager provideIWallPaperManager() {
         return IWallpaperManager.Stub.asInterface(
@@ -78,6 +96,12 @@
 
     @Singleton
     @Provides
+    static KeyguardManager provideKeyguardManager(Context context) {
+        return context.getSystemService(KeyguardManager.class);
+    }
+
+    @Singleton
+    @Provides
     static LatencyTracker provideLatencyTracker(Context context) {
         return LatencyTracker.getInstance(context);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index 3cf14d6..25986c5 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -25,6 +25,7 @@
 import com.android.systemui.globalactions.GlobalActionsComponent;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.pip.PipUI;
+import com.android.systemui.power.InattentiveSleepWarningController;
 import com.android.systemui.power.PowerUI;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsModule;
@@ -102,6 +103,13 @@
     @ClassKey(PowerUI.class)
     public abstract SystemUI bindPowerUI(PowerUI sysui);
 
+    /** Inject into InattentiveSleepWarningController. */
+    @Binds
+    @IntoMap
+    @ClassKey(InattentiveSleepWarningController.class)
+    public abstract SystemUI bindInattentiveSleepWarningController(
+            InattentiveSleepWarningController sysui);
+
     /** Inject into Recents. */
     @Binds
     @IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
index f1d02bb..f44eae7 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
@@ -25,6 +25,7 @@
 
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dock.DockManagerImpl;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.EnhancedEstimates;
 import com.android.systemui.power.EnhancedEstimatesImpl;
 import com.android.systemui.recents.Recents;
@@ -34,9 +35,12 @@
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
 
 import java.util.Optional;
 
@@ -93,6 +97,17 @@
         return new Divider(context, recentsOptionalLazy);
     }
 
+    @Singleton
+    @Provides
+    static HeadsUpManagerPhone provideHeadsUpManagerPhone(Context context,
+            StatusBarStateController statusBarStateController,
+            KeyguardBypassController bypassController) {
+        return new HeadsUpManagerPhone(context, statusBarStateController, bypassController);
+    }
+
+    @Binds
+    abstract HeadsUpManager bindHeadsUpManagerPhone(HeadsUpManagerPhone headsUpManagerPhone);
+
     @Provides
     @Singleton
     static Recents provideRecents(Context context, RecentsImplementation recentsImplementation,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 6ae21b3..0ac158d 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -28,10 +28,15 @@
 import com.android.systemui.recents.Recents;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.notification.collection.NotifListBuilderImpl;
+import com.android.systemui.statusbar.notification.collection.listbuilder.NotifListBuilder;
 import com.android.systemui.statusbar.notification.people.PeopleHubModule;
 import com.android.systemui.statusbar.phone.KeyguardLiftController;
 import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.util.sensors.AsyncSensorManager;
+import com.android.systemui.util.time.SystemClock;
+import com.android.systemui.util.time.SystemClockImpl;
 
 import javax.inject.Singleton;
 
@@ -80,8 +85,19 @@
     abstract Divider optionalDivider();
 
     @BindsOptionalOf
+    abstract HeadsUpManager optionalHeadsUpManager();
+
+    @BindsOptionalOf
     abstract Recents optionalRecents();
 
     @BindsOptionalOf
     abstract StatusBar optionalStatusBar();
+
+    @Singleton
+    @Binds
+    abstract SystemClock bindSystemClock(SystemClockImpl systemClock);
+
+    @Singleton
+    @Binds
+    abstract NotifListBuilder bindNotifListBuilder(NotifListBuilderImpl impl);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningController.java b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningController.java
new file mode 100644
index 0000000..7169431
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningController.java
@@ -0,0 +1,62 @@
+/*
+ * 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.power;
+
+import android.content.Context;
+
+import com.android.systemui.SystemUI;
+import com.android.systemui.statusbar.CommandQueue;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Receives messages sent from {@link com.android.server.power.InattentiveSleepWarningController}
+ * and shows the appropriate inattentive sleep UI (e.g. {@link InattentiveSleepWarningView}).
+ */
+@Singleton
+public class InattentiveSleepWarningController extends SystemUI implements CommandQueue.Callbacks {
+    private final CommandQueue mCommandQueue;
+    private InattentiveSleepWarningView mOverlayView;
+
+    @Inject
+    public InattentiveSleepWarningController(Context context, CommandQueue commandQueue) {
+        super(context);
+        mCommandQueue = commandQueue;
+    }
+
+    @Override
+    public void start() {
+        mCommandQueue.addCallback(this);
+    }
+
+    @Override
+    public void showInattentiveSleepWarning() {
+        if (mOverlayView == null) {
+            mOverlayView = new InattentiveSleepWarningView(mContext);
+        }
+
+        mOverlayView.show();
+    }
+
+    @Override
+    public void dismissInattentiveSleepWarning() {
+        if (mOverlayView != null) {
+            mOverlayView.dismiss();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java
new file mode 100644
index 0000000..8ccc679
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java
@@ -0,0 +1,85 @@
+/*
+ * 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.power;
+
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.os.Binder;
+import android.os.IBinder;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+
+import com.android.systemui.R;
+
+/**
+ * View that shows a warning shortly before the device goes into sleep
+ * after prolonged user inactivity when bound to.
+ */
+public class InattentiveSleepWarningView extends FrameLayout {
+    private final IBinder mWindowToken = new Binder();
+    private final WindowManager mWindowManager;
+
+    InattentiveSleepWarningView(Context context) {
+        super(context);
+        mWindowManager = mContext.getSystemService(WindowManager.class);
+
+        final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
+        layoutInflater.inflate(R.layout.inattentive_sleep_warning, this, true /* attachToRoot */);
+
+        setFocusable(true);
+        setOnKeyListener((v, keyCode, event) -> {
+            // overlay consumes key presses
+            return true;
+        });
+    }
+
+    /**
+     * Show the warning.
+     */
+    public void show() {
+        if (getParent() == null) {
+            mWindowManager.addView(this, getLayoutParams(mWindowToken));
+        }
+    }
+
+    /**
+     * Dismiss the warning.
+     */
+    public void dismiss() {
+        if (getParent() != null) {
+            mWindowManager.removeView(this);
+        }
+    }
+
+    /**
+     * @param windowToken token for the window
+     */
+    private WindowManager.LayoutParams getLayoutParams(IBinder windowToken) {
+        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
+                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
+                PixelFormat.TRANSLUCENT);
+        lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
+        lp.setTitle("InattentiveSleepWarning");
+        lp.token = windowToken;
+        return lp;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 94a1cf0..d377f1c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -319,7 +319,14 @@
             } else{
                 mColumns = mCellWidth == 0 ? 1 :
                         Math.min(maxTiles, availableWidth / mCellWidth );
-                mCellMarginHorizontal = (availableWidth - mColumns * mCellWidth) / (mColumns - 1);
+                // If we can only fit one column, use mCellMarginHorizontal to center it.
+                if (mColumns == 1) {
+                    mCellMarginHorizontal = (availableWidth - mCellWidth) / 2;
+                } else {
+                    mCellMarginHorizontal =
+                            (availableWidth - mColumns * mCellWidth) / (mColumns - 1);
+                }
+
             }
             return mColumns != prevNumColumns;
         }
@@ -357,6 +364,10 @@
 
         @Override
         protected int getColumnStart(int column) {
+            if (mColumns == 1) {
+                // Only one column/tile. Use the margin to center the tile.
+                return getPaddingStart() + mCellMarginHorizontal;
+            }
             return getPaddingStart() + column *  (mCellWidth + mCellMarginHorizontal);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
index 60bc6b6..fcdd234 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
@@ -35,7 +35,6 @@
 
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.stackdivider.Divider;
@@ -73,7 +72,7 @@
     }
 
     @Override
-    public void onStart(Context context, SysUiServiceProvider sysUiServiceProvider) {
+    public void onStart(Context context) {
         mContext = context;
         mHandler = new Handler();
         mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 882930b..5f37cc45 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -45,7 +45,7 @@
     @Override
     public void start() {
         mCommandQueue.addCallback(this);
-        mImpl.onStart(mContext, this);
+        mImpl.onStart(mContext);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java
index 8cd17e9..1d29ac6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java
@@ -19,15 +19,13 @@
 import android.content.res.Configuration;
 import android.graphics.Rect;
 
-import com.android.systemui.SysUiServiceProvider;
-
 import java.io.PrintWriter;
 
 /**
  * API for creating a Recents view.
  */
 public interface RecentsImplementation {
-    default void onStart(Context context, SysUiServiceProvider sysUiServiceProvider) {}
+    default void onStart(Context context) {}
     default void onBootCompleted() {}
     default void onAppTransitionFinished() {}
     default void onConfigurationChanged(Configuration newConfig) {}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 7963203..e790c1d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -87,6 +87,7 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import java.util.function.Consumer;
 import java.util.function.Function;
 
 import javax.inject.Inject;
@@ -107,7 +108,7 @@
         public Context context;
         public Bitmap image;
         public Uri imageUri;
-        public Runnable finisher;
+        public Consumer<Uri> finisher;
         public Function<PendingIntent, Void> onEditReady;
         public int iconSize;
         public int previewWidth;
@@ -260,7 +261,7 @@
      * Creates a new worker thread and saves the screenshot to the media store.
      */
     private void saveScreenshotInWorkerThread(
-            Runnable finisher, @Nullable Function<PendingIntent, Void> onEditReady) {
+            Consumer<Uri> finisher, @Nullable Function<PendingIntent, Void> onEditReady) {
         SaveImageInBackgroundData data = new SaveImageInBackgroundData();
         data.context = mContext;
         data.image = mScreenBitmap;
@@ -276,15 +277,15 @@
                 .execute();
     }
 
-    private void saveScreenshotInWorkerThread(Runnable finisher) {
+    private void saveScreenshotInWorkerThread(Consumer<Uri> finisher) {
         saveScreenshotInWorkerThread(finisher, null);
     }
 
     /**
      * Takes a screenshot of the current display and shows an animation.
      */
-    private void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible,
-            Rect crop) {
+    private void takeScreenshot(Consumer<Uri> finisher, boolean statusBarVisible,
+            boolean navBarVisible, Rect crop) {
         int rot = mDisplay.getRotation();
         int width = crop.width();
         int height = crop.height();
@@ -294,7 +295,7 @@
         if (mScreenBitmap == null) {
             notifyScreenshotError(mContext, mNotificationManager,
                     R.string.screenshot_failed_to_capture_text);
-            finisher.run();
+            finisher.accept(null);
             return;
         }
 
@@ -307,7 +308,7 @@
                 statusBarVisible, navBarVisible);
     }
 
-    void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible) {
+    void takeScreenshot(Consumer<Uri> finisher, boolean statusBarVisible, boolean navBarVisible) {
         mDisplay.getRealMetrics(mDisplayMetrics);
         takeScreenshot(finisher, statusBarVisible, navBarVisible,
                 new Rect(0, 0, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
@@ -316,7 +317,7 @@
     /**
      * Displays a screenshot selector
      */
-    void takeScreenshotPartial(final Runnable finisher, final boolean statusBarVisible,
+    void takeScreenshotPartial(final Consumer<Uri> finisher, final boolean statusBarVisible,
             final boolean navBarVisible) {
         mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
         mScreenshotSelectorView.setOnTouchListener(new View.OnTouchListener() {
@@ -392,8 +393,8 @@
     /**
      * Starts the animation after taking the screenshot
      */
-    private void startAnimation(final Runnable finisher, int w, int h, boolean statusBarVisible,
-            boolean navBarVisible) {
+    private void startAnimation(final Consumer<Uri> finisher, int w, int h,
+            boolean statusBarVisible, boolean navBarVisible) {
         // If power save is on, show a toast so there is some visual indication that a screenshot
         // has been taken.
         PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index 083f971..e9dbe02 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -453,7 +453,7 @@
                         mNotificationBuilder.build());
             }
         }
-        mParams.finisher.run();
+        mParams.finisher.accept(mParams.imageUri);
         mParams.clearContext();
     }
 
@@ -462,7 +462,7 @@
         // If we are cancelled while the task is running in the background, we may get null
         // params. The finisher is expected to always be called back, so just use the baked-in
         // params from the ctor in any case.
-        mParams.finisher.run();
+        mParams.finisher.accept(null);
         mParams.clearImage();
         mParams.clearContext();
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index fd63506..6243b4b 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -18,6 +18,7 @@
 
 import android.app.Service;
 import android.content.Intent;
+import android.net.Uri;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
@@ -27,6 +28,8 @@
 import android.util.Log;
 import android.view.WindowManager;
 
+import java.util.function.Consumer;
+
 import javax.inject.Inject;
 
 public class TakeScreenshotService extends Service {
@@ -39,10 +42,10 @@
         @Override
         public void handleMessage(Message msg) {
             final Messenger callback = msg.replyTo;
-            Runnable finisher = new Runnable() {
+            Consumer<Uri> finisher = new Consumer<Uri>() {
                 @Override
-                public void run() {
-                    Message reply = Message.obtain(null, 1);
+                public void accept(Uri uri) {
+                    Message reply = Message.obtain(null, 1, uri);
                     try {
                         callback.send(reply);
                     } catch (RemoteException e) {
@@ -55,7 +58,7 @@
             // animation and error notification.
             if (!mUserManager.isUserUnlocked()) {
                 Log.w(TAG, "Skipping screenshot because storage is locked!");
-                post(finisher);
+                post(() -> finisher.accept(null));
                 return;
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 621f101..88b6fdd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -70,53 +70,55 @@
     private static final int OP_SET_ICON    = 1;
     private static final int OP_REMOVE_ICON = 2;
 
-    private static final int MSG_ICON                          = 1 << MSG_SHIFT;
-    private static final int MSG_DISABLE                       = 2 << MSG_SHIFT;
-    private static final int MSG_EXPAND_NOTIFICATIONS          = 3 << MSG_SHIFT;
-    private static final int MSG_COLLAPSE_PANELS               = 4 << MSG_SHIFT;
-    private static final int MSG_EXPAND_SETTINGS               = 5 << MSG_SHIFT;
-    private static final int MSG_SYSTEM_BAR_APPEARANCE_CHANGED = 6 << MSG_SHIFT;
-    private static final int MSG_DISPLAY_READY                 = 7 << MSG_SHIFT;
-    private static final int MSG_SHOW_IME_BUTTON               = 8 << MSG_SHIFT;
-    private static final int MSG_TOGGLE_RECENT_APPS            = 9 << MSG_SHIFT;
-    private static final int MSG_PRELOAD_RECENT_APPS           = 10 << MSG_SHIFT;
-    private static final int MSG_CANCEL_PRELOAD_RECENT_APPS    = 11 << MSG_SHIFT;
-    private static final int MSG_SET_WINDOW_STATE              = 12 << MSG_SHIFT;
-    private static final int MSG_SHOW_RECENT_APPS              = 13 << MSG_SHIFT;
-    private static final int MSG_HIDE_RECENT_APPS              = 14 << MSG_SHIFT;
-    private static final int MSG_SHOW_SCREEN_PIN_REQUEST       = 18 << MSG_SHIFT;
-    private static final int MSG_APP_TRANSITION_PENDING        = 19 << MSG_SHIFT;
-    private static final int MSG_APP_TRANSITION_CANCELLED      = 20 << MSG_SHIFT;
-    private static final int MSG_APP_TRANSITION_STARTING       = 21 << MSG_SHIFT;
-    private static final int MSG_ASSIST_DISCLOSURE             = 22 << MSG_SHIFT;
-    private static final int MSG_START_ASSIST                  = 23 << MSG_SHIFT;
-    private static final int MSG_CAMERA_LAUNCH_GESTURE         = 24 << MSG_SHIFT;
-    private static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS     = 25 << MSG_SHIFT;
-    private static final int MSG_SHOW_PICTURE_IN_PICTURE_MENU  = 26 << MSG_SHIFT;
-    private static final int MSG_ADD_QS_TILE                   = 27 << MSG_SHIFT;
-    private static final int MSG_REMOVE_QS_TILE                = 28 << MSG_SHIFT;
-    private static final int MSG_CLICK_QS_TILE                 = 29 << MSG_SHIFT;
-    private static final int MSG_TOGGLE_APP_SPLIT_SCREEN       = 30 << MSG_SHIFT;
-    private static final int MSG_APP_TRANSITION_FINISHED       = 31 << MSG_SHIFT;
-    private static final int MSG_DISMISS_KEYBOARD_SHORTCUTS    = 32 << MSG_SHIFT;
-    private static final int MSG_HANDLE_SYSTEM_KEY             = 33 << MSG_SHIFT;
-    private static final int MSG_SHOW_GLOBAL_ACTIONS           = 34 << MSG_SHIFT;
-    private static final int MSG_TOGGLE_PANEL                  = 35 << MSG_SHIFT;
-    private static final int MSG_SHOW_SHUTDOWN_UI              = 36 << MSG_SHIFT;
-    private static final int MSG_SET_TOP_APP_HIDES_STATUS_BAR  = 37 << MSG_SHIFT;
-    private static final int MSG_ROTATION_PROPOSAL             = 38 << MSG_SHIFT;
-    private static final int MSG_BIOMETRIC_SHOW                = 39 << MSG_SHIFT;
-    private static final int MSG_BIOMETRIC_AUTHENTICATED       = 40 << MSG_SHIFT;
-    private static final int MSG_BIOMETRIC_HELP                = 41 << MSG_SHIFT;
-    private static final int MSG_BIOMETRIC_ERROR               = 42 << MSG_SHIFT;
-    private static final int MSG_BIOMETRIC_HIDE                = 43 << MSG_SHIFT;
-    private static final int MSG_SHOW_CHARGING_ANIMATION       = 44 << MSG_SHIFT;
-    private static final int MSG_SHOW_PINNING_TOAST_ENTER_EXIT = 45 << MSG_SHIFT;
-    private static final int MSG_SHOW_PINNING_TOAST_ESCAPE     = 46 << MSG_SHIFT;
-    private static final int MSG_RECENTS_ANIMATION_STATE_CHANGED = 47 << MSG_SHIFT;
-    private static final int MSG_SHOW_TRANSIENT                = 48 << MSG_SHIFT;
-    private static final int MSG_ABORT_TRANSIENT               = 49 << MSG_SHIFT;
-    private static final int MSG_TOP_APP_WINDOW_CHANGED        = 50 << MSG_SHIFT;
+    private static final int MSG_ICON                              = 1 << MSG_SHIFT;
+    private static final int MSG_DISABLE                           = 2 << MSG_SHIFT;
+    private static final int MSG_EXPAND_NOTIFICATIONS              = 3 << MSG_SHIFT;
+    private static final int MSG_COLLAPSE_PANELS                   = 4 << MSG_SHIFT;
+    private static final int MSG_EXPAND_SETTINGS                   = 5 << MSG_SHIFT;
+    private static final int MSG_SYSTEM_BAR_APPEARANCE_CHANGED     = 6 << MSG_SHIFT;
+    private static final int MSG_DISPLAY_READY                     = 7 << MSG_SHIFT;
+    private static final int MSG_SHOW_IME_BUTTON                   = 8 << MSG_SHIFT;
+    private static final int MSG_TOGGLE_RECENT_APPS                = 9 << MSG_SHIFT;
+    private static final int MSG_PRELOAD_RECENT_APPS               = 10 << MSG_SHIFT;
+    private static final int MSG_CANCEL_PRELOAD_RECENT_APPS        = 11 << MSG_SHIFT;
+    private static final int MSG_SET_WINDOW_STATE                  = 12 << MSG_SHIFT;
+    private static final int MSG_SHOW_RECENT_APPS                  = 13 << MSG_SHIFT;
+    private static final int MSG_HIDE_RECENT_APPS                  = 14 << MSG_SHIFT;
+    private static final int MSG_SHOW_SCREEN_PIN_REQUEST           = 18 << MSG_SHIFT;
+    private static final int MSG_APP_TRANSITION_PENDING            = 19 << MSG_SHIFT;
+    private static final int MSG_APP_TRANSITION_CANCELLED          = 20 << MSG_SHIFT;
+    private static final int MSG_APP_TRANSITION_STARTING           = 21 << MSG_SHIFT;
+    private static final int MSG_ASSIST_DISCLOSURE                 = 22 << MSG_SHIFT;
+    private static final int MSG_START_ASSIST                      = 23 << MSG_SHIFT;
+    private static final int MSG_CAMERA_LAUNCH_GESTURE             = 24 << MSG_SHIFT;
+    private static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS         = 25 << MSG_SHIFT;
+    private static final int MSG_SHOW_PICTURE_IN_PICTURE_MENU      = 26 << MSG_SHIFT;
+    private static final int MSG_ADD_QS_TILE                       = 27 << MSG_SHIFT;
+    private static final int MSG_REMOVE_QS_TILE                    = 28 << MSG_SHIFT;
+    private static final int MSG_CLICK_QS_TILE                     = 29 << MSG_SHIFT;
+    private static final int MSG_TOGGLE_APP_SPLIT_SCREEN           = 30 << MSG_SHIFT;
+    private static final int MSG_APP_TRANSITION_FINISHED           = 31 << MSG_SHIFT;
+    private static final int MSG_DISMISS_KEYBOARD_SHORTCUTS        = 32 << MSG_SHIFT;
+    private static final int MSG_HANDLE_SYSTEM_KEY                 = 33 << MSG_SHIFT;
+    private static final int MSG_SHOW_GLOBAL_ACTIONS               = 34 << MSG_SHIFT;
+    private static final int MSG_TOGGLE_PANEL                      = 35 << MSG_SHIFT;
+    private static final int MSG_SHOW_SHUTDOWN_UI                  = 36 << MSG_SHIFT;
+    private static final int MSG_SET_TOP_APP_HIDES_STATUS_BAR      = 37 << MSG_SHIFT;
+    private static final int MSG_ROTATION_PROPOSAL                 = 38 << MSG_SHIFT;
+    private static final int MSG_BIOMETRIC_SHOW                    = 39 << MSG_SHIFT;
+    private static final int MSG_BIOMETRIC_AUTHENTICATED           = 40 << MSG_SHIFT;
+    private static final int MSG_BIOMETRIC_HELP                    = 41 << MSG_SHIFT;
+    private static final int MSG_BIOMETRIC_ERROR                   = 42 << MSG_SHIFT;
+    private static final int MSG_BIOMETRIC_HIDE                    = 43 << MSG_SHIFT;
+    private static final int MSG_SHOW_CHARGING_ANIMATION           = 44 << MSG_SHIFT;
+    private static final int MSG_SHOW_PINNING_TOAST_ENTER_EXIT     = 45 << MSG_SHIFT;
+    private static final int MSG_SHOW_PINNING_TOAST_ESCAPE         = 46 << MSG_SHIFT;
+    private static final int MSG_RECENTS_ANIMATION_STATE_CHANGED   = 47 << MSG_SHIFT;
+    private static final int MSG_SHOW_TRANSIENT                    = 48 << MSG_SHIFT;
+    private static final int MSG_ABORT_TRANSIENT                   = 49 << MSG_SHIFT;
+    private static final int MSG_TOP_APP_WINDOW_CHANGED            = 50 << MSG_SHIFT;
+    private static final int MSG_SHOW_INATTENTIVE_SLEEP_WARNING    = 51 << MSG_SHIFT;
+    private static final int MSG_DISMISS_INATTENTIVE_SLEEP_WARNING = 52 << MSG_SHIFT;
 
     public static final int FLAG_EXCLUDE_NONE = 0;
     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -294,6 +296,18 @@
          */
         default void topAppWindowChanged(int displayId, boolean isFullscreen, boolean isImmersive) {
         }
+
+        /**
+         * Called to notify System UI that a warning about the device going to sleep
+         * due to prolonged user inactivity should be shown.
+         */
+        default void showInattentiveSleepWarning() { }
+
+        /**
+         * Called to notify System UI that the warning about the device going to sleep
+         * due to prolonged user inactivity should be dismissed.
+         */
+        default void dismissInattentiveSleepWarning() { }
     }
 
     public CommandQueue(Context context) {
@@ -793,6 +807,22 @@
         }
     }
 
+    @Override
+    public void showInattentiveSleepWarning() {
+        synchronized (mLock) {
+            mHandler.obtainMessage(MSG_SHOW_INATTENTIVE_SLEEP_WARNING)
+                    .sendToTarget();
+        }
+    }
+
+    @Override
+    public void dismissInattentiveSleepWarning() {
+        synchronized (mLock) {
+            mHandler.obtainMessage(MSG_DISMISS_INATTENTIVE_SLEEP_WARNING)
+                    .sendToTarget();
+        }
+    }
+
     private void handleShowImeButton(int displayId, IBinder token, int vis, int backDisposition,
             boolean showImeSwitcher, boolean isMultiClientImeEnabled) {
         if (displayId == INVALID_DISPLAY) return;
@@ -1138,6 +1168,16 @@
                     args.recycle();
                     break;
                 }
+                case MSG_SHOW_INATTENTIVE_SLEEP_WARNING:
+                    for (int i = 0; i < mCallbacks.size(); i++) {
+                        mCallbacks.get(i).showInattentiveSleepWarning();
+                    }
+                    break;
+                case MSG_DISMISS_INATTENTIVE_SLEEP_WARNING:
+                    for (int i = 0; i < mCallbacks.size(); i++) {
+                        mCallbacks.get(i).dismissInattentiveSleepWarning();
+                    }
+                    break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/MediaTransferManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/MediaTransferManager.java
index b21c65e..18574f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/MediaTransferManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/MediaTransferManager.java
@@ -71,7 +71,7 @@
 
             ViewParent parent = view.getParent();
             StatusBarNotification statusBarNotification =
-                    getRowForParent(parent).getStatusBarNotification();
+                    getRowForParent(parent).getEntry().getSbn();
             final Intent intent = new Intent()
                     .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
                     .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
index ef40d98..0bfcdbd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
@@ -44,7 +44,7 @@
     private static  final DataExtractor sIconExtractor = new DataExtractor() {
         @Override
         public Object extractData(ExpandableNotificationRow row) {
-            return row.getStatusBarNotification().getNotification();
+            return row.getEntry().getSbn().getNotification();
         }
     };
     private static final IconComparator sIconVisibilityComparator = new IconComparator() {
@@ -207,7 +207,7 @@
         }
         // in case no view is visible we make sure the time is visible
         int timeVisibility = !hasVisibleText
-                || mRow.getStatusBarNotification().getNotification().showsTime()
+                || mRow.getEntry().getSbn().getNotification().showsTime()
                 ? View.VISIBLE : View.GONE;
         time.setVisibility(timeVisibility);
         View left = null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index e10d27b..c556bc0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -216,7 +216,7 @@
         private StatusBarNotification getNotificationForParent(ViewParent parent) {
             while (parent != null) {
                 if (parent instanceof ExpandableNotificationRow) {
-                    return ((ExpandableNotificationRow) parent).getStatusBarNotification();
+                    return ((ExpandableNotificationRow) parent).getEntry().getSbn();
                 }
                 parent = parent.getParent();
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index ef733a9..4204f68 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -204,7 +204,7 @@
         }
 
         for (ExpandableNotificationRow viewToRemove : viewsToRemove) {
-            if (mGroupManager.isChildInGroupWithSummary(viewToRemove.getStatusBarNotification())) {
+            if (mGroupManager.isChildInGroupWithSummary(viewToRemove.getEntry().getSbn())) {
                 // we are only transferring this notification to its parent, don't generate an
                 // animation
                 mListContainer.setChildTransferInProgress(true);
@@ -339,7 +339,7 @@
                 for (ExpandableNotificationRow remove : toRemove) {
                     parent.removeChildNotification(remove);
                     if (mEntryManager.getActiveNotificationUnfiltered(
-                            remove.getStatusBarNotification().getKey()) == null) {
+                            remove.getEntry().getSbn().getKey()) == null) {
                         // We only want to add an animation if the view is completely removed
                         // otherwise it's just a transfer
                         mListContainer.notifyGroupChildRemoved(remove,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java b/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java
index bc7c22d..9398e6f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java
@@ -21,6 +21,8 @@
 import android.view.ViewGroup;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.LockIcon;
+import com.android.systemui.statusbar.phone.NotificationPanelView;
 import com.android.systemui.statusbar.phone.StatusBarWindowView;
 import com.android.systemui.util.InjectionInflationController;
 
@@ -66,6 +68,11 @@
         return mStatusBarWindowView;
     }
 
+    /** Gets the {@link LockIcon} inside of {@link R.layout#super_status_bar}. */
+    public LockIcon getLockIcon() {
+        return getStatusBarWindowView().findViewById(R.id.lock_icon);
+    }
+
     /**
      * Gets the inflated {@link NotificationShelf} from
      * {@link R.layout#status_bar_notification_shelf}.
@@ -89,4 +96,13 @@
         }
         return mNotificationShelf;
     }
+
+    public NotificationPanelView getNotificationPanelView() {
+        StatusBarWindowView statusBarWindowView = getStatusBarWindowView();
+        if (statusBarWindowView == null) {
+            return null;
+        }
+
+        return mStatusBarWindowView.findViewById(R.id.notification_panel);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index e48e819..9b31234 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -125,21 +125,22 @@
         return mAnimationRunning;
     }
 
-    private class AnimationRunner extends IRemoteAnimationRunner.Stub {
+    class AnimationRunner extends IRemoteAnimationRunner.Stub {
 
-        private ExpandableNotificationRow mSourceNotification;
-        private final ExpandAnimationParameters mParams = new ExpandAnimationParameters();
+        private final ExpandableNotificationRow mSourceNotification;
+        private final ExpandAnimationParameters mParams;
         private final Rect mWindowCrop = new Rect();
         private final float mNotificationCornerRadius;
         private float mCornerRadius;
         private boolean mIsFullScreenLaunch = true;
         private final SyncRtSurfaceTransactionApplier mSyncRtTransactionApplier;
 
-        AnimationRunner(ExpandableNotificationRow sourceNotification) {
-            mSourceNotification = sourceNotification;
-            mSyncRtTransactionApplier = new SyncRtSurfaceTransactionApplier(sourceNotification);
-            mNotificationCornerRadius = Math.max(sourceNotification.getCurrentTopRoundness(),
-                    sourceNotification.getCurrentBottomRoundness());
+        public AnimationRunner(ExpandableNotificationRow sourceNofitication) {
+            mSourceNotification = sourceNofitication;
+            mParams = new ExpandAnimationParameters();
+            mSyncRtTransactionApplier = new SyncRtSurfaceTransactionApplier(mSourceNotification);
+            mNotificationCornerRadius = Math.max(mSourceNotification.getCurrentTopRoundness(),
+                    mSourceNotification.getCurrentBottomRoundness());
         }
 
         @Override
@@ -154,7 +155,6 @@
                     setAnimationPending(false);
                     invokeCallback(iRemoteAnimationFinishedCallback);
                     mNotificationPanel.collapse(false /* delayed */, 1.0f /* speedUpFactor */);
-                    mSourceNotification = null;
                     return;
                 }
 
@@ -254,7 +254,6 @@
                 mCallback.onExpandAnimationFinished(mIsFullScreenLaunch);
                 applyParamsToNotification(null);
                 applyParamsToNotificationList(null);
-                mSourceNotification = null;
             }
 
         }
@@ -282,7 +281,6 @@
             mSourceNotification.post(() -> {
                 setAnimationPending(false);
                 mCallback.onLaunchAnimationCancelled();
-                mSourceNotification = null;
             });
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NewNotifPipeline.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NewNotifPipeline.java
deleted file mode 100644
index 31921a4..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NewNotifPipeline.java
+++ /dev/null
@@ -1,49 +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.notification;
-
-import android.util.Log;
-
-import com.android.systemui.statusbar.NotificationListener;
-import com.android.systemui.statusbar.notification.collection.NotifCollection;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/**
- * Initialization code for the new notification pipeline.
- */
-@Singleton
-public class NewNotifPipeline {
-    private final NotifCollection mNotifCollection;
-
-    @Inject
-    public NewNotifPipeline(
-            NotifCollection notifCollection) {
-        mNotifCollection = notifCollection;
-    }
-
-    /** Hooks the new pipeline up to NotificationManager */
-    public void initialize(
-            NotificationListener notificationService) {
-        mNotifCollection.attach(notificationService);
-
-        Log.d(TAG, "Notif pipeline initialized");
-    }
-
-    private static final String TAG = "NewNotifPipeline";
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
index fd2f720..b5c6641 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
@@ -55,7 +55,7 @@
         mShadeController.wakeUpIfDozing(SystemClock.uptimeMillis(), v, "NOTIFICATION_CLICK");
 
         final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
-        final StatusBarNotification sbn = row.getStatusBarNotification();
+        final StatusBarNotification sbn = row.getEntry().getSbn();
         if (sbn == null) {
             Log.e(TAG, "NotificationClicker called on an unclickable notification,");
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/CollectionReadyForBuildListener.java
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifListBuilder.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/CollectionReadyForBuildListener.java
index 17fef68..cefb506 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/CollectionReadyForBuildListener.java
@@ -22,7 +22,7 @@
  * Interface for the class responsible for converting a NotifCollection into the final sorted,
  * filtered, and grouped list of currently visible notifications.
  */
-public interface NotifListBuilder {
+public interface CollectionReadyForBuildListener {
     /**
      * Called after the NotifCollection has received an update from NotificationManager but before
      * it dispatches any change events to its listeners. This is to inform the list builder that
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/GroupEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/GroupEntry.java
new file mode 100644
index 0000000..f9f3266
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/GroupEntry.java
@@ -0,0 +1,76 @@
+/*
+ * 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.notification.collection;
+
+import android.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Represents a set of grouped notifications. The final notification list is usually a mix of
+ * GroupEntries and NotificationEntries.
+ */
+public class GroupEntry extends ListEntry {
+    @Nullable private NotificationEntry mSummary;
+    private final List<NotificationEntry> mChildren = new ArrayList<>();
+
+    private final List<NotificationEntry> mUnmodifiableChildren =
+            Collections.unmodifiableList(mChildren);
+
+    GroupEntry(String key) {
+        super(key);
+    }
+
+    @Override
+    public NotificationEntry getRepresentativeEntry() {
+        return mSummary;
+    }
+
+    @Nullable
+    public NotificationEntry getSummary() {
+        return mSummary;
+    }
+
+    public List<NotificationEntry> getChildren() {
+        return mUnmodifiableChildren;
+    }
+
+    void setSummary(@Nullable NotificationEntry summary) {
+        mSummary = summary;
+    }
+
+    void clearChildren() {
+        mChildren.clear();
+    }
+
+    void addChild(NotificationEntry child) {
+        mChildren.add(child);
+    }
+
+    void sortChildren(Comparator<? super NotificationEntry> c) {
+        mChildren.sort(c);
+    }
+
+    List<NotificationEntry> getRawChildren() {
+        return mChildren;
+    }
+
+    public static final GroupEntry ROOT_ENTRY = new GroupEntry("<root>");
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
new file mode 100644
index 0000000..e1268f6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
@@ -0,0 +1,60 @@
+/*
+ * 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.notification.collection;
+
+import com.android.systemui.statusbar.notification.collection.listbuilder.NotifListBuilder;
+
+import java.util.List;
+
+
+/**
+ * Utility class for dumping the results of a {@link NotifListBuilder} to a debug string.
+ */
+public class ListDumper {
+
+    /** See class description */
+    public static String dumpList(List<ListEntry> entries) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < entries.size(); i++) {
+            ListEntry entry = entries.get(i);
+            dumpEntry(entry, Integer.toString(i), "", sb);
+            if (entry instanceof GroupEntry) {
+                GroupEntry ge = (GroupEntry) entry;
+                for (int j = 0; j < ge.getChildren().size(); j++) {
+                    dumpEntry(
+                            ge.getChildren().get(j),
+                            Integer.toString(j),
+                            INDENT,
+                            sb);
+                }
+            }
+        }
+        return sb.toString();
+    }
+
+    private static void dumpEntry(
+            ListEntry entry, String index, String indent, StringBuilder sb) {
+        sb.append(indent)
+                .append("[").append(index).append("] ")
+                .append(entry.getKey())
+                .append(" (parent=")
+                .append(entry.getParent() != null ? entry.getParent().getKey() : null)
+                .append(")\n");
+    }
+
+    private static final String INDENT = "  ";
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java
new file mode 100644
index 0000000..dc68c4b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java
@@ -0,0 +1,72 @@
+/*
+ * 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.notification.collection;
+
+import android.annotation.Nullable;
+
+/**
+ * Abstract superclass for top-level entries, i.e. things that can appear in the final notification
+ * list shown to users. In practice, this means either GroupEntries or NotificationEntries.
+ */
+public abstract class ListEntry {
+    private final String mKey;
+
+    @Nullable private GroupEntry mParent;
+    @Nullable private GroupEntry mPreviousParent;
+    private int mSection;
+    int mFirstAddedIteration = -1;
+
+    ListEntry(String key) {
+        mKey = key;
+    }
+
+    public String getKey() {
+        return mKey;
+    }
+
+    /**
+     * Should return the "representative entry" for this ListEntry. For NotificationEntries, its
+     * the entry itself. For groups, it should be the summary. This method exists to interface with
+     * legacy code that expects groups to also be NotificationEntries.
+     */
+    public abstract NotificationEntry getRepresentativeEntry();
+
+    @Nullable public GroupEntry getParent() {
+        return mParent;
+    }
+
+    void setParent(@Nullable GroupEntry parent) {
+        mParent = parent;
+    }
+
+    @Nullable public GroupEntry getPreviousParent() {
+        return mPreviousParent;
+    }
+
+    void setPreviousParent(@Nullable GroupEntry previousParent) {
+        mPreviousParent = previousParent;
+    }
+
+    /** The section this notification was assigned to (0 to N-1, where N is number of sections). */
+    public int getSection() {
+        return mSection;
+    }
+
+    void setSection(int section) {
+        mSection = section;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
index b551352..6f085c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
@@ -95,7 +95,7 @@
     private final Collection<NotificationEntry> mReadOnlyNotificationSet =
             Collections.unmodifiableCollection(mNotificationSet.values());
 
-    @Nullable private NotifListBuilder mListBuilder;
+    @Nullable private CollectionReadyForBuildListener mBuildListener;
     private final List<NotifCollectionListener> mNotifCollectionListeners = new ArrayList<>();
     private final List<NotifLifetimeExtender> mLifetimeExtenders = new ArrayList<>();
 
@@ -123,9 +123,9 @@
      * Sets the class responsible for converting the collection into the list of currently-visible
      * notifications.
      */
-    public void setListBuilder(NotifListBuilder listBuilder) {
+    public void setBuildListener(CollectionReadyForBuildListener buildListener) {
         Assert.isMainThread();
-        mListBuilder = listBuilder;
+        mBuildListener = buildListener;
     }
 
     /**
@@ -282,8 +282,8 @@
     }
 
     private void rebuildList() {
-        if (mListBuilder != null) {
-            mListBuilder.onBuildList(mReadOnlyNotificationSet);
+        if (mBuildListener != null) {
+            mBuildListener.onBuildList(mReadOnlyNotificationSet);
         }
     }
 
@@ -339,8 +339,8 @@
 
     private void dispatchOnEntryAdded(NotificationEntry entry) {
         mAmDispatchingToOtherCode = true;
-        if (mListBuilder != null) {
-            mListBuilder.onBeginDispatchToListeners();
+        if (mBuildListener != null) {
+            mBuildListener.onBeginDispatchToListeners();
         }
         for (NotifCollectionListener listener : mNotifCollectionListeners) {
             listener.onEntryAdded(entry);
@@ -350,8 +350,8 @@
 
     private void dispatchOnEntryUpdated(NotificationEntry entry) {
         mAmDispatchingToOtherCode = true;
-        if (mListBuilder != null) {
-            mListBuilder.onBeginDispatchToListeners();
+        if (mBuildListener != null) {
+            mBuildListener.onBeginDispatchToListeners();
         }
         for (NotifCollectionListener listener : mNotifCollectionListeners) {
             listener.onEntryUpdated(entry);
@@ -364,8 +364,8 @@
             @CancellationReason int reason,
             boolean removedByUser) {
         mAmDispatchingToOtherCode = true;
-        if (mListBuilder != null) {
-            mListBuilder.onBeginDispatchToListeners();
+        if (mBuildListener != null) {
+            mBuildListener.onBeginDispatchToListeners();
         }
         for (NotifCollectionListener listener : mNotifCollectionListeners) {
             listener.onEntryRemoved(entry, reason, removedByUser);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImpl.java
new file mode 100644
index 0000000..21a4b4f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImpl.java
@@ -0,0 +1,737 @@
+/*
+ * 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.notification.collection;
+
+import static com.android.systemui.statusbar.notification.collection.GroupEntry.ROOT_ENTRY;
+import static com.android.systemui.statusbar.notification.collection.ListDumper.dumpList;
+import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_BUILD_PENDING;
+import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_BUILD_STARTED;
+import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_FILTERING;
+import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_FINALIZING;
+import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_IDLE;
+import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_SORTING;
+import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_TRANSFORMING;
+
+import android.annotation.MainThread;
+import android.annotation.Nullable;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.systemui.statusbar.notification.collection.listbuilder.NotifListBuilder;
+import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener;
+import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener;
+import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeTransformGroupsListener;
+import com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.SectionsProvider;
+import com.android.systemui.util.Assert;
+import com.android.systemui.util.time.SystemClock;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * The implementation of {@link NotifListBuilder}.
+ */
+@MainThread
+@Singleton
+public class NotifListBuilderImpl implements NotifListBuilder {
+
+    private final SystemClock mSystemClock;
+
+    private final List<ListEntry> mNotifList = new ArrayList<>();
+
+    private final PipelineState mPipelineState = new PipelineState();
+    private final Map<String, GroupEntry> mGroups = new ArrayMap<>();
+    private Collection<NotificationEntry> mAllEntries = Collections.emptyList();
+    private final List<ListEntry> mNewEntries = new ArrayList<>();
+    private int mIterationCount = 0;
+
+    private final List<NotifFilter> mNotifFilters = new ArrayList<>();
+    private final List<NotifPromoter> mNotifPromoters = new ArrayList<>();
+    private final List<NotifComparator> mNotifComparators = new ArrayList<>();
+    private SectionsProvider mSectionsProvider = new DefaultSectionsProvider();
+
+    private final List<OnBeforeTransformGroupsListener> mOnBeforeTransformGroupsListeners =
+            new ArrayList<>();
+    private final List<OnBeforeSortListener> mOnBeforeSortListeners =
+            new ArrayList<>();
+    private final List<OnBeforeRenderListListener> mOnBeforeRenderListListeners =
+            new ArrayList<>();
+    @Nullable private OnRenderListListener mOnRenderListListener;
+
+    private final List<ListEntry> mReadOnlyNotifList = Collections.unmodifiableList(mNotifList);
+
+    @Inject
+    public NotifListBuilderImpl(SystemClock systemClock) {
+        Assert.isMainThread();
+        mSystemClock = systemClock;
+    }
+
+    /**
+     * Attach the list builder to the NotifCollection. After this is called, it will start building
+     * the notif list in response to changes to the colletion.
+     */
+    public void attach(NotifCollection collection) {
+        Assert.isMainThread();
+        collection.setBuildListener(mReadyForBuildListener);
+    }
+
+    /**
+     * Registers the listener that's responsible for rendering the notif list to the screen. Called
+     * At the very end of pipeline execution, after all other listeners and pluggables have fired.
+     */
+    public void setOnRenderListListener(OnRenderListListener onRenderListListener) {
+        Assert.isMainThread();
+
+        mPipelineState.requireState(STATE_IDLE);
+        mOnRenderListListener = onRenderListListener;
+    }
+
+    @Override
+    public void addOnBeforeTransformGroupsListener(OnBeforeTransformGroupsListener listener) {
+        Assert.isMainThread();
+
+        mPipelineState.requireState(STATE_IDLE);
+        mOnBeforeTransformGroupsListeners.add(listener);
+    }
+
+    @Override
+    public void addOnBeforeSortListener(OnBeforeSortListener listener) {
+        Assert.isMainThread();
+
+        mPipelineState.requireState(STATE_IDLE);
+        mOnBeforeSortListeners.add(listener);
+    }
+
+    @Override
+    public void addOnBeforeRenderListListener(OnBeforeRenderListListener listener) {
+        Assert.isMainThread();
+
+        mPipelineState.requireState(STATE_IDLE);
+        mOnBeforeRenderListListeners.add(listener);
+    }
+
+    @Override
+    public void addFilter(NotifFilter filter) {
+        Assert.isMainThread();
+        mPipelineState.requireState(STATE_IDLE);
+
+        mNotifFilters.add(filter);
+        filter.setInvalidationListener(this::onFilterInvalidated);
+    }
+
+    @Override
+    public void addPromoter(NotifPromoter promoter) {
+        Assert.isMainThread();
+        mPipelineState.requireState(STATE_IDLE);
+
+        mNotifPromoters.add(promoter);
+        promoter.setInvalidationListener(this::onPromoterInvalidated);
+    }
+
+    @Override
+    public void setSectionsProvider(SectionsProvider provider) {
+        Assert.isMainThread();
+        mPipelineState.requireState(STATE_IDLE);
+
+        mSectionsProvider = provider;
+        provider.setInvalidationListener(this::onSectionsProviderInvalidated);
+    }
+
+    @Override
+    public void setComparators(List<NotifComparator> comparators) {
+        Assert.isMainThread();
+        mPipelineState.requireState(STATE_IDLE);
+
+        mNotifComparators.clear();
+        for (NotifComparator comparator : comparators) {
+            mNotifComparators.add(comparator);
+            comparator.setInvalidationListener(this::onNotifComparatorInvalidated);
+        }
+    }
+
+    @Override
+    public List<ListEntry> getActiveNotifs() {
+        Assert.isMainThread();
+        return mReadOnlyNotifList;
+    }
+
+    private final CollectionReadyForBuildListener mReadyForBuildListener =
+            new CollectionReadyForBuildListener() {
+                @Override
+                public void onBeginDispatchToListeners() {
+                    Assert.isMainThread();
+                    mPipelineState.incrementTo(STATE_BUILD_PENDING);
+                }
+
+                @Override
+                public void onBuildList(Collection<NotificationEntry> entries) {
+                    Assert.isMainThread();
+                    mPipelineState.requireIsBefore(STATE_BUILD_STARTED);
+
+                    Log.i(TAG, "Build request received from NotifCollection");
+                    mAllEntries = entries;
+                    buildList();
+                }
+            };
+
+    private void onFilterInvalidated(NotifFilter filter) {
+        Assert.isMainThread();
+
+        // TODO: Convert these log statements (here and elsewhere) into timeline logging
+        Log.i(TAG, String.format(
+                "Filter \"%s\" invalidated; pipeline state is %d",
+                filter.getName(),
+                mPipelineState.getState()));
+
+        rebuildListIfBefore(STATE_FILTERING);
+    }
+
+    private void onPromoterInvalidated(NotifPromoter filter) {
+        Assert.isMainThread();
+
+        Log.i(TAG, String.format(
+                "NotifPromoter \"%s\" invalidated; pipeline state is %d",
+                filter.getName(),
+                mPipelineState.getState()));
+
+        rebuildListIfBefore(STATE_TRANSFORMING);
+    }
+
+    private void onSectionsProviderInvalidated(SectionsProvider provider) {
+        Assert.isMainThread();
+
+        Log.i(TAG, String.format(
+                "Sections provider \"%s\" invalidated; pipeline state is %d",
+                provider.getName(),
+                mPipelineState.getState()));
+
+        rebuildListIfBefore(STATE_SORTING);
+    }
+
+    private void onNotifComparatorInvalidated(NotifComparator comparator) {
+        Assert.isMainThread();
+
+        Log.i(TAG, String.format(
+                "Comparator \"%s\" invalidated; pipeline state is %d",
+                comparator.getName(),
+                mPipelineState.getState()));
+
+        rebuildListIfBefore(STATE_SORTING);
+    }
+
+    /**
+     * The core algorithm of the pipeline. See the top comment in {@link NotifListBuilder} for
+     * details on our contracts with other code.
+     *
+     * Once the build starts we are very careful to protect against reentrant code. Anything that
+     * tries to invalidate itself after the pipeline has passed it by will return in an exception.
+     * In general, we should be extremely sensitive to client code doing things in the wrong order;
+     * if we detect that behavior, we should crash instantly.
+     */
+    private void buildList() {
+        Log.i(TAG, "Starting notif list build #" + mIterationCount + "...");
+
+        mPipelineState.requireIsBefore(STATE_BUILD_STARTED);
+        mPipelineState.setState(STATE_BUILD_STARTED);
+
+        // Step 1: Filtering and initial grouping
+        // Filter out any notifs that shouldn't be shown right now and cluster any that are part of
+        // a group
+        mPipelineState.incrementTo(STATE_FILTERING);
+        mNotifList.clear();
+        mNewEntries.clear();
+        filterAndGroup(mAllEntries, mNotifList, mNewEntries);
+        pruneIncompleteGroups(mNotifList, mNewEntries);
+
+        // Step 2: Group transforming
+        // Move some notifs out of their groups and up to top-level (mostly used for heads-upping)
+        dispatchOnBeforeTransformGroups(mReadOnlyNotifList, mNewEntries);
+        mPipelineState.incrementTo(STATE_TRANSFORMING);
+        promoteNotifs(mNotifList);
+        pruneIncompleteGroups(mNotifList, mNewEntries);
+
+        // Step 3: Sort
+        // Assign each top-level entry a section, then sort the list by section and then within
+        // section by our list of custom comparators
+        dispatchOnBeforeSort(mReadOnlyNotifList);
+        mPipelineState.incrementTo(STATE_SORTING);
+        sortList();
+
+        // Step 4: Lock in our group structure and log anything that's changed since the last run
+        mPipelineState.incrementTo(STATE_FINALIZING);
+        logParentingChanges();
+        freeEmptyGroups();
+
+        // Step 5: Dispatch the new list, first to any listeners and then to the view layer
+        Log.i(TAG, "List finalized, is:\n" + dumpList(mNotifList));
+        Log.i(TAG, "Dispatching final list to listeners...");
+        dispatchOnBeforeRenderList(mReadOnlyNotifList);
+        if (mOnRenderListListener != null) {
+            mOnRenderListListener.onRenderList(mReadOnlyNotifList);
+        }
+
+        // Step 6: We're done!
+        Log.i(TAG, "Notif list build #" + mIterationCount + " completed");
+        mPipelineState.setState(STATE_IDLE);
+        mIterationCount++;
+    }
+
+    private void filterAndGroup(
+            Collection<NotificationEntry> entries,
+            List<ListEntry> out,
+            List<ListEntry> newlyVisibleEntries) {
+
+        long now = mSystemClock.uptimeMillis();
+
+        for (GroupEntry group : mGroups.values()) {
+            group.setPreviousParent(group.getParent());
+            group.setParent(null);
+            group.clearChildren();
+            group.setSummary(null);
+        }
+
+        for (NotificationEntry entry : entries) {
+            entry.setPreviousParent(entry.getParent());
+            entry.setParent(null);
+
+            // See if we should filter out this notification
+            boolean shouldFilterOut = applyFilters(entry, now);
+            if (shouldFilterOut) {
+                continue;
+            }
+
+            if (entry.mFirstAddedIteration == -1) {
+                entry.mFirstAddedIteration = mIterationCount;
+                newlyVisibleEntries.add(entry);
+            }
+
+            // Otherwise, group it
+            if (entry.getSbn().isGroup()) {
+                final String topLevelKey = entry.getSbn().getGroupKey();
+
+                GroupEntry group = mGroups.get(topLevelKey);
+                if (group == null) {
+                    group = new GroupEntry(topLevelKey);
+                    group.mFirstAddedIteration = mIterationCount;
+                    newlyVisibleEntries.add(group);
+                    mGroups.put(topLevelKey, group);
+                }
+                if (group.getParent() == null) {
+                    group.setParent(ROOT_ENTRY);
+                    out.add(group);
+                }
+
+                entry.setParent(group);
+
+                if (entry.getSbn().getNotification().isGroupSummary()) {
+                    final NotificationEntry existingSummary = group.getSummary();
+
+                    if (existingSummary == null) {
+                        group.setSummary(entry);
+                    } else {
+                        Log.w(TAG, String.format(
+                                "Duplicate summary for group '%s': '%s' vs. '%s'",
+                                group.getKey(),
+                                existingSummary.getKey(),
+                                entry.getKey()));
+
+                        // Use whichever one was posted most recently
+                        if (entry.getSbn().getPostTime()
+                                > existingSummary.getSbn().getPostTime()) {
+                            group.setSummary(entry);
+                            annulAddition(existingSummary, out, newlyVisibleEntries);
+                        } else {
+                            annulAddition(entry, out, newlyVisibleEntries);
+                        }
+                    }
+                } else {
+                    group.addChild(entry);
+                }
+
+            } else {
+
+                final String topLevelKey = entry.getKey();
+                if (mGroups.containsKey(topLevelKey)) {
+                    Log.wtf(TAG, "Duplicate non-group top-level key: " + topLevelKey);
+                } else {
+                    entry.setParent(ROOT_ENTRY);
+                    out.add(entry);
+                }
+            }
+        }
+    }
+
+    private void promoteNotifs(List<ListEntry> list) {
+        for (int i = 0; i < list.size(); i++) {
+            final ListEntry tle = list.get(i);
+
+            if (tle instanceof GroupEntry) {
+                final GroupEntry group = (GroupEntry) tle;
+
+                group.getRawChildren().removeIf(child -> {
+                    final boolean shouldPromote = applyTopLevelPromoters(child);
+
+                    if (shouldPromote) {
+                        child.setParent(ROOT_ENTRY);
+                        list.add(child);
+                    }
+
+                    return shouldPromote;
+                });
+            }
+        }
+    }
+
+    private void pruneIncompleteGroups(
+            List<ListEntry> shadeList,
+            List<ListEntry> newlyVisibleEntries) {
+
+        for (int i = 0; i < shadeList.size(); i++) {
+            final ListEntry tle = shadeList.get(i);
+
+            if (tle instanceof GroupEntry) {
+                final GroupEntry group = (GroupEntry) tle;
+                final List<NotificationEntry> children = group.getRawChildren();
+
+                if (group.getSummary() != null && children.size() == 0) {
+                    shadeList.remove(i);
+                    i--;
+
+                    NotificationEntry summary = group.getSummary();
+                    summary.setParent(ROOT_ENTRY);
+                    shadeList.add(summary);
+
+                    group.setSummary(null);
+                    annulAddition(group, shadeList, newlyVisibleEntries);
+
+                } else if (group.getSummary() == null
+                        || children.size() < MIN_CHILDREN_FOR_GROUP) {
+                    // If the group doesn't provide a summary or is too small, ignore it and add
+                    // its children (if any) directly to top-level.
+
+                    shadeList.remove(i);
+                    i--;
+
+                    if (group.getSummary() != null) {
+                        final NotificationEntry summary = group.getSummary();
+                        group.setSummary(null);
+                        annulAddition(summary, shadeList, newlyVisibleEntries);
+                    }
+
+                    for (int j = 0; j < children.size(); j++) {
+                        final NotificationEntry child = children.get(j);
+                        child.setParent(ROOT_ENTRY);
+                        shadeList.add(child);
+                    }
+                    children.clear();
+
+                    annulAddition(group, shadeList, newlyVisibleEntries);
+                }
+            }
+        }
+    }
+
+    /**
+     * If a ListEntry was added to the shade list and then later removed (e.g. because it was a
+     * group that was broken up), this method will erase any bookkeeping traces of that addition
+     * and/or check that they were already erased.
+     *
+     * Before calling this method, the entry must already have been removed from its parent. If
+     * it's a group, its summary must be null and its children must be empty.
+     */
+    private void annulAddition(
+            ListEntry entry,
+            List<ListEntry> shadeList,
+            List<ListEntry> newlyVisibleEntries) {
+
+        // This function does very little, but if any of its assumptions are violated (and it has a
+        // lot of them), it will put the system into an inconsistent state. So we check all of them
+        // here.
+
+        if (entry.getParent() == null || entry.mFirstAddedIteration == -1) {
+            throw new IllegalStateException(
+                    "Cannot nullify addition of " + entry.getKey() + ": no such addition. ("
+                            + entry.getParent() + " " + entry.mFirstAddedIteration + ")");
+        }
+
+        if (entry.getParent() == ROOT_ENTRY) {
+            if (shadeList.contains(entry)) {
+                throw new IllegalStateException("Cannot nullify addition of " + entry.getKey()
+                        + ": it's still in the shade list.");
+            }
+        }
+
+        if (entry instanceof GroupEntry) {
+            GroupEntry ge = (GroupEntry) entry;
+            if (ge.getSummary() != null) {
+                throw new IllegalStateException(
+                        "Cannot nullify group " + ge.getKey() + ": summary is not null");
+            }
+            if (!ge.getChildren().isEmpty()) {
+                throw new IllegalStateException(
+                        "Cannot nullify group " + ge.getKey() + ": still has children");
+            }
+        } else if (entry instanceof NotificationEntry) {
+            if (entry == entry.getParent().getSummary()
+                    || entry.getParent().getChildren().contains(entry)) {
+                throw new IllegalStateException("Cannot nullify addition of child "
+                        + entry.getKey() + ": it's still attached to its parent.");
+            }
+        }
+
+        entry.setParent(null);
+        if (entry.mFirstAddedIteration == mIterationCount) {
+            if (!newlyVisibleEntries.remove(entry)) {
+                throw new IllegalStateException("Cannot late-filter entry " + entry.getKey() + " "
+                        + entry + " from " + newlyVisibleEntries + " "
+                        + entry.mFirstAddedIteration);
+            }
+            entry.mFirstAddedIteration = -1;
+        }
+    }
+
+    private void sortList() {
+        // Assign sections to top-level elements and sort their children
+        for (ListEntry entry : mNotifList) {
+            entry.setSection(mSectionsProvider.getSection(entry));
+            if (entry instanceof GroupEntry) {
+                GroupEntry parent = (GroupEntry) entry;
+                for (NotificationEntry child : parent.getChildren()) {
+                    child.setSection(0);
+                }
+                parent.sortChildren(sChildComparator);
+            }
+        }
+
+        // Finally, sort all top-level elements
+        mNotifList.sort(mTopLevelComparator);
+    }
+
+    private void freeEmptyGroups() {
+        mGroups.values().removeIf(ge -> ge.getSummary() == null && ge.getChildren().isEmpty());
+    }
+
+    private void logParentingChanges() {
+        for (NotificationEntry entry : mAllEntries) {
+            if (entry.getParent() != entry.getPreviousParent()) {
+                Log.i(TAG, String.format(
+                        "%s: parent changed from %s to %s",
+                        entry.getKey(),
+                        entry.getPreviousParent() == null
+                                ? "null" : entry.getPreviousParent().getKey(),
+                        entry.getParent() == null
+                                ? "null" : entry.getParent().getKey()));
+            }
+        }
+        for (GroupEntry group : mGroups.values()) {
+            if (group.getParent() != group.getPreviousParent()) {
+                Log.i(TAG, String.format(
+                        "%s: parent changed from %s to %s",
+                        group.getKey(),
+                        group.getPreviousParent() == null
+                                ? "null" : group.getPreviousParent().getKey(),
+                        group.getParent() == null
+                                ? "null" : group.getParent().getKey()));
+            }
+        }
+    }
+
+    private final Comparator<ListEntry> mTopLevelComparator = (o1, o2) -> {
+
+        int cmp = Integer.compare(o1.getSection(), o2.getSection());
+
+        if (cmp == 0) {
+            for (int i = 0; i < mNotifComparators.size(); i++) {
+                cmp = mNotifComparators.get(i).compare(o1, o2);
+                if (cmp != 0) {
+                    break;
+                }
+            }
+        }
+
+        final NotificationEntry rep1 = o1.getRepresentativeEntry();
+        final NotificationEntry rep2 = o2.getRepresentativeEntry();
+
+        if (cmp == 0) {
+            cmp = rep1.getRanking().getRank() - rep2.getRanking().getRank();
+        }
+
+        if (cmp == 0) {
+            cmp = Long.compare(
+                    rep2.getSbn().getNotification().when,
+                    rep1.getSbn().getNotification().when);
+        }
+
+        return cmp;
+    };
+
+    private static final Comparator<NotificationEntry> sChildComparator = (o1, o2) -> {
+        int cmp = o1.getRanking().getRank() - o2.getRanking().getRank();
+
+        if (cmp == 0) {
+            cmp = Long.compare(
+                    o2.getSbn().getNotification().when,
+                    o1.getSbn().getNotification().when);
+        }
+
+        return cmp;
+    };
+
+    private boolean applyFilters(NotificationEntry entry, long now) {
+        NotifFilter filter = findRejectingFilter(entry, now);
+
+        if (filter != entry.mExcludingFilter) {
+            if (entry.mExcludingFilter == null) {
+                Log.i(TAG, String.format(
+                        "%s: filtered out by '%s'",
+                        entry.getKey(),
+                        filter.getName()));
+            } else if (filter == null) {
+                Log.i(TAG, String.format(
+                        "%s: no longer filtered out (previous filter was '%s')",
+                        entry.getKey(),
+                        entry.mExcludingFilter.getName()));
+            } else {
+                Log.i(TAG, String.format(
+                        "%s: filter changed: '%s' -> '%s'",
+                        entry.getKey(),
+                        entry.mExcludingFilter,
+                        filter));
+            }
+
+            // Note that groups and summaries can also be filtered out later if they're part of a
+            // malformed group. We currently don't have a great way to track that beyond parenting
+            // change logs. Consider adding something similar to mExcludingFilter for them.
+            entry.mExcludingFilter = filter;
+        }
+
+        return filter != null;
+    }
+
+    @Nullable private NotifFilter findRejectingFilter(NotificationEntry entry, long now) {
+        for (int i = 0; i < mNotifFilters.size(); i++) {
+            NotifFilter filter = mNotifFilters.get(i);
+            if (filter.shouldFilterOut(entry, now)) {
+                return filter;
+            }
+        }
+        return null;
+    }
+
+    private boolean applyTopLevelPromoters(NotificationEntry entry) {
+        NotifPromoter promoter = findPromoter(entry);
+
+        if (promoter != entry.mNotifPromoter) {
+            if (entry.mNotifPromoter == null) {
+                Log.i(TAG, String.format(
+                        "%s: Entry promoted to top level by '%s'",
+                        entry.getKey(),
+                        promoter.getName()));
+            } else if (promoter == null) {
+                Log.i(TAG, String.format(
+                        "%s: Entry is no longer promoted to top level (previous promoter was '%s')",
+                        entry.getKey(),
+                        entry.mNotifPromoter.getName()));
+            } else {
+                Log.i(TAG, String.format(
+                        "%s: Top-level promoter changed: '%s' -> '%s'",
+                        entry.getKey(),
+                        entry.mNotifPromoter,
+                        promoter));
+            }
+
+            entry.mNotifPromoter = promoter;
+        }
+
+        return promoter != null;
+    }
+
+    @Nullable private NotifPromoter findPromoter(NotificationEntry entry) {
+        for (int i = 0; i < mNotifPromoters.size(); i++) {
+            NotifPromoter promoter = mNotifPromoters.get(i);
+            if (promoter.shouldPromoteToTopLevel(entry)) {
+                return promoter;
+            }
+        }
+        return null;
+    }
+
+    private void rebuildListIfBefore(@PipelineState.StateName int state) {
+        mPipelineState.requireIsBefore(state);
+        if (mPipelineState.is(STATE_IDLE)) {
+            buildList();
+        }
+    }
+
+    private void dispatchOnBeforeTransformGroups(
+            List<ListEntry> entries,
+            List<ListEntry> newlyVisibleEntries) {
+        for (int i = 0; i < mOnBeforeTransformGroupsListeners.size(); i++) {
+            mOnBeforeTransformGroupsListeners.get(i)
+                    .onBeforeTransformGroups(entries, newlyVisibleEntries);
+        }
+    }
+
+    private void dispatchOnBeforeSort(List<ListEntry> entries) {
+        for (int i = 0; i < mOnBeforeSortListeners.size(); i++) {
+            mOnBeforeSortListeners.get(i).onBeforeSort(entries);
+        }
+    }
+
+    private void dispatchOnBeforeRenderList(List<ListEntry> entries) {
+        for (int i = 0; i < mOnBeforeRenderListListeners.size(); i++) {
+            mOnBeforeRenderListListeners.get(i).onBeforeRenderList(entries);
+        }
+    }
+
+    /** See {@link #setOnRenderListListener(OnRenderListListener)} */
+    public interface OnRenderListListener {
+        /**
+         * Called with the final filtered, grouped, and sorted list.
+         *
+         * @param entries A read-only view into the current notif list. Note that this list is
+         *                backed by the live list and will change in response to new pipeline runs.
+         */
+        void onRenderList(List<ListEntry> entries);
+    }
+
+    private static class DefaultSectionsProvider extends SectionsProvider {
+        DefaultSectionsProvider() {
+            super("DefaultSectionsProvider");
+        }
+
+        @Override
+        public int getSection(ListEntry entry) {
+            return 0;
+        }
+    }
+
+    private static final String TAG = "NotifListBuilderImpl";
+
+    private static final int MIN_CHILDREN_FOR_GROUP = 2;
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index 28ccaf5..3eb55ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -60,6 +60,8 @@
 import com.android.systemui.statusbar.InflationTask;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.notification.InflationException;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag;
 import com.android.systemui.statusbar.notification.row.NotificationGuts;
@@ -84,7 +86,7 @@
  * At the moment, there are many things here that shouldn't be and vice-versa. Hopefully we can
  * clean this up in the future.
  */
-public final class NotificationEntry {
+public final class NotificationEntry extends ListEntry {
 
     private final String mKey;
     private StatusBarNotification mSbn;
@@ -98,6 +100,12 @@
     /** List of lifetime extenders that are extending the lifetime of this notification. */
     final List<NotifLifetimeExtender> mLifetimeExtenders = new ArrayList<>();
 
+    /** If this notification was filtered out, then the filter that did the filtering. */
+    @Nullable NotifFilter mExcludingFilter;
+
+    /** If this was a group child that was promoted to the top level, then who did the promoting. */
+    @Nullable NotifPromoter mNotifPromoter;
+
 
     /*
     * Old members
@@ -164,8 +172,8 @@
     public NotificationEntry(
             @NonNull StatusBarNotification sbn,
             @NonNull Ranking ranking) {
-        checkNotNull(sbn);
-        checkNotNull(sbn.getKey());
+        super(checkNotNull(checkNotNull(sbn).getKey()));
+
         checkNotNull(ranking);
 
         mKey = sbn.getKey();
@@ -173,6 +181,11 @@
         setRanking(ranking);
     }
 
+    @Override
+    public NotificationEntry getRepresentativeEntry() {
+        return this;
+    }
+
     /** The key for this notification. Guaranteed to be immutable and unique */
     public String getKey() {
         return mKey;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/FakePipelineConsumer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/FakePipelineConsumer.java
new file mode 100644
index 0000000..986ee17
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/FakePipelineConsumer.java
@@ -0,0 +1,85 @@
+/*
+ * 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.notification.collection.init;
+
+import com.android.systemui.Dumpable;
+import com.android.systemui.statusbar.notification.collection.GroupEntry;
+import com.android.systemui.statusbar.notification.collection.ListEntry;
+import com.android.systemui.statusbar.notification.collection.NotifListBuilderImpl;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Temporary class that tracks the result of the list builder and dumps it to text when requested.
+ *
+ * Eventually, this will be something that hands off the result of the pipeline to the View layer.
+ */
+public class FakePipelineConsumer implements Dumpable {
+    private List<ListEntry> mEntries = Collections.emptyList();
+
+    /** Attach the consumer to the pipeline. */
+    public void attach(NotifListBuilderImpl listBuilder) {
+        listBuilder.setOnRenderListListener(this::onBuildComplete);
+    }
+
+    private void onBuildComplete(List<ListEntry> entries) {
+        mEntries = entries;
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println();
+        pw.println("Active notif tree:");
+        for (int i = 0; i < mEntries.size(); i++) {
+            ListEntry entry = mEntries.get(i);
+            if (entry instanceof GroupEntry) {
+                GroupEntry ge = (GroupEntry) entry;
+                pw.println(dumpGroup(ge, "", i));
+
+                pw.println(dumpEntry(ge.getSummary(), INDENT, -1));
+                for (int j = 0; j < ge.getChildren().size(); j++) {
+                    pw.println(dumpEntry(ge.getChildren().get(j), INDENT, j));
+                }
+            } else {
+                pw.println(dumpEntry(entry.getRepresentativeEntry(), "", i));
+            }
+        }
+    }
+
+    private String dumpGroup(GroupEntry entry, String indent, int index) {
+        return String.format(
+                "%s[%d] %s (group)",
+                indent,
+                index,
+                entry.getKey());
+    }
+
+    private String dumpEntry(NotificationEntry entry, String indent, int index) {
+        return String.format(
+                "%s[%s] %s (channel=%s)",
+                indent,
+                index == -1 ? "*" : Integer.toString(index),
+                entry.getKey(),
+                entry.getChannel() != null ? entry.getChannel().getId() : "");
+    }
+
+    private static final String INDENT = "   ";
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NewNotifPipeline.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NewNotifPipeline.java
new file mode 100644
index 0000000..3b3e7e2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NewNotifPipeline.java
@@ -0,0 +1,72 @@
+/*
+ * 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.notification.collection.init;
+
+import android.util.Log;
+
+import com.android.systemui.DumpController;
+import com.android.systemui.Dumpable;
+import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.notification.collection.NotifCollection;
+import com.android.systemui.statusbar.notification.collection.NotifListBuilderImpl;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Initialization code for the new notification pipeline.
+ */
+@Singleton
+public class NewNotifPipeline implements Dumpable {
+    private final NotifCollection mNotifCollection;
+    private final NotifListBuilderImpl mNotifPipeline;
+    private final DumpController mDumpController;
+
+    private final FakePipelineConsumer mFakePipelineConsumer = new FakePipelineConsumer();
+
+    @Inject
+    public NewNotifPipeline(
+            NotifCollection notifCollection,
+            NotifListBuilderImpl notifPipeline,
+            DumpController dumpController) {
+        mNotifCollection = notifCollection;
+        mNotifPipeline = notifPipeline;
+        mDumpController = dumpController;
+    }
+
+    /** Hooks the new pipeline up to NotificationManager */
+    public void initialize(
+            NotificationListener notificationService) {
+        mFakePipelineConsumer.attach(mNotifPipeline);
+        mNotifPipeline.attach(mNotifCollection);
+        mNotifCollection.attach(notificationService);
+
+        Log.d(TAG, "Notif pipeline initialized");
+
+        mDumpController.registerDumpable("NotifPipeline", this);
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        mFakePipelineConsumer.dump(fd, pw, args);
+    }
+
+    private static final String TAG = "NewNotifPipeline";
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifListBuilder.java
new file mode 100644
index 0000000..15d3b92
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifListBuilder.java
@@ -0,0 +1,117 @@
+/*
+ * 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.notification.collection.listbuilder;
+
+import com.android.systemui.statusbar.notification.collection.ListEntry;
+import com.android.systemui.statusbar.notification.collection.NotifCollection;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.SectionsProvider;
+
+import java.util.List;
+
+/**
+ * The system that constructs the current "notification list", the list of notifications that are
+ * currently being displayed to the user.
+ *
+ * The pipeline proceeds through a series of stages in order to produce the final list (see below).
+ * Each stage exposes hooks and listeners for other code to participate.
+ *
+ * This list differs from the canonical one we receive from system server in a few ways:
+ * - Filtered: Some notifications are filtered out. For example, we filter out notifications whose
+ *   views haven't been inflated yet. We also filter out some notifications if we're on the lock
+ *   screen. To participate, see {@link #addFilter(NotifFilter)}.
+ * - Grouped: Notifications that are part of the same group are clustered together into a single
+ *   GroupEntry. These groups are then transformed in order to remove children or completely split
+ *   them apart. To participate, see {@link #addPromoter(NotifPromoter)}.
+ * - Sorted: All top-level notifications are sorted. To participate, see
+ *   {@link #setSectionsProvider(SectionsProvider)} and {@link #setComparators(List)}
+ *
+ * The exact order of all hooks is as follows:
+ *  0. Collection listeners are fired (see {@link NotifCollection}).
+ *  1. NotifFilters are called on each notification currently in NotifCollection.
+ *  2. Initial grouping is performed (NotificationEntries will have their parents set
+ *     appropriately).
+ *  3. OnBeforeTransformGroupListeners are fired
+ *  4. NotifPromoters are called on each notification with a parent
+ *  5. OnBeforeSortListeners are fired
+ *  6. SectionsProvider is called on each top-level entry in the list
+ *  7. The top-level entries are sorted using the provided NotifComparators (plus some additional
+ *     built-in logic).
+ *  8. OnBeforeRenderListListeners are fired
+ *  9. The list is handed off to the view layer to be rendered.
+ */
+public interface NotifListBuilder {
+
+    /**
+     * Registers a filter with the pipeline. Filters are called on each notification in the order
+     * that they were registered. If any filter returns true, the notification is removed from the
+     * pipeline (and no other filters are called on that notif).
+     */
+    void addFilter(NotifFilter filter);
+
+    /**
+     * Registers a promoter with the pipeline. Promoters are able to promote child notifications to
+     * top-level, i.e. move a notification that would be a child of a group and make it appear
+     * ungrouped. Promoters are called on each child notification in the order that they are
+     * registered. If any promoter returns true, the notification is removed from the group (and no
+     * other promoters are called on it).
+     */
+    void addPromoter(NotifPromoter promoter);
+
+    /**
+     * Assigns sections to each top-level entry, where a section is simply an integer. Sections are
+     * the primary metric by which top-level entries are sorted; NotifComparators are only consulted
+     * when two entries are in the same section. The pipeline doesn't assign any particular meaning
+     * to section IDs -- from it's perspective they're just numbers and it sorts them by a simple
+     * numerical comparison.
+     */
+    void setSectionsProvider(SectionsProvider provider);
+
+    /**
+     * Comparators that are used to sort top-level entries that share the same section. The
+     * comparators are executed in order until one of them returns a non-zero result. If all return
+     * zero, the pipeline falls back to sorting by rank (and, failing that, Notification.when).
+     */
+    void setComparators(List<NotifComparator> comparators);
+
+    /**
+     * Called after notifications have been filtered and after the initial grouping has been
+     * performed but before NotifPromoters have had a chance to promote children out of groups.
+     */
+    void addOnBeforeTransformGroupsListener(OnBeforeTransformGroupsListener listener);
+
+    /**
+     * Called after notifs have been filtered and groups have been determined but before sections
+     * have been determined or the notifs have been sorted.
+     */
+    void addOnBeforeSortListener(OnBeforeSortListener listener);
+
+    /**
+     * Called at the end of the pipeline after the notif list has been finalized but before it has
+     * been handed off to the view layer.
+     */
+    void addOnBeforeRenderListListener(OnBeforeRenderListListener listener);
+
+    /**
+     * Returns a read-only view in to the current notification list. If this method is called
+     * during pipeline execution it will return the current state of the list, which will likely
+     * be only partially-generated.
+     */
+    List<ListEntry> getActiveNotifs();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/OnBeforeRenderListListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/OnBeforeRenderListListener.java
new file mode 100644
index 0000000..f6ca12d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/OnBeforeRenderListListener.java
@@ -0,0 +1,33 @@
+/*
+ * 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.notification.collection.listbuilder;
+
+import com.android.systemui.statusbar.notification.collection.ListEntry;
+
+import java.util.List;
+
+/** See {@link NotifListBuilder#addOnBeforeRenderListListener(OnBeforeRenderListListener)} */
+public interface OnBeforeRenderListListener {
+    /**
+     * Called at the end of the pipeline after the notif list has been finalized but before it has
+     * been handed off to the view layer.
+     *
+     * @param entries The current list of top-level entries. Note that this is a live view into the
+     *                current list and will change whenever the pipeline is rerun.
+     */
+    void onBeforeRenderList(List<ListEntry> entries);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/OnBeforeSortListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/OnBeforeSortListener.java
new file mode 100644
index 0000000..7be7ac0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/OnBeforeSortListener.java
@@ -0,0 +1,33 @@
+/*
+ * 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.notification.collection.listbuilder;
+
+import com.android.systemui.statusbar.notification.collection.ListEntry;
+
+import java.util.List;
+
+/** See {@link NotifListBuilder#addOnBeforeSortListener(OnBeforeSortListener)} */
+public interface OnBeforeSortListener {
+    /**
+     * Called after the notif list has been filtered and grouped but before sections have been
+     * determined or sorting has taken place.
+     *
+     * @param entries The current list of top-level entries. Note that this is a live view into the
+     *                current list and will change whenever the pipeline is rerun.
+     */
+    void onBeforeSort(List<ListEntry> entries);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/OnBeforeTransformGroupsListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/OnBeforeTransformGroupsListener.java
new file mode 100644
index 0000000..170ff48
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/OnBeforeTransformGroupsListener.java
@@ -0,0 +1,40 @@
+/*
+ * 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.notification.collection.listbuilder;
+
+import com.android.systemui.statusbar.notification.collection.ListEntry;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
+
+import java.util.List;
+
+/**
+ * See
+ * {@link NotifListBuilder#addOnBeforeTransformGroupsListener(OnBeforeTransformGroupsListener)}
+ */
+public interface OnBeforeTransformGroupsListener {
+    /**
+     * Called after notifs have been filtered and grouped but before {@link NotifPromoter}s have
+     * been called.
+     *
+     * @param list The current filtered and grouped list of (top-level) entries. Note that this is
+     *             a live view into the current notif list and will change as the list moves through
+     *             the pipeline.
+     * @param newlyVisibleEntries The list of all entries (both top-level and children) who have
+     *                            been added to the list for the first time.
+     */
+    void onBeforeTransformGroups(List<ListEntry> list, List<ListEntry> newlyVisibleEntries);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/PipelineState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/PipelineState.java
new file mode 100644
index 0000000..ad4bbd9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/PipelineState.java
@@ -0,0 +1,97 @@
+/*
+ * 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.notification.collection.listbuilder;
+
+import android.annotation.IntDef;
+
+import com.android.systemui.statusbar.notification.collection.NotifListBuilderImpl;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Used by {@link NotifListBuilderImpl} to track its internal state machine.
+ */
+public class PipelineState {
+
+    private @StateName int mState = STATE_IDLE;
+
+    /** Returns true if the current state matches <code>state</code> */
+    public boolean is(@StateName int state) {
+        return state == mState;
+    }
+
+    public @StateName int getState() {
+        return mState;
+    }
+
+    public void setState(@StateName int state) {
+        mState = state;
+    }
+
+    /**
+     * Increments the state from <code>(to - 1)</code> to <code>to</code>. If the current state
+     * isn't <code>(to - 1)</code>, throws an exception.
+     */
+    public void incrementTo(@StateName int to) {
+        if (mState != to - 1) {
+            throw new IllegalStateException(
+                    "Cannot increment from state " + mState + " to state " + to);
+        }
+        mState = to;
+    }
+
+    /**
+     * Throws an exception if the current state is not <code>state</code>.
+     */
+    public void requireState(@StateName int state) {
+        if (state != mState) {
+            throw new IllegalStateException(
+                    "Required state is <" + state + " but actual state is " + mState);
+        }
+    }
+
+    /**
+     * Throws an exception if the current state is >= <code>state</code>.
+     */
+    public void requireIsBefore(@StateName int state) {
+        if (mState >= state) {
+            throw new IllegalStateException(
+                    "Required state is <" + state + " but actual state is " + mState);
+        }
+    }
+
+    public static final int STATE_IDLE = 0;
+    public static final int STATE_BUILD_PENDING = 1;
+    public static final int STATE_BUILD_STARTED = 2;
+    public static final int STATE_FILTERING = 3;
+    public static final int STATE_TRANSFORMING = 4;
+    public static final int STATE_SORTING = 5;
+    public static final int STATE_FINALIZING = 6;
+
+    @IntDef(prefix = { "STATE_" }, value = {
+            STATE_IDLE,
+            STATE_BUILD_PENDING,
+            STATE_BUILD_STARTED,
+            STATE_FILTERING,
+            STATE_TRANSFORMING,
+            STATE_SORTING,
+            STATE_FINALIZING,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface StateName {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifComparator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifComparator.java
new file mode 100644
index 0000000..a191c83
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifComparator.java
@@ -0,0 +1,43 @@
+/*
+ * 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.notification.collection.listbuilder.pluggable;
+
+import com.android.systemui.statusbar.notification.collection.ListEntry;
+import com.android.systemui.statusbar.notification.collection.listbuilder.NotifListBuilder;
+
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Pluggable for participating in notif sorting. See {@link NotifListBuilder#setComparators(List)}.
+ */
+public abstract class NotifComparator
+        extends Pluggable<NotifComparator>
+        implements Comparator<ListEntry> {
+
+    protected NotifComparator(String name) {
+        super(name);
+    }
+
+    /**
+     * Compare two ListEntries. Note that these might be either NotificationEntries or GroupEntries.
+     *
+     * @return a negative integer, zero, or a positive integer as the first argument is less than
+     *      equal to, or greater than the second (same as standard Comparator<> interface).
+     */
+    public abstract int compare(ListEntry o1, ListEntry o2);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifFilter.java
new file mode 100644
index 0000000..685eac8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifFilter.java
@@ -0,0 +1,45 @@
+/*
+ * 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.notification.collection.listbuilder.pluggable;
+
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.listbuilder.NotifListBuilder;
+
+/**
+ * Pluggable for participating in notif filtering. See
+ * {@link NotifListBuilder#addFilter(NotifFilter)}.
+ */
+public abstract class NotifFilter extends Pluggable<NotifFilter> {
+    protected NotifFilter(String name) {
+        super(name);
+    }
+
+    /**
+     * If returns true, this notification will not be included in the final list displayed to the
+     * user. Filtering is performed on each active notification every time the pipeline is run.
+     * This doesn't necessarily mean that your filter will get called on every notification,
+     * however. If another filter returns true before yours, we'll skip straight to the next notif.
+     *
+     * @param entry The entry in question
+     * @param now A timestamp in SystemClock.uptimeMillis that represents "now" for the purposes of
+     *            pipeline execution. This value will be the same for all pluggable calls made
+     *            during this pipeline run, giving pluggables a stable concept of "now" to compare
+     *            various entries against.
+     * @return True if the notif should be removed from the list
+     */
+    public abstract boolean shouldFilterOut(NotificationEntry entry, long now);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifPromoter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifPromoter.java
new file mode 100644
index 0000000..84e16f4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifPromoter.java
@@ -0,0 +1,42 @@
+/*
+ * 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.notification.collection.listbuilder.pluggable;
+
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.listbuilder.NotifListBuilder;
+
+/**
+ *  Pluggable for participating in notif promotion. Notif promoters can upgrade notifications
+ *  from being children of a group to top-level notifications. See
+ *  {@link NotifListBuilder#addPromoter(NotifPromoter)}.
+ */
+public abstract class NotifPromoter extends Pluggable<NotifPromoter> {
+    protected NotifPromoter(String name) {
+        super(name);
+    }
+
+    /**
+     * If true, the child will be removed from its parent and placed at the top level of the notif
+     * list. By the time this method is called, child.getParent() has been set, so you can
+     * examine it (or any other entries in the notif list) for extra information.
+     *
+     * This method is only called on notifs that are currently children of groups. This doesn't
+     * necessarily mean that your promoter will get called on every child notification, however. If
+     * another promoter returns true before yours, we'll skip straight to the next notif.
+     */
+    public abstract boolean shouldPromoteToTopLevel(NotificationEntry child);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/Pluggable.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/Pluggable.java
new file mode 100644
index 0000000..f9ce197
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/Pluggable.java
@@ -0,0 +1,71 @@
+/*
+ * 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.notification.collection.listbuilder.pluggable;
+
+import android.annotation.Nullable;
+
+import com.android.systemui.statusbar.notification.collection.listbuilder.NotifListBuilder;
+
+/**
+ * Generic superclass for chunks of code that can plug into the {@link NotifListBuilder}.
+ *
+ * A pluggable is fundamentally three things:
+ * 1. A name (for debugging purposes)
+ * 2. The functionality that the pluggable provides to the pipeline (this is determined by the
+ *    subclass).
+ * 3. A way for the pluggable to inform the pipeline that its state has changed and the pipeline
+ *    should be rerun (in this case, the invalidate() method).
+ *
+ * @param <This> The type of the subclass. Subclasses should bind their own type here.
+ */
+public abstract class Pluggable<This> {
+    private final String mName;
+    @Nullable private PluggableListener<This> mListener;
+
+    Pluggable(String name) {
+        mName = name;
+    }
+
+    public final String getName() {
+        return mName;
+    }
+
+    /**
+     * Call this method when something has caused this pluggable's behavior to change. The pipeline
+     * will be re-run.
+     */
+    public final void invalidateList() {
+        if (mListener != null) {
+            mListener.onPluggableInvalidated((This) this);
+        }
+    }
+
+    /** Set a listener to be notified when a pluggable is invalidated. */
+    public void setInvalidationListener(PluggableListener<This> listener) {
+        mListener = listener;
+    }
+
+    /**
+     * Listener interface for when pluggables are invalidated.
+     *
+     * @param <T> The type of pluggable that is being listened to.
+     */
+    public interface PluggableListener<T> {
+        /** Called whenever {@link #invalidateList()} is called on this pluggable. */
+        void onPluggableInvalidated(T pluggable);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/SectionsProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/SectionsProvider.java
new file mode 100644
index 0000000..11ea850
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/SectionsProvider.java
@@ -0,0 +1,37 @@
+/*
+ * 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.notification.collection.listbuilder.pluggable;
+
+import com.android.systemui.statusbar.notification.collection.ListEntry;
+
+/**
+ * Interface for sorting notifications into "sections", such as a heads-upping section, people
+ * section, alerting section, silent section, etc.
+ */
+public abstract class SectionsProvider extends Pluggable<SectionsProvider> {
+
+    protected SectionsProvider(String name) {
+        super(name);
+    }
+
+    /**
+     * Returns the section that this entry belongs to. A section can be any non-negative integer.
+     * When entries are sorted, they are first sorted by section and then by any remainining
+     * comparators.
+     */
+    public abstract int getSection(ListEntry entry);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index f0d07a7..9ac5b44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -198,7 +198,6 @@
     private String mLoggingKey;
     private NotificationGuts mGuts;
     private NotificationEntry mEntry;
-    private StatusBarNotification mStatusBarNotification;
     private String mAppName;
 
     /**
@@ -261,10 +260,10 @@
         @Override
         public void onClick(View v) {
             if (!shouldShowPublic() && (!mIsLowPriority || isExpanded())
-                    && mGroupManager.isSummaryOfGroup(mStatusBarNotification)) {
+                    && mGroupManager.isSummaryOfGroup(mEntry.getSbn())) {
                 mGroupExpansionChanging = true;
-                final boolean wasExpanded = mGroupManager.isGroupExpanded(mStatusBarNotification);
-                boolean nowExpanded = mGroupManager.toggleGroupExpansion(mStatusBarNotification);
+                final boolean wasExpanded = mGroupManager.isGroupExpanded(mEntry.getSbn());
+                boolean nowExpanded = mGroupManager.toggleGroupExpansion(mEntry.getSbn());
                 mOnExpandClickListener.onExpandClicked(mEntry, nowExpanded);
                 MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTIFICATION_GROUP_EXPANDER,
                         nowExpanded);
@@ -441,7 +440,6 @@
      */
     public void setEntry(@NonNull NotificationEntry entry) {
         mEntry = entry;
-        mStatusBarNotification = entry.getSbn();
         cacheIsSystemNotification();
     }
 
@@ -516,7 +514,7 @@
      */
     public boolean getIsNonblockable() {
         boolean isNonblockable = Dependency.get(NotificationBlockingHelperManager.class)
-                .isNonblockable(mStatusBarNotification.getPackageName(),
+                .isNonblockable(mEntry.getSbn().getPackageName(),
                         mEntry.getChannel().getId());
 
         // If the SystemNotifAsyncTask hasn't finished running or retrieved a value, we'll try once
@@ -526,7 +524,7 @@
                 Log.d(TAG, "Retrieving isSystemNotification on main thread");
             }
             mSystemNotificationAsyncTask.cancel(true /* mayInterruptIfRunning */);
-            mEntry.mIsSystemNotification = isSystemNotification(mContext, mStatusBarNotification);
+            mEntry.mIsSystemNotification = isSystemNotification(mContext, mEntry.getSbn());
         }
 
         isNonblockable |= mEntry.getChannel().isImportanceLockedByOEM();
@@ -547,11 +545,11 @@
         for (NotificationContentView l : mLayouts) {
             l.onNotificationUpdated(mEntry);
         }
-        mIsColorized = mStatusBarNotification.getNotification().isColorized();
+        mIsColorized = mEntry.getSbn().getNotification().isColorized();
         mShowingPublicInitialized = false;
         updateNotificationColor();
         if (mMenuRow != null) {
-            mMenuRow.onNotificationUpdated(mStatusBarNotification);
+            mMenuRow.onNotificationUpdated(mEntry.getSbn());
             mMenuRow.setAppName(mAppName);
         }
         if (mIsSummaryWithChildren) {
@@ -583,7 +581,7 @@
     /** Called when the notification's ranking was changed (but nothing else changed). */
     public void onNotificationRankingUpdated() {
         if (mMenuRow != null) {
-            mMenuRow.onNotificationUpdated(mStatusBarNotification);
+            mMenuRow.onNotificationUpdated(mEntry.getSbn());
         }
     }
 
@@ -676,10 +674,6 @@
         layout.setHeights(minHeight, headsUpHeight, mNotificationMaxHeight);
     }
 
-    public StatusBarNotification getStatusBarNotification() {
-        return mStatusBarNotification;
-    }
-
     public NotificationEntry getEntry() {
         return mEntry;
     }
@@ -807,7 +801,7 @@
      * @return whether this notification is the only child in the group summary
      */
     public boolean isOnlyChildInGroup() {
-        return mGroupManager.isOnlyChildInGroup(getStatusBarNotification());
+        return mGroupManager.isOnlyChildInGroup(mEntry.getSbn());
     }
 
     public ExpandableNotificationRow getNotificationParent() {
@@ -1181,7 +1175,7 @@
         }
 
         if (mMenuRow.getMenuView() == null) {
-            mMenuRow.createMenu(this, mStatusBarNotification);
+            mMenuRow.createMenu(this, mEntry.getSbn());
             mMenuRow.setAppName(mAppName);
             FrameLayout.LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
                     LayoutParams.MATCH_PARENT);
@@ -1222,7 +1216,7 @@
         if (oldMenu != null) {
             int menuIndex = indexOfChild(oldMenu);
             removeView(oldMenu);
-            mMenuRow.createMenu(ExpandableNotificationRow.this, mStatusBarNotification);
+            mMenuRow.createMenu(ExpandableNotificationRow.this, mEntry.getSbn());
             mMenuRow.setAppName(mAppName);
             addView(mMenuRow.getMenuView(), menuIndex);
         }
@@ -1230,7 +1224,7 @@
             l.initView();
             l.reInflateViews();
         }
-        mStatusBarNotification.clearPackageContext();
+        mEntry.getSbn().clearPackageContext();
         mNotificationInflater.clearCachesAndReInflate();
     }
 
@@ -1290,7 +1284,7 @@
                 == Configuration.UI_MODE_NIGHT_YES;
 
         mNotificationColor = ContrastColorUtil.resolveContrastColor(mContext,
-                getStatusBarNotification().getNotification().color,
+                mEntry.getSbn().getNotification().color,
                 getBackgroundColorWithoutTint(), nightMode);
     }
 
@@ -1438,7 +1432,7 @@
     public void performDismiss(boolean fromAccessibility) {
         if (isOnlyChildInGroup()) {
             NotificationEntry groupSummary =
-                    mGroupManager.getLogicalGroupSummary(getStatusBarNotification());
+                    mGroupManager.getLogicalGroupSummary(mEntry.getSbn());
             if (groupSummary.isClearable()) {
                 // If this is the only child in the group, dismiss the group, but don't try to show
                 // the blocking helper affordance!
@@ -2209,8 +2203,8 @@
         getFalsingManager().setNotificationExpanded();
         if (mIsSummaryWithChildren && !shouldShowPublic() && allowChildExpansion
                 && !mChildrenContainer.showingAsLowPriority()) {
-            final boolean wasExpanded = mGroupManager.isGroupExpanded(mStatusBarNotification);
-            mGroupManager.setGroupExpanded(mStatusBarNotification, userExpanded);
+            final boolean wasExpanded = mGroupManager.isGroupExpanded(mEntry.getSbn());
+            mGroupManager.setGroupExpanded(mEntry.getSbn(), userExpanded);
             onExpansionChanged(true /* userAction */, wasExpanded);
             return;
         }
@@ -2356,7 +2350,7 @@
 
     @Override
     public boolean isGroupExpanded() {
-        return mGroupManager.isGroupExpanded(mStatusBarNotification);
+        return mGroupManager.isGroupExpanded(mEntry.getSbn());
     }
 
     private void onChildrenCountChanged() {
@@ -2397,9 +2391,9 @@
             for (int i = 0; i < numChildren; i++) {
                 final ExpandableNotificationRow childRow = childrenRows.get(i);
                 final NotificationChannel childChannel = childRow.getEntry().getChannel();
-                final StatusBarNotification childSbn = childRow.getStatusBarNotification();
-                if (childSbn.getUser().equals(mStatusBarNotification.getUser()) &&
-                        childSbn.getPackageName().equals(mStatusBarNotification.getPackageName())) {
+                final StatusBarNotification childSbn = childRow.getEntry().getSbn();
+                if (childSbn.getUser().equals(mEntry.getSbn().getUser())
+                        && childSbn.getPackageName().equals(mEntry.getSbn().getPackageName())) {
                     channels.add(childChannel);
                 }
             }
@@ -2593,7 +2587,7 @@
     public void makeActionsVisibile() {
         setUserExpanded(true, true);
         if (isChildInGroup()) {
-            mGroupManager.setGroupExpanded(mStatusBarNotification, true);
+            mGroupManager.setGroupExpanded(mEntry.getSbn(), true);
         }
         notifyHeightChanged(false /* needsAnimation */);
     }
@@ -2890,7 +2884,7 @@
 
     public void onExpandedByGesture(boolean userExpanded) {
         int event = MetricsEvent.ACTION_NOTIFICATION_GESTURE_EXPANDER;
-        if (mGroupManager.isSummaryOfGroup(getStatusBarNotification())) {
+        if (mGroupManager.isSummaryOfGroup(mEntry.getSbn())) {
             event = MetricsEvent.ACTION_NOTIFICATION_GROUP_GESTURE_EXPANDER;
         }
         MetricsLogger.action(mContext, event, userExpanded);
@@ -2935,7 +2929,7 @@
     private void onExpansionChanged(boolean userAction, boolean wasExpanded) {
         boolean nowExpanded = isExpanded();
         if (mIsSummaryWithChildren && (!mIsLowPriority || wasExpanded)) {
-            nowExpanded = mGroupManager.isGroupExpanded(mStatusBarNotification);
+            nowExpanded = mGroupManager.isGroupExpanded(mEntry.getSbn());
         }
         if (nowExpanded != wasExpanded) {
             updateShelfIconColor();
@@ -3224,7 +3218,7 @@
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         super.dump(fd, pw, args);
-        pw.println("  Notification: " + getStatusBarNotification().getKey());
+        pw.println("  Notification: " + mEntry.getKey());
         pw.print("    visibility: " + getVisibility());
         pw.print(", alpha: " + getAlpha());
         pw.print(", translation: " + getTranslation());
@@ -3267,7 +3261,7 @@
 
         @Override
         protected Boolean doInBackground(Void... voids) {
-            return isSystemNotification(mContext, mStatusBarNotification);
+            return isSystemNotification(mContext, mEntry.getSbn());
         }
 
         @Override
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 37f63c9..7b758aa 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
@@ -166,7 +166,7 @@
     }
 
     private LogMaker getLogMaker() {
-        return mBlockingHelperRow.getStatusBarNotification()
+        return mBlockingHelperRow.getEntry().getSbn()
             .getLogMaker()
             .setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER);
     }
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 a91a119..54dee8c 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
@@ -512,7 +512,7 @@
                     existingWrapper.onReinflated();
                 }
             } catch (Exception e) {
-                handleInflationError(runningInflations, e, row.getStatusBarNotification(), callback);
+                handleInflationError(runningInflations, e, row.getEntry().getSbn(), callback);
                 // Add a running inflation to make sure we don't trigger callbacks.
                 // Safe to do because only happens in tests.
                 runningInflations.put(inflationId, new CancellationSignal());
@@ -563,7 +563,7 @@
                     onViewApplied(newView);
                 } catch (Exception anotherException) {
                     runningInflations.remove(inflationId);
-                    handleInflationError(runningInflations, e, row.getStatusBarNotification(),
+                    handleInflationError(runningInflations, e, row.getEntry().getSbn(),
                             callback);
                 }
             }
@@ -838,7 +838,7 @@
 
         private void handleError(Exception e) {
             mRow.getEntry().onInflationTaskFinished();
-            StatusBarNotification sbn = mRow.getStatusBarNotification();
+            StatusBarNotification sbn = mRow.getEntry().getSbn();
             final String ident = sbn.getPackageName() + "/0x"
                     + Integer.toHexString(sbn.getId());
             Log.e(StatusBar.TAG, "couldn't inflate view for notification " + ident, e);
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 f67cd1b..77c0a46 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
@@ -189,7 +189,7 @@
     @VisibleForTesting
     protected boolean bindGuts(final ExpandableNotificationRow row,
             NotificationMenuRowPlugin.MenuItem item) {
-        StatusBarNotification sbn = row.getStatusBarNotification();
+        StatusBarNotification sbn = row.getEntry().getSbn();
 
         row.setGutsView(item);
         row.setTag(sbn.getPackageName());
@@ -238,7 +238,7 @@
             final ExpandableNotificationRow row,
             NotificationSnooze notificationSnoozeView) {
         NotificationGuts guts = row.getGuts();
-        StatusBarNotification sbn = row.getStatusBarNotification();
+        StatusBarNotification sbn = row.getEntry().getSbn();
 
         notificationSnoozeView.setSnoozeListener(mListContainer.getSwipeActionHelper());
         notificationSnoozeView.setStatusBarNotification(sbn);
@@ -258,7 +258,7 @@
             final ExpandableNotificationRow row,
             AppOpsInfo appOpsInfoView) {
         NotificationGuts guts = row.getGuts();
-        StatusBarNotification sbn = row.getStatusBarNotification();
+        StatusBarNotification sbn = row.getEntry().getSbn();
         UserHandle userHandle = sbn.getUser();
         PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext,
                 userHandle.getIdentifier());
@@ -284,7 +284,7 @@
             final ExpandableNotificationRow row,
             NotificationInfo notificationInfoView) throws Exception {
         NotificationGuts guts = row.getGuts();
-        StatusBarNotification sbn = row.getStatusBarNotification();
+        StatusBarNotification sbn = row.getEntry().getSbn();
         String packageName = sbn.getPackageName();
         // Settings link is only valid for notifications that specify a non-system user
         NotificationInfo.OnSettingsClickListener onSettingsClick = null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
index 2da4d2c..7248bce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
@@ -39,7 +39,7 @@
     @Override
     public void onContentUpdated(ExpandableNotificationRow row) {
         super.onContentUpdated(row);
-        updateImageTag(row.getStatusBarNotification());
+        updateImageTag(row.getEntry().getSbn());
     }
 
     private void updateImageTag(StatusBarNotification notification) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java
index 4261df3..41f93cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java
@@ -44,7 +44,7 @@
     public void onContentUpdated(ExpandableNotificationRow row) {
         // Reinspect the notification. Before the super call, because the super call also updates
         // the transformation types and we need to have our values set by then.
-        resolveViews(row.getStatusBarNotification());
+        resolveViews(row.getEntry().getSbn());
         super.onContentUpdated(row);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index 0b3871d..5e52c0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -125,7 +125,7 @@
         updateTransformedTypes();
         addRemainingTransformTypes();
         updateCropToPaddingForImageViews();
-        Notification notification = row.getStatusBarNotification().getNotification();
+        Notification notification = row.getEntry().getSbn().getNotification();
         mIcon.setTag(ImageTransformState.ICON_TAG, notification.getSmallIcon());
         // The work profile image is always the same lets just set the icon tag for it not to
         // animate
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
index 516d649..2a4b315 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
@@ -183,7 +183,7 @@
             QuickQSPanel panel = ctrl.getStatusBarView().findViewById(
                     com.android.systemui.R.id.quick_qs_panel);
             panel.getMediaPlayer().setMediaSession(token,
-                    mRow.getStatusBarNotification().getNotification().getSmallIcon(),
+                    mRow.getEntry().getSbn().getNotification().getSmallIcon(),
                     getNotificationHeader().getOriginalIconColor(),
                     mRow.getCurrentBackgroundTint(),
                     mActions,
@@ -191,11 +191,11 @@
             QSPanel bigPanel = ctrl.getStatusBarView().findViewById(
                     com.android.systemui.R.id.quick_settings_panel);
             bigPanel.addMediaSession(token,
-                    mRow.getStatusBarNotification().getNotification().getSmallIcon(),
+                    mRow.getEntry().getSbn().getNotification().getSmallIcon(),
                     getNotificationHeader().getOriginalIconColor(),
                     mRow.getCurrentBackgroundTint(),
                     mActions,
-                    mRow.getStatusBarNotification());
+                    mRow.getEntry().getSbn());
         }
 
         boolean showCompactSeekbar = mMediaManager.getShowCompactMediaSeekbar();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
index 97d8443..90ea6e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
@@ -286,7 +286,7 @@
     public void onContentUpdated(ExpandableNotificationRow row) {
         // Reinspect the notification. Before the super call, because the super call also updates
         // the transformation types and we need to have our values set by then.
-        resolveTemplateViews(row.getStatusBarNotification());
+        resolveTemplateViews(row.getEntry().getSbn());
         super.onContentUpdated(row);
         if (row.getHeaderVisibleAmount() != DEFAULT_HEADER_VISIBLE_AMOUNT) {
             setHeaderVisibleAmount(row.getHeaderVisibleAmount());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 45f7b3a..75ceb0f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -299,7 +299,7 @@
 
     public void recreateNotificationHeader(OnClickListener listener) {
         mHeaderClickListener = listener;
-        StatusBarNotification notification = mContainingNotification.getStatusBarNotification();
+        StatusBarNotification notification = mContainingNotification.getEntry().getSbn();
         final Notification.Builder builder = Notification.Builder.recoverBuilder(getContext(),
                 notification.getNotification());
         RemoteViews header = builder.makeNotificationHeader();
@@ -329,7 +329,7 @@
      */
     private void recreateLowPriorityHeader(Notification.Builder builder) {
         RemoteViews header;
-        StatusBarNotification notification = mContainingNotification.getStatusBarNotification();
+        StatusBarNotification notification = mContainingNotification.getEntry().getSbn();
         if (mIsLowPriority) {
             if (builder == null) {
                 builder = Notification.Builder.recoverBuilder(getContext(),
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 462fa59..43af3aa 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
@@ -1454,8 +1454,8 @@
         }
         ExpandableNotificationRow row = topEntry.getRow();
         if (row.isChildInGroup()) {
-            final NotificationEntry groupSummary
-                    = mGroupManager.getGroupSummary(row.getStatusBarNotification());
+            final NotificationEntry groupSummary =
+                    mGroupManager.getGroupSummary(row.getEntry().getSbn());
             if (groupSummary != null) {
                 row = groupSummary.getRow();
             }
@@ -2996,7 +2996,7 @@
     private boolean isChildInGroup(View child) {
         return child instanceof ExpandableNotificationRow
                 && mGroupManager.isChildInGroupWithSummary(
-                ((ExpandableNotificationRow) child).getStatusBarNotification());
+                ((ExpandableNotificationRow) child).getEntry().getSbn());
     }
 
     /**
@@ -3071,7 +3071,7 @@
         if (child instanceof ExpandableNotificationRow) {
             ExpandableNotificationRow row = (ExpandableNotificationRow) child;
             NotificationEntry groupSummary =
-                    mGroupManager.getGroupSummary(row.getStatusBarNotification());
+                    mGroupManager.getGroupSummary(row.getEntry().getSbn());
             if (groupSummary != null && groupSummary.getRow() != row) {
                 return row.getVisibility() == View.INVISIBLE;
             }
@@ -6134,7 +6134,7 @@
             }
             if (view instanceof ExpandableNotificationRow) {
                 ExpandableNotificationRow row = (ExpandableNotificationRow) view;
-                mMetricsLogger.write(row.getStatusBarNotification().getLogMaker()
+                mMetricsLogger.write(row.getEntry().getSbn().getLogMaker()
                         .setCategory(MetricsEvent.ACTION_TOUCH_GEAR)
                         .setType(MetricsEvent.TYPE_ACTION)
                         );
@@ -6160,7 +6160,7 @@
         public void onMenuShown(View row) {
             if (row instanceof ExpandableNotificationRow) {
                 ExpandableNotificationRow notificationRow = (ExpandableNotificationRow) row;
-                mMetricsLogger.write(notificationRow.getStatusBarNotification().getLogMaker()
+                mMetricsLogger.write(notificationRow.getEntry().getSbn().getLogMaker()
                         .setCategory(MetricsEvent.ACTION_REVEAL_GEAR)
                         .setType(MetricsEvent.TYPE_ACTION));
                 mHeadsUpManager.setMenuShown(notificationRow.getEntry(), true);
@@ -6256,7 +6256,7 @@
                 ExpandableNotificationRow row = (ExpandableNotificationRow) view;
                 if (row.isHeadsUp()) {
                     mHeadsUpManager.addSwipedOutNotification(
-                            row.getStatusBarNotification().getKey());
+                            row.getEntry().getSbn().getKey());
                 }
                 isBlockingHelperShown =
                         row.performDismissWithBlockingHelper(false /* fromAccessibility */);
@@ -6327,9 +6327,9 @@
             if (animView instanceof ExpandableNotificationRow) {
                 ExpandableNotificationRow row = (ExpandableNotificationRow) animView;
                 if (row.isPinned() && !canChildBeDismissed(row)
-                        && row.getStatusBarNotification().getNotification().fullScreenIntent
+                        && row.getEntry().getSbn().getNotification().fullScreenIntent
                                 == null) {
-                    mHeadsUpManager.removeNotification(row.getStatusBarNotification().getKey(),
+                    mHeadsUpManager.removeNotification(row.getEntry().getSbn().getKey(),
                             true /* removeImmediately */);
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index 6aee194..063ad85 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -88,8 +88,9 @@
     private final PulseExpansionHandler mPulseExpansionHandler;
     private final StatusBarWindowController mStatusBarWindowController;
     private final NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
+    private final StatusBarWindowViewController mStatusBarWindowViewController;
+    private final LockscreenLockIconController mLockscreenLockIconController;
     private NotificationIconAreaController mNotificationIconAreaController;
-    private StatusBarWindowViewController mStatusBarWindowViewController;
     private StatusBarWindowView mStatusBarWindow;
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private NotificationPanelView mNotificationPanel;
@@ -110,7 +111,9 @@
             VisualStabilityManager visualStabilityManager,
             PulseExpansionHandler pulseExpansionHandler,
             StatusBarWindowController statusBarWindowController,
-            NotificationWakeUpCoordinator notificationWakeUpCoordinator) {
+            NotificationWakeUpCoordinator notificationWakeUpCoordinator,
+            StatusBarWindowViewController statusBarWindowViewController,
+            LockscreenLockIconController lockscreenLockIconController) {
         super();
         mDozeLog = dozeLog;
         mPowerManager = powerManager;
@@ -129,6 +132,8 @@
         mPulseExpansionHandler = pulseExpansionHandler;
         mStatusBarWindowController = statusBarWindowController;
         mNotificationWakeUpCoordinator = notificationWakeUpCoordinator;
+        mStatusBarWindowViewController = statusBarWindowViewController;
+        mLockscreenLockIconController = lockscreenLockIconController;
     }
 
     // TODO: we should try to not pass status bar in here if we can avoid it.
@@ -138,13 +143,11 @@
      */
     public void initialize(StatusBar statusBar,
             NotificationIconAreaController notificationIconAreaController,
-            StatusBarWindowViewController statusBarWindowViewController,
             StatusBarWindowView statusBarWindow,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             NotificationPanelView notificationPanel, View ambientIndicationContainer) {
         mStatusBar = statusBar;
         mNotificationIconAreaController = notificationIconAreaController;
-        mStatusBarWindowViewController = statusBarWindowViewController;
         mStatusBarWindow = statusBarWindow;
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mNotificationPanel = notificationPanel;
@@ -262,7 +265,7 @@
                 mKeyguardViewMediator.setPulsing(pulsing);
                 mNotificationPanel.setPulsing(pulsing);
                 mVisualStabilityManager.setPulsing(pulsing);
-                mStatusBarWindowViewController.setPulsing(pulsing);
+                mLockscreenLockIconController.setPulsing(pulsing);
                 mIgnoreTouchWhilePulsing = false;
                 if (mKeyguardUpdateMonitor != null && passiveAuthInterrupt) {
                     mKeyguardUpdateMonitor.onAuthInterruptDetected(pulsing /* active */);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
index 1c8e832..8ee964f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
@@ -22,7 +22,6 @@
 import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.graphics.PointF;
-import android.graphics.Rect;
 import android.graphics.Region;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
@@ -32,9 +31,7 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.util.Log;
-import android.util.MathUtils;
 import android.util.StatsLog;
-import android.view.Gravity;
 import android.view.ISystemGestureExclusionListener;
 import android.view.InputChannel;
 import android.view.InputDevice;
@@ -44,7 +41,6 @@
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
-import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
@@ -53,7 +49,10 @@
 import com.android.systemui.R;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.model.SysUiState;
+import com.android.systemui.plugins.NavigationEdgeBackPlugin;
+import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.shared.system.QuickStepContract;
 
 import java.io.PrintWriter;
@@ -62,7 +61,8 @@
 /**
  * Utility class to handle edge swipes for back gesture
  */
-public class EdgeBackGestureHandler implements DisplayListener {
+public class EdgeBackGestureHandler implements DisplayListener,
+        PluginListener<NavigationEdgeBackPlugin> {
 
     private static final String TAG = "EdgeBackGestureHandler";
     private static final int MAX_LONG_PRESS_TIMEOUT = SystemProperties.getInt(
@@ -85,6 +85,7 @@
 
     private final Context mContext;
     private final OverviewProxyService mOverviewProxyService;
+    private PluginManager mPluginManager;
 
     private final Point mDisplaySize = new Point();
     private final int mDisplayId;
@@ -100,14 +101,6 @@
     private final float mTouchSlop;
     // Duration after which we consider the event as longpress.
     private final int mLongPressTimeout;
-    // The threshold where the touch needs to be at most, such that the arrow is displayed above the
-    // finger, otherwise it will be below
-    private final int mMinArrowPosition;
-    // The amount by which the arrow is shifted to avoid the finger
-    private final int mFingerOffset;
-
-
-    private final int mNavBarHeight;
 
     private final PointF mDownPoint = new PointF();
     private boolean mThresholdCrossed = false;
@@ -123,24 +116,49 @@
     private InputMonitor mInputMonitor;
     private InputEventReceiver mInputEventReceiver;
 
-    private final WindowManager mWm;
-
-    private NavigationBarEdgePanel mEdgePanel;
-    private WindowManager.LayoutParams mEdgePanelLp;
-    private final Rect mSamplingRect = new Rect();
-    private RegionSamplingHelper mRegionSamplingHelper;
+    private NavigationEdgeBackPlugin mEdgeBackPlugin;
     private int mLeftInset;
     private int mRightInset;
     private int mSysUiFlags;
 
+    private final NavigationEdgeBackPlugin.BackCallback mBackCallback =
+            new NavigationEdgeBackPlugin.BackCallback() {
+                @Override
+                public void triggerBack() {
+                    sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
+                    sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
+
+                    mOverviewProxyService.notifyBackAction(true, (int) mDownPoint.x,
+                            (int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge);
+                    int backtype = (mInRejectedExclusion
+                            ? StatsLog.BACK_GESTURE__TYPE__COMPLETED_REJECTED :
+                            StatsLog.BACK_GESTURE__TYPE__COMPLETED);
+                    StatsLog.write(StatsLog.BACK_GESTURE_REPORTED_REPORTED, backtype,
+                            (int) mDownPoint.y, mIsOnLeftEdge
+                                    ? StatsLog.BACK_GESTURE__X_LOCATION__LEFT :
+                                    StatsLog.BACK_GESTURE__X_LOCATION__RIGHT);
+                }
+
+                @Override
+                public void cancelBack() {
+                    mOverviewProxyService.notifyBackAction(false, (int) mDownPoint.x,
+                            (int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge);
+                    int backtype = StatsLog.BACK_GESTURE__TYPE__INCOMPLETE;
+                    StatsLog.write(StatsLog.BACK_GESTURE_REPORTED_REPORTED, backtype,
+                            (int) mDownPoint.y, mIsOnLeftEdge
+                                    ? StatsLog.BACK_GESTURE__X_LOCATION__LEFT :
+                                    StatsLog.BACK_GESTURE__X_LOCATION__RIGHT);
+                }
+            };
+
     public EdgeBackGestureHandler(Context context, OverviewProxyService overviewProxyService,
-            SysUiState sysUiFlagContainer) {
+            SysUiState sysUiFlagContainer, PluginManager pluginManager) {
         final Resources res = context.getResources();
         mContext = context;
         mDisplayId = context.getDisplayId();
         mMainExecutor = context.getMainExecutor();
-        mWm = context.getSystemService(WindowManager.class);
         mOverviewProxyService = overviewProxyService;
+        mPluginManager = pluginManager;
 
         // Reduce the default touch slop to ensure that we can intercept the gesture
         // before the app starts to react to it.
@@ -149,9 +167,6 @@
         mLongPressTimeout = Math.min(MAX_LONG_PRESS_TIMEOUT,
                 ViewConfiguration.getLongPressTimeout());
 
-        mNavBarHeight = res.getDimensionPixelSize(R.dimen.navigation_bar_frame_height);
-        mMinArrowPosition = res.getDimensionPixelSize(R.dimen.navigation_edge_arrow_min_y);
-        mFingerOffset = res.getDimensionPixelSize(R.dimen.navigation_edge_finger_offset);
         updateCurrentUserResources(res);
         sysUiFlagContainer.addCallback(sysUiFlags -> mSysUiFlags = sysUiFlags);
     }
@@ -206,15 +221,14 @@
         mIsEnabled = isEnabled;
         disposeInputChannel();
 
-        if (mEdgePanel != null) {
-            mWm.removeView(mEdgePanel);
-            mEdgePanel = null;
-            mRegionSamplingHelper.stop();
-            mRegionSamplingHelper = null;
+        if (mEdgeBackPlugin != null) {
+            mEdgeBackPlugin.onDestroy();
+            mEdgeBackPlugin = null;
         }
 
         if (!mIsEnabled) {
             mContext.getSystemService(DisplayManager.class).unregisterDisplayListener(this);
+            mPluginManager.removePluginListener(this);
 
             try {
                 WindowManagerGlobal.getWindowManagerService()
@@ -244,41 +258,51 @@
                     mInputMonitor.getInputChannel(), Looper.getMainLooper());
 
             // Add a nav bar panel window
-            mEdgePanel = new NavigationBarEdgePanel(mContext);
-            mEdgePanelLp = new WindowManager.LayoutParams(
-                    mContext.getResources()
-                            .getDimensionPixelSize(R.dimen.navigation_edge_panel_width),
-                    mContext.getResources()
-                            .getDimensionPixelSize(R.dimen.navigation_edge_panel_height),
-                    WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
-                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                            | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
-                            | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
-                    PixelFormat.TRANSLUCENT);
-            mEdgePanelLp.privateFlags |=
-                    WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
-            mEdgePanelLp.setTitle(TAG + mDisplayId);
-            mEdgePanelLp.accessibilityTitle = mContext.getString(R.string.nav_bar_edge_panel);
-            mEdgePanelLp.windowAnimations = 0;
-            mEdgePanel.setLayoutParams(mEdgePanelLp);
-            mWm.addView(mEdgePanel, mEdgePanelLp);
-            mRegionSamplingHelper = new RegionSamplingHelper(mEdgePanel,
-                    new RegionSamplingHelper.SamplingCallback() {
-                        @Override
-                        public void onRegionDarknessChanged(boolean isRegionDark) {
-                            mEdgePanel.setIsDark(!isRegionDark, true /* animate */);
-                        }
-
-                        @Override
-                        public Rect getSampledRegion(View sampledView) {
-                            return mSamplingRect;
-                        }
-                    });
-            mRegionSamplingHelper.setWindowVisible(true);
+            setEdgeBackPlugin(new NavigationBarEdgePanel(mContext));
+            mPluginManager.addPluginListener(
+                    this, NavigationEdgeBackPlugin.class, /*allowMultiple=*/ false);
         }
     }
 
+    @Override
+    public void onPluginConnected(NavigationEdgeBackPlugin plugin, Context context) {
+        setEdgeBackPlugin(plugin);
+    }
+
+    @Override
+    public void onPluginDisconnected(NavigationEdgeBackPlugin plugin) {
+        setEdgeBackPlugin(new NavigationBarEdgePanel(mContext));
+    }
+
+    private void setEdgeBackPlugin(NavigationEdgeBackPlugin edgeBackPlugin) {
+        if (mEdgeBackPlugin != null) {
+            mEdgeBackPlugin.onDestroy();
+        }
+        mEdgeBackPlugin = edgeBackPlugin;
+        mEdgeBackPlugin.setBackCallback(mBackCallback);
+        mEdgeBackPlugin.setLayoutParams(createLayoutParams());
+        updateDisplaySize();
+    }
+
+    private WindowManager.LayoutParams createLayoutParams() {
+        Resources resources = mContext.getResources();
+        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
+                resources.getDimensionPixelSize(R.dimen.navigation_edge_panel_width),
+                resources.getDimensionPixelSize(R.dimen.navigation_edge_panel_height),
+                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
+                PixelFormat.TRANSLUCENT);
+        layoutParams.privateFlags |=
+                WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
+        layoutParams.setTitle(TAG + mContext.getDisplayId());
+        layoutParams.accessibilityTitle = mContext.getString(R.string.nav_bar_edge_panel);
+        layoutParams.windowAnimations = 0;
+        return layoutParams;
+    }
+
     private void onInputEvent(InputEvent ev) {
         if (ev instanceof MotionEvent) {
             onMotionEvent((MotionEvent) ev);
@@ -316,7 +340,7 @@
         mInRejectedExclusion = false;
         MotionEvent cancelEv = MotionEvent.obtain(ev);
         cancelEv.setAction(MotionEvent.ACTION_CANCEL);
-        mEdgePanel.handleTouch(cancelEv);
+        mEdgeBackPlugin.onMotionEvent(cancelEv);
         cancelEv.recycle();
     }
 
@@ -330,14 +354,8 @@
             mAllowGesture = !QuickStepContract.isBackGestureDisabled(mSysUiFlags)
                     && isWithinTouchRegion((int) ev.getX(), (int) ev.getY());
             if (mAllowGesture) {
-                mEdgePanelLp.gravity = mIsOnLeftEdge
-                        ? (Gravity.LEFT | Gravity.TOP)
-                        : (Gravity.RIGHT | Gravity.TOP);
-                mEdgePanel.setIsLeftPanel(mIsOnLeftEdge);
-                mEdgePanel.handleTouch(ev);
-                updateEdgePanelPosition(ev.getY());
-                mWm.updateViewLayout(mEdgePanel, mEdgePanelLp);
-                mRegionSamplingHelper.start(mSamplingRect);
+                mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge);
+                mEdgeBackPlugin.onMotionEvent(ev);
 
                 mDownPoint.set(ev.getX(), ev.getY());
                 mThresholdCrossed = false;
@@ -369,53 +387,10 @@
             }
 
             // forward touch
-            mEdgePanel.handleTouch(ev);
-
-            boolean isUp = action == MotionEvent.ACTION_UP;
-            if (isUp) {
-                boolean performAction = mEdgePanel.shouldTriggerBack();
-                if (performAction) {
-                    // Perform back
-                    sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
-                    sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
-                }
-                mOverviewProxyService.notifyBackAction(performAction, (int) mDownPoint.x,
-                        (int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge);
-                int backtype = performAction ? (mInRejectedExclusion
-                        ? StatsLog.BACK_GESTURE__TYPE__COMPLETED_REJECTED :
-                                StatsLog.BACK_GESTURE__TYPE__COMPLETED) :
-                                        StatsLog.BACK_GESTURE__TYPE__INCOMPLETE;
-                StatsLog.write(StatsLog.BACK_GESTURE_REPORTED_REPORTED, backtype,
-                        (int) mDownPoint.y, mIsOnLeftEdge
-                                ? StatsLog.BACK_GESTURE__X_LOCATION__LEFT :
-                                StatsLog.BACK_GESTURE__X_LOCATION__RIGHT);
-            }
-            if (isUp || action == MotionEvent.ACTION_CANCEL) {
-                mRegionSamplingHelper.stop();
-            } else {
-                updateSamplingRect();
-                mRegionSamplingHelper.updateSamplingRect();
-            }
+            mEdgeBackPlugin.onMotionEvent(ev);
         }
     }
 
-    private void updateEdgePanelPosition(float touchY) {
-        float position = touchY - mFingerOffset;
-        position = Math.max(position, mMinArrowPosition);
-        position = (position - mEdgePanelLp.height / 2.0f);
-        mEdgePanelLp.y = MathUtils.constrain((int) position, 0, mDisplaySize.y);
-        updateSamplingRect();
-    }
-
-    private void updateSamplingRect() {
-        int top = mEdgePanelLp.y;
-        int left = mIsOnLeftEdge ? mLeftInset : mDisplaySize.x - mRightInset - mEdgePanelLp.width;
-        int right = left + mEdgePanelLp.width;
-        int bottom = top + mEdgePanelLp.height;
-        mSamplingRect.set(left, top, right, bottom);
-        mEdgePanel.adjustRectToBoundingBox(mSamplingRect);
-    }
-
     @Override
     public void onDisplayAdded(int displayId) { }
 
@@ -433,6 +408,9 @@
         mContext.getSystemService(DisplayManager.class)
                 .getDisplay(mDisplayId)
                 .getRealSize(mDisplaySize);
+        if (mEdgeBackPlugin != null) {
+            mEdgeBackPlugin.setDisplaySize(mDisplaySize);
+        }
     }
 
     private void sendEvent(int action, int code) {
@@ -454,6 +432,9 @@
     public void setInsets(int leftInset, int rightInset) {
         mLeftInset = leftInset;
         mRightInset = rightInset;
+        if (mEdgeBackPlugin != null) {
+            mEdgeBackPlugin.setInsets(leftInset, rightInset);
+        }
     }
 
     public void dump(PrintWriter pw) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index 4e06c84..6ac6d35 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -52,13 +52,9 @@
 import java.util.HashSet;
 import java.util.Stack;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 /**
  * A implementation of HeadsUpManager for phone and car.
  */
-@Singleton
 public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
         VisualStabilityManager.Callback, OnHeadsUpChangedListener,
         ConfigurationController.ConfigurationListener, StateListener {
@@ -113,7 +109,6 @@
     ///////////////////////////////////////////////////////////////////////////////////////////////
     //  Constructor:
 
-    @Inject
     public HeadsUpManagerPhone(@NonNull final Context context,
             StatusBarStateController statusBarStateController,
             KeyguardBypassController bypassController) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index 7f31f3d..ac06d9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -132,7 +132,7 @@
                 if (mPickedChild != null && mTouchingHeadsUpView) {
                     // We may swallow this click if the heads up just came in.
                     if (mHeadsUpManager.shouldSwallowClick(
-                            mPickedChild.getStatusBarNotification().getKey())) {
+                            mPickedChild.getEntry().getSbn().getKey())) {
                         endMotion();
                         return true;
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
new file mode 100644
index 0000000..1e35b46
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
@@ -0,0 +1,89 @@
+/*
+ * 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.phone;
+
+import com.android.systemui.statusbar.SuperStatusBarViewFactory;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/** Controls the {@link LockIcon} in the lockscreen. */
+@Singleton
+public class LockscreenLockIconController {
+
+    private final LockIcon mLockIcon;
+
+    @Inject
+    public LockscreenLockIconController(SuperStatusBarViewFactory superStatusBarViewFactory) {
+        mLockIcon = superStatusBarViewFactory.getLockIcon();
+    }
+
+    /**
+     * Called whenever the scrims become opaque, transparent or semi-transparent.
+     */
+    public void onScrimVisibilityChanged(Integer scrimsVisible) {
+        if (mLockIcon != null) {
+            mLockIcon.onScrimVisibilityChanged(scrimsVisible);
+        }
+    }
+
+    /**
+     * Propagate {@link StatusBar} pulsing state.
+     */
+    public void setPulsing(boolean pulsing) {
+        if (mLockIcon != null) {
+            mLockIcon.setPulsing(pulsing);
+        }
+    }
+
+    /**
+     * Called when the biometric authentication mode changes.
+     *
+     * @param wakeAndUnlock If the type is {@link BiometricUnlockController#isWakeAndUnlock()}
+     * @param isUnlock      If the type is {@link BiometricUnlockController#isBiometricUnlock()} ()
+     */
+    public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) {
+        if (mLockIcon != null) {
+            mLockIcon.onBiometricAuthModeChanged(wakeAndUnlock, isUnlock);
+        }
+    }
+
+    /**
+     * When we're launching an affordance, like double pressing power to open camera.
+     */
+    public void onShowingLaunchAffordanceChanged(Boolean showing) {
+        if (mLockIcon != null) {
+            mLockIcon.onShowingLaunchAffordanceChanged(showing);
+        }
+    }
+
+    /** Sets whether the bouncer is showing. */
+    public void setBouncerShowingScrimmed(boolean bouncerShowing) {
+        if (mLockIcon != null) {
+            mLockIcon.setBouncerShowingScrimmed(bouncerShowing);
+        }
+    }
+
+    /**
+     * When {@link KeyguardBouncer} starts to be dismissed and starts to play its animation.
+     */
+    public void onBouncerPreHideAnimation() {
+        if (mLockIcon != null) {
+            mLockIcon.onBouncerPreHideAnimation();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
index 4f223c3..2357309 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
@@ -19,34 +19,40 @@
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.Configuration;
-import android.graphics.Canvas;;
+import android.content.res.Resources;
+import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Path;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.SystemClock;
 import android.os.VibrationEffect;
-import android.util.DisplayMetrics;
 import android.util.MathUtils;
 import android.view.ContextThemeWrapper;
+import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
+import android.view.WindowManager;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 
-import com.android.settingslib.Utils;
-import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.VibratorHelper;
-
 import androidx.core.graphics.ColorUtils;
 import androidx.dynamicanimation.animation.DynamicAnimation;
 import androidx.dynamicanimation.animation.FloatPropertyCompat;
 import androidx.dynamicanimation.animation.SpringAnimation;
 import androidx.dynamicanimation.animation.SpringForce;
 
-public class NavigationBarEdgePanel extends View {
+import com.android.settingslib.Utils;
+import com.android.systemui.Dependency;
+import com.android.systemui.Interpolators;
+import com.android.systemui.R;
+import com.android.systemui.plugins.NavigationEdgeBackPlugin;
+import com.android.systemui.statusbar.VibratorHelper;
+
+public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPlugin {
+
+    private static final String TAG = "NavigationBarEdgePanel";
 
     private static final long COLOR_ANIMATION_DURATION_MS = 120;
     private static final long DISAPPEAR_FADE_ANIMATION_DURATION_MS = 80;
@@ -114,6 +120,7 @@
     private static final Interpolator RUBBER_BAND_INTERPOLATOR_APPEAR
             = new PathInterpolator(1.0f / RUBBER_BAND_AMOUNT_APPEAR, 1.0f, 1.0f, 1.0f);
 
+    private final WindowManager mWindowManager;
     private final VibratorHelper mVibratorHelper;
 
     /**
@@ -134,9 +141,14 @@
      * The minimum delta needed in movement for the arrow to change direction / stop triggering back
      */
     private final float mMinDeltaForSwitch;
+    // The closest to y = 0 that the arrow will be displayed.
+    private int mMinArrowPosition;
+    // The amount the arrow is shifted to avoid the finger.
+    private int mFingerOffset;
 
     private final float mSwipeThreshold;
     private final Path mArrowPath = new Path();
+    private final Point mDisplaySize = new Point();
 
     private final SpringAnimation mAngleAnimation;
     private final SpringAnimation mTranslationAnimation;
@@ -158,6 +170,11 @@
     private int mArrowColorDark;
     private int mProtectionColor;
     private int mArrowColor;
+    private RegionSamplingHelper mRegionSamplingHelper;
+    private final Rect mSamplingRect = new Rect();
+    private WindowManager.LayoutParams mLayoutParams;
+    private int mLeftInset;
+    private int mRightInset;
 
     /**
      * True if the panel is currently on the left of the screen
@@ -242,10 +259,12 @@
                     return object.getVerticalTranslation();
                 }
             };
+    private BackCallback mBackCallback;
 
     public NavigationBarEdgePanel(Context context) {
         super(context);
 
+        mWindowManager = context.getSystemService(WindowManager.class);
         mVibratorHelper = Dependency.get(VibratorHelper.class);
 
         mDensity = context.getResources().getDisplayMetrics().density;
@@ -263,13 +282,10 @@
 
         mArrowColorAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
         mArrowColorAnimator.setDuration(COLOR_ANIMATION_DURATION_MS);
-        mArrowColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                int newColor = ColorUtils.blendARGB(mArrowStartColor, mArrowColor,
-                        animation.getAnimatedFraction());
-                setCurrentArrowColor(newColor);
-            }
+        mArrowColorAnimator.addUpdateListener(animation -> {
+            int newColor = ColorUtils.blendARGB(
+                    mArrowStartColor, mArrowColor, animation.getAnimatedFraction());
+            setCurrentArrowColor(newColor);
         });
 
         mArrowDisappearAnimation = ValueAnimator.ofFloat(0.0f, 1.0f);
@@ -317,6 +333,27 @@
         mSwipeThreshold = context.getResources()
                 .getDimension(R.dimen.navigation_edge_action_drag_threshold);
         setVisibility(GONE);
+
+        mRegionSamplingHelper = new RegionSamplingHelper(this,
+                new RegionSamplingHelper.SamplingCallback() {
+                    @Override
+                    public void onRegionDarknessChanged(boolean isRegionDark) {
+                        setIsDark(!isRegionDark, true /* animate */);
+                    }
+
+                    @Override
+                    public Rect getSampledRegion(View sampledView) {
+                        return mSamplingRect;
+                    }
+                });
+        mRegionSamplingHelper.setWindowVisible(true);
+    }
+
+    @Override
+    public void onDestroy() {
+        mWindowManager.removeView(this);
+        mRegionSamplingHelper.stop();
+        mRegionSamplingHelper = null;
     }
 
     @Override
@@ -324,30 +361,51 @@
         return false;
     }
 
-    public boolean shouldTriggerBack() {
-        return mTriggerBack;
-    }
-
-    public void setIsDark(boolean isDark, boolean animate) {
+    private void setIsDark(boolean isDark, boolean animate) {
         mIsDark = isDark;
         updateIsDark(animate);
     }
 
-    public void setShowProtection(boolean showProtection) {
+    private void setShowProtection(boolean showProtection) {
         mShowProtection = showProtection;
         invalidate();
     }
 
+    @Override
     public void setIsLeftPanel(boolean isLeftPanel) {
         mIsLeftPanel = isLeftPanel;
+        mLayoutParams.gravity = mIsLeftPanel
+                ? (Gravity.LEFT | Gravity.TOP)
+                : (Gravity.RIGHT | Gravity.TOP);
+    }
+
+    @Override
+    public void setInsets(int leftInset, int rightInset) {
+        mLeftInset = leftInset;
+        mRightInset = rightInset;
+    }
+
+    @Override
+    public void setDisplaySize(Point displaySize) {
+        mDisplaySize.set(displaySize.x, displaySize.y);
+        mScreenSize = Math.min(mDisplaySize.x, mDisplaySize.y);
+    }
+
+    @Override
+    public void setBackCallback(BackCallback callback) {
+        mBackCallback = callback;
+    }
+
+    @Override
+    public void setLayoutParams(WindowManager.LayoutParams layoutParams) {
+        mLayoutParams = layoutParams;
+        mWindowManager.addView(this, mLayoutParams);
     }
 
     /**
-     * Adjust the rect to conform the the actual visible bounding box of the arrow.
-     *
-     * @param samplingRect the existing bounding box in screen coordinates, to be modified
+     * Adjusts the sampling rect to conform to the actual visible bounding box of the arrow.
      */
-    public void adjustRectToBoundingBox(Rect samplingRect) {
+    private void adjustSamplingRectToBoundingBox() {
         float translation = mDesiredTranslation;
         if (!mTriggerBack) {
             // Let's take the resting position and bounds as the sampling rect, since we are not
@@ -361,7 +419,7 @@
             }
         }
         float left = translation - mArrowThickness / 2.0f;
-        left = mIsLeftPanel ? left : samplingRect.width() - left;
+        left = mIsLeftPanel ? left : mSamplingRect.width() - left;
 
         // Let's calculate the position of the end based on the angle
         float width = getStaticArrowWidth();
@@ -371,49 +429,49 @@
         }
 
         float top = (getHeight() * 0.5f) + mDesiredVerticalTranslation - height / 2.0f;
-        samplingRect.offset((int) left, (int) top);
-        samplingRect.set(samplingRect.left, samplingRect.top,
-                (int) (samplingRect.left + width),
-                (int) (samplingRect.top + height));
+        mSamplingRect.offset((int) left, (int) top);
+        mSamplingRect.set(mSamplingRect.left, mSamplingRect.top,
+                (int) (mSamplingRect.left + width),
+                (int) (mSamplingRect.top + height));
+        mRegionSamplingHelper.updateSamplingRect();
     }
 
-    /**
-     * Updates the UI based on the motion events passed in device co-ordinates
-     */
-    public void handleTouch(MotionEvent event) {
+    @Override
+    public void onMotionEvent(MotionEvent event) {
         if (mVelocityTracker == null) {
             mVelocityTracker = VelocityTracker.obtain();
         }
         mVelocityTracker.addMovement(event);
         switch (event.getActionMasked()) {
-            case MotionEvent.ACTION_DOWN : {
+            case MotionEvent.ACTION_DOWN:
                 mDragSlopPassed = false;
                 resetOnDown();
                 mStartX = event.getX();
                 mStartY = event.getY();
                 setVisibility(VISIBLE);
+                updatePosition(event.getY());
+                mRegionSamplingHelper.start(mSamplingRect);
+                mWindowManager.updateViewLayout(this, mLayoutParams);
                 break;
-            }
-            case MotionEvent.ACTION_MOVE: {
+            case MotionEvent.ACTION_MOVE:
                 handleMoveEvent(event);
                 break;
-            }
-            // Fall through
             case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL: {
                 if (mTriggerBack) {
                     triggerBack();
                 } else {
-                    if (mTranslationAnimation.isRunning()) {
-                        mTranslationAnimation.addEndListener(mSetGoneEndListener);
-                    } else {
-                        setVisibility(GONE);
-                    }
+                    cancelBack();
                 }
+                mRegionSamplingHelper.stop();
                 mVelocityTracker.recycle();
                 mVelocityTracker = null;
                 break;
-            }
+            case MotionEvent.ACTION_CANCEL:
+                cancelBack();
+                mRegionSamplingHelper.stop();
+                mVelocityTracker.recycle();
+                mVelocityTracker = null;
+                break;
         }
     }
 
@@ -452,10 +510,10 @@
     }
 
     private void loadDimens() {
-        mArrowPaddingEnd = getContext().getResources().getDimensionPixelSize(
-                R.dimen.navigation_edge_panel_padding);
-        DisplayMetrics metrics = getResources().getDisplayMetrics();
-        mScreenSize = Math.min(metrics.widthPixels, metrics.heightPixels);
+        Resources res = getResources();
+        mArrowPaddingEnd = res.getDimensionPixelSize(R.dimen.navigation_edge_panel_padding);
+        mMinArrowPosition = res.getDimensionPixelSize(R.dimen.navigation_edge_arrow_min_y);
+        mFingerOffset = res.getDimensionPixelSize(R.dimen.navigation_edge_finger_offset);
     }
 
     private void updateArrowDirection() {
@@ -531,6 +589,11 @@
     }
 
     private void triggerBack() {
+        mBackCallback.triggerBack();
+
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        }
         mVelocityTracker.computeCurrentVelocity(1000);
         // Only do the extra translation if we're not already flinging
         boolean isSlow = Math.abs(mVelocityTracker.getXVelocity()) < 500;
@@ -573,7 +636,16 @@
         } else {
             translationEnd.run();
         }
+    }
 
+    private void cancelBack() {
+        mBackCallback.cancelBack();
+
+        if (mTranslationAnimation.isRunning()) {
+            mTranslationAnimation.addEndListener(mSetGoneEndListener);
+        } else {
+            setVisibility(GONE);
+        }
     }
 
     private void resetOnDown() {
@@ -680,6 +752,24 @@
         float verticalTranslation = RUBBER_BAND_INTERPOLATOR.getInterpolation(progress)
                 * maxYOffset * Math.signum(yOffset);
         setDesiredVerticalTransition(verticalTranslation, true /* animated */);
+        updateSamplingRect();
+    }
+
+    private void updatePosition(float touchY) {
+        float position = touchY - mFingerOffset;
+        position = Math.max(position, mMinArrowPosition);
+        position -= mLayoutParams.height / 2.0f;
+        mLayoutParams.y = MathUtils.constrain((int) position, 0, mDisplaySize.y);
+        updateSamplingRect();
+    }
+
+    private void updateSamplingRect() {
+        int top = mLayoutParams.y;
+        int left = mIsLeftPanel ? mLeftInset : mDisplaySize.x - mRightInset - mLayoutParams.width;
+        int right = left + mLayoutParams.width;
+        int bottom = top + mLayoutParams.height;
+        mSamplingRect.set(left, top, right, bottom);
+        adjustSamplingRectToBoundingBox();
     }
 
     private void setDesiredVerticalTransition(float verticalTranslation, boolean animated) {
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 d3c7940..5a1b20d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -72,6 +72,7 @@
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsOnboarding;
+import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -96,6 +97,7 @@
     private final RegionSamplingHelper mRegionSamplingHelper;
     private final int mNavColorSampleMargin;
     private final SysUiState mSysUiFlagContainer;
+    private final PluginManager mPluginManager;
 
     View mCurrentView = null;
     private View mVertical;
@@ -272,6 +274,7 @@
         boolean isGesturalMode = isGesturalMode(mNavBarMode);
 
         mSysUiFlagContainer = Dependency.get(SysUiState.class);
+        mPluginManager = Dependency.get(PluginManager.class);
         // Set up the context group of buttons
         mContextualButtonGroup = new ContextualButtonGroup(R.id.menu_container);
         final ContextualButton imeSwitcherButton = new ContextualButton(R.id.ime_switcher,
@@ -315,8 +318,8 @@
 
         mNavColorSampleMargin = getResources()
                         .getDimensionPixelSize(R.dimen.navigation_handle_sample_horizontal_margin);
-        mEdgeBackGestureHandler =
-                new EdgeBackGestureHandler(context, mOverviewProxyService, mSysUiFlagContainer);
+        mEdgeBackGestureHandler = new EdgeBackGestureHandler(
+                context, mOverviewProxyService, mSysUiFlagContainer, mPluginManager);
         mRegionSamplingHelper = new RegionSamplingHelper(this,
                 new RegionSamplingHelper.SamplingCallback() {
                     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 8ebf574..35407c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -986,7 +986,7 @@
             }
             ExpandableNotificationRow row = (ExpandableNotificationRow) child;
             boolean suppressedSummary = mGroupManager != null
-                    && mGroupManager.isSummaryOfSuppressedGroup(row.getStatusBarNotification());
+                    && mGroupManager.isSummaryOfSuppressedGroup(row.getEntry().getSbn());
             if (suppressedSummary) {
                 continue;
             }
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 adea8c6..06183b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -30,8 +30,6 @@
 import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_TOP_BAR;
 
 import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
-import static com.android.systemui.Dependency.BG_HANDLER;
-import static com.android.systemui.Dependency.MAIN_HANDLER;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
@@ -123,7 +121,6 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.RegisterStatusBarResult;
 import com.android.internal.view.AppearanceRegion;
-import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.ViewMediatorCallback;
@@ -148,7 +145,6 @@
 import com.android.systemui.charging.WirelessChargingAnimation;
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.doze.DozeHost;
 import com.android.systemui.fragments.ExtensionFragmentListener;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
@@ -198,7 +194,6 @@
 import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
 import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.NewNotifPipeline;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
 import com.android.systemui.statusbar.notification.NotificationAlertingManager;
 import com.android.systemui.statusbar.notification.NotificationClicker;
@@ -210,6 +205,7 @@
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationRowBinderImpl;
+import com.android.systemui.statusbar.notification.collection.init.NewNotifPipeline;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
@@ -222,7 +218,6 @@
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
 import com.android.systemui.statusbar.policy.ExtensionController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
 import com.android.systemui.statusbar.policy.NetworkController;
@@ -355,12 +350,12 @@
 
     private final Point mCurrentDisplaySize = new Point();
 
-    protected StatusBarWindowViewController mStatusBarWindowViewController;
     protected StatusBarWindowView mStatusBarWindow;
     protected PhoneStatusBarView mStatusBarView;
     private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
     protected StatusBarWindowController mStatusBarWindowController;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    private final LockscreenLockIconController mLockscreenLockIconController;
     @VisibleForTesting
     DozeServiceHost mDozeServiceHost;
     private boolean mWakeUpComingFromTouch;
@@ -382,12 +377,14 @@
     private final FalsingManager mFalsingManager;
     private final BroadcastDispatcher mBroadcastDispatcher;
     private final ConfigurationController mConfigurationController;
-    private final StatusBarWindowViewController.Builder mStatusBarWindowViewControllerBuilder;
+    private final StatusBarWindowViewController mStatusBarWindowViewController;
     private final DozeParameters mDozeParameters;
     private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
     private final PluginManager mPluginManager;
     private final RemoteInputUriController mRemoteInputUriController;
     private final Optional<Divider> mDividerOptional;
+    private final StatusBarNotificationActivityStarter.Builder
+            mStatusBarNotificationActivityStarterBuilder;
     private final SuperStatusBarViewFactory mSuperStatusBarViewFactory;
     private final LightsOutNotifController mLightsOutNotifController;
     private final DismissCallbackRegistry mDismissCallbackRegistry;
@@ -662,7 +659,8 @@
             NotificationListener notificationListener,
             ConfigurationController configurationController,
             StatusBarWindowController statusBarWindowController,
-            StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder,
+            StatusBarWindowViewController statusBarWindowViewController,
+            LockscreenLockIconController lockscreenLockIconController,
             DozeParameters dozeParameters,
             ScrimController scrimController,
             @Nullable KeyguardLiftController keyguardLiftController,
@@ -679,6 +677,8 @@
             RemoteInputUriController remoteInputUriController,
             Optional<Divider> dividerOptional,
             LightsOutNotifController lightsOutNotifController,
+            StatusBarNotificationActivityStarter.Builder
+                    statusBarNotificationActivityStarterBuilder,
             SuperStatusBarViewFactory superStatusBarViewFactory,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             ViewMediatorCallback viewMediatorCallback,
@@ -732,7 +732,8 @@
         mNotificationListener = notificationListener;
         mConfigurationController = configurationController;
         mStatusBarWindowController = statusBarWindowController;
-        mStatusBarWindowViewControllerBuilder = statusBarWindowViewControllerBuilder;
+        mStatusBarWindowViewController = statusBarWindowViewController;
+        mLockscreenLockIconController = lockscreenLockIconController;
         mDozeServiceHost = dozeServiceHost;
         mPowerManager = powerManager;
         mDozeParameters = dozeParameters;
@@ -748,7 +749,7 @@
         mPluginManager = pluginManager;
         mRemoteInputUriController = remoteInputUriController;
         mDividerOptional = dividerOptional;
-
+        mStatusBarNotificationActivityStarterBuilder = statusBarNotificationActivityStarterBuilder;
         mSuperStatusBarViewFactory = superStatusBarViewFactory;
         mLightsOutNotifController =  lightsOutNotifController;
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
@@ -795,7 +796,6 @@
                 R.bool.config_vibrateOnIconAnimation);
 
         DateTimeView.setReceiverHandler(Dependency.get(Dependency.TIME_TICK_HANDLER));
-        putComponent(StatusBar.class, this);
 
         // start old BaseStatusBar.start().
         mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
@@ -895,9 +895,8 @@
 
         mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
         mDozeServiceHost.initialize(this, mNotificationIconAreaController,
-                mStatusBarWindowViewController, mStatusBarWindow, mStatusBarKeyguardViewManager,
+                mStatusBarWindow, mStatusBarKeyguardViewManager,
                 mNotificationPanel, mAmbientIndicationContainer);
-        putComponent(DozeHost.class, mDozeServiceHost);
 
         Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(this);
 
@@ -969,7 +968,7 @@
 
         // TODO: Deal with the ugliness that comes from having some of the statusbar broken out
         // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
-        mNotificationPanel = mStatusBarWindow.findViewById(R.id.notification_panel);
+        mNotificationPanel = mSuperStatusBarViewFactory.getNotificationPanelView();
 
         mStackScroller = mStatusBarWindow.findViewById(R.id.notification_stack_scroller);
         NotificationListContainer notifListContainer = (NotificationListContainer) mStackScroller;
@@ -1053,7 +1052,6 @@
         mGroupManager.setHeadsUpManager(mHeadsUpManager);
         mGroupAlertTransferHelper.setHeadsUpManager(mHeadsUpManager);
         mNotificationLogger.setHeadsUpManager(mHeadsUpManager);
-        putComponent(HeadsUpManager.class, mHeadsUpManager);
 
         createNavigationBar(result);
 
@@ -1096,7 +1094,7 @@
         mScrimController.setScrimVisibleListener(scrimsVisible -> {
             mStatusBarWindowController.setScrimsVisibility(scrimsVisible);
             if (mStatusBarWindow != null) {
-                mStatusBarWindowViewController.onScrimVisibilityChanged(scrimsVisible);
+                mLockscreenLockIconController.onScrimVisibilityChanged(scrimsVisible);
             }
         });
         mScrimController.attachViews(scrimBehind, scrimInFront, scrimForBubble);
@@ -1114,7 +1112,7 @@
         }
 
         mNotificationPanel.setLaunchAffordanceListener(
-                mStatusBarWindowViewController::onShowingLaunchAffordanceChanged);
+                mLockscreenLockIconController::onShowingLaunchAffordanceChanged);
 
         // Set up the quick settings tile panel
         View container = mStatusBarWindow.findViewById(R.id.qs_frame);
@@ -1231,6 +1229,7 @@
                         mStatusBarStateController,
                         mNotificationLogger);
 
+        // TODO: inject this.
         mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanel,
                 mHeadsUpManager, mStatusBarWindow, mStackScroller, mDozeScrimController,
                 mScrimController, mActivityLaunchAnimator, mDynamicPrivacyController,
@@ -1245,20 +1244,12 @@
         mNotificationShelf.setOnActivatedListener(mPresenter);
         mRemoteInputManager.getController().addCallback(mStatusBarWindowController);
 
-        final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback =
-                (StatusBarRemoteInputCallback) Dependency.get(
-                        NotificationRemoteInputManager.Callback.class);
-        final ActivityStarter activityStarter = Dependency.get(ActivityStarter.class);
-
-        mNotificationActivityStarter = new StatusBarNotificationActivityStarter(mContext,
-                mCommandQueue, mAssistManagerLazy.get(), mNotificationPanel, mPresenter,
-                mEntryManager, mHeadsUpManager, activityStarter, mActivityLaunchAnimator,
-                mBarService, mStatusBarStateController, mKeyguardManager, mDreamManager,
-                mRemoteInputManager, mStatusBarRemoteInputCallback, mGroupManager,
-                mLockscreenUserManager, this, mKeyguardStateController,
-                mNotificationInterruptionStateProvider, mMetricsLogger,
-                new LockPatternUtils(mContext), Dependency.get(MAIN_HANDLER),
-                Dependency.get(BG_HANDLER), mActivityIntentHelper, mBubbleController);
+        mNotificationActivityStarter =
+                mStatusBarNotificationActivityStarterBuilder
+                        .setShadeController(this)
+                        .setActivityLaunchAnimator(mActivityLaunchAnimator)
+                        .setNotificationPresenter(mPresenter)
+                        .build();
 
         mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
 
@@ -1391,9 +1382,7 @@
 
     protected void inflateStatusBarWindow(Context context) {
         mStatusBarWindow = mSuperStatusBarViewFactory.getStatusBarWindowView();
-        mStatusBarWindowViewController = mStatusBarWindowViewControllerBuilder
-                .setShadeController(this)
-                .build();
+        mStatusBarWindowViewController.setupExpandedStatusBar();
     }
 
     protected void startKeyguard() {
@@ -3698,7 +3687,7 @@
         mBouncerShowing = bouncerShowing;
         mKeyguardBypassController.setBouncerShowing(bouncerShowing);
         mPulseExpansionHandler.setBouncerShowing(bouncerShowing);
-        mStatusBarWindowViewController.setBouncerShowingScrimmed(isBouncerShowingScrimmed());
+        mLockscreenLockIconController.setBouncerShowingScrimmed(isBouncerShowingScrimmed());
         if (mStatusBarView != null) mStatusBarView.setBouncerShowing(bouncerShowing);
         updateHideIconsForBouncer(true /* animate */);
         mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
@@ -3949,7 +3938,7 @@
     public void notifyBiometricAuthModeChanged() {
         mDozeServiceHost.updateDozing();
         updateScrimController();
-        mStatusBarWindowViewController.onBiometricAuthModeChanged(
+        mLockscreenLockIconController.onBiometricAuthModeChanged(
                 mBiometricUnlockController.isWakeAndUnlock(),
                 mBiometricUnlockController.isBiometricUnlock());
     }
@@ -4346,7 +4335,7 @@
      */
     public void onBouncerPreHideAnimation() {
         mNotificationPanel.onBouncerPreHideAnimation();
-        mStatusBarWindowViewController.onBouncerPreHideAnimation();
+        mLockscreenLockIconController.onBouncerPreHideAnimation();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
index 60e9385..5d69409 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
@@ -56,12 +56,12 @@
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.NewNotifPipeline;
 import com.android.systemui.statusbar.notification.NotificationAlertingManager;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.collection.init.NewNotifPipeline;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -143,7 +143,8 @@
             NotificationListener notificationListener,
             ConfigurationController configurationController,
             StatusBarWindowController statusBarWindowController,
-            StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder,
+            StatusBarWindowViewController statusBarWindowViewController,
+            LockscreenLockIconController lockscreenLockIconController,
             DozeParameters dozeParameters,
             ScrimController scrimController,
             @Nullable KeyguardLiftController keyguardLiftController,
@@ -160,6 +161,8 @@
             RemoteInputUriController remoteInputUriController,
             Optional<Divider> dividerOptional,
             LightsOutNotifController lightsOutNotifController,
+            StatusBarNotificationActivityStarter.Builder
+                    statusBarNotificationActivityStarterBuilder,
             SuperStatusBarViewFactory superStatusBarViewFactory,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             ViewMediatorCallback viewMediatorCallback,
@@ -214,7 +217,8 @@
                 notificationListener,
                 configurationController,
                 statusBarWindowController,
-                statusBarWindowViewControllerBuilder,
+                statusBarWindowViewController,
+                lockscreenLockIconController,
                 dozeParameters,
                 scrimController,
                 keyguardLiftController,
@@ -231,6 +235,7 @@
                 remoteInputUriController,
                 dividerOptional,
                 lightsOutNotifController,
+                statusBarNotificationActivityStarterBuilder,
                 superStatusBarViewFactory,
                 statusBarKeyguardViewManager,
                 viewMediatorCallback,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index b340813..863874e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -52,6 +52,8 @@
 import com.android.systemui.UiOffloadThread;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.bubbles.BubbleController;
+import com.android.systemui.dagger.qualifiers.BgHandler;
+import com.android.systemui.dagger.qualifiers.MainHandler;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.CommandQueue;
@@ -60,6 +62,7 @@
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.SuperStatusBarViewFactory;
 import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
@@ -71,6 +74,11 @@
 import com.android.systemui.statusbar.policy.HeadsUpUtil;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import dagger.Lazy;
+
 /**
  * Status bar implementation of {@link NotificationActivityStarter}.
  */
@@ -79,7 +87,7 @@
     private static final String TAG = "NotifActivityStarter";
     protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    private final AssistManager mAssistManager;
+    private final Lazy<AssistManager> mAssistManagerLazy;
     private final NotificationGroupManager mGroupManager;
     private final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback;
     private final NotificationRemoteInputManager mRemoteInputManager;
@@ -108,32 +116,20 @@
 
     private boolean mIsCollapsingToShowActivityOverLockscreen;
 
-    public StatusBarNotificationActivityStarter(Context context,
-            CommandQueue commandQueue,
-            AssistManager assistManager,
-            NotificationPanelView panel,
-            NotificationPresenter presenter,
-            NotificationEntryManager entryManager,
-            HeadsUpManagerPhone headsUpManager,
-            ActivityStarter activityStarter,
-            ActivityLaunchAnimator activityLaunchAnimator,
-            IStatusBarService statusBarService,
-            StatusBarStateController statusBarStateController,
-            KeyguardManager keyguardManager,
-            IDreamManager dreamManager,
-            NotificationRemoteInputManager remoteInputManager,
-            StatusBarRemoteInputCallback remoteInputCallback,
-            NotificationGroupManager groupManager,
+    private StatusBarNotificationActivityStarter(Context context, CommandQueue commandQueue,
+            Lazy<AssistManager> assistManagerLazy, NotificationPanelView panel,
+            NotificationPresenter presenter, NotificationEntryManager entryManager,
+            HeadsUpManagerPhone headsUpManager, ActivityStarter activityStarter,
+            ActivityLaunchAnimator activityLaunchAnimator, IStatusBarService statusBarService,
+            StatusBarStateController statusBarStateController, KeyguardManager keyguardManager,
+            IDreamManager dreamManager, NotificationRemoteInputManager remoteInputManager,
+            StatusBarRemoteInputCallback remoteInputCallback, NotificationGroupManager groupManager,
             NotificationLockscreenUserManager lockscreenUserManager,
-            ShadeController shadeController,
-            KeyguardStateController keyguardStateController,
+            ShadeController shadeController, KeyguardStateController keyguardStateController,
             NotificationInterruptionStateProvider notificationInterruptionStateProvider,
-            MetricsLogger metricsLogger,
-            LockPatternUtils lockPatternUtils,
-            Handler mainThreadHandler,
-            Handler backgroundHandler,
-            ActivityIntentHelper activityIntentHelper,
-            BubbleController bubbleController) {
+            MetricsLogger metricsLogger, LockPatternUtils lockPatternUtils,
+            Handler mainThreadHandler, Handler backgroundHandler,
+            ActivityIntentHelper activityIntentHelper, BubbleController bubbleController) {
         mContext = context;
         mNotificationPanel = panel;
         mPresenter = presenter;
@@ -152,7 +148,7 @@
         mStatusBarStateController = statusBarStateController;
         mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
         mMetricsLogger = metricsLogger;
-        mAssistManager = assistManager;
+        mAssistManagerLazy = assistManagerLazy;
         mGroupManager = groupManager;
         mLockPatternUtils = lockPatternUtils;
         mBackgroundHandler = backgroundHandler;
@@ -318,7 +314,7 @@
             startNotificationIntent(intent, fillInIntent, row, wasOccluded, isActivityIntent);
         }
         if (isActivityIntent || isBubble) {
-            mAssistManager.hideAssist();
+            mAssistManagerLazy.get().hideAssist();
         }
         if (shouldCollapse()) {
             collapseOnMainThread();
@@ -490,4 +486,128 @@
             }
         });
     }
+
+    /**
+     * Public builder for {@link StatusBarNotificationActivityStarter}.
+     */
+    @Singleton
+    public static class Builder {
+        private final Context mContext;
+        private final CommandQueue mCommandQueue;
+        private final Lazy<AssistManager> mAssistManagerLazy;
+        private final NotificationEntryManager mEntryManager;
+        private final HeadsUpManagerPhone mHeadsUpManager;
+        private final ActivityStarter mActivityStarter;
+        private final IStatusBarService mStatusBarService;
+        private final StatusBarStateController mStatusBarStateController;
+        private final KeyguardManager mKeyguardManager;
+        private final IDreamManager mDreamManager;
+        private final NotificationRemoteInputManager mRemoteInputManager;
+        private final StatusBarRemoteInputCallback mRemoteInputCallback;
+        private final NotificationGroupManager mGroupManager;
+        private final NotificationLockscreenUserManager mLockscreenUserManager;
+        private final KeyguardStateController mKeyguardStateController;
+        private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
+        private final MetricsLogger mMetricsLogger;
+        private final LockPatternUtils mLockPatternUtils;
+        private final Handler mMainThreadHandler;
+        private final Handler mBackgroundHandler;
+        private final ActivityIntentHelper mActivityIntentHelper;
+        private final BubbleController mBubbleController;
+        private final SuperStatusBarViewFactory mSuperStatusBarViewFactory;
+        private ShadeController mShadeController;
+        private NotificationPresenter mNotificationPresenter;
+        private ActivityLaunchAnimator mActivityLaunchAnimator;
+
+        @Inject
+        public Builder(Context context,
+                CommandQueue commandQueue,
+                Lazy<AssistManager> assistManagerLazy,
+                NotificationEntryManager entryManager,
+                HeadsUpManagerPhone headsUpManager,
+                ActivityStarter activityStarter,
+                IStatusBarService statusBarService,
+                StatusBarStateController statusBarStateController,
+                KeyguardManager keyguardManager,
+                IDreamManager dreamManager,
+                NotificationRemoteInputManager remoteInputManager,
+                StatusBarRemoteInputCallback remoteInputCallback,
+                NotificationGroupManager groupManager,
+                NotificationLockscreenUserManager lockscreenUserManager,
+                KeyguardStateController keyguardStateController,
+                NotificationInterruptionStateProvider notificationInterruptionStateProvider,
+                MetricsLogger metricsLogger,
+                LockPatternUtils lockPatternUtils,
+                @MainHandler Handler mainThreadHandler,
+                @BgHandler Handler backgroundHandler,
+                ActivityIntentHelper activityIntentHelper,
+                BubbleController bubbleController,
+                SuperStatusBarViewFactory superStatusBarViewFactory) {
+            mContext = context;
+            mCommandQueue = commandQueue;
+            mAssistManagerLazy = assistManagerLazy;
+            mEntryManager = entryManager;
+            mHeadsUpManager = headsUpManager;
+            mActivityStarter = activityStarter;
+            mStatusBarService = statusBarService;
+            mStatusBarStateController = statusBarStateController;
+            mKeyguardManager = keyguardManager;
+            mDreamManager = dreamManager;
+            mRemoteInputManager = remoteInputManager;
+            mRemoteInputCallback = remoteInputCallback;
+            mGroupManager = groupManager;
+            mLockscreenUserManager = lockscreenUserManager;
+            mKeyguardStateController = keyguardStateController;
+            mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
+            mMetricsLogger = metricsLogger;
+            mLockPatternUtils = lockPatternUtils;
+            mMainThreadHandler = mainThreadHandler;
+            mBackgroundHandler = backgroundHandler;
+            mActivityIntentHelper = activityIntentHelper;
+            mBubbleController = bubbleController;
+            mSuperStatusBarViewFactory = superStatusBarViewFactory;
+        }
+        public Builder setShadeController(ShadeController shadeController) {
+            mShadeController = shadeController;
+            return this;
+        }
+
+        public Builder setNotificationPresenter(NotificationPresenter notificationPresenter) {
+            mNotificationPresenter = notificationPresenter;
+            return this;
+        }
+
+        public Builder setActivityLaunchAnimator(ActivityLaunchAnimator activityLaunchAnimator) {
+            mActivityLaunchAnimator = activityLaunchAnimator;
+            return this;
+        }
+
+        public StatusBarNotificationActivityStarter build() {
+            return new StatusBarNotificationActivityStarter(mContext,
+                    mCommandQueue, mAssistManagerLazy,
+                    mSuperStatusBarViewFactory.getNotificationPanelView(),
+                    mNotificationPresenter,
+                    mEntryManager,
+                    mHeadsUpManager,
+                    mActivityStarter,
+                    mActivityLaunchAnimator,
+                    mStatusBarService,
+                    mStatusBarStateController,
+                    mKeyguardManager,
+                    mDreamManager,
+                    mRemoteInputManager,
+                    mRemoteInputCallback,
+                    mGroupManager,
+                    mLockscreenUserManager,
+                    mShadeController,
+                    mKeyguardStateController,
+                    mNotificationInterruptionStateProvider,
+                    mMetricsLogger,
+                    mLockPatternUtils,
+                    mMainThreadHandler,
+                    mBackgroundHandler,
+                    mActivityIntentHelper,
+                    mBubbleController);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
index b5a7847..3e6ba4d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
@@ -50,6 +50,8 @@
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
+import dagger.Lazy;
+
 /**
  */
 @Singleton
@@ -60,7 +62,7 @@
     private final SysuiStatusBarStateController mStatusBarStateController;
     private final NotificationLockscreenUserManager mLockscreenUserManager;
     private final ActivityStarter mActivityStarter;
-    private final ShadeController mShadeController;
+    private final Lazy<ShadeController> mShadeControllerLazy;
     private final Context mContext;
     private final ActivityIntentHelper mActivityIntentHelper;
     private final NotificationGroupManager mGroupManager;
@@ -79,7 +81,7 @@
             NotificationLockscreenUserManager notificationLockscreenUserManager,
             KeyguardStateController keyguardStateController,
             StatusBarStateController statusBarStateController,
-            ActivityStarter activityStarter, ShadeController shadeController,
+            ActivityStarter activityStarter, Lazy<ShadeController> shadeControllerLazy,
             CommandQueue commandQueue) {
         mContext = context;
         mContext.registerReceiverAsUser(mChallengeReceiver, UserHandle.ALL,
@@ -87,7 +89,7 @@
         mLockscreenUserManager = notificationLockscreenUserManager;
         mKeyguardStateController = keyguardStateController;
         mStatusBarStateController = (SysuiStatusBarStateController) statusBarStateController;
-        mShadeController = shadeController;
+        mShadeControllerLazy = shadeControllerLazy;
         mActivityStarter = activityStarter;
         mStatusBarStateController.addCallback(this);
         mKeyguardManager = context.getSystemService(KeyguardManager.class);
@@ -116,7 +118,7 @@
         if (!row.isPinned()) {
             mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
         }
-        mShadeController.showBouncer(true /* scrimmed */);
+        mShadeControllerLazy.get().showBouncer(true /* scrimmed */);
         mPendingRemoteInputView = clicked;
     }
 
@@ -162,8 +164,8 @@
                     });
                 }
             };
-            mShadeController.postOnShadeExpanded(clickPendingViewRunnable);
-            mShadeController.instantExpandNotificationsPanel();
+            mShadeControllerLazy.get().postOnShadeExpanded(clickPendingViewRunnable);
+            mShadeControllerLazy.get().instantExpandNotificationsPanel();
         }
     }
 
@@ -175,7 +177,7 @@
         } else {
             if (row.isChildInGroup() && !row.areChildrenExpanded()) {
                 // The group isn't expanded, let's make sure it's visible!
-                mGroupManager.toggleGroupExpansion(row.getStatusBarNotification());
+                mGroupManager.toggleGroupExpansion(row.getEntry().getSbn());
             }
             row.setUserExpanded(true);
             row.getPrivateLayout().setOnExpandedVisibleListener(clickedView::performClick);
@@ -251,7 +253,7 @@
                 boolean handled = defaultHandler.handleClick();
 
                 // close the shade if it was open and maybe wait for activity start.
-                return handled && mShadeController.closeShadeIfOpen();
+                return handled && mShadeControllerLazy.get().closeShadeIfOpen();
             }, null, afterKeyguardGone);
             return true;
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java
index c1328ec..feac5da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java
@@ -38,7 +38,6 @@
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DragDownHelper;
@@ -58,21 +57,40 @@
 import java.io.PrintWriter;
 
 import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import dagger.Lazy;
 
 /**
  * Controller for {@link StatusBarWindowView}.
  */
+@Singleton
 public class StatusBarWindowViewController {
-    private final StatusBarWindowView mView;
+    private final InjectionInflationController mInjectionInflationController;
+    private final NotificationWakeUpCoordinator mCoordinator;
+    private final PulseExpansionHandler mPulseExpansionHandler;
+    private final DynamicPrivacyController mDynamicPrivacyController;
+    private final KeyguardBypassController mBypassController;
+    private final PluginManager mPluginManager;
     private final FalsingManager mFalsingManager;
-    private final GestureDetector mGestureDetector;
+    private final TunerService mTunerService;
+    private final NotificationLockscreenUserManager mNotificationLockscreenUserManager;
+    private final NotificationEntryManager mNotificationEntryManager;
+    private final KeyguardStateController mKeyguardStateController;
+    private final SysuiStatusBarStateController mStatusBarStateController;
+    private final DozeLog mDozeLog;
+    private final DozeParameters mDozeParameters;
+    private final CommandQueue mCommandQueue;
+    private final StatusBarWindowView mView;
+    private final Lazy<ShadeController> mShadeControllerLazy;
+
+    private GestureDetector mGestureDetector;
     private View mBrightnessMirror;
     private boolean mTouchActive;
     private boolean mTouchCancelled;
     private boolean mExpandAnimationPending;
     private boolean mExpandAnimationRunning;
     private NotificationStackScrollLayout mStackScrollLayout;
-    private LockIcon mLockIcon;
     private PhoneStatusBarView mStatusBarView;
     private StatusBar mService;
     private DragDownHelper mDragDownHelper;
@@ -81,8 +99,8 @@
     private boolean mExpandingBelowNotch;
     private final DockManager mDockManager;
 
-    private StatusBarWindowViewController(
-            StatusBarWindowView view,
+    @Inject
+    public StatusBarWindowViewController(
             InjectionInflationController injectionInflationController,
             NotificationWakeUpCoordinator coordinator,
             PulseExpansionHandler pulseExpansionHandler,
@@ -91,7 +109,6 @@
             FalsingManager falsingManager,
             PluginManager pluginManager,
             TunerService tunerService,
-            ShadeController shadeController,
             NotificationLockscreenUserManager notificationLockscreenUserManager,
             NotificationEntryManager notificationEntryManager,
             KeyguardStateController keyguardStateController,
@@ -99,47 +116,68 @@
             DozeLog dozeLog,
             DozeParameters dozeParameters,
             CommandQueue commandQueue,
+            SuperStatusBarViewFactory superStatusBarViewFactory,
+            Lazy<ShadeController> shadeControllerLazy,
             DockManager dockManager) {
-        mView = view;
+        mInjectionInflationController = injectionInflationController;
+        mCoordinator = coordinator;
+        mPulseExpansionHandler = pulseExpansionHandler;
+        mDynamicPrivacyController = dynamicPrivacyController;
+        mBypassController = bypassController;
         mFalsingManager = falsingManager;
+        mPluginManager = pluginManager;
+        mTunerService = tunerService;
+        mNotificationLockscreenUserManager = notificationLockscreenUserManager;
+        mNotificationEntryManager = notificationEntryManager;
+        mKeyguardStateController = keyguardStateController;
+        mStatusBarStateController = statusBarStateController;
+        mDozeLog = dozeLog;
+        mDozeParameters = dozeParameters;
+        mCommandQueue = commandQueue;
+        mView = superStatusBarViewFactory.getStatusBarWindowView();
+        mShadeControllerLazy = shadeControllerLazy;
         mDockManager = dockManager;
 
+        // This view is not part of the newly inflated expanded status bar.
+        mBrightnessMirror = mView.findViewById(R.id.brightness_mirror);
+    }
+
+    /** Inflates the {@link R.layout#status_bar_expanded} layout and sets it up. */
+    public void setupExpandedStatusBar() {
         // TODO: create controller for NotificationPanelView
         NotificationPanelView notificationPanelView = new NotificationPanelView(
-                view.getContext(),
+                mView.getContext(),
                 null,
-                injectionInflationController,
-                coordinator,
-                pulseExpansionHandler,
-                dynamicPrivacyController,
-                bypassController,
-                falsingManager,
-                pluginManager,
-                shadeController,
-                notificationLockscreenUserManager,
-                notificationEntryManager,
-                keyguardStateController,
-                statusBarStateController,
-                dozeLog,
-                dozeParameters,
-                commandQueue);
+                mInjectionInflationController,
+                mCoordinator,
+                mPulseExpansionHandler,
+                mDynamicPrivacyController,
+                mBypassController,
+                mFalsingManager,
+                mPluginManager,
+                mShadeControllerLazy.get(),
+                mNotificationLockscreenUserManager,
+                mNotificationEntryManager,
+                mKeyguardStateController,
+                mStatusBarStateController,
+                mDozeLog,
+                mDozeParameters,
+                mCommandQueue);
         ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
         notificationPanelView.setVisibility(View.INVISIBLE);
         notificationPanelView.setId(R.id.notification_panel);
-        LayoutInflater li = injectionInflationController.injectable(
+        LayoutInflater li = mInjectionInflationController.injectable(
                 LayoutInflater.from(mView.getContext()));
 
         li.inflate(R.layout.status_bar_expanded, notificationPanelView);
         notificationPanelView.onChildrenAttached();
 
-        ViewStub statusBarExpanded = view.findViewById(R.id.status_bar_expanded);
+        ViewStub statusBarExpanded = mView.findViewById(R.id.status_bar_expanded);
         mView.addView(notificationPanelView, mView.indexOfChild(statusBarExpanded), lp);
         mView.removeView(statusBarExpanded);
 
         mStackScrollLayout = mView.findViewById(R.id.notification_stack_scroller);
-        mLockIcon = mView.findViewById(R.id.lock_icon);
-        mBrightnessMirror = mView.findViewById(R.id.brightness_mirror);
 
         TunerService.Tunable tunable = (key, newValue) -> {
             AmbientDisplayConfiguration configuration =
@@ -153,7 +191,7 @@
                     mSingleTapEnabled = configuration.tapGestureEnabled(UserHandle.USER_CURRENT);
             }
         };
-        tunerService.addTunable(tunable,
+        mTunerService.addTunable(tunable,
                 Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
                 Settings.Secure.DOZE_TAP_SCREEN_GESTURE);
 
@@ -188,6 +226,7 @@
                 boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP;
                 boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL;
 
+                boolean expandingBelowNotch = mExpandingBelowNotch;
                 if (isUp || isCancel) {
                     mExpandingBelowNotch = false;
                 }
@@ -224,7 +263,7 @@
                     }
                 }
                 if (isDown) {
-                    getStackScrollLayout().closeControlsIfOutsideTouch(ev);
+                    mStackScrollLayout.closeControlsIfOutsideTouch(ev);
                 }
                 if (mService.isDozing()) {
                     mService.mDozeScrimController.extendPulse();
@@ -236,8 +275,9 @@
                 // regular view bounds.
                 if (isDown && ev.getY() >= mView.getBottom()) {
                     mExpandingBelowNotch = true;
+                    expandingBelowNotch = true;
                 }
-                if (mExpandingBelowNotch) {
+                if (expandingBelowNotch) {
                     return mStatusBarView.dispatchTouchEvent(ev);
                 }
 
@@ -264,10 +304,9 @@
 
             @Override
             public void didIntercept(MotionEvent ev) {
-                NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
                 MotionEvent cancellation = MotionEvent.obtain(ev);
                 cancellation.setAction(MotionEvent.ACTION_CANCEL);
-                stackScrollLayout.onInterceptTouchEvent(cancellation);
+                mStackScrollLayout.onInterceptTouchEvent(cancellation);
                 notificationPanelView.onInterceptTouchEvent(cancellation);
                 cancellation.recycle();
             }
@@ -345,6 +384,13 @@
             public void onChildViewRemoved(View parent, View child) {
             }
         });
+
+        ExpandHelper.Callback expandHelperCallback = mStackScrollLayout.getExpandHelperCallback();
+        DragDownHelper.DragDownCallback dragDownCallback = mStackScrollLayout.getDragDownCallback();
+        setDragDownHelper(
+                new DragDownHelper(
+                        mView.getContext(), mView, expandHelperCallback,
+                        dragDownCallback, mFalsingManager));
     }
 
     public StatusBarWindowView getView() {
@@ -387,44 +433,8 @@
     }
 
     public void cancelExpandHelper() {
-        NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
-        if (stackScrollLayout != null) {
-            stackScrollLayout.cancelExpandHelper();
-        }
-    }
-
-    @VisibleForTesting
-    protected NotificationStackScrollLayout getStackScrollLayout() {
-        return mStackScrollLayout;
-    }
-
-    /**
-     * Called whenever the scrims become opaque, transparent or semi-transparent.
-     */
-    public void onScrimVisibilityChanged(Integer scrimsVisible) {
-        if (mLockIcon != null) {
-            mLockIcon.onScrimVisibilityChanged(scrimsVisible);
-        }
-    }
-
-    /**
-     * Propagate {@link StatusBar} pulsing state.
-     */
-    public void setPulsing(boolean pulsing) {
-        if (mLockIcon != null) {
-            mLockIcon.setPulsing(pulsing);
-        }
-    }
-
-    /**
-     * Called when the biometric authentication mode changes.
-     *
-     * @param wakeAndUnlock If the type is {@link BiometricUnlockController#isWakeAndUnlock()}
-     * @param isUnlock      If the type is {@link BiometricUnlockController#isBiometricUnlock()} ()
-     */
-    public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) {
-        if (mLockIcon != null) {
-            mLockIcon.onBiometricAuthModeChanged(wakeAndUnlock, isUnlock);
+        if (mStackScrollLayout != null) {
+            mStackScrollLayout.cancelExpandHelper();
         }
     }
 
@@ -434,138 +444,10 @@
 
     public void setService(StatusBar statusBar) {
         mService = statusBar;
-        NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
-        ExpandHelper.Callback expandHelperCallback = stackScrollLayout.getExpandHelperCallback();
-        DragDownHelper.DragDownCallback dragDownCallback = stackScrollLayout.getDragDownCallback();
-        setDragDownHelper(
-                new DragDownHelper(
-                        mView.getContext(), mView, expandHelperCallback,
-                        dragDownCallback, mFalsingManager));
     }
 
     @VisibleForTesting
     void setDragDownHelper(DragDownHelper dragDownHelper) {
         mDragDownHelper = dragDownHelper;
     }
-
-    /**
-     * When we're launching an affordance, like double pressing power to open camera.
-     */
-    public void onShowingLaunchAffordanceChanged(Boolean showing) {
-        if (mLockIcon != null) {
-            mLockIcon.onShowingLaunchAffordanceChanged(showing);
-        }
-    }
-
-    public void setBouncerShowingScrimmed(boolean bouncerShowing) {
-        if (mLockIcon != null) {
-            mLockIcon.setBouncerShowingScrimmed(bouncerShowing);
-        }
-    }
-
-    /**
-     * When {@link KeyguardBouncer} starts to be dismissed and starts to play its animation.
-     */
-    public void onBouncerPreHideAnimation() {
-        if (mLockIcon != null) {
-            mLockIcon.onBouncerPreHideAnimation();
-        }
-    }
-
-    /**
-     * Builder for {@link StatusBarWindowViewController}.
-     */
-    public static class Builder {
-        private final InjectionInflationController mInjectionInflationController;
-        private final NotificationWakeUpCoordinator mCoordinator;
-        private final PulseExpansionHandler mPulseExpansionHandler;
-        private final DynamicPrivacyController mDynamicPrivacyController;
-        private final KeyguardBypassController mBypassController;
-        private final FalsingManager mFalsingManager;
-        private final PluginManager mPluginManager;
-        private final TunerService mTunerService;
-        private final KeyguardStateController mKeyguardStateController;
-        private final SysuiStatusBarStateController mStatusBarStateController;
-        private ShadeController mShadeController;
-        private final NotificationLockscreenUserManager mNotificationLockScreenUserManager;
-        private final NotificationEntryManager mNotificationEntryManager;
-        private final DozeLog mDozeLog;
-        private final DozeParameters mDozeParameters;
-        private final CommandQueue mCommandQueue;
-        private final SuperStatusBarViewFactory mSuperStatusBarViewFactory;
-        private final StatusBarWindowView mView;
-        private final DockManager mDockManager;
-
-        @Inject
-        public Builder(
-                InjectionInflationController injectionInflationController,
-                NotificationWakeUpCoordinator coordinator,
-                PulseExpansionHandler pulseExpansionHandler,
-                DynamicPrivacyController dynamicPrivacyController,
-                KeyguardBypassController bypassController,
-                FalsingManager falsingManager,
-                PluginManager pluginManager,
-                TunerService tunerService,
-                NotificationLockscreenUserManager notificationLockscreenUserManager,
-                NotificationEntryManager notificationEntryManager,
-                KeyguardStateController keyguardStateController,
-                StatusBarStateController statusBarStateController,
-                DozeLog dozeLog,
-                DozeParameters dozeParameters,
-                CommandQueue commandQueue,
-                SuperStatusBarViewFactory superStatusBarViewFactory,
-                DockManager dockManager) {
-            mInjectionInflationController = injectionInflationController;
-            mCoordinator = coordinator;
-            mPulseExpansionHandler = pulseExpansionHandler;
-            mDynamicPrivacyController = dynamicPrivacyController;
-            mBypassController = bypassController;
-            mFalsingManager = falsingManager;
-            mPluginManager = pluginManager;
-            mTunerService = tunerService;
-            mNotificationLockScreenUserManager = notificationLockscreenUserManager;
-            mNotificationEntryManager = notificationEntryManager;
-            mKeyguardStateController = keyguardStateController;
-            mStatusBarStateController = (SysuiStatusBarStateController) statusBarStateController;
-            mDozeLog = dozeLog;
-            mDozeParameters = dozeParameters;
-            mCommandQueue = commandQueue;
-            mSuperStatusBarViewFactory = superStatusBarViewFactory;
-            mView = mSuperStatusBarViewFactory.getStatusBarWindowView();
-            mDockManager = dockManager;
-        }
-
-        /**
-         * Provide {@link ShadeController} that this view needs.
-         */
-        public Builder setShadeController(ShadeController shadeController) {
-            mShadeController = shadeController;
-            return this;
-        }
-
-        /**
-         * Build a {@link StatusBarWindowView}.
-         */
-        public StatusBarWindowViewController build() {
-            return new StatusBarWindowViewController(
-                    mView,
-                    mInjectionInflationController,
-                    mCoordinator,
-                    mPulseExpansionHandler,
-                    mDynamicPrivacyController,
-                    mBypassController,
-                    mFalsingManager,
-                    mPluginManager,
-                    mTunerService,
-                    mShadeController,
-                    mNotificationLockScreenUserManager,
-                    mNotificationEntryManager,
-                    mKeyguardStateController,
-                    mStatusBarStateController,
-                    mDozeLog,
-                    mDozeParameters,
-                    mCommandQueue,
-                    mDockManager);
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index f0f9420..dc80906 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -33,13 +33,13 @@
 import com.android.settingslib.fuelgauge.BatterySaverUtils;
 import com.android.settingslib.fuelgauge.Estimate;
 import com.android.settingslib.utils.PowerUtil;
-import com.android.systemui.Dependency;
 import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.qualifiers.BgHandler;
+import com.android.systemui.dagger.qualifiers.MainHandler;
 import com.android.systemui.power.EnhancedEstimates;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.text.NumberFormat;
 import java.util.ArrayList;
 
 import javax.inject.Inject;
@@ -53,42 +53,39 @@
 public class BatteryControllerImpl extends BroadcastReceiver implements BatteryController {
     private static final String TAG = "BatteryController";
 
-    public static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST";
+    private static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST";
 
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final int UPDATE_GRANULARITY_MSEC = 1000 * 60;
 
     private final EnhancedEstimates mEstimates;
     private final BroadcastDispatcher mBroadcastDispatcher;
-    private final ArrayList<BatteryController.BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
+    private final ArrayList<BatteryController.BatteryStateChangeCallback>
+            mChangeCallbacks = new ArrayList<>();
     private final ArrayList<EstimateFetchCompletion> mFetchCallbacks = new ArrayList<>();
     private final PowerManager mPowerManager;
-    private final Handler mHandler;
+    private final Handler mMainHandler;
+    private final Handler mBgHandler;
     private final Context mContext;
 
-    protected int mLevel;
-    protected boolean mPluggedIn;
-    protected boolean mCharging;
-    protected boolean mCharged;
-    protected boolean mPowerSave;
-    protected boolean mAodPowerSave;
+    private int mLevel;
+    private boolean mPluggedIn;
+    private boolean mCharging;
+    private boolean mCharged;
+    private boolean mPowerSave;
+    private boolean mAodPowerSave;
     private boolean mTestmode = false;
     private boolean mHasReceivedBattery = false;
     private Estimate mEstimate;
     private boolean mFetchingEstimate = false;
 
-    @Inject
-    public BatteryControllerImpl(Context context, EnhancedEstimates enhancedEstimates,
-            BroadcastDispatcher broadcastDispatcher) {
-        this(context, enhancedEstimates, context.getSystemService(PowerManager.class),
-                broadcastDispatcher);
-    }
-
     @VisibleForTesting
+    @Inject
     BatteryControllerImpl(Context context, EnhancedEstimates enhancedEstimates,
-            PowerManager powerManager, BroadcastDispatcher broadcastDispatcher) {
+            PowerManager powerManager, BroadcastDispatcher broadcastDispatcher,
+            @MainHandler Handler mainHandler, @BgHandler Handler bgHandler) {
         mContext = context;
-        mHandler = new Handler();
+        mMainHandler = mainHandler;
+        mBgHandler = bgHandler;
         mPowerManager = powerManager;
         mEstimates = enhancedEstimates;
         mBroadcastDispatcher = broadcastDispatcher;
@@ -162,7 +159,7 @@
             setPowerSave(intent.getBooleanExtra(PowerManager.EXTRA_POWER_SAVE_MODE, false));
         } else if (action.equals(ACTION_LEVEL_TEST)) {
             mTestmode = true;
-            mHandler.post(new Runnable() {
+            mMainHandler.post(new Runnable() {
                 int curLevel = 0;
                 int incr = 1;
                 int saveLevel = mLevel;
@@ -189,7 +186,7 @@
                     if (curLevel == 100) {
                         incr *= -1;
                     }
-                    mHandler.postDelayed(this, 200);
+                    mMainHandler.postDelayed(this, 200);
                 }
             });
         }
@@ -222,7 +219,6 @@
                 return null;
             }
 
-            String percentage = NumberFormat.getPercentInstance().format((double) mLevel / 100.0);
             return PowerUtil.getBatteryRemainingShortStringFormatted(
                     mContext, mEstimate.getEstimateMillis());
         }
@@ -235,7 +231,7 @@
         }
 
         mFetchingEstimate = true;
-        Dependency.get(Dependency.BG_HANDLER).post(() -> {
+        mBgHandler.post(() -> {
             // Only fetch the estimate if they are enabled
             synchronized (mFetchCallbacks) {
                 mEstimate = null;
@@ -244,7 +240,7 @@
                 }
             }
             mFetchingEstimate = false;
-            Dependency.get(Dependency.MAIN_HANDLER).post(this::notifyEstimateFetchCallbacks);
+            mMainHandler.post(this::notifyEstimateFetchCallbacks);
         });
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index 7587c8c..6331a2d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -111,8 +111,8 @@
             if (mWifiManager != null) {
                 if (mListening) {
                     if (mCallbacks.size() == 1) {
-                        mWifiManager.registerSoftApCallback(this,
-                                new HandlerExecutor(mMainHandler));
+                        mWifiManager.registerSoftApCallback(new HandlerExecutor(mMainHandler),
+                                this);
                     } else {
                         // mWifiManager#registerSoftApCallback triggers a call to
                         // onConnectedClientsChanged on the Main Handler. In order to always update
@@ -146,7 +146,7 @@
         if (mListening || !listening) return;
         mListening = true;
         if (mCallbacks.size() >= 1) {
-            mWifiManager.registerSoftApCallback(this, new HandlerExecutor(mMainHandler));
+            mWifiManager.registerSoftApCallback(new HandlerExecutor(mMainHandler), this);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index a441f66..5a43321 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -128,7 +128,7 @@
     }
 
     public void handleBootCompleted() {
-        mWifiManager.registerTrafficStateCallback(new WifiTrafficStateCallback(), null);
+        mWifiManager.registerTrafficStateCallback(new WifiTrafficStateCallback());
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index 379cf1f..39de0f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -50,8 +50,6 @@
 
     @Override
     public void start() {
-        putComponent(TvStatusBar.class, this);
-
         final IStatusBarService barService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
         mCommandQueue.addCallback(this);
diff --git a/packages/SystemUI/src/com/android/systemui/util/time/SystemClock.java b/packages/SystemUI/src/com/android/systemui/util/time/SystemClock.java
new file mode 100644
index 0000000..4316df1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/time/SystemClock.java
@@ -0,0 +1,46 @@
+/*
+ * 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.util.time;
+
+/**
+ * Testable wrapper around {@link android.os.SystemClock}.
+ *
+ * Dagger can inject this wrapper into your classes. The implementation just proxies calls to the
+ * real SystemClock.
+ *
+ * In tests, pass an instance of FakeSystemClock, which allows you to control the values returned by
+ * the various getters below.
+ */
+public interface SystemClock {
+    /** @see android.os.SystemClock#uptimeMillis() */
+    long uptimeMillis();
+
+    /** @see android.os.SystemClock#elapsedRealtime() */
+    long elapsedRealtime();
+
+    /** @see android.os.SystemClock#elapsedRealtimeNanos() */
+    long elapsedRealtimeNanos();
+
+    /** @see android.os.SystemClock#currentThreadTimeMillis() */
+    long currentThreadTimeMillis();
+
+    /** @see android.os.SystemClock#currentThreadTimeMicro() */
+    long currentThreadTimeMicro();
+
+    /** @see android.os.SystemClock#currentTimeMicro() */
+    long currentTimeMicro();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/time/SystemClockImpl.java b/packages/SystemUI/src/com/android/systemui/util/time/SystemClockImpl.java
new file mode 100644
index 0000000..532ea05
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/time/SystemClockImpl.java
@@ -0,0 +1,55 @@
+/*
+ * 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.util.time;
+
+import javax.inject.Inject;
+
+/** Default implementation of {@link SystemClock}. */
+public class SystemClockImpl implements SystemClock {
+    @Inject
+    public SystemClockImpl() {}
+
+    @Override
+    public long uptimeMillis() {
+        return android.os.SystemClock.uptimeMillis();
+    }
+
+    @Override
+    public long elapsedRealtime() {
+        return android.os.SystemClock.elapsedRealtime();
+    }
+
+    @Override
+    public long elapsedRealtimeNanos() {
+        return android.os.SystemClock.elapsedRealtimeNanos();
+    }
+
+    @Override
+    public long currentThreadTimeMillis() {
+        return android.os.SystemClock.currentThreadTimeMillis();
+    }
+
+    @Override
+    public long currentThreadTimeMicro() {
+        return android.os.SystemClock.currentThreadTimeMicro();
+    }
+
+    @Override
+    public long currentTimeMicro() {
+        return android.os.SystemClock.currentTimeMicro();
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index 1e9000b..ba264c0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -136,7 +136,6 @@
                 mTestableLooper.processAllMessages();
             }
         };
-        mScreenDecorations.mComponents = mContext.getComponents();
         reset(mTunerService);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
index f792d7d..d847208 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
@@ -17,13 +17,9 @@
 import android.content.Context;
 import android.testing.LeakCheck;
 import android.testing.TestableContext;
-import android.util.ArrayMap;
 import android.view.Display;
 
-public class SysuiTestableContext extends TestableContext implements SysUiServiceProvider {
-
-    private ArrayMap<Class<?>, Object> mComponents;
-
+public class SysuiTestableContext extends TestableContext {
     public SysuiTestableContext(Context base) {
         super(base);
         setTheme(R.style.Theme_SystemUI);
@@ -34,21 +30,6 @@
         setTheme(R.style.Theme_SystemUI);
     }
 
-    public ArrayMap<Class<?>, Object> getComponents() {
-        if (mComponents == null) mComponents = new ArrayMap<>();
-        return mComponents;
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> T getComponent(Class<T> interfaceType) {
-        return (T) (mComponents != null ? mComponents.get(interfaceType) : null);
-    }
-
-    public <T, C extends T> void putComponent(Class<T> interfaceType, C component) {
-        if (mComponents == null) mComponents = new ArrayMap<>();
-        mComponents.put(interfaceType, component);
-    }
-
     @Override
     public Context createDisplayContext(Display display) {
         if (display == null) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 486fa12..f6375fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -53,7 +53,6 @@
 import com.android.internal.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.StatusBar;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -88,8 +87,6 @@
 
         TestableContext context = spy(mContext);
 
-        mContext.putComponent(StatusBar.class, mock(StatusBar.class));
-
         when(context.getPackageManager()).thenReturn(mPackageManager);
         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE))
                 .thenReturn(true);
@@ -104,7 +101,6 @@
 
         mAuthController = new TestableAuthController(
                 context, mock(CommandQueue.class), new MockInjector());
-        mAuthController.mComponents = mContext.getComponents();
 
         mAuthController.start();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
index 47b35fd..e8f19238 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
@@ -687,7 +687,6 @@
 
     private void createPowerUi() {
         mPowerUI = new PowerUI(mContext, mBroadcastDispatcher, mStatusBarLazy);
-        mPowerUI.mComponents = mContext.getComponents();
         mPowerUI.mThermalService = mThermalServiceMock;
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryBuilder.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryBuilder.java
index fcfdd11..d18b16b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryBuilder.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryBuilder.java
@@ -20,6 +20,7 @@
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager.Importance;
+import android.content.Context;
 import android.os.UserHandle;
 import android.service.notification.SnoozeCriterion;
 import android.service.notification.StatusBarNotification;
@@ -92,6 +93,10 @@
         return this;
     }
 
+    public Notification.Builder modifyNotification(Context context) {
+        return mSbnBuilder.modifyNotification(context);
+    }
+
     public NotificationEntryBuilder setUser(UserHandle user) {
         mSbnBuilder.setUser(user);
         return this;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index 99c94ac..46a8dad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -117,7 +117,7 @@
     private NotificationEntry createEntry() throws Exception {
         ExpandableNotificationRow row = mHelper.createRow();
         NotificationEntry entry = new NotificationEntryBuilder()
-                .setSbn(row.getStatusBarNotification())
+                .setSbn(row.getEntry().getSbn())
                 .build();
         entry.setRow(row);
         return entry;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SbnBuilder.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SbnBuilder.java
index fe117fe..94b3ac4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SbnBuilder.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SbnBuilder.java
@@ -16,7 +16,9 @@
 
 package com.android.systemui.statusbar;
 
+import android.annotation.Nullable;
 import android.app.Notification;
+import android.content.Context;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 
@@ -32,7 +34,8 @@
     private String mTag;
     private int mUid;
     private int mInitialPid;
-    private Notification mNotification = new Notification();
+    @Nullable private Notification mNotification;
+    @Nullable private Notification.Builder mNotificationBuilder;
     private Notification.BubbleMetadata mBubbleMetadata;
     private UserHandle mUser = UserHandle.of(0);
     private String mOverrideGroupKey;
@@ -55,9 +58,19 @@
     }
 
     public StatusBarNotification build() {
-        if (mBubbleMetadata != null) {
-            mNotification.setBubbleMetadata(mBubbleMetadata);
+        Notification notification;
+        if (mNotificationBuilder != null) {
+            notification = mNotificationBuilder.build();
+        } else if (mNotification != null) {
+            notification = mNotification;
+        } else {
+            notification = new Notification();
         }
+
+        if (mBubbleMetadata != null) {
+            notification.setBubbleMetadata(mBubbleMetadata);
+        }
+
         return new StatusBarNotification(
                 mPkg,
                 mOpPkg,
@@ -65,7 +78,7 @@
                 mTag,
                 mUid,
                 mInitialPid,
-                mNotification,
+                notification,
                 mUser,
                 mOverrideGroupKey,
                 mPostTime);
@@ -106,6 +119,17 @@
         return this;
     }
 
+    public Notification.Builder modifyNotification(Context context) {
+        if (mNotification != null) {
+            mNotificationBuilder = new Notification.Builder(context, mNotification);
+            mNotification = null;
+        } else if (mNotificationBuilder == null) {
+            mNotificationBuilder = new Notification.Builder(context);
+        }
+
+        return mNotificationBuilder;
+    }
+
     public SbnBuilder setUser(UserHandle user) {
         mUser = user;
         return this;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImplTest.java
new file mode 100644
index 0000000..a25af84
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImplTest.java
@@ -0,0 +1,1197 @@
+/*
+ * 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.notification.collection;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.systemui.statusbar.notification.collection.ListDumper.dumpList;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.util.ArrayMap;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.collection.NotifListBuilderImpl.OnRenderListListener;
+import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener;
+import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener;
+import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeTransformGroupsListener;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.SectionsProvider;
+import com.android.systemui.util.Assert;
+import com.android.systemui.util.time.FakeSystemClock;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class NotifListBuilderImplTest extends SysuiTestCase {
+
+    private NotifListBuilderImpl mListBuilder;
+    private FakeSystemClock mSystemClock = new FakeSystemClock();
+
+    @Mock private NotifCollection mNotifCollection;
+    @Spy private OnBeforeTransformGroupsListener mOnBeforeTransformGroupsListener;
+    @Spy private OnBeforeSortListener mOnBeforeSortListener;
+    @Spy private OnBeforeRenderListListener mOnBeforeRenderListListener;
+    @Spy private OnRenderListListener mOnRenderListListener = list -> mBuiltList = list;
+
+    @Captor private ArgumentCaptor<CollectionReadyForBuildListener> mBuildListenerCaptor;
+
+    private CollectionReadyForBuildListener mReadyForBuildListener;
+    private List<NotificationEntryBuilder> mPendingSet = new ArrayList<>();
+    private List<NotificationEntry> mEntrySet = new ArrayList<>();
+    private List<ListEntry> mBuiltList;
+
+    private Map<String, Integer> mNextIdMap = new ArrayMap<>();
+    private int mNextRank = 0;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        Assert.sMainLooper = TestableLooper.get(this).getLooper();
+
+        mListBuilder = new NotifListBuilderImpl(mSystemClock);
+        mListBuilder.setOnRenderListListener(mOnRenderListListener);
+
+        mListBuilder.attach(mNotifCollection);
+
+        Mockito.verify(mNotifCollection).setBuildListener(mBuildListenerCaptor.capture());
+        mReadyForBuildListener = checkNotNull(mBuildListenerCaptor.getValue());
+    }
+
+    @Test
+    public void testNotifsAreSortedByRankAndWhen() {
+        // GIVEN a simple pipeline
+
+        // WHEN a series of notifs with jumbled ranks are added
+        addNotif(0, PACKAGE_1).setRank(2);
+        addNotif(1, PACKAGE_2).setRank(4).modifyNotification(mContext).setWhen(22);
+        addNotif(2, PACKAGE_3).setRank(4).modifyNotification(mContext).setWhen(33);
+        addNotif(3, PACKAGE_3).setRank(3);
+        addNotif(4, PACKAGE_5).setRank(4).modifyNotification(mContext).setWhen(11);
+        addNotif(5, PACKAGE_3).setRank(1);
+        addNotif(6, PACKAGE_1).setRank(0);
+        dispatchBuild();
+
+        // The final output is sorted based first by rank and then by when
+        verifyBuiltList(
+                notif(6),
+                notif(5),
+                notif(0),
+                notif(3),
+                notif(2),
+                notif(1),
+                notif(4)
+        );
+    }
+
+    @Test
+    public void testNotifsAreGrouped() {
+        // GIVEN a simple pipeline
+
+        // WHEN a group is added
+        addGroupChild(0, PACKAGE_1, GROUP_1);
+        addGroupChild(1, PACKAGE_1, GROUP_1);
+        addGroupChild(2, PACKAGE_1, GROUP_1);
+        addGroupSummary(3, PACKAGE_1, GROUP_1);
+        dispatchBuild();
+
+        // THEN the notifs are grouped together
+        verifyBuiltList(
+                group(
+                        summary(3),
+                        child(0),
+                        child(1),
+                        child(2)
+                )
+        );
+    }
+
+    @Test
+    public void testNotifsWithDifferentGroupKeysAreGrouped() {
+        // GIVEN a simple pipeline
+
+        // WHEN a package posts two different groups
+        addGroupChild(0, PACKAGE_1, GROUP_1);
+        addGroupChild(1, PACKAGE_1, GROUP_2);
+        addGroupSummary(2, PACKAGE_1, GROUP_2);
+        addGroupChild(3, PACKAGE_1, GROUP_2);
+        addGroupChild(4, PACKAGE_1, GROUP_1);
+        addGroupChild(5, PACKAGE_1, GROUP_2);
+        addGroupChild(6, PACKAGE_1, GROUP_1);
+        addGroupSummary(7, PACKAGE_1, GROUP_1);
+        dispatchBuild();
+
+        // THEN the groups are separated separately
+        verifyBuiltList(
+                group(
+                        summary(2),
+                        child(1),
+                        child(3),
+                        child(5)
+                ),
+                group(
+                        summary(7),
+                        child(0),
+                        child(4),
+                        child(6)
+                )
+        );
+    }
+
+    @Test
+    public void testNotifsNotifChildrenAreSorted() {
+        // GIVEN a simple pipeline
+
+        // WHEN a group is added
+        addGroupChild(0, PACKAGE_1, GROUP_1).setRank(4);
+        addGroupChild(1, PACKAGE_1, GROUP_1).setRank(2)
+                .modifyNotification(mContext).setWhen(11);
+        addGroupChild(2, PACKAGE_1, GROUP_1).setRank(1);
+        addGroupChild(3, PACKAGE_1, GROUP_1).setRank(2)
+                .modifyNotification(mContext).setWhen(33);
+        addGroupChild(4, PACKAGE_1, GROUP_1).setRank(2)
+                .modifyNotification(mContext).setWhen(22);
+        addGroupChild(5, PACKAGE_1, GROUP_1).setRank(0);
+        addGroupSummary(6, PACKAGE_1, GROUP_1).setRank(3);
+        dispatchBuild();
+
+        // THEN the children are sorted by rank and when
+        verifyBuiltList(
+                group(
+                        summary(6),
+                        child(5),
+                        child(2),
+                        child(3),
+                        child(4),
+                        child(1),
+                        child(0)
+                )
+        );
+    }
+
+    @Test
+    public void testDuplicateGroupSummariesAreDiscarded() {
+        // GIVEN a simple pipeline
+
+        // WHEN a group with multiple summaries is added
+        addNotif(0, PACKAGE_3);
+        addGroupChild(1, PACKAGE_1, GROUP_1);
+        addGroupChild(2, PACKAGE_1, GROUP_1);
+        addGroupSummary(3, PACKAGE_1, GROUP_1).setPostTime(22);
+        addGroupSummary(4, PACKAGE_1, GROUP_1).setPostTime(33);
+        addNotif(5, PACKAGE_2);
+        addGroupSummary(6, PACKAGE_1, GROUP_1).setPostTime(11);
+        addGroupChild(7, PACKAGE_1, GROUP_1);
+        dispatchBuild();
+
+        // THEN only most recent summary is used
+        verifyBuiltList(
+                notif(0),
+                group(
+                        summary(4),
+                        child(1),
+                        child(2),
+                        child(7)
+                ),
+                notif(5)
+        );
+
+        // THEN the extra summaries have their parents set to null
+        assertNull(mEntrySet.get(3).getParent());
+        assertNull(mEntrySet.get(6).getParent());
+    }
+
+    @Test
+    public void testGroupsWithNoSummaryAreUngrouped() {
+        // GIVEN a group with no summary
+        addNotif(0, PACKAGE_2);
+        addGroupChild(1, PACKAGE_4, GROUP_2);
+        addGroupChild(2, PACKAGE_4, GROUP_2);
+        addGroupChild(3, PACKAGE_4, GROUP_2);
+        addGroupChild(4, PACKAGE_4, GROUP_2);
+
+        // WHEN we build the list
+        dispatchBuild();
+
+        // THEN the children aren't grouped
+        verifyBuiltList(
+                notif(0),
+                notif(1),
+                notif(2),
+                notif(3),
+                notif(4)
+        );
+    }
+
+    @Test
+    public void testGroupsWithNoChildrenAreUngrouped() {
+        // GIVEN a group with a summary but no children
+        addGroupSummary(0, PACKAGE_5, GROUP_1);
+        addNotif(1, PACKAGE_5);
+        addNotif(2, PACKAGE_1);
+
+        // WHEN we build the list
+        dispatchBuild();
+
+        // THEN the summary isn't grouped but is still added to the final list
+        verifyBuiltList(
+                notif(0),
+                notif(1),
+                notif(2)
+        );
+    }
+
+    @Test
+    public void testGroupsWithTooFewChildrenAreSplitUp() {
+        // GIVEN a group with one child
+        addGroupChild(0, PACKAGE_2, GROUP_1);
+        addGroupSummary(1, PACKAGE_2, GROUP_1);
+
+        // WHEN we build the list
+        dispatchBuild();
+
+        // THEN the child is added at top level and the summary is discarded
+        verifyBuiltList(
+                notif(0)
+        );
+
+        assertNull(mEntrySet.get(1).getParent());
+    }
+
+    @Test
+    public void testGroupsWhoLoseChildrenMidPipelineAreSplitUp() {
+        // GIVEN a group with two children
+        addGroupChild(0, PACKAGE_2, GROUP_1);
+        addGroupSummary(1, PACKAGE_2, GROUP_1);
+        addGroupChild(2, PACKAGE_2, GROUP_1);
+
+        // GIVEN a promoter that will promote one of children to top level
+        mListBuilder.addPromoter(new IdPromoter(0));
+
+        // WHEN we build the list
+        dispatchBuild();
+
+        // THEN both children end up at top level (because group is now too small)
+        verifyBuiltList(
+                notif(0),
+                notif(2)
+        );
+
+        // THEN the summary is discarded
+        assertNull(mEntrySet.get(1).getParent());
+    }
+
+    @Test
+    public void testPreviousParentsAreSetProperly() {
+        // GIVEN a notification that is initially added to the list
+        PackageFilter filter = new PackageFilter(PACKAGE_2);
+        filter.setEnabled(false);
+        mListBuilder.addFilter(filter);
+
+        addNotif(0, PACKAGE_1);
+        addNotif(1, PACKAGE_2);
+        addNotif(2, PACKAGE_3);
+        dispatchBuild();
+
+        // WHEN it is suddenly filtered out
+        filter.setEnabled(true);
+        dispatchBuild();
+
+        // THEN its previous parent indicates that it used to be added
+        assertNull(mEntrySet.get(1).getParent());
+        assertEquals(GroupEntry.ROOT_ENTRY, mEntrySet.get(1).getPreviousParent());
+    }
+
+    @Test
+    public void testThatAnnulledGroupsAndSummariesAreProperlyRolledBack() {
+        // GIVEN a registered transform groups listener
+        RecordingOnBeforeTransformGroupsListener listener =
+                new RecordingOnBeforeTransformGroupsListener();
+        mListBuilder.addOnBeforeTransformGroupsListener(listener);
+
+        // GIVEN a malformed group that will be dismantled
+        addGroupChild(0, PACKAGE_2, GROUP_1);
+        addGroupSummary(1, PACKAGE_2, GROUP_1);
+        addNotif(2, PACKAGE_1);
+
+        // WHEN we build the list
+        dispatchBuild();
+
+        // THEN only the child appears in the final list
+        verifyBuiltList(
+                notif(0),
+                notif(2)
+        );
+
+        // THEN the list of newly visible entries doesn't contain the summary or the group
+        assertEquals(
+                Arrays.asList(
+                        mEntrySet.get(0),
+                        mEntrySet.get(2)),
+                listener.newlyVisibleEntries
+        );
+
+        // THEN the summary has a null parent and an unset firstAddedIteration
+        assertNull(mEntrySet.get(1).getParent());
+        assertEquals(-1, mEntrySet.get(1).mFirstAddedIteration);
+    }
+
+    @Test
+    public void testNotifsAreFiltered() {
+        // GIVEN a NotifFilter that filters out a specific package
+        NotifFilter filter1 = spy(new PackageFilter(PACKAGE_2));
+        mListBuilder.addFilter(filter1);
+
+        // WHEN the pipeline is kicked off on a list of notifs
+        addNotif(0, PACKAGE_1);
+        addNotif(1, PACKAGE_2);
+        addNotif(2, PACKAGE_3);
+        addNotif(3, PACKAGE_2);
+        dispatchBuild();
+
+        // THEN the filter is called on each notif in the original set
+        verify(filter1).shouldFilterOut(eq(mEntrySet.get(0)), anyLong());
+        verify(filter1).shouldFilterOut(eq(mEntrySet.get(1)), anyLong());
+        verify(filter1).shouldFilterOut(eq(mEntrySet.get(2)), anyLong());
+        verify(filter1).shouldFilterOut(eq(mEntrySet.get(3)), anyLong());
+
+        // THEN the final list doesn't contain any filtered-out notifs
+        verifyBuiltList(
+                notif(0),
+                notif(2)
+        );
+
+        // THEN each filtered notif records the filter that did it
+        assertEquals(filter1, mEntrySet.get(1).mExcludingFilter);
+        assertEquals(filter1, mEntrySet.get(3).mExcludingFilter);
+    }
+
+    @Test
+    public void testNotifFiltersCanBePreempted() {
+        // GIVEN two notif filters
+        NotifFilter filter1 = spy(new PackageFilter(PACKAGE_2));
+        NotifFilter filter2 = spy(new PackageFilter(PACKAGE_5));
+        mListBuilder.addFilter(filter1);
+        mListBuilder.addFilter(filter2);
+
+        // WHEN the pipeline is kicked off on a list of notifs
+        addNotif(0, PACKAGE_1);
+        addNotif(1, PACKAGE_2);
+        addNotif(2, PACKAGE_5);
+        dispatchBuild();
+
+        // THEN both filters are called on the first notif but the second filter is never called
+        // on the already-filtered second notif
+        verify(filter1).shouldFilterOut(eq(mEntrySet.get(0)), anyLong());
+        verify(filter1).shouldFilterOut(eq(mEntrySet.get(1)), anyLong());
+        verify(filter1).shouldFilterOut(eq(mEntrySet.get(2)), anyLong());
+        verify(filter2).shouldFilterOut(eq(mEntrySet.get(0)), anyLong());
+        verify(filter2).shouldFilterOut(eq(mEntrySet.get(2)), anyLong());
+
+        // THEN the final list doesn't contain any filtered-out notifs
+        verifyBuiltList(
+                notif(0)
+        );
+
+        // THEN each filtered notif records the filter that did it
+        assertEquals(filter1, mEntrySet.get(1).mExcludingFilter);
+        assertEquals(filter2, mEntrySet.get(2).mExcludingFilter);
+    }
+
+    @Test
+    public void testNotifsArePromoted() {
+        // GIVEN a NotifPromoter that promotes certain notif IDs
+        NotifPromoter promoter = spy(new IdPromoter(1, 2));
+        mListBuilder.addPromoter(promoter);
+
+        // WHEN the pipeline is kicked off
+        addNotif(0, PACKAGE_1);
+        addGroupChild(1, PACKAGE_2, GROUP_1);
+        addGroupChild(2, PACKAGE_2, GROUP_1);
+        addGroupChild(3, PACKAGE_2, GROUP_1);
+        addGroupChild(4, PACKAGE_2, GROUP_1);
+        addGroupSummary(5, PACKAGE_2, GROUP_1);
+        addNotif(6, PACKAGE_3);
+        dispatchBuild();
+
+        // THEN the filter is called on each group child
+        verify(promoter).shouldPromoteToTopLevel(mEntrySet.get(1));
+        verify(promoter).shouldPromoteToTopLevel(mEntrySet.get(2));
+        verify(promoter).shouldPromoteToTopLevel(mEntrySet.get(3));
+        verify(promoter).shouldPromoteToTopLevel(mEntrySet.get(4));
+
+        // THEN the final list contains the promoted entries at top level
+        verifyBuiltList(
+                notif(0),
+                notif(2),
+                notif(3),
+                group(
+                        summary(5),
+                        child(1),
+                        child(4)),
+                notif(6)
+        );
+
+        // THEN each promoted notif records the promoter that did it
+        assertEquals(promoter, mEntrySet.get(2).mNotifPromoter);
+        assertEquals(promoter, mEntrySet.get(3).mNotifPromoter);
+    }
+
+    @Test
+    public void testNotifPromotersCanBePreempted() {
+        // GIVEN two notif promoters
+        NotifPromoter promoter1 = spy(new IdPromoter(1));
+        NotifPromoter promoter2 = spy(new IdPromoter(2));
+        mListBuilder.addPromoter(promoter1);
+        mListBuilder.addPromoter(promoter2);
+
+        // WHEN the pipeline is kicked off on some notifs and a group
+        addNotif(0, PACKAGE_1);
+        addGroupChild(1, PACKAGE_2, GROUP_1);
+        addGroupChild(2, PACKAGE_2, GROUP_1);
+        addGroupChild(3, PACKAGE_2, GROUP_1);
+        addGroupSummary(4, PACKAGE_2, GROUP_1);
+        addNotif(5, PACKAGE_3);
+        dispatchBuild();
+
+        // THEN both promoters are called on each child, except for children that a previous
+        // promoter has already promoted
+        verify(promoter1).shouldPromoteToTopLevel(mEntrySet.get(1));
+        verify(promoter1).shouldPromoteToTopLevel(mEntrySet.get(2));
+        verify(promoter1).shouldPromoteToTopLevel(mEntrySet.get(3));
+
+        verify(promoter2).shouldPromoteToTopLevel(mEntrySet.get(1));
+        verify(promoter2).shouldPromoteToTopLevel(mEntrySet.get(3));
+
+        // THEN each promoter is recorded on each notif it promoted
+        assertEquals(promoter1, mEntrySet.get(2).mNotifPromoter);
+        assertEquals(promoter2, mEntrySet.get(3).mNotifPromoter);
+    }
+
+    @Test
+    public void testNotifsAreSectioned() {
+        // GIVEN a filter that removes all PACKAGE_4 notifs and a SectionsProvider that divides
+        // notifs based on package name
+        mListBuilder.addFilter(new PackageFilter(PACKAGE_4));
+        final SectionsProvider sectionsProvider = spy(new PackageSectioner());
+        mListBuilder.setSectionsProvider(sectionsProvider);
+
+        // WHEN we build a list with different packages
+        addNotif(0, PACKAGE_4);
+        addNotif(1, PACKAGE_2);
+        addNotif(2, PACKAGE_1);
+        addNotif(3, PACKAGE_3);
+        addGroupSummary(4, PACKAGE_2, GROUP_1);
+        addGroupChild(5, PACKAGE_2, GROUP_1);
+        addGroupChild(6, PACKAGE_2, GROUP_1);
+        addNotif(7, PACKAGE_1);
+        addNotif(8, PACKAGE_2);
+        addNotif(9, PACKAGE_5);
+        addNotif(10, PACKAGE_4);
+        dispatchBuild();
+
+        // THEN the list is sorted according to section
+        verifyBuiltList(
+                notif(2),
+                notif(7),
+                notif(1),
+                group(
+                        summary(4),
+                        child(5),
+                        child(6)
+                ),
+                notif(8),
+                notif(3),
+                notif(9)
+        );
+
+        // THEN the sections provider is called on all top level elements (but no children and no
+        // entries that were filtered out)
+        verify(sectionsProvider).getSection(mEntrySet.get(1));
+        verify(sectionsProvider).getSection(mEntrySet.get(2));
+        verify(sectionsProvider).getSection(mEntrySet.get(3));
+        verify(sectionsProvider).getSection(mEntrySet.get(7));
+        verify(sectionsProvider).getSection(mEntrySet.get(8));
+        verify(sectionsProvider).getSection(mEntrySet.get(9));
+        verify(sectionsProvider).getSection(mBuiltList.get(3));
+    }
+
+    @Test
+    public void testThatNotifComparatorsAreCalled() {
+        // GIVEN a set of comparators that care about specific packages
+        mListBuilder.setComparators(Arrays.asList(
+                new HypeComparator(PACKAGE_4),
+                new HypeComparator(PACKAGE_1, PACKAGE_3),
+                new HypeComparator(PACKAGE_2)
+        ));
+
+        // WHEN the pipeline is kicked off on a bunch of notifications
+        addNotif(0, PACKAGE_1);
+        addNotif(1, PACKAGE_5);
+        addNotif(2, PACKAGE_3);
+        addNotif(3, PACKAGE_4);
+        addNotif(4, PACKAGE_2);
+        dispatchBuild();
+
+        // THEN the notifs are sorted according to the hierarchy of comparators
+        verifyBuiltList(
+                notif(3),
+                notif(0),
+                notif(2),
+                notif(4),
+                notif(1)
+        );
+    }
+
+    @Test
+    public void testListenersAndPluggablesAreFiredInOrder() {
+        // GIVEN a bunch of registered listeners and pluggables
+        NotifFilter filter = spy(new PackageFilter(PACKAGE_1));
+        NotifPromoter promoter = spy(new IdPromoter(3));
+        PackageSectioner sectioner = spy(new PackageSectioner());
+        NotifComparator comparator = spy(new HypeComparator(PACKAGE_4));
+        mListBuilder.addFilter(filter);
+        mListBuilder.addOnBeforeTransformGroupsListener(mOnBeforeTransformGroupsListener);
+        mListBuilder.addPromoter(promoter);
+        mListBuilder.addOnBeforeSortListener(mOnBeforeSortListener);
+        mListBuilder.setComparators(Collections.singletonList(comparator));
+        mListBuilder.setSectionsProvider(sectioner);
+        mListBuilder.addOnBeforeRenderListListener(mOnBeforeRenderListListener);
+
+        // WHEN a few new notifs are added
+        addNotif(0, PACKAGE_1);
+        addGroupSummary(1, PACKAGE_2, GROUP_1);
+        addGroupChild(2, PACKAGE_2, GROUP_1);
+        addGroupChild(3, PACKAGE_2, GROUP_1);
+        addNotif(4, PACKAGE_5);
+        addNotif(5, PACKAGE_5);
+        addNotif(6, PACKAGE_4);
+        dispatchBuild();
+
+        // THEN the pluggables and listeners are called in order
+        InOrder inOrder = inOrder(
+                filter,
+                mOnBeforeTransformGroupsListener,
+                promoter,
+                mOnBeforeSortListener,
+                sectioner,
+                comparator,
+                mOnBeforeRenderListListener,
+                mOnRenderListListener);
+
+        inOrder.verify(filter, atLeastOnce())
+                .shouldFilterOut(any(NotificationEntry.class), anyLong());
+        inOrder.verify(mOnBeforeTransformGroupsListener)
+                .onBeforeTransformGroups(anyList(), anyList());
+        inOrder.verify(promoter, atLeastOnce())
+                .shouldPromoteToTopLevel(any(NotificationEntry.class));
+        inOrder.verify(mOnBeforeSortListener).onBeforeSort(anyList());
+        inOrder.verify(sectioner, atLeastOnce()).getSection(any(ListEntry.class));
+        inOrder.verify(comparator, atLeastOnce())
+                .compare(any(ListEntry.class), any(ListEntry.class));
+        inOrder.verify(mOnBeforeRenderListListener).onBeforeRenderList(anyList());
+        inOrder.verify(mOnRenderListListener).onRenderList(anyList());
+    }
+
+    @Test
+    public void testThatPluggableInvalidationsTriggersRerun() {
+        // GIVEN a variety of pluggables
+        NotifFilter packageFilter = new PackageFilter(PACKAGE_1);
+        NotifPromoter idPromoter = new IdPromoter(4);
+        SectionsProvider sectionsProvider = new PackageSectioner();
+        NotifComparator hypeComparator = new HypeComparator(PACKAGE_2);
+
+        mListBuilder.addFilter(packageFilter);
+        mListBuilder.addPromoter(idPromoter);
+        mListBuilder.setSectionsProvider(sectionsProvider);
+        mListBuilder.setComparators(Collections.singletonList(hypeComparator));
+
+        // GIVEN a set of random notifs
+        addNotif(0, PACKAGE_1);
+        addNotif(1, PACKAGE_2);
+        addNotif(2, PACKAGE_3);
+        dispatchBuild();
+
+        // WHEN each pluggable is invalidated THEN the list is re-rendered
+
+        clearInvocations(mOnRenderListListener);
+        packageFilter.invalidateList();
+        verify(mOnRenderListListener).onRenderList(anyList());
+
+        clearInvocations(mOnRenderListListener);
+        idPromoter.invalidateList();
+        verify(mOnRenderListListener).onRenderList(anyList());
+
+        clearInvocations(mOnRenderListListener);
+        sectionsProvider.invalidateList();
+        verify(mOnRenderListListener).onRenderList(anyList());
+
+        clearInvocations(mOnRenderListListener);
+        hypeComparator.invalidateList();
+        verify(mOnRenderListListener).onRenderList(anyList());
+    }
+
+    @Test
+    public void testNotifFiltersAreAllSentTheSameNow() {
+        // GIVEN three notif filters
+        NotifFilter filter1 = spy(new PackageFilter(PACKAGE_5));
+        NotifFilter filter2 = spy(new PackageFilter(PACKAGE_5));
+        NotifFilter filter3 = spy(new PackageFilter(PACKAGE_5));
+        mListBuilder.addFilter(filter1);
+        mListBuilder.addFilter(filter2);
+        mListBuilder.addFilter(filter3);
+
+        // GIVEN the SystemClock is set to a particular time:
+        mSystemClock.setAutoIncrement(true);
+        mSystemClock.setUptimeMillis(47);
+
+        // WHEN the pipeline is kicked off on a list of notifs
+        addNotif(0, PACKAGE_1);
+        addNotif(1, PACKAGE_2);
+        dispatchBuild();
+
+        // THEN the value of `now` is the same for all calls to shouldFilterOut
+        verify(filter1).shouldFilterOut(mEntrySet.get(0), 47);
+        verify(filter2).shouldFilterOut(mEntrySet.get(0), 47);
+        verify(filter3).shouldFilterOut(mEntrySet.get(0), 47);
+        verify(filter1).shouldFilterOut(mEntrySet.get(1), 47);
+        verify(filter2).shouldFilterOut(mEntrySet.get(1), 47);
+        verify(filter3).shouldFilterOut(mEntrySet.get(1), 47);
+    }
+
+    @Test
+    public void testNewlyAddedEntries() {
+        // GIVEN a registered OnBeforeTransformGroupsListener
+        RecordingOnBeforeTransformGroupsListener listener =
+                spy(new RecordingOnBeforeTransformGroupsListener());
+        mListBuilder.addOnBeforeTransformGroupsListener(listener);
+
+        // Given some new notifs
+        addNotif(0, PACKAGE_1);
+        addGroupChild(1, PACKAGE_2, GROUP_1);
+        addGroupSummary(2, PACKAGE_2, GROUP_1);
+        addGroupChild(3, PACKAGE_2, GROUP_1);
+        addNotif(4, PACKAGE_3);
+        addGroupChild(5, PACKAGE_2, GROUP_1);
+
+        // WHEN we run the pipeline
+        dispatchBuild();
+
+        verifyBuiltList(
+                notif(0),
+                group(
+                        summary(2),
+                        child(1),
+                        child(3),
+                        child(5)
+                ),
+                notif(4)
+        );
+
+        // THEN all the new notifs, including the new GroupEntry, are passed to the listener
+        verify(listener).onBeforeTransformGroups(
+                Arrays.asList(
+                        mEntrySet.get(0),
+                        mBuiltList.get(1),
+                        mEntrySet.get(4)
+                ),
+                Arrays.asList(
+                        mEntrySet.get(0),
+                        mEntrySet.get(1),
+                        mBuiltList.get(1),
+                        mEntrySet.get(2),
+                        mEntrySet.get(3),
+                        mEntrySet.get(4),
+                        mEntrySet.get(5)
+                )
+        );
+    }
+
+    @Test
+    public void testNewlyAddedEntriesOnSecondRun() {
+        // GIVEN a registered OnBeforeTransformGroupsListener
+        RecordingOnBeforeTransformGroupsListener listener =
+                spy(new RecordingOnBeforeTransformGroupsListener());
+        mListBuilder.addOnBeforeTransformGroupsListener(listener);
+
+        // Given some notifs that have already been added (two of which are in malformed groups)
+        addNotif(0, PACKAGE_1);
+        addGroupChild(1, PACKAGE_2, GROUP_1);
+        addGroupChild(2, PACKAGE_3, GROUP_2);
+
+        dispatchBuild();
+        clearInvocations(listener);
+
+        // WHEN we run the pipeline
+        addGroupSummary(3, PACKAGE_2, GROUP_1);
+        addGroupChild(4, PACKAGE_3, GROUP_2);
+        addGroupSummary(5, PACKAGE_3, GROUP_2);
+        addGroupChild(6, PACKAGE_3, GROUP_2);
+        addNotif(7, PACKAGE_2);
+
+        dispatchBuild();
+
+        verifyBuiltList(
+                notif(0),
+                notif(1),
+                group(
+                        summary(5),
+                        child(2),
+                        child(4),
+                        child(6)
+                ),
+                notif(7)
+        );
+
+        // THEN all the new notifs, including the new GroupEntry, are passed to the listener
+        verify(listener).onBeforeTransformGroups(
+                Arrays.asList(
+                        mEntrySet.get(0),
+                        mEntrySet.get(1),
+                        mBuiltList.get(2),
+                        mEntrySet.get(7)
+                ),
+                Arrays.asList(
+                        mBuiltList.get(2),
+                        mEntrySet.get(4),
+                        mEntrySet.get(5),
+                        mEntrySet.get(6),
+                        mEntrySet.get(7)
+                )
+        );
+    }
+
+    @Test
+    public void testAnnulledGroupsHaveParentSetProperly() {
+        // GIVEN a list containing a small group that's already been built once
+        addGroupChild(0, PACKAGE_2, GROUP_2);
+        addGroupSummary(1, PACKAGE_2, GROUP_2);
+        addGroupChild(2, PACKAGE_2, GROUP_2);
+        dispatchBuild();
+
+        verifyBuiltList(
+                group(
+                        summary(1),
+                        child(0),
+                        child(2)
+                )
+        );
+        GroupEntry group = (GroupEntry) mBuiltList.get(0);
+
+        // WHEN a child is removed such that the group is no longer big enough
+        mEntrySet.remove(2);
+        dispatchBuild();
+
+        // THEN the group is annulled and its parent is set back to null
+        verifyBuiltList(
+                notif(0)
+        );
+        assertNull(group.getParent());
+
+        // but its previous parent indicates that it was added in the previous iteration
+        assertEquals(GroupEntry.ROOT_ENTRY, group.getPreviousParent());
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testOutOfOrderFilterInvalidationThrows() {
+        // GIVEN a NotifFilter that gets invalidated during the grouping stage
+        NotifFilter filter = new PackageFilter(PACKAGE_5);
+        OnBeforeTransformGroupsListener listener =
+                (list, newlyVisibleEntries) -> filter.invalidateList();
+        mListBuilder.addFilter(filter);
+        mListBuilder.addOnBeforeTransformGroupsListener(listener);
+
+        // WHEN we try to run the pipeline and the filter is invalidated
+        addNotif(0, PACKAGE_1);
+        dispatchBuild();
+
+        // Then an exception is thrown
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testOutOfOrderPrompterInvalidationThrows() {
+        // GIVEN a NotifPromoter that gets invalidated during the sorting stage
+        NotifPromoter promoter = new IdPromoter(47);
+        OnBeforeSortListener listener =
+                (list) -> promoter.invalidateList();
+        mListBuilder.addPromoter(promoter);
+        mListBuilder.addOnBeforeSortListener(listener);
+
+        // WHEN we try to run the pipeline and the promoter is invalidated
+        addNotif(0, PACKAGE_1);
+        dispatchBuild();
+
+        // Then an exception is thrown
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testOutOfOrderComparatorInvalidationThrows() {
+        // GIVEN a NotifComparator that gets invalidated during the finalizing stage
+        NotifComparator comparator = new HypeComparator(PACKAGE_5);
+        OnBeforeRenderListListener listener =
+                (list) -> comparator.invalidateList();
+        mListBuilder.setComparators(Collections.singletonList(comparator));
+        mListBuilder.addOnBeforeRenderListListener(listener);
+
+        // WHEN we try to run the pipeline and the comparator is invalidated
+        addNotif(0, PACKAGE_1);
+        dispatchBuild();
+
+        // Then an exception is thrown
+    }
+
+    /**
+     * Adds a notif to the collection that will be passed to the list builder when
+     * {@link #dispatchBuild()}s is called.
+     *
+     * @param index Index of this notification in the set. This must be the current size of the set.
+     *              it exists to improve readability of the resulting code, since later tests will
+     *              have to refer to notifs by index.
+     * @param packageId Package that the notif should be posted under
+     * @return A NotificationEntryBuilder that can be used to further modify the notif. Do not call
+     *         build() on the builder; that will be done on the next dispatchBuild().
+     */
+    private NotificationEntryBuilder addNotif(int index, String packageId) {
+        final NotificationEntryBuilder builder = new NotificationEntryBuilder()
+                .setPkg(packageId)
+                .setId(nextId(packageId))
+                .setRank(nextRank());
+
+        builder.modifyNotification(mContext)
+                .setContentTitle("Top level singleton")
+                .setChannelId("test_channel");
+
+        assertEquals(mEntrySet.size() + mPendingSet.size(), index);
+        mPendingSet.add(builder);
+        return builder;
+    }
+
+    /** Same behavior as {@link #addNotif(int, String)}. */
+    private NotificationEntryBuilder addGroupSummary(int index, String packageId, String groupId) {
+        final NotificationEntryBuilder builder = new NotificationEntryBuilder()
+                .setPkg(packageId)
+                .setId(nextId(packageId))
+                .setRank(nextRank());
+
+        builder.modifyNotification(mContext)
+                .setChannelId("test_channel")
+                .setContentTitle("Group summary")
+                .setGroup(groupId)
+                .setGroupSummary(true);
+
+        assertEquals(mEntrySet.size() + mPendingSet.size(), index);
+        mPendingSet.add(builder);
+        return builder;
+    }
+
+    /** Same behavior as {@link #addNotif(int, String)}. */
+    private NotificationEntryBuilder addGroupChild(int index, String packageId, String groupId) {
+        final NotificationEntryBuilder builder = new NotificationEntryBuilder()
+                .setPkg(packageId)
+                .setId(nextId(packageId))
+                .setRank(nextRank());
+
+        builder.modifyNotification(mContext)
+                .setChannelId("test_channel")
+                .setContentTitle("Group child")
+                .setGroup(groupId);
+
+        assertEquals(mEntrySet.size() + mPendingSet.size(), index);
+        mPendingSet.add(builder);
+        return builder;
+    }
+
+    private int nextId(String packageName) {
+        Integer nextId = mNextIdMap.get(packageName);
+        if (nextId == null) {
+            nextId = 0;
+        }
+        mNextIdMap.put(packageName, nextId + 1);
+        return nextId;
+    }
+
+    private int nextRank() {
+        int nextRank = mNextRank;
+        mNextRank++;
+        return nextRank;
+    }
+
+    private void dispatchBuild() {
+        if (mPendingSet.size() > 0) {
+            for (NotificationEntryBuilder builder : mPendingSet) {
+                mEntrySet.add(builder.build());
+            }
+            mPendingSet.clear();
+        }
+
+        mReadyForBuildListener.onBeginDispatchToListeners();
+        mReadyForBuildListener.onBuildList(mEntrySet);
+    }
+
+    private void verifyBuiltList(ExpectedEntry ...expectedEntries) {
+        try {
+            assertEquals(
+                    "List is the wrong length",
+                    expectedEntries.length,
+                    mBuiltList.size());
+
+            for (int i = 0; i < expectedEntries.length; i++) {
+                ListEntry outEntry = mBuiltList.get(i);
+                ExpectedEntry expectedEntry = expectedEntries[i];
+
+                if (expectedEntry instanceof ExpectedNotif) {
+                    assertEquals(
+                            "Entry " + i + " isn't a NotifEntry",
+                            NotificationEntry.class,
+                            outEntry.getClass());
+                    assertEquals(
+                            "Entry " + i + " doesn't match expected value.",
+                            ((ExpectedNotif) expectedEntry).entry, outEntry);
+                } else {
+                    ExpectedGroup cmpGroup = (ExpectedGroup) expectedEntry;
+
+                    assertEquals(
+                            "Entry " + i + " isn't a GroupEntry",
+                            GroupEntry.class,
+                            outEntry.getClass());
+
+                    GroupEntry outGroup = (GroupEntry) outEntry;
+
+                    assertEquals(
+                            "Summary notif for entry " + i
+                                    + " doesn't match expected value",
+                            cmpGroup.summary,
+                            outGroup.getSummary());
+                    assertEquals(
+                            "Summary notif for entry " + i
+                                        + " doesn't have proper parent",
+                            outGroup,
+                            outGroup.getSummary().getParent());
+
+                    assertEquals("Children for entry " + i,
+                            cmpGroup.children,
+                            outGroup.getChildren());
+
+                    for (int j = 0; j < outGroup.getChildren().size(); j++) {
+                        NotificationEntry child = outGroup.getChildren().get(j);
+                        assertEquals(
+                                "Child " + j + " for entry " + i
+                                        + " doesn't have proper parent",
+                                outGroup,
+                                child.getParent());
+                    }
+                }
+            }
+        } catch (AssertionError err) {
+            throw new AssertionError(
+                    "List under test failed verification:\n" + dumpList(mBuiltList), err);
+        }
+    }
+
+    private ExpectedNotif notif(int index) {
+        return new ExpectedNotif(mEntrySet.get(index));
+    }
+
+    private ExpectedGroup group(ExpectedSummary summary, ExpectedChild...children) {
+        return new ExpectedGroup(
+                summary.entry,
+                Arrays.stream(children)
+                        .map(child -> child.entry)
+                        .collect(Collectors.toList()));
+    }
+
+    private ExpectedSummary summary(int index) {
+        return new ExpectedSummary(mEntrySet.get(index));
+    }
+
+    private ExpectedChild child(int index) {
+        return new ExpectedChild(mEntrySet.get(index));
+    }
+
+    private abstract static class ExpectedEntry {
+    }
+
+    private static class ExpectedNotif extends ExpectedEntry {
+        public final NotificationEntry entry;
+
+        private ExpectedNotif(NotificationEntry entry) {
+            this.entry = entry;
+        }
+    }
+
+    private static class ExpectedGroup extends ExpectedEntry {
+        public final NotificationEntry summary;
+        public final List<NotificationEntry> children;
+
+        private ExpectedGroup(
+                NotificationEntry summary,
+                List<NotificationEntry> children) {
+            this.summary = summary;
+            this.children = children;
+        }
+    }
+
+    private static class ExpectedSummary {
+        public final NotificationEntry entry;
+
+        private ExpectedSummary(NotificationEntry entry) {
+            this.entry = entry;
+        }
+    }
+
+    private static class ExpectedChild {
+        public final NotificationEntry entry;
+
+        private ExpectedChild(NotificationEntry entry) {
+            this.entry = entry;
+        }
+    }
+
+    /** Filters out notifs from a particular package */
+    private static class PackageFilter extends NotifFilter {
+        private final String mPackageName;
+
+        private boolean mEnabled = true;
+
+        PackageFilter(String packageName) {
+            super("PackageFilter");
+
+            mPackageName = packageName;
+        }
+
+        @Override
+        public boolean shouldFilterOut(NotificationEntry entry, long now) {
+            return mEnabled && entry.getSbn().getPackageName().equals(mPackageName);
+        }
+
+        public void setEnabled(boolean enabled) {
+            mEnabled = enabled;
+        }
+    }
+
+    /** Promotes notifs with particular IDs */
+    private static class IdPromoter extends NotifPromoter {
+        private final List<Integer> mIds;
+
+        IdPromoter(Integer... ids) {
+            super("IdPromoter");
+            mIds = Arrays.asList(ids);
+        }
+
+        @Override
+        public boolean shouldPromoteToTopLevel(NotificationEntry child) {
+            return mIds.contains(child.getSbn().getId());
+        }
+    }
+
+    /** Sorts specific notifs above all others. */
+    private static class HypeComparator extends NotifComparator {
+
+        private final List<String> mPreferredPackages;
+
+        HypeComparator(String ...preferredPackages) {
+            super("HypeComparator");
+            mPreferredPackages = Arrays.asList(preferredPackages);
+        }
+
+        @Override
+        public int compare(ListEntry o1, ListEntry o2) {
+            boolean contains1 = mPreferredPackages.contains(
+                    o1.getRepresentativeEntry().getSbn().getPackageName());
+            boolean contains2 = mPreferredPackages.contains(
+                    o2.getRepresentativeEntry().getSbn().getPackageName());
+
+            return Boolean.compare(contains2, contains1);
+        }
+    }
+
+    /** Sorts notifs into sections based on their package name */
+    private static class PackageSectioner extends SectionsProvider {
+
+        PackageSectioner() {
+            super("PackageSectioner");
+        }
+
+        @Override
+        public int getSection(ListEntry entry) {
+            switch (entry.getRepresentativeEntry().getSbn().getPackageName()) {
+                case PACKAGE_1:
+                    return 1;
+                case PACKAGE_2:
+                    return 2;
+                case PACKAGE_3:
+                    return 3;
+                default:
+                    return 4;
+            }
+        }
+    }
+
+    private static class RecordingOnBeforeTransformGroupsListener
+            implements OnBeforeTransformGroupsListener {
+        public List<ListEntry> newlyVisibleEntries;
+
+        @Override
+        public void onBeforeTransformGroups(List<ListEntry> list,
+                List<ListEntry> newlyVisibleEntries) {
+            this.newlyVisibleEntries = newlyVisibleEntries;
+        }
+    }
+
+    private static final String PACKAGE_1 = "com.test1";
+    private static final String PACKAGE_2 = "com.test2";
+    private static final String PACKAGE_3 = "org.test3";
+    private static final String PACKAGE_4 = "com.test4";
+    private static final String PACKAGE_5 = "com.test5";
+
+    private static final String GROUP_1 = "group_1";
+    private static final String GROUP_2 = "group_2";
+}
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 71c2e11..ba28879 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
@@ -139,7 +139,7 @@
     @Test
     public void testInflationThrowsErrorDoesntCallUpdated() throws Exception {
         mRow.getPrivateLayout().removeAllViews();
-        mRow.getStatusBarNotification().getNotification().contentView
+        mRow.getEntry().getSbn().getNotification().contentView
                 = new RemoteViews(mContext.getPackageName(), R.layout.status_bar);
         runThenWaitForInflation(() -> mNotificationInflater.inflateNotificationViews(),
                 true /* expectingException */, mNotificationInflater);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 0b123fc..749dae5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -320,7 +320,7 @@
                 .setUserSentiment(USER_SENTIMENT_NEGATIVE)
                 .build();
         when(row.getIsNonblockable()).thenReturn(false);
-        StatusBarNotification statusBarNotification = row.getStatusBarNotification();
+        StatusBarNotification statusBarNotification = row.getEntry().getSbn();
         NotificationEntry entry = row.getEntry();
 
         mGutsManager.initializeNotificationInfo(row, notificationInfoView);
@@ -352,7 +352,7 @@
                 .setUserSentiment(USER_SENTIMENT_NEGATIVE)
                 .build();
         when(row.getIsNonblockable()).thenReturn(false);
-        StatusBarNotification statusBarNotification = row.getStatusBarNotification();
+        StatusBarNotification statusBarNotification = row.getEntry().getSbn();
         NotificationEntry entry = row.getEntry();
 
         mGutsManager.initializeNotificationInfo(row, notificationInfoView);
@@ -386,7 +386,7 @@
                 .build();
         row.getEntry().setIsHighPriority(true);
         when(row.getIsNonblockable()).thenReturn(false);
-        StatusBarNotification statusBarNotification = row.getStatusBarNotification();
+        StatusBarNotification statusBarNotification = row.getEntry().getSbn();
         NotificationEntry entry = row.getEntry();
 
         mGutsManager.initializeNotificationInfo(row, notificationInfoView);
@@ -418,7 +418,7 @@
                 .setUserSentiment(USER_SENTIMENT_NEGATIVE)
                 .build();
         when(row.getIsNonblockable()).thenReturn(false);
-        StatusBarNotification statusBarNotification = row.getStatusBarNotification();
+        StatusBarNotification statusBarNotification = row.getEntry().getSbn();
         NotificationEntry entry = row.getEntry();
 
         when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
@@ -452,7 +452,7 @@
                 .setUserSentiment(USER_SENTIMENT_NEGATIVE)
                 .build();
         when(row.getIsNonblockable()).thenReturn(false);
-        StatusBarNotification statusBarNotification = row.getStatusBarNotification();
+        StatusBarNotification statusBarNotification = row.getEntry().getSbn();
         NotificationEntry entry = row.getEntry();
 
         mGutsManager.initializeNotificationInfo(row, notificationInfoView);
@@ -530,7 +530,7 @@
 
     private NotificationMenuRowPlugin.MenuItem createTestMenuItem(ExpandableNotificationRow row) {
         NotificationMenuRowPlugin menuRow = new NotificationMenuRow(mContext);
-        menuRow.createMenu(row, row.getStatusBarNotification());
+        menuRow.createMenu(row, row.getEntry().getSbn());
 
         NotificationMenuRowPlugin.MenuItem menuItem = menuRow.getLongpressMenuItem(mContext);
         assertNotNull(menuItem);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 5b624bc..d20a37a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -448,12 +448,12 @@
                 mock(ExpandableNotificationRow.LongPressListener.class));
 
         ExpandableNotificationRow row = mock(ExpandableNotificationRow.class, RETURNS_DEEP_STUBS);
-        when(row.getStatusBarNotification().getLogMaker()).thenReturn(new LogMaker(
+        when(row.getEntry().getSbn().getLogMaker()).thenReturn(new LogMaker(
                 MetricsProto.MetricsEvent.VIEW_UNKNOWN));
 
         mStackScroller.mMenuEventListener.onMenuClicked(row, 0, 0, mock(
                 NotificationMenuRowPlugin.MenuItem.class));
-        verify(row.getStatusBarNotification()).getLogMaker();  // This writes most of the log data
+        verify(row.getEntry().getSbn()).getLogMaker();  // This writes most of the log data
         verify(mMetricsLogger).write(logMatcher(MetricsProto.MetricsEvent.ACTION_TOUCH_GEAR,
                 MetricsProto.MetricsEvent.TYPE_ACTION));
     }
@@ -463,11 +463,11 @@
     public void testOnMenuShownLogging() { ;
 
         ExpandableNotificationRow row = mock(ExpandableNotificationRow.class, RETURNS_DEEP_STUBS);
-        when(row.getStatusBarNotification().getLogMaker()).thenReturn(new LogMaker(
+        when(row.getEntry().getSbn().getLogMaker()).thenReturn(new LogMaker(
                 MetricsProto.MetricsEvent.VIEW_UNKNOWN));
 
         mStackScroller.mMenuEventListener.onMenuShown(row);
-        verify(row.getStatusBarNotification()).getLogMaker();  // This writes most of the log data
+        verify(row.getEntry().getSbn()).getLogMaker();  // This writes most of the log data
         verify(mMetricsLogger).write(logMatcher(MetricsProto.MetricsEvent.ACTION_REVEAL_GEAR,
                 MetricsProto.MetricsEvent.TYPE_ACTION));
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
index bc4e401..8decae3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
@@ -34,8 +34,6 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiBaseFragmentTest;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.tuner.TunerService;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -58,10 +56,8 @@
 
     @Before
     public void setup() {
-        mSysuiContext.putComponent(CommandQueue.class, mock(CommandQueue.class));
         StatusBar statusBar = mock(StatusBar.class);
         mDependency.injectTestDependency(StatusBar.class, statusBar);
-        mSysuiContext.putComponent(TunerService.class, mock(TunerService.class));
         mStatusBarStateController = mDependency
                 .injectMockDependency(StatusBarStateController.class);
         injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index 105dbad..222fcb6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -90,6 +90,7 @@
     @Mock private NotificationPanelView mNotificationPanel;
     @Mock private View mAmbientIndicationContainer;
     @Mock private BiometricUnlockController mBiometricUnlockController;
+    @Mock private LockscreenLockIconController mLockscreenLockIconController;
 
     @Before
     public void setup() {
@@ -99,11 +100,11 @@
                 mBatteryController, mScrimController, () -> mBiometricUnlockController,
                 mKeyguardViewMediator, () -> mAssistManager, mDozeScrimController,
                 mKeyguardUpdateMonitor, mVisualStabilityManager, mPulseExpansionHandler,
-                mStatusBarWindowController, mNotificationWakeUpCoordinator);
+                mStatusBarWindowController, mNotificationWakeUpCoordinator,
+                mStatusBarWindowViewController, mLockscreenLockIconController);
 
-        mDozeServiceHost.initialize(mStatusBar, mNotificationIconAreaController,
-                mStatusBarWindowViewController, mStatusBarWindow, mStatusBarKeyguardViewManager,
-                mNotificationPanel, mAmbientIndicationContainer);
+        mDozeServiceHost.initialize(mStatusBar, mNotificationIconAreaController, mStatusBarWindow,
+                mStatusBarKeyguardViewManager, mNotificationPanel, mAmbientIndicationContainer);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarButtonTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarButtonTest.java
index 098a69f..aae0757 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarButtonTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarButtonTest.java
@@ -18,7 +18,6 @@
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
 
 import android.graphics.PixelFormat;
 import android.hardware.display.DisplayManager;
@@ -37,7 +36,6 @@
 import com.android.systemui.SysuiTestableContext;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import org.junit.After;
@@ -60,11 +58,9 @@
 
     @Before
     public void setup() {
-        mContext.putComponent(CommandQueue.class, mock(CommandQueue.class));
         final Display display = createVirtualDisplay();
         final SysuiTestableContext context =
                 (SysuiTestableContext) mContext.createDisplayContext(display);
-        context.putComponent(CommandQueue.class, mock(CommandQueue.class));
 
         mDependency.injectMockDependency(AssistManager.class);
         mDependency.injectMockDependency(OverviewProxyService.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarInflaterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarInflaterViewTest.java
index 991e495..80e33fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarInflaterViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarInflaterViewTest.java
@@ -33,7 +33,6 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.statusbar.CommandQueue;
 
 import org.junit.After;
 import org.junit.Before;
@@ -52,7 +51,6 @@
 
     @Before
     public void setUp() {
-        mContext.putComponent(CommandQueue.class, mock(CommandQueue.class));
         mDependency.injectMockDependency(AssistManager.class);
         mDependency.injectMockDependency(OverviewProxyService.class);
         mDependency.injectMockDependency(NavigationModeController.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
index a49ae35..3ad1e39 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
@@ -87,7 +87,6 @@
         ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
         entry.setRow(row);
         when(row.getEntry()).thenReturn(entry);
-        when(row.getStatusBarNotification()).thenReturn(entry.getSbn());
         when(row.isInflationFlagSet(anyInt())).thenReturn(true);
         return entry;
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index 24a5d93..6f5cfbe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -64,6 +64,7 @@
 import com.android.systemui.statusbar.NotificationTestHelper;
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.SuperStatusBarViewFactory;
 import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -116,8 +117,11 @@
     @Mock
     private Intent mContentIntentInner;
     @Mock
-
     private NotificationActivityStarter mNotificationActivityStarter;
+    @Mock
+    private SuperStatusBarViewFactory mSuperStatusBarViewFactory;
+    @Mock
+    private NotificationPanelView mNotificationPanelView;
 
     private NotificationTestHelper mNotificationTestHelper;
     private ExpandableNotificationRow mNotificationRow;
@@ -141,13 +145,13 @@
 
         // Create standard notification with contentIntent
         mNotificationRow = mNotificationTestHelper.createRow();
-        StatusBarNotification sbn = mNotificationRow.getStatusBarNotification();
+        StatusBarNotification sbn = mNotificationRow.getEntry().getSbn();
         sbn.getNotification().contentIntent = mContentIntent;
         sbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
 
         // Create bubble notification row with contentIntent
         mBubbleNotificationRow = mNotificationTestHelper.createBubble();
-        StatusBarNotification bubbleSbn = mBubbleNotificationRow.getStatusBarNotification();
+        StatusBarNotification bubbleSbn = mBubbleNotificationRow.getEntry().getSbn();
         bubbleSbn.getNotification().contentIntent = mContentIntent;
         bubbleSbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
 
@@ -156,19 +160,25 @@
         mActiveNotifications.add(mBubbleNotificationRow.getEntry());
         when(mEntryManager.getVisibleNotifications()).thenReturn(mActiveNotifications);
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
+        when(mSuperStatusBarViewFactory.getNotificationPanelView())
+                .thenReturn(mNotificationPanelView);
 
-        mNotificationActivityStarter = new StatusBarNotificationActivityStarter(getContext(),
-                mock(CommandQueue.class), mAssistManager, mock(NotificationPanelView.class),
-                mock(NotificationPresenter.class), mEntryManager, mock(HeadsUpManagerPhone.class),
-                mActivityStarter, mock(ActivityLaunchAnimator.class), mStatusBarService,
+        mNotificationActivityStarter = (new StatusBarNotificationActivityStarter.Builder(
+                getContext(), mock(CommandQueue.class), () -> mAssistManager,
+                mEntryManager, mock(HeadsUpManagerPhone.class),
+                mActivityStarter, mStatusBarService,
                 mock(StatusBarStateController.class), mock(KeyguardManager.class),
                 mock(IDreamManager.class), mRemoteInputManager,
                 mock(StatusBarRemoteInputCallback.class), mock(NotificationGroupManager.class),
-                mock(NotificationLockscreenUserManager.class), mShadeController,
+                mock(NotificationLockscreenUserManager.class),
                 mKeyguardStateController,
                 mock(NotificationInterruptionStateProvider.class), mock(MetricsLogger.class),
                 mock(LockPatternUtils.class), mHandler, mHandler, mActivityIntentHelper,
-                mBubbleController);
+                mBubbleController, mSuperStatusBarViewFactory))
+                .setShadeController(mShadeController)
+                .setNotificationPresenter(mock(NotificationPresenter.class))
+                .setActivityLaunchAnimator(mock(ActivityLaunchAnimator.class))
+        .build();
 
         // set up dismissKeyguardThenExecute to synchronously invoke the OnDismissAction arg
         doAnswer(mCallOnDismiss).when(mActivityStarter).dismissKeyguardThenExecute(
@@ -194,7 +204,7 @@
     public void testOnNotificationClicked_keyGuardShowing()
             throws PendingIntent.CanceledException, RemoteException {
         // Given
-        StatusBarNotification sbn = mNotificationRow.getStatusBarNotification();
+        StatusBarNotification sbn = mNotificationRow.getEntry().getSbn();
         sbn.getNotification().contentIntent = mContentIntent;
         sbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
 
@@ -228,7 +238,7 @@
     @Test
     public void testOnNotificationClicked_bubble_noContentIntent_noKeyGuard()
             throws RemoteException {
-        StatusBarNotification sbn = mBubbleNotificationRow.getStatusBarNotification();
+        StatusBarNotification sbn = mBubbleNotificationRow.getEntry().getSbn();
 
         // Given
         sbn.getNotification().contentIntent = null;
@@ -257,7 +267,7 @@
     @Test
     public void testOnNotificationClicked_bubble_noContentIntent_keyGuardShowing()
             throws RemoteException {
-        StatusBarNotification sbn = mBubbleNotificationRow.getStatusBarNotification();
+        StatusBarNotification sbn = mBubbleNotificationRow.getEntry().getSbn();
 
         // Given
         sbn.getNotification().contentIntent = null;
@@ -287,7 +297,7 @@
     @Test
     public void testOnNotificationClicked_bubble_withContentIntent_keyGuardShowing()
             throws RemoteException {
-        StatusBarNotification sbn = mBubbleNotificationRow.getStatusBarNotification();
+        StatusBarNotification sbn = mBubbleNotificationRow.getEntry().getSbn();
 
         // Given
         sbn.getNotification().contentIntent = mContentIntent;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
index b1b66b5..9d76b42 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
@@ -72,7 +72,7 @@
         mRemoteInputCallback = spy(new StatusBarRemoteInputCallback(mContext,
                 mock(NotificationGroupManager.class), mNotificationLockscreenUserManager,
                 mKeyguardStateController, mStatusBarStateController, mActivityStarter,
-                mShadeController, new CommandQueue(mContext)));
+                () -> mShadeController, new CommandQueue(mContext)));
         mRemoteInputCallback.mChallengeReceiver = mRemoteInputCallback.new ChallengeReceiver();
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 95929c3a..e78fb9e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -111,7 +111,6 @@
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.NewNotifPipeline;
 import com.android.systemui.statusbar.notification.NotificationAlertingManager;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -120,6 +119,7 @@
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.init.NewNotifPipeline;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
@@ -216,7 +216,6 @@
     @Mock private NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
     @Mock private StatusBarWindowController mStatusBarWindowController;
     @Mock private NotificationIconAreaController mNotificationIconAreaController;
-    @Mock private StatusBarWindowViewController.Builder mStatusBarWindowViewControllerBuilder;
     @Mock private StatusBarWindowViewController mStatusBarWindowViewController;
     @Mock private DozeParameters mDozeParameters;
     @Mock private Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy;
@@ -236,6 +235,9 @@
     @Mock private DismissCallbackRegistry mDismissCallbackRegistry;
     @Mock private ScreenPinningRequest mScreenPinningRequest;
     @Mock private NotificationEntryManager mEntryManager;
+    @Mock private LockscreenLockIconController mLockscreenLockIconController;
+    @Mock private StatusBarNotificationActivityStarter.Builder
+            mStatusBarNotificationActivityStarterBuilder;
 
     @Before
     public void setup() throws Exception {
@@ -295,9 +297,6 @@
         when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
         ConfigurationController configurationController = new ConfigurationControllerImpl(mContext);
 
-        when(mStatusBarWindowViewControllerBuilder.build())
-                .thenReturn(mStatusBarWindowViewController);
-
         when(mLockscreenWallpaperLazy.get()).thenReturn(mLockscreenWallpaper);
         when(mBiometricUnlockControllerLazy.get()).thenReturn(mBiometricUnlockController);
 
@@ -355,7 +354,8 @@
                 mNotificationListener,
                 configurationController,
                 mStatusBarWindowController,
-                mStatusBarWindowViewControllerBuilder,
+                mStatusBarWindowViewController,
+                mLockscreenLockIconController,
                 mDozeParameters,
                 mScrimController,
                 mKeyguardLiftController,
@@ -371,6 +371,7 @@
                 mRemoteInputUriController,
                 Optional.of(mDivider),
                 mLightsOutNotifController,
+                mStatusBarNotificationActivityStarterBuilder,
                 mSuperStatusBarViewFactory,
                 mStatusBarKeyguardViewManager,
                 mViewMediatorCallback,
@@ -389,7 +390,6 @@
 
         // TODO: we should be able to call mStatusBar.start() and have all the below values
         // initialized automatically.
-        mStatusBar.mComponents = mContext.getComponents();
         mStatusBar.mStatusBarWindow = mStatusBarWindowView;
         mStatusBar.mNotificationPanel = mNotificationPanelView;
         mStatusBar.mDozeScrimController = mDozeScrimController;
@@ -398,7 +398,6 @@
         mStatusBar.mKeyguardIndicationController = mKeyguardIndicationController;
         mStatusBar.mBarService = mBarService;
         mStatusBar.mStackScroller = mStackScroller;
-        mStatusBar.mStatusBarWindowViewController = mStatusBarWindowViewController;
         mStatusBar.startKeyguard();
         Dependency.get(InitController.class).executePostInitTasks();
         notificationLogger.setUpWithContainer(mStackScroller);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
index 4d4e9ae..ee9ea9f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
@@ -82,14 +82,13 @@
         MockitoAnnotations.initMocks(this);
 
         mView = new StatusBarWindowView(getContext(), null);
-        mContext.putComponent(StatusBar.class, mStatusBar);
         when(mStatusBar.isDozing()).thenReturn(false);
         mDependency.injectTestDependency(ShadeController.class, mShadeController);
 
         when(mSuperStatusBarViewFactory.getStatusBarWindowView()).thenReturn(mView);
         when(mDockManager.isDocked()).thenReturn(false);
 
-        mController = new StatusBarWindowViewController.Builder(
+        mController = new StatusBarWindowViewController(
                 new InjectionInflationController(
                         SystemUIFactory.getInstance().getRootComponent()),
                 mCoordinator,
@@ -107,9 +106,9 @@
                 mDozeParameters,
                 new CommandQueue(mContext),
                 mSuperStatusBarViewFactory,
-                mDockManager)
-                .setShadeController(mShadeController)
-                .build();
+                () -> mShadeController,
+                mDockManager);
+        mController.setupExpandedStatusBar();
         mController.setService(mStatusBar);
         mController.setDragDownHelper(mDragDownHelper);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
index 48ed4ba..05a4867 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
@@ -20,6 +20,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Intent;
+import android.os.Handler;
 import android.os.PowerManager;
 import android.os.PowerSaveState;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -53,7 +54,7 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mBatteryController = new BatteryControllerImpl(getContext(), mock(EnhancedEstimates.class),
-                mPowerManager, mBroadcastDispatcher);
+                mPowerManager, mBroadcastDispatcher, new Handler(), new Handler());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
index 0d1e1bd..811e6a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
@@ -70,11 +70,11 @@
         mContext.addMockSystemService(WifiManager.class, mWifiManager);
 
         doAnswer((InvocationOnMock invocation) -> {
-            ((WifiManager.SoftApCallback) invocation.getArgument(0))
+            ((WifiManager.SoftApCallback) invocation.getArgument(1))
                     .onConnectedClientsChanged(new ArrayList<>());
             return null;
-        }).when(mWifiManager).registerSoftApCallback(any(WifiManager.SoftApCallback.class),
-                any(Executor.class));
+        }).when(mWifiManager).registerSoftApCallback(any(Executor.class),
+                any(WifiManager.SoftApCallback.class));
 
         mController = new HotspotControllerImpl(mContext, new Handler(mLooper.getLooper()));
         mController.handleSetListening(true);
@@ -85,7 +85,7 @@
         mController.addCallback(mCallback1);
         mController.addCallback(mCallback2);
 
-        verify(mWifiManager, times(1)).registerSoftApCallback(eq(mController), any());
+        verify(mWifiManager, times(1)).registerSoftApCallback(any(), eq(mController));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java b/packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java
new file mode 100644
index 0000000..7b5417c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java
@@ -0,0 +1,111 @@
+/*
+ * 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.util.time;
+
+public class FakeSystemClock implements SystemClock {
+    private boolean mAutoIncrement = true;
+
+    private long mUptimeMillis;
+    private long mElapsedRealtime;
+    private long mElapsedRealtimeNanos;
+    private long mCurrentThreadTimeMillis;
+    private long mCurrentThreadTimeMicro;
+    private long mCurrentTimeMicro;
+
+    @Override
+    public long uptimeMillis() {
+        long value = mUptimeMillis;
+        if (mAutoIncrement) {
+            mUptimeMillis++;
+        }
+        return value;
+    }
+
+    @Override
+    public long elapsedRealtime() {
+        long value = mElapsedRealtime;
+        if (mAutoIncrement) {
+            mElapsedRealtime++;
+        }
+        return value;
+    }
+
+    @Override
+    public long elapsedRealtimeNanos() {
+        long value = mElapsedRealtimeNanos;
+        if (mAutoIncrement) {
+            mElapsedRealtimeNanos++;
+        }
+        return value;
+    }
+
+    @Override
+    public long currentThreadTimeMillis() {
+        long value = mCurrentThreadTimeMillis;
+        if (mAutoIncrement) {
+            mCurrentThreadTimeMillis++;
+        }
+        return value;
+    }
+
+    @Override
+    public long currentThreadTimeMicro() {
+        long value = mCurrentThreadTimeMicro;
+        if (mAutoIncrement) {
+            mCurrentThreadTimeMicro++;
+        }
+        return value;
+    }
+
+    @Override
+    public long currentTimeMicro() {
+        long value = mCurrentTimeMicro;
+        if (mAutoIncrement) {
+            mCurrentTimeMicro++;
+        }
+        return value;
+    }
+
+    public void setUptimeMillis(long uptimeMillis) {
+        mUptimeMillis = uptimeMillis;
+    }
+
+    public void setElapsedRealtime(long elapsedRealtime) {
+        mElapsedRealtime = elapsedRealtime;
+    }
+
+    public void setElapsedRealtimeNanos(long elapsedRealtimeNanos) {
+        mElapsedRealtimeNanos = elapsedRealtimeNanos;
+    }
+
+    public void setCurrentThreadTimeMillis(long currentThreadTimeMillis) {
+        mCurrentThreadTimeMillis = currentThreadTimeMillis;
+    }
+
+    public void setCurrentThreadTimeMicro(long currentThreadTimeMicro) {
+        mCurrentThreadTimeMicro = currentThreadTimeMicro;
+    }
+
+    public void setCurrentTimeMicro(long currentTimeMicro) {
+        mCurrentTimeMicro = currentTimeMicro;
+    }
+
+    /** If true, each call to get____ will be one higher than the previous call to that method. */
+    public void setAutoIncrement(boolean autoIncrement) {
+        mAutoIncrement = autoIncrement;
+    }
+}
diff --git a/services/core/java/android/os/UserManagerInternal.java b/services/core/java/android/os/UserManagerInternal.java
index e5f8b49..9a7cb3f 100644
--- a/services/core/java/android/os/UserManagerInternal.java
+++ b/services/core/java/android/os/UserManagerInternal.java
@@ -143,8 +143,8 @@
      * <p>Called by the {@link com.android.server.devicepolicy.DevicePolicyManagerService} when
      * createAndManageUser is called by the device owner.
      */
-    public abstract UserInfo createUserEvenWhenDisallowed(String name, int flags,
-            String[] disallowedPackages);
+    public abstract UserInfo createUserEvenWhenDisallowed(String name, String userType,
+            int flags, String[] disallowedPackages);
 
     /**
      * Same as {@link UserManager#removeUser(int userId)}, but bypasses the check for
@@ -202,8 +202,7 @@
 
     /**
      * Checks if the {@code callingUserId} and {@code targetUserId} are same or in same group
-     * and that the {@code callingUserId} is not a managed profile and
-     * {@code targetUserId} is enabled.
+     * and that the {@code callingUserId} is not a profile and {@code targetUserId} is enabled.
      *
      * @return TRUE if the {@code callingUserId} can access {@code targetUserId}. FALSE
      * otherwise
@@ -215,8 +214,7 @@
             String debugMsg, boolean throwSecurityException);
 
     /**
-     * If {@code userId} is of a managed profile, return the parent user ID. Otherwise return
-     * itself.
+     * If {@code userId} is of a profile, return the parent user ID. Otherwise return itself.
      */
     public abstract int getProfileParentId(int userId);
 
diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java
index 190e6cf..7b02b6e 100644
--- a/services/core/java/com/android/server/DynamicSystemService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.content.pm.PackageManager;
-import android.gsi.GsiInstallParams;
 import android.gsi.GsiProgress;
 import android.gsi.IGsiService;
 import android.gsi.IGsid;
@@ -47,6 +46,7 @@
     private static final int GSID_ROUGH_TIMEOUT_MS = 8192;
     private static final String PATH_DEFAULT = "/data/gsi";
     private Context mContext;
+    private String mInstallPath;
     private volatile IGsiService mGsiService;
 
     DynamicSystemService(Context context) {
@@ -115,8 +115,8 @@
     }
 
     @Override
-    public boolean startInstallation(String name, long size, boolean readOnly)
-            throws RemoteException {
+    public boolean startInstallation() throws RemoteException {
+        IGsiService service = getGsiService();
         // priority from high to low: sysprop -> sdcard -> /data
         String path = SystemProperties.get("os.aot.path");
         if (path.isEmpty()) {
@@ -138,14 +138,19 @@
             }
             Slog.i(TAG, "startInstallation -> " + path);
         }
+        mInstallPath = path;
+        if (service.openInstall(path) != 0) {
+            Slog.i(TAG, "Failed to open " + path);
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean createPartition(String name, long size, boolean readOnly)
+            throws RemoteException {
         IGsiService service = getGsiService();
-        GsiInstallParams installParams = new GsiInstallParams();
-        installParams.installDir = path;
-        installParams.name = name;
-        installParams.size = size;
-        installParams.wipe = readOnly;
-        installParams.readOnly = readOnly;
-        if (service.beginGsiInstall(installParams) != 0) {
+        if (service.createPartition(name, size, readOnly) != 0) {
             Slog.i(TAG, "Failed to install " + name);
             return false;
         }
@@ -153,6 +158,16 @@
     }
 
     @Override
+    public boolean finishInstallation() throws RemoteException {
+        IGsiService service = getGsiService();
+        if (service.closeInstall() != 0) {
+            Slog.i(TAG, "Failed to finish installation");
+            return false;
+        }
+        return true;
+    }
+
+    @Override
     public GsiProgress getInstallationProgress() throws RemoteException {
         return getGsiService().getInstallProgress();
     }
@@ -190,6 +205,8 @@
 
     @Override
     public boolean remove() throws RemoteException {
+        IGsiService gsiService = getGsiService();
+        String install_dir = gsiService.getInstalledGsiImageDir();
         return getGsiService().removeGsi();
     }
 
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index f8b0072..dc61261 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -20,6 +20,7 @@
 
 import static java.util.Arrays.copyOf;
 
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.content.BroadcastReceiver;
@@ -112,6 +113,7 @@
         Context context;
 
         String callingPackage;
+        String callingFeatureId;
 
         IBinder binder;
 
@@ -145,7 +147,7 @@
         boolean canReadCallLog() {
             try {
                 return TelephonyPermissions.checkReadCallLog(
-                        context, subId, callerPid, callerUid, callingPackage);
+                        context, subId, callerPid, callerUid, callingPackage, callingFeatureId);
             } catch (SecurityException e) {
                 return false;
             }
@@ -578,7 +580,7 @@
     }
 
     @Override
-    public void addOnSubscriptionsChangedListener(String callingPackage,
+    public void addOnSubscriptionsChangedListener(String callingPackage, String callingFeatureId,
             IOnSubscriptionsChangedListener callback) {
         int callerUserId = UserHandle.getCallingUserId();
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
@@ -600,6 +602,7 @@
             r.context = mContext;
             r.onSubscriptionsChangedListenerCallback = callback;
             r.callingPackage = callingPackage;
+            r.callingFeatureId = callingFeatureId;
             r.callerUid = Binder.getCallingUid();
             r.callerPid = Binder.getCallingPid();
             r.events = 0;
@@ -632,7 +635,7 @@
 
     @Override
     public void addOnOpportunisticSubscriptionsChangedListener(String callingPackage,
-            IOnSubscriptionsChangedListener callback) {
+            String callingFeatureId, IOnSubscriptionsChangedListener callback) {
         int callerUserId = UserHandle.getCallingUserId();
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
         if (VDBG) {
@@ -653,6 +656,7 @@
             r.context = mContext;
             r.onOpportunisticSubscriptionsChangedListenerCallback = callback;
             r.callingPackage = callingPackage;
+            r.callingFeatureId = callingFeatureId;
             r.callerUid = Binder.getCallingUid();
             r.callerPid = Binder.getCallingPid();
             r.events = 0;
@@ -728,21 +732,28 @@
         }
     }
 
+    @Deprecated
     @Override
-    public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
+    public void listen(String callingPackage, IPhoneStateListener callback, int events,
             boolean notifyNow) {
-        listenForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, pkgForDebug, callback,
-                events, notifyNow);
+        listenWithFeature(callingPackage, null, callback, events, notifyNow);
     }
 
     @Override
-    public void listenForSubscriber(int subId, String pkgForDebug, IPhoneStateListener callback,
-            int events, boolean notifyNow) {
-        listen(pkgForDebug, callback, events, notifyNow, subId);
+    public void listenWithFeature(String callingPackage, String callingFeatureId,
+            IPhoneStateListener callback, int events, boolean notifyNow) {
+        listenForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, callingPackage,
+                callingFeatureId, callback, events, notifyNow);
     }
 
-    private void listen(String callingPackage, IPhoneStateListener callback, int events,
-            boolean notifyNow, int subId) {
+    @Override
+    public void listenForSubscriber(int subId, String callingPackage, String callingFeatureId,
+            IPhoneStateListener callback, int events, boolean notifyNow) {
+        listen(callingPackage, callingFeatureId, callback, events, notifyNow, subId);
+    }
+
+    private void listen(String callingPackage, @Nullable String callingFeatureId,
+            IPhoneStateListener callback, int events, boolean notifyNow, int subId) {
         int callerUserId = UserHandle.getCallingUserId();
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
         String str = "listen: E pkg=" + callingPackage + " events=0x" + Integer.toHexString(events)
@@ -757,7 +768,8 @@
             // Checks permission and throws SecurityException for disallowed operations. For pre-M
             // apps whose runtime permission has been revoked, we return immediately to skip sending
             // events to the app without crashing it.
-            if (!checkListenerPermission(events, subId, callingPackage, "listen")) {
+            if (!checkListenerPermission(events, subId, callingPackage, callingFeatureId,
+                    "listen")) {
                 return;
             }
 
@@ -774,6 +786,7 @@
                 r.context = mContext;
                 r.callback = callback;
                 r.callingPackage = callingPackage;
+                r.callingFeatureId = callingFeatureId;
                 r.callerUid = Binder.getCallingUid();
                 r.callerPid = Binder.getCallingPid();
                 // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
@@ -2374,8 +2387,8 @@
                 == PackageManager.PERMISSION_GRANTED;
     }
 
-    private boolean checkListenerPermission(
-            int events, int subId, String callingPackage, String message) {
+    private boolean checkListenerPermission(int events, int subId, String callingPackage,
+            @Nullable String callingFeatureId, String message) {
         LocationAccessPolicy.LocationPermissionQuery.Builder locationQueryBuilder =
                 new LocationAccessPolicy.LocationPermissionQuery.Builder()
                 .setCallingPackage(callingPackage)
@@ -2410,7 +2423,7 @@
 
         if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) {
             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mContext, subId, callingPackage, message)) {
+                    mContext, subId, callingPackage, callingFeatureId, message)) {
                 return false;
             }
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 4bb29f0..3dc745b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -346,7 +346,6 @@
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
 import com.android.server.appop.AppOpsService;
-import com.android.server.compat.CompatConfig;
 import com.android.server.compat.PlatformCompat;
 import com.android.server.contentcapture.ContentCaptureManagerInternal;
 import com.android.server.firewall.IntentFirewall;
@@ -5032,8 +5031,9 @@
             bindApplicationTimeMillis = SystemClock.elapsedRealtime();
             mAtmInternal.preBindApplication(app.getWindowProcessController());
             final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
-            long[] disabledCompatChanges = CompatConfig.get().getDisabledChanges(app.info);
+            long[] disabledCompatChanges = {};
             if (mPlatformCompat != null) {
+                disabledCompatChanges = mPlatformCompat.getDisabledChanges(app.info);
                 mPlatformCompat.resetReporting(app.info);
             }
             if (app.isolatedEntryPoint != null) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 1f56176..908ec6b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -37,11 +37,13 @@
 import android.app.IUidObserver;
 import android.app.KeyguardManager;
 import android.app.ProfilerInfo;
+import android.app.UserSwitchObserver;
 import android.app.WaitResult;
 import android.app.usage.AppStandbyInfo;
 import android.app.usage.ConfigurationStats;
 import android.app.usage.IUsageStatsManager;
 import android.app.usage.UsageStatsManager;
+import android.compat.Compatibility;
 import android.content.ComponentCallbacks2;
 import android.content.ComponentName;
 import android.content.Context;
@@ -80,15 +82,17 @@
 import android.os.UserManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.DebugUtils;
 import android.util.DisplayMetrics;
 import android.util.proto.ProtoOutputStream;
 import android.view.Display;
 
+import com.android.internal.compat.CompatibilityChangeConfig;
 import com.android.internal.util.HexDump;
 import com.android.internal.util.MemInfoReader;
 import com.android.internal.util.Preconditions;
-import com.android.server.compat.CompatConfig;
+import com.android.server.compat.PlatformCompat;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -1729,6 +1733,30 @@
         return 0;
     }
 
+    private void switchUserAndWaitForComplete(int userId) throws RemoteException {
+        // Register switch observer.
+        final CountDownLatch switchLatch = new CountDownLatch(1);
+        mInterface.registerUserSwitchObserver(
+                new UserSwitchObserver() {
+                    @Override
+                    public void onUserSwitchComplete(int newUserId) {
+                        if (userId == newUserId) {
+                            switchLatch.countDown();
+                        }
+                    }
+                }, ActivityManagerShellCommand.class.getName());
+
+        // Switch.
+        mInterface.switchUser(userId);
+
+        // Wait.
+        try {
+            switchLatch.await(USER_OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            getErrPrintWriter().println("Thread interrupted unexpectedly.");
+        }
+    }
+
     int runSwitchUser(PrintWriter pw) throws RemoteException {
         UserManager userManager = mInternal.mContext.getSystemService(UserManager.class);
         final int userSwitchable = userManager.getUserSwitchability();
@@ -1736,8 +1764,23 @@
             getErrPrintWriter().println("Error: " + userSwitchable);
             return -1;
         }
-        String user = getNextArgRequired();
-        mInterface.switchUser(Integer.parseInt(user));
+        boolean wait = false;
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            if ("-w".equals(opt)) {
+                wait = true;
+            } else {
+                getErrPrintWriter().println("Error: unknown option: " + opt);
+                return -1;
+            }
+        }
+
+        int userId = Integer.parseInt(getNextArgRequired());
+        if (wait) {
+            switchUserAndWaitForComplete(userId);
+        } else {
+            mInterface.switchUser(userId);
+        }
         return 0;
     }
 
@@ -2862,56 +2905,49 @@
         return 0;
     }
 
-    private void killPackage(String packageName, PrintWriter pw) throws RemoteException {
-        int uid = mPm.getPackageUid(packageName, 0, mUserId);
-        if (uid < 0) {
-            // uid is negative if the package wasn't found.
-            pw.println("Didn't find package " + packageName + " on device.");
-        } else {
-            pw.println("Killing package " + packageName + " (UID " + uid + ").");
-            final long origId = Binder.clearCallingIdentity();
-            mInterface.killUid(UserHandle.getAppId(uid),
-                    UserHandle.USER_ALL, "killPackage");
-            Binder.restoreCallingIdentity(origId);
-        }
-    }
-
     private int runCompat(PrintWriter pw) throws RemoteException {
-        final CompatConfig config = CompatConfig.get();
+        final PlatformCompat platformCompat = (PlatformCompat)
+                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
         String toggleValue = getNextArgRequired();
         long changeId;
         String changeIdString = getNextArgRequired();
         try {
             changeId = Long.parseLong(changeIdString);
         } catch (NumberFormatException e) {
-            changeId = config.lookupChangeId(changeIdString);
+            changeId = platformCompat.lookupChangeId(changeIdString);
         }
         if (changeId == -1) {
             pw.println("Unknown or invalid change: '" + changeIdString + "'.");
+            return -1;
         }
         String packageName = getNextArgRequired();
+        if (!platformCompat.isKnownChangeId(changeId)) {
+            pw.println("Warning! Change " + changeId + " is not known yet. Enabling/disabling it"
+                    + " could have no effect.");
+        }
+        ArraySet<Long> enabled = new ArraySet<>();
+        ArraySet<Long> disabled = new ArraySet<>();
         switch (toggleValue) {
             case "enable":
-                if (!config.addOverride(changeId, packageName, true)) {
-                    pw.println("Warning! Change " + changeId + " is not known yet. Enabling it"
-                            + " could have no effect.");
-                }
+                enabled.add(changeId);
                 pw.println("Enabled change " + changeId + " for " + packageName + ".");
-                killPackage(packageName, pw);
+                CompatibilityChangeConfig overrides =
+                        new CompatibilityChangeConfig(
+                                new Compatibility.ChangeConfig(enabled, disabled));
+                platformCompat.setOverrides(overrides, packageName);
                 return 0;
             case "disable":
-                if (!config.addOverride(changeId, packageName, false)) {
-                    pw.println("Warning! Change " + changeId + " is not known yet. Disabling it"
-                            + " could have no effect.");
-                }
+                disabled.add(changeId);
                 pw.println("Disabled change " + changeId + " for " + packageName + ".");
-                killPackage(packageName, pw);
+                overrides =
+                        new CompatibilityChangeConfig(
+                                new Compatibility.ChangeConfig(enabled, disabled));
+                platformCompat.setOverrides(overrides, packageName);
                 return 0;
             case "reset":
-                if (config.removeOverride(changeId, packageName)) {
+                if (platformCompat.clearOverride(changeId, packageName)) {
                     pw.println("Reset change " + changeId + " for " + packageName
                             + " to default value.");
-                    killPackage(packageName, pw);
                 } else {
                     pw.println("No override exists for changeId " + changeId + ".");
                 }
diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
index 5255316..0524f91 100644
--- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
@@ -445,7 +445,7 @@
         if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_RADIO) != 0) {
             // We were asked to fetch Telephony data.
             if (mTelephony == null) {
-                mTelephony = TelephonyManager.from(mContext);
+                mTelephony = mContext.getSystemService(TelephonyManager.class);
             }
 
             if (mTelephony != null) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index a47ea4f..8c60d0c 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -731,7 +731,7 @@
 
     public void notePhoneState(int state) {
         enforceCallingPermission();
-        int simState = TelephonyManager.getDefault().getSimState();
+        int simState = mContext.getSystemService(TelephonyManager.class).getSimState();
         synchronized (mStats) {
             mStats.notePhoneStateLocked(state, simState);
         }
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 4361676..31ceb38 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -384,7 +384,7 @@
 
         // We need to delay unlocking managed profiles until the parent user
         // is also unlocked.
-        if (mInjector.getUserManager().isManagedProfile(userId)) {
+        if (mInjector.getUserManager().isProfile(userId)) {
             final UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
             if (parent != null
                     && isUserRunning(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 09cbc5c..9a92778 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -2797,10 +2797,6 @@
                 setSystemAudioMute(mute);
                 AudioSystem.setMasterMute(mute);
                 sendMasterMuteUpdate(mute, flags);
-
-                Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION);
-                intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, mute);
-                sendBroadcastToAll(intent);
             }
         }
     }
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
new file mode 100644
index 0000000..22cb507
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -0,0 +1,228 @@
+/*
+ * 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.biometrics;
+
+
+// TODO(b/141025588): Create separate internal and external permissions for AuthService.
+// TODO(b/141025588): Get rid of the USE_FINGERPRINT permission.
+
+import static android.Manifest.permission.USE_BIOMETRIC;
+import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
+import static android.Manifest.permission.USE_FINGERPRINT;
+import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
+import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
+import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.biometrics.IAuthService;
+import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
+import android.hardware.biometrics.IBiometricService;
+import android.hardware.biometrics.IBiometricServiceReceiver;
+import android.hardware.face.IFaceService;
+import android.hardware.fingerprint.IFingerprintService;
+import android.hardware.iris.IIrisService;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.SystemService;
+import com.android.server.biometrics.face.FaceAuthenticator;
+import com.android.server.biometrics.fingerprint.FingerprintAuthenticator;
+import com.android.server.biometrics.iris.IrisAuthenticator;
+
+/**
+ * System service that provides an interface for authenticating with biometrics and
+ * PIN/pattern/password to BiometricPrompt and lock screen.
+ */
+public class AuthService extends SystemService {
+    private static final String TAG = "AuthService";
+    private static final boolean DEBUG = false;
+
+    private final boolean mHasFeatureFace;
+    private final boolean mHasFeatureFingerprint;
+    private final boolean mHasFeatureIris;
+    private final Injector mInjector;
+
+    private IBiometricService mBiometricService;
+    @VisibleForTesting
+    final IAuthService.Stub mImpl;
+
+    /**
+     * Class for injecting dependencies into AuthService.
+     * TODO(b/141025588): Replace with a dependency injection framework (e.g. Guice, Dagger).
+     */
+    @VisibleForTesting
+    public static class Injector {
+
+        /**
+         * Allows to mock BiometricService for testing.
+         */
+        @VisibleForTesting
+        public IBiometricService getBiometricService() {
+            return IBiometricService.Stub.asInterface(
+                    ServiceManager.getService(Context.BIOMETRIC_SERVICE));
+        }
+
+        /**
+         * Allows to stub publishBinderService(...) for testing.
+         */
+        @VisibleForTesting
+        public void publishBinderService(AuthService service, IAuthService.Stub impl) {
+            service.publishBinderService(Context.AUTH_SERVICE, impl);
+        }
+    }
+
+    private final class AuthServiceImpl extends IAuthService.Stub {
+        @Override
+        public void authenticate(IBinder token, long sessionId, int userId,
+                IBiometricServiceReceiver receiver, String opPackageName, Bundle bundle)
+                throws RemoteException {
+            final int callingUserId = UserHandle.getCallingUserId();
+
+            // In the BiometricServiceBase, do the AppOps and foreground check.
+            if (userId == callingUserId) {
+                // Check the USE_BIOMETRIC permission here.
+                checkPermission();
+            } else {
+                // Only allow internal clients to authenticate with a different userId
+                Slog.w(TAG, "User " + callingUserId + " is requesting authentication of userid: "
+                        + userId);
+                checkInternalPermission();
+            }
+
+            if (token == null || receiver == null || opPackageName == null || bundle == null) {
+                Slog.e(TAG, "Unable to authenticate, one or more null arguments");
+                return;
+            }
+
+            mBiometricService.authenticate(token, sessionId, userId, receiver, opPackageName,
+                    bundle);
+        }
+
+        @Override
+        public int canAuthenticate(String opPackageName, int userId) throws RemoteException {
+            final int callingUserId = UserHandle.getCallingUserId();
+            Slog.d(TAG, "canAuthenticate, userId: " + userId
+                    + ", callingUserId: " + callingUserId);
+
+            if (userId != callingUserId) {
+                checkInternalPermission();
+            } else {
+                checkPermission();
+            }
+            return mBiometricService.canAuthenticate(opPackageName, userId);
+        }
+
+        @Override
+        public boolean hasEnrolledBiometrics(int userId, String opPackageName)
+                throws RemoteException {
+            checkInternalPermission();
+            return mBiometricService.hasEnrolledBiometrics(userId, opPackageName);
+        }
+
+        @Override
+        public void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback)
+                throws RemoteException {
+            checkInternalPermission();
+            mBiometricService.registerEnabledOnKeyguardCallback(callback);
+        }
+
+        @Override
+        public void setActiveUser(int userId) throws RemoteException {
+            checkInternalPermission();
+            mBiometricService.setActiveUser(userId);
+        }
+
+        @Override
+        public void resetLockout(byte[] token) throws RemoteException {
+            checkInternalPermission();
+            mBiometricService.resetLockout(token);
+        }
+    }
+
+    public AuthService(Context context) {
+        this(context, new Injector());
+    }
+
+    public AuthService(Context context, Injector injector) {
+        super(context);
+
+        mInjector = injector;
+        mImpl = new AuthServiceImpl();
+        final PackageManager pm = context.getPackageManager();
+        mHasFeatureFace = pm.hasSystemFeature(PackageManager.FEATURE_FACE);
+        mHasFeatureFingerprint = pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
+        mHasFeatureIris = pm.hasSystemFeature(PackageManager.FEATURE_IRIS);
+    }
+
+    @Override
+    public void onStart() {
+        mBiometricService = mInjector.getBiometricService();
+
+        if (mHasFeatureFace) {
+            final FaceAuthenticator faceAuthenticator = new FaceAuthenticator(
+                    IFaceService.Stub.asInterface(ServiceManager.getService(Context.FACE_SERVICE)));
+            try {
+                // TODO(b/141025588): Pass down the real id, strength, and modality.
+                mBiometricService.registerAuthenticator(0, 0, TYPE_FACE, faceAuthenticator);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception", e);
+            }
+        }
+        if (mHasFeatureFingerprint) {
+            final FingerprintAuthenticator fingerprintAuthenticator = new FingerprintAuthenticator(
+                    IFingerprintService.Stub.asInterface(
+                            ServiceManager.getService(Context.FINGERPRINT_SERVICE)));
+            try {
+                // TODO(b/141025588): Pass down the real id, strength, and modality.
+                mBiometricService.registerAuthenticator(1, 0, TYPE_FINGERPRINT,
+                        fingerprintAuthenticator);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception", e);
+            }
+        }
+        if (mHasFeatureIris) {
+            final IrisAuthenticator irisAuthenticator = new IrisAuthenticator(
+                    IIrisService.Stub.asInterface(ServiceManager.getService(Context.IRIS_SERVICE)));
+            try {
+                // TODO(b/141025588): Pass down the real id, strength, and modality.
+                mBiometricService.registerAuthenticator(2, 0, TYPE_IRIS, irisAuthenticator);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception", e);
+            }
+        }
+        mInjector.publishBinderService(this, mImpl);
+    }
+
+    private void checkInternalPermission() {
+        getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL,
+                "Must have USE_BIOMETRIC_INTERNAL permission");
+    }
+
+    private void checkPermission() {
+        if (getContext().checkCallingOrSelfPermission(USE_FINGERPRINT)
+                != PackageManager.PERMISSION_GRANTED) {
+            getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC,
+                    "Must have USE_BIOMETRIC permission");
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 44c81fc..5d36793 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -42,8 +42,6 @@
 import android.hardware.biometrics.IBiometricService;
 import android.hardware.biometrics.IBiometricServiceReceiver;
 import android.hardware.biometrics.IBiometricServiceReceiverInternal;
-import android.hardware.face.IFaceService;
-import android.hardware.fingerprint.IFingerprintService;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
@@ -67,8 +65,6 @@
 import com.android.internal.os.SomeArgs;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.server.SystemService;
-import com.android.server.biometrics.face.FaceAuthenticator;
-import com.android.server.biometrics.fingerprint.FingerprintAuthenticator;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -215,9 +211,6 @@
     private final Injector mInjector;
     @VisibleForTesting
     final IBiometricService.Stub mImpl;
-    private final boolean mHasFeatureFace;
-    private final boolean mHasFeatureFingerprint;
-    private final boolean mHasFeatureIris;
     @VisibleForTesting
     final SettingObserver mSettingObserver;
     private final List<EnabledOnKeyguardCallback> mEnabledOnKeyguardCallbacks;
@@ -702,6 +695,8 @@
         @Override
         public void registerAuthenticator(int id, int strength, int modality,
                 IBiometricAuthenticator authenticator) {
+            checkInternalPermission();
+
             mAuthenticators.add(new AuthenticatorWrapper(id, strength, modality, authenticator));
         }
 
@@ -782,24 +777,6 @@
         }
 
         /**
-         * Allows to mock FaceAuthenticator for testing.
-         */
-        @VisibleForTesting
-        public IBiometricAuthenticator getFingerprintAuthenticator() {
-            return new FingerprintAuthenticator(IFingerprintService.Stub.asInterface(
-                    ServiceManager.getService(Context.FINGERPRINT_SERVICE)));
-        }
-
-        /**
-         * Allows to mock FaceAuthenticator for testing.
-         */
-        @VisibleForTesting
-        public IBiometricAuthenticator getFaceAuthenticator() {
-            return new FaceAuthenticator(
-                    IFaceService.Stub.asInterface(ServiceManager.getService(Context.FACE_SERVICE)));
-        }
-
-        /**
          * Allows to mock SettingObserver for testing.
          */
         @VisibleForTesting
@@ -853,11 +830,6 @@
         mSettingObserver = mInjector.getSettingObserver(context, mHandler,
                 mEnabledOnKeyguardCallbacks);
 
-        final PackageManager pm = context.getPackageManager();
-        mHasFeatureFace = pm.hasSystemFeature(PackageManager.FEATURE_FACE);
-        mHasFeatureFingerprint = pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
-        mHasFeatureIris = pm.hasSystemFeature(PackageManager.FEATURE_IRIS);
-
         try {
             injector.getActivityManagerService().registerUserSwitchObserver(
                     new UserSwitchObserver() {
@@ -875,28 +847,6 @@
 
     @Override
     public void onStart() {
-        // TODO(b/141025588): remove this code block once AuthService is integrated.
-        {
-            if (mHasFeatureFace) {
-                try {
-                    mImpl.registerAuthenticator(0, 0, TYPE_FACE, mInjector.getFaceAuthenticator());
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Remote exception", e);
-                }
-            }
-            if (mHasFeatureFingerprint) {
-                try {
-                    mImpl.registerAuthenticator(0, 0, TYPE_FINGERPRINT,
-                            mInjector.getFingerprintAuthenticator());
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Remote exception", e);
-                }
-            }
-            if (mHasFeatureIris) {
-                Slog.e(TAG, "Iris is not supported");
-            }
-        }
-
         mKeyStore = mInjector.getKeyStore();
         mStatusBarService = mInjector.getStatusBarService();
         mInjector.publishBinderService(this, mImpl);
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index d6ec22b..490cce3 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -43,13 +43,14 @@
 import java.util.Set;
 
 import javax.xml.datatype.DatatypeConfigurationException;
+
 /**
  * This class maintains state relating to platform compatibility changes.
  *
  * <p>It stores the default configuration for each change, and any per-package overrides that have
  * been configured.
  */
-public final class CompatConfig {
+final class CompatConfig {
 
     private static final String TAG = "CompatConfig";
 
@@ -61,13 +62,13 @@
     private final LongSparseArray<CompatChange> mChanges = new LongSparseArray<>();
 
     @VisibleForTesting
-    public CompatConfig() {
+    CompatConfig() {
     }
 
     /**
      * @return The static instance of this class to be used within the system server.
      */
-    public static CompatConfig get() {
+    static CompatConfig get() {
         return sInstance;
     }
 
@@ -77,7 +78,7 @@
      *
      * @param change The change to add. Any change with the same ID will be overwritten.
      */
-    public void addChange(CompatChange change) {
+    void addChange(CompatChange change) {
         synchronized (mChanges) {
             mChanges.put(change.getId(), change);
         }
@@ -89,10 +90,10 @@
      *
      * @param app The app in question
      * @return A sorted long array of change IDs. We use a primitive array to minimize memory
-     *      footprint: Every app process will store this array statically so we aim to reduce
-     *      overhead as much as possible.
+     * footprint: Every app process will store this array statically so we aim to reduce
+     * overhead as much as possible.
      */
-    public long[] getDisabledChanges(ApplicationInfo app) {
+    long[] getDisabledChanges(ApplicationInfo app) {
         LongArray disabled = new LongArray();
         synchronized (mChanges) {
             for (int i = 0; i < mChanges.size(); ++i) {
@@ -113,7 +114,7 @@
      * @param name Name of the change to look up
      * @return The change ID, or {@code -1} if no change with that name exists.
      */
-    public long lookupChangeId(String name) {
+    long lookupChangeId(String name) {
         synchronized (mChanges) {
             for (int i = 0; i < mChanges.size(); ++i) {
                 if (TextUtils.equals(mChanges.valueAt(i).getName(), name)) {
@@ -128,11 +129,11 @@
      * Find if a given change is enabled for a given application.
      *
      * @param changeId The ID of the change in question
-     * @param app App to check for
+     * @param app      App to check for
      * @return {@code true} if the change is enabled for this app. Also returns {@code true} if the
-     *      change ID is not known, as unknown changes are enabled by default.
+     * change ID is not known, as unknown changes are enabled by default.
      */
-    public boolean isChangeEnabled(long changeId, ApplicationInfo app) {
+    boolean isChangeEnabled(long changeId, ApplicationInfo app) {
         synchronized (mChanges) {
             CompatChange c = mChanges.get(changeId);
             if (c == null) {
@@ -150,14 +151,15 @@
      *
      * <p>Note, package overrides are not persistent and will be lost on system or runtime restart.
      *
-     * @param changeId The ID of the change to be overridden. Note, this call will succeed even if
-     *                 this change is not known; it will only have any effect if any code in the
-     *                 platform is gated on the ID given.
+     * @param changeId    The ID of the change to be overridden. Note, this call will succeed even
+     *                    if
+     *                    this change is not known; it will only have any effect if any code in the
+     *                    platform is gated on the ID given.
      * @param packageName The app package name to override the change for.
-     * @param enabled If the change should be enabled or disabled.
+     * @param enabled     If the change should be enabled or disabled.
      * @return {@code true} if the change existed before adding the override.
      */
-    public boolean addOverride(long changeId, String packageName, boolean enabled) {
+    boolean addOverride(long changeId, String packageName, boolean enabled) {
         boolean alreadyKnown = true;
         synchronized (mChanges) {
             CompatChange c = mChanges.get(changeId);
@@ -172,15 +174,27 @@
     }
 
     /**
+     * Check whether the change is known to the compat config.
+     *
+     * @return {@code true} if the change is known.
+     */
+    boolean isKnownChangeId(long changeId) {
+        synchronized (mChanges) {
+            CompatChange c = mChanges.get(changeId);
+            return c != null;
+        }
+    }
+
+    /**
      * Removes an override previously added via {@link #addOverride(long, String, boolean)}. This
      * restores the default behaviour for the given change and app, once any app processes have been
      * restarted.
      *
-     * @param changeId The ID of the change that was overridden.
+     * @param changeId    The ID of the change that was overridden.
      * @param packageName The app package name that was overridden.
      * @return {@code true} if an override existed;
      */
-    public boolean removeOverride(long changeId, String packageName) {
+    boolean removeOverride(long changeId, String packageName) {
         boolean overrideExists = false;
         synchronized (mChanges) {
             CompatChange c = mChanges.get(changeId);
@@ -191,22 +205,22 @@
         }
         return overrideExists;
     }
+
     /**
      * Overrides the enabled state for a given change and app. This method is intended to be used
      * *only* for debugging purposes.
      *
      * <p>Note, package overrides are not persistent and will be lost on system or runtime restart.
      *
-     * @param overrides list of overrides to default changes config.
+     * @param overrides   list of overrides to default changes config.
      * @param packageName app for which the overrides will be applied.
      */
-    public void addOverrides(
-            CompatibilityChangeConfig overrides, String packageName) {
+    void addOverrides(CompatibilityChangeConfig overrides, String packageName) {
         synchronized (mChanges) {
-            for (Long changeId: overrides.enabledChanges()) {
+            for (Long changeId : overrides.enabledChanges()) {
                 addOverride(changeId, packageName, true);
             }
-            for (Long changeId: overrides.disabledChanges()) {
+            for (Long changeId : overrides.disabledChanges()) {
                 addOverride(changeId, packageName, false);
             }
         }
@@ -221,7 +235,7 @@
      *
      * @param packageName The package for which the overrides should be purged.
      */
-    public void removePackageOverrides(String packageName) {
+    void removePackageOverrides(String packageName) {
         synchronized (mChanges) {
             for (int i = 0; i < mChanges.size(); ++i) {
                 mChanges.valueAt(i).removePackageOverride(packageName);
@@ -230,11 +244,11 @@
     }
 
     /**
-    * Dumps the current list of compatibility config information.
-    *
-    * @param pw The {@link PrintWriter} instance to which the information will be dumped.
-    */
-    public void dumpConfig(PrintWriter pw) {
+     * Dumps the current list of compatibility config information.
+     *
+     * @param pw The {@link PrintWriter} instance to which the information will be dumped.
+     */
+    void dumpConfig(PrintWriter pw) {
         synchronized (mChanges) {
             if (mChanges.size() == 0) {
                 pw.println("No compat overrides.");
@@ -252,10 +266,10 @@
      *
      * @param applicationInfo the {@link ApplicationInfo} for which the info should be dumped.
      * @return A {@link CompatibilityChangeConfig} which contains the compat config info for the
-     *         given app.
+     * given app.
      */
 
-    public CompatibilityChangeConfig getAppConfig(ApplicationInfo applicationInfo) {
+    CompatibilityChangeConfig getAppConfig(ApplicationInfo applicationInfo) {
         Set<Long> enabled = new HashSet<>();
         Set<Long> disabled = new HashSet<>();
         synchronized (mChanges) {
@@ -276,15 +290,15 @@
      *
      * @return An array of {@link CompatibilityChangeInfo} with the current changes.
      */
-    public CompatibilityChangeInfo[] dumpChanges() {
+    CompatibilityChangeInfo[] dumpChanges() {
         synchronized (mChanges) {
             CompatibilityChangeInfo[] changeInfos = new CompatibilityChangeInfo[mChanges.size()];
             for (int i = 0; i < mChanges.size(); ++i) {
                 CompatChange change = mChanges.valueAt(i);
                 changeInfos[i] = new CompatibilityChangeInfo(change.getId(),
-                                                      change.getName(),
-                                                      change.getEnableAfterTargetSdk(),
-                                                      change.getDisabled());
+                        change.getName(),
+                        change.getEnableAfterTargetSdk(),
+                        change.getDisabled());
             }
             return changeInfos;
         }
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 75e2d22..709f3f8 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -16,9 +16,13 @@
 
 package com.android.server.compat;
 
+import android.app.ActivityManager;
+import android.app.IActivityManager;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Slog;
 import android.util.StatsLog;
@@ -106,12 +110,26 @@
     @Override
     public void setOverrides(CompatibilityChangeConfig overrides, String packageName) {
         CompatConfig.get().addOverrides(overrides, packageName);
+        killPackage(packageName);
+    }
+
+    @Override
+    public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName) {
+        CompatConfig.get().addOverrides(overrides, packageName);
     }
 
     @Override
     public void clearOverrides(String packageName) {
         CompatConfig config = CompatConfig.get();
         config.removePackageOverrides(packageName);
+        killPackage(packageName);
+    }
+
+    @Override
+    public boolean clearOverride(long changeId, String packageName) {
+        boolean existed = CompatConfig.get().removeOverride(changeId, packageName);
+        killPackage(packageName);
+        return existed;
     }
 
     @Override
@@ -124,6 +142,39 @@
         return CompatConfig.get().dumpChanges();
     }
 
+    /**
+     * Check whether the change is known to the compat config.
+     * @param changeId
+     * @return {@code true} if the change is known.
+     */
+    public boolean isKnownChangeId(long changeId) {
+        return CompatConfig.get().isKnownChangeId(changeId);
+
+    }
+
+    /**
+     * Retrieves the set of disabled changes for a given app. Any change ID not in the returned
+     * array is by default enabled for the app.
+     *
+     * @param appInfo The app in question
+     * @return A sorted long array of change IDs. We use a primitive array to minimize memory
+     *      footprint: Every app process will store this array statically so we aim to reduce
+     *      overhead as much as possible.
+     */
+    public long[] getDisabledChanges(ApplicationInfo appInfo) {
+        return CompatConfig.get().getDisabledChanges(appInfo);
+    }
+
+    /**
+     * Look up a change ID by name.
+     *
+     * @param name Name of the change to look up
+     * @return The change ID, or {@code -1} if no change with that name exists.
+     */
+    public long lookupChangeId(String name) {
+        return CompatConfig.get().lookupChangeId(name);
+    }
+
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
@@ -151,4 +202,34 @@
     private void reportChange(long changeId, int uid, int state) {
         mChangeReporter.reportChange(uid, changeId, state);
     }
+
+    private void killPackage(String packageName) {
+        int uid = -1;
+        try {
+            uid = mContext.getPackageManager().getPackageUid(packageName, 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            Slog.w(TAG, "Didn't find package " + packageName + " on device.", e);
+            return;
+        }
+
+        Slog.d(TAG, "Killing package " + packageName + " (UID " + uid + ").");
+        killUid(UserHandle.getAppId(uid),
+                UserHandle.USER_ALL, "PlatformCompat overrides");
+    }
+
+    private void killUid(int appId, int userId, String reason) {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            IActivityManager am = ActivityManager.getService();
+            if (am != null) {
+                try {
+                    am.killUid(appId, userId, reason);
+                } catch (RemoteException e) {
+                    /* ignore - same process */
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index b3804c4..acedc36 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -286,8 +286,8 @@
 
     private void startStateMachineUpdaters(Handler handler) {
         mCarrierConfigChange.startListening();
-        TelephonyManager.from(mContext).listen(mPhoneStateListener,
-                PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
+        mContext.getSystemService(TelephonyManager.class).listen(
+                mPhoneStateListener, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(UsbManager.ACTION_USB_STATE);
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index 126beef..eea1980 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -34,6 +34,7 @@
 import android.hardware.SensorManager;
 import android.hardware.display.AmbientBrightnessDayStats;
 import android.hardware.display.BrightnessChangeEvent;
+import android.hardware.display.BrightnessConfiguration;
 import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerInternal;
@@ -125,6 +126,7 @@
     private static final int MSG_BRIGHTNESS_CHANGED = 1;
     private static final int MSG_STOP_SENSOR_LISTENER = 2;
     private static final int MSG_START_SENSOR_LISTENER = 3;
+    private static final int MSG_BRIGHTNESS_CONFIG_CHANGED = 4;
 
     private static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
 
@@ -158,6 +160,7 @@
     private boolean mColorSamplingEnabled;
     private int mNoFramesToSample;
     private float mFrameRate;
+    private BrightnessConfiguration mBrightnessConfiguration;
     // End of block of members that should only be accessed on the mBgHandler thread.
 
     private @UserIdInt int mCurrentUserId = UserHandle.USER_NULL;
@@ -202,6 +205,14 @@
         mBgHandler.obtainMessage(MSG_BACKGROUND_START, (Float) initialBrightness).sendToTarget();
     }
 
+    /**
+     * Update tracker with new brightness configuration.
+     */
+    public void setBrightnessConfiguration(BrightnessConfiguration brightnessConfiguration) {
+        mBgHandler.obtainMessage(MSG_BRIGHTNESS_CONFIG_CHANGED,
+                brightnessConfiguration).sendToTarget();
+    }
+
     private void backgroundStart(float initialBrightness) {
         readEvents();
         readAmbientBrightnessStats();
@@ -759,7 +770,9 @@
     private void enableColorSampling() {
         if (!mInjector.isBrightnessModeAutomatic(mContentResolver)
                 || !mInjector.isInteractive(mContext)
-                || mColorSamplingEnabled) {
+                || mColorSamplingEnabled
+                || mBrightnessConfiguration == null
+                || !mBrightnessConfiguration.shouldCollectColorSamples()) {
             return;
         }
 
@@ -977,6 +990,18 @@
                     stopSensorListener();
                     disableColorSampling();
                     break;
+                case MSG_BRIGHTNESS_CONFIG_CHANGED:
+                    mBrightnessConfiguration = (BrightnessConfiguration) msg.obj;
+                    boolean shouldCollectColorSamples =
+                            mBrightnessConfiguration != null
+                                    && mBrightnessConfiguration.shouldCollectColorSamples();
+                    if (shouldCollectColorSamples && !mColorSamplingEnabled) {
+                        enableColorSampling();
+                    } else if (!shouldCollectColorSamples && mColorSamplingEnabled) {
+                        disableColorSampling();
+                    }
+                    break;
+
             }
         }
     }
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 5804fc8..e42545e 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -931,6 +931,10 @@
                     autoBrightnessAdjustmentChanged, mPowerRequest.policy);
         }
 
+        if (mBrightnessTracker != null) {
+            mBrightnessTracker.setBrightnessConfiguration(mBrightnessConfiguration);
+        }
+
         // Apply auto-brightness.
         boolean slowChange = false;
         if (brightness < 0) {
diff --git a/services/core/java/com/android/server/display/WifiDisplayController.java b/services/core/java/com/android/server/display/WifiDisplayController.java
index d9d46b8..283a78b 100644
--- a/services/core/java/com/android/server/display/WifiDisplayController.java
+++ b/services/core/java/com/android/server/display/WifiDisplayController.java
@@ -16,8 +16,6 @@
 
 package com.android.server.display;
 
-import com.android.internal.util.DumpUtils;
-
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -36,16 +34,18 @@
 import android.net.wifi.p2p.WifiP2pDeviceList;
 import android.net.wifi.p2p.WifiP2pGroup;
 import android.net.wifi.p2p.WifiP2pManager;
-import android.net.wifi.p2p.WifiP2pWfdInfo;
 import android.net.wifi.p2p.WifiP2pManager.ActionListener;
 import android.net.wifi.p2p.WifiP2pManager.Channel;
 import android.net.wifi.p2p.WifiP2pManager.GroupInfoListener;
 import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
+import android.net.wifi.p2p.WifiP2pWfdInfo;
 import android.os.Handler;
 import android.provider.Settings;
 import android.util.Slog;
 import android.view.Surface;
 
+import com.android.internal.util.DumpUtils;
+
 import java.io.PrintWriter;
 import java.net.Inet4Address;
 import java.net.InetAddress;
@@ -292,11 +292,11 @@
 
                 WifiP2pWfdInfo wfdInfo = new WifiP2pWfdInfo();
                 wfdInfo.setWfdEnabled(true);
-                wfdInfo.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE);
+                wfdInfo.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE);
                 wfdInfo.setSessionAvailable(true);
                 wfdInfo.setControlPort(DEFAULT_CONTROL_PORT);
                 wfdInfo.setMaxThroughput(MAX_THROUGHPUT);
-                mWifiP2pManager.setWFDInfo(mWifiP2pChannel, wfdInfo, new ActionListener() {
+                mWifiP2pManager.setWfdInfo(mWifiP2pChannel, wfdInfo, new ActionListener() {
                     @Override
                     public void onSuccess() {
                         if (DEBUG) {
@@ -324,7 +324,7 @@
             if (mWfdEnabled || mWfdEnabling) {
                 WifiP2pWfdInfo wfdInfo = new WifiP2pWfdInfo();
                 wfdInfo.setWfdEnabled(false);
-                mWifiP2pManager.setWFDInfo(mWifiP2pChannel, wfdInfo, new ActionListener() {
+                mWifiP2pManager.setWfdInfo(mWifiP2pChannel, wfdInfo, new ActionListener() {
                     @Override
                     public void onSuccess() {
                         if (DEBUG) {
@@ -508,7 +508,8 @@
                 Slog.d(TAG, "updateDesiredDevice: new information "
                         + describeWifiP2pDevice(device));
             }
-            mDesiredDevice.update(device);
+            mDesiredDevice.updateSupplicantDetails(device);
+            mDesiredDevice.status = device.status;
             if (mAdvertisedDisplay != null
                     && mAdvertisedDisplay.getDeviceAddress().equals(address)) {
                 readvertiseDisplay(createWifiDisplay(mDesiredDevice));
@@ -694,7 +695,7 @@
             config.wps = wps;
             config.deviceAddress = mConnectingDevice.deviceAddress;
             // Helps with STA & P2P concurrency
-            config.groupOwnerIntent = WifiP2pConfig.MIN_GROUP_OWNER_INTENT;
+            config.groupOwnerIntent = WifiP2pConfig.GROUP_OWNER_INTENT_MIN;
 
             WifiDisplay display = createWifiDisplay(mConnectingDevice);
             advertiseDisplay(display, null, 0, 0, 0);
@@ -824,6 +825,10 @@
         requestPeers();
     }
 
+    private static boolean contains(WifiP2pGroup group, WifiP2pDevice device) {
+        return group.getOwner().equals(device) || group.getClientList().contains(device);
+    }
+
     private void handleConnectionChanged(NetworkInfo networkInfo) {
         mNetworkInfo = networkInfo;
         if (mWfdEnabled && networkInfo.isConnected()) {
@@ -835,7 +840,7 @@
                             Slog.d(TAG, "Received group info: " + describeWifiP2pGroup(info));
                         }
 
-                        if (mConnectingDevice != null && !info.contains(mConnectingDevice)) {
+                        if (mConnectingDevice != null && !contains(info, mConnectingDevice)) {
                             Slog.i(TAG, "Aborting connection to Wifi display because "
                                     + "the current P2P group does not contain the device "
                                     + "we expected to find: " + mConnectingDevice.deviceName
@@ -844,7 +849,7 @@
                             return;
                         }
 
-                        if (mDesiredDevice != null && !info.contains(mDesiredDevice)) {
+                        if (mDesiredDevice != null && !contains(info, mDesiredDevice)) {
                             disconnect();
                             return;
                         }
@@ -1038,14 +1043,15 @@
     }
 
     private static boolean isWifiDisplay(WifiP2pDevice device) {
-        return device.wfdInfo != null
-                && device.wfdInfo.isWfdEnabled()
-                && isPrimarySinkDeviceType(device.wfdInfo.getDeviceType());
+        WifiP2pWfdInfo wfdInfo = device.getWfdInfo();
+        return wfdInfo != null
+                && wfdInfo.isWfdEnabled()
+                && isPrimarySinkDeviceType(wfdInfo.getDeviceType());
     }
 
     private static boolean isPrimarySinkDeviceType(int deviceType) {
-        return deviceType == WifiP2pWfdInfo.PRIMARY_SINK
-                || deviceType == WifiP2pWfdInfo.SOURCE_OR_PRIMARY_SINK;
+        return deviceType == WifiP2pWfdInfo.DEVICE_TYPE_PRIMARY_SINK
+                || deviceType == WifiP2pWfdInfo.DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK;
     }
 
     private static String describeWifiP2pDevice(WifiP2pDevice device) {
@@ -1058,7 +1064,7 @@
 
     private static WifiDisplay createWifiDisplay(WifiP2pDevice device) {
         return new WifiDisplay(device.deviceAddress, device.deviceName, null,
-                true, device.wfdInfo.isSessionAvailable(), false);
+                true, device.getWfdInfo().isSessionAvailable(), false);
     }
 
     private final BroadcastReceiver mWifiP2pReceiver = new BroadcastReceiver() {
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index fb57d69..637bcae 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -301,6 +301,7 @@
 
     // Timeout when holding wakelocks for downloading PSDS data.
     private static final long DOWNLOAD_PSDS_DATA_TIMEOUT_MS = 60 * 1000;
+    private static final long WAKELOCK_TIMEOUT_MILLIS = 30 * 1000;
 
     private final ExponentialBackOff mPsdsBackOff = new ExponentialBackOff(RETRY_INTERVAL,
             MAX_RETRY_INTERVAL);
@@ -901,13 +902,8 @@
                 if (mDownloadPsdsWakeLock.isHeld()) {
                     // This wakelock may have time-out, if a timeout was specified.
                     // Catch (and ignore) any timeout exceptions.
-                    try {
-                        mDownloadPsdsWakeLock.release();
-                        if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadPsdsData()");
-                    } catch (Exception e) {
-                        Log.i(TAG, "Wakelock timeout & release race exception in "
-                                + "handleDownloadPsdsData()", e);
-                    }
+                    mDownloadPsdsWakeLock.release();
+                    if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadPsdsData()");
                 } else {
                     Log.e(TAG, "WakeLock expired before release in "
                             + "handleDownloadPsdsData()");
@@ -1482,39 +1478,35 @@
             Log.v(TAG, "SV count: " + info.mSvCount);
         }
         // Calculate number of satellites used in fix.
+        GnssStatus gnssStatus = GnssStatus.wrap(
+                info.mSvCount,
+                info.mSvidWithFlags,
+                info.mCn0s,
+                info.mSvElevations,
+                info.mSvAzimuths,
+                info.mSvCarrierFreqs);
         int usedInFixCount = 0;
         int maxCn0 = 0;
         int meanCn0 = 0;
-        for (int i = 0; i < info.mSvCount; i++) {
-            if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
+        for (int i = 0; i < gnssStatus.getSatelliteCount(); i++) {
+            if (gnssStatus.usedInFix(i)) {
                 ++usedInFixCount;
-                if (info.mCn0s[i] > maxCn0) {
-                    maxCn0 = (int) info.mCn0s[i];
+                if (gnssStatus.getCn0DbHz(i) > maxCn0) {
+                    maxCn0 = (int) gnssStatus.getCn0DbHz(i);
                 }
-                meanCn0 += info.mCn0s[i];
+                meanCn0 += gnssStatus.getCn0DbHz(i);
+                mGnssMetrics.logConstellationType(gnssStatus.getConstellationType(i));
             }
             if (VERBOSE) {
-                Log.v(TAG, "svid: " + (info.mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
-                        " cn0: " + info.mCn0s[i] +
-                        " elev: " + info.mSvElevations[i] +
-                        " azimuth: " + info.mSvAzimuths[i] +
-                        " carrier frequency: " + info.mSvCarrierFreqs[i] +
-                        ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
-                                ? "  " : " E") +
-                        ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
-                                ? "  " : " A") +
-                        ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
-                                ? "" : "U") +
-                        ((info.mSvidWithFlags[i] &
-                                GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
-                                ? "" : "F"));
-            }
-
-            if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
-                int constellationType =
-                        (info.mSvidWithFlags[i] >> GnssStatus.CONSTELLATION_TYPE_SHIFT_WIDTH)
-                                & GnssStatus.CONSTELLATION_TYPE_MASK;
-                mGnssMetrics.logConstellationType(constellationType);
+                Log.v(TAG, "svid: " + gnssStatus.getSvid(i)
+                        + " cn0: " + gnssStatus.getCn0DbHz(i)
+                        + " elev: " + gnssStatus.getElevationDegrees(i)
+                        + " azimuth: " + gnssStatus.getAzimuthDegrees(i)
+                        + " carrier frequency: " + gnssStatus.getCn0DbHz(i)
+                        + (gnssStatus.hasEphemerisData(i) ? " E" : "  ")
+                        + (gnssStatus.hasAlmanacData(i) ? " A" : "  ")
+                        + (gnssStatus.usedInFix(i) ? "U" : "")
+                        + (gnssStatus.hasCarrierFrequencyHz(i) ? "F" : ""));
             }
         }
         if (usedInFixCount > 0) {
@@ -1523,7 +1515,7 @@
         // return number of sats used in fix instead of total reported
         mLocationExtras.set(usedInFixCount, meanCn0, maxCn0);
 
-        mGnssMetrics.logSvStatus(info.mSvCount, info.mSvidWithFlags, info.mSvCarrierFreqs);
+        mGnssMetrics.logSvStatus(gnssStatus);
     }
 
     @NativeEntryPoint
@@ -2013,7 +2005,7 @@
         // hold a wake lock until this message is delivered
         // note that this assumes the message will not be removed from the queue before
         // it is handled (otherwise the wake lock would be leaked).
-        mWakeLock.acquire();
+        mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS);
         if (DEBUG) {
             Log.d(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg
                     + ", " + obj + ")");
diff --git a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
index 2e72fbd..93227bd 100644
--- a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
+++ b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
@@ -321,7 +321,11 @@
 
     private void handleUpdateNetworkState(Network network, boolean isConnected,
             NetworkCapabilities capabilities) {
-        boolean networkAvailable = isConnected && TelephonyManager.getDefault().getDataEnabled();
+        boolean networkAvailable = false;
+        TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
+        if (telephonyManager != null) {
+            networkAvailable = isConnected && telephonyManager.getDataEnabled();
+        }
         NetworkAttributes networkAttributes = updateTrackedNetworksState(isConnected, network,
                 capabilities);
         String apn = networkAttributes.mApn;
diff --git a/services/core/java/com/android/server/location/NtpTimeHelper.java b/services/core/java/com/android/server/location/NtpTimeHelper.java
index 296b500..67841ac 100644
--- a/services/core/java/com/android/server/location/NtpTimeHelper.java
+++ b/services/core/java/com/android/server/location/NtpTimeHelper.java
@@ -181,11 +181,7 @@
                 mHandler.postDelayed(this::retrieveAndInjectNtpTime, delay);
             }
         }
-        try {
-            // release wake lock held by task
-            mWakeLock.release();
-        } catch (Exception e) {
-            // This happens when the WakeLock is already released.
-        }
+        // release wake lock held by task
+        mWakeLock.release();
     }
 }
diff --git a/services/core/java/com/android/server/media/MediaRoute2Provider.java b/services/core/java/com/android/server/media/MediaRoute2Provider.java
new file mode 100644
index 0000000..91c9253
--- /dev/null
+++ b/services/core/java/com/android/server/media/MediaRoute2Provider.java
@@ -0,0 +1,82 @@
+/*
+ * 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.server.media;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.media.MediaRoute2Info;
+import android.media.MediaRoute2ProviderInfo;
+
+import java.util.Objects;
+
+abstract class MediaRoute2Provider {
+    final ComponentName mComponentName;
+    final String mUniqueId;
+
+    private Callback mCallback;
+    private MediaRoute2ProviderInfo mProviderInfo;
+
+    MediaRoute2Provider(@NonNull ComponentName componentName) {
+        mComponentName = Objects.requireNonNull(componentName, "Component name must not be null.");
+        mUniqueId = componentName.flattenToShortString();
+    }
+
+    public void setCallback(MediaRoute2ProviderProxy.Callback callback) {
+        mCallback = callback;
+    }
+
+    public abstract void requestSelectRoute(String packageName, String routeId, int seq);
+    public abstract void unselectRoute(String packageName, String routeId);
+    public abstract void sendControlRequest(MediaRoute2Info route, Intent request);
+    public abstract void requestSetVolume(MediaRoute2Info route, int volume);
+    public abstract void requestUpdateVolume(MediaRoute2Info route, int delta);
+
+    @NonNull
+    public String getUniqueId() {
+        return mUniqueId;
+    }
+
+    @Nullable
+    public MediaRoute2ProviderInfo getProviderInfo() {
+        return mProviderInfo;
+    }
+
+    void setAndNotifyProviderInfo(MediaRoute2ProviderInfo info) {
+        //TODO: check if info is not updated
+        if (info == null) {
+            mProviderInfo = null;
+        } else {
+            mProviderInfo = new MediaRoute2ProviderInfo.Builder(info)
+                    .setUniqueId(mUniqueId)
+                    .build();
+        }
+        if (mCallback != null) {
+            mCallback.onProviderStateChanged(this);
+        }
+    }
+
+    public boolean hasComponentName(String packageName, String className) {
+        return mComponentName.getPackageName().equals(packageName)
+                && mComponentName.getClassName().equals(className);
+    }
+
+    public interface Callback {
+        void onProviderStateChanged(MediaRoute2Provider provider);
+    }
+}
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
index 51a0df3..3b6580a 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
@@ -17,7 +17,6 @@
 package com.android.server.media;
 
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -42,20 +41,14 @@
 /**
  * Maintains a connection to a particular media route provider service.
  */
-final class MediaRoute2ProviderProxy implements ServiceConnection {
+final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements ServiceConnection {
     private static final String TAG = "MR2ProviderProxy";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final Context mContext;
-    private final ComponentName mComponentName;
-    private final String mUniqueId;
     private final int mUserId;
     private final Handler mHandler;
 
-    private Callback mCallback;
-
-    private MediaRoute2ProviderInfo mProviderInfo;
-
     // Connection state
     private boolean mRunning;
     private boolean mBound;
@@ -64,9 +57,8 @@
 
     MediaRoute2ProviderProxy(@NonNull Context context, @NonNull ComponentName componentName,
             int userId) {
+        super(componentName);
         mContext = Objects.requireNonNull(context, "Context must not be null.");
-        mComponentName = Objects.requireNonNull(componentName, "Component name must not be null.");
-        mUniqueId = componentName.flattenToShortString();
         mUserId = userId;
         mHandler = new Handler();
     }
@@ -80,10 +72,7 @@
         pw.println(prefix + "  mConnectionReady=" + mConnectionReady);
     }
 
-    public void setCallback(Callback callback) {
-        mCallback = callback;
-    }
-
+    @Override
     public void requestSelectRoute(String packageName, String routeId, int seq) {
         if (mConnectionReady) {
             mActiveConnection.requestSelectRoute(packageName, routeId, seq);
@@ -91,6 +80,7 @@
         }
     }
 
+    @Override
     public void unselectRoute(String packageName, String routeId) {
         if (mConnectionReady) {
             mActiveConnection.unselectRoute(packageName, routeId);
@@ -98,6 +88,7 @@
         }
     }
 
+    @Override
     public void sendControlRequest(MediaRoute2Info route, Intent request) {
         if (mConnectionReady) {
             mActiveConnection.sendControlRequest(route.getId(), request);
@@ -105,6 +96,7 @@
         }
     }
 
+    @Override
     public void requestSetVolume(MediaRoute2Info route, int volume) {
         if (mConnectionReady) {
             mActiveConnection.requestSetVolume(route.getId(), volume);
@@ -112,6 +104,7 @@
         }
     }
 
+    @Override
     public void requestUpdateVolume(MediaRoute2Info route, int delta) {
         if (mConnectionReady) {
             mActiveConnection.requestUpdateVolume(route.getId(), delta);
@@ -119,16 +112,6 @@
         }
     }
 
-    @NonNull
-    public String getUniqueId() {
-        return mUniqueId;
-    }
-
-    @Nullable
-    public MediaRoute2ProviderInfo getProviderInfo() {
-        return mProviderInfo;
-    }
-
     public boolean hasComponentName(String packageName, String className) {
         return mComponentName.getPackageName().equals(packageName)
                 && mComponentName.getClassName().equals(className);
@@ -270,20 +253,6 @@
         setAndNotifyProviderInfo(info);
     }
 
-    private void setAndNotifyProviderInfo(MediaRoute2ProviderInfo info) {
-        //TODO: check if info is not updated
-        if (info == null) {
-            mProviderInfo = null;
-        } else {
-            mProviderInfo = new MediaRoute2ProviderInfo.Builder(info)
-                .setUniqueId(mUniqueId)
-                .build();
-        }
-        if (mCallback != null) {
-            mCallback.onProviderStateChanged(MediaRoute2ProviderProxy.this);
-        }
-    }
-
     private void disconnect() {
         if (mActiveConnection != null) {
             mConnectionReady = false;
@@ -298,10 +267,6 @@
         return "Service connection " + mComponentName.flattenToShortString();
     }
 
-    public interface Callback {
-        void onProviderStateChanged(@NonNull MediaRoute2ProviderProxy provider);
-    }
-
     private final class Connection implements DeathRecipient {
         private final IMediaRoute2Provider mProvider;
         private final ProviderClient mClient;
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index adfb9cb..7820cd7 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -728,14 +728,15 @@
 
     static final class UserHandler extends Handler implements
             MediaRoute2ProviderWatcher.Callback,
-            MediaRoute2ProviderProxy.Callback {
+            MediaRoute2Provider.Callback {
 
         private final WeakReference<MediaRouter2ServiceImpl> mServiceRef;
         private final UserRecord mUserRecord;
         private final MediaRoute2ProviderWatcher mWatcher;
 
         //TODO: Make this thread-safe.
-        private final ArrayList<MediaRoute2ProviderProxy> mMediaProviders =
+        private final SystemMediaRoute2Provider mSystemProvider;
+        private final ArrayList<MediaRoute2Provider> mMediaProviders =
                 new ArrayList<>();
         private final List<MediaRoute2ProviderInfo> mProviderInfos = new ArrayList<>();
 
@@ -746,6 +747,8 @@
             super(Looper.getMainLooper(), null, true);
             mServiceRef = new WeakReference<>(service);
             mUserRecord = userRecord;
+            mSystemProvider = new SystemMediaRoute2Provider(service.mContext, this);
+            mMediaProviders.add(mSystemProvider);
             mWatcher = new MediaRoute2ProviderWatcher(service.mContext, this,
                     this, mUserRecord.mUserId);
         }
@@ -777,7 +780,7 @@
         }
 
         @Override
-        public void onProviderStateChanged(@NonNull MediaRoute2ProviderProxy provider) {
+        public void onProviderStateChanged(@NonNull MediaRoute2Provider provider) {
             sendMessage(PooledLambda.obtainMessage(UserHandler::updateProvider, this, provider));
         }
 
@@ -790,7 +793,7 @@
                     controlHints, seq));
         }
 
-        private void updateProvider(MediaRoute2ProviderProxy provider) {
+        private void updateProvider(MediaRoute2Provider provider) {
             int providerIndex = getProviderInfoIndex(provider.getUniqueId());
             MediaRoute2ProviderInfo providerInfo = provider.getProviderInfo();
             MediaRoute2ProviderInfo prevInfo =
@@ -954,7 +957,7 @@
 
         private void requestSelectRoute(String clientPackageName, MediaRoute2Info route, int seq) {
             if (route != null) {
-                MediaRoute2ProviderProxy provider = findProvider(route.getProviderId());
+                MediaRoute2Provider provider = findProvider(route.getProviderId());
                 if (provider == null) {
                     Slog.w(TAG, "Ignoring to select route of unknown provider " + route);
                 } else {
@@ -965,7 +968,7 @@
 
         private void unselectRoute(String clientPackageName, MediaRoute2Info route) {
             if (route != null) {
-                MediaRoute2ProviderProxy provider = findProvider(route.getProviderId());
+                MediaRoute2Provider provider = findProvider(route.getProviderId());
                 if (provider == null) {
                     Slog.w(TAG, "Ignoring to unselect route of unknown provider " + route);
                 } else {
@@ -975,21 +978,21 @@
         }
 
         private void sendControlRequest(MediaRoute2Info route, Intent request) {
-            final MediaRoute2ProviderProxy provider = findProvider(route.getProviderId());
+            final MediaRoute2Provider provider = findProvider(route.getProviderId());
             if (provider != null) {
                 provider.sendControlRequest(route, request);
             }
         }
 
         private void requestSetVolume(MediaRoute2Info route, int volume) {
-            final MediaRoute2ProviderProxy provider = findProvider(route.getProviderId());
+            final MediaRoute2Provider provider = findProvider(route.getProviderId());
             if (provider != null) {
                 provider.requestSetVolume(route, volume);
             }
         }
 
         private void requestUpdateVolume(MediaRoute2Info route, int delta) {
-            final MediaRoute2ProviderProxy provider = findProvider(route.getProviderId());
+            final MediaRoute2Provider provider = findProvider(route.getProviderId());
             if (provider != null) {
                 provider.requestUpdateVolume(route, delta);
             }
@@ -1153,8 +1156,8 @@
             }
         }
 
-        private MediaRoute2ProviderProxy findProvider(String providerId) {
-            for (MediaRoute2ProviderProxy provider : mMediaProviders) {
+        private MediaRoute2Provider findProvider(String providerId) {
+            for (MediaRoute2Provider provider : mMediaProviders) {
                 if (TextUtils.equals(provider.getUniqueId(), providerId)) {
                     return provider;
                 }
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
new file mode 100644
index 0000000..13ded61
--- /dev/null
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -0,0 +1,202 @@
+/*
+ * 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.server.media;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.media.AudioManager;
+import android.media.AudioRoutesInfo;
+import android.media.IAudioRoutesObserver;
+import android.media.IAudioService;
+import android.media.MediaRoute2Info;
+import android.media.MediaRoute2ProviderInfo;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.R;
+
+/**
+ * Provides routes for local playbacks such as phone speaker, wired headset, or Bluetooth speakers.
+ */
+class SystemMediaRoute2Provider extends MediaRoute2Provider {
+    private static final String TAG = "MR2SystemProvider";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private static final String DEFAULT_ROUTE_ID = "DEFAULT_ROUTE";
+    private static final String BLUETOOTH_ROUTE_ID = "BLUETOOTH_ROUTE";
+
+    // TODO: Move these to a proper place
+    public static final String CATEGORY_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO";
+    public static final String CATEGORY_LIVE_VIDEO = "android.media.intent.category.LIVE_VIDEO";
+
+    private final AudioManager mAudioManager;
+    private final IAudioService mAudioService;
+    private final Handler mHandler;
+    private final Context mContext;
+
+    private static ComponentName sComponentName = new ComponentName(
+            SystemMediaRoute2Provider.class.getPackageName$(),
+            SystemMediaRoute2Provider.class.getName());
+
+    //TODO: Clean up these when audio manager support multiple bt devices
+    MediaRoute2Info mDefaultRoute;
+    MediaRoute2Info mBluetoothA2dpRoute;
+    final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo();
+
+    final IAudioRoutesObserver.Stub mAudioRoutesObserver = new IAudioRoutesObserver.Stub() {
+        @Override
+        public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) {
+            mHandler.post(new Runnable() {
+                @Override public void run() {
+                    updateAudioRoutes(newRoutes);
+                }
+            });
+        }
+    };
+
+    SystemMediaRoute2Provider(Context context, Callback callback) {
+        super(sComponentName);
+        setCallback(callback);
+
+        mContext = context;
+        mHandler = new Handler(Looper.getMainLooper());
+
+        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        mAudioService = IAudioService.Stub.asInterface(
+                ServiceManager.getService(Context.AUDIO_SERVICE));
+
+        initializeRoutes();
+    }
+
+    //TODO: implement method
+    @Override
+    public void requestSelectRoute(@NonNull String packageName, @NonNull String routeId, int seq) {
+        try {
+            mAudioService.setBluetoothA2dpOn(
+                    !TextUtils.equals(routeId, mDefaultRoute.getId()));
+        } catch (RemoteException ex) {
+            Log.e(TAG, "Error changing Bluetooth A2DP route");
+        }
+    }
+
+    //TODO: implement method
+    @Override
+    public void unselectRoute(@NonNull String packageName, @NonNull String routeId) {
+        // does nothing..?
+    }
+
+    //TODO: implement method
+    @Override
+    public void sendControlRequest(@NonNull MediaRoute2Info route, @NonNull Intent request) {
+    }
+
+    //TODO: implement method
+    @Override
+    public void requestSetVolume(MediaRoute2Info route, int volume) {
+    }
+
+    //TODO: implement method
+    @Override
+    public void requestUpdateVolume(MediaRoute2Info route, int delta) {
+    }
+
+    void initializeRoutes() {
+        //TODO: adds necessary info
+        mDefaultRoute = new MediaRoute2Info.Builder(
+                DEFAULT_ROUTE_ID,
+                mContext.getResources().getText(R.string.default_audio_route_name).toString())
+                .setVolumeHandling(mAudioManager.isVolumeFixed()
+                        ? MediaRoute2Info.PLAYBACK_VOLUME_FIXED
+                        : MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
+                .setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
+                .setVolume(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
+                .addSupportedCategory(CATEGORY_LIVE_AUDIO)
+                .addSupportedCategory(CATEGORY_LIVE_VIDEO)
+                .build();
+
+        AudioRoutesInfo newAudioRoutes = null;
+        try {
+            newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver);
+        } catch (RemoteException e) {
+        }
+        if (newAudioRoutes != null) {
+            // This will select the active BT route if there is one and the current
+            // selected route is the default system route, or if there is no selected
+            // route yet.
+            updateAudioRoutes(newAudioRoutes);
+        }
+
+        publishRoutes();
+    }
+
+    void updateAudioRoutes(AudioRoutesInfo newRoutes) {
+        int name = R.string.default_audio_route_name;
+        mCurAudioRoutesInfo.mainType = newRoutes.mainType;
+        if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HEADPHONES) != 0
+                || (newRoutes.mainType & AudioRoutesInfo.MAIN_HEADSET) != 0) {
+            name = com.android.internal.R.string.default_audio_route_name_headphones;
+        } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) {
+            name = com.android.internal.R.string.default_audio_route_name_dock_speakers;
+        } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HDMI) != 0) {
+            name = com.android.internal.R.string.default_audio_route_name_hdmi;
+        } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_USB) != 0) {
+            name = com.android.internal.R.string.default_audio_route_name_usb;
+        }
+
+        mDefaultRoute = new MediaRoute2Info.Builder(
+                DEFAULT_ROUTE_ID, mContext.getResources().getText(name).toString())
+                .setVolumeHandling(mAudioManager.isVolumeFixed()
+                        ? MediaRoute2Info.PLAYBACK_VOLUME_FIXED
+                        : MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
+                .setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
+                .setVolume(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
+                .addSupportedCategory(CATEGORY_LIVE_AUDIO)
+                .addSupportedCategory(CATEGORY_LIVE_VIDEO)
+                .build();
+
+        if (!TextUtils.equals(newRoutes.bluetoothName, mCurAudioRoutesInfo.bluetoothName)) {
+            mCurAudioRoutesInfo.bluetoothName = newRoutes.bluetoothName;
+            if (mCurAudioRoutesInfo.bluetoothName != null) {
+                //TODO: mark as bluetooth once MediaRoute2Info has device type
+                mBluetoothA2dpRoute = new MediaRoute2Info.Builder(BLUETOOTH_ROUTE_ID,
+                        mCurAudioRoutesInfo.bluetoothName.toString())
+                        .setDescription(mContext.getResources().getText(
+                                R.string.bluetooth_a2dp_audio_route_name).toString())
+                        .addSupportedCategory(CATEGORY_LIVE_AUDIO)
+                        .build();
+            } else if (mBluetoothA2dpRoute != null) {
+                mBluetoothA2dpRoute = null;
+            }
+        }
+
+        publishRoutes();
+    }
+    void publishRoutes() {
+        MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder()
+                .addRoute(mDefaultRoute);
+        if (mBluetoothA2dpRoute != null) {
+            builder.addRoute(mBluetoothA2dpRoute);
+        }
+        setAndNotifyProviderInfo(builder.build());
+    }
+}
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 41806ca..08c9426 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -337,7 +337,7 @@
                 powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
 
         NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
-                wakeLock, getDefaultClock(), TelephonyManager.getDefault(),
+                wakeLock, getDefaultClock(), context.getSystemService(TelephonyManager.class),
                 new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(),
                 new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir());
         service.registerLocalService();
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5b39fb6..ec53157 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -7724,7 +7724,7 @@
     }
 
     private void listenForCallState() {
-        TelephonyManager.from(getContext()).listen(new PhoneStateListener() {
+        getContext().getSystemService(TelephonyManager.class).listen(new PhoneStateListener() {
             @Override
             public void onCallStateChanged(int state, String incomingNumber) {
                 if (mCallState == state) return;
diff --git a/services/core/java/com/android/server/os/DeviceIdentifiersPolicyService.java b/services/core/java/com/android/server/os/DeviceIdentifiersPolicyService.java
index 9c1ac34..947405e 100644
--- a/services/core/java/com/android/server/os/DeviceIdentifiersPolicyService.java
+++ b/services/core/java/com/android/server/os/DeviceIdentifiersPolicyService.java
@@ -56,16 +56,17 @@
             // for any device / profile owner checks. The majority of requests for the serial number
             // should use the getSerialForPackage method with the calling package specified.
             if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mContext,
-                    /* callingPackage */ null, "getSerial")) {
+                    /* callingPackage */ null, null, "getSerial")) {
                 return Build.UNKNOWN;
             }
             return SystemProperties.get("ro.serialno", Build.UNKNOWN);
         }
 
         @Override
-        public @Nullable String getSerialForPackage(String callingPackage) throws RemoteException {
+        public @Nullable String getSerialForPackage(String callingPackage,
+                String callingFeatureId) throws RemoteException {
             if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mContext,
-                    callingPackage, "getSerial")) {
+                    callingPackage, callingFeatureId, "getSerial")) {
                 return Build.UNKNOWN;
             }
             return SystemProperties.get("ro.serialno", Build.UNKNOWN);
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index bb5b04a..ec11a97 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -29,27 +29,24 @@
 import android.content.pm.PackageParser;
 import android.content.pm.ProviderInfo;
 import android.net.Uri;
-import android.os.Build;
 import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.Trace;
-import android.permission.IPermissionManager;
+import android.os.UserHandle;
 import android.provider.DeviceConfig;
+import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseSetArray;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
 import com.android.server.FgThread;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 
@@ -60,7 +57,7 @@
 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
 public class AppsFilter {
 
-    private static final String TAG = PackageManagerService.TAG;
+    private static final String TAG = "AppsFilter";
 
     // Logs all filtering instead of enforcing
     private static final boolean DEBUG_ALLOW_ALL = false;
@@ -69,52 +66,46 @@
     private static final boolean DEBUG_LOGGING = false | DEBUG_ALLOW_ALL;
 
     /**
-     * This contains a list of packages that are implicitly queryable because another app explicitly
+     * This contains a list of app UIDs that are implicitly queryable because another app explicitly
      * interacted with it. For example, if application A starts a service in application B,
      * application B is implicitly allowed to query for application A; regardless of any manifest
      * entries.
      */
-    private final SparseArray<HashMap<String, Set<String>>> mImplicitlyQueryable =
-            new SparseArray<>();
+    private final SparseSetArray<Integer> mImplicitlyQueryable = new SparseSetArray<>();
 
     /**
-     * A mapping from the set of packages that query other packages via package name to the
+     * A mapping from the set of App IDs that query other App IDs via package name to the
      * list of packages that they can see.
      */
-    private final HashMap<String, Set<String>> mQueriesViaPackage = new HashMap<>();
+    private final SparseSetArray<Integer> mQueriesViaPackage = new SparseSetArray<>();
 
     /**
-     * A mapping from the set of packages that query others via intent to the list
+     * A mapping from the set of App IDs that query others via intent to the list
      * of packages that the intents resolve to.
      */
-    private final HashMap<String, Set<String>> mQueriesViaIntent = new HashMap<>();
+    private final SparseSetArray<Integer> mQueriesViaIntent = new SparseSetArray<>();
 
     /**
-     * A set of packages that are always queryable by any package, regardless of their manifest
+     * A set of App IDs that are always queryable by any package, regardless of their manifest
      * content.
      */
-    private final HashSet<String> mForceQueryable;
+    private final ArraySet<Integer> mForceQueryable = new ArraySet<>();
+
     /**
-     * A set of packages that are always queryable by any package, regardless of their manifest
-     * content.
+     * The set of package names provided by the device that should be force queryable regardless of
+     * their manifest contents.
      */
-    private final Set<String> mForceQueryableByDevice;
+    private final String[] mForceQueryableByDevicePackageNames;
 
     /** True if all system apps should be made queryable by default. */
     private final boolean mSystemAppsQueryable;
 
-    private final IPermissionManager mPermissionManager;
-
     private final FeatureConfig mFeatureConfig;
 
-    AppsFilter(FeatureConfig featureConfig, IPermissionManager permissionManager,
-            String[] forceQueryableWhitelist, boolean systemAppsQueryable) {
+    AppsFilter(FeatureConfig featureConfig, String[] forceQueryableWhitelist,
+            boolean systemAppsQueryable) {
         mFeatureConfig = featureConfig;
-        final HashSet<String> forceQueryableByDeviceSet = new HashSet<>();
-        Collections.addAll(forceQueryableByDeviceSet, forceQueryableWhitelist);
-        this.mForceQueryableByDevice = Collections.unmodifiableSet(forceQueryableByDeviceSet);
-        this.mForceQueryable = new HashSet<>();
-        mPermissionManager = permissionManager;
+        mForceQueryableByDevicePackageNames = forceQueryableWhitelist;
         mSystemAppsQueryable = systemAppsQueryable;
     }
 
@@ -127,7 +118,6 @@
 
         /** @return true if the feature is enabled for the given package. */
         boolean packageIsEnabled(PackageParser.Package pkg);
-
     }
 
     private static class FeatureConfigImpl implements FeatureConfig {
@@ -174,7 +164,6 @@
         }
     }
 
-
     public static AppsFilter create(PackageManagerService.Injector injector) {
         final boolean forceSystemAppsQueryable =
                 injector.getContext().getResources()
@@ -192,15 +181,12 @@
                 forcedQueryablePackageNames[i] = forcedQueryablePackageNames[i].intern();
             }
         }
-        IPermissionManager permissionmgr =
-                (IPermissionManager) ServiceManager.getService("permissionmgr");
-
-        return new AppsFilter(featureConfig, permissionmgr, forcedQueryablePackageNames,
+        return new AppsFilter(featureConfig, forcedQueryablePackageNames,
                 forceSystemAppsQueryable);
     }
 
     /** Returns true if the querying package may query for the potential target package */
-    private static boolean canQuery(PackageParser.Package querying,
+    private static boolean canQueryViaIntent(PackageParser.Package querying,
             PackageParser.Package potentialTarget) {
         if (querying.mQueriesIntents == null) {
             return false;
@@ -274,22 +260,14 @@
      * Grants access based on an interaction between a calling and target package, granting
      * visibility of the caller from the target.
      *
-     * @param callingPackage the package initiating the interaction
-     * @param targetPackage  the package being interacted with and thus gaining visibility of the
-     *                       initiating package.
-     * @param userId         the user in which this interaction was taking place
+     * @param callingUid the uid initiating the interaction
+     * @param targetUid  the uid being interacted with and thus gaining visibility of the
+     *                   initiating uid.
      */
-    public void grantImplicitAccess(
-            String callingPackage, String targetPackage, int userId) {
-        HashMap<String, Set<String>> currentUser = mImplicitlyQueryable.get(userId);
-        if (currentUser == null) {
-            currentUser = new HashMap<>();
-            mImplicitlyQueryable.put(userId, currentUser);
+    public void grantImplicitAccess(int callingUid, int targetUid) {
+        if (mImplicitlyQueryable.add(targetUid, callingUid) && DEBUG_LOGGING) {
+            Slog.wtf(TAG, "implicit access granted: " + callingUid + " -> " + targetUid);
         }
-        if (!currentUser.containsKey(targetPackage)) {
-            currentUser.put(targetPackage, new HashSet<>());
-        }
-        currentUser.get(targetPackage).add(callingPackage);
     }
 
     public void onSystemReady() {
@@ -299,50 +277,57 @@
     /**
      * Adds a package that should be considered when filtering visibility between apps.
      *
-     * @param newPkg   the new package being added
-     * @param existing all other packages currently on the device.
+     * @param newPkgSetting    the new setting being added
+     * @param existingSettings all other settings currently on the device.
      */
-    public void addPackage(PackageParser.Package newPkg,
-            Map<String, PackageParser.Package> existing) {
+    public void addPackage(PackageSetting newPkgSetting,
+            ArrayMap<String, PackageSetting> existingSettings) {
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.addPackage");
         try {
-            // let's re-evaluate the ability of already added packages to see this new package
-            if (newPkg.mForceQueryable
-                    || (mSystemAppsQueryable && (newPkg.isSystem()
-                    || newPkg.isUpdatedSystemApp()))) {
-                mForceQueryable.add(newPkg.packageName);
-            } else {
-                for (String packageName : mQueriesViaIntent.keySet()) {
-                    if (packageName == newPkg.packageName) {
-                        continue;
+            final PackageParser.Package newPkg = newPkgSetting.pkg;
+            if (newPkg == null) {
+                // nothing to add
+                return;
+            }
+
+            final boolean newIsForceQueryable =
+                    mForceQueryable.contains(newPkgSetting.appId)
+                            /* shared user that is already force queryable */
+                            || newPkg.mForceQueryable
+                            || (newPkgSetting.isSystem() && (mSystemAppsQueryable
+                            || ArrayUtils.contains(mForceQueryableByDevicePackageNames,
+                            newPkg.packageName)));
+            if (newIsForceQueryable) {
+                mForceQueryable.add(newPkgSetting.appId);
+            }
+
+            for (int i = existingSettings.size() - 1; i >= 0; i--) {
+                final PackageSetting existingSetting = existingSettings.valueAt(i);
+                if (existingSetting.appId == newPkgSetting.appId || existingSetting.pkg == null) {
+                    continue;
+                }
+                final PackageParser.Package existingPkg = existingSetting.pkg;
+                // let's evaluate the ability of already added packages to see this new package
+                if (!newIsForceQueryable) {
+                    if (canQueryViaIntent(existingPkg, newPkg)) {
+                        mQueriesViaIntent.add(existingSetting.appId, newPkgSetting.appId);
                     }
-                    final PackageParser.Package existingPackage = existing.get(packageName);
-                    if (canQuery(existingPackage, newPkg)) {
-                        mQueriesViaIntent.get(packageName).add(newPkg.packageName);
+                    if (existingPkg.mQueriesPackages != null
+                            && existingPkg.mQueriesPackages.contains(newPkg.packageName)) {
+                        mQueriesViaPackage.add(existingSetting.appId, newPkgSetting.appId);
+                    }
+                }
+                // now we'll evaluate our new package's ability to see existing packages
+                if (!mForceQueryable.contains(existingSetting.appId)) {
+                    if (canQueryViaIntent(newPkg, existingPkg)) {
+                        mQueriesViaIntent.add(newPkgSetting.appId, existingSetting.appId);
+                    }
+                    if (newPkg.mQueriesPackages != null
+                            && newPkg.mQueriesPackages.contains(existingPkg.packageName)) {
+                        mQueriesViaPackage.add(newPkgSetting.appId, existingSetting.appId);
                     }
                 }
             }
-            // if the new package declares them, let's evaluate its ability to see existing packages
-            mQueriesViaIntent.put(newPkg.packageName, new HashSet<>());
-            for (PackageParser.Package existingPackage : existing.values()) {
-                if (existingPackage.packageName == newPkg.packageName) {
-                    continue;
-                }
-                if (existingPackage.mForceQueryable
-                        || (mSystemAppsQueryable
-                        && (newPkg.isSystem() || newPkg.isUpdatedSystemApp()))) {
-                    continue;
-                }
-                if (canQuery(newPkg, existingPackage)) {
-                    mQueriesViaIntent.get(newPkg.packageName).add(existingPackage.packageName);
-                }
-            }
-            final HashSet<String> queriesPackages = new HashSet<>(
-                    newPkg.mQueriesPackages == null ? 0 : newPkg.mQueriesPackages.size());
-            if (newPkg.mQueriesPackages != null) {
-                queriesPackages.addAll(newPkg.mQueriesPackages);
-            }
-            mQueriesViaPackage.put(newPkg.packageName, queriesPackages);
         } finally {
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
@@ -351,24 +336,41 @@
     /**
      * Removes a package for consideration when filtering visibility between apps.
      *
-     * @param packageName the name of the package being removed.
+     * @param setting  the setting of the package being removed.
+     * @param allUsers array of all current users on device.
      */
-    public void removePackage(String packageName) {
-        mForceQueryable.remove(packageName);
+    public void removePackage(PackageSetting setting, int[] allUsers,
+            ArrayMap<String, PackageSetting> existingSettings) {
+        mForceQueryable.remove(setting.appId);
 
-        for (int i = 0; i < mImplicitlyQueryable.size(); i++) {
-            mImplicitlyQueryable.valueAt(i).remove(packageName);
-            for (Set<String> initiators : mImplicitlyQueryable.valueAt(i).values()) {
-                initiators.remove(packageName);
+        for (int u = 0; u < allUsers.length; u++) {
+            final int userId = allUsers[u];
+            final int removingUid = UserHandle.getUid(userId, setting.appId);
+            mImplicitlyQueryable.remove(removingUid);
+            for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) {
+                mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i), removingUid);
             }
         }
 
-        mQueriesViaIntent.remove(packageName);
-        for (Set<String> declarators : mQueriesViaIntent.values()) {
-            declarators.remove(packageName);
+        mQueriesViaIntent.remove(setting.appId);
+        for (int i = mQueriesViaIntent.size() - 1; i >= 0; i--) {
+            mQueriesViaIntent.remove(mQueriesViaIntent.keyAt(i), setting.appId);
+        }
+        mQueriesViaPackage.remove(setting.appId);
+        for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) {
+            mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), setting.appId);
         }
 
-        mQueriesViaPackage.remove(packageName);
+        // re-add other shared user members to re-establish visibility between them and other
+        // packages
+        if (setting.sharedUser != null) {
+            for (int i = setting.sharedUser.packages.size() - 1; i >= 0; i--) {
+                if (setting.sharedUser.packages.valueAt(i) == setting) {
+                    continue;
+                }
+                addPackage(setting.sharedUser.packages.valueAt(i), existingSettings);
+            }
+        }
     }
 
     /**
@@ -385,6 +387,25 @@
             PackageSetting targetPkgSetting, int userId) {
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplication");
         try {
+            if (!shouldFilterApplicationInternal(callingUid, callingSetting,
+                    targetPkgSetting,
+                    userId)) {
+                return false;
+            }
+            if (DEBUG_LOGGING) {
+                log(callingSetting, targetPkgSetting,
+                        DEBUG_ALLOW_ALL ? "ALLOWED" : "BLOCKED", new RuntimeException());
+            }
+            return !DEBUG_ALLOW_ALL;
+        } finally {
+            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+        }
+    }
+
+    private boolean shouldFilterApplicationInternal(int callingUid,
+            SettingBase callingSetting, PackageSetting targetPkgSetting, int userId) {
+        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplicationInternal");
+        try {
             final boolean featureEnabled = mFeatureConfig.isGloballyEnabled();
             if (!featureEnabled) {
                 if (DEBUG_LOGGING) {
@@ -402,85 +423,37 @@
                 Slog.wtf(TAG, "No setting found for non system uid " + callingUid);
                 return true;
             }
-            PackageSetting callingPkgSetting = null;
+            final PackageSetting callingPkgSetting;
+            final ArraySet<PackageSetting> callingSharedPkgSettings;
             if (callingSetting instanceof PackageSetting) {
                 callingPkgSetting = (PackageSetting) callingSetting;
-                if (!shouldFilterApplicationInternal(callingPkgSetting, targetPkgSetting,
-                        userId)) {
+                callingSharedPkgSettings = null;
+            } else {
+                callingPkgSetting = null;
+                callingSharedPkgSettings = ((SharedUserSetting) callingSetting).packages;
+            }
+
+            if (callingPkgSetting != null) {
+                if (!mFeatureConfig.packageIsEnabled(callingPkgSetting.pkg)) {
+                    if (DEBUG_LOGGING) {
+                        log(callingSetting, targetPkgSetting, "DISABLED");
+                    }
                     return false;
                 }
-            } else if (callingSetting instanceof SharedUserSetting) {
-                final ArraySet<PackageSetting> packageSettings =
-                        ((SharedUserSetting) callingSetting).packages;
-                if (packageSettings != null && packageSettings.size() > 0) {
-                    for (int i = 0, max = packageSettings.size(); i < max; i++) {
-                        final PackageSetting packageSetting = packageSettings.valueAt(i);
-                        if (!shouldFilterApplicationInternal(packageSetting, targetPkgSetting,
-                                userId)) {
-                            return false;
+            } else {
+                for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
+                    if (!mFeatureConfig.packageIsEnabled(callingSharedPkgSettings.valueAt(i).pkg)) {
+                        if (DEBUG_LOGGING) {
+                            log(callingSetting, targetPkgSetting, "DISABLED");
                         }
-                        if (callingPkgSetting == null && packageSetting.pkg != null) {
-                            callingPkgSetting = packageSetting;
-                        }
-                    }
-                    if (callingPkgSetting == null) {
-                        Slog.wtf(TAG, callingSetting + " does not have any non-null packages!");
-                        return true;
-                    }
-                } else {
-                    Slog.wtf(TAG, callingSetting + " has no packages!");
-                    return true;
-                }
-            }
-
-            if (DEBUG_LOGGING) {
-                log(callingPkgSetting, targetPkgSetting,
-                        DEBUG_ALLOW_ALL ? "ALLOWED" : "BLOCKED");
-            }
-            return !DEBUG_ALLOW_ALL;
-        } finally {
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-        }
-    }
-
-    private boolean shouldFilterApplicationInternal(
-            PackageSetting callingPkgSetting, PackageSetting targetPkgSetting, int userId) {
-        return shouldFilterApplicationInternal(callingPkgSetting, targetPkgSetting, userId,
-                true /*expandSharedUser*/);
-    }
-
-    /**
-     * @param expandSharedUser true if all members of the shared user a target may belong to should
-     *                         be considered
-     */
-    private boolean shouldFilterApplicationInternal(
-            PackageSetting callingPkgSetting, PackageSetting targetPkgSetting, int userId,
-            boolean expandSharedUser) {
-        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplicationInternal");
-        try {
-            // special case shared user targets
-            if (expandSharedUser && targetPkgSetting.sharedUser != null) {
-                for (PackageSetting sharedMemberSetting : targetPkgSetting.sharedUser.packages) {
-                    if (!shouldFilterApplicationInternal(
-                            callingPkgSetting, sharedMemberSetting, userId,
-                            false /*expandSharedUser*/)) {
                         return false;
                     }
                 }
-                return true;
             }
 
-            final String callingName = callingPkgSetting.pkg.packageName;
-            final PackageParser.Package targetPkg = targetPkgSetting.pkg;
-
-            if (!mFeatureConfig.packageIsEnabled(callingPkgSetting.pkg)) {
-                if (DEBUG_LOGGING) {
-                    log(callingPkgSetting, targetPkgSetting, "DISABLED");
-                }
-                return false;
-            }
             // This package isn't technically installed and won't be written to settings, so we can
             // treat it as filtered until it's available again.
+            final PackageParser.Package targetPkg = targetPkgSetting.pkg;
             if (targetPkg == null) {
                 if (DEBUG_LOGGING) {
                     Slog.wtf(TAG, "shouldFilterApplication: " + "targetPkg is null");
@@ -488,149 +461,180 @@
                 return true;
             }
             final String targetName = targetPkg.packageName;
-            if (callingPkgSetting.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.R) {
+            final int callingAppId;
+            if (callingPkgSetting != null) {
+                callingAppId = callingPkgSetting.appId;
+            } else {
+                callingAppId = callingSharedPkgSettings.valueAt(0).appId; // all should be the same
+            }
+            final int targetAppId = targetPkgSetting.appId;
+            if (callingAppId == targetAppId) {
                 if (DEBUG_LOGGING) {
-                    log(callingPkgSetting, targetPkgSetting, "caller pre-R");
+                    log(callingSetting, targetPkgSetting, "same app id");
                 }
                 return false;
             }
-            if (callingPkgSetting.appId == targetPkgSetting.appId) {
+
+            if (callingSetting.getPermissionsState().hasPermission(
+                    Manifest.permission.QUERY_ALL_PACKAGES, UserHandle.getUserId(callingUid))) {
                 if (DEBUG_LOGGING) {
-                    log(callingPkgSetting, targetPkgSetting, "same app id");
+                    log(callingSetting, targetPkgSetting, "has query-all permission");
                 }
                 return false;
             }
-            if (isImplicitlyQueryableSystemApp(targetPkgSetting)) {
+            if (mForceQueryable.contains(targetAppId)) {
                 if (DEBUG_LOGGING) {
-                    log(callingPkgSetting, targetPkgSetting, "implicitly queryable sys");
+                    log(callingSetting, targetPkgSetting, "force queryable");
                 }
                 return false;
             }
-            if (targetPkg.mForceQueryable) {
-                if (DEBUG_LOGGING) {
-                    log(callingPkgSetting, targetPkgSetting, "manifest forceQueryable");
-                }
-                return false;
-            }
-            if (mForceQueryable.contains(targetName)) {
-                if (DEBUG_LOGGING) {
-                    log(callingPkgSetting, targetPkgSetting, "whitelist forceQueryable");
-                }
-                return false;
-            }
-            if (mQueriesViaPackage.containsKey(callingName)
-                    && mQueriesViaPackage.get(callingName).contains(
-                    targetName)) {
+            if (mQueriesViaPackage.contains(callingAppId, targetAppId)) {
                 // the calling package has explicitly declared the target package; allow
                 if (DEBUG_LOGGING) {
-                    log(callingPkgSetting, targetPkgSetting, "queries package");
+                    log(callingSetting, targetPkgSetting, "queries package");
                 }
                 return false;
-            } else if (mQueriesViaIntent.containsKey(callingName)
-                    && mQueriesViaIntent.get(callingName).contains(targetName)) {
+            } else if (mQueriesViaIntent.contains(callingAppId, targetAppId)) {
                 if (DEBUG_LOGGING) {
-                    log(callingPkgSetting, targetPkgSetting, "queries intent");
+                    log(callingSetting, targetPkgSetting, "queries intent");
                 }
                 return false;
             }
-            if (mImplicitlyQueryable.get(userId) != null
-                    && mImplicitlyQueryable.get(userId).containsKey(callingName)
-                    && mImplicitlyQueryable.get(userId).get(callingName).contains(targetName)) {
+
+            final int targetUid = UserHandle.getUid(userId, targetAppId);
+            if (mImplicitlyQueryable.contains(callingUid, targetUid)) {
                 if (DEBUG_LOGGING) {
-                    log(callingPkgSetting, targetPkgSetting, "implicitly queryable for user");
+                    log(callingSetting, targetPkgSetting, "implicitly queryable for user");
                 }
                 return false;
             }
-            final ArrayList<PackageParser.Instrumentation> inst =
-                    callingPkgSetting.pkg.instrumentation;
-            if (inst.size() > 0) {
-                for (int i = 0, max = inst.size(); i < max; i++) {
-                    if (inst.get(i).info.targetPackage == targetName) {
-                        if (DEBUG_LOGGING) {
-                            log(callingPkgSetting, targetPkgSetting, "instrumentation");
-                        }
+            if (callingPkgSetting != null) {
+                if (callingPkgInstruments(callingPkgSetting, targetPkgSetting, targetName)) {
+                    return false;
+                }
+            } else {
+                for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
+                    if (callingPkgInstruments(callingSharedPkgSettings.valueAt(i),
+                            targetPkgSetting, targetName)) {
                         return false;
                     }
                 }
             }
-            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.checkPermission");
-            try {
-                if (mPermissionManager.checkPermission(
-                        Manifest.permission.QUERY_ALL_PACKAGES, callingName, userId)
-                        == PackageManager.PERMISSION_GRANTED) {
-                    if (DEBUG_LOGGING) {
-                        log(callingPkgSetting, targetPkgSetting, "permission");
-                    }
-                    return false;
-                }
-            } catch (RemoteException e) {
-                return true;
-            } finally {
-                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-            }
             return true;
         } finally {
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
     }
 
-    private static void log(PackageSetting callingPkgSetting, PackageSetting targetPkgSetting,
-            String description) {
-        Slog.wtf(TAG,
-                "interaction: " + callingPkgSetting.name + " -> " + targetPkgSetting.name + " "
-                        + description);
+    private static boolean callingPkgInstruments(PackageSetting callingPkgSetting,
+            PackageSetting targetPkgSetting,
+            String targetName) {
+        final ArrayList<PackageParser.Instrumentation> inst = callingPkgSetting.pkg.instrumentation;
+        for (int i = inst.size() - 1; i >= 0; i--) {
+            if (inst.get(i).info.targetPackage == targetName) {
+                if (DEBUG_LOGGING) {
+                    log(callingPkgSetting, targetPkgSetting, "instrumentation");
+                }
+                return true;
+            }
+        }
+        return false;
     }
 
-    private boolean isImplicitlyQueryableSystemApp(PackageSetting targetPkgSetting) {
-        return targetPkgSetting.isSystem() && (mSystemAppsQueryable
-                || mForceQueryableByDevice.contains(targetPkgSetting.pkg.packageName));
+    private static void log(SettingBase callingPkgSetting, PackageSetting targetPkgSetting,
+            String description) {
+        log(callingPkgSetting, targetPkgSetting, description, null);
+    }
+
+    private static void log(SettingBase callingPkgSetting, PackageSetting targetPkgSetting,
+            String description, Throwable throwable) {
+        Slog.wtf(TAG,
+                "interaction: " + callingPkgSetting.toString()
+                        + " -> " + targetPkgSetting.name + " "
+                        + description, throwable);
     }
 
     public void dumpQueries(
-            PrintWriter pw, @Nullable String filteringPackageName, DumpState dumpState,
+            PrintWriter pw, PackageManagerService pms, @Nullable Integer filteringAppId,
+            DumpState dumpState,
             int[] users) {
+        final SparseArray<String> cache = new SparseArray<>();
+        ToString<Integer> expandPackages = input -> {
+            String cachedValue = cache.get(input);
+            if (cachedValue == null) {
+                final String[] packagesForUid = pms.getPackagesForUid(input);
+                if (packagesForUid == null) {
+                    cachedValue = "[unknown app id " + input + "]";
+                } else {
+                    cachedValue = packagesForUid.length == 1 ? packagesForUid[0]
+                            : "[" + TextUtils.join(",", packagesForUid) + "]";
+                }
+                cache.put(input, cachedValue);
+            }
+            return cachedValue;
+        };
         pw.println();
         pw.println("Queries:");
         dumpState.onTitlePrinted();
+        if (!mFeatureConfig.isGloballyEnabled()) {
+            pw.println("  DISABLED");
+            if (!DEBUG_LOGGING) {
+                return;
+            }
+        }
         pw.println("  system apps queryable: " + mSystemAppsQueryable);
-        dumpPackageSet(pw, filteringPackageName, mForceQueryableByDevice, "System whitelist", "  ");
-        dumpPackageSet(pw, filteringPackageName, mForceQueryable, "forceQueryable", "  ");
+        dumpPackageSet(pw, filteringAppId, mForceQueryable, "forceQueryable", "  ", expandPackages);
         pw.println("  queries via package name:");
-        dumpQueriesMap(pw, filteringPackageName, mQueriesViaPackage, "    ");
+        dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, "    ", expandPackages);
         pw.println("  queries via intent:");
-        dumpQueriesMap(pw, filteringPackageName, mQueriesViaIntent, "    ");
+        dumpQueriesMap(pw, filteringAppId, mQueriesViaIntent, "    ", expandPackages);
         pw.println("  queryable via interaction:");
         for (int user : users) {
             pw.append("    User ").append(Integer.toString(user)).println(":");
-            final HashMap<String, Set<String>> queryMapForUser = mImplicitlyQueryable.get(user);
-            if (queryMapForUser != null) {
-                dumpQueriesMap(pw, filteringPackageName, queryMapForUser, "      ");
-            }
+            dumpQueriesMap(pw,
+                    filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId),
+                    mImplicitlyQueryable, "      ", expandPackages);
         }
     }
 
-    private static void dumpQueriesMap(PrintWriter pw, @Nullable String filteringPackageName,
-            HashMap<String, Set<String>> queriesMap, String spacing) {
-        for (String callingPkg : queriesMap.keySet()) {
-            if (Objects.equals(callingPkg, filteringPackageName)) {
-                // don't filter target package names if the calling is filteringPackageName
-                dumpPackageSet(pw, null /*filteringPackageName*/, queriesMap.get(callingPkg),
-                        callingPkg, spacing);
+    private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId,
+            SparseSetArray<Integer> queriesMap, String spacing,
+            @Nullable ToString<Integer> toString) {
+        for (int i = 0; i < queriesMap.size(); i++) {
+            Integer callingId = queriesMap.keyAt(i);
+            if (Objects.equals(callingId, filteringId)) {
+                // don't filter target package names if the calling is filteringId
+                dumpPackageSet(
+                        pw, null /*filteringId*/, queriesMap.get(callingId),
+                        toString == null
+                                ? callingId.toString()
+                                : toString.toString(callingId),
+                        spacing, toString);
             } else {
-                dumpPackageSet(pw, filteringPackageName, queriesMap.get(callingPkg), callingPkg,
-                        spacing);
+                dumpPackageSet(
+                        pw, filteringId, queriesMap.get(callingId),
+                        toString == null
+                                ? callingId.toString()
+                                : toString.toString(callingId),
+                        spacing, toString);
             }
         }
     }
 
-    private static void dumpPackageSet(PrintWriter pw, @Nullable String filteringPackageName,
-            Set<String> targetPkgSet, String subTitle, String spacing) {
+    private interface ToString<T> {
+        String toString(T input);
+    }
+
+    private static <T> void dumpPackageSet(PrintWriter pw, @Nullable T filteringId,
+            Set<T> targetPkgSet, String subTitle, String spacing,
+            @Nullable ToString<T> toString) {
         if (targetPkgSet != null && targetPkgSet.size() > 0
-                && (filteringPackageName == null || targetPkgSet.contains(filteringPackageName))) {
+                && (filteringId == null || targetPkgSet.contains(filteringId))) {
             pw.append(spacing).append(subTitle).println(":");
-            for (String pkgName : targetPkgSet) {
-                if (filteringPackageName == null || Objects.equals(filteringPackageName, pkgName)) {
-                    pw.append(spacing).append("  ").println(pkgName);
+            for (T item : targetPkgSet) {
+                if (filteringId == null || Objects.equals(filteringId, item)) {
+                    pw.append(spacing).append("  ")
+                            .println(toString == null ? item : toString.toString(item));
                 }
             }
         }
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 2b6c347..bd95667 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -304,7 +304,7 @@
             long ident = injectClearCallingIdentity();
             try {
                 final UserInfo callingUserInfo = mUm.getUserInfo(callingUserId);
-                if (callingUserInfo != null && callingUserInfo.isManagedProfile()) {
+                if (callingUserInfo != null && callingUserInfo.isProfile()) {
                     Slog.w(TAG, message + " for another profile "
                             + targetUserId + " from " + callingUserId + " not allowed");
                     return false;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 6564e71..93249e9 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -26,7 +26,6 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PackageDeleteObserver;
-import android.app.PackageInstallObserver;
 import android.app.admin.DevicePolicyEventLogger;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.content.Context;
@@ -1015,73 +1014,56 @@
         }
     }
 
-    static class PackageInstallObserverAdapter extends PackageInstallObserver {
-        private final Context mContext;
-        private final IntentSender mTarget;
-        private final int mSessionId;
-        private final boolean mShowNotification;
-        private final int mUserId;
-
-        public PackageInstallObserverAdapter(Context context, IntentSender target, int sessionId,
-                boolean showNotification, int userId) {
-            mContext = context;
-            mTarget = target;
-            mSessionId = sessionId;
-            mShowNotification = showNotification;
-            mUserId = userId;
+    static void sendOnUserActionRequired(Context context, IntentSender target, int sessionId,
+            Intent intent) {
+        final Intent fillIn = new Intent();
+        fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
+        fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
+                PackageInstaller.STATUS_PENDING_USER_ACTION);
+        fillIn.putExtra(Intent.EXTRA_INTENT, intent);
+        try {
+            target.sendIntent(context, 0, fillIn, null, null);
+        } catch (SendIntentException ignored) {
         }
+    }
 
-        @Override
-        public void onUserActionRequired(Intent intent) {
-            final Intent fillIn = new Intent();
-            fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId);
-            fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
-                    PackageInstaller.STATUS_PENDING_USER_ACTION);
-            fillIn.putExtra(Intent.EXTRA_INTENT, intent);
-            try {
-                mTarget.sendIntent(mContext, 0, fillIn, null, null);
-            } catch (SendIntentException ignored) {
+    static void sendOnPackageInstalled(Context context, IntentSender target, int sessionId,
+            boolean showNotification, int userId, String basePackageName, int returnCode,
+            String msg, Bundle extras) {
+        if (PackageManager.INSTALL_SUCCEEDED == returnCode && showNotification) {
+            boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING);
+            Notification notification = buildSuccessNotification(context,
+                    context.getResources()
+                            .getString(update ? R.string.package_updated_device_owner :
+                                    R.string.package_installed_device_owner),
+                    basePackageName,
+                    userId);
+            if (notification != null) {
+                NotificationManager notificationManager = (NotificationManager)
+                        context.getSystemService(Context.NOTIFICATION_SERVICE);
+                notificationManager.notify(basePackageName,
+                        SystemMessage.NOTE_PACKAGE_STATE,
+                        notification);
             }
         }
-
-        @Override
-        public void onPackageInstalled(String basePackageName, int returnCode, String msg,
-                Bundle extras) {
-            if (PackageManager.INSTALL_SUCCEEDED == returnCode && mShowNotification) {
-                boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING);
-                Notification notification = buildSuccessNotification(mContext,
-                        mContext.getResources()
-                                .getString(update ? R.string.package_updated_device_owner :
-                                        R.string.package_installed_device_owner),
-                        basePackageName,
-                        mUserId);
-                if (notification != null) {
-                    NotificationManager notificationManager = (NotificationManager)
-                            mContext.getSystemService(Context.NOTIFICATION_SERVICE);
-                    notificationManager.notify(basePackageName,
-                            SystemMessage.NOTE_PACKAGE_STATE,
-                            notification);
-                }
+        final Intent fillIn = new Intent();
+        fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName);
+        fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
+        fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
+                PackageManager.installStatusToPublicStatus(returnCode));
+        fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
+                PackageManager.installStatusToString(returnCode, msg));
+        fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode);
+        if (extras != null) {
+            final String existing = extras.getString(
+                    PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE);
+            if (!TextUtils.isEmpty(existing)) {
+                fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing);
             }
-            final Intent fillIn = new Intent();
-            fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName);
-            fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId);
-            fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
-                    PackageManager.installStatusToPublicStatus(returnCode));
-            fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
-                    PackageManager.installStatusToString(returnCode, msg));
-            fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode);
-            if (extras != null) {
-                final String existing = extras.getString(
-                        PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE);
-                if (!TextUtils.isEmpty(existing)) {
-                    fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing);
-                }
-            }
-            try {
-                mTarget.sendIntent(mContext, 0, fillIn, null, null);
-            } catch (SendIntentException ignored) {
-            }
+        }
+        try {
+            target.sendIntent(context, 0, fillIn, null, null);
+        } catch (SendIntentException ignored) {
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 38649a7..d5f4ff2 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -18,7 +18,6 @@
 
 import static android.content.pm.PackageManager.INSTALL_FAILED_ABORTED;
 import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_SIGNATURE;
-import static android.content.pm.PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
@@ -79,7 +78,6 @@
 import android.os.ParcelFileDescriptor;
 import android.os.ParcelableException;
 import android.os.Process;
-import android.os.RemoteException;
 import android.os.RevocableFileDescriptor;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -107,7 +105,6 @@
 import com.android.internal.util.Preconditions;
 import com.android.server.LocalServices;
 import com.android.server.pm.Installer.InstallerException;
-import com.android.server.pm.PackageInstallerService.PackageInstallObserverAdapter;
 import com.android.server.pm.dex.DexManager;
 import com.android.server.security.VerityUtils;
 
@@ -131,7 +128,7 @@
 public class PackageInstallerSession extends IPackageInstallerSession.Stub {
     private static final String TAG = "PackageInstallerSession";
     private static final boolean LOGD = true;
-    private static final String REMOVE_SPLIT_MARKER_EXTENSION = ".removed";
+    private static final String REMOVE_MARKER_EXTENSION = ".removed";
 
     private static final int MSG_COMMIT = 1;
     private static final int MSG_ON_PACKAGE_INSTALLED = 2;
@@ -261,7 +258,7 @@
     private final ArrayList<FileBridge> mBridges = new ArrayList<>();
 
     @GuardedBy("mLock")
-    private IPackageInstallObserver2 mRemoteObserver;
+    private IntentSender mRemoteStatusReceiver;
 
     /** Fields derived from commit parsing */
     @GuardedBy("mLock")
@@ -298,9 +295,6 @@
     private File mResolvedBaseFile;
 
     @GuardedBy("mLock")
-    private File mResolvedStageDir;
-
-    @GuardedBy("mLock")
     private final List<File> mResolvedStagedFiles = new ArrayList<>();
     @GuardedBy("mLock")
     private final List<File> mResolvedInheritedFiles = new ArrayList<>();
@@ -319,7 +313,7 @@
             // Installers can't stage directories, so it's fine to ignore
             // entries like "lost+found".
             if (file.isDirectory()) return false;
-            if (file.getName().endsWith(REMOVE_SPLIT_MARKER_EXTENSION)) return false;
+            if (file.getName().endsWith(REMOVE_MARKER_EXTENSION)) return false;
             if (DexMetadataHelper.isDexMetadataFile(file)) return false;
             if (VerityUtils.isFsveritySignatureFile(file)) return false;
             return true;
@@ -329,7 +323,7 @@
         @Override
         public boolean accept(File file) {
             if (file.isDirectory()) return false;
-            if (!file.getName().endsWith(REMOVE_SPLIT_MARKER_EXTENSION)) return false;
+            if (!file.getName().endsWith(REMOVE_MARKER_EXTENSION)) return false;
             return true;
         }
     };
@@ -346,14 +340,14 @@
                     final String packageName = (String) args.arg1;
                     final String message = (String) args.arg2;
                     final Bundle extras = (Bundle) args.arg3;
-                    final IPackageInstallObserver2 observer = (IPackageInstallObserver2) args.arg4;
+                    final IntentSender statusReceiver = (IntentSender) args.arg4;
                     final int returnCode = args.argi1;
                     args.recycle();
 
-                    try {
-                        observer.onPackageInstalled(packageName, returnCode, message, extras);
-                    } catch (RemoteException ignored) {
-                    }
+                    PackageInstallerService.sendOnPackageInstalled(mContext,
+                            statusReceiver, sessionId,
+                            isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId,
+                            packageName, returnCode, message, extras);
 
                     break;
             }
@@ -564,23 +558,6 @@
         }
     }
 
-    /**
-     * Resolve the actual location where staged data should be written. This
-     * might point at an ASEC mount point, which is why we delay path resolution
-     * until someone actively works with the session.
-     */
-    @GuardedBy("mLock")
-    private File resolveStageDirLocked() throws IOException {
-        if (mResolvedStageDir == null) {
-            if (stageDir != null) {
-                mResolvedStageDir = stageDir;
-            } else {
-                throw new IOException("Missing stageDir");
-            }
-        }
-        return mResolvedStageDir;
-    }
-
     @Override
     public void setClientProgress(float progress) {
         synchronized (mLock) {
@@ -620,14 +597,32 @@
             assertCallerIsOwnerOrRootLocked();
             assertPreparedAndNotCommittedOrDestroyedLocked("getNames");
 
-            try {
-                return resolveStageDirLocked().list();
-            } catch (IOException e) {
-                throw ExceptionUtils.wrap(e);
-            }
+            return getNamesLocked();
         }
     }
 
+    @GuardedBy("mLock")
+    private String[] getNamesLocked() {
+        return stageDir.list();
+    }
+
+    private static File[] filterFiles(File parent, String[] names, FileFilter filter) {
+        return Arrays.stream(names).map(name -> new File(parent, name)).filter(
+                file -> filter.accept(file)).toArray(File[]::new);
+    }
+
+    @GuardedBy("mLock")
+    private File[] getAddedFilesLocked() {
+        String[] names = getNamesLocked();
+        return filterFiles(stageDir, names, sAddedFilter);
+    }
+
+    @GuardedBy("mLock")
+    private File[] getRemovedFilesLocked() {
+        String[] names = getNamesLocked();
+        return filterFiles(stageDir, names, sRemovedFilter);
+    }
+
     @Override
     public void removeSplit(String splitName) {
         if (TextUtils.isEmpty(params.appPackageName)) {
@@ -646,13 +641,17 @@
         }
     }
 
+    private static String getRemoveMarkerName(String name) {
+        final String markerName = name + REMOVE_MARKER_EXTENSION;
+        if (!FileUtils.isValidExtFilename(markerName)) {
+            throw new IllegalArgumentException("Invalid marker: " + markerName);
+        }
+        return markerName;
+    }
+
     private void createRemoveSplitMarkerLocked(String splitName) throws IOException {
         try {
-            final String markerName = splitName + REMOVE_SPLIT_MARKER_EXTENSION;
-            if (!FileUtils.isValidExtFilename(markerName)) {
-                throw new IllegalArgumentException("Invalid marker: " + markerName);
-            }
-            final File target = new File(resolveStageDirLocked(), markerName);
+            final File target = new File(stageDir, getRemoveMarkerName(splitName));
             target.createNewFile();
             Os.chmod(target.getAbsolutePath(), 0 /*mode*/);
         } catch (ErrnoException e) {
@@ -686,7 +685,6 @@
         // will block any attempted install transitions.
         final RevocableFileDescriptor fd;
         final FileBridge bridge;
-        final File stageDir;
         synchronized (mLock) {
             assertCallerIsOwnerOrRootLocked();
             assertPreparedAndNotSealedLocked("openWrite");
@@ -700,8 +698,6 @@
                 bridge = new FileBridge();
                 mBridges.add(bridge);
             }
-
-            stageDir = resolveStageDirLocked();
         }
 
         try {
@@ -807,7 +803,7 @@
             if (!FileUtils.isValidExtFilename(name)) {
                 throw new IllegalArgumentException("Invalid name: " + name);
             }
-            final File target = new File(resolveStageDirLocked(), name);
+            final File target = new File(stageDir, name);
             final FileDescriptor targetFd = Os.open(target.getAbsolutePath(), O_RDONLY, 0);
             return new ParcelFileDescriptor(targetFd);
         } catch (ErrnoException e) {
@@ -953,7 +949,7 @@
      * This method may be called multiple times to update the status receiver validate caller
      * permissions.
      */
-    public boolean markAsCommitted(
+    private boolean markAsCommitted(
             @NonNull IntentSender statusReceiver, boolean forTransfer) {
         Preconditions.checkNotNull(statusReceiver);
 
@@ -964,10 +960,7 @@
             assertCallerIsOwnerOrRootLocked();
             assertPreparedAndNotDestroyedLocked("commit");
 
-            final PackageInstallObserverAdapter adapter = new PackageInstallObserverAdapter(
-                    mContext, statusReceiver, sessionId,
-                    isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId);
-            mRemoteObserver = adapter.getBinder();
+            mRemoteStatusReceiver = statusReceiver;
 
             if (forTransfer) {
                 mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, null);
@@ -991,12 +984,7 @@
             if (!mSealed) {
                 try {
                     sealAndValidateLocked(childSessions);
-                } catch (IOException e) {
-                    throw new IllegalArgumentException(e);
                 } catch (PackageManagerException e) {
-                    // Do now throw an exception here to stay compatible with O and older
-                    destroyInternal();
-                    dispatchSessionFinished(e.error, ExceptionUtils.getCompleteMessage(e), null);
                     return false;
                 }
             }
@@ -1096,52 +1084,59 @@
      */
     @GuardedBy("mLock")
     private void sealAndValidateLocked(List<PackageInstallerSession> childSessions)
-            throws PackageManagerException, IOException {
-        assertNoWriteFileTransfersOpenLocked();
-        assertPreparedAndNotDestroyedLocked("sealing of session");
+            throws PackageManagerException {
+        try {
+            assertNoWriteFileTransfersOpenLocked();
+            assertPreparedAndNotDestroyedLocked("sealing of session");
 
-        mSealed = true;
+            mSealed = true;
 
-        if (childSessions != null) {
-            assertMultiPackageConsistencyLocked(childSessions);
-        }
-
-        if (params.isStaged) {
-            final PackageInstallerSession activeSession = mStagingManager.getActiveSession();
-            final boolean anotherSessionAlreadyInProgress =
-                    activeSession != null && sessionId != activeSession.sessionId
-                            && mParentSessionId != activeSession.sessionId;
-            if (anotherSessionAlreadyInProgress) {
-                throw new PackageManagerException(
-                        PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
-                        "There is already in-progress committed staged session "
-                                + activeSession.sessionId, null);
+            if (childSessions != null) {
+                assertMultiPackageConsistencyLocked(childSessions);
             }
-        }
 
-        // Read transfers from the original owner stay open, but as the session's data
-        // cannot be modified anymore, there is no leak of information. For staged sessions,
-        // further validation is performed by the staging manager.
-        if (!params.isMultiPackage) {
-            final PackageInfo pkgInfo = mPm.getPackageInfo(
-                    params.appPackageName, PackageManager.GET_SIGNATURES
-                            | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId);
-
-            resolveStageDirLocked();
-
-            try {
-                if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
-                    validateApexInstallLocked();
-                } else {
-                    validateApkInstallLocked(pkgInfo);
+            if (params.isStaged) {
+                final PackageInstallerSession activeSession = mStagingManager.getActiveSession();
+                final boolean anotherSessionAlreadyInProgress =
+                        activeSession != null && sessionId != activeSession.sessionId
+                                && mParentSessionId != activeSession.sessionId;
+                if (anotherSessionAlreadyInProgress) {
+                    throw new PackageManagerException(
+                            PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
+                            "There is already in-progress committed staged session "
+                                    + activeSession.sessionId, null);
                 }
-            } catch (PackageManagerException e) {
-                throw e;
-            } catch (Throwable e) {
-                // Convert all exceptions into package manager exceptions as only those are handled
-                // in the code above
-                throw new PackageManagerException(e);
             }
+
+            // Read transfers from the original owner stay open, but as the session's data
+            // cannot be modified anymore, there is no leak of information. For staged sessions,
+            // further validation is performed by the staging manager.
+            if (!params.isMultiPackage) {
+                final PackageInfo pkgInfo = mPm.getPackageInfo(
+                        params.appPackageName, PackageManager.GET_SIGNATURES
+                                | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId);
+
+                try {
+                    if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
+                        validateApexInstallLocked();
+                    } else {
+                        validateApkInstallLocked(pkgInfo);
+                    }
+                } catch (PackageManagerException e) {
+                    throw e;
+                } catch (Throwable e) {
+                    // Convert all exceptions into package manager exceptions as only those are
+                    // handled in the code above.
+                    throw new PackageManagerException(e);
+                }
+            }
+        } catch (PackageManagerException e) {
+            // Session is sealed but could not be verified, we need to destroy it.
+            destroyInternal();
+            // Dispatch message to remove session from PackageInstallerService
+            dispatchSessionFinished(
+                    e.error, ExceptionUtils.getCompleteMessage(e), null);
+            throw e;
         }
     }
 
@@ -1164,15 +1159,8 @@
         synchronized (mLock) {
             try {
                 sealAndValidateLocked(childSessions);
-            } catch (IOException e) {
-                throw new IllegalStateException(e);
             } catch (PackageManagerException e) {
                 Slog.e(TAG, "Package not valid", e);
-                // Session is sealed but could not be verified, we need to destroy it.
-                destroyInternal();
-                // Dispatch message to remove session from PackageInstallerService
-                dispatchSessionFinished(
-                        e.error, ExceptionUtils.getCompleteMessage(e), null);
             }
         }
     }
@@ -1213,13 +1201,7 @@
 
             try {
                 sealAndValidateLocked(childSessions);
-            } catch (IOException e) {
-                throw new IllegalStateException(e);
             } catch (PackageManagerException e) {
-                // Session is sealed but could not be verified, we need to destroy it
-                destroyInternal();
-                dispatchSessionFinished(e.error, ExceptionUtils.getCompleteMessage(e), null);
-
                 throw new IllegalArgumentException("Package is not valid", e);
             }
 
@@ -1304,11 +1286,10 @@
                 }
             }
             if (!success) {
-                try {
-                    mRemoteObserver.onPackageInstalled(
-                            null, failure.error, failure.getLocalizedMessage(), null);
-                } catch (RemoteException ignored) {
-                }
+                PackageInstallerService.sendOnPackageInstalled(mContext,
+                        mRemoteStatusReceiver, sessionId,
+                        isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId, null,
+                        failure.error, failure.getLocalizedMessage(), null);
                 return;
             }
             mPm.installStage(activeChildSessions);
@@ -1352,10 +1333,9 @@
                     final Intent intent = new Intent(PackageInstaller.ACTION_CONFIRM_INSTALL);
                     intent.setPackage(mPm.getPackageInstallerPackageName());
                     intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
-                    try {
-                        mRemoteObserver.onUserActionRequired(intent);
-                    } catch (RemoteException ignored) {
-                    }
+
+                    PackageInstallerService.sendOnUserActionRequired(mContext,
+                            mRemoteStatusReceiver, sessionId, intent);
 
                     // Commit was keeping session marked as active until now; release
                     // that extra refcount so session appears idle.
@@ -1368,7 +1348,7 @@
                 if (params.mode == SessionParams.MODE_INHERIT_EXISTING) {
                     try {
                         final List<File> fromFiles = mResolvedInheritedFiles;
-                        final File toDir = resolveStageDirLocked();
+                        final File toDir = stageDir;
 
                         if (LOGD) Slog.d(TAG, "Inherited files: " + mResolvedInheritedFiles);
                         if (!mResolvedInheritedFiles.isEmpty() && mInheritedFilesBase == null) {
@@ -1418,8 +1398,7 @@
                 computeProgressLocked(true);
 
                 // Unpack native libraries
-                extractNativeLibraries(mResolvedStageDir, params.abiOverride,
-                        mayInheritNativeLibs());
+                extractNativeLibraries(stageDir, params.abiOverride, mayInheritNativeLibs());
             }
 
             // We've reached point of no return; call into PMS to install the stage.
@@ -1479,7 +1458,7 @@
     @GuardedBy("mLock")
     private void validateApexInstallLocked()
             throws PackageManagerException {
-        final File[] addedFiles = mResolvedStageDir.listFiles(sAddedFilter);
+        final File[] addedFiles = getAddedFilesLocked();
         if (ArrayUtils.isEmpty(addedFiles)) {
             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged");
         }
@@ -1489,13 +1468,6 @@
                     "Too many files for apex install");
         }
 
-        try {
-            resolveStageDirLocked();
-        } catch (IOException e) {
-            throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
-                    "Failed to resolve stage location", e);
-        }
-
         File addedFile = addedFiles[0]; // there is only one file
 
         // Ensure file name has proper suffix
@@ -1508,7 +1480,7 @@
                     "Invalid filename: " + targetName);
         }
 
-        final File targetFile = new File(mResolvedStageDir, targetName);
+        final File targetFile = new File(stageDir, targetName);
         resolveAndStageFile(addedFile, targetFile);
 
         mResolvedBaseFile = targetFile;
@@ -1549,25 +1521,18 @@
                 && params.mode == SessionParams.MODE_INHERIT_EXISTING
                 && VerityUtils.hasFsverity(pkgInfo.applicationInfo.getBaseCodePath());
 
-        try {
-            resolveStageDirLocked();
-        } catch (IOException e) {
-            throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
-                    "Failed to resolve stage location", e);
-        }
-
-        final File[] removedFiles = mResolvedStageDir.listFiles(sRemovedFilter);
+        final File[] removedFiles = getRemovedFilesLocked();
         final List<String> removeSplitList = new ArrayList<>();
         if (!ArrayUtils.isEmpty(removedFiles)) {
             for (File removedFile : removedFiles) {
                 final String fileName = removedFile.getName();
                 final String splitName = fileName.substring(
-                        0, fileName.length() - REMOVE_SPLIT_MARKER_EXTENSION.length());
+                        0, fileName.length() - REMOVE_MARKER_EXTENSION.length());
                 removeSplitList.add(splitName);
             }
         }
 
-        final File[] addedFiles = mResolvedStageDir.listFiles(sAddedFilter);
+        final File[] addedFiles = getAddedFilesLocked();
         if (ArrayUtils.isEmpty(addedFiles) && removeSplitList.size() == 0) {
             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged");
         }
@@ -1611,7 +1576,7 @@
                         "Invalid filename: " + targetName);
             }
 
-            final File targetFile = new File(mResolvedStageDir, targetName);
+            final File targetFile = new File(stageDir, targetName);
             resolveAndStageFile(addedFile, targetFile);
 
             // Base is coming from session
@@ -1626,7 +1591,7 @@
                     throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
                             "Invalid filename: " + dexMetadataFile);
                 }
-                final File targetDexMetadataFile = new File(mResolvedStageDir,
+                final File targetDexMetadataFile = new File(stageDir,
                         DexMetadataHelper.buildDexMetadataPathForApk(targetName));
                 resolveAndStageFile(dexMetadataFile, targetDexMetadataFile);
             }
@@ -2186,17 +2151,17 @@
     }
 
     private void dispatchSessionFinished(int returnCode, String msg, Bundle extras) {
-        final IPackageInstallObserver2 observer;
+        final IntentSender statusReceiver;
         final String packageName;
         synchronized (mLock) {
             mFinalStatus = returnCode;
             mFinalMessage = msg;
 
-            observer = mRemoteObserver;
+            statusReceiver = mRemoteStatusReceiver;
             packageName = mPackageName;
         }
 
-        if (observer != null) {
+        if (statusReceiver != null) {
             // Execute observer.onPackageInstalled on different tread as we don't want callers
             // inside the system server have to worry about catching the callbacks while they are
             // calling into the session
@@ -2204,7 +2169,7 @@
             args.arg1 = packageName;
             args.arg2 = msg;
             args.arg3 = extras;
-            args.arg4 = observer;
+            args.arg4 = statusReceiver;
             args.argi1 = returnCode;
 
             mHandler.obtainMessage(MSG_ON_PACKAGE_INSTALLED, args).sendToTarget();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index fe82f7c..fa98c96 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -11701,7 +11701,7 @@
             ksms.addScannedPackageLPw(pkg);
 
             mComponentResolver.addAllComponents(pkg, chatty);
-            mAppsFilter.addPackage(pkg, mPackages);
+            mAppsFilter.addPackage(pkgSetting, mSettings.mPackages);
 
             // Don't allow ephemeral applications to define new permissions groups.
             if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
@@ -11889,31 +11889,10 @@
         }
     }
 
-    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
-        if (DEBUG_INSTALL) {
-            if (chatty)
-                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
-        }
-
-        // writer
-        synchronized (mLock) {
-            // Remove the parent package
-            mPackages.remove(pkg.applicationInfo.packageName);
-            cleanPackageDataStructuresLILPw(pkg, chatty);
-
-            // Remove the child packages
-            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
-            for (int i = 0; i < childCount; i++) {
-                PackageParser.Package childPkg = pkg.childPackages.get(i);
-                mPackages.remove(childPkg.applicationInfo.packageName);
-                cleanPackageDataStructuresLILPw(childPkg, chatty);
-            }
-        }
-    }
-
     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
         mComponentResolver.removeAllComponents(pkg, chatty);
-        mAppsFilter.removePackage(pkg.packageName);
+        mAppsFilter.removePackage((PackageSetting) pkg.mExtras,
+                mInjector.getUserManagerInternal().getUserIds(), mSettings.mPackages);
         mPermissionManager.removeAllPermissions(pkg, chatty);
 
         final int instrumentationSize = pkg.instrumentation.size();
@@ -20861,7 +20840,11 @@
             }
 
             if (dumpState.isDumping(DumpState.DUMP_QUERIES)) {
-                mAppsFilter.dumpQueries(pw, packageName, dumpState, mUserManager.getUserIds());
+                final PackageSetting setting = mSettings.getPackageLPr(packageName);
+                Integer filteringAppId = setting == null ? null : setting.appId;
+                mAppsFilter.dumpQueries(
+                        pw, this, filteringAppId, dumpState,
+                        mUserManager.getUserIds());
             }
 
             if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
@@ -23195,8 +23178,9 @@
                 int callingUid, int targetAppId) {
             synchronized (mLock) {
                 final PackageParser.Package callingPackage = getPackage(callingUid);
+                final int targetUid = UserHandle.getUid(userId, targetAppId);
                 final PackageParser.Package targetPackage =
-                        getPackage(UserHandle.getUid(userId, targetAppId));
+                        getPackage(targetUid);
                 if (callingPackage == null || targetPackage == null) {
                     return;
                 }
@@ -23207,8 +23191,7 @@
                     mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
                             UserHandle.getAppId(callingUid), targetAppId);
                 } else {
-                    mAppsFilter.grantImplicitAccess(
-                            callingPackage.packageName, targetPackage.packageName, userId);
+                    mAppsFilter.grantImplicitAccess(callingUid, targetUid);
                 }
             }
         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 525d357..232374c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -2453,27 +2453,40 @@
         String name;
         int userId = -1;
         int flags = 0;
+        String userType = null;
         String opt;
         boolean preCreateOnly = false;
         while ((opt = getNextOption()) != null) {
+            String newUserType = null;
             if ("--profileOf".equals(opt)) {
                 userId = UserHandle.parseUserArg(getNextArgRequired());
             } else if ("--managed".equals(opt)) {
-                flags |= UserInfo.FLAG_MANAGED_PROFILE;
+                newUserType = UserManager.USER_TYPE_PROFILE_MANAGED;
             } else if ("--restricted".equals(opt)) {
-                flags |= UserInfo.FLAG_RESTRICTED;
+                newUserType = UserManager.USER_TYPE_FULL_RESTRICTED;
+            } else if ("--guest".equals(opt)) {
+                newUserType = UserManager.USER_TYPE_FULL_GUEST;
+            } else if ("--demo".equals(opt)) {
+                newUserType = UserManager.USER_TYPE_FULL_DEMO;
             } else if ("--ephemeral".equals(opt)) {
                 flags |= UserInfo.FLAG_EPHEMERAL;
-            } else if ("--guest".equals(opt)) {
-                flags |= UserInfo.FLAG_GUEST;
-            } else if ("--demo".equals(opt)) {
-                flags |= UserInfo.FLAG_DEMO;
             } else if ("--pre-create-only".equals(opt)) {
                 preCreateOnly = true;
+            } else if ("--user-type".equals(opt)) {
+                newUserType = getNextArgRequired();
             } else {
                 getErrPrintWriter().println("Error: unknown option " + opt);
                 return 1;
             }
+            // Ensure only one user-type was specified.
+            if (newUserType != null) {
+                if (userType != null && !userType.equals(newUserType)) {
+                    getErrPrintWriter().println("Error: more than one user type was specified ("
+                            + userType + " and " + newUserType + ")");
+                    return 1;
+                }
+                userType = newUserType;
+            }
         }
         String arg = getNextArg();
         if (arg == null && !preCreateOnly) {
@@ -2490,16 +2503,20 @@
                 ServiceManager.getService(Context.USER_SERVICE));
         IAccountManager accm = IAccountManager.Stub.asInterface(
                 ServiceManager.getService(Context.ACCOUNT_SERVICE));
-        if ((flags & UserInfo.FLAG_RESTRICTED) != 0) {
+        if (userType == null) {
+            userType = UserInfo.getDefaultUserType(flags);
+        }
+        if (UserManager.isUserTypeRestricted(userType)) {
             // In non-split user mode, userId can only be SYSTEM
             int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM;
             info = um.createRestrictedProfile(name, parentUserId);
             accm.addSharedAccountsFromParentUser(parentUserId, userId,
                     (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell");
         } else if (userId < 0) {
-            info = preCreateOnly ? um.preCreateUser(flags) : um.createUser(name, flags);
+            info = preCreateOnly ?
+                    um.preCreateUser(userType) : um.createUser(name, userType, flags);
         } else {
-            info = um.createProfileForUser(name, flags, userId, null);
+            info = um.createProfileForUser(name, userType, flags, userId, null);
         }
 
         if (info != null) {
@@ -3421,9 +3438,15 @@
         pw.println("    Lists the current users.");
         pw.println("");
         pw.println("  create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral]");
-        pw.println("      [--guest] [--pre-create-only] USER_NAME");
+        pw.println("      [--guest] [--pre-create-only] [--user-type USER_TYPE] USER_NAME");
         pw.println("    Create a new user with the given USER_NAME, printing the new user identifier");
         pw.println("    of the user.");
+        // TODO(b/142482943): Consider fetching the list of user types from UMS.
+        pw.println("    USER_TYPE is the name of a user type, e.g. android.os.usertype.profile.MANAGED.");
+        pw.println("      If not specified, the default user type is android.os.usertype.full.SECONDARY.");
+        pw.println("      --managed is shorthand for '--user-type android.os.usertype.profile.MANAGED'.");
+        pw.println("      --restricted is shorthand for '--user-type android.os.usertype.full.RESTRICTED'.");
+        pw.println("      --guest is shorthand for '--user-type android.os.usertype.full.GUEST'.");
         pw.println("");
         pw.println("  remove-user USER_ID");
         pw.println("    Remove the user with the given USER_IDENTIFIER, deleting all data");
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 5c9b9c9..8ddfad9 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -20,8 +20,11 @@
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 
 import android.Manifest;
+import android.annotation.ColorRes;
+import android.annotation.DrawableRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringRes;
 import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -77,6 +80,7 @@
 import android.security.GateKeeper;
 import android.service.gatekeeper.IGateKeeperService;
 import android.stats.devicepolicy.DevicePolicyEnums;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.IntArray;
@@ -152,6 +156,7 @@
     private static final String TAG_NAME = "name";
     private static final String TAG_ACCOUNT = "account";
     private static final String ATTR_FLAGS = "flags";
+    private static final String ATTR_TYPE = "type";
     private static final String ATTR_ICON_PATH = "icon";
     private static final String ATTR_ID = "id";
     private static final String ATTR_CREATION_TIME = "created";
@@ -220,15 +225,10 @@
     @VisibleForTesting
     static final int MAX_RECENTLY_REMOVED_IDS_SIZE = 100;
 
-    private static final int USER_VERSION = 8;
+    private static final int USER_VERSION = 9;
 
     private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms
 
-    // Maximum number of managed profiles permitted per user is 1. This cannot be increased
-    // without first making sure that the rest of the framework is prepared for it.
-    @VisibleForTesting
-    static final int MAX_MANAGED_PROFILES = 1;
-
     static final int WRITE_USER_MSG = 1;
     static final int WRITE_USER_DELAY = 2*1000;  // 2 seconds
 
@@ -304,6 +304,12 @@
     private final SparseArray<UserData> mUsers = new SparseArray<>();
 
     /**
+     * Map of user type names to their corresponding {@link UserTypeDetails}.
+     * Should not be modified after UserManagerService constructor finishes.
+     */
+    private final ArrayMap<String, UserTypeDetails> mUserTypes;
+
+    /**
      * User restrictions set via UserManager.  This doesn't include restrictions set by
      * device owner / profile owners. Only non-empty restriction bundles are stored.
      *
@@ -543,6 +549,7 @@
         mPackagesLock = packagesLock;
         mHandler = new MainHandler();
         mUserDataPreparer = userDataPreparer;
+        mUserTypes = UserTypeFactory.getUserTypes();
         synchronized (mPackagesLock) {
             mUsersDir = new File(dataDir, USER_INFO_DIR);
             mUsersDir.mkdirs();
@@ -700,22 +707,37 @@
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mUsersLock) {
-                return getProfilesLU(userId, enabledOnly, returnFullInfo);
+                return getProfilesLU(userId, /* userType */ null, enabledOnly, returnFullInfo);
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
     }
 
+    // TODO(b/142482943): Will probably need a getProfiles(userType). But permissions may vary.
+
     @Override
     public int[] getProfileIds(@UserIdInt int userId, boolean enabledOnly) {
+        return getProfileIds(userId, null, enabledOnly);
+    }
+
+    // TODO(b/142482943): Probably @Override and make this accessible in UserManager.
+    /**
+     * Returns all the users of type userType that are in the same profile group as userId
+     * (including userId itself, if it is of the appropriate user type).
+     *
+     * <p>If userType is non-{@code null}, only returns users that are of type userType.
+     * If enabledOnly, only returns users that are not {@link UserInfo#FLAG_DISABLED}.
+     */
+    public int[] getProfileIds(@UserIdInt int userId, @Nullable String userType,
+            boolean enabledOnly) {
         if (userId != UserHandle.getCallingUserId()) {
             checkManageOrCreateUsersPermission("getting profiles related to user " + userId);
         }
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mUsersLock) {
-                return getProfileIdsLU(userId, enabledOnly).toArray();
+                return getProfileIdsLU(userId, userType, enabledOnly).toArray();
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -724,9 +746,9 @@
 
     /** Assume permissions already checked and caller's identity cleared */
     @GuardedBy("mUsersLock")
-    private List<UserInfo> getProfilesLU(@UserIdInt int userId, boolean enabledOnly,
-            boolean fullInfo) {
-        IntArray profileIds = getProfileIdsLU(userId, enabledOnly);
+    private List<UserInfo> getProfilesLU(@UserIdInt int userId, @Nullable String userType,
+            boolean enabledOnly, boolean fullInfo) {
+        IntArray profileIds = getProfileIdsLU(userId, userType, enabledOnly);
         ArrayList<UserInfo> users = new ArrayList<>(profileIds.size());
         for (int i = 0; i < profileIds.size(); i++) {
             int profileId = profileIds.get(i);
@@ -746,9 +768,12 @@
 
     /**
      *  Assume permissions already checked and caller's identity cleared
+     *  <p>If userType is {@code null}, returns all profiles for user; else, only returns
+     *  profiles of that type.
      */
     @GuardedBy("mUsersLock")
-    private IntArray getProfileIdsLU(@UserIdInt int userId, boolean enabledOnly) {
+    private IntArray getProfileIdsLU(@UserIdInt int userId, @Nullable String userType,
+            boolean enabledOnly) {
         UserInfo user = getUserInfoLU(userId);
         IntArray result = new IntArray(mUsers.size());
         if (user == null) {
@@ -770,6 +795,9 @@
             if (profile.partial) {
                 continue;
             }
+            if (userType != null && !userType.equals(profile.userType)) {
+                continue;
+            }
             result.add(profile.id);
         }
         return result;
@@ -1116,6 +1144,45 @@
         }
     }
 
+    /**
+     * Returns the user type, e.g. {@link UserManager#USER_TYPE_FULL_GUEST}, of the given userId,
+     * or null if the user doesn't exist.
+     */
+    @Override
+    public @Nullable String getUserTypeForUser(@UserIdInt int userId) {
+        // TODO(b/142482943): Decide on the appropriate permission requirements.
+        checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "getUserTypeForUser");
+        return getUserTypeNoChecks(userId);
+    }
+
+    /**
+     * Returns the user type of the given userId, or null if the user doesn't exist.
+     * <p>No permissions checks are made (but userId checks may be made).
+     */
+    private @Nullable String getUserTypeNoChecks(@UserIdInt int userId) {
+        synchronized (mUsersLock) {
+            final UserInfo userInfo = getUserInfoLU(userId);
+            return userInfo != null ? userInfo.userType : null;
+        }
+    }
+
+    /**
+     * Returns the UserTypeDetails of the given userId's user type, or null if the no such user.
+     * <p>No permissions checks are made (but userId checks may be made).
+     */
+    private @Nullable UserTypeDetails getUserTypeDetailsNoChecks(@UserIdInt int userId) {
+        final String typeStr = getUserTypeNoChecks(userId);
+        return typeStr != null ? mUserTypes.get(typeStr) : null;
+    }
+
+    /**
+     * Returns the UserTypeDetails of the given userInfo's user type (or null for a null userInfo).
+     */
+    private @Nullable UserTypeDetails getUserTypeDetails(@Nullable UserInfo userInfo) {
+        final String typeStr = userInfo != null ? userInfo.userType : null;
+        return typeStr != null ? mUserTypes.get(typeStr) : null;
+    }
+
     @Override
     public UserInfo getUserInfo(@UserIdInt int userId) {
         checkManageOrCreateUsersPermission("query user");
@@ -1139,11 +1206,78 @@
     }
 
     @Override
-    public int getManagedProfileBadge(@UserIdInt int userId) {
-        checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "getManagedProfileBadge");
+    public boolean hasBadge(@UserIdInt int userId) {
+        checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "hasBadge");
+        final UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId);
+        return userTypeDetails != null && userTypeDetails.hasBadge();
+    }
+
+    @Override
+    public @StringRes int getUserBadgeLabelResId(@UserIdInt int userId) {
+        checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "getUserBadgeLabelResId");
+        final UserInfo userInfo = getUserInfoNoChecks(userId);
+        final UserTypeDetails userTypeDetails = getUserTypeDetails(userInfo);
+        if (userInfo == null || userTypeDetails == null || !userTypeDetails.hasBadge()) {
+            Slog.e(LOG_TAG, "Requested badge label for non-badged user " + userId);
+            return Resources.ID_NULL;
+        }
+        final int badgeIndex = userInfo.profileBadge;
+        return userTypeDetails.getBadgeLabel(badgeIndex);
+    }
+
+    @Override
+    public @ColorRes int getUserBadgeColorResId(@UserIdInt int userId) {
+        checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "getUserBadgeColorResId");
+        final UserInfo userInfo = getUserInfoNoChecks(userId);
+        final UserTypeDetails userTypeDetails = getUserTypeDetails(userInfo);
+        if (userInfo == null || userTypeDetails == null || !userTypeDetails.hasBadge()) {
+            Slog.e(LOG_TAG, "Requested badge color for non-badged user " + userId);
+            return Resources.ID_NULL;
+        }
+        final int badgeIndex = userInfo.profileBadge;
+        return userTypeDetails.getBadgeColor(badgeIndex);
+    }
+
+    @Override
+    public @DrawableRes int getUserIconBadgeResId(@UserIdInt int userId) {
+        checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "getUserIconBadgeResId");
+        final UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId);
+        if (userTypeDetails == null || !userTypeDetails.hasBadge()) {
+            Slog.e(LOG_TAG, "Requested icon badge for non-badged user " + userId);
+            return Resources.ID_NULL;
+        }
+        return userTypeDetails.getIconBadge();
+    }
+
+    @Override
+    public @DrawableRes int getUserBadgeResId(@UserIdInt int userId) {
+        checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "getUserBadgeResId");
+        final UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId);
+        if (userTypeDetails == null || !userTypeDetails.hasBadge()) {
+            Slog.e(LOG_TAG, "Requested badge for non-badged user " + userId);
+            return Resources.ID_NULL;
+        }
+        return userTypeDetails.getBadgePlain();
+    }
+
+    @Override
+    public @DrawableRes int getUserBadgeNoBackgroundResId(@UserIdInt int userId) {
+        checkManageOrInteractPermIfCallerInOtherProfileGroup(userId,
+                "getUserBadgeNoBackgroundResId");
+        final UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId);
+        if (userTypeDetails == null || !userTypeDetails.hasBadge()) {
+            Slog.e(LOG_TAG, "Requested badge (no background) for non-badged user " + userId);
+            return Resources.ID_NULL;
+        }
+        return userTypeDetails.getBadgeNoBackground();
+    }
+
+    @Override
+    public boolean isProfile(@UserIdInt int userId) {
+        checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "isProfile");
         synchronized (mUsersLock) {
             UserInfo userInfo = getUserInfoLU(userId);
-            return userInfo != null ? userInfo.profileBadge : 0;
+            return userInfo != null && userInfo.isProfile();
         }
     }
 
@@ -1896,33 +2030,93 @@
         return count >= UserManager.getMaxSupportedUsers();
     }
 
+    /**
+     * Returns whether more users of the given type can be added (based on how many users of that
+     * type already exist).
+     *
+     * <p>For checking whether more profiles can be added to a particular parent use
+     * {@link #canAddMoreProfilesToUser}.
+     */
+    private boolean canAddMoreUsersOfType(UserTypeDetails userTypeDetails) {
+        final int max = userTypeDetails.getMaxAllowed();
+        if (max == UserTypeDetails.UNLIMITED_NUMBER_OF_USERS) {
+            return true; // Indicates that there is no max.
+        }
+        return getNumberOfUsersOfType(userTypeDetails.getName()) < max;
+    }
+
+    /**
+     * Gets the number of users of the given user type.
+     * Does not include users that are about to die.
+     */
+    private int getNumberOfUsersOfType(String userType) {
+        int count = 0;
+        synchronized (mUsersLock) {
+            final int size = mUsers.size();
+            for (int i = 0; i < size; i++) {
+                final UserInfo user = mUsers.valueAt(i).info;
+                if (user.userType.equals(userType)
+                        && !user.guestToRemove
+                        && !mRemovingUserIds.get(user.id)
+                        && !user.preCreated) {
+                    count++;
+                }
+            }
+        }
+        return count;
+    }
+
     @Override
     public boolean canAddMoreManagedProfiles(@UserIdInt int userId, boolean allowedToRemoveOne) {
-        checkManageUsersPermission("check if more managed profiles can be added.");
-        if (ActivityManager.isLowRamDeviceStatic()) {
+        return canAddMoreProfilesToUser(UserManager.USER_TYPE_PROFILE_MANAGED, userId,
+                allowedToRemoveOne);
+    }
+
+    /** Returns whether more profiles of the given type can be added to the given parent userId. */
+    @Override
+    public boolean canAddMoreProfilesToUser(String userType, @UserIdInt int userId,
+            boolean allowedToRemoveOne) {
+        checkManageUsersPermission("check if more profiles can be added.");
+        final UserTypeDetails type = mUserTypes.get(userType);
+        if (type == null) {
             return false;
         }
-        if (!mContext.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_MANAGED_USERS)) {
-            return false;
+        // Managed profiles have their own specific rules.
+        final boolean isManagedProfile = type.isManagedProfile();
+        if (isManagedProfile) {
+            if (ActivityManager.isLowRamDeviceStatic()) {
+                return false;
+            }
+            if (!mContext.getPackageManager().hasSystemFeature(
+                    PackageManager.FEATURE_MANAGED_USERS)) {
+                return false;
+            }
         }
-        // Limit number of managed profiles that can be created
-        final int managedProfilesCount = getProfiles(userId, false).size() - 1;
-        final int profilesRemovedCount = managedProfilesCount > 0 && allowedToRemoveOne ? 1 : 0;
-        if (managedProfilesCount - profilesRemovedCount >= getMaxManagedProfiles()) {
-            return false;
-        }
-        synchronized(mUsersLock) {
+        synchronized (mUsersLock) {
+            // Check if the parent exists and its type is even allowed to have a profile.
             UserInfo userInfo = getUserInfoLU(userId);
             if (userInfo == null || !userInfo.canHaveProfile()) {
                 return false;
             }
-            int usersCountAfterRemoving = getAliveUsersExcludingGuestsCountLU()
-                    - profilesRemovedCount;
-            // We allow creating a managed profile in the special case where there is only one user.
-            return usersCountAfterRemoving  == 1
-                    || usersCountAfterRemoving < UserManager.getMaxSupportedUsers();
+
+            // Limit the number of profiles that can be created
+            final int maxUsersOfType = getMaxUsersOfTypePerParent(type);
+            if (maxUsersOfType != UserTypeDetails.UNLIMITED_NUMBER_OF_USERS) {
+                final int userTypeCount = getProfileIds(userId, userType, false).length;
+                final int profilesRemovedCount = userTypeCount > 0 && allowedToRemoveOne ? 1 : 0;
+                if (userTypeCount - profilesRemovedCount >= maxUsersOfType) {
+                    return false;
+                }
+                // Allow creating a managed profile in the special case where there is only one user
+                if (isManagedProfile) {
+                    int usersCountAfterRemoving = getAliveUsersExcludingGuestsCountLU()
+                            - profilesRemovedCount;
+                    return usersCountAfterRemoving == 1
+                            || usersCountAfterRemoving < UserManager.getMaxSupportedUsers();
+                }
+            }
         }
+        return true;
     }
 
     @GuardedBy("mUsersLock")
@@ -2207,9 +2401,18 @@
      */
     @GuardedBy({"mRestrictionsLock", "mPackagesLock"})
     private void upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions) {
+        upgradeIfNecessaryLP(oldGlobalUserRestrictions, mUserVersion);
+    }
+
+    /**
+     * Version of {@link #upgradeIfNecessaryLP(Bundle)} that takes in the userVersion for testing
+     * purposes. For non-tests, use {@link #upgradeIfNecessaryLP(Bundle)}.
+     */
+    @GuardedBy({"mRestrictionsLock", "mPackagesLock"})
+    @VisibleForTesting
+    void upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions, int userVersion) {
         Set<Integer> userIdsToWrite = new ArraySet<>();
         final int originalVersion = mUserVersion;
-        int userVersion = mUserVersion;
         if (userVersion < 1) {
             // Assign a proper name for the owner, if not initialized correctly before
             UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM);
@@ -2298,6 +2501,44 @@
             userVersion = 8;
         }
 
+        if (userVersion < 9) {
+            // Convert from UserInfo flags to UserTypes. Apply FLAG_PROFILE to FLAG_MANAGED_PROFILE.
+            synchronized (mUsersLock) {
+                for (int i = 0; i < mUsers.size(); i++) {
+                    UserData userData = mUsers.valueAt(i);
+                    final int flags = userData.info.flags;
+                    if ((flags & UserInfo.FLAG_SYSTEM) != 0) {
+                        if ((flags & UserInfo.FLAG_FULL) != 0) {
+                            userData.info.userType = UserManager.USER_TYPE_FULL_SYSTEM;
+                        } else {
+                            userData.info.userType = UserManager.USER_TYPE_SYSTEM_HEADLESS;
+                        }
+                    } else {
+                        try {
+                            userData.info.userType = UserInfo.getDefaultUserType(flags);
+                        } catch (IllegalArgumentException e) {
+                            // TODO(b/142482943): What should we do here? Delete user? Crashloop?
+                            throw new IllegalStateException("Cannot upgrade user with flags "
+                                    + Integer.toHexString(flags) + " because it doesn't correspond "
+                                    + "to a valid user type.", e);
+                        }
+                    }
+                    // OEMs are responsible for their own custom upgrade logic here.
+
+                    final UserTypeDetails userTypeDetails = mUserTypes.get(userData.info.userType);
+                    if (userTypeDetails == null) {
+                        throw new IllegalStateException(
+                                "Cannot upgrade user with flags " + Integer.toHexString(flags)
+                                        + " because " + userData.info.userType + " isn't defined"
+                                        + " on this device!");
+                    }
+                    userData.info.flags |= userTypeDetails.getDefaultUserInfoFlags();
+                    userIdsToWrite.add(userData.info.id);
+                }
+            }
+            userVersion = 9;
+        }
+
         if (userVersion < USER_VERSION) {
             Slog.w(LOG_TAG, "User version " + mUserVersion + " didn't upgrade as expected to "
                     + USER_VERSION);
@@ -2320,12 +2561,11 @@
     private void fallbackToSingleUserLP() {
         int flags = UserInfo.FLAG_SYSTEM | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN
                 | UserInfo.FLAG_PRIMARY;
-        // In headless system user mode, headless system user is not a full user.
-        if (!UserManager.isHeadlessSystemUserMode()) {
-            flags |= UserInfo.FLAG_FULL;
-        }
         // Create the system user
-        UserInfo system = new UserInfo(UserHandle.USER_SYSTEM, null, null, flags);
+        String systemUserType = UserManager.isHeadlessSystemUserMode() ?
+                UserManager.USER_TYPE_SYSTEM_HEADLESS : UserManager.USER_TYPE_FULL_SYSTEM;
+        flags |= mUserTypes.get(systemUserType).getDefaultUserInfoFlags();
+        UserInfo system = new UserInfo(UserHandle.USER_SYSTEM, null, null, flags, systemUserType);
         UserData userData = putUserInfo(system);
         mNextSerialNumber = MIN_USER_ID;
         mUserVersion = USER_VERSION;
@@ -2410,6 +2650,7 @@
         serializer.attribute(null, ATTR_ID, Integer.toString(userInfo.id));
         serializer.attribute(null, ATTR_SERIAL_NO, Integer.toString(userInfo.serialNumber));
         serializer.attribute(null, ATTR_FLAGS, Integer.toString(userInfo.flags));
+        serializer.attribute(null, ATTR_TYPE, userInfo.userType);
         serializer.attribute(null, ATTR_CREATION_TIME, Long.toString(userInfo.creationTime));
         serializer.attribute(null, ATTR_LAST_LOGGED_IN_TIME,
                 Long.toString(userInfo.lastLoggedInTime));
@@ -2570,6 +2811,7 @@
     UserData readUserLP(int id, InputStream is) throws IOException,
             XmlPullParserException {
         int flags = 0;
+        String userType = null;
         int serialNumber = id;
         String name = null;
         String account = null;
@@ -2613,6 +2855,8 @@
             }
             serialNumber = readIntAttribute(parser, ATTR_SERIAL_NO, id);
             flags = readIntAttribute(parser, ATTR_FLAGS, 0);
+            userType = parser.getAttributeValue(null, ATTR_TYPE);
+            userType = userType != null ? userType.intern() : null;
             iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH);
             creationTime = readLongAttribute(parser, ATTR_CREATION_TIME, 0);
             lastLoggedInTime = readLongAttribute(parser, ATTR_LAST_LOGGED_IN_TIME, 0);
@@ -2678,7 +2922,7 @@
         }
 
         // Create the UserInfo object that gets passed around
-        UserInfo userInfo = new UserInfo(id, name, iconPath, flags);
+        UserInfo userInfo = new UserInfo(id, name, iconPath, flags, userType);
         userInfo.serialNumber = serialNumber;
         userInfo.creationTime = creationTime;
         userInfo.lastLoggedInTime = lastLoggedInTime;
@@ -2745,108 +2989,135 @@
         }
     }
 
+    /**
+     * Creates a profile user. Used for actual profiles, like
+     * {@link UserManager#USER_TYPE_PROFILE_MANAGED}, as well as for
+     * {@link UserManager#USER_TYPE_FULL_RESTRICTED}.
+     */
     @Override
-    public UserInfo createProfileForUser(String name, int flags, @UserIdInt int userId,
-            String[] disallowedPackages) {
+    public UserInfo createProfileForUser(String name, @NonNull String userType,
+            @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages) {
         checkManageOrCreateUsersPermission(flags);
-        return createUserInternal(name, flags, userId, disallowedPackages);
+        return createUserInternal(name, userType, flags, userId, disallowedPackages);
+    }
+
+    /** @see #createProfileForUser */
+    @Override
+    public UserInfo createProfileForUserEvenWhenDisallowed(String name, @NonNull String userType,
+            @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages) {
+        checkManageOrCreateUsersPermission(flags);
+        return createUserInternalUnchecked(name, userType, flags, userId,
+                /* preCreate= */ false, disallowedPackages);
     }
 
     @Override
-    public UserInfo createProfileForUserEvenWhenDisallowed(String name, int flags,
-            @UserIdInt int userId, String[] disallowedPackages) {
+    public UserInfo createUser(String name, @NonNull String userType, @UserInfoFlag int flags) {
         checkManageOrCreateUsersPermission(flags);
-        return createUserInternalUnchecked(name, flags, userId, /* preCreate= */ false,
-                disallowedPackages);
+        return createUserInternal(name, userType, flags, UserHandle.USER_NULL,
+                /* disallowedPackages= */ null);
     }
 
     @Override
-    public boolean removeUserEvenWhenDisallowed(@UserIdInt int userId) {
-        checkManageOrCreateUsersPermission("Only the system can remove users");
-        return removeUserUnchecked(userId);
-    }
+    public UserInfo preCreateUser(String userType) {
+        final UserTypeDetails userTypeDetails = mUserTypes.get(userType);
+        final int flags = userTypeDetails != null ? userTypeDetails.getDefaultUserInfoFlags() : 0;
 
-    @Override
-    public UserInfo createUser(String name, int flags) {
-        checkManageOrCreateUsersPermission(flags);
-        return createUserInternal(name, flags, UserHandle.USER_NULL);
-    }
-
-    @Override
-    public UserInfo preCreateUser(int flags) {
         checkManageOrCreateUsersPermission(flags);
 
-        Preconditions.checkArgument(!UserInfo.isManagedProfile(flags),
-                "cannot pre-create managed profiles");
+        Preconditions.checkArgument(isUserTypeEligibleForPreCreation(userTypeDetails),
+                "cannot pre-create user of type " + userType);
+        Slog.i(LOG_TAG, "Pre-creating user of type " + userType);
 
-        Slog.i(LOG_TAG, "Pre-creating user with flags " + UserInfo.flagsToString(flags));
-
-        return createUserInternalUnchecked(/* name= */ null, flags,
+        return createUserInternalUnchecked(/* name= */ null, userType, flags,
                 /* parentId= */ UserHandle.USER_NULL, /* preCreate= */ true,
                 /* disallowedPackages= */ null);
     }
 
-    private UserInfo createUserInternal(@Nullable String name, @UserInfoFlag int flags,
-            @UserIdInt int parentId) {
-        return createUserInternal(name, flags, parentId, null);
-    }
-
-    private UserInfo createUserInternal(@Nullable String name, @UserInfoFlag int flags,
-            @UserIdInt int parentId, @Nullable String[] disallowedPackages) {
-        String restriction = ((flags & UserInfo.FLAG_MANAGED_PROFILE) != 0)
+    private UserInfo createUserInternal(@Nullable String name, @NonNull String userType,
+            @UserInfoFlag int flags, @UserIdInt int parentId,
+            @Nullable String[] disallowedPackages) {
+        String restriction = (UserManager.isUserTypeManagedProfile(userType))
                 ? UserManager.DISALLOW_ADD_MANAGED_PROFILE
                 : UserManager.DISALLOW_ADD_USER;
         if (hasUserRestriction(restriction, UserHandle.getCallingUserId())) {
             Log.w(LOG_TAG, "Cannot add user. " + restriction + " is enabled.");
             return null;
         }
-        return createUserInternalUnchecked(name, flags, parentId, /* preCreate= */ false,
-                disallowedPackages);
+        return createUserInternalUnchecked(name, userType, flags, parentId,
+                /* preCreate= */ false, disallowedPackages);
     }
 
-    private UserInfo createUserInternalUnchecked(@Nullable String name, @UserInfoFlag int flags,
-            @UserIdInt int parentId, boolean preCreate,
-            @Nullable String[] disallowedPackages) {
+    private UserInfo createUserInternalUnchecked(@Nullable String name,
+            @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId,
+            boolean preCreate, @Nullable String[] disallowedPackages) {
         final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
         t.traceBegin("createUser-" + flags);
         try {
-            return createUserInternalUncheckedNoTracing(name, flags, parentId, preCreate,
-                disallowedPackages, t);
+            return createUserInternalUncheckedNoTracing(name, userType, flags, parentId,
+                    preCreate, disallowedPackages, t);
         } finally {
             t.traceEnd();
         }
     }
 
     private UserInfo createUserInternalUncheckedNoTracing(@Nullable String name,
-            @UserInfoFlag int flags, @UserIdInt int parentId, boolean preCreate,
-            @Nullable String[] disallowedPackages, @NonNull TimingsTraceAndSlog t) {
+            @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId,
+            boolean preCreate, @Nullable String[] disallowedPackages,
+            @NonNull TimingsTraceAndSlog t) {
+
+        final UserTypeDetails userTypeDetails = mUserTypes.get(userType);
+        if (userTypeDetails == null) {
+            Slog.e(LOG_TAG, "Cannot create user of invalid user type: " + userType);
+            return null;
+        }
+        userType = userType.intern(); // Now that we know it's valid, we can intern it.
+        flags |= userTypeDetails.getDefaultUserInfoFlags();
+        if (!checkUserTypeConsistency(flags)) {
+            Slog.e(LOG_TAG, "Cannot add user. Flags (" + Integer.toHexString(flags)
+                    + ") and userTypeDetails (" + userType +  ") are inconsistent.");
+            return null;
+        }
+        if ((flags & UserInfo.FLAG_SYSTEM) != 0) {
+            Slog.e(LOG_TAG, "Cannot add user. Flags (" + Integer.toHexString(flags)
+                    + ") indicated SYSTEM user, which cannot be created.");
+            return null;
+        }
+        synchronized (mUsersLock) {
+            if (mForceEphemeralUsers) {
+                flags |= UserInfo.FLAG_EPHEMERAL;
+            }
+        }
 
         // First try to use a pre-created user (if available).
-        // NOTE: currently we don't support pre-created managed profiles
-        if (!preCreate && (parentId < 0 && !UserInfo.isManagedProfile(flags))) {
+        // TODO(b/142482943): Move this to its own function later.
+        if (!preCreate
+                && (parentId < 0 && isUserTypeEligibleForPreCreation(userTypeDetails))) {
             final UserData preCreatedUserData;
             synchronized (mUsersLock) {
-                preCreatedUserData = getPreCreatedUserLU(flags);
+                preCreatedUserData = getPreCreatedUserLU(userType);
             }
             if (preCreatedUserData != null) {
                 final UserInfo preCreatedUser = preCreatedUserData.info;
-                Log.i(LOG_TAG, "Reusing pre-created user " + preCreatedUser.id + " for flags + "
-                        + UserInfo.flagsToString(flags));
-                if (DBG) {
-                    Log.d(LOG_TAG, "pre-created user flags: "
-                            + UserInfo.flagsToString(preCreatedUser.flags)
-                            + " new-user flags: " + UserInfo.flagsToString(flags));
+                final int newFlags = preCreatedUser.flags | flags;
+                if (!checkUserTypeConsistency(newFlags)) {
+                    Slog.wtf(LOG_TAG, "Cannot reuse pre-created user " + preCreatedUser.id
+                            + " of type " + userType + " because flags are inconsistent. "
+                            + "Flags (" + Integer.toHexString(flags) + "); preCreatedUserFlags ( "
+                            + Integer.toHexString(preCreatedUser.flags) + ").");
+                } else {
+                    Log.i(LOG_TAG, "Reusing pre-created user " + preCreatedUser.id + " of type "
+                            + userType + " and bestowing on it flags "
+                            + UserInfo.flagsToString(flags));
+                    preCreatedUser.name = name;
+                    preCreatedUser.flags = newFlags;
+                    preCreatedUser.preCreated = false;
+                    preCreatedUser.creationTime = getCreationTime();
+
+                    dispatchUserAddedIntent(preCreatedUser);
+                    writeUserLP(preCreatedUserData);
+                    writeUserListLP();
+                    return preCreatedUser;
                 }
-                preCreatedUser.name = name;
-                preCreatedUser.preCreated = false;
-                preCreatedUser.creationTime = getCreationTime();
-
-                dispatchUserAddedIntent(preCreatedUser);
-
-                writeUserLP(preCreatedUserData);
-                writeUserListLP();
-
-                return preCreatedUser;
             }
         }
 
@@ -2857,10 +3128,11 @@
             return null;
         }
 
-        final boolean isGuest = UserInfo.isGuest(flags);
-        final boolean isManagedProfile = UserInfo.isManagedProfile(flags);
-        final boolean isRestricted = (flags & UserInfo.FLAG_RESTRICTED) != 0;
-        final boolean isDemo = (flags & UserInfo.FLAG_DEMO) != 0;
+        final boolean isProfile = userTypeDetails.isProfile();
+        final boolean isGuest = UserManager.isUserTypeGuest(userType);
+        final boolean isRestricted = UserManager.isUserTypeRestricted(userType);
+        final boolean isDemo = UserManager.isUserTypeDemo(userType);
+
         final long ident = Binder.clearCallingIdentity();
         UserInfo userInfo;
         UserData userData;
@@ -2874,21 +3146,23 @@
                     }
                     if (parent == null) return null;
                 }
-                if (isManagedProfile && !canAddMoreManagedProfiles(parentId, false)) {
-                    Log.e(LOG_TAG, "Cannot add more managed profiles for user " + parentId);
+                if (!preCreate && !canAddMoreUsersOfType(userTypeDetails)) {
+                    Log.e(LOG_TAG, "Cannot add more users of type " + userType
+                            + ". Maximum number of that type already exists.");
                     return null;
                 }
-                if (!isGuest && !isManagedProfile && !isDemo && isUserLimitReached()) {
-                    // If we're not adding a guest/demo user or a managed profile,
-                    // and the limit has been reached, cannot add a user.
+                // TODO(b/142482943): Perhaps let the following code apply to restricted users too.
+                if (isProfile && !canAddMoreProfilesToUser(userType, parentId, false)) {
+                    Log.e(LOG_TAG, "Cannot add more profiles of type " + userType
+                            + " for user " + parentId);
+                    return null;
+                }
+                if (!isGuest && !isProfile && !isDemo && isUserLimitReached()) {
+                    // If we're not adding a guest/demo user or a profile and the 'user limit' has
+                    // been reached, cannot add a user.
                     Log.e(LOG_TAG, "Cannot add user. Maximum user limit is reached.");
                     return null;
                 }
-                // If we're adding a guest and there already exists one, bail.
-                if (isGuest && !preCreate && findCurrentGuestUser() != null) {
-                    Log.e(LOG_TAG, "Cannot add guest user. Guest user already exists.");
-                    return null;
-                }
                 // In legacy mode, restricted profile's parent can only be the owner user
                 if (isRestricted && !UserManager.isSplitSystemUser()
                         && (parentId != UserHandle.USER_SYSTEM)) {
@@ -2908,30 +3182,23 @@
                     }
                 }
 
-                if (!isManagedProfile) {
-                    // New users cannot be system, and it's not a profile, so per-force it's FULL.
-                    flags |= UserInfo.FLAG_FULL;
-                }
-
                 userId = getNextAvailableId();
                 Environment.getUserSystemDirectory(userId).mkdirs();
-                boolean ephemeralGuests = areGuestUsersEphemeral();
 
                 synchronized (mUsersLock) {
-                    // Add ephemeral flag to guests/users if required. Also inherit it from parent.
-                    if ((isGuest && ephemeralGuests) || mForceEphemeralUsers
-                            || (parent != null && parent.info.isEphemeral())) {
+                    // Inherit ephemeral flag from parent.
+                    if (parent != null && parent.info.isEphemeral()) {
                         flags |= UserInfo.FLAG_EPHEMERAL;
                     }
 
-                    userInfo = new UserInfo(userId, name, null, flags);
+                    userInfo = new UserInfo(userId, name, null, flags, userType);
                     userInfo.serialNumber = mNextSerialNumber++;
                     userInfo.creationTime = getCreationTime();
                     userInfo.partial = true;
                     userInfo.preCreated = preCreate;
                     userInfo.lastLoggedInFingerprint = Build.FINGERPRINT;
-                    if (isManagedProfile && parentId != UserHandle.USER_NULL) {
-                        userInfo.profileBadge = getFreeProfileBadgeLU(parentId);
+                    if (userTypeDetails.hasBadge() && parentId != UserHandle.USER_NULL) {
+                        userInfo.profileBadge = getFreeProfileBadgeLU(parentId, userType);
                     }
                     userData = new UserData();
                     userData.info = userInfo;
@@ -2940,7 +3207,7 @@
                 writeUserLP(userData);
                 writeUserListLP();
                 if (parent != null) {
-                    if (isManagedProfile) {
+                    if (isProfile) {
                         if (parent.info.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
                             parent.info.profileGroupId = parent.info.id;
                             writeUserLP(parent);
@@ -2966,7 +3233,7 @@
                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
             t.traceEnd();
 
-            final Set<String> installablePackages =
+            final Set<String> installablePackages = // TODO(b/142482943): use userType
                     mSystemPackageInstaller.getInstallablePackagesForUserType(flags);
             t.traceBegin("PM.createNewUser");
             mPm.createNewUser(userId, installablePackages, disallowedPackages);
@@ -2978,6 +3245,7 @@
             }
             updateUserIds();
             Bundle restrictions = new Bundle();
+            // TODO(b/142482943): Generalize this using UserTypeDetails default restrictions.
             if (isGuest) {
                 synchronized (mGuestRestrictions) {
                     restrictions.putAll(mGuestRestrictions);
@@ -3026,6 +3294,22 @@
         return userInfo;
     }
 
+    /** Checks that the flags do not contain mutually exclusive types/properties. */
+    static boolean checkUserTypeConsistency(@UserInfoFlag int flags) {
+        // Mask to check that flags don't refer to multiple user types.
+        final int userTypeFlagMask = UserInfo.FLAG_GUEST | UserInfo.FLAG_DEMO
+                | UserInfo.FLAG_RESTRICTED | UserInfo.FLAG_PROFILE;
+        return isAtMostOneFlag(flags & userTypeFlagMask)
+                && isAtMostOneFlag(flags & (UserInfo.FLAG_PROFILE | UserInfo.FLAG_FULL))
+                && isAtMostOneFlag(flags & (UserInfo.FLAG_PROFILE | UserInfo.FLAG_SYSTEM));
+    }
+
+    /** Returns whether the given flags contains at most one 1. */
+    private static boolean isAtMostOneFlag(int flags) {
+        return (flags & (flags - 1)) == 0;
+        // If !=0, this means that flags is not a power of 2, and therefore is multiple types.
+    }
+
     /** Install/uninstall system packages for all users based on their user-type, as applicable. */
     boolean installWhitelistedSystemPackages(boolean isFirstBoot, boolean isUpgrade) {
         return mSystemPackageInstaller.installWhitelistedSystemPackages(isFirstBoot, isUpgrade);
@@ -3045,39 +3329,23 @@
                 : (userInfo.isDemo() ? TRON_DEMO_CREATED : TRON_USER_CREATED), 1);
     }
 
-    private boolean areGuestUsersEphemeral() {
-        return Resources.getSystem()
-                .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
-    }
-
     /**
-     * Gets a pre-created user for the given flag.
+     * Gets a pre-created user for the given user type.
      *
      * <p>Should be used only during user creation, so the pre-created user can be used (instead of
      * creating and initializing a new user from scratch).
      */
     // TODO(b/143092698): add unit test
     @GuardedBy("mUsersLock")
-    private @Nullable UserData getPreCreatedUserLU(@UserInfoFlag int flags) {
-        if (DBG) {
-            Slog.d(LOG_TAG, "getPreCreatedUser(): initialFlags= " + UserInfo.flagsToString(flags));
-        }
-        flags |= UserInfo.FLAG_FULL;
-        if (UserInfo.isGuest(flags) && areGuestUsersEphemeral()) {
-            flags |= UserInfo.FLAG_EPHEMERAL;
-        }
-        if (DBG) {
-            Slog.d(LOG_TAG, "getPreCreatedUser(): targetFlags= " + UserInfo.flagsToString(flags));
-        }
+    private @Nullable UserData getPreCreatedUserLU(String userType) {
+        if (DBG) Slog.d(LOG_TAG, "getPreCreatedUser(): userType= " + userType);
         final int userSize = mUsers.size();
         for (int i = 0; i < userSize; i++) {
             final UserData user = mUsers.valueAt(i);
             if (DBG) Slog.d(LOG_TAG, i + ":" + user.info.toFullString());
-            if (user.info.preCreated
-                    && (user.info.flags & ~UserInfo.FLAG_INITIALIZED) == flags) {
+            if (user.info.preCreated && user.info.userType.equals(userType)) {
                 if (!user.info.isInitialized()) {
-                    Slog.w(LOG_TAG, "found pre-created user for flags "
-                            + "" + UserInfo.flagsToString(flags)
+                    Slog.w(LOG_TAG, "found pre-created user of type " + userType
                             + ", but it's not initialized yet: " + user.info.toFullString());
                     continue;
                 }
@@ -3087,6 +3355,18 @@
         return null;
     }
 
+    /**
+     * Returns whether a user with the given userTypeDetails is eligible to be
+     * {@link UserInfo#preCreated}.
+     */
+    private static boolean isUserTypeEligibleForPreCreation(UserTypeDetails userTypeDetails) {
+        if (userTypeDetails == null) {
+            return false;
+        }
+        return !userTypeDetails.isProfile()
+                && !userTypeDetails.getName().equals(UserManager.USER_TYPE_FULL_RESTRICTED);
+    }
+
     @VisibleForTesting
     UserData putUserInfo(UserInfo userInfo) {
         final UserData userData = new UserData();
@@ -3111,7 +3391,7 @@
     public UserInfo createRestrictedProfile(String name, int parentUserId) {
         checkManageOrCreateUsersPermission("setupRestrictedProfile");
         final UserInfo user = createProfileForUser(
-                name, UserInfo.FLAG_RESTRICTED, parentUserId, null);
+                name, UserManager.USER_TYPE_FULL_RESTRICTED, 0, parentUserId, null);
         if (user == null) {
             return null;
         }
@@ -3217,6 +3497,12 @@
         return removeUserUnchecked(userId);
     }
 
+    @Override
+    public boolean removeUserEvenWhenDisallowed(@UserIdInt int userId) {
+        checkManageOrCreateUsersPermission("Only the system can remove users");
+        return removeUserUnchecked(userId);
+    }
+
     private boolean removeUserUnchecked(@UserIdInt int userId) {
         long ident = Binder.clearCallingIdentity();
         try {
@@ -3264,6 +3550,7 @@
                 Log.w(LOG_TAG, "Unable to notify AppOpsService of removing user.", e);
             }
 
+            // TODO(b/142482943): Send some sort of broadcast for profiles even if non-managed?
             if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
                     && userData.info.isManagedProfile()) {
                 // Send broadcast to notify system that the user removed was a
@@ -4035,6 +4322,7 @@
                         pw.print(" <pre-created>");
                     }
                     pw.println();
+                    pw.print("    Type: "); pw.println(userInfo.userType);
                     pw.print("    Flags: "); pw.print(userInfo.flags); pw.print(" (");
                     pw.print(UserInfo.flagsToString(userInfo.flags)); pw.println(")");
                     pw.print("    State: ");
@@ -4119,11 +4407,20 @@
         pw.print("  Max users: " + UserManager.getMaxSupportedUsers());
         pw.println(" (limit reached: " + isUserLimitReached() + ")");
         pw.println("  Supports switchable users: " + UserManager.supportsMultipleUsers());
-        pw.println("  All guests ephemeral: " + areGuestUsersEphemeral());
+        pw.println("  All guests ephemeral: " + Resources.getSystem().getBoolean(
+                com.android.internal.R.bool.config_guestUserEphemeral));
         pw.println("  Is split-system user: " + UserManager.isSplitSystemUser());
         pw.println("  Is headless-system mode: " + UserManager.isHeadlessSystemUserMode());
         pw.println("  User version: " + mUserVersion);
 
+        // Dump UserTypes
+        pw.println();
+        pw.println("  User types (" + mUserTypes.size() + " types):");
+        for (int i = 0; i < mUserTypes.size(); i++) {
+            pw.println("    " + mUserTypes.keyAt(i) + ": ");
+            mUserTypes.valueAt(i).dump(pw);
+        }
+
         // Dump package whitelist
         pw.println();
         mSystemPackageInstaller.dump(pw);
@@ -4322,10 +4619,10 @@
         }
 
         @Override
-        public UserInfo createUserEvenWhenDisallowed(String name, int flags,
-                String[] disallowedPackages) {
-            UserInfo user = createUserInternalUnchecked(name, flags, UserHandle.USER_NULL,
-                    /* preCreated= */ false, disallowedPackages);
+        public UserInfo createUserEvenWhenDisallowed(String name, @NonNull String userType,
+                @UserInfoFlag int flags, String[] disallowedPackages) {
+            UserInfo user = createUserInternalUnchecked(name, userType, flags,
+                    UserHandle.USER_NULL, /* preCreated= */ false, disallowedPackages);
             // Keep this in sync with UserManager.createUser
             if (user != null && !user.isAdmin() && !user.isDemo()) {
                 setUserRestriction(UserManager.DISALLOW_SMS, true, user.id);
@@ -4410,7 +4707,7 @@
             }
             synchronized (mUsersLock) {
                 UserInfo callingUserInfo = getUserInfoLU(callingUserId);
-                if (callingUserInfo == null || callingUserInfo.isManagedProfile()) {
+                if (callingUserInfo == null || callingUserInfo.isProfile()) {
                     if (throwSecurityException) {
                         throw new SecurityException(
                                 debugMsg + " for another profile "
@@ -4529,36 +4826,53 @@
                 (DBG_WITH_STACKTRACE ? " called at\n" + Debug.getCallers(10, "  ") : ""));
     }
 
+    /** @see #getMaxUsersOfTypePerParent(UserTypeDetails) */
     @VisibleForTesting
-    static int getMaxManagedProfiles() {
-        // Allow overriding max managed profiles on debuggable builds for testing
-        // of multiple profiles.
-        if (!Build.IS_DEBUGGABLE) {
-            return MAX_MANAGED_PROFILES;
-        } else {
-            return SystemProperties.getInt("persist.sys.max_profiles",
-                    MAX_MANAGED_PROFILES);
+    int getMaxUsersOfTypePerParent(String userType) {
+        final UserTypeDetails type = mUserTypes.get(userType);
+        if (type == null) {
+            return 0;
         }
+        return getMaxUsersOfTypePerParent(type);
+    }
+
+    /**
+     * Returns the maximum number of users allowed for the given userTypeDetails per parent user.
+     * This is applicable for user types that are {@link UserTypeDetails#isProfile()}.
+     * If there is no maximum, {@link UserTypeDetails#UNLIMITED_NUMBER_OF_USERS} is returned.
+     */
+    private static int getMaxUsersOfTypePerParent(UserTypeDetails userTypeDetails) {
+        final int defaultMax = userTypeDetails.getMaxAllowedPerParent();
+        if (!Build.IS_DEBUGGABLE) {
+            return defaultMax;
+        } else {
+            if (userTypeDetails.isManagedProfile()) {
+                return SystemProperties.getInt("persist.sys.max_profiles", defaultMax);
+            }
+        }
+        return defaultMax;
     }
 
     @GuardedBy("mUsersLock")
     @VisibleForTesting
-    int getFreeProfileBadgeLU(int parentUserId) {
-        int maxManagedProfiles = getMaxManagedProfiles();
-        boolean[] usedBadges = new boolean[maxManagedProfiles];
+    int getFreeProfileBadgeLU(int parentUserId, String userType) {
+        Set<Integer> usedBadges = new ArraySet<>();
         final int userSize = mUsers.size();
         for (int i = 0; i < userSize; i++) {
             UserInfo ui = mUsers.valueAt(i).info;
             // Check which badge indexes are already used by this profile group.
-            if (ui.isManagedProfile()
+            if (ui.userType.equals(userType)
                     && ui.profileGroupId == parentUserId
-                    && !mRemovingUserIds.get(ui.id)
-                    && ui.profileBadge < maxManagedProfiles) {
-                usedBadges[ui.profileBadge] = true;
+                    && !mRemovingUserIds.get(ui.id)) {
+                usedBadges.add(ui.profileBadge);
             }
         }
-        for (int i = 0; i < maxManagedProfiles; i++) {
-            if (!usedBadges[i]) {
+        int maxUsersOfType = getMaxUsersOfTypePerParent(userType);
+        if (maxUsersOfType == UserTypeDetails.UNLIMITED_NUMBER_OF_USERS) {
+            maxUsersOfType = Integer.MAX_VALUE;
+        }
+        for (int i = 0; i < maxUsersOfType; i++) {
+            if (!usedBadges.contains(i)) {
                 return i;
             }
         }
diff --git a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
index ef6b24c..95197b0 100644
--- a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
+++ b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
@@ -389,7 +389,7 @@
         final ArrayMap<String, Integer> result = new ArrayMap<>(whitelist.size() + 1);
         // First, do the whitelisted user types.
         for (int i = 0; i < whitelist.size(); i++) {
-            final String pkgName = whitelist.keyAt(i);
+            final String pkgName = whitelist.keyAt(i).intern();
             final int flags = getFlagsFromUserTypes(whitelist.valueAt(i));
             if (flags != 0) {
                 result.put(pkgName, flags);
@@ -402,7 +402,7 @@
         final ArrayMap<String, Set<String>> blacklist =
                 sysConfig.getAndClearPackageToUserTypeBlacklist();
         for (int i = 0; i < blacklist.size(); i++) {
-            final String pkgName = blacklist.keyAt(i);
+            final String pkgName = blacklist.keyAt(i).intern();
             final int nonFlags = getFlagsFromUserTypes(blacklist.valueAt(i));
             final Integer flags = result.get(pkgName);
             if (flags != null) {
@@ -411,12 +411,13 @@
         }
         // Regardless of the whitelists/blacklists, ensure mandatory packages.
         result.put("android",
-                UserInfo.FLAG_SYSTEM | UserInfo.FLAG_FULL | UserInfo.PROFILE_FLAGS_MASK);
+                UserInfo.FLAG_SYSTEM | UserInfo.FLAG_FULL | UserInfo.FLAG_PROFILE);
         return result;
     }
 
     /** Converts a user types, as used in SystemConfig, to a UserInfo flag. */
     private static int getFlagsFromUserTypes(Iterable<String> userTypes) {
+        // TODO(b/142482943): Update all this for the new UserTypes.
         int flags = 0;
         for (String type : userTypes) {
             switch (type) {
@@ -442,7 +443,7 @@
                     flags |= UserInfo.FLAG_SYSTEM;
                     break;
                 case "PROFILE":
-                    flags |= UserInfo.PROFILE_FLAGS_MASK;
+                    flags |= UserInfo.FLAG_PROFILE;
                     break;
                 default:
                     Slog.w(TAG, "SystemConfig contained an invalid user type: " + type);
diff --git a/services/core/java/com/android/server/pm/permission/PermissionsState.java b/services/core/java/com/android/server/pm/permission/PermissionsState.java
index 505a0e2..b68d541 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionsState.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionsState.java
@@ -23,6 +23,7 @@
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.ArrayUtils;
 
 import java.util.ArrayList;
@@ -30,7 +31,6 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
-import com.android.internal.annotations.GuardedBy;
 
 /**
  * This class encapsulates the permissions for a package or a shared user.
@@ -708,7 +708,11 @@
     }
 
     private static final class PermissionData {
+
+        private final Object mLock = new Object();
+
         private final BasePermission mPerm;
+        @GuardedBy("mLock")
         private SparseArray<PermissionState> mUserStates = new SparseArray<>();
 
         public PermissionData(BasePermission perm) {
@@ -717,11 +721,14 @@
 
         public PermissionData(PermissionData other) {
             this(other.mPerm);
-            final int otherStateCount = other.mUserStates.size();
-            for (int i = 0; i < otherStateCount; i++) {
-                final int otherUserId = other.mUserStates.keyAt(i);
-                PermissionState otherState = other.mUserStates.valueAt(i);
-                mUserStates.put(otherUserId, new PermissionState(otherState));
+
+            synchronized (mLock) {
+                final int otherStateCount = other.mUserStates.size();
+                for (int i = 0; i < otherStateCount; i++) {
+                    final int otherUserId = other.mUserStates.keyAt(i);
+                    PermissionState otherState = other.mUserStates.valueAt(i);
+                    mUserStates.put(otherUserId, new PermissionState(otherState));
+                }
             }
         }
 
@@ -730,71 +737,83 @@
         }
 
         public boolean isGranted(int userId) {
-            if (isInstallPermission()) {
-                userId = UserHandle.USER_ALL;
-            }
+            synchronized (mLock) {
+                if (isInstallPermission()) {
+                    userId = UserHandle.USER_ALL;
+                }
 
-            PermissionState userState = mUserStates.get(userId);
-            if (userState == null) {
-                return false;
-            }
+                PermissionState userState = mUserStates.get(userId);
+                if (userState == null) {
+                    return false;
+                }
 
-            return userState.mGranted;
+                return userState.mGranted;
+            }
         }
 
         public boolean grant(int userId) {
-            if (!isCompatibleUserId(userId)) {
-                return false;
+            synchronized (mLock) {
+                if (!isCompatibleUserId(userId)) {
+                    return false;
+                }
+
+                if (isGranted(userId)) {
+                    return false;
+                }
+
+                PermissionState userState = mUserStates.get(userId);
+                if (userState == null) {
+                    userState = new PermissionState(mPerm.getName());
+                    mUserStates.put(userId, userState);
+                }
+
+                userState.mGranted = true;
+
+                return true;
             }
-
-            if (isGranted(userId)) {
-                return false;
-            }
-
-            PermissionState userState = mUserStates.get(userId);
-            if (userState == null) {
-                userState = new PermissionState(mPerm.getName());
-                mUserStates.put(userId, userState);
-            }
-
-            userState.mGranted = true;
-
-            return true;
         }
 
         public boolean revoke(int userId) {
-            if (!isCompatibleUserId(userId)) {
-                return false;
+            synchronized (mLock) {
+                if (!isCompatibleUserId(userId)) {
+                    return false;
+                }
+
+                if (!isGranted(userId)) {
+                    return false;
+                }
+
+                PermissionState userState = mUserStates.get(userId);
+                userState.mGranted = false;
+
+                if (userState.isDefault()) {
+                    mUserStates.remove(userId);
+                }
+
+                return true;
             }
-
-            if (!isGranted(userId)) {
-                return false;
-            }
-
-            PermissionState userState = mUserStates.get(userId);
-            userState.mGranted = false;
-
-            if (userState.isDefault()) {
-                mUserStates.remove(userId);
-            }
-
-            return true;
         }
 
         public PermissionState getPermissionState(int userId) {
-            return mUserStates.get(userId);
+            synchronized (mLock) {
+                return mUserStates.get(userId);
+            }
         }
 
         public int getFlags(int userId) {
-            PermissionState userState = mUserStates.get(userId);
-            if (userState != null) {
-                return userState.mFlags;
+            synchronized (mLock) {
+                PermissionState userState = mUserStates.get(userId);
+                if (userState != null) {
+                    return userState.mFlags;
+                }
+                return 0;
             }
-            return 0;
         }
 
         public boolean isDefault() {
-            return mUserStates.size() <= 0;
+            synchronized (mLock) {
+                return mUserStates.size() <= 0;
+            }
         }
 
         public static boolean isInstallPermissionKey(int userId) {
@@ -802,32 +821,34 @@
         }
 
         public boolean updateFlags(int userId, int flagMask, int flagValues) {
-            if (isInstallPermission()) {
-                userId = UserHandle.USER_ALL;
-            }
+            synchronized (mLock) {
+                if (isInstallPermission()) {
+                    userId = UserHandle.USER_ALL;
+                }
 
-            if (!isCompatibleUserId(userId)) {
+                if (!isCompatibleUserId(userId)) {
+                    return false;
+                }
+
+                final int newFlags = flagValues & flagMask;
+
+                PermissionState userState = mUserStates.get(userId);
+                if (userState != null) {
+                    final int oldFlags = userState.mFlags;
+                    userState.mFlags = (userState.mFlags & ~flagMask) | newFlags;
+                    if (userState.isDefault()) {
+                        mUserStates.remove(userId);
+                    }
+                    return userState.mFlags != oldFlags;
+                } else if (newFlags != 0) {
+                    userState = new PermissionState(mPerm.getName());
+                    userState.mFlags = newFlags;
+                    mUserStates.put(userId, userState);
+                    return true;
+                }
+
                 return false;
             }
-
-            final int newFlags = flagValues & flagMask;
-
-            PermissionState userState = mUserStates.get(userId);
-            if (userState != null) {
-                final int oldFlags = userState.mFlags;
-                userState.mFlags = (userState.mFlags & ~flagMask) | newFlags;
-                if (userState.isDefault()) {
-                    mUserStates.remove(userId);
-                }
-                return userState.mFlags != oldFlags;
-            } else if (newFlags != 0) {
-                userState = new PermissionState(mPerm.getName());
-                userState.mFlags = newFlags;
-                mUserStates.put(userId, userState);
-                return true;
-            }
-
-            return false;
         }
 
         private boolean isCompatibleUserId(int userId) {
diff --git a/services/core/java/com/android/server/power/InattentiveSleepWarningController.java b/services/core/java/com/android/server/power/InattentiveSleepWarningController.java
new file mode 100644
index 0000000..db8a63f
--- /dev/null
+++ b/services/core/java/com/android/server/power/InattentiveSleepWarningController.java
@@ -0,0 +1,103 @@
+/**
+ * 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.power;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.statusbar.IStatusBarService;
+
+/**
+ * Communicates with System UI to show/hide the inattentive sleep warning overlay.
+ */
+@VisibleForTesting
+public class InattentiveSleepWarningController {
+    private static final String TAG = "InattentiveSleepWarning";
+
+    private final Handler mHandler = new Handler();
+
+    private boolean mIsShown;
+    private IStatusBarService mStatusBarService;
+
+    InattentiveSleepWarningController() {
+    }
+
+    /**
+     * Returns true if the warning is currently being displayed, false otherwise.
+     */
+    @GuardedBy("PowerManagerService.mLock")
+    public boolean isShown() {
+        return mIsShown;
+    }
+
+    /**
+     * Show the warning.
+     */
+    @GuardedBy("PowerManagerService.mLock")
+    public void show() {
+        if (isShown()) {
+            return;
+        }
+
+        mHandler.post(this::showInternal);
+        mIsShown = true;
+    }
+
+    private void showInternal() {
+        try {
+            getStatusBar().showInattentiveSleepWarning();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to show inattentive sleep warning", e);
+            mIsShown = false;
+        }
+    }
+
+    /**
+     * Dismiss the warning.
+     */
+    @GuardedBy("PowerManagerService.mLock")
+    public void dismiss() {
+        if (!isShown()) {
+            return;
+        }
+
+        mHandler.post(this::dismissInternal);
+        mIsShown = false;
+    }
+
+    private void dismissInternal() {
+        try {
+            getStatusBar().dismissInattentiveSleepWarning();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to dismiss inattentive sleep warning", e);
+        }
+    }
+
+    private IStatusBarService getStatusBar() {
+        if (mStatusBarService == null) {
+            mStatusBarService = IStatusBarService.Stub.asInterface(
+                    ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+        }
+
+        return mStatusBarService;
+    }
+}
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index b67d9b2..7fc9fdc0 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -536,6 +536,7 @@
             case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
                 return WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;
             case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
+            case PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE:
                 return WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT;
             default:
                 return WindowManagerPolicy.OFF_BECAUSE_OF_USER;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index befe4e9..00e0f71 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -128,6 +128,8 @@
     private static final int MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT = 3;
     // Message: Polling to look for long held wake locks.
     private static final int MSG_CHECK_FOR_LONG_WAKELOCKS = 4;
+    // Message: Sent when an attentive timeout occurs to update the power state.
+    private static final int MSG_ATTENTIVE_TIMEOUT = 5;
 
     // Dirty bit: mWakeLocks changed
     private static final int DIRTY_WAKE_LOCKS = 1 << 0;
@@ -157,6 +159,8 @@
     private static final int DIRTY_QUIESCENT = 1 << 12;
     // Dirty bit: VR Mode enabled changed
     private static final int DIRTY_VR_MODE_CHANGED = 1 << 13;
+    // Dirty bit: attentive timer may have timed out
+    private static final int DIRTY_ATTENTIVE = 1 << 14;
 
     // Summarizes the state of all active wakelocks.
     private static final int WAKE_LOCK_CPU = 1 << 0;
@@ -249,6 +253,8 @@
     private DreamManagerInternal mDreamManager;
     private Light mAttentionLight;
 
+    private InattentiveSleepWarningController mInattentiveSleepWarningOverlayController;
+
     private final Object mLock = LockGuard.installNewLock(LockGuard.INDEX_POWER);
 
     // A bitfield that indicates what parts of the power state have
@@ -381,6 +387,9 @@
     // True if the device should suspend when the screen is off due to proximity.
     private boolean mSuspendWhenScreenOffDueToProximityConfig;
 
+    // Default value for attentive timeout.
+    private int mAttentiveTimeoutConfig;
+
     // True if dreams are supported on this device.
     private boolean mDreamsSupportedConfig;
 
@@ -441,9 +450,16 @@
     // The screen off timeout setting value in milliseconds.
     private long mScreenOffTimeoutSetting;
 
+    // Default for attentive warning duration.
+    private long mAttentiveWarningDurationConfig;
+
     // The sleep timeout setting value in milliseconds.
     private long mSleepTimeoutSetting;
 
+    // How long to show a warning message to user before the device goes to sleep
+    // after long user inactivity, even if wakelocks are held.
+    private long mAttentiveTimeoutSetting;
+
     // The maximum allowable screen off timeout according to the device
     // administration policy.  Overrides other settings.
     private long mMaximumScreenOffTimeoutFromDeviceAdmin = Long.MAX_VALUE;
@@ -735,6 +751,10 @@
         AmbientDisplayConfiguration createAmbientDisplayConfiguration(Context context) {
             return new AmbientDisplayConfiguration(context);
         }
+
+        InattentiveSleepWarningController createInattentiveSleepWarningController() {
+            return new InattentiveSleepWarningController();
+        }
     }
 
     final Constants mConstants;
@@ -779,6 +799,9 @@
         mBatterySaverStateMachine = new BatterySaverStateMachine(
                 mLock, mContext, mBatterySaverController);
 
+        mInattentiveSleepWarningOverlayController =
+                mInjector.createInattentiveSleepWarningController();
+
         synchronized (mLock) {
             mWakeLockSuspendBlocker =
                     mInjector.createSuspendBlocker(this, "PowerManagerService.WakeLocks");
@@ -902,6 +925,9 @@
         resolver.registerContentObserver(Settings.Secure.getUriFor(
                 Settings.Secure.SLEEP_TIMEOUT),
                 false, mSettingsObserver, UserHandle.USER_ALL);
+        resolver.registerContentObserver(Settings.Secure.getUriFor(
+                Settings.Secure.ATTENTIVE_TIMEOUT),
+                false, mSettingsObserver, UserHandle.USER_ALL);
         resolver.registerContentObserver(Settings.Global.getUriFor(
                 Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
                 false, mSettingsObserver, UserHandle.USER_ALL);
@@ -966,6 +992,10 @@
                 com.android.internal.R.bool.config_allowTheaterModeWakeFromUnplug);
         mSuspendWhenScreenOffDueToProximityConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);
+        mAttentiveTimeoutConfig = resources.getInteger(
+                com.android.internal.R.integer.config_attentiveTimeout);
+        mAttentiveWarningDurationConfig = resources.getInteger(
+                com.android.internal.R.integer.config_attentiveWarningDuration);
         mDreamsSupportedConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_dreamsSupported);
         mDreamsEnabledByDefaultConfig = resources.getBoolean(
@@ -1015,6 +1045,9 @@
         mSleepTimeoutSetting = Settings.Secure.getIntForUser(resolver,
                 Settings.Secure.SLEEP_TIMEOUT, DEFAULT_SLEEP_TIMEOUT,
                 UserHandle.USER_CURRENT);
+        mAttentiveTimeoutSetting = Settings.Secure.getIntForUser(resolver,
+                Settings.Secure.ATTENTIVE_TIMEOUT, mAttentiveTimeoutConfig,
+                UserHandle.USER_CURRENT);
         mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver,
                 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC);
         mTheaterModeEnabled = Settings.Global.getInt(mContext.getContentResolver(),
@@ -1700,6 +1733,7 @@
 
                 updateWakeLockSummaryLocked(dirtyPhase1);
                 updateUserActivitySummaryLocked(now, dirtyPhase1);
+                updateAttentiveStateLocked(now, dirtyPhase1);
                 if (!updateWakefulnessLocked(dirtyPhase1)) {
                     break;
                 }
@@ -2042,8 +2076,10 @@
             if (mWakefulness == WAKEFULNESS_AWAKE
                     || mWakefulness == WAKEFULNESS_DREAMING
                     || mWakefulness == WAKEFULNESS_DOZING) {
-                final long sleepTimeout = getSleepTimeoutLocked();
-                final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);
+                final long attentiveTimeout = getAttentiveTimeoutLocked();
+                final long sleepTimeout = getSleepTimeoutLocked(attentiveTimeout);
+                final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,
+                        attentiveTimeout);
                 final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
                 final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
                 final long nextProfileTimeout = getNextProfileTimeoutLocked(now);
@@ -2134,6 +2170,12 @@
         mHandler.sendMessageAtTime(msg, timeMs);
     }
 
+    private void scheduleAttentiveTimeout(long timeMs) {
+        final Message msg = mHandler.obtainMessage(MSG_ATTENTIVE_TIMEOUT);
+        msg.setAsynchronous(true);
+        mHandler.sendMessageAtTime(msg, timeMs);
+    }
+
     /**
      * Finds the next profile timeout time or returns -1 if there are no profiles to be locked.
      */
@@ -2150,6 +2192,69 @@
         return nextTimeout;
     }
 
+    private void updateAttentiveStateLocked(long now, int dirty) {
+        long attentiveTimeout = getAttentiveTimeoutLocked();
+        long goToSleepTime = mLastUserActivityTime + attentiveTimeout;
+        long showWarningTime = goToSleepTime - mAttentiveWarningDurationConfig;
+
+        boolean warningDismissed = maybeHideInattentiveSleepWarningLocked(now, showWarningTime);
+
+        if (attentiveTimeout >= 0 && (warningDismissed
+                || (dirty & (DIRTY_ATTENTIVE | DIRTY_STAY_ON | DIRTY_SCREEN_BRIGHTNESS_BOOST
+                | DIRTY_PROXIMITY_POSITIVE | DIRTY_WAKEFULNESS | DIRTY_BOOT_COMPLETED
+                | DIRTY_SETTINGS)) != 0)) {
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "Updating attentive state");
+            }
+
+            mHandler.removeMessages(MSG_ATTENTIVE_TIMEOUT);
+
+            if (isBeingKeptFromShowingInattentiveSleepWarningLocked()) {
+                return;
+            }
+
+            long nextTimeout = -1;
+
+            if (now < showWarningTime) {
+                nextTimeout = showWarningTime;
+            } else if (now < goToSleepTime) {
+                if (DEBUG) {
+                    long timeToSleep = goToSleepTime - now;
+                    Slog.d(TAG, "Going to sleep in " + timeToSleep
+                            + "ms if there is no user activity");
+                }
+                mInattentiveSleepWarningOverlayController.show();
+                nextTimeout = goToSleepTime;
+            } else {
+                if (DEBUG && mWakefulness != WAKEFULNESS_ASLEEP) {
+                    Slog.i(TAG, "Going to sleep now due to long user inactivity");
+                }
+            }
+
+            if (nextTimeout >= 0) {
+                scheduleAttentiveTimeout(nextTimeout);
+            }
+        }
+    }
+
+    private boolean maybeHideInattentiveSleepWarningLocked(long now, long showWarningTime) {
+        long attentiveTimeout = getAttentiveTimeoutLocked();
+
+        if (mInattentiveSleepWarningOverlayController.isShown() && (attentiveTimeout < 0
+                || isBeingKeptFromShowingInattentiveSleepWarningLocked()
+                || now < showWarningTime)) {
+            mInattentiveSleepWarningOverlayController.dismiss();
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean isAttentiveTimeoutExpired(long now) {
+        long attentiveTimeout = getAttentiveTimeoutLocked();
+        return attentiveTimeout >= 0 && now > mLastUserActivityTime + attentiveTimeout;
+    }
+
     /**
      * Called when a user activity timeout has occurred.
      * Simply indicates that something about user activity has changed so that the new
@@ -2169,15 +2274,38 @@
         }
     }
 
-    private long getSleepTimeoutLocked() {
-        final long timeout = mSleepTimeoutSetting;
+    private void handleAttentiveTimeout() { // runs on handler thread
+        synchronized (mLock) {
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "handleAttentiveTimeout");
+            }
+
+            mDirty |= DIRTY_ATTENTIVE;
+            updatePowerStateLocked();
+        }
+    }
+
+    private long getAttentiveTimeoutLocked() {
+        long timeout = mAttentiveTimeoutSetting;
         if (timeout <= 0) {
             return -1;
         }
+
+        return Math.max(timeout, mMinimumScreenOffTimeoutConfig);
+    }
+
+    private long getSleepTimeoutLocked(long attentiveTimeout) {
+        long timeout = mSleepTimeoutSetting;
+        if (timeout <= 0) {
+            return -1;
+        }
+        if (attentiveTimeout >= 0) {
+            timeout = Math.min(timeout, attentiveTimeout);
+        }
         return Math.max(timeout, mMinimumScreenOffTimeoutConfig);
     }
 
-    private long getScreenOffTimeoutLocked(long sleepTimeout) {
+    private long getScreenOffTimeoutLocked(long sleepTimeout, long attentiveTimeout) {
         long timeout = mScreenOffTimeoutSetting;
         if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
             timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
@@ -2188,6 +2316,9 @@
         if (sleepTimeout >= 0) {
             timeout = Math.min(timeout, sleepTimeout);
         }
+        if (attentiveTimeout >= 0) {
+            timeout = Math.min(timeout, attentiveTimeout);
+        }
         return Math.max(timeout, mMinimumScreenOffTimeoutConfig);
     }
 
@@ -2209,13 +2340,16 @@
         boolean changed = false;
         if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
                 | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
-                | DIRTY_DOCK_STATE)) != 0) {
+                | DIRTY_DOCK_STATE | DIRTY_ATTENTIVE)) != 0) {
             if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
                 if (DEBUG_SPEW) {
                     Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
                 }
                 final long time = SystemClock.uptimeMillis();
-                if (shouldNapAtBedTimeLocked()) {
+                if (isAttentiveTimeoutExpired(time)) {
+                    changed = goToSleepNoUpdateLocked(time, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
+                            PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, Process.SYSTEM_UID);
+                } else if (shouldNapAtBedTimeLocked()) {
                     changed = napNoUpdateLocked(time, Process.SYSTEM_UID);
                 } else {
                     changed = goToSleepNoUpdateLocked(time,
@@ -2242,7 +2376,16 @@
      * to being fully awake or else go to sleep for good.
      */
     private boolean isItBedTimeYetLocked() {
-        return mBootCompleted && !isBeingKeptAwakeLocked();
+        if (!mBootCompleted) {
+            return false;
+        }
+
+        long now = SystemClock.uptimeMillis();
+        if (isAttentiveTimeoutExpired(now)) {
+            return !isBeingKeptFromInattentiveSleepLocked();
+        } else {
+            return !isBeingKeptAwakeLocked();
+        }
     }
 
     /**
@@ -2263,11 +2406,29 @@
     }
 
     /**
+     * Returns true if the device is prevented from going into inattentive sleep by the stay on
+     * while powered setting. We also keep the device awake when the proximity sensor returns a
+     * positive result so that the device does not lock while in a phone call. This function only
+     * controls whether the device will go to sleep which is independent of whether it will be
+     * allowed to suspend.
+     */
+    private boolean isBeingKeptFromInattentiveSleepLocked() {
+        return mStayOn || mScreenBrightnessBoostInProgress || mProximityPositive
+                || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
+                | USER_ACTIVITY_SCREEN_DIM)) != 0;
+    }
+
+    private boolean isBeingKeptFromShowingInattentiveSleepWarningLocked() {
+        return mStayOn || mScreenBrightnessBoostInProgress || mProximityPositive || !mBootCompleted;
+    }
+
+    /**
      * Determines whether to post a message to the sandman to update the dream state.
      */
     private void updateDreamLocked(int dirty, boolean displayBecameReady) {
         if ((dirty & (DIRTY_WAKEFULNESS
                 | DIRTY_USER_ACTIVITY
+                | DIRTY_ATTENTIVE
                 | DIRTY_WAKE_LOCKS
                 | DIRTY_BOOT_COMPLETED
                 | DIRTY_SETTINGS
@@ -2350,6 +2511,7 @@
             }
 
             // Determine whether the dream should continue.
+            long now = SystemClock.uptimeMillis();
             if (wakefulness == WAKEFULNESS_DREAMING) {
                 if (isDreaming && canDreamLocked()) {
                     if (mDreamsBatteryLevelDrainCutoffConfig >= 0
@@ -2371,11 +2533,15 @@
 
                 // Dream has ended or will be stopped.  Update the power state.
                 if (isItBedTimeYetLocked()) {
-                    goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
-                            PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
+                    int flags = 0;
+                    if (isAttentiveTimeoutExpired(now)) {
+                        flags |= PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE;
+                    }
+                    goToSleepNoUpdateLocked(now, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, flags,
+                            Process.SYSTEM_UID);
                     updatePowerStateLocked();
                 } else {
-                    wakeUpNoUpdateLocked(SystemClock.uptimeMillis(),
+                    wakeUpNoUpdateLocked(now,
                             PowerManager.WAKE_REASON_UNKNOWN,
                             "android.server.power:DREAM_FINISHED", Process.SYSTEM_UID,
                             mContext.getOpPackageName(), Process.SYSTEM_UID);
@@ -2387,7 +2553,7 @@
                 }
 
                 // Doze has ended or will be stopped.  Update the power state.
-                reallyGoToSleepNoUpdateLocked(SystemClock.uptimeMillis(), Process.SYSTEM_UID);
+                reallyGoToSleepNoUpdateLocked(now, Process.SYSTEM_UID);
                 updatePowerStateLocked();
             }
         }
@@ -3474,6 +3640,9 @@
             pw.println("  mMinimumScreenOffTimeoutConfig=" + mMinimumScreenOffTimeoutConfig);
             pw.println("  mMaximumScreenDimDurationConfig=" + mMaximumScreenDimDurationConfig);
             pw.println("  mMaximumScreenDimRatioConfig=" + mMaximumScreenDimRatioConfig);
+            pw.println("  mAttentiveTimeoutConfig=" + mAttentiveTimeoutConfig);
+            pw.println("  mAttentiveTimeoutSetting=" + mAttentiveTimeoutSetting);
+            pw.println("  mAttentiveWarningDurationConfig=" + mAttentiveWarningDurationConfig);
             pw.println("  mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting);
             pw.println("  mSleepTimeoutSetting=" + mSleepTimeoutSetting);
             pw.println("  mMaximumScreenOffTimeoutFromDeviceAdmin="
@@ -3501,10 +3670,12 @@
             pw.println("  mForegroundProfile=" + mForegroundProfile);
             pw.println("  mUserId=" + mUserId);
 
-            final long sleepTimeout = getSleepTimeoutLocked();
-            final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);
+            final long attentiveTimeout = getAttentiveTimeoutLocked();
+            final long sleepTimeout = getSleepTimeoutLocked(attentiveTimeout);
+            final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout, attentiveTimeout);
             final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
             pw.println();
+            pw.println("Attentive timeout: " + attentiveTimeout + " ms");
             pw.println("Sleep timeout: " + sleepTimeout + " ms");
             pw.println("Screen off timeout: " + screenOffTimeout + " ms");
             pw.println("Screen dim duration: " + screenDimDuration + " ms");
@@ -3772,6 +3943,16 @@
                     PowerServiceSettingsAndConfigurationDumpProto.SLEEP_TIMEOUT_SETTING_MS,
                     mSleepTimeoutSetting);
             proto.write(
+                    PowerServiceSettingsAndConfigurationDumpProto.ATTENTIVE_TIMEOUT_SETTING_MS,
+                    mAttentiveTimeoutSetting);
+            proto.write(
+                    PowerServiceSettingsAndConfigurationDumpProto.ATTENTIVE_TIMEOUT_CONFIG_MS,
+                    mAttentiveTimeoutConfig);
+            proto.write(
+                    PowerServiceSettingsAndConfigurationDumpProto
+                            .ATTENTIVE_WARNING_DURATION_CONFIG_MS,
+                    mAttentiveWarningDurationConfig);
+            proto.write(
                     PowerServiceSettingsAndConfigurationDumpProto
                             .MAXIMUM_SCREEN_OFF_TIMEOUT_FROM_DEVICE_ADMIN_MS,
                     // Clamp to int32
@@ -3853,9 +4034,11 @@
                     mIsVrModeEnabled);
             proto.end(settingsAndConfigurationToken);
 
-            final long sleepTimeout = getSleepTimeoutLocked();
-            final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);
+            final long attentiveTimeout = getAttentiveTimeoutLocked();
+            final long sleepTimeout = getSleepTimeoutLocked(attentiveTimeout);
+            final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout, attentiveTimeout);
             final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
+            proto.write(PowerManagerServiceDumpProto.ATTENTIVE_TIMEOUT_MS, attentiveTimeout);
             proto.write(PowerManagerServiceDumpProto.SLEEP_TIMEOUT_MS, sleepTimeout);
             proto.write(PowerManagerServiceDumpProto.SCREEN_OFF_TIMEOUT_MS, screenOffTimeout);
             proto.write(PowerManagerServiceDumpProto.SCREEN_DIM_DURATION_MS, screenDimDuration);
@@ -4009,6 +4192,9 @@
                 case MSG_CHECK_FOR_LONG_WAKELOCKS:
                     checkForLongWakeLocks();
                     break;
+                case MSG_ATTENTIVE_TIMEOUT:
+                    handleAttentiveTimeout();
+                    break;
             }
         }
     }
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 25c41f5..c256b84 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -1375,6 +1375,28 @@
                 this, in, out, err, args, callback, resultReceiver);
     }
 
+    @Override
+    public void showInattentiveSleepWarning() {
+        enforceStatusBarService();
+        if (mBar != null) {
+            try {
+                mBar.showInattentiveSleepWarning();
+            } catch (RemoteException ex) {
+            }
+        }
+    }
+
+    @Override
+    public void dismissInattentiveSleepWarning() {
+        enforceStatusBarService();
+        if (mBar != null) {
+            try {
+                mBar.dismissInattentiveSleepWarning();
+            } catch (RemoteException ex) {
+            }
+        }
+    }
+
     public String[] getStatusBarIcons() {
         return mContext.getResources().getStringArray(R.array.config_statusBarIcons);
     }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index dd561e1..d66aa18 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -2170,14 +2170,21 @@
         }
     }
 
+    @Deprecated
     @Override
     public ParcelFileDescriptor getWallpaper(String callingPkg, IWallpaperManagerCallback cb,
             final int which, Bundle outParams, int wallpaperUserId) {
+        return getWallpaperWithFeature(callingPkg, null, cb, which, outParams, wallpaperUserId);
+    }
+
+    @Override
+    public ParcelFileDescriptor getWallpaperWithFeature(String callingPkg, String callingFeatureId,
+            IWallpaperManagerCallback cb, final int which, Bundle outParams, int wallpaperUserId) {
         final int hasPrivilege = mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.READ_WALLPAPER_INTERNAL);
         if (hasPrivilege != PackageManager.PERMISSION_GRANTED) {
             mContext.getSystemService(StorageManager.class).checkPermissionReadImages(true,
-                    Binder.getCallingPid(), Binder.getCallingUid(), callingPkg);
+                    Binder.getCallingPid(), Binder.getCallingUid(), callingPkg, callingFeatureId);
         }
 
         wallpaperUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 3d41608..8039724 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1159,7 +1159,7 @@
         this.task = task;
     }
 
-    TaskStack getStack() {
+    ActivityStack getStack() {
         return task != null ? task.getTaskStack() : null;
     }
 
@@ -1201,7 +1201,7 @@
         } else if (mLastParent != null && mLastParent.getTaskStack() != null) {
             task.getTaskStack().mExitingActivities.remove(this);
         }
-        final TaskStack stack = getStack();
+        final ActivityStack stack = getStack();
 
         // If we reparent, make sure to remove ourselves from the old animation registry.
         if (mAnimatingActivityRegistry != null) {
@@ -1265,7 +1265,7 @@
 
         if (prevDc.mFocusedApp == this) {
             prevDc.setFocusedApp(null);
-            final TaskStack stack = dc.getTopStack();
+            final ActivityStack stack = dc.getTopStack();
             if (stack != null) {
                 final Task task = stack.getTopChild();
                 if (task != null && task.getTopChild() == this) {
@@ -3021,7 +3021,7 @@
             getDisplayContent().mNoAnimationNotifyOnTransitionFinished.add(token);
         }
 
-        final TaskStack stack = getStack();
+        final ActivityStack stack = getStack();
         if (delayed && !isEmpty()) {
             // set the token aside because it has an active animation to be finished
             ProtoLog.v(WM_DEBUG_ADD_REMOVE,
@@ -3751,7 +3751,7 @@
 
                 // Notify the pinned stack upon all windows drawn. If there was an animation in
                 // progress then this signal will resume that animation.
-                final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
+                final ActivityStack pinnedStack = mDisplayContent.getPinnedStack();
                 if (pinnedStack != null) {
                     pinnedStack.onAllWindowsDrawn();
                 }
@@ -4358,7 +4358,7 @@
         final boolean isDisplaySleeping = getDisplay().isSleeping()
                 && getDisplayId() != DEFAULT_DISPLAY;
         // Whether this activity is the top activity of this stack.
-        final boolean isTop = this == stack.getTopActivity();
+        final boolean isTop = this == stack.getTopNonFinishingActivity();
         // Exclude the case where this is the top activity in a pinned stack.
         final boolean isTopNotPinnedStack = stack.isAttached()
                 && stack.getDisplay().isTopNotPinnedStack(stack);
@@ -5781,7 +5781,7 @@
                     getTransit(), task)) {
                 task.getBounds(mTmpRect);
             } else {
-                final TaskStack stack = getStack();
+                final ActivityStack stack = getStack();
                 if (stack == null) {
                     return;
                 }
@@ -6171,8 +6171,7 @@
         // The rest of the condition is that only one side is smaller than the parent, but it still
         // needs to exclude the cases where the size is limited by the fixed aspect ratio.
         if (info.maxAspectRatio > 0) {
-            final float aspectRatio = (0.5f + Math.max(appWidth, appHeight))
-                    / Math.min(appWidth, appHeight);
+            final float aspectRatio = Math.max(appWidth, appHeight) / Math.min(appWidth, appHeight);
             if (aspectRatio >= info.maxAspectRatio) {
                 // The current size has reached the max aspect ratio.
                 return false;
@@ -6541,7 +6540,7 @@
     void savePinnedStackBounds() {
         // Leaving PiP to fullscreen, save the snap fraction based on the pre-animation bounds
         // for the next re-entry into PiP (assuming the activity is not hidden or destroyed)
-        final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
+        final ActivityStack pinnedStack = mDisplayContent.getPinnedStack();
         if (pinnedStack == null) return;
         final Rect stackBounds;
         if (pinnedStack.lastAnimatingBoundsWasToFullscreen()) {
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 6f6e659..8385232 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -16,12 +16,15 @@
 
 package com.android.server.wm;
 
+import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT;
+import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.PINNED_WINDOWING_MODE_ELEVATION_IN_DIP;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
@@ -33,10 +36,17 @@
 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
 import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
 import static android.view.Display.INVALID_DISPLAY;
+import static android.view.WindowManager.DOCKED_BOTTOM;
+import static android.view.WindowManager.DOCKED_INVALID;
+import static android.view.WindowManager.DOCKED_LEFT;
+import static android.view.WindowManager.DOCKED_RIGHT;
+import static android.view.WindowManager.DOCKED_TOP;
 import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
 import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
 import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
@@ -48,13 +58,10 @@
 import static android.view.WindowManager.TRANSIT_TASK_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
 
-import static com.android.server.am.ActivityStackProto.BOUNDS;
 import static com.android.server.am.ActivityStackProto.DISPLAY_ID;
 import static com.android.server.am.ActivityStackProto.FULLSCREEN;
-import static com.android.server.am.ActivityStackProto.ID;
 import static com.android.server.am.ActivityStackProto.RESUMED_ACTIVITY;
 import static com.android.server.am.ActivityStackProto.STACK;
-import static com.android.server.am.ActivityStackProto.TASKS;
 import static com.android.server.wm.ActivityRecord.FINISH_RESULT_REMOVED;
 import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
 import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
@@ -97,8 +104,24 @@
 import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_ACTIVITY_STACK_MSG;
 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
+import static com.android.server.wm.BoundsAnimationController.FADE_IN;
+import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
+import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
+import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
+import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
 import static com.android.server.wm.RootActivityContainer.FindTaskResult;
+import static com.android.server.wm.StackProto.ADJUSTED_BOUNDS;
+import static com.android.server.wm.StackProto.ADJUSTED_FOR_IME;
+import static com.android.server.wm.StackProto.ADJUST_DIVIDER_AMOUNT;
+import static com.android.server.wm.StackProto.ADJUST_IME_AMOUNT;
+import static com.android.server.wm.StackProto.ANIMATING_BOUNDS;
+import static com.android.server.wm.StackProto.DEFER_REMOVAL;
+import static com.android.server.wm.StackProto.FILLS_PARENT;
+import static com.android.server.wm.StackProto.MINIMIZE_AMOUNT;
+import static com.android.server.wm.StackProto.WINDOW_CONTAINER;
 import static com.android.server.wm.Task.REPARENT_LEAVE_STACK_IN_PLACE;
+import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
@@ -111,6 +134,7 @@
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.app.IActivityController;
+import android.app.RemoteAction;
 import android.app.ResultInfo;
 import android.app.WindowConfiguration.ActivityType;
 import android.app.WindowConfiguration.WindowingMode;
@@ -124,7 +148,9 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.res.Configuration;
+import android.graphics.Point;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Debug;
@@ -138,17 +164,24 @@
 import android.os.UserHandle;
 import android.service.voice.IVoiceInteractionSession;
 import android.util.ArraySet;
+import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.IntArray;
 import android.util.Log;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 import android.view.Display;
+import android.view.DisplayCutout;
+import android.view.DisplayInfo;
+import android.view.RemoteAnimationTarget;
+import android.view.SurfaceControl;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.os.logging.MetricsLoggerWrapper;
+import com.android.internal.policy.DividerSnapAlgorithm;
+import com.android.internal.policy.DockedDividerUtils;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityManagerService;
@@ -167,7 +200,8 @@
 /**
  * State and management of a single stack of activities.
  */
-class ActivityStack extends TaskStack {
+class ActivityStack extends WindowContainer<Task> implements BoundsAnimationTarget,
+        ConfigurationContainerListener {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_ATM;
     private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
     private static final String TAG_APP = TAG + POSTFIX_APP;
@@ -228,52 +262,12 @@
     /** Stack is completely invisible. */
     static final int STACK_VISIBILITY_INVISIBLE = 2;
 
-    // TODO(display-unify): Remove after display unification.
-    protected void onParentChanged(ActivityDisplay newParent, ActivityDisplay oldParent) {
-        onParentChanged(
-                newParent != null ? newParent.mDisplayContent : null,
-                oldParent != null ? oldParent.mDisplayContent : null);
-    }
+    /** 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;
 
-    @Override
-    protected void onParentChanged(
-            ConfigurationContainer newParent, ConfigurationContainer oldParent) {
-        final ActivityDisplay display = newParent != null
-                ? ((WindowContainer) newParent).getDisplayContent().mActivityDisplay : null;
-        final ActivityDisplay oldDisplay = oldParent != null
-                ? ((WindowContainer) oldParent).getDisplayContent().mActivityDisplay : null;
-
-        mDisplayId = (display != null) ? display.mDisplayId : INVALID_DISPLAY;
-        mPrevDisplayId = (oldDisplay != null) ? oldDisplay.mDisplayId : INVALID_DISPLAY;
-
-        if (display != null) {
-            // Rotations are relative to the display. This means if there are 2 displays rotated
-            // differently (eg. 2 monitors with one landscape and one portrait), moving a stack
-            // from one to the other could look like a rotation change. To prevent this
-            // apparent rotation change (and corresponding bounds rotation), pretend like our
-            // current rotation is already the same as the new display.
-            // Note, if ActivityStack or related logic ever gets nested, this logic will need
-            // to move to onConfigurationChanged.
-            getConfiguration().windowConfiguration.setRotation(
-                    display.getWindowConfiguration().getRotation());
-        }
-        super.onParentChanged(newParent, oldParent);
-        if (display != null && 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);
-        }
-        mRootActivityContainer.updateUIDsPresentOnDisplay();
-
-        // Resume next focusable stack after reparenting to another display if we aren't removing
-        // the prevous display.
-        if (oldDisplay != null && oldDisplay.isRemoving()) {
-            postReparent();
-        }
-    }
+    /** Dimming amount for non-focused stack when stacks are IME-adjusted. */
+    private static final float IME_ADJUST_DIM_AMOUNT = 0.25f;
 
     enum ActivityState {
         INITIALIZING,
@@ -362,13 +356,71 @@
     // Id of the previous display the stack was on.
     int mPrevDisplayId = INVALID_DISPLAY;
 
+    /** Unique identifier */
+    final int mStackId;
+
+    /** For comparison with DisplayContent bounds. */
+    private Rect mTmpRect = new Rect();
+    private Rect mTmpRect2 = new Rect();
+    private Rect mTmpRect3 = new Rect();
+
+    /** For Pinned stack controlling. */
+    private Rect mTmpToBounds = new Rect();
+
+    /** Stack bounds adjusted to screen content area (taking into account IM windows, etc.) */
+    private final Rect mAdjustedBounds = new Rect();
+
+    /**
+     * Fully adjusted IME bounds. These are different from {@link #mAdjustedBounds} because they
+     * represent the state when the animation has ended.
+     */
+    private final Rect mFullyAdjustedImeBounds = new Rect();
+
+    /** ActivityRecords that are exiting, but still on screen for animations. */
+    final ArrayList<ActivityRecord> mExitingActivities = new ArrayList<>();
+
+    /** Detach this stack from its display when animation completes. */
+    // TODO: maybe tie this to WindowContainer#removeChild some how...
+    private boolean mDeferRemoval;
+
+    private final Rect mTmpAdjustedBounds = new Rect();
+    private boolean mAdjustedForIme;
+    private boolean mImeGoingAway;
+    private WindowState mImeWin;
+    private float mMinimizeAmount;
+    private float mAdjustImeAmount;
+    private float mAdjustDividerAmount;
+    private final int mDockedStackMinimizeThickness;
+
+    // If this is true, we are in the bounds animating mode. The task will be down or upscaled to
+    // perfectly fit the region it would have been cropped to. We may also avoid certain logic we
+    // would otherwise apply while resizing, while resizing in the bounds animating mode.
+    private boolean mBoundsAnimating = false;
+    // Set when an animation has been requested but has not yet started from the UI thread. This is
+    // cleared when the animation actually starts.
+    private boolean mBoundsAnimatingRequested = false;
+    private boolean mBoundsAnimatingToFullscreen = false;
+    private boolean mCancelCurrentBoundsAnimation = false;
+    private Rect mBoundsAnimationTarget = new Rect();
+    private Rect mBoundsAnimationSourceHintBounds = new Rect();
+    private @BoundsAnimationController.AnimationType int mAnimationType;
+
+    Rect mPreAnimationBounds = new Rect();
+
+    private Dimmer mDimmer = new Dimmer(this);
+
+    /**
+     * For {@link #prepareSurfaces}.
+     */
+    private final Rect mTmpDimBoundsRect = new Rect();
+    private final Point mLastSurfaceSize = new Point();
+
+    private final AnimatingActivityRegistry mAnimatingActivityRegistry =
+            new AnimatingActivityRegistry();
+
     /** Stores the override windowing-mode from before a transient mode change (eg. split) */
     private int mRestoreOverrideWindowingMode = WINDOWING_MODE_UNDEFINED;
 
-    private final Rect mTmpRect = new Rect();
-    private final Rect mTmpRect2 = new Rect();
-    private final ActivityOptions mTmpOptions = ActivityOptions.makeBasic();
-
     /** List for processing through a set of activities */
     private final ArrayList<ActivityRecord> mTmpActivities = new ArrayList<>();
 
@@ -474,12 +526,18 @@
 
     ActivityStack(ActivityDisplay display, int stackId, ActivityStackSupervisor supervisor,
             int windowingMode, int activityType, boolean onTop) {
-        super(supervisor.mService.mWindowManager, stackId);
+        super(supervisor.mService.mWindowManager);
+        mStackId = stackId;
+        mDockedStackMinimizeThickness =
+                supervisor.mService.mWindowManager.mContext.getResources().getDimensionPixelSize(
+                        com.android.internal.R.dimen.docked_stack_minimize_thickness);
+        EventLog.writeEvent(com.android.server.EventLogTags.WM_STACK_CREATED, stackId);
         mStackSupervisor = supervisor;
         mService = supervisor.mService;
         mRootActivityContainer = mService.mRootActivityContainer;
         mHandler = new ActivityStackHandler(supervisor.mLooper);
         mWindowManager = mService.mWindowManager;
+        mRemoteToken = new RemoteToken(this);
         mCurrentUser = mService.mAmInternal.getCurrentUserId();
         // Set display id before setting activity and window type to make sure it won't affect
         // stacks on a wrong display.
@@ -529,6 +587,27 @@
         getBounds(newBounds);
 
         super.onConfigurationChanged(newParentConfig);
+
+        // Only need to update surface size here since the super method will handle updating
+        // surface position.
+        updateSurfaceSize(getPendingTransaction());
+
+        if (mDisplayContent == null) {
+            return;
+        }
+
+        if (prevWindowingMode != getWindowingMode()) {
+            mDisplayContent.onStackWindowingModeChanged(this);
+
+            if (inSplitScreenSecondaryWindowingMode()) {
+                // When the stack is resized due to entering split screen secondary, offset the
+                // windows to compensate for the new stack position.
+                forAllWindows(w -> {
+                    w.mWinAnimator.setOffsetPositionForStackResize(true);
+                }, true);
+            }
+        }
+
         final ActivityDisplay display = getDisplay();
         if (display == null ) {
             return;
@@ -669,7 +748,6 @@
             // Leaving a transient mode. Interpret UNDEFINED as "restore"
             windowingMode = mRestoreOverrideWindowingMode;
         }
-        mTmpOptions.setLaunchWindowingMode(windowingMode);
 
         // Need to make sure windowing mode is supported. If we in the process of creating the stack
         // no need to resolve the windowing mode again as it is already resolved to the right mode.
@@ -716,7 +794,7 @@
             return;
         }
 
-        final ActivityRecord topActivity = getTopActivity();
+        final ActivityRecord topActivity = getTopNonFinishingActivity();
 
         // For now, assume that the Stack's windowing mode is what will actually be used
         // by it's activities. In the future, there may be situations where this doesn't
@@ -835,20 +913,6 @@
         return mRootActivityContainer.getActivityDisplay(mDisplayId);
     }
 
-    void positionChildAtTop(Task child) {
-        positionChildAtTop(child, true /* includingParents */);
-    }
-
-    private void positionChildAtBottom(Task child) {
-        // If there are other focusable stacks on the display, the z-order of the display should not
-        // be changed just because a task was placed at the bottom. E.g. if it is moving the topmost
-        // task to bottom, the next focusable stack on the same display should be focused.
-        final ActivityStack nextFocusableStack = getDisplay().getNextFocusableStack(
-                child.getStack(), true /* ignoreCurrent */);
-        positionChildAtBottom(child, nextFocusableStack == null /* includingParents */);
-        child.updateTaskMovement(true);
-    }
-
     /**
      * Defers updating the bounds of the stack. If the stack was resized/repositioned while
      * deferring, the bounds will update in {@link #continueUpdateBounds()}.
@@ -977,9 +1041,9 @@
         return null;
     }
 
-    ActivityRecord getTopActivity() {
+    ActivityRecord getTopNonFinishingActivity() {
         for (int taskNdx = getChildCount() - 1; taskNdx >= 0; --taskNdx) {
-            final ActivityRecord r = getChildAt(taskNdx).getTopActivity();
+            final ActivityRecord r = getChildAt(taskNdx).getTopNonFinishingActivity();
             if (r != null) {
                 return r;
             }
@@ -1200,7 +1264,7 @@
             }
 
             // Overlays should not be considered as the task's logical top activity.
-            final ActivityRecord r = task.getTopActivity(false /* includeOverlays */);
+            final ActivityRecord r = task.getTopNonFinishingActivity(false /* includeOverlays */);
             if (r == null || r.finishing || r.mUserId != userId ||
                     r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
                 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r);
@@ -1759,7 +1823,7 @@
     }
 
     boolean isTopActivityVisible() {
-        final ActivityRecord topActivity = getTopActivity();
+        final ActivityRecord topActivity = getTopNonFinishingActivity();
         return topActivity != null && topActivity.visible;
     }
 
@@ -2835,7 +2899,7 @@
             boolean startIt = true;
             for (int taskNdx = getChildCount() - 1; taskNdx >= 0; --taskNdx) {
                 task = getChildAt(taskNdx);
-                if (task.getTopActivity() == null) {
+                if (task.getTopNonFinishingActivity() == null) {
                     // All activities in task are finishing.
                     continue;
                 }
@@ -3316,7 +3380,7 @@
 
         int taskNdx = mChildren.indexOf(task);
         if (taskNdx >= 0) {
-            ActivityRecord newTop = getChildAt(taskNdx).getTopActivity();
+            ActivityRecord newTop = getChildAt(taskNdx).getTopNonFinishingActivity();
             if (newTop != null) {
                 taskTop = newTop;
             }
@@ -3938,7 +4002,8 @@
         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);
 
         final ActivityStack topStack = getDisplay().getTopStack();
-        final ActivityRecord topActivity = topStack != null ? topStack.getTopActivity() : null;
+        final ActivityRecord topActivity = topStack != null
+                ? topStack.getTopNonFinishingActivity() : null;
         final int numTasks = getChildCount();
         final int index = mChildren.indexOf(tr);
         if (numTasks == 0 || index < 0)  {
@@ -3969,7 +4034,7 @@
             positionChildAtTop(tr);
 
             // Don't refocus if invisible to current user
-            final ActivityRecord top = tr.getTopActivity();
+            final ActivityRecord top = tr.getTopNonFinishingActivity();
             if (top == null || !top.okToShowLocked()) {
                 if (top != null) {
                     mStackSupervisor.mRecentTasks.add(top.getTask());
@@ -4288,7 +4353,7 @@
         int userId = UserHandle.getUserId(callingUid);
         for (int taskNdx = getChildCount() - 1; taskNdx >= 0; --taskNdx) {
             final Task task = getChildAt(taskNdx);
-            if (task.getTopActivity() == null) {
+            if (task.getTopNonFinishingActivity() == null) {
                 // Skip if there are no activities in the task
                 continue;
             }
@@ -4584,11 +4649,6 @@
         // We only want to move the parents to the parents if we are creating this task at the
         // top of its stack.
         addChild(task, toTop ? MAX_VALUE : 0, showForAllUsers, toTop /*moveParents*/);
-
-        if (toTop) {
-            // TODO(stack-merge): figure-out a way to remove this call.
-            positionChildAtTop(task);
-        }
     }
 
     void positionChildAt(Task task, int position) {
@@ -4602,15 +4662,19 @@
         final ActivityRecord topRunningActivity = task.topRunningActivityLocked();
         final boolean wasResumed = topRunningActivity == task.getStack().mResumedActivity;
 
-        // TODO(stack-merge): Can all of these be consolidated to just making the super call in the
-        //  else?
-        if (position >= getChildCount()) {
-            positionChildAtTop(task);
-        } else if (position <= 0) {
-            positionChildAtBottom(task);
-        } else {
-            super.positionChildAt(task, position);
+        boolean toTop = position >= getChildCount();
+        boolean includingParents = toTop || getDisplay().getNextFocusableStack(this,
+                true /* ignoreCurrent */) == null;
+        if (WindowManagerDebugConfig.DEBUG_STACK) {
+            Slog.i(TAG_WM, "positionChildAt: positioning task=" + task + " at " + position);
         }
+        positionChildAt(position, task, includingParents);
+        task.updateTaskMovement(toTop);
+        if (getDisplayContent().mAppTransition.isTransitionSet()) {
+            task.setSendingToBottom(!toTop);
+        }
+        getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
+
 
         // TODO: Investigate if this random code is really needed.
         if (task.voiceSession != null) {
@@ -4692,8 +4756,66 @@
                 return;
             }
         }
-        super.animateResizePinnedStack(
-                toBounds, sourceHintBounds, animationDuration, fromFullscreen);
+
+        // Get the from-bounds
+        final Rect fromBounds = new Rect();
+        getBounds(fromBounds);
+
+        // Get non-null fullscreen to-bounds for animating if the bounds are null
+        @BoundsAnimationController.SchedulePipModeChangedState int schedulePipModeChangedState =
+                NO_PIP_MODE_CHANGED_CALLBACKS;
+        final boolean toFullscreen = toBounds == null;
+        if (toFullscreen) {
+            if (fromFullscreen) {
+                throw new IllegalArgumentException("Should not defer scheduling PiP mode"
+                        + " change on animation to fullscreen.");
+            }
+            schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_START;
+
+            mWmService.getStackBounds(
+                    WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mTmpToBounds);
+            if (!mTmpToBounds.isEmpty()) {
+                // If there is a fullscreen bounds, use that
+                toBounds = new Rect(mTmpToBounds);
+            } else {
+                // Otherwise, use the display bounds
+                toBounds = new Rect();
+                getDisplayContent().getBounds(toBounds);
+            }
+        } else if (fromFullscreen) {
+            schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_END;
+        }
+
+        setAnimationFinalBounds(sourceHintBounds, toBounds, toFullscreen);
+
+        final Rect finalToBounds = toBounds;
+        final @BoundsAnimationController.SchedulePipModeChangedState int
+                finalSchedulePipModeChangedState = schedulePipModeChangedState;
+        final DisplayContent displayContent = getDisplayContent();
+        @BoundsAnimationController.AnimationType int intendedAnimationType =
+                displayContent.mBoundsAnimationController.getAnimationType();
+        if (intendedAnimationType == FADE_IN) {
+            if (fromFullscreen) {
+                setPinnedStackAlpha(0f);
+            }
+            if (toBounds.width() == fromBounds.width()
+                    && toBounds.height() == fromBounds.height()) {
+                intendedAnimationType = BoundsAnimationController.BOUNDS;
+            } else if (!fromFullscreen && !toBounds.equals(fromBounds)) {
+                // intendedAnimationType may have been reset at the end of RecentsAnimation,
+                // force it to BOUNDS type if we know for certain we're animating to
+                // a different bounds, especially for expand and collapse of PiP window.
+                intendedAnimationType = BoundsAnimationController.BOUNDS;
+            }
+        }
+
+        final @BoundsAnimationController.AnimationType int animationType = intendedAnimationType;
+        mCancelCurrentBoundsAnimation = false;
+        displayContent.mBoundsAnimationController.getHandler().post(() -> {
+            displayContent.mBoundsAnimationController.animateBounds(this, fromBounds,
+                    finalToBounds, animationDuration, finalSchedulePipModeChangedState,
+                    fromFullscreen, toFullscreen, animationType);
+        });
     }
 
     void dismissPip() {
@@ -4747,6 +4869,1580 @@
         return mStackId;
     }
 
+    Task findHomeTask() {
+        if (!isActivityTypeHome() || mChildren.isEmpty()) {
+            return null;
+        }
+        return mChildren.get(mChildren.size() - 1);
+    }
+
+    void prepareFreezingTaskBounds() {
+        for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
+            final Task task = mChildren.get(taskNdx);
+            task.prepareFreezingBounds();
+        }
+    }
+
+    /**
+     * Overrides the adjusted bounds, i.e. sets temporary layout bounds which are different from
+     * the normal task bounds.
+     *
+     * @param bounds The adjusted bounds.
+     */
+    private void setAdjustedBounds(Rect bounds) {
+        if (mAdjustedBounds.equals(bounds) && !isAnimatingForIme()) {
+            return;
+        }
+
+        mAdjustedBounds.set(bounds);
+        final boolean adjusted = !mAdjustedBounds.isEmpty();
+        Rect insetBounds = null;
+        if (adjusted && isAdjustedForMinimizedDockedStack()) {
+            insetBounds = getRawBounds();
+        } else if (adjusted && mAdjustedForIme) {
+            if (mImeGoingAway) {
+                insetBounds = getRawBounds();
+            } else {
+                insetBounds = mFullyAdjustedImeBounds;
+            }
+        }
+        alignTasksToAdjustedBounds(adjusted ? mAdjustedBounds : getRawBounds(), insetBounds);
+        mDisplayContent.setLayoutNeeded();
+
+        updateSurfaceBounds();
+    }
+
+    private void alignTasksToAdjustedBounds(Rect adjustedBounds, Rect tempInsetBounds) {
+        if (matchParentBounds()) {
+            return;
+        }
+
+        final boolean alignBottom = mAdjustedForIme && getDockSide() == DOCKED_TOP;
+
+        // Update bounds of containing tasks.
+        for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
+            final Task task = mChildren.get(taskNdx);
+            task.alignToAdjustedBounds(adjustedBounds, tempInsetBounds, alignBottom);
+        }
+    }
+
+    @Override
+    public int setBounds(Rect bounds) {
+        return setBounds(getRequestedOverrideBounds(), bounds);
+    }
+
+    private int setBounds(Rect existing, Rect bounds) {
+        if (equivalentBounds(existing, bounds)) {
+            return BOUNDS_CHANGE_NONE;
+        }
+
+        final int result = super.setBounds(!inMultiWindowMode() ? null : bounds);
+
+        updateAdjustedBounds();
+
+        updateSurfaceBounds();
+        return result;
+    }
+
+    /** Bounds of the stack without adjusting for other factors in the system like visibility
+     * of docked stack.
+     * Most callers should be using {@link ConfigurationContainer#getRequestedOverrideBounds} a
+     * it takes into consideration other system factors. */
+    void getRawBounds(Rect out) {
+        out.set(getRawBounds());
+    }
+
+    private Rect getRawBounds() {
+        return super.getBounds();
+    }
+
+    @Override
+    public void getBounds(Rect bounds) {
+        bounds.set(getBounds());
+    }
+
+    @Override
+    public Rect getBounds() {
+        // If we're currently adjusting for IME or minimized docked stack, we use the adjusted
+        // bounds; otherwise, no need to adjust the output bounds if fullscreen or the docked
+        // stack is visible since it is already what we want to represent to the rest of the
+        // system.
+        if (!mAdjustedBounds.isEmpty()) {
+            return mAdjustedBounds;
+        } else {
+            return super.getBounds();
+        }
+    }
+
+    /**
+     * Sets the bounds animation target bounds ahead of an animation.  This can't currently be done
+     * in onAnimationStart() since that is started on the UiThread.
+     */
+    private void setAnimationFinalBounds(Rect sourceHintBounds, Rect destBounds,
+            boolean toFullscreen) {
+        if (mAnimationType == BoundsAnimationController.BOUNDS) {
+            mBoundsAnimatingRequested = true;
+        }
+        mBoundsAnimatingToFullscreen = toFullscreen;
+        if (destBounds != null) {
+            mBoundsAnimationTarget.set(destBounds);
+        } else {
+            mBoundsAnimationTarget.setEmpty();
+        }
+        if (sourceHintBounds != null) {
+            mBoundsAnimationSourceHintBounds.set(sourceHintBounds);
+        } else if (!mBoundsAnimating) {
+            // If the bounds are already animating, we don't want to reset the source hint. This is
+            // because the source hint is sent when starting the animation from the client that
+            // requested to enter pip. Other requests can adjust the pip bounds during an animation,
+            // but could accidentally reset the source hint bounds.
+            mBoundsAnimationSourceHintBounds.setEmpty();
+        }
+
+        mPreAnimationBounds.set(getRawBounds());
+    }
+
+    /**
+     * @return the final bounds for the bounds animation.
+     */
+    void getFinalAnimationBounds(Rect outBounds) {
+        outBounds.set(mBoundsAnimationTarget);
+    }
+
+    /**
+     * @return the final source bounds for the bounds animation.
+     */
+    void getFinalAnimationSourceHintBounds(Rect outBounds) {
+        outBounds.set(mBoundsAnimationSourceHintBounds);
+    }
+
+    /**
+     * @return the final animation bounds if the task stack is currently being animated, or the
+     *         current stack bounds otherwise.
+     */
+    void getAnimationOrCurrentBounds(Rect outBounds) {
+        if ((mBoundsAnimatingRequested || mBoundsAnimating) && !mBoundsAnimationTarget.isEmpty()) {
+            getFinalAnimationBounds(outBounds);
+            return;
+        }
+        getBounds(outBounds);
+    }
+
+    /** Bounds of the stack with other system factors taken into consideration. */
+    void getDimBounds(Rect out) {
+        getBounds(out);
+    }
+
+    /**
+     * Updates the passed-in {@code inOutBounds} based on the current state of the
+     * pinned controller. This gets run *after* the override configuration is updated, so it's
+     * safe to rely on the controller's state in here (though eventually this dependence should
+     * be removed).
+     *
+     * This does NOT modify this TaskStack's configuration. However, it does, for the time-being,
+     * update pinned controller state.
+     *
+     * @param inOutBounds the bounds to update (both input and output).
+     * @return true if bounds were updated to some non-empty value.
+     */
+    boolean calculatePinnedBoundsForConfigChange(Rect inOutBounds) {
+        boolean animating = false;
+        if ((mBoundsAnimatingRequested || mBoundsAnimating) && !mBoundsAnimationTarget.isEmpty()) {
+            animating = true;
+            getFinalAnimationBounds(mTmpRect2);
+        } else {
+            mTmpRect2.set(inOutBounds);
+        }
+        boolean updated = mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(
+                mTmpRect2, mTmpRect3);
+        if (updated) {
+            inOutBounds.set(mTmpRect3);
+
+            // The final boundary is updated while there is an existing boundary animation. Let's
+            // cancel this animation to prevent the obsolete animation overwritten updated bounds.
+            if (animating && !inOutBounds.equals(mBoundsAnimationTarget)) {
+                final DisplayContent displayContent = getDisplayContent();
+                displayContent.mBoundsAnimationController.getHandler().post(() ->
+                        displayContent.mBoundsAnimationController.cancel(this));
+            }
+            // Once we've set the bounds based on the rotation of the old bounds in the new
+            // orientation, clear the animation target bounds since they are obsolete, and
+            // cancel any currently running animations
+            mBoundsAnimationTarget.setEmpty();
+            mBoundsAnimationSourceHintBounds.setEmpty();
+            mCancelCurrentBoundsAnimation = true;
+        }
+        return updated;
+    }
+
+    /**
+     * Updates the passed-in {@code inOutBounds} based on the current state of the
+     * docked controller. This gets run *after* the override configuration is updated, so it's
+     * safe to rely on the controller's state in here (though eventually this dependence should
+     * be removed).
+     *
+     * This does NOT modify this TaskStack's configuration. However, it does, for the time-being,
+     * update docked controller state.
+     *
+     * @param parentConfig the parent configuration for reference.
+     * @param inOutBounds the bounds to update (both input and output).
+     */
+    void calculateDockedBoundsForConfigChange(Configuration parentConfig, Rect inOutBounds) {
+        final boolean primary =
+                getRequestedOverrideWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+        repositionSplitScreenStackAfterRotation(parentConfig, primary, inOutBounds);
+        final DisplayCutout cutout = mDisplayContent.getDisplayInfo().displayCutout;
+        snapDockedStackAfterRotation(parentConfig, cutout, inOutBounds);
+        if (primary) {
+            final int newDockSide = getDockSide(parentConfig, inOutBounds);
+            // Update the dock create mode and clear the dock create bounds, these
+            // might change after a rotation and the original values will be invalid.
+            mWmService.setDockedStackCreateStateLocked(
+                    (newDockSide == DOCKED_LEFT || newDockSide == DOCKED_TOP)
+                            ? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT
+                            : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT,
+                    null);
+            mDisplayContent.getDockedDividerController().notifyDockSideChanged(newDockSide);
+        }
+    }
+
+    /**
+     * Some primary split screen sides are not allowed by the policy. This method queries the policy
+     * and moves the primary stack around if needed.
+     *
+     * @param parentConfig the configuration of the stack's parent.
+     * @param primary true if adjusting the primary docked stack, false for secondary.
+     * @param inOutBounds the bounds of the stack to adjust.
+     */
+    void repositionSplitScreenStackAfterRotation(Configuration parentConfig, boolean primary,
+            Rect inOutBounds) {
+        final int dockSide = getDockSide(mDisplayContent, parentConfig, inOutBounds);
+        final int otherDockSide = DockedDividerUtils.invertDockSide(dockSide);
+        final int primaryDockSide = primary ? dockSide : otherDockSide;
+        if (mDisplayContent.getDockedDividerController()
+                .canPrimaryStackDockTo(primaryDockSide,
+                        parentConfig.windowConfiguration.getBounds(),
+                        parentConfig.windowConfiguration.getRotation())) {
+            return;
+        }
+        final Rect parentBounds = parentConfig.windowConfiguration.getBounds();
+        switch (otherDockSide) {
+            case DOCKED_LEFT:
+                int movement = inOutBounds.left;
+                inOutBounds.left -= movement;
+                inOutBounds.right -= movement;
+                break;
+            case DOCKED_RIGHT:
+                movement = parentBounds.right - inOutBounds.right;
+                inOutBounds.left += movement;
+                inOutBounds.right += movement;
+                break;
+            case DOCKED_TOP:
+                movement = inOutBounds.top;
+                inOutBounds.top -= movement;
+                inOutBounds.bottom -= movement;
+                break;
+            case DOCKED_BOTTOM:
+                movement = parentBounds.bottom - inOutBounds.bottom;
+                inOutBounds.top += movement;
+                inOutBounds.bottom += movement;
+                break;
+        }
+    }
+
+    /**
+     * Snaps the bounds after rotation to the closest snap target for the docked stack.
+     */
+    void snapDockedStackAfterRotation(Configuration parentConfig, DisplayCutout displayCutout,
+            Rect outBounds) {
+
+        // Calculate the current position.
+        final int dividerSize = mDisplayContent.getDockedDividerController().getContentWidth();
+        final int dockSide = getDockSide(parentConfig, outBounds);
+        final int dividerPosition = DockedDividerUtils.calculatePositionForBounds(outBounds,
+                dockSide, dividerSize);
+        final int displayWidth = parentConfig.windowConfiguration.getBounds().width();
+        final int displayHeight = parentConfig.windowConfiguration.getBounds().height();
+
+        // Snap the position to a target.
+        final int rotation = parentConfig.windowConfiguration.getRotation();
+        final int orientation = parentConfig.orientation;
+        mDisplayContent.getDisplayPolicy().getStableInsetsLw(rotation, displayWidth, displayHeight,
+                displayCutout, outBounds);
+        final DividerSnapAlgorithm algorithm = new DividerSnapAlgorithm(
+                mWmService.mContext.getResources(), displayWidth, displayHeight,
+                dividerSize, orientation == Configuration.ORIENTATION_PORTRAIT, outBounds,
+                getDockSide(), isMinimizedDockAndHomeStackResizable());
+        final DividerSnapAlgorithm.SnapTarget target =
+                algorithm.calculateNonDismissingSnapTarget(dividerPosition);
+
+        // Recalculate the bounds based on the position of the target.
+        DockedDividerUtils.calculateBoundsForPosition(target.position, dockSide,
+                outBounds, displayWidth, displayHeight,
+                dividerSize);
+    }
+
+    /**
+     * Put a Task in this stack. Used for adding only.
+     * When task is added to top of the stack, the entire branch of the hierarchy (including stack
+     * and display) will be brought to top.
+     * @param task The task to add.
+     * @param position Target position to add the task to.
+     * @param showForAllUsers Whether to show the task regardless of the current user.
+     */
+    void addChild(Task task, int position, boolean showForAllUsers, boolean moveParents) {
+        // Add child task.
+        addChild(task, null);
+
+        // Move child to a proper position, as some restriction for position might apply.
+        position = positionChildAt(
+                position, task, moveParents /* includingParents */, showForAllUsers);
+    }
+
+    @Override
+    void addChild(Task task, int position) {
+        addChild(task, position, task.showForAllUsers(), false /* includingParents */);
+    }
+
+    void positionChildAtTop(Task child) {
+        if (child == null) {
+            // TODO: Fix the call-points that cause this to happen.
+            return;
+        }
+
+        positionChildAt(POSITION_TOP, child, true /* includingParents */);
+        child.updateTaskMovement(true);
+
+        final DisplayContent displayContent = getDisplayContent();
+        if (displayContent.mAppTransition.isTransitionSet()) {
+            child.setSendingToBottom(false);
+        }
+        displayContent.layoutAndAssignWindowLayersIfNeeded();
+    }
+
+    private void positionChildAtBottom(Task child) {
+        // If there are other focusable stacks on the display, the z-order of the display should not
+        // be changed just because a task was placed at the bottom. E.g. if it is moving the topmost
+        // task to bottom, the next focusable stack on the same display should be focused.
+        final ActivityStack nextFocusableStack = getDisplay().getNextFocusableStack(
+                child.getStack(), true /* ignoreCurrent */);
+        positionChildAtBottom(child, nextFocusableStack == null /* includingParents */);
+        child.updateTaskMovement(true);
+    }
+
+    @VisibleForTesting
+    void positionChildAtBottom(Task child, boolean includingParents) {
+        if (child == null) {
+            // TODO: Fix the call-points that cause this to happen.
+            return;
+        }
+
+        positionChildAt(POSITION_BOTTOM, child, includingParents);
+
+        if (getDisplayContent().mAppTransition.isTransitionSet()) {
+            child.setSendingToBottom(true);
+        }
+        getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
+    }
+
+    @Override
+    void positionChildAt(int position, Task child, boolean includingParents) {
+        positionChildAt(position, child, includingParents, child.showForAllUsers());
+    }
+
+    /**
+     * Overridden version of {@link ActivityStack#positionChildAt(int, Task, boolean)}. Used in
+     * {@link ActivityStack#addChild(Task, int, boolean showForAllUsers, boolean)}, as it can
+     * receive showForAllUsers param from {@link ActivityRecord} instead of
+     * {@link Task#showForAllUsers()}.
+     */
+    private int positionChildAt(int position, Task child, boolean includingParents,
+            boolean showForAllUsers) {
+        final int targetPosition = findPositionForTask(child, position, showForAllUsers);
+        super.positionChildAt(targetPosition, child, includingParents);
+
+        // Log positioning.
+        if (DEBUG_TASK_MOVEMENT) {
+            Slog.d(TAG_WM, "positionTask: task=" + this + " position=" + position);
+        }
+
+        final int toTop = targetPosition == mChildren.size() - 1 ? 1 : 0;
+        EventLog.writeEvent(com.android.server.EventLogTags.WM_TASK_MOVED, child.mTaskId, toTop,
+                targetPosition);
+
+        return targetPosition;
+    }
+
+    @Override
+    void onChildPositionChanged(WindowContainer child) {
+        if (!mChildren.contains(child)) {
+            return;
+        }
+
+        final Task task = (Task) child;
+        final boolean isTop = getTopChild() == task;
+        task.updateTaskMovement(isTop);
+        if (isTop) {
+            final DisplayContent displayContent = getDisplayContent();
+            if (displayContent.mAppTransition.isTransitionSet()) {
+                task.setSendingToBottom(false);
+            }
+            displayContent.layoutAndAssignWindowLayersIfNeeded();
+        }
+    }
+
+    // TODO(display-unify): Remove after display unification.
+    protected void onParentChanged(ActivityDisplay newParent, ActivityDisplay oldParent) {
+        onParentChanged(
+                newParent != null ? newParent.mDisplayContent : null,
+                oldParent != null ? oldParent.mDisplayContent : null);
+    }
+
+    @Override
+    protected void onParentChanged(
+            ConfigurationContainer newParent, ConfigurationContainer oldParent) {
+        final ActivityDisplay display = newParent != null
+                ? ((WindowContainer) newParent).getDisplayContent().mActivityDisplay : null;
+        final ActivityDisplay oldDisplay = oldParent != null
+                ? ((WindowContainer) oldParent).getDisplayContent().mActivityDisplay : null;
+
+        mDisplayId = (display != null) ? display.mDisplayId : INVALID_DISPLAY;
+        mPrevDisplayId = (oldDisplay != null) ? oldDisplay.mDisplayId : INVALID_DISPLAY;
+
+        if (display != null) {
+            // Rotations are relative to the display. This means if there are 2 displays rotated
+            // differently (eg. 2 monitors with one landscape and one portrait), moving a stack
+            // from one to the other could look like a rotation change. To prevent this
+            // apparent rotation change (and corresponding bounds rotation), pretend like our
+            // current rotation is already the same as the new display.
+            // Note, if ActivityStack or related logic ever gets nested, this logic will need
+            // to move to onConfigurationChanged.
+            getConfiguration().windowConfiguration.setRotation(
+                    display.getWindowConfiguration().getRotation());
+        }
+        super.onParentChanged(newParent, oldParent);
+        if (getParent() == null && mDisplayContent != null) {
+            EventLog.writeEvent(com.android.server.EventLogTags.WM_STACK_REMOVED, mStackId);
+
+            mDisplayContent = null;
+            mWmService.mWindowPlacerLocked.requestTraversal();
+        }
+        if (display != null && 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);
+        }
+        mRootActivityContainer.updateUIDsPresentOnDisplay();
+
+        // Resume next focusable stack after reparenting to another display if we aren't removing
+        // the prevous display.
+        if (oldDisplay != null && oldDisplay.isRemoving()) {
+            postReparent();
+        }
+    }
+
+    void reparent(DisplayContent newParent, boolean onTop) {
+        // Real parent of stack is within display object, so we have to delegate re-parenting there.
+        newParent.moveStackToDisplay(this, onTop);
+    }
+
+    // TODO: We should really have users as a window container in the hierarchy so that we don't
+    // have to do complicated things like we are doing in this method.
+    int findPositionForTask(Task task, int targetPosition, boolean showForAllUsers) {
+        final boolean canShowTask =
+                showForAllUsers || mWmService.isCurrentProfileLocked(task.mUserId);
+
+        final int stackSize = mChildren.size();
+        int minPosition = 0;
+        int maxPosition = stackSize - 1;
+
+        if (canShowTask) {
+            minPosition = computeMinPosition(minPosition, stackSize);
+        } else {
+            maxPosition = computeMaxPosition(maxPosition);
+        }
+
+        // preserve POSITION_BOTTOM/POSITION_TOP positions if they are still valid.
+        if (targetPosition == POSITION_BOTTOM && minPosition == 0) {
+            return POSITION_BOTTOM;
+        } else if (targetPosition == POSITION_TOP && maxPosition == (stackSize - 1)) {
+            return POSITION_TOP;
+        }
+        // Reset position based on minimum/maximum possible positions.
+        return Math.min(Math.max(targetPosition, minPosition), maxPosition);
+    }
+
+    /** Calculate the minimum possible position for a task that can be shown to the user.
+     *  The minimum position will be above all other tasks that can't be shown.
+     *  @param minPosition The minimum position the caller is suggesting.
+     *                  We will start adjusting up from here.
+     *  @param size The size of the current task list.
+     */
+    private int computeMinPosition(int minPosition, int size) {
+        while (minPosition < size) {
+            final Task tmpTask = mChildren.get(minPosition);
+            final boolean canShowTmpTask =
+                    tmpTask.showForAllUsers()
+                            || mWmService.isCurrentProfileLocked(tmpTask.mUserId);
+            if (canShowTmpTask) {
+                break;
+            }
+            minPosition++;
+        }
+        return minPosition;
+    }
+
+    /** Calculate the maximum possible position for a task that can't be shown to the user.
+     *  The maximum position will be below all other tasks that can be shown.
+     *  @param maxPosition The maximum position the caller is suggesting.
+     *                  We will start adjusting down from here.
+     */
+    private int computeMaxPosition(int maxPosition) {
+        while (maxPosition > 0) {
+            final Task tmpTask = mChildren.get(maxPosition);
+            final boolean canShowTmpTask =
+                    tmpTask.showForAllUsers()
+                            || mWmService.isCurrentProfileLocked(tmpTask.mUserId);
+            if (!canShowTmpTask) {
+                break;
+            }
+            maxPosition--;
+        }
+        return maxPosition;
+    }
+
+    private void updateSurfaceBounds() {
+        updateSurfaceSize(getPendingTransaction());
+        updateSurfacePosition();
+        scheduleAnimation();
+    }
+
+    /**
+     * Calculate an amount by which to expand the stack bounds in each direction.
+     * Used to make room for shadows in the pinned windowing mode.
+     */
+    int getStackOutset() {
+        DisplayContent displayContent = getDisplayContent();
+        if (inPinnedWindowingMode() && displayContent != null) {
+            final DisplayMetrics displayMetrics = displayContent.getDisplayMetrics();
+
+            // We multiply by two to match the client logic for converting view elevation
+            // to insets, as in {@link WindowManager.LayoutParams#setSurfaceInsets}
+            return (int) Math.ceil(
+                    mWmService.dipToPixel(PINNED_WINDOWING_MODE_ELEVATION_IN_DIP, displayMetrics)
+                            * 2);
+        }
+        return 0;
+    }
+
+    @Override
+    void getRelativeDisplayedPosition(Point outPos) {
+        super.getRelativeDisplayedPosition(outPos);
+        final int outset = getStackOutset();
+        outPos.x -= outset;
+        outPos.y -= outset;
+    }
+
+    private void updateSurfaceSize(SurfaceControl.Transaction transaction) {
+        if (mSurfaceControl == null) {
+            return;
+        }
+
+        final Rect stackBounds = getDisplayedBounds();
+        int width = stackBounds.width();
+        int height = stackBounds.height();
+
+        final int outset = getStackOutset();
+        width += 2 * outset;
+        height += 2 * outset;
+
+        if (width == mLastSurfaceSize.x && height == mLastSurfaceSize.y) {
+            return;
+        }
+        transaction.setWindowCrop(mSurfaceControl, width, height);
+        mLastSurfaceSize.set(width, height);
+    }
+
+    @VisibleForTesting
+    Point getLastSurfaceSize() {
+        return mLastSurfaceSize;
+    }
+
+    @Override
+    void onDisplayChanged(DisplayContent dc) {
+        super.onDisplayChanged(dc);
+        updateSurfaceBounds();
+    }
+
+    /**
+     * Determines the stack and task bounds of the other stack when in docked mode. The current task
+     * bounds is passed in but depending on the stack, the task and stack must match. Only in
+     * minimized mode with resizable launcher, the other stack ignores calculating the stack bounds
+     * and uses the task bounds passed in as the stack and task bounds, otherwise the stack bounds
+     * is calculated and is also used for its task bounds.
+     * If any of the out bounds are empty, it represents default bounds
+     *
+     * @param currentTempTaskBounds the current task bounds of the other stack
+     * @param outStackBounds the calculated stack bounds of the other stack
+     * @param outTempTaskBounds the calculated task bounds of the other stack
+     */
+    void getStackDockedModeBounds(Rect dockedBounds,
+            Rect currentTempTaskBounds, Rect outStackBounds, Rect outTempTaskBounds) {
+        final Configuration parentConfig = getParent().getConfiguration();
+        outTempTaskBounds.setEmpty();
+
+        if (dockedBounds == null || dockedBounds.isEmpty()) {
+            // Calculate the primary docked bounds.
+            final boolean dockedOnTopOrLeft = mWmService.mDockedStackCreateMode
+                    == SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
+            getStackDockedModeBounds(parentConfig,
+                    true /* primary */, outStackBounds, dockedBounds,
+                    mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
+            return;
+        }
+        final int dockedSide = getDockSide(parentConfig, dockedBounds);
+
+        // When the home stack is resizable, should always have the same stack and task bounds
+        if (isActivityTypeHome()) {
+            final Task homeTask = findHomeTask();
+            if (homeTask == null || homeTask.isResizeable()) {
+                // Calculate the home stack bounds when in docked mode and the home stack is
+                // resizeable.
+                getDisplayContent().mDividerControllerLocked
+                        .getHomeStackBoundsInDockedMode(parentConfig,
+                                dockedSide, outStackBounds);
+            } else {
+                // Home stack isn't resizeable, so don't specify stack bounds.
+                outStackBounds.setEmpty();
+            }
+
+            outTempTaskBounds.set(outStackBounds);
+            return;
+        }
+
+        // When minimized state, the stack bounds for all non-home and docked stack bounds should
+        // match the passed task bounds
+        if (isMinimizedDockAndHomeStackResizable() && currentTempTaskBounds != null) {
+            outStackBounds.set(currentTempTaskBounds);
+            return;
+        }
+
+        if (dockedSide == DOCKED_INVALID) {
+            // Not sure how you got here...Only thing we can do is return current bounds.
+            Slog.e(TAG_WM, "Failed to get valid docked side for docked stack");
+            outStackBounds.set(getRawBounds());
+            return;
+        }
+
+        final boolean dockedOnTopOrLeft = dockedSide == DOCKED_TOP || dockedSide == DOCKED_LEFT;
+        getStackDockedModeBounds(parentConfig,
+                false /* primary */, outStackBounds, dockedBounds,
+                mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
+    }
+
+    /**
+     * Outputs the bounds a stack should be given the presence of a docked stack on the display.
+     * @param parentConfig The parent configuration.
+     * @param primary {@code true} if getting the primary stack bounds.
+     * @param outBounds Output bounds that should be used for the stack.
+     * @param dockedBounds Bounds of the docked stack.
+     * @param dockDividerWidth We need to know the width of the divider make to the output bounds
+     *                         close to the side of the dock.
+     * @param dockOnTopOrLeft If the docked stack is on the top or left side of the screen.
+     */
+    private void getStackDockedModeBounds(Configuration parentConfig, boolean primary,
+            Rect outBounds, Rect dockedBounds, int dockDividerWidth,
+            boolean dockOnTopOrLeft) {
+        final Rect displayRect = parentConfig.windowConfiguration.getBounds();
+        final boolean splitHorizontally = displayRect.width() > displayRect.height();
+
+        outBounds.set(displayRect);
+        if (primary) {
+            if (mWmService.mDockedStackCreateBounds != null) {
+                outBounds.set(mWmService.mDockedStackCreateBounds);
+                return;
+            }
+
+            // The initial bounds of the docked stack when it is created about half the screen space
+            // and its bounds can be adjusted after that. The bounds of all other stacks are
+            // adjusted to occupy whatever screen space the docked stack isn't occupying.
+            final DisplayCutout displayCutout = mDisplayContent.getDisplayInfo().displayCutout;
+            mDisplayContent.getDisplayPolicy().getStableInsetsLw(
+                    parentConfig.windowConfiguration.getRotation(),
+                    displayRect.width(), displayRect.height(), displayCutout, mTmpRect2);
+            final int position = new DividerSnapAlgorithm(mWmService.mContext.getResources(),
+                    displayRect.width(),
+                    displayRect.height(),
+                    dockDividerWidth,
+                    parentConfig.orientation == ORIENTATION_PORTRAIT,
+                    mTmpRect2).getMiddleTarget().position;
+
+            if (dockOnTopOrLeft) {
+                if (splitHorizontally) {
+                    outBounds.right = position;
+                } else {
+                    outBounds.bottom = position;
+                }
+            } else {
+                if (splitHorizontally) {
+                    outBounds.left = position + dockDividerWidth;
+                } else {
+                    outBounds.top = position + dockDividerWidth;
+                }
+            }
+            return;
+        }
+
+        // Other stacks occupy whatever space is left by the docked stack.
+        if (!dockOnTopOrLeft) {
+            if (splitHorizontally) {
+                outBounds.right = dockedBounds.left - dockDividerWidth;
+            } else {
+                outBounds.bottom = dockedBounds.top - dockDividerWidth;
+            }
+        } else {
+            if (splitHorizontally) {
+                outBounds.left = dockedBounds.right + dockDividerWidth;
+            } else {
+                outBounds.top = dockedBounds.bottom + dockDividerWidth;
+            }
+        }
+        DockedDividerUtils.sanitizeStackBounds(outBounds, !dockOnTopOrLeft);
+    }
+
+    void resetDockedStackToMiddle() {
+        if (!inSplitScreenPrimaryWindowingMode()) {
+            throw new IllegalStateException("Not a docked stack=" + this);
+        }
+
+        mWmService.mDockedStackCreateBounds = null;
+
+        final Rect bounds = new Rect();
+        final Rect tempBounds = new Rect();
+        getStackDockedModeBounds(null /* dockedBounds */, null /* currentTempTaskBounds */,
+                bounds, tempBounds);
+        mStackSupervisor.resizeDockedStackLocked(bounds, null /* tempTaskBounds */,
+                null /* tempTaskInsetBounds */, null /* tempOtherTaskBounds */,
+                null /* tempOtherTaskInsetBounds */, false /* preserveWindows */,
+                false /* deferResume */);
+    }
+
+    @Override
+    void removeIfPossible() {
+        if (isAnimating(TRANSITION | CHILDREN)) {
+            mDeferRemoval = true;
+            return;
+        }
+        removeImmediately();
+    }
+
+    /**
+     * Adjusts the stack bounds if the IME is visible.
+     *
+     * @param imeWin The IME window.
+     * @param keepLastAmount Use {@code true} to keep the last adjusted amount from
+     *                       {@link DockedStackDividerController} for adjusting the stack bounds,
+     *                       Use {@code false} to reset adjusted amount as 0.
+     * @see #updateAdjustForIme(float, float, boolean)
+     */
+    void setAdjustedForIme(WindowState imeWin, boolean keepLastAmount) {
+        mImeWin = imeWin;
+        mImeGoingAway = false;
+        if (!mAdjustedForIme || keepLastAmount) {
+            mAdjustedForIme = true;
+            DockedStackDividerController controller = getDisplayContent().mDividerControllerLocked;
+            final float adjustImeAmount = keepLastAmount ? controller.mLastAnimationProgress : 0f;
+            final float adjustDividerAmount = keepLastAmount ? controller.mLastDividerProgress : 0f;
+            updateAdjustForIme(adjustImeAmount, adjustDividerAmount, true /* force */);
+        }
+    }
+
+    boolean isAdjustedForIme() {
+        return mAdjustedForIme;
+    }
+
+    boolean isAnimatingForIme() {
+        return mImeWin != null && mImeWin.isAnimatingLw();
+    }
+
+    /**
+     * Update the stack's bounds (crop or position) according to the IME window's
+     * current position. When IME window is animated, the bottom stack is animated
+     * together to track the IME window's current position, and the top stack is
+     * cropped as necessary.
+     *
+     * @return true if a traversal should be performed after the adjustment.
+     */
+    boolean updateAdjustForIme(float adjustAmount, float adjustDividerAmount, boolean force) {
+        if (adjustAmount != mAdjustImeAmount
+                || adjustDividerAmount != mAdjustDividerAmount || force) {
+            mAdjustImeAmount = adjustAmount;
+            mAdjustDividerAmount = adjustDividerAmount;
+            updateAdjustedBounds();
+            return isVisible();
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Resets the adjustment after it got adjusted for the IME.
+     * @param adjustBoundsNow if true, reset and update the bounds immediately and forget about
+     *                        animations; otherwise, set flag and animates the window away together
+     *                        with IME window.
+     */
+    void resetAdjustedForIme(boolean adjustBoundsNow) {
+        if (adjustBoundsNow) {
+            mImeWin = null;
+            mImeGoingAway = false;
+            mAdjustImeAmount = 0f;
+            mAdjustDividerAmount = 0f;
+            if (!mAdjustedForIme) {
+                return;
+            }
+            mAdjustedForIme = false;
+            updateAdjustedBounds();
+            mWmService.setResizeDimLayer(false, getWindowingMode(), 1.0f);
+        } else {
+            mImeGoingAway |= mAdjustedForIme;
+        }
+    }
+
+    /**
+     * Sets the amount how much we currently minimize our stack.
+     *
+     * @param minimizeAmount The amount, between 0 and 1.
+     * @return Whether the amount has changed and a layout is needed.
+     */
+    boolean setAdjustedForMinimizedDock(float minimizeAmount) {
+        if (minimizeAmount != mMinimizeAmount) {
+            mMinimizeAmount = minimizeAmount;
+            updateAdjustedBounds();
+            return isVisible();
+        } else {
+            return false;
+        }
+    }
+
+    boolean shouldIgnoreInput() {
+        return isAdjustedForMinimizedDockedStack()
+                || (inSplitScreenPrimaryWindowingMode() && isMinimizedDockAndHomeStackResizable());
+    }
+
+    /**
+     * Puts all visible tasks that are adjusted for IME into resizing mode and adds the windows
+     * to the list of to be drawn windows the service is waiting for.
+     */
+    void beginImeAdjustAnimation() {
+        for (int j = mChildren.size() - 1; j >= 0; j--) {
+            final Task task = mChildren.get(j);
+            if (task.hasContentToDisplay()) {
+                task.setDragResizing(true, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
+                task.setWaitingForDrawnIfResizingChanged();
+            }
+        }
+    }
+
+    /**
+     * Resets the resizing state of all windows.
+     */
+    void endImeAdjustAnimation() {
+        for (int j = mChildren.size() - 1; j >= 0; j--) {
+            mChildren.get(j).setDragResizing(false, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
+        }
+    }
+
+    int getMinTopStackBottom(final Rect displayContentRect, int originalStackBottom) {
+        return displayContentRect.top + (int)
+                ((originalStackBottom - displayContentRect.top) * ADJUSTED_STACK_FRACTION_MIN);
+    }
+
+    private boolean adjustForIME(final WindowState imeWin) {
+        // To prevent task stack resize animation may flicking when playing app transition
+        // animation & IME window enter animation in parallel, we need to make sure app
+        // transition is done and then adjust task size for IME, skip the new adjusted frame when
+        // app transition is still running.
+        if (getDisplayContent().mAppTransition.isRunning()) {
+            return false;
+        }
+
+        final int dockedSide = getDockSide();
+        final boolean dockedTopOrBottom = dockedSide == DOCKED_TOP || dockedSide == DOCKED_BOTTOM;
+        if (imeWin == null || !dockedTopOrBottom) {
+            return false;
+        }
+
+        final Rect displayStableRect = mTmpRect;
+        final Rect contentBounds = mTmpRect2;
+
+        // Calculate the content bounds excluding the area occupied by IME
+        getDisplayContent().getStableRect(displayStableRect);
+        contentBounds.set(displayStableRect);
+        int imeTop = Math.max(imeWin.getFrameLw().top, contentBounds.top);
+
+        imeTop += imeWin.getGivenContentInsetsLw().top;
+        if (contentBounds.bottom > imeTop) {
+            contentBounds.bottom = imeTop;
+        }
+
+        final int yOffset = displayStableRect.bottom - contentBounds.bottom;
+
+        final int dividerWidth =
+                getDisplayContent().mDividerControllerLocked.getContentWidth();
+        final int dividerWidthInactive =
+                getDisplayContent().mDividerControllerLocked.getContentWidthInactive();
+
+        if (dockedSide == DOCKED_TOP) {
+            // If this stack is docked on top, we make it smaller so the bottom stack is not
+            // occluded by IME. We shift its bottom up by the height of the IME, but
+            // leaves at least 30% of the top stack visible.
+            final int minTopStackBottom =
+                    getMinTopStackBottom(displayStableRect, getRawBounds().bottom);
+            final int bottom = Math.max(
+                    getRawBounds().bottom - yOffset + dividerWidth - dividerWidthInactive,
+                    minTopStackBottom);
+            mTmpAdjustedBounds.set(getRawBounds());
+            mTmpAdjustedBounds.bottom = (int) (mAdjustImeAmount * bottom + (1 - mAdjustImeAmount)
+                    * getRawBounds().bottom);
+            mFullyAdjustedImeBounds.set(getRawBounds());
+        } else {
+            // When the stack is on bottom and has no focus, it's only adjusted for divider width.
+            final int dividerWidthDelta = dividerWidthInactive - dividerWidth;
+
+            // When the stack is on bottom and has focus, it needs to be moved up so as to
+            // not occluded by IME, and at the same time adjusted for divider width.
+            // We try to move it up by the height of the IME window, but only to the extent
+            // that leaves at least 30% of the top stack visible.
+            // 'top' is where the top of bottom stack will move to in this case.
+            final int topBeforeImeAdjust =
+                    getRawBounds().top - dividerWidth + dividerWidthInactive;
+            final int minTopStackBottom =
+                    getMinTopStackBottom(displayStableRect,
+                            getRawBounds().top - dividerWidth);
+            final int top = Math.max(
+                    getRawBounds().top - yOffset, minTopStackBottom + dividerWidthInactive);
+
+            mTmpAdjustedBounds.set(getRawBounds());
+            // Account for the adjustment for IME and divider width separately.
+            // (top - topBeforeImeAdjust) is the amount of movement due to IME only,
+            // and dividerWidthDelta is due to divider width change only.
+            mTmpAdjustedBounds.top =
+                    getRawBounds().top + (int) (mAdjustImeAmount * (top - topBeforeImeAdjust)
+                            + mAdjustDividerAmount * dividerWidthDelta);
+            mFullyAdjustedImeBounds.set(getRawBounds());
+            mFullyAdjustedImeBounds.top = top;
+            mFullyAdjustedImeBounds.bottom = top + getRawBounds().height();
+        }
+        return true;
+    }
+
+    private boolean adjustForMinimizedDockedStack(float minimizeAmount) {
+        final int dockSide = getDockSide();
+        if (dockSide == DOCKED_INVALID && !mTmpAdjustedBounds.isEmpty()) {
+            return false;
+        }
+
+        if (dockSide == DOCKED_TOP) {
+            mWmService.getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect);
+            int topInset = mTmpRect.top;
+            mTmpAdjustedBounds.set(getRawBounds());
+            mTmpAdjustedBounds.bottom = (int) (minimizeAmount * topInset + (1 - minimizeAmount)
+                    * getRawBounds().bottom);
+        } else if (dockSide == DOCKED_LEFT) {
+            mTmpAdjustedBounds.set(getRawBounds());
+            final int width = getRawBounds().width();
+            mTmpAdjustedBounds.right =
+                    (int) (minimizeAmount * mDockedStackMinimizeThickness
+                            + (1 - minimizeAmount) * getRawBounds().right);
+            mTmpAdjustedBounds.left = mTmpAdjustedBounds.right - width;
+        } else if (dockSide == DOCKED_RIGHT) {
+            mTmpAdjustedBounds.set(getRawBounds());
+            mTmpAdjustedBounds.left =
+                    (int) (minimizeAmount * (getRawBounds().right - mDockedStackMinimizeThickness)
+                            + (1 - minimizeAmount) * getRawBounds().left);
+        }
+        return true;
+    }
+
+    private boolean isMinimizedDockAndHomeStackResizable() {
+        return mDisplayContent.mDividerControllerLocked.isMinimizedDock()
+                && mDisplayContent.mDividerControllerLocked.isHomeStackResizable();
+    }
+
+    /**
+     * @return the distance in pixels how much the stack gets minimized from it's original size
+     */
+    int getMinimizeDistance() {
+        final int dockSide = getDockSide();
+        if (dockSide == DOCKED_INVALID) {
+            return 0;
+        }
+
+        if (dockSide == DOCKED_TOP) {
+            mWmService.getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect);
+            int topInset = mTmpRect.top;
+            return getRawBounds().bottom - topInset;
+        } else if (dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT) {
+            return getRawBounds().width() - mDockedStackMinimizeThickness;
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * Updates the adjustment depending on it's current state.
+     */
+    private void updateAdjustedBounds() {
+        boolean adjust = false;
+        if (mMinimizeAmount != 0f) {
+            adjust = adjustForMinimizedDockedStack(mMinimizeAmount);
+        } else if (mAdjustedForIme) {
+            adjust = adjustForIME(mImeWin);
+        }
+        if (!adjust) {
+            mTmpAdjustedBounds.setEmpty();
+        }
+        setAdjustedBounds(mTmpAdjustedBounds);
+
+        final boolean isImeTarget = (mWmService.getImeFocusStackLocked() == this);
+        if (mAdjustedForIme && adjust && !isImeTarget) {
+            final float alpha = Math.max(mAdjustImeAmount, mAdjustDividerAmount)
+                    * IME_ADJUST_DIM_AMOUNT;
+            mWmService.setResizeDimLayer(true, getWindowingMode(), alpha);
+        }
+    }
+
+    void applyAdjustForImeIfNeeded(Task task) {
+        if (mMinimizeAmount != 0f || !mAdjustedForIme || mAdjustedBounds.isEmpty()) {
+            return;
+        }
+
+        final Rect insetBounds = mImeGoingAway ? getRawBounds() : mFullyAdjustedImeBounds;
+        task.alignToAdjustedBounds(mAdjustedBounds, insetBounds, getDockSide() == DOCKED_TOP);
+        mDisplayContent.setLayoutNeeded();
+    }
+
+
+    boolean isAdjustedForMinimizedDockedStack() {
+        return mMinimizeAmount != 0f;
+    }
+
+    /**
+     * @return {@code true} if we have a {@link Task} that is animating (currently only used for the
+     *         recents animation); {@code false} otherwise.
+     */
+    boolean isTaskAnimating() {
+        for (int j = mChildren.size() - 1; j >= 0; j--) {
+            final Task task = mChildren.get(j);
+            if (task.isTaskAnimating()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    void dump(PrintWriter pw, String prefix, boolean dumpAll) {
+        pw.println(prefix + "mStackId=" + mStackId);
+        pw.println(prefix + "mDeferRemoval=" + mDeferRemoval);
+        pw.println(prefix + "mBounds=" + getRawBounds().toShortString());
+        if (mMinimizeAmount != 0f) {
+            pw.println(prefix + "mMinimizeAmount=" + mMinimizeAmount);
+        }
+        if (mAdjustedForIme) {
+            pw.println(prefix + "mAdjustedForIme=true");
+            pw.println(prefix + "mAdjustImeAmount=" + mAdjustImeAmount);
+            pw.println(prefix + "mAdjustDividerAmount=" + mAdjustDividerAmount);
+        }
+        if (!mAdjustedBounds.isEmpty()) {
+            pw.println(prefix + "mAdjustedBounds=" + mAdjustedBounds.toShortString());
+        }
+        for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; taskNdx--) {
+            mChildren.get(taskNdx).dump(pw, prefix + "  ", dumpAll);
+        }
+        if (!mExitingActivities.isEmpty()) {
+            pw.println();
+            pw.println("  Exiting application tokens:");
+            for (int i = mExitingActivities.size() - 1; i >= 0; i--) {
+                WindowToken token = mExitingActivities.get(i);
+                pw.print("  Exiting App #"); pw.print(i);
+                pw.print(' '); pw.print(token);
+                pw.println(':');
+                token.dump(pw, "    ", dumpAll);
+            }
+        }
+        mAnimatingActivityRegistry.dump(pw, "AnimatingApps:", prefix);
+    }
+
+    @Override
+    boolean fillsParent() {
+        return matchParentBounds();
+    }
+
+    String getName() {
+        return toShortString();
+    }
+
+    public String toShortString() {
+        return "Stack=" + mStackId;
+    }
+
+    /**
+     * For docked workspace (or workspace that's side-by-side to the docked), provides
+     * information which side of the screen was the dock anchored.
+     */
+    int getDockSide() {
+        return getDockSide(mDisplayContent.getConfiguration(), getRawBounds());
+    }
+
+    int getDockSideForDisplay(DisplayContent dc) {
+        return getDockSide(dc, dc.getConfiguration(), getRawBounds());
+    }
+
+    int getDockSide(Configuration parentConfig, Rect bounds) {
+        if (mDisplayContent == null) {
+            return DOCKED_INVALID;
+        }
+        return getDockSide(mDisplayContent, parentConfig, bounds);
+    }
+
+    private int getDockSide(DisplayContent dc, Configuration parentConfig, Rect bounds) {
+        return dc.getDockedDividerController().getDockSide(bounds,
+                parentConfig.windowConfiguration.getBounds(),
+                parentConfig.orientation, parentConfig.windowConfiguration.getRotation());
+    }
+
+    boolean hasTaskForUser(int userId) {
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final Task task = mChildren.get(i);
+            if (task.mUserId == userId) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void findTaskForResizePoint(int x, int y, int delta,
+            DisplayContent.TaskForResizePointSearchResult results) {
+        if (!getWindowConfiguration().canResizeTask()) {
+            results.searchDone = true;
+            return;
+        }
+
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final Task task = mChildren.get(i);
+            if (task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
+                results.searchDone = true;
+                return;
+            }
+
+            // We need to use the task's dim bounds (which is derived from the visible bounds of
+            // its apps windows) for any touch-related tests. Can't use the task's original
+            // bounds because it might be adjusted to fit the content frame. One example is when
+            // the task is put to top-left quadrant, the actual visible area would not start at
+            // (0,0) after it's adjusted for the status bar.
+            task.getDimBounds(mTmpRect);
+            mTmpRect.inset(-delta, -delta);
+            if (mTmpRect.contains(x, y)) {
+                mTmpRect.inset(delta, delta);
+
+                results.searchDone = true;
+
+                if (!mTmpRect.contains(x, y)) {
+                    results.taskForResize = task;
+                    return;
+                }
+                // User touched inside the task. No need to look further,
+                // focus transfer will be handled in ACTION_UP.
+                return;
+            }
+        }
+    }
+
+    void setTouchExcludeRegion(Task focusedTask, int delta, Region touchExcludeRegion,
+            Rect contentRect, Rect postExclude) {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final Task task = mChildren.get(i);
+            ActivityRecord topVisibleActivity = task.getTopVisibleActivity();
+            if (topVisibleActivity == null || !topVisibleActivity.hasContentToDisplay()) {
+                continue;
+            }
+
+            /**
+             * Exclusion region is the region that TapDetector doesn't care about.
+             * Here we want to remove all non-focused tasks from the exclusion region.
+             * We also remove the outside touch area for resizing for all freeform
+             * tasks (including the focused).
+             *
+             * We save the focused task region once we find it, and add it back at the end.
+             *
+             * If the task is home stack and it is resizable in the minimized state, we want to
+             * exclude the docked stack from touch so we need the entire screen area and not just a
+             * small portion which the home stack currently is resized to.
+             */
+
+            if (task.isActivityTypeHome() && isMinimizedDockAndHomeStackResizable()) {
+                mDisplayContent.getBounds(mTmpRect);
+            } else {
+                task.getDimBounds(mTmpRect);
+            }
+
+            if (task == focusedTask) {
+                // Add the focused task rect back into the exclude region once we are done
+                // processing stacks.
+                postExclude.set(mTmpRect);
+            }
+
+            final boolean isFreeformed = task.inFreeformWindowingMode();
+            if (task != focusedTask || isFreeformed) {
+                if (isFreeformed) {
+                    // If the task is freeformed, enlarge the area to account for outside
+                    // touch area for resize.
+                    mTmpRect.inset(-delta, -delta);
+                    // Intersect with display content rect. If we have system decor (status bar/
+                    // navigation bar), we want to exclude that from the tap detection.
+                    // Otherwise, if the app is partially placed under some system button (eg.
+                    // Recents, Home), pressing that button would cause a full series of
+                    // unwanted transfer focus/resume/pause, before we could go home.
+                    mTmpRect.intersect(contentRect);
+                }
+                touchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);
+            }
+        }
+    }
+
+    public boolean setPinnedStackSize(Rect stackBounds, Rect tempTaskBounds) {
+        // Hold the lock since this is called from the BoundsAnimator running on the UiThread
+        synchronized (mWmService.mGlobalLock) {
+            if (mCancelCurrentBoundsAnimation) {
+                return false;
+            }
+        }
+
+        try {
+            mWmService.mActivityTaskManager.resizePinnedStack(stackBounds, tempTaskBounds);
+        } catch (RemoteException e) {
+            // I don't believe you.
+        }
+        return true;
+    }
+
+    void onAllWindowsDrawn() {
+        if (!mBoundsAnimating && !mBoundsAnimatingRequested) {
+            return;
+        }
+
+        getDisplayContent().mBoundsAnimationController.onAllWindowsDrawn();
+    }
+
+    @Override  // AnimatesBounds
+    public boolean onAnimationStart(boolean schedulePipModeChangedCallback, boolean forceUpdate,
+            @BoundsAnimationController.AnimationType int animationType) {
+        // Hold the lock since this is called from the BoundsAnimator running on the UiThread
+        synchronized (mWmService.mGlobalLock) {
+            if (!isAttached()) {
+                // Don't run the animation if the stack is already detached
+                return false;
+            }
+
+            if (animationType == BoundsAnimationController.BOUNDS) {
+                mBoundsAnimatingRequested = false;
+                mBoundsAnimating = true;
+            }
+            mAnimationType = animationType;
+
+            // If we are changing UI mode, as in the PiP to fullscreen
+            // transition, then we need to wait for the window to draw.
+            if (schedulePipModeChangedCallback) {
+                forAllWindows((w) -> {
+                    w.mWinAnimator.resetDrawState();
+                }, false /* traverseTopToBottom */);
+            }
+        }
+
+        if (inPinnedWindowingMode()) {
+            try {
+                mWmService.mActivityTaskManager.notifyPinnedStackAnimationStarted();
+            } catch (RemoteException e) {
+                // I don't believe you...
+            }
+
+            if ((schedulePipModeChangedCallback || animationType == FADE_IN)) {
+                // We need to schedule the PiP mode change before the animation up. It is possible
+                // in this case for the animation down to not have been completed, so always
+                // force-schedule and update to the client to ensure that it is notified that it
+                // is no longer in picture-in-picture mode
+                updatePictureInPictureModeForPinnedStackAnimation(null, forceUpdate);
+            }
+        }
+        return true;
+    }
+
+    @Override  // AnimatesBounds
+    public void onAnimationEnd(boolean schedulePipModeChangedCallback, Rect finalStackSize,
+            boolean moveToFullscreen) {
+        synchronized (mWmService.mGlobalLock) {
+            if (inPinnedWindowingMode()) {
+                // Update to the final bounds if requested. This is done here instead of in the
+                // bounds animator to allow us to coordinate this after we notify the PiP mode
+                // changed
+
+                if (schedulePipModeChangedCallback) {
+                    // We need to schedule the PiP mode change after the animation down, so use the
+                    // final bounds
+                    updatePictureInPictureModeForPinnedStackAnimation(mBoundsAnimationTarget,
+                            false /* forceUpdate */);
+                }
+
+                if (mAnimationType == BoundsAnimationController.FADE_IN) {
+                    setPinnedStackAlpha(1f);
+                    mWmService.mAtmService.notifyPinnedStackAnimationEnded();
+                    return;
+                }
+
+                if (finalStackSize != null && !mCancelCurrentBoundsAnimation) {
+                    setPinnedStackSize(finalStackSize, null);
+                } else {
+                    // We have been canceled, so the final stack size is null, still run the
+                    // animation-end logic
+                    onPipAnimationEndResize();
+                }
+
+                mWmService.mAtmService.notifyPinnedStackAnimationEnded();
+                if (moveToFullscreen) {
+                    ((ActivityStack) this).dismissPip();
+                }
+            } else {
+                // No PiP animation, just run the normal animation-end logic
+                onPipAnimationEndResize();
+            }
+        }
+    }
+
+    /**
+     * Sets the current picture-in-picture aspect ratio.
+     */
+    void setPictureInPictureAspectRatio(float aspectRatio) {
+        if (!mWmService.mAtmService.mSupportsPictureInPicture) {
+            return;
+        }
+
+        final DisplayContent displayContent = getDisplayContent();
+        if (displayContent == null) {
+            return;
+        }
+
+        if (!inPinnedWindowingMode()) {
+            return;
+        }
+
+        final PinnedStackController pinnedStackController =
+                getDisplayContent().getPinnedStackController();
+
+        if (Float.compare(aspectRatio, pinnedStackController.getAspectRatio()) == 0) {
+            return;
+        }
+
+        // Notify the pinned stack controller about aspect ratio change.
+        // This would result a callback delivered from SystemUI to WM to start animation,
+        // if the bounds are ought to be altered due to aspect ratio change.
+        pinnedStackController.setAspectRatio(
+                pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio)
+                        ? aspectRatio : -1f);
+    }
+
+    /**
+     * Sets the current picture-in-picture actions.
+     */
+    void setPictureInPictureActions(List<RemoteAction> actions) {
+        if (!mWmService.mAtmService.mSupportsPictureInPicture) {
+            return;
+        }
+
+        if (!inPinnedWindowingMode()) {
+            return;
+        }
+
+        getDisplayContent().getPinnedStackController().setActions(actions);
+    }
+
+    /** Called immediately prior to resizing the tasks at the end of the pinned stack animation. */
+    void onPipAnimationEndResize() {
+        mBoundsAnimating = false;
+        for (int i = 0; i < mChildren.size(); i++) {
+            final Task t = mChildren.get(i);
+            t.clearPreserveNonFloatingState();
+        }
+        mWmService.requestTraversal();
+    }
+
+    @Override
+    public boolean shouldDeferStartOnMoveToFullscreen() {
+        synchronized (mWmService.mGlobalLock) {
+            if (!isAttached()) {
+                // Unnecessary to pause the animation because the stack is detached.
+                return false;
+            }
+
+            // Workaround for the recents animation -- normally we need to wait for the new activity
+            // to show before starting the PiP animation, but because we start and show the home
+            // activity early for the recents animation prior to the PiP animation starting, there
+            // is no subsequent all-drawn signal. In this case, we can skip the pause when the home
+            // stack is already visible and drawn.
+            final ActivityStack homeStack = mDisplayContent.getHomeStack();
+            if (homeStack == null) {
+                return true;
+            }
+            final Task homeTask = homeStack.getTopChild();
+            if (homeTask == null) {
+                return true;
+            }
+            final ActivityRecord homeApp = homeTask.getTopVisibleActivity();
+            if (!homeTask.isVisible() || homeApp == null) {
+                return true;
+            }
+            return !homeApp.allDrawn;
+        }
+    }
+
+    /**
+     * @return True if we are currently animating the pinned stack from fullscreen to non-fullscreen
+     *         bounds and we have a deferred PiP mode changed callback set with the animation.
+     */
+    public boolean deferScheduleMultiWindowModeChanged() {
+        if (inPinnedWindowingMode()) {
+            // For the pinned stack, the deferring of the multi-window mode changed is tied to the
+            // transition animation into picture-in-picture, and is called once the animation
+            // completes, or is interrupted in a way that would leave the stack in a non-fullscreen
+            // state.
+            // @see BoundsAnimationController
+            // @see BoundsAnimationControllerTests
+            return (mBoundsAnimatingRequested || mBoundsAnimating);
+        }
+        return false;
+    }
+
+    public boolean isForceScaled() {
+        return mBoundsAnimating;
+    }
+
+    public boolean isAnimatingBounds() {
+        return mBoundsAnimating;
+    }
+
+    public boolean lastAnimatingBoundsWasToFullscreen() {
+        return mBoundsAnimatingToFullscreen;
+    }
+
+    public boolean isAnimatingBoundsToFullscreen() {
+        return isAnimatingBounds() && lastAnimatingBoundsWasToFullscreen();
+    }
+
+    public boolean pinnedStackResizeDisallowed() {
+        if (mBoundsAnimating && mCancelCurrentBoundsAnimation) {
+            return true;
+        }
+        return false;
+    }
+
+    /** Returns true if a removal action is still being deferred. */
+    boolean checkCompleteDeferredRemoval() {
+        if (isAnimating(TRANSITION | CHILDREN)) {
+            return true;
+        }
+        if (mDeferRemoval) {
+            removeImmediately();
+        }
+
+        return super.checkCompleteDeferredRemoval();
+    }
+
+    @Override
+    int getOrientation() {
+        return (canSpecifyOrientation()) ? super.getOrientation() : SCREEN_ORIENTATION_UNSET;
+    }
+
+    private boolean canSpecifyOrientation() {
+        final int windowingMode = getWindowingMode();
+        final int activityType = getActivityType();
+        return windowingMode == WINDOWING_MODE_FULLSCREEN
+                || activityType == ACTIVITY_TYPE_HOME
+                || activityType == ACTIVITY_TYPE_RECENTS
+                || activityType == ACTIVITY_TYPE_ASSISTANT;
+    }
+
+    @Override
+    Dimmer getDimmer() {
+        return mDimmer;
+    }
+
+    @Override
+    void prepareSurfaces() {
+        mDimmer.resetDimStates();
+        super.prepareSurfaces();
+        getDimBounds(mTmpDimBoundsRect);
+
+        // Bounds need to be relative, as the dim layer is a child.
+        mTmpDimBoundsRect.offsetTo(0, 0);
+        if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) {
+            scheduleAnimation();
+        }
+    }
+
+    @Override
+    public boolean setPinnedStackAlpha(float alpha) {
+        // Hold the lock since this is called from the BoundsAnimator running on the UiThread
+        synchronized (mWmService.mGlobalLock) {
+            final SurfaceControl sc = getSurfaceControl();
+            if (sc == null || !sc.isValid()) {
+                // If the stack is already removed, don't bother updating any stack animation
+                return false;
+            }
+            getPendingTransaction().setAlpha(sc, mCancelCurrentBoundsAnimation ? 1 : alpha);
+            scheduleAnimation();
+            return !mCancelCurrentBoundsAnimation;
+        }
+    }
+
+    public DisplayInfo getDisplayInfo() {
+        return mDisplayContent.getDisplayInfo();
+    }
+
+    void dim(float alpha) {
+        mDimmer.dimAbove(getPendingTransaction(), alpha);
+        scheduleAnimation();
+    }
+
+    void stopDimming() {
+        mDimmer.stopDim(getPendingTransaction());
+        scheduleAnimation();
+    }
+
+    AnimatingActivityRegistry getAnimatingActivityRegistry() {
+        return mAnimatingActivityRegistry;
+    }
+
+    @Override
+    void getAnimationFrames(Rect outFrame, Rect outInsets, Rect outStableInsets,
+            Rect outSurfaceInsets) {
+        final Task task = getTopChild();
+        if (task != null) {
+            task.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
+        } else {
+            super.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
+        }
+    }
+
+    @Override
+    RemoteAnimationTarget createRemoteAnimationTarget(
+            RemoteAnimationController.RemoteAnimationRecord record) {
+        final Task task = getTopChild();
+        return task != null ? task.createRemoteAnimationTarget(record) : null;
+    }
+
     @Override
     public String toString() {
         return "ActivityStack{" + Integer.toHexString(System.identityHashCode(this))
@@ -4790,10 +6486,10 @@
             @WindowTraceLogLevel int logLevel) {
         final long token = proto.start(fieldId);
         writeToProtoInnerStackOnly(proto, STACK, logLevel);
-        proto.write(ID, mStackId);
+        proto.write(com.android.server.am.ActivityStackProto.ID, mStackId);
         for (int taskNdx = getChildCount() - 1; taskNdx >= 0; --taskNdx) {
             final Task task = getChildAt(taskNdx);
-            task.writeToProto(proto, TASKS, logLevel);
+            task.writeToProto(proto, com.android.server.am.ActivityStackProto.TASKS, logLevel);
         }
         if (mResumedActivity != null) {
             mResumedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
@@ -4801,11 +6497,36 @@
         proto.write(DISPLAY_ID, mDisplayId);
         if (!matchParentBounds()) {
             final Rect bounds = getRequestedOverrideBounds();
-            bounds.writeToProto(proto, BOUNDS);
+            bounds.writeToProto(proto, com.android.server.am.ActivityStackProto.BOUNDS);
         }
 
         // TODO: Remove, no longer needed with windowingMode.
         proto.write(FULLSCREEN, matchParentBounds());
         proto.end(token);
     }
+
+    // TODO(proto-merge): Remove once protos for ActivityStack and TaskStack are merged.
+    void writeToProtoInnerStackOnly(ProtoOutputStream proto, long fieldId,
+            @WindowTraceLogLevel int logLevel) {
+        if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
+            return;
+        }
+
+        final long token = proto.start(fieldId);
+        super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
+        proto.write(StackProto.ID, mStackId);
+        for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; taskNdx--) {
+            mChildren.get(taskNdx).writeToProtoInnerTaskOnly(proto, StackProto.TASKS, logLevel);
+        }
+        proto.write(FILLS_PARENT, matchParentBounds());
+        getRawBounds().writeToProto(proto, StackProto.BOUNDS);
+        proto.write(DEFER_REMOVAL, mDeferRemoval);
+        proto.write(MINIMIZE_AMOUNT, mMinimizeAmount);
+        proto.write(ADJUSTED_FOR_IME, mAdjustedForIme);
+        proto.write(ADJUST_IME_AMOUNT, mAdjustImeAmount);
+        proto.write(ADJUST_DIVIDER_AMOUNT, mAdjustDividerAmount);
+        mAdjustedBounds.writeToProto(proto, ADJUSTED_BOUNDS);
+        proto.write(ANIMATING_BOUNDS, mBoundsAnimating);
+        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 572bf83..530fdcf 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -1428,7 +1428,7 @@
             moveHomeStackToFrontIfNeeded(flags, currentStack.getDisplay(), reason);
         }
 
-        final ActivityRecord r = task.getTopActivity();
+        final ActivityRecord r = task.getTopNonFinishingActivity();
         currentStack.moveTaskToFrontLocked(task, false /* noAnimation */, options,
                 r == null ? null : r.appTimeTracker, reason);
 
@@ -1709,15 +1709,6 @@
             return;
         }
 
-        // It is possible for the bounds animation from the WM to call this but be delayed by
-        // another AM call that is holding the AMS lock. In such a case, the pinnedBounds may be
-        // incorrect if AMS.resizeStackWithBoundsFromWindowManager() is already called while waiting
-        // for the AMS lock to be freed. So check and make sure these bounds are still good.
-        // TODO(stack-merge): Is this still relevant?
-        if (stack.pinnedStackResizeDisallowed()) {
-            return;
-        }
-
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "resizePinnedStack");
         mService.deferWindowLayout();
         try {
@@ -2086,7 +2077,7 @@
 
         // When launching tasks behind, update the last active time of the top task after the new
         // task has been shown briefly
-        final ActivityRecord top = stack.getTopActivity();
+        final ActivityRecord top = stack.getTopNonFinishingActivity();
         if (top != null) {
             top.getTask().touchActiveTime();
         }
@@ -2467,7 +2458,7 @@
 
     /** Notifies that the top activity of the task is forced to be resizeable. */
     private void handleForcedResizableTaskIfNeeded(Task task, int reason) {
-        final ActivityRecord topActivity = task.getTopActivity();
+        final ActivityRecord topActivity = task.getTopNonFinishingActivity();
         if (topActivity == null || topActivity.noDisplay
                 || !topActivity.isNonResizableOrForcedResizable(task.getWindowingMode())) {
             return;
@@ -2759,7 +2750,7 @@
             // Work Challenge is present) let startActivityInPackage handle the intercepting.
             if (!mService.mAmInternal.shouldConfirmCredentials(task.mUserId)
                     && task.getRootActivity() != null) {
-                final ActivityRecord targetActivity = task.getTopActivity();
+                final ActivityRecord targetActivity = task.getTopNonFinishingActivity();
 
                 mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
                         true /* forceSend */, targetActivity);
@@ -2776,7 +2767,7 @@
                 }
 
                 mService.getActivityStartController().postStartActivityProcessingForLastStarter(
-                        task.getTopActivity(), ActivityManager.START_TASK_TO_FRONT,
+                        task.getTopNonFinishingActivity(), ActivityManager.START_TASK_TO_FRONT,
                         task.getStack());
                 return ActivityManager.START_TASK_TO_FRONT;
             }
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 2218c72..be7f887 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1502,7 +1502,8 @@
             return startResult;
         }
 
-        final ActivityRecord targetTaskTop = newTask ? null : targetTask.getTopActivity();
+        final ActivityRecord targetTaskTop = newTask
+                ? null : targetTask.getTopNonFinishingActivity();
         if (targetTaskTop != null) {
             // Recycle the target task for this launch.
             startResult = recycleTask(targetTask, targetTaskTop, reusedTask);
@@ -1559,8 +1560,8 @@
         mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
                 false /* forceSend */, mStartActivity);
 
-        mTargetStack.startActivityLocked(mStartActivity, topStack.getTopActivity(), newTask,
-                mKeepCurTransition, mOptions);
+        mTargetStack.startActivityLocked(mStartActivity, topStack.getTopNonFinishingActivity(),
+                newTask, mKeepCurTransition, mOptions);
         if (mDoResume) {
             final ActivityRecord topTaskActivity =
                     mStartActivity.getTask().topRunningActivityLocked();
@@ -1612,7 +1613,7 @@
             return mInTask;
         } else {
             final ActivityRecord top = computeStackFocus(mStartActivity, false /* newTask */,
-                    mLaunchFlags, mOptions).getTopActivity();
+                    mLaunchFlags, mOptions).getTopNonFinishingActivity();
             if (top != null) {
                 return top.getTask();
             }
@@ -1727,7 +1728,8 @@
             return START_RETURN_INTENT_TO_CALLER;
         }
 
-        complyActivityFlags(targetTask, reusedTask != null ? reusedTask.getTopActivity() : null);
+        complyActivityFlags(targetTask,
+                reusedTask != null ? reusedTask.getTopNonFinishingActivity() : null);
 
         if (clearTaskForReuse) {
             // Clear task for re-use so later code to methods
@@ -1755,7 +1757,7 @@
         // FLAG_ACTIVITY_CLEAR_TOP flag. In that case, return the top running activity in the
         // task instead.
         mLastStartActivityRecord =
-                targetTaskTop.finishing ? targetTask.getTopActivity() : targetTaskTop;
+                targetTaskTop.finishing ? targetTask.getTopNonFinishingActivity() : targetTaskTop;
         return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
     }
 
@@ -1806,7 +1808,7 @@
      * task.
      */
     private void complyActivityFlags(Task targetTask, ActivityRecord reusedActivity) {
-        ActivityRecord targetTaskTop = targetTask.getTopActivity();
+        ActivityRecord targetTaskTop = targetTask.getTopNonFinishingActivity();
         final boolean resetTask =
                 reusedActivity != null && (mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0;
         if (resetTask) {
@@ -2037,7 +2039,8 @@
                 if (!mOptions.canTaskOverlayResume()) {
                     final Task task = mRootActivityContainer.anyTaskForId(
                             mOptions.getLaunchTaskId());
-                    final ActivityRecord top = task != null ? task.getTopActivity() : null;
+                    final ActivityRecord top = task != null
+                            ? task.getTopNonFinishingActivity() : null;
                     if (top != null && !top.isState(RESUMED)) {
 
                         // The caller specifies that we'd like to be avoided to be moved to the
@@ -2295,8 +2298,8 @@
 
         if (differentTopTask && !mAvoidMoveToFront) {
             mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
-            if (mSourceRecord == null || (mSourceStack.getTopActivity() != null &&
-                    mSourceStack.getTopActivity().getTask()
+            if (mSourceRecord == null || (mSourceStack.getTopNonFinishingActivity() != null &&
+                    mSourceStack.getTopNonFinishingActivity().getTask()
                             == mSourceRecord.getTask())) {
                 // We really do want to push this one into the user's face, right now.
                 if (mLaunchTaskBehind && mSourceRecord != null) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 3ef848c..6977a45 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2410,7 +2410,7 @@
             mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
                     false /* forceNonResizable */);
 
-            final ActivityRecord topActivity = task.getTopActivity();
+            final ActivityRecord topActivity = task.getTopNonFinishingActivity();
             if (topActivity != null) {
 
                 // We are reshowing a task, use a starting window to hide the initial draw delay
@@ -2999,7 +2999,7 @@
     public boolean isTopOfTask(IBinder token) {
         synchronized (mGlobalLock) {
             ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            return r != null && r.getTask().getTopActivity() == r;
+            return r != null && r.getTask().getTopNonFinishingActivity() == r;
         }
     }
 
@@ -3243,7 +3243,7 @@
 
     private void sanitizeAndApplyConfigChange(ConfigurationContainer container,
             WindowContainerTransaction.Change change) {
-        if (!(container instanceof Task)) {
+        if (!(container instanceof Task || container instanceof ActivityStack)) {
             throw new RuntimeException("Invalid token in task transaction");
         }
         // The "client"-facing API should prevent bad changes; however, just in case, sanitize
@@ -3589,7 +3589,7 @@
                 "enqueueAssistContext()");
 
         synchronized (mGlobalLock) {
-            ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
+            ActivityRecord activity = getTopDisplayFocusedStack().getTopNonFinishingActivity();
             if (activity == null) {
                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
                 return null;
@@ -3722,7 +3722,7 @@
                 return false;
             }
 
-            final ActivityRecord activity = focusedStack.getTopActivity();
+            final ActivityRecord activity = focusedStack.getTopNonFinishingActivity();
             if (activity == null) {
                 return false;
             }
@@ -3737,7 +3737,7 @@
         try {
             synchronized (mGlobalLock) {
                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
-                ActivityRecord top = getTopDisplayFocusedStack().getTopActivity();
+                ActivityRecord top = getTopDisplayFocusedStack().getTopNonFinishingActivity();
                 if (top != caller) {
                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
                             + " is not current top " + top);
@@ -4355,7 +4355,7 @@
     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
         Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
         synchronized (mGlobalLock) {
-            ActivityRecord activity = getTopDisplayFocusedStack().getTopActivity();
+            ActivityRecord activity = getTopDisplayFocusedStack().getTopNonFinishingActivity();
             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
             }
@@ -6576,7 +6576,7 @@
                             + " Requested task not found");
                     return null;
                 }
-                final ActivityRecord activity = task.getTopActivity();
+                final ActivityRecord activity = task.getTopNonFinishingActivity();
                 if (activity == null) {
                     Slog.w(TAG, "getApplicationThreadForTopActivity failed:"
                             + " Requested activity not found");
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index cb868e1a..b4dd55d 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -556,9 +556,9 @@
     // Last systemUiVisibility we dispatched to windows.
     private int mLastDispatchedSystemUiVisibility = 0;
 
-    private final ArrayList<TaskStack> mTmpAlwaysOnTopStacks = new ArrayList<>();
-    private final ArrayList<TaskStack> mTmpNormalStacks = new ArrayList<>();
-    private final ArrayList<TaskStack> mTmpHomeStacks = new ArrayList<>();
+    private final ArrayList<ActivityStack> mTmpAlwaysOnTopStacks = new ArrayList<>();
+    private final ArrayList<ActivityStack> mTmpNormalStacks = new ArrayList<>();
+    private final ArrayList<ActivityStack> mTmpHomeStacks = new ArrayList<>();
 
     /** Corner radius that windows should have in order to match the display. */
     private final float mWindowCornerRadius;
@@ -1801,15 +1801,15 @@
         return (mDisplay.getFlags() & FLAG_PRIVATE) != 0;
     }
 
-    TaskStack getHomeStack() {
+    ActivityStack getHomeStack() {
         return mTaskStackContainers.getHomeStack();
     }
 
     /**
      * @return The primary split-screen stack, but only if it is visible, and {@code null} otherwise.
      */
-    TaskStack getSplitScreenPrimaryStack() {
-        TaskStack stack = mTaskStackContainers.getSplitScreenPrimaryStack();
+    ActivityStack getSplitScreenPrimaryStack() {
+        ActivityStack stack = mTaskStackContainers.getSplitScreenPrimaryStack();
         return (stack != null && stack.isVisible()) ? stack : null;
     }
 
@@ -1821,11 +1821,11 @@
      * Like {@link #getSplitScreenPrimaryStack}, but also returns the stack if it's currently
      * not visible.
      */
-    TaskStack getSplitScreenPrimaryStackIgnoringVisibility() {
+    ActivityStack getSplitScreenPrimaryStackIgnoringVisibility() {
         return mTaskStackContainers.getSplitScreenPrimaryStack();
     }
 
-    TaskStack getPinnedStack() {
+    ActivityStack getPinnedStack() {
         return mTaskStackContainers.getPinnedStack();
     }
 
@@ -1837,7 +1837,7 @@
      * Returns the topmost stack on the display that is compatible with the input windowing mode.
      * Null is no compatible stack on the display.
      */
-    TaskStack getTopStackInWindowingMode(int windowingMode) {
+    ActivityStack getTopStackInWindowingMode(int windowingMode) {
         return getStack(windowingMode, ACTIVITY_TYPE_UNDEFINED);
     }
 
@@ -1845,17 +1845,17 @@
      * Returns the topmost stack on the display that is compatible with the input windowing mode and
      * activity type. Null is no compatible stack on the display.
      */
-    TaskStack getStack(int windowingMode, int activityType) {
+    ActivityStack getStack(int windowingMode, int activityType) {
         return mTaskStackContainers.getStack(windowingMode, activityType);
     }
 
     @VisibleForTesting
-    WindowList<TaskStack> getStacks() {
+    WindowList<ActivityStack> getStacks() {
         return mTaskStackContainers.mChildren;
     }
 
     @VisibleForTesting
-    TaskStack getTopStack() {
+    ActivityStack getTopStack() {
         return mTaskStackContainers.getTopStack();
     }
 
@@ -1863,7 +1863,7 @@
         return mTaskStackContainers.getVisibleTasks();
     }
 
-    void onStackWindowingModeChanged(TaskStack stack) {
+    void onStackWindowingModeChanged(ActivityStack stack) {
         mTaskStackContainers.onStackWindowingModeChanged(stack);
     }
 
@@ -2207,17 +2207,17 @@
         out.set(mDisplayFrames.mStable);
     }
 
-    void setStackOnDisplay(TaskStack stack, int position) {
+    void setStackOnDisplay(ActivityStack stack, int position) {
         if (DEBUG_STACK) Slog.d(TAG_WM, "Set stack=" + stack + " on displayId=" + mDisplayId);
         mTaskStackContainers.addChild(stack, position);
     }
 
-    void moveStackToDisplay(TaskStack stack, boolean onTop) {
+    void moveStackToDisplay(ActivityStack stack, boolean onTop) {
         stack.reparent(mTaskStackContainers, onTop ? POSITION_TOP: POSITION_BOTTOM);
     }
 
     // TODO(display-unify): No longer needed then.
-    void removeStackFromDisplay(TaskStack stack) {
+    void removeStackFromDisplay(ActivityStack stack) {
         mTaskStackContainers.removeChild(stack);
     }
 
@@ -2250,7 +2250,7 @@
         getParent().positionChildAt(position, this, includingParents);
     }
 
-    void positionStackAt(int position, TaskStack child, boolean includingParents) {
+    void positionStackAt(int position, ActivityStack child, boolean includingParents) {
         mTaskStackContainers.positionChildAt(position, child, includingParents);
         layoutAndAssignWindowLayersIfNeeded();
     }
@@ -2284,7 +2284,7 @@
         final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
         mTmpTaskForResizePointSearchResult.reset();
         for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
-            final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
+            final ActivityStack stack = mTaskStackContainers.getChildAt(stackNdx);
             if (!stack.getWindowConfiguration().canResizeTask()) {
                 return null;
             }
@@ -2307,7 +2307,7 @@
             mTmpRect2.setEmpty();
             for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0;
                     --stackNdx) {
-                final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
+                final ActivityStack stack = mTaskStackContainers.getChildAt(stackNdx);
                 stack.setTouchExcludeRegion(focusedTask, delta, mTouchExcludeRegion,
                         mDisplayFrames.mContent, mTmpRect2);
             }
@@ -2437,7 +2437,7 @@
         boolean updated = false;
 
         for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
-            final TaskStack stack = mTaskStackContainers.getChildAt(i);
+            final ActivityStack stack = mTaskStackContainers.getChildAt(i);
             if (stack == null || !stack.isAdjustedForIme()) {
                 continue;
             }
@@ -2466,7 +2466,7 @@
     boolean clearImeAdjustAnimation() {
         boolean changed = false;
         for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
-            final TaskStack stack = mTaskStackContainers.getChildAt(i);
+            final ActivityStack stack = mTaskStackContainers.getChildAt(i);
             if (stack != null && stack.isAdjustedForIme()) {
                 stack.resetAdjustedForIme(true /* adjustBoundsNow */);
                 changed  = true;
@@ -2477,7 +2477,7 @@
 
     void beginImeAdjustAnimation() {
         for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
-            final TaskStack stack = mTaskStackContainers.getChildAt(i);
+            final ActivityStack stack = mTaskStackContainers.getChildAt(i);
             if (stack.isVisible() && stack.isAdjustedForIme()) {
                 stack.beginImeAdjustAnimation();
             }
@@ -2488,10 +2488,10 @@
         final WindowState imeWin = mInputMethodWindow;
         final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw()
                 && !mDividerControllerLocked.isImeHideRequested();
-        final TaskStack dockedStack = getSplitScreenPrimaryStack();
+        final ActivityStack dockedStack = getSplitScreenPrimaryStack();
         final boolean dockVisible = dockedStack != null;
         final Task topDockedTask = dockVisible ? dockedStack.getTopChild() : null;
-        final TaskStack imeTargetStack = mWmService.getImeFocusStackLocked();
+        final ActivityStack imeTargetStack = mWmService.getImeFocusStackLocked();
         final int imeDockSide = (dockVisible && imeTargetStack != null) ?
                 imeTargetStack.getDockSide() : DOCKED_INVALID;
         final boolean imeOnTop = (imeDockSide == DOCKED_TOP);
@@ -2515,7 +2515,7 @@
 
         if (imeVisible && dockVisible && (imeOnTop || imeOnBottom) && !dockMinimized) {
             for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
-                final TaskStack stack = mTaskStackContainers.getChildAt(i);
+                final ActivityStack stack = mTaskStackContainers.getChildAt(i);
                 final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
                 if (stack.isVisible() && (imeOnBottom || isDockedOnBottom)
                         && stack.inSplitScreenWindowingMode()) {
@@ -2528,7 +2528,7 @@
                     imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin, imeHeight);
         } else {
             for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
-                final TaskStack stack = mTaskStackContainers.getChildAt(i);
+                final ActivityStack stack = mTaskStackContainers.getChildAt(i);
                 stack.resetAdjustedForIme(!dockVisible);
             }
             mDividerControllerLocked.setAdjustedForIme(
@@ -2539,7 +2539,7 @@
 
     void prepareFreezingTaskBounds() {
         for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
-            final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
+            final ActivityStack stack = mTaskStackContainers.getChildAt(stackNdx);
             stack.prepareFreezingTaskBounds();
         }
     }
@@ -2620,7 +2620,7 @@
         super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
         proto.write(ID, mDisplayId);
         for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
-            final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
+            final ActivityStack stack = mTaskStackContainers.getChildAt(stackNdx);
             stack.writeToProtoInnerStackOnly(proto, STACKS, logLevel);
         }
         mDividerControllerLocked.writeToProto(proto, DOCKED_STACK_DIVIDER_CONTROLLER);
@@ -2735,7 +2735,7 @@
         pw.println();
         pw.println(prefix + "Application tokens in top down Z order:");
         for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
-            final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
+            final ActivityStack stack = mTaskStackContainers.getChildAt(stackNdx);
             stack.dump(pw, prefix + "  ", dumpAll);
         }
 
@@ -2765,15 +2765,15 @@
         pw.println();
 
         // Dump stack references
-        final TaskStack homeStack = getHomeStack();
+        final ActivityStack homeStack = getHomeStack();
         if (homeStack != null) {
             pw.println(prefix + "homeStack=" + homeStack.getName());
         }
-        final TaskStack pinnedStack = getPinnedStack();
+        final ActivityStack pinnedStack = getPinnedStack();
         if (pinnedStack != null) {
             pw.println(prefix + "pinnedStack=" + pinnedStack.getName());
         }
-        final TaskStack splitScreenPrimaryStack = getSplitScreenPrimaryStack();
+        final ActivityStack splitScreenPrimaryStack = getSplitScreenPrimaryStack();
         if (splitScreenPrimaryStack != null) {
             pw.println(prefix + "splitScreenPrimaryStack=" + splitScreenPrimaryStack.getName());
         }
@@ -2806,7 +2806,7 @@
 
     /** Returns true if the stack in the windowing mode is visible. */
     boolean isStackVisible(int windowingMode) {
-        final TaskStack stack = getTopStackInWindowingMode(windowingMode);
+        final ActivityStack stack = getTopStackInWindowingMode(windowingMode);
         return stack != null && stack.isVisible();
     }
 
@@ -3911,7 +3911,7 @@
      * Window container class that contains all containers on this display relating to Apps.
      * I.e Activities.
      */
-    private final class TaskStackContainers extends DisplayChildWindowContainer<TaskStack> {
+    private final class TaskStackContainers extends DisplayChildWindowContainer<ActivityStack> {
         /**
          * A control placed at the appropriate level for transitions to occur.
          */
@@ -3936,9 +3936,9 @@
 
         // Cached reference to some special stacks we tend to get a lot so we don't need to loop
         // through the list to find them.
-        private TaskStack mHomeStack = null;
-        private TaskStack mPinnedStack = null;
-        private TaskStack mSplitScreenPrimaryStack = null;
+        private ActivityStack mHomeStack = null;
+        private ActivityStack mPinnedStack = null;
+        private ActivityStack mSplitScreenPrimaryStack = null;
 
         TaskStackContainers(WindowManagerService service) {
             super(service);
@@ -3954,7 +3954,7 @@
          * Returns the topmost stack on the display that is compatible with the input windowing mode
          * and activity type. Null is no compatible stack on the display.
          */
-        TaskStack getStack(int windowingMode, int activityType) {
+        ActivityStack getStack(int windowingMode, int activityType) {
             if (activityType == ACTIVITY_TYPE_HOME) {
                 return mHomeStack;
             }
@@ -3964,7 +3964,7 @@
                 return mSplitScreenPrimaryStack;
             }
             for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
-                final TaskStack stack = mTaskStackContainers.getChildAt(i);
+                final ActivityStack stack = mTaskStackContainers.getChildAt(i);
                 if (activityType == ACTIVITY_TYPE_UNDEFINED
                         && windowingMode == stack.getWindowingMode()) {
                     // Passing in undefined type means we want to match the topmost stack with the
@@ -3979,23 +3979,23 @@
         }
 
         @VisibleForTesting
-        TaskStack getTopStack() {
+        ActivityStack getTopStack() {
             return mTaskStackContainers.getChildCount() > 0
                     ? mTaskStackContainers.getChildAt(mTaskStackContainers.getChildCount() - 1) : null;
         }
 
-        TaskStack getHomeStack() {
+        ActivityStack getHomeStack() {
             if (mHomeStack == null && mDisplayId == DEFAULT_DISPLAY) {
                 Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this);
             }
             return mHomeStack;
         }
 
-        TaskStack getPinnedStack() {
+        ActivityStack getPinnedStack() {
             return mPinnedStack;
         }
 
-        TaskStack getSplitScreenPrimaryStack() {
+        ActivityStack getSplitScreenPrimaryStack() {
             return mSplitScreenPrimaryStack;
         }
 
@@ -4009,7 +4009,7 @@
             return visibleTasks;
         }
 
-        void onStackWindowingModeChanged(TaskStack stack) {
+        void onStackWindowingModeChanged(ActivityStack stack) {
             removeStackReferenceIfNeeded(stack);
             addStackReferenceIfNeeded(stack);
             if (stack == mPinnedStack && getTopStack() != stack) {
@@ -4018,7 +4018,7 @@
             }
         }
 
-        private void addStackReferenceIfNeeded(TaskStack stack) {
+        private void addStackReferenceIfNeeded(ActivityStack stack) {
             if (stack.isActivityTypeHome()) {
                 if (mHomeStack != null) {
                     throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack="
@@ -4046,7 +4046,7 @@
             }
         }
 
-        private void removeStackReferenceIfNeeded(TaskStack stack) {
+        private void removeStackReferenceIfNeeded(ActivityStack stack) {
             if (stack == mHomeStack) {
                 mHomeStack = null;
             } else if (stack == mPinnedStack) {
@@ -4061,14 +4061,13 @@
         }
 
         @Override
-        void addChild(TaskStack stack, int position) {
+        void addChild(ActivityStack stack, int position) {
             addStackReferenceIfNeeded(stack);
             position = findPositionForStack(position, stack, true /* adding */);
 
             super.addChild(stack, position);
             if (mActivityDisplay != null) {
-                // TODO(stack-merge): Remove cast.
-                mActivityDisplay.addChild((ActivityStack) stack, position, true /*fromDc*/);
+                mActivityDisplay.addChild(stack, position, true /*fromDc*/);
             }
 
             // The reparenting case is handled in WindowContainer.
@@ -4079,11 +4078,10 @@
         }
 
         @Override
-        protected void removeChild(TaskStack stack) {
+        protected void removeChild(ActivityStack stack) {
             super.removeChild(stack);
             if (mActivityDisplay != null) {
-                // TODO(stack-merge): Remove cast.
-                mActivityDisplay.onChildRemoved((ActivityStack) stack);
+                mActivityDisplay.onChildRemoved(stack);
             }
             removeStackReferenceIfNeeded(stack);
         }
@@ -4095,7 +4093,7 @@
         }
 
         @Override
-        void positionChildAt(int position, TaskStack child, boolean includingParents) {
+        void positionChildAt(int position, ActivityStack child, boolean includingParents) {
             if (child.getWindowConfiguration().isAlwaysOnTop()
                     && position != POSITION_TOP) {
                 // This stack is always-on-top, override the default behavior.
@@ -4134,7 +4132,8 @@
          * @param adding Flag indicates whether we're adding a new stack or positioning an existing.
          * @return The proper position for the stack.
          */
-        private int findPositionForStack(int requestedPosition, TaskStack stack, boolean adding) {
+        private int findPositionForStack(int requestedPosition, ActivityStack stack,
+                boolean adding) {
             if (stack.inPinnedWindowingMode()) {
                 return POSITION_TOP;
             }
@@ -4316,7 +4315,7 @@
             assignStackOrdering(t);
 
             for (int i = 0; i < mChildren.size(); i++) {
-                final TaskStack s = mChildren.get(i);
+                final ActivityStack s = mChildren.get(i);
                 s.assignChildLayers(t);
             }
         }
@@ -4329,7 +4328,7 @@
             mTmpHomeStacks.clear();
             mTmpNormalStacks.clear();
             for (int i = 0; i < mChildren.size(); ++i) {
-                final TaskStack s = mChildren.get(i);
+                final ActivityStack s = mChildren.get(i);
                 if (s.isAlwaysOnTop()) {
                     mTmpAlwaysOnTopStacks.add(s);
                 } else if (s.isActivityTypeHome()) {
@@ -4349,7 +4348,7 @@
             int layerForSplitScreenDividerAnchor = layer++;
             int layerForAnimationLayer = layer++;
             for (int i = 0; i < mTmpNormalStacks.size(); i++) {
-                final TaskStack s = mTmpNormalStacks.get(i);
+                final ActivityStack s = mTmpNormalStacks.get(i);
                 s.assignLayer(t, layer++);
                 if (s.inSplitScreenWindowingMode()) {
                     // The split screen divider anchor is located above the split screen window.
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 0c68084..c76d03c 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -541,8 +541,8 @@
             }
             mService.mH.removeCallbacks(mDisplayRotationHandlerTimeout);
             mIsWaitingForRemoteRotation = false;
-            mService.mAtmService.applyContainerTransaction(t);
             mDisplayContent.sendNewConfiguration();
+            mService.mAtmService.applyContainerTransaction(t);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index b454922..07d5094 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -140,7 +140,7 @@
     float mLastDividerProgress;
     private final DividerSnapAlgorithm[] mSnapAlgorithmForRotation = new DividerSnapAlgorithm[4];
     private boolean mImeHideRequested;
-    private TaskStack mDimmedStack;
+    private ActivityStack mDimmedStack;
 
     DockedStackDividerController(WindowManagerService service, DisplayContent displayContent) {
         mService = service;
@@ -255,7 +255,7 @@
     }
 
     boolean isHomeStackResizable() {
-        final TaskStack homeStack = mDisplayContent.getHomeStack();
+        final ActivityStack homeStack = mDisplayContent.getHomeStack();
         if (homeStack == null) {
             return false;
         }
@@ -371,7 +371,7 @@
         if (mWindow == null) {
             return;
         }
-        TaskStack stack = mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
+        ActivityStack stack = mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
 
         // If the stack is invisible, we policy force hide it in WindowAnimator.shouldForceHide
         final boolean visible = stack != null;
@@ -415,7 +415,7 @@
     }
 
     void positionDockedStackedDivider(Rect frame) {
-        TaskStack stack = mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
+        ActivityStack stack = mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
         if (stack == null) {
             // Unfortunately we might end up with still having a divider, even though the underlying
             // stack was already removed. This is because we are on AM thread and the removal of the
@@ -523,7 +523,8 @@
 
             // If a primary stack was just created, it will not have access to display content at
             // this point so pass it from here to get a valid dock side.
-            final TaskStack stack = mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
+            final ActivityStack stack =
+                    mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
             mOriginalDockedSide = stack.getDockSideForDisplay(mDisplayContent);
             return;
         }
@@ -558,7 +559,7 @@
             boolean isHomeStackResizable) {
         long animDuration = 0;
         if (animate) {
-            final TaskStack stack =
+            final ActivityStack stack =
                     mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
             final long transitionDuration = isAnimationMaximizing()
                     ? mDisplayContent.mAppTransition.getLastClipRevealTransitionDuration()
@@ -629,10 +630,10 @@
      */
     void setResizeDimLayer(boolean visible, int targetWindowingMode, float alpha) {
         // TODO: Maybe only allow split-screen windowing modes?
-        final TaskStack stack = targetWindowingMode != WINDOWING_MODE_UNDEFINED
+        final ActivityStack stack = targetWindowingMode != WINDOWING_MODE_UNDEFINED
                 ? mDisplayContent.getTopStackInWindowingMode(targetWindowingMode)
                 : null;
-        final TaskStack dockedStack = mDisplayContent.getSplitScreenPrimaryStack();
+        final ActivityStack dockedStack = mDisplayContent.getSplitScreenPrimaryStack();
         boolean visibleAndValid = visible && stack != null && dockedStack != null;
 
         // Ensure an old dim that was shown for the docked stack divider is removed so we don't end
@@ -703,7 +704,7 @@
         if (mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility() == null) {
             return;
         }
-        final TaskStack homeStack = mDisplayContent.getHomeStack();
+        final ActivityStack homeStack = mDisplayContent.getHomeStack();
         if (homeStack == null) {
             return;
         }
@@ -717,7 +718,7 @@
         if (mMinimizedDock && mService.mKeyguardOrAodShowingOnDefaultDisplay) {
             return;
         }
-        final TaskStack topSecondaryStack = mDisplayContent.getTopStackInWindowingMode(
+        final ActivityStack topSecondaryStack = mDisplayContent.getTopStackInWindowingMode(
                 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
         final RecentsAnimationController recentsAnim = mService.getRecentsAnimationController();
         final boolean minimizedForRecentsAnimation = recentsAnim != null &&
@@ -872,7 +873,7 @@
     }
 
     private boolean setMinimizedDockedStack(boolean minimized) {
-        final TaskStack stack = mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
+        final ActivityStack stack = mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
         notifyDockedStackMinimizedChanged(minimized, false /* animate */, isHomeStackResizable());
         return stack != null && stack.setAdjustedForMinimizedDock(minimized ? 1f : 0f);
     }
@@ -922,7 +923,7 @@
     }
 
     private boolean animateForMinimizedDockedStack(long now) {
-        final TaskStack stack = mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
+        final ActivityStack stack = mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
         if (!mAnimationStarted) {
             mAnimationStarted = true;
             mAnimationStartTime = now;
@@ -956,7 +957,7 @@
     /**
      * Gets the amount how much to minimize a stack depending on the interpolated fraction t.
      */
-    private float getMinimizeAmount(TaskStack stack, float t) {
+    private float getMinimizeAmount(ActivityStack stack, float t) {
         final float naturalAmount = getInterpolatedAnimationValue(t);
         if (isAnimationMaximizing()) {
             return adjustMaximizeAmount(stack, t, naturalAmount);
@@ -971,7 +972,7 @@
      * transition so we don't create a visible "hole", but only if both the clip reveal and the
      * docked stack divider start from about the same portion on the screen.
      */
-    private float adjustMaximizeAmount(TaskStack stack, float t, float naturalAmount) {
+    private float adjustMaximizeAmount(ActivityStack stack, float t, float naturalAmount) {
         if (mMaximizeMeetFraction == 1f) {
             return naturalAmount;
         }
@@ -987,7 +988,7 @@
      * Retrieves the animation fraction at which the docked stack has to meet the clip reveal
      * edge. See {@link #adjustMaximizeAmount}.
      */
-    private float getClipRevealMeetFraction(TaskStack stack) {
+    private float getClipRevealMeetFraction(ActivityStack stack) {
         if (!isAnimationMaximizing() || stack == null ||
                 !mDisplayContent.mAppTransition.hadClipRevealAnimation()) {
             return 1f;
diff --git a/services/core/java/com/android/server/wm/DragResizeMode.java b/services/core/java/com/android/server/wm/DragResizeMode.java
index c0bf1e8..71beb50 100644
--- a/services/core/java/com/android/server/wm/DragResizeMode.java
+++ b/services/core/java/com/android/server/wm/DragResizeMode.java
@@ -35,7 +35,7 @@
      */
     static final int DRAG_RESIZE_MODE_DOCKED_DIVIDER = 1;
 
-    static boolean isModeAllowedForStack(TaskStack stack, int mode) {
+    static boolean isModeAllowedForStack(ActivityStack stack, int mode) {
         switch (mode) {
             case DRAG_RESIZE_MODE_FREEFORM:
                 return stack.getWindowingMode() == WINDOWING_MODE_FREEFORM;
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index 6810f8c..2ece6e2 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -239,7 +239,7 @@
     boolean activityBlockedFromFinish(ActivityRecord activity) {
         final Task task = activity.getTask();
         if (activity == task.getRootActivity()
-                && activity == task.getTopActivity()
+                && activity == task.getTopNonFinishingActivity()
                 && task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV
                 && isRootTask(task)) {
             Slog.i(TAG, "Not finishing task in lock task mode");
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 6cb1e76..a5b1fda 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -140,7 +140,7 @@
         public void startAnimation(Rect destinationBounds, Rect sourceRectHint,
                 int animationDuration) {
             synchronized (mService.mGlobalLock) {
-                final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
+                final ActivityStack pinnedStack = mDisplayContent.getPinnedStack();
                 pinnedStack.animateResizePinnedStack(destinationBounds,
                         sourceRectHint, animationDuration, true /* fromFullscreen */);
             }
@@ -468,7 +468,7 @@
             }
             try {
                 final Rect animatingBounds = new Rect();
-                final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
+                final ActivityStack pinnedStack = mDisplayContent.getPinnedStack();
                 if (pinnedStack != null) {
                     pinnedStack.getAnimationOrCurrentBounds(animatingBounds);
                 }
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 2f46937..f0e441f 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -717,7 +717,7 @@
                 // Only look at tasks for the user ID of interest.
                 continue;
             }
-            if (task.autoRemoveRecents && task.getTopActivity() == null) {
+            if (task.autoRemoveRecents && task.getTopNonFinishingActivity() == null) {
                 // This situation is broken, and we should just get rid of it now.
                 remove(task);
                 Slog.w(TAG, "Removing auto-remove without activity: " + task);
@@ -931,7 +931,7 @@
                 }
             }
 
-            if (task.autoRemoveRecents && task.getTopActivity() == null) {
+            if (task.autoRemoveRecents && task.getTopNonFinishingActivity() == null) {
                 // Don't include auto remove tasks that are finished or finishing.
                 if (DEBUG_RECENTS) {
                     Slog.d(TAG_RECENTS, "Skipping, auto-remove without activity: " + task);
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index caf95de..948ed79 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -429,7 +429,7 @@
         // 1) The next launching task is not being animated by the recents animation
         // 2) The next task is home activity. (i.e. pressing home key to back home in recents).
         if ((!controller.isAnimatingTask(stack.getTopChild())
-                || controller.isTargetApp(stack.getTopActivity()))
+                || controller.isTargetApp(stack.getTopNonFinishingActivity()))
                 && controller.shouldDeferCancelUntilNextTransition()) {
             // Always prepare an app transition since we rely on the transition callbacks to cleanup
             mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
@@ -494,7 +494,7 @@
             final Task task = targetStack.getChildAt(i);
             if (task.mUserId == mUserId
                     && task.getBaseIntent().getComponent().equals(mTargetIntent.getComponent())) {
-                return task.getTopActivity();
+                return task.getTopNonFinishingActivity();
             }
         }
         return null;
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 7a3e43b..282144e 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -366,7 +366,7 @@
         // Make leashes for each of the visible/target tasks and add it to the recents animation to
         // be started
         final ArrayList<Task> visibleTasks = mDisplayContent.getVisibleTasks();
-        final TaskStack targetStack = mDisplayContent.getStack(WINDOWING_MODE_UNDEFINED,
+        final ActivityStack targetStack = mDisplayContent.getStack(WINDOWING_MODE_UNDEFINED,
                 targetActivityType);
         if (targetStack != null) {
             for (int i = targetStack.getChildCount() - 1; i >= 0; i--) {
@@ -410,7 +410,8 @@
         }
 
         // Save the minimized home height
-        final TaskStack dockedStack = mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
+        final ActivityStack dockedStack =
+                mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
         mDisplayContent.getDockedDividerController().getHomeStackBoundsInDockedMode(
                 mDisplayContent.getConfiguration(),
                 dockedStack == null ? DOCKED_INVALID : dockedStack.getDockSide(),
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index 5a21016..0995df8 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -676,7 +676,7 @@
                 final ActivityStack stack = display.getChildAt(j);
                 // Get top activity from a visible stack and add it to the list.
                 if (stack.shouldBeVisible(null /* starting */)) {
-                    final ActivityRecord top = stack.getTopActivity();
+                    final ActivityRecord top = stack.getTopNonFinishingActivity();
                     if (top != null) {
                         if (stack == topFocusedStack) {
                             topActivityTokens.add(0, top.appToken);
@@ -1250,6 +1250,7 @@
         stack.getBounds(info.bounds);
         info.displayId = displayId;
         info.stackId = stack.mStackId;
+        info.stackToken = stack.mRemoteToken;
         info.userId = stack.mCurrentUser;
         info.visible = stack.shouldBeVisible(null);
         // A stack might be not attached to a display.
@@ -1267,8 +1268,8 @@
             taskIds[i] = task.mTaskId;
             taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
                     : task.realActivity != null ? task.realActivity.flattenToString()
-                    : task.getTopActivity() != null ? task.getTopActivity().packageName
-                    : "unknown";
+                    : task.getTopNonFinishingActivity() != null
+                            ? task.getTopNonFinishingActivity().packageName : "unknown";
             taskBounds[i] = mService.getTaskBounds(task.mTaskId);
             taskUserIds[i] = task.mUserId;
         }
@@ -2137,7 +2138,7 @@
      */
     private boolean taskTopActivityIsUser(Task task, @UserIdInt int userId) {
         // To handle the case that work app is in the task but just is not the top one.
-        final ActivityRecord activityRecord = task.getTopActivity();
+        final ActivityRecord activityRecord = task.getTopNonFinishingActivity();
         final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
 
         return (activityRecord != null && activityRecord.mUserId == userId)
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 63b11ff..565f95e 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -412,10 +412,10 @@
         }
     }
 
-    TaskStack getStack(int windowingMode, int activityType) {
+    ActivityStack getStack(int windowingMode, int activityType) {
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final DisplayContent dc = mChildren.get(i);
-            final TaskStack stack = dc.getStack(windowingMode, activityType);
+            final ActivityStack stack = dc.getStack(windowingMode, activityType);
             if (stack != null) {
                 return stack;
             }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index a4c7bcd..96bac88 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -60,9 +60,7 @@
 import static com.android.server.EventLogTags.WM_TASK_REMOVED;
 import static com.android.server.am.TaskRecordProto.ACTIVITIES;
 import static com.android.server.am.TaskRecordProto.ACTIVITY_TYPE;
-import static com.android.server.am.TaskRecordProto.BOUNDS;
 import static com.android.server.am.TaskRecordProto.FULLSCREEN;
-import static com.android.server.am.TaskRecordProto.ID;
 import static com.android.server.am.TaskRecordProto.LAST_NON_FULLSCREEN_BOUNDS;
 import static com.android.server.am.TaskRecordProto.MIN_HEIGHT;
 import static com.android.server.am.TaskRecordProto.MIN_WIDTH;
@@ -89,10 +87,8 @@
 import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
 import static com.android.server.wm.TaskProto.APP_WINDOW_TOKENS;
-import static com.android.server.wm.TaskProto.BOUNDS;
 import static com.android.server.wm.TaskProto.DISPLAYED_BOUNDS;
 import static com.android.server.wm.TaskProto.FILLS_PARENT;
-import static com.android.server.wm.TaskProto.ID;
 import static com.android.server.wm.TaskProto.SURFACE_HEIGHT;
 import static com.android.server.wm.TaskProto.SURFACE_WIDTH;
 import static com.android.server.wm.TaskProto.WINDOW_CONTAINER;
@@ -314,6 +310,7 @@
     private final Rect mTmpNonDecorBounds = new Rect();
     private final Rect mTmpBounds = new Rect();
     private final Rect mTmpInsets = new Rect();
+    private final Rect mTmpFullBounds = new Rect();
 
     // Last non-fullscreen bounds the task was launched in or resized to.
     // The information is persisted and used to determine the appropriate stack to launch the
@@ -658,7 +655,7 @@
         }
 
         final int toStackWindowingMode = toStack.getWindowingMode();
-        final ActivityRecord topActivity = getTopActivity();
+        final ActivityRecord topActivity = getTopNonFinishingActivity();
 
         final boolean mightReplaceWindow = topActivity != null
                 && replaceWindowsOnTaskMove(getWindowingMode(), toStackWindowingMode);
@@ -932,7 +929,6 @@
 
     @Override
     void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
-        // TODO(stack-merge): Remove casts after object merge.
         final ActivityStack oldStack = ((ActivityStack) oldParent);
         final ActivityStack newStack = ((ActivityStack) newParent);
 
@@ -1081,11 +1077,11 @@
         return getChildAt(rootActivityIndex);
     }
 
-    ActivityRecord getTopActivity() {
-        return getTopActivity(true /* includeOverlays */);
+    ActivityRecord getTopNonFinishingActivity() {
+        return getTopNonFinishingActivity(true /* includeOverlays */);
     }
 
-    ActivityRecord getTopActivity(boolean includeOverlays) {
+    ActivityRecord getTopNonFinishingActivity(boolean includeOverlays) {
         for (int i = getChildCount() - 1; i >= 0; --i) {
             final ActivityRecord r = getChildAt(i);
             if (r.finishing || (!includeOverlays && r.mTaskOverlay)) {
@@ -1332,9 +1328,9 @@
      * Completely remove all activities associated with an existing
      * task starting at a specified index.
      */
-    private void performClearTaskAtIndexLocked(int activityNdx, String reason) {
+    private void performClearTaskAtIndexLocked(String reason) {
         int numActivities = getChildCount();
-        for ( ; activityNdx < numActivities; ++activityNdx) {
+        for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
             final ActivityRecord r = getChildAt(activityNdx);
             if (r.finishing) {
                 continue;
@@ -1359,7 +1355,7 @@
      */
     void performClearTaskLocked() {
         mReuseTask = true;
-        performClearTaskAtIndexLocked(0, "clear-task-all");
+        performClearTaskAtIndexLocked("clear-task-all");
         mReuseTask = false;
     }
 
@@ -1429,7 +1425,7 @@
 
     void removeTaskActivitiesLocked(String reason) {
         // Just remove the entire task.
-        performClearTaskAtIndexLocked(0, reason);
+        performClearTaskAtIndexLocked(reason);
     }
 
     String lockTaskAuthToString() {
@@ -1674,7 +1670,9 @@
     }
 
     void adjustForMinimalTaskDimensions(Rect bounds, Rect previousBounds) {
-        if (bounds == null) {
+        final Rect parentBounds = getParent() != null ? getParent().getBounds() : null;
+        if (bounds == null
+                || (bounds.isEmpty() && (parentBounds == null || parentBounds.isEmpty()))) {
             return;
         }
         int minWidth = mMinWidth;
@@ -1698,6 +1696,14 @@
                 minHeight = defaultMinSize;
             }
         }
+        if (bounds.isEmpty()) {
+            // If inheriting parent bounds, check if parent bounds adhere to minimum size. If they
+            // do, we can just skip.
+            if (parentBounds.width() >= minWidth && parentBounds.height() >= minHeight) {
+                return;
+            }
+            bounds.set(parentBounds);
+        }
         final boolean adjustWidth = minWidth > bounds.width();
         final boolean adjustHeight = minHeight > bounds.height();
         if (!(adjustWidth || adjustHeight)) {
@@ -1949,10 +1955,19 @@
         }
         density *= DisplayMetrics.DENSITY_DEFAULT_SCALE;
 
-        final Rect bounds = inOutConfig.windowConfiguration.getBounds();
+        final Rect resolvedBounds = inOutConfig.windowConfiguration.getBounds();
+        if (resolvedBounds == null) {
+            mTmpFullBounds.setEmpty();
+        } else {
+            mTmpFullBounds.set(resolvedBounds);
+        }
+        if (mTmpFullBounds.isEmpty()) {
+            mTmpFullBounds.set(parentConfig.windowConfiguration.getBounds());
+        }
+
         Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
         if (outAppBounds == null || outAppBounds.isEmpty()) {
-            inOutConfig.windowConfiguration.setAppBounds(bounds);
+            inOutConfig.windowConfiguration.setAppBounds(mTmpFullBounds);
             outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
         }
         // Non-null compatibility insets means the activity prefers to keep its original size, so
@@ -1975,7 +1990,7 @@
                 // area, i.e. the screen area without the system bars.
                 // The non decor inset are areas that could never be removed in Honeycomb. See
                 // {@link WindowManagerPolicy#getNonDecorInsetsLw}.
-                calculateInsetFrames(mTmpNonDecorBounds, mTmpStableBounds, bounds, di);
+                calculateInsetFrames(mTmpNonDecorBounds, mTmpStableBounds, mTmpFullBounds, di);
             } else {
                 // Apply the given non-decor and stable insets to calculate the corresponding bounds
                 // for screen size of configuration.
@@ -1984,8 +1999,8 @@
                     rotation = parentConfig.windowConfiguration.getRotation();
                 }
                 if (rotation != ROTATION_UNDEFINED && compatInsets != null) {
-                    mTmpNonDecorBounds.set(bounds);
-                    mTmpStableBounds.set(bounds);
+                    mTmpNonDecorBounds.set(mTmpFullBounds);
+                    mTmpStableBounds.set(mTmpFullBounds);
                     compatInsets.getDisplayBoundsByRotation(mTmpBounds, rotation);
                     intersectWithInsetsIfFits(mTmpNonDecorBounds, mTmpBounds,
                             compatInsets.mNonDecorInsets[rotation]);
@@ -2017,13 +2032,13 @@
                 if (WindowConfiguration.isFloating(windowingMode)) {
                     // For floating tasks, calculate the smallest width from the bounds of the task
                     inOutConfig.smallestScreenWidthDp = (int) (
-                            Math.min(bounds.width(), bounds.height()) / density);
+                            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(bounds);
+                            getSmallestScreenWidthDpForDockedBounds(mTmpFullBounds);
                 }
                 // otherwise, it will just inherit
             }
@@ -2068,11 +2083,6 @@
                     newParentConfig.orientation);
         }
 
-        if (outOverrideBounds.isEmpty()) {
-            // If the task fills the parent, just inherit all the other configs from parent.
-            return;
-        }
-
         adjustForMinimalTaskDimensions(outOverrideBounds, mTmpBounds);
         if (windowingMode == WINDOWING_MODE_FREEFORM) {
             // by policy, make sure the window remains within parent somewhere
@@ -2119,7 +2129,7 @@
             // Use the top activity as the reference of orientation. Don't include overlays because
             // it is usually not the actual content or just temporarily shown.
             // E.g. ForcedResizableInfoActivity.
-            refActivity = getTopActivity(false /* includeOverlays */);
+            refActivity = getTopNonFinishingActivity(false /* includeOverlays */);
         }
 
         // If the task or the reference activity requires a different orientation (either by
@@ -2235,8 +2245,8 @@
         return getTaskStack() != null ? getTaskStack().getDisplayContent() : null;
     }
 
-    TaskStack getTaskStack() {
-        return (TaskStack) getParent();
+    ActivityStack getTaskStack() {
+        return (ActivityStack) getParent();
     }
 
     int getAdjustedAddPosition(ActivityRecord r, int suggestedPosition) {
@@ -2302,13 +2312,12 @@
     }
 
     // TODO: Consolidate this with Task.reparent()
-    void reparent(TaskStack stack, int position, boolean moveParents, String reason) {
+    void reparent(ActivityStack stack, int position, boolean moveParents, String reason) {
         if (DEBUG_STACK) Slog.i(TAG, "reParentTask: removing taskId=" + mTaskId
                 + " from stack=" + getTaskStack());
         EventLog.writeEvent(WM_TASK_REMOVED, mTaskId, "reParentTask");
 
-        // TODO(stack-merge): Remove cast.
-        final ActivityStack prevStack = (ActivityStack) getTaskStack();
+        final ActivityStack prevStack = getTaskStack();
         final boolean wasTopFocusedStack =
                 mAtmService.mRootActivityContainer.isTopDisplayFocusedStack(prevStack);
         final ActivityDisplay prevStackDisplay = prevStack.getDisplay();
@@ -2903,7 +2912,7 @@
         info.stackId = getStackId();
         info.taskId = mTaskId;
         info.displayId = mStack == null ? Display.INVALID_DISPLAY : mStack.mDisplayId;
-        info.isRunning = getTopActivity() != null;
+        info.isRunning = getTopNonFinishingActivity() != null;
         info.baseIntent = new Intent(getBaseIntent());
         info.baseActivity = mReuseActivitiesReport.base != null
                 ? mReuseActivitiesReport.base.intent.getComponent()
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index d7bc072..8ad8972 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -284,7 +284,8 @@
                     && outParams.mBounds.isEmpty()
                     && source.getDisplayId() == display.mDisplayId) {
                 // Set bounds to be not very far from source activity.
-                cascadeBounds(source.getBounds(), display, outParams.mBounds);
+                cascadeBounds(source.getConfiguration().windowConfiguration.getBounds(),
+                        display, outParams.mBounds);
             }
             getTaskBounds(root, display, layout, resolvedMode, hasInitialBounds, outParams.mBounds);
         }
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index f7b802d..a867a5d4 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -133,14 +133,15 @@
 
         @Override
         public void onInputEvent(InputEvent event) {
-            if (!(event instanceof MotionEvent)
-                    || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
-                return;
-            }
-            final MotionEvent motionEvent = (MotionEvent) event;
             boolean handled = false;
-
             try {
+                // All returns need to be in the try block to make sure the finishInputEvent is
+                // called correctly.
+                if (!(event instanceof MotionEvent)
+                        || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
+                    return;
+                }
+                final MotionEvent motionEvent = (MotionEvent) event;
                 if (mDragEnded) {
                     // The drag has ended but the clean-up message has not been processed by
                     // window manager. Drop events that occur after this until window manager
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
deleted file mode 100644
index ec627c8..0000000
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ /dev/null
@@ -1,1816 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT;
-import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.PINNED_WINDOWING_MODE_ELEVATION_IN_DIP;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.WindowManager.DOCKED_BOTTOM;
-import static android.view.WindowManager.DOCKED_INVALID;
-import static android.view.WindowManager.DOCKED_LEFT;
-import static android.view.WindowManager.DOCKED_RIGHT;
-import static android.view.WindowManager.DOCKED_TOP;
-
-import static com.android.server.wm.BoundsAnimationController.FADE_IN;
-import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
-import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
-import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
-import static com.android.server.wm.BoundsAnimationController.SchedulePipModeChangedState;
-import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
-import static com.android.server.wm.StackProto.ADJUSTED_BOUNDS;
-import static com.android.server.wm.StackProto.ADJUSTED_FOR_IME;
-import static com.android.server.wm.StackProto.ADJUST_DIVIDER_AMOUNT;
-import static com.android.server.wm.StackProto.ADJUST_IME_AMOUNT;
-import static com.android.server.wm.StackProto.ANIMATING_BOUNDS;
-import static com.android.server.wm.StackProto.BOUNDS;
-import static com.android.server.wm.StackProto.DEFER_REMOVAL;
-import static com.android.server.wm.StackProto.FILLS_PARENT;
-import static com.android.server.wm.StackProto.ID;
-import static com.android.server.wm.StackProto.MINIMIZE_AMOUNT;
-import static com.android.server.wm.StackProto.TASKS;
-import static com.android.server.wm.StackProto.WINDOW_CONTAINER;
-import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
-import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-
-import android.app.RemoteAction;
-import android.content.res.Configuration;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.os.RemoteException;
-import android.util.DisplayMetrics;
-import android.util.EventLog;
-import android.util.Slog;
-import android.util.proto.ProtoOutputStream;
-import android.view.DisplayCutout;
-import android.view.DisplayInfo;
-import android.view.RemoteAnimationTarget;
-import android.view.SurfaceControl;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.policy.DividerSnapAlgorithm;
-import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
-import com.android.internal.policy.DockedDividerUtils;
-import com.android.server.EventLogTags;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-public class TaskStack extends WindowContainer<Task> implements
-        BoundsAnimationTarget, ConfigurationContainerListener {
-    /** 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;
-
-    /** Dimming amount for non-focused stack when stacks are IME-adjusted. */
-    private static final float IME_ADJUST_DIM_AMOUNT = 0.25f;
-
-    /** Unique identifier */
-    final int mStackId;
-
-    /** For comparison with DisplayContent bounds. */
-    private Rect mTmpRect = new Rect();
-    private Rect mTmpRect2 = new Rect();
-    private Rect mTmpRect3 = new Rect();
-
-    /** For Pinned stack controlling. */
-    private Rect mTmpToBounds = new Rect();
-
-    /** Stack bounds adjusted to screen content area (taking into account IM windows, etc.) */
-    private final Rect mAdjustedBounds = new Rect();
-
-    /**
-     * Fully adjusted IME bounds. These are different from {@link #mAdjustedBounds} because they
-     * represent the state when the animation has ended.
-     */
-    private final Rect mFullyAdjustedImeBounds = new Rect();
-
-    /** ActivityRecords that are exiting, but still on screen for animations. */
-    final ArrayList<ActivityRecord> mExitingActivities = new ArrayList<>();
-
-    /** Detach this stack from its display when animation completes. */
-    // TODO: maybe tie this to WindowContainer#removeChild some how...
-    private boolean mDeferRemoval;
-
-    private final Rect mTmpAdjustedBounds = new Rect();
-    private boolean mAdjustedForIme;
-    private boolean mImeGoingAway;
-    private WindowState mImeWin;
-    private float mMinimizeAmount;
-    private float mAdjustImeAmount;
-    private float mAdjustDividerAmount;
-    private final int mDockedStackMinimizeThickness;
-
-    // If this is true, we are in the bounds animating mode. The task will be down or upscaled to
-    // perfectly fit the region it would have been cropped to. We may also avoid certain logic we
-    // would otherwise apply while resizing, while resizing in the bounds animating mode.
-    private boolean mBoundsAnimating = false;
-    // Set when an animation has been requested but has not yet started from the UI thread. This is
-    // cleared when the animation actually starts.
-    private boolean mBoundsAnimatingRequested = false;
-    private boolean mBoundsAnimatingToFullscreen = false;
-    private boolean mCancelCurrentBoundsAnimation = false;
-    private Rect mBoundsAnimationTarget = new Rect();
-    private Rect mBoundsAnimationSourceHintBounds = new Rect();
-    private @BoundsAnimationController.AnimationType int mAnimationType;
-
-    Rect mPreAnimationBounds = new Rect();
-
-    private Dimmer mDimmer = new Dimmer(this);
-
-    /**
-     * For {@link #prepareSurfaces}.
-     */
-    private final Rect mTmpDimBoundsRect = new Rect();
-    private final Point mLastSurfaceSize = new Point();
-
-    private final AnimatingActivityRegistry mAnimatingActivityRegistry =
-            new AnimatingActivityRegistry();
-
-    TaskStack(WindowManagerService service, int stackId) {
-        super(service);
-        mStackId = stackId;
-        mDockedStackMinimizeThickness = service.mContext.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.docked_stack_minimize_thickness);
-        EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId);
-    }
-
-    Task findHomeTask() {
-        if (!isActivityTypeHome() || mChildren.isEmpty()) {
-            return null;
-        }
-        return mChildren.get(mChildren.size() - 1);
-    }
-
-    void prepareFreezingTaskBounds() {
-        for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
-            final Task task = mChildren.get(taskNdx);
-            task.prepareFreezingBounds();
-        }
-    }
-
-    /**
-     * Overrides the adjusted bounds, i.e. sets temporary layout bounds which are different from
-     * the normal task bounds.
-     *
-     * @param bounds The adjusted bounds.
-     */
-    private void setAdjustedBounds(Rect bounds) {
-        if (mAdjustedBounds.equals(bounds) && !isAnimatingForIme()) {
-            return;
-        }
-
-        mAdjustedBounds.set(bounds);
-        final boolean adjusted = !mAdjustedBounds.isEmpty();
-        Rect insetBounds = null;
-        if (adjusted && isAdjustedForMinimizedDockedStack()) {
-            insetBounds = getRawBounds();
-        } else if (adjusted && mAdjustedForIme) {
-            if (mImeGoingAway) {
-                insetBounds = getRawBounds();
-            } else {
-                insetBounds = mFullyAdjustedImeBounds;
-            }
-        }
-        alignTasksToAdjustedBounds(adjusted ? mAdjustedBounds : getRawBounds(), insetBounds);
-        mDisplayContent.setLayoutNeeded();
-
-        updateSurfaceBounds();
-    }
-
-    private void alignTasksToAdjustedBounds(Rect adjustedBounds, Rect tempInsetBounds) {
-        if (matchParentBounds()) {
-            return;
-        }
-
-        final boolean alignBottom = mAdjustedForIme && getDockSide() == DOCKED_TOP;
-
-        // Update bounds of containing tasks.
-        for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
-            final Task task = mChildren.get(taskNdx);
-            task.alignToAdjustedBounds(adjustedBounds, tempInsetBounds, alignBottom);
-        }
-    }
-
-    @Override
-    public int setBounds(Rect bounds) {
-        return setBounds(getRequestedOverrideBounds(), bounds);
-    }
-
-    private int setBounds(Rect existing, Rect bounds) {
-        if (equivalentBounds(existing, bounds)) {
-            return BOUNDS_CHANGE_NONE;
-        }
-
-        final int result = super.setBounds(!inMultiWindowMode() ? null : bounds);
-
-        updateAdjustedBounds();
-
-        updateSurfaceBounds();
-        return result;
-    }
-
-    /** Bounds of the stack without adjusting for other factors in the system like visibility
-     * of docked stack.
-     * Most callers should be using {@link ConfigurationContainer#getRequestedOverrideBounds} a
-     * it takes into consideration other system factors. */
-    void getRawBounds(Rect out) {
-        out.set(getRawBounds());
-    }
-
-    private Rect getRawBounds() {
-        return super.getBounds();
-    }
-
-    @Override
-    public void getBounds(Rect bounds) {
-        bounds.set(getBounds());
-    }
-
-    @Override
-    public Rect getBounds() {
-        // If we're currently adjusting for IME or minimized docked stack, we use the adjusted
-        // bounds; otherwise, no need to adjust the output bounds if fullscreen or the docked
-        // stack is visible since it is already what we want to represent to the rest of the
-        // system.
-        if (!mAdjustedBounds.isEmpty()) {
-            return mAdjustedBounds;
-        } else {
-            return super.getBounds();
-        }
-    }
-
-    /**
-     * Sets the bounds animation target bounds ahead of an animation.  This can't currently be done
-     * in onAnimationStart() since that is started on the UiThread.
-     */
-    private void setAnimationFinalBounds(Rect sourceHintBounds, Rect destBounds,
-            boolean toFullscreen) {
-        if (mAnimationType == BoundsAnimationController.BOUNDS) {
-            mBoundsAnimatingRequested = true;
-        }
-        mBoundsAnimatingToFullscreen = toFullscreen;
-        if (destBounds != null) {
-            mBoundsAnimationTarget.set(destBounds);
-        } else {
-            mBoundsAnimationTarget.setEmpty();
-        }
-        if (sourceHintBounds != null) {
-            mBoundsAnimationSourceHintBounds.set(sourceHintBounds);
-        } else if (!mBoundsAnimating) {
-            // If the bounds are already animating, we don't want to reset the source hint. This is
-            // because the source hint is sent when starting the animation from the client that
-            // requested to enter pip. Other requests can adjust the pip bounds during an animation,
-            // but could accidentally reset the source hint bounds.
-            mBoundsAnimationSourceHintBounds.setEmpty();
-        }
-
-        mPreAnimationBounds.set(getRawBounds());
-    }
-
-    /**
-     * @return the final bounds for the bounds animation.
-     */
-    void getFinalAnimationBounds(Rect outBounds) {
-        outBounds.set(mBoundsAnimationTarget);
-    }
-
-    /**
-     * @return the final source bounds for the bounds animation.
-     */
-    void getFinalAnimationSourceHintBounds(Rect outBounds) {
-        outBounds.set(mBoundsAnimationSourceHintBounds);
-    }
-
-    /**
-     * @return the final animation bounds if the task stack is currently being animated, or the
-     *         current stack bounds otherwise.
-     */
-    void getAnimationOrCurrentBounds(Rect outBounds) {
-        if ((mBoundsAnimatingRequested || mBoundsAnimating) && !mBoundsAnimationTarget.isEmpty()) {
-            getFinalAnimationBounds(outBounds);
-            return;
-        }
-        getBounds(outBounds);
-    }
-
-    /** Bounds of the stack with other system factors taken into consideration. */
-    void getDimBounds(Rect out) {
-        getBounds(out);
-    }
-
-    /**
-     * Updates the passed-in {@code inOutBounds} based on the current state of the
-     * pinned controller. This gets run *after* the override configuration is updated, so it's
-     * safe to rely on the controller's state in here (though eventually this dependence should
-     * be removed).
-     *
-     * This does NOT modify this TaskStack's configuration. However, it does, for the time-being,
-     * update pinned controller state.
-     *
-     * @param inOutBounds the bounds to update (both input and output).
-     * @return true if bounds were updated to some non-empty value.
-     */
-    boolean calculatePinnedBoundsForConfigChange(Rect inOutBounds) {
-        boolean animating = false;
-        if ((mBoundsAnimatingRequested || mBoundsAnimating) && !mBoundsAnimationTarget.isEmpty()) {
-            animating = true;
-            getFinalAnimationBounds(mTmpRect2);
-        } else {
-            mTmpRect2.set(inOutBounds);
-        }
-        boolean updated = mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(
-                mTmpRect2, mTmpRect3);
-        if (updated) {
-            inOutBounds.set(mTmpRect3);
-
-            // The final boundary is updated while there is an existing boundary animation. Let's
-            // cancel this animation to prevent the obsolete animation overwritten updated bounds.
-            if (animating && !inOutBounds.equals(mBoundsAnimationTarget)) {
-                final DisplayContent displayContent = getDisplayContent();
-                displayContent.mBoundsAnimationController.getHandler().post(() ->
-                        displayContent.mBoundsAnimationController.cancel(this));
-            }
-            // Once we've set the bounds based on the rotation of the old bounds in the new
-            // orientation, clear the animation target bounds since they are obsolete, and
-            // cancel any currently running animations
-            mBoundsAnimationTarget.setEmpty();
-            mBoundsAnimationSourceHintBounds.setEmpty();
-            mCancelCurrentBoundsAnimation = true;
-        }
-        return updated;
-    }
-
-    /**
-     * Updates the passed-in {@code inOutBounds} based on the current state of the
-     * docked controller. This gets run *after* the override configuration is updated, so it's
-     * safe to rely on the controller's state in here (though eventually this dependence should
-     * be removed).
-     *
-     * This does NOT modify this TaskStack's configuration. However, it does, for the time-being,
-     * update docked controller state.
-     *
-     * @param parentConfig the parent configuration for reference.
-     * @param inOutBounds the bounds to update (both input and output).
-     */
-    void calculateDockedBoundsForConfigChange(Configuration parentConfig, Rect inOutBounds) {
-        final boolean primary =
-                getRequestedOverrideWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-        repositionSplitScreenStackAfterRotation(parentConfig, primary, inOutBounds);
-        final DisplayCutout cutout = mDisplayContent.getDisplayInfo().displayCutout;
-        snapDockedStackAfterRotation(parentConfig, cutout, inOutBounds);
-        if (primary) {
-            final int newDockSide = getDockSide(parentConfig, inOutBounds);
-            // Update the dock create mode and clear the dock create bounds, these
-            // might change after a rotation and the original values will be invalid.
-            mWmService.setDockedStackCreateStateLocked(
-                    (newDockSide == DOCKED_LEFT || newDockSide == DOCKED_TOP)
-                            ? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT
-                            : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT,
-                    null);
-            mDisplayContent.getDockedDividerController().notifyDockSideChanged(newDockSide);
-        }
-    }
-
-    /**
-     * Some primary split screen sides are not allowed by the policy. This method queries the policy
-     * and moves the primary stack around if needed.
-     *
-     * @param parentConfig the configuration of the stack's parent.
-     * @param primary true if adjusting the primary docked stack, false for secondary.
-     * @param inOutBounds the bounds of the stack to adjust.
-     */
-    void repositionSplitScreenStackAfterRotation(Configuration parentConfig, boolean primary,
-            Rect inOutBounds) {
-        final int dockSide = getDockSide(mDisplayContent, parentConfig, inOutBounds);
-        final int otherDockSide = DockedDividerUtils.invertDockSide(dockSide);
-        final int primaryDockSide = primary ? dockSide : otherDockSide;
-        if (mDisplayContent.getDockedDividerController()
-                .canPrimaryStackDockTo(primaryDockSide,
-                        parentConfig.windowConfiguration.getBounds(),
-                        parentConfig.windowConfiguration.getRotation())) {
-            return;
-        }
-        final Rect parentBounds = parentConfig.windowConfiguration.getBounds();
-        switch (otherDockSide) {
-            case DOCKED_LEFT:
-                int movement = inOutBounds.left;
-                inOutBounds.left -= movement;
-                inOutBounds.right -= movement;
-                break;
-            case DOCKED_RIGHT:
-                movement = parentBounds.right - inOutBounds.right;
-                inOutBounds.left += movement;
-                inOutBounds.right += movement;
-                break;
-            case DOCKED_TOP:
-                movement = inOutBounds.top;
-                inOutBounds.top -= movement;
-                inOutBounds.bottom -= movement;
-                break;
-            case DOCKED_BOTTOM:
-                movement = parentBounds.bottom - inOutBounds.bottom;
-                inOutBounds.top += movement;
-                inOutBounds.bottom += movement;
-                break;
-        }
-    }
-
-    /**
-     * Snaps the bounds after rotation to the closest snap target for the docked stack.
-     */
-    void snapDockedStackAfterRotation(Configuration parentConfig, DisplayCutout displayCutout,
-            Rect outBounds) {
-
-        // Calculate the current position.
-        final int dividerSize = mDisplayContent.getDockedDividerController().getContentWidth();
-        final int dockSide = getDockSide(parentConfig, outBounds);
-        final int dividerPosition = DockedDividerUtils.calculatePositionForBounds(outBounds,
-                dockSide, dividerSize);
-        final int displayWidth = parentConfig.windowConfiguration.getBounds().width();
-        final int displayHeight = parentConfig.windowConfiguration.getBounds().height();
-
-        // Snap the position to a target.
-        final int rotation = parentConfig.windowConfiguration.getRotation();
-        final int orientation = parentConfig.orientation;
-        mDisplayContent.getDisplayPolicy().getStableInsetsLw(rotation, displayWidth, displayHeight,
-                displayCutout, outBounds);
-        final DividerSnapAlgorithm algorithm = new DividerSnapAlgorithm(
-                mWmService.mContext.getResources(), displayWidth, displayHeight,
-                dividerSize, orientation == Configuration.ORIENTATION_PORTRAIT, outBounds,
-                getDockSide(), isMinimizedDockAndHomeStackResizable());
-        final SnapTarget target = algorithm.calculateNonDismissingSnapTarget(dividerPosition);
-
-        // Recalculate the bounds based on the position of the target.
-        DockedDividerUtils.calculateBoundsForPosition(target.position, dockSide,
-                outBounds, displayWidth, displayHeight,
-                dividerSize);
-    }
-
-    /**
-     * Put a Task in this stack. Used for adding only.
-     * When task is added to top of the stack, the entire branch of the hierarchy (including stack
-     * and display) will be brought to top.
-     * @param task The task to add.
-     * @param position Target position to add the task to.
-     * @param showForAllUsers Whether to show the task regardless of the current user.
-     */
-    void addChild(Task task, int position, boolean showForAllUsers, boolean moveParents) {
-        // Add child task.
-        addChild(task, null);
-
-        // Move child to a proper position, as some restriction for position might apply.
-        position = positionChildAt(
-                position, task, moveParents /* includingParents */, showForAllUsers);
-        // TODO: Feels like this should go in TaskRecord#onParentChanged
-        final boolean toTop = position >= getChildCount();
-        task.updateTaskMovement(toTop);
-    }
-
-    @Override
-    void addChild(Task task, int position) {
-        addChild(task, position, task.showForAllUsers(), false /* includingParents */);
-    }
-
-    void positionChildAt(Task child, int position) {
-        if (DEBUG_STACK) {
-            Slog.i(TAG_WM, "positionChildAt: positioning task=" + child + " at " + position);
-        }
-        if (child == null) {
-            if (DEBUG_STACK) {
-                Slog.i(TAG_WM, "positionChildAt: could not find task=" + this);
-            }
-            return;
-        }
-        positionChildAt(position, child, false /* includingParents */);
-        child.updateTaskMovement(true);
-        getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
-    }
-
-    void positionChildAtTop(Task child, boolean includingParents) {
-        if (child == null) {
-            // TODO: Fix the call-points that cause this to happen.
-            return;
-        }
-
-        positionChildAt(POSITION_TOP, child, includingParents);
-        child.updateTaskMovement(true);
-
-        final DisplayContent displayContent = getDisplayContent();
-        if (displayContent.mAppTransition.isTransitionSet()) {
-            child.setSendingToBottom(false);
-        }
-        displayContent.layoutAndAssignWindowLayersIfNeeded();
-    }
-
-    void positionChildAtBottom(Task child, boolean includingParents) {
-        if (child == null) {
-            // TODO: Fix the call-points that cause this to happen.
-            return;
-        }
-
-        positionChildAt(POSITION_BOTTOM, child, includingParents);
-
-        if (getDisplayContent().mAppTransition.isTransitionSet()) {
-            child.setSendingToBottom(true);
-        }
-        getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
-    }
-
-    @Override
-    void positionChildAt(int position, Task child, boolean includingParents) {
-        positionChildAt(position, child, includingParents, child.showForAllUsers());
-    }
-
-    /**
-     * Overridden version of {@link TaskStack#positionChildAt(int, Task, boolean)}. Used in
-     * {@link TaskStack#addChild(Task, int, boolean showForAllUsers, boolean)}, as it can receive
-     * showForAllUsers param from {@link ActivityRecord} instead of {@link Task#showForAllUsers()}.
-     */
-    private int positionChildAt(int position, Task child, boolean includingParents,
-            boolean showForAllUsers) {
-        final int targetPosition = findPositionForTask(child, position, showForAllUsers);
-        super.positionChildAt(targetPosition, child, includingParents);
-
-        // Log positioning.
-        if (DEBUG_TASK_MOVEMENT)
-            Slog.d(TAG_WM, "positionTask: task=" + this + " position=" + position);
-
-        final int toTop = targetPosition == mChildren.size() - 1 ? 1 : 0;
-        EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, child.mTaskId, toTop, targetPosition);
-
-        return targetPosition;
-    }
-
-    @Override
-    void onChildPositionChanged(WindowContainer child) {
-        if (mChildren.contains(child)) {
-            ((Task) child).updateTaskMovement(getTopChild() == child);
-        }
-    }
-
-    void reparent(DisplayContent newParent, boolean onTop) {
-        // Real parent of stack is within display object, so we have to delegate re-parenting there.
-        newParent.moveStackToDisplay(this, onTop);
-    }
-
-    // TODO: We should really have users as a window container in the hierarchy so that we don't
-    // have to do complicated things like we are doing in this method.
-    int findPositionForTask(Task task, int targetPosition, boolean showForAllUsers) {
-        final boolean canShowTask =
-                showForAllUsers || mWmService.isCurrentProfileLocked(task.mUserId);
-
-        final int stackSize = mChildren.size();
-        int minPosition = 0;
-        int maxPosition = stackSize - 1;
-
-        if (canShowTask) {
-            minPosition = computeMinPosition(minPosition, stackSize);
-        } else {
-            maxPosition = computeMaxPosition(maxPosition);
-        }
-
-        // preserve POSITION_BOTTOM/POSITION_TOP positions if they are still valid.
-        if (targetPosition == POSITION_BOTTOM && minPosition == 0) {
-            return POSITION_BOTTOM;
-        } else if (targetPosition == POSITION_TOP && maxPosition == (stackSize - 1)) {
-            return POSITION_TOP;
-        }
-        // Reset position based on minimum/maximum possible positions.
-        return Math.min(Math.max(targetPosition, minPosition), maxPosition);
-    }
-
-    /** Calculate the minimum possible position for a task that can be shown to the user.
-     *  The minimum position will be above all other tasks that can't be shown.
-     *  @param minPosition The minimum position the caller is suggesting.
-     *                  We will start adjusting up from here.
-     *  @param size The size of the current task list.
-     */
-    private int computeMinPosition(int minPosition, int size) {
-        while (minPosition < size) {
-            final Task tmpTask = mChildren.get(minPosition);
-            final boolean canShowTmpTask =
-                    tmpTask.showForAllUsers()
-                            || mWmService.isCurrentProfileLocked(tmpTask.mUserId);
-            if (canShowTmpTask) {
-                break;
-            }
-            minPosition++;
-        }
-        return minPosition;
-    }
-
-    /** Calculate the maximum possible position for a task that can't be shown to the user.
-     *  The maximum position will be below all other tasks that can be shown.
-     *  @param maxPosition The maximum position the caller is suggesting.
-     *                  We will start adjusting down from here.
-     */
-    private int computeMaxPosition(int maxPosition) {
-        while (maxPosition > 0) {
-            final Task tmpTask = mChildren.get(maxPosition);
-            final boolean canShowTmpTask =
-                    tmpTask.showForAllUsers()
-                            || mWmService.isCurrentProfileLocked(tmpTask.mUserId);
-            if (!canShowTmpTask) {
-                break;
-            }
-            maxPosition--;
-        }
-        return maxPosition;
-    }
-
-    @Override
-    public void onConfigurationChanged(Configuration newParentConfig) {
-        final int prevWindowingMode = getWindowingMode();
-        super.onConfigurationChanged(newParentConfig);
-
-        // Only need to update surface size here since the super method will handle updating
-        // surface position.
-        updateSurfaceSize(getPendingTransaction());
-        final int windowingMode = getWindowingMode();
-
-        if (mDisplayContent == null) {
-            return;
-        }
-
-        if (prevWindowingMode != windowingMode) {
-            mDisplayContent.onStackWindowingModeChanged(this);
-
-            if (inSplitScreenSecondaryWindowingMode()) {
-                // When the stack is resized due to entering split screen secondary, offset the
-                // windows to compensate for the new stack position.
-                forAllWindows(w -> {
-                    w.mWinAnimator.setOffsetPositionForStackResize(true);
-                }, true);
-            }
-        }
-    }
-
-    private void updateSurfaceBounds() {
-        updateSurfaceSize(getPendingTransaction());
-        updateSurfacePosition();
-        scheduleAnimation();
-    }
-
-    /**
-     * Calculate an amount by which to expand the stack bounds in each direction.
-     * Used to make room for shadows in the pinned windowing mode.
-     */
-    int getStackOutset() {
-        DisplayContent displayContent = getDisplayContent();
-        if (inPinnedWindowingMode() && displayContent != null) {
-            final DisplayMetrics displayMetrics = displayContent.getDisplayMetrics();
-
-            // We multiply by two to match the client logic for converting view elevation
-            // to insets, as in {@link WindowManager.LayoutParams#setSurfaceInsets}
-            return (int)Math.ceil(mWmService.dipToPixel(PINNED_WINDOWING_MODE_ELEVATION_IN_DIP,
-                    displayMetrics) * 2);
-        }
-        return 0;
-    }
-
-    @Override
-    void getRelativeDisplayedPosition(Point outPos) {
-        super.getRelativeDisplayedPosition(outPos);
-        final int outset = getStackOutset();
-        outPos.x -= outset;
-        outPos.y -= outset;
-    }
-
-    private void updateSurfaceSize(SurfaceControl.Transaction transaction) {
-        if (mSurfaceControl == null) {
-            return;
-        }
-
-        final Rect stackBounds = getDisplayedBounds();
-        int width = stackBounds.width();
-        int height = stackBounds.height();
-
-        final int outset = getStackOutset();
-        width += 2*outset;
-        height += 2*outset;
-
-        if (width == mLastSurfaceSize.x && height == mLastSurfaceSize.y) {
-            return;
-        }
-        transaction.setWindowCrop(mSurfaceControl, width, height);
-        mLastSurfaceSize.set(width, height);
-    }
-
-    @VisibleForTesting
-    Point getLastSurfaceSize() {
-        return mLastSurfaceSize;
-    }
-
-    @Override
-    void onDisplayChanged(DisplayContent dc) {
-        super.onDisplayChanged(dc);
-        updateSurfaceBounds();
-    }
-
-    /**
-     * Determines the stack and task bounds of the other stack when in docked mode. The current task
-     * bounds is passed in but depending on the stack, the task and stack must match. Only in
-     * minimized mode with resizable launcher, the other stack ignores calculating the stack bounds
-     * and uses the task bounds passed in as the stack and task bounds, otherwise the stack bounds
-     * is calculated and is also used for its task bounds.
-     * If any of the out bounds are empty, it represents default bounds
-     *
-     * @param currentTempTaskBounds the current task bounds of the other stack
-     * @param outStackBounds the calculated stack bounds of the other stack
-     * @param outTempTaskBounds the calculated task bounds of the other stack
-     */
-    void getStackDockedModeBounds(Rect dockedBounds,
-            Rect currentTempTaskBounds, Rect outStackBounds, Rect outTempTaskBounds) {
-        final Configuration parentConfig = getParent().getConfiguration();
-        outTempTaskBounds.setEmpty();
-
-        if (dockedBounds == null || dockedBounds.isEmpty()) {
-            // Calculate the primary docked bounds.
-            final boolean dockedOnTopOrLeft = mWmService.mDockedStackCreateMode
-                    == SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
-            getStackDockedModeBounds(parentConfig,
-                    true /* primary */, outStackBounds, dockedBounds,
-                    mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
-            return;
-        }
-        final int dockedSide = getDockSide(parentConfig, dockedBounds);
-
-        // When the home stack is resizable, should always have the same stack and task bounds
-        if (isActivityTypeHome()) {
-            final Task homeTask = findHomeTask();
-            if (homeTask == null || homeTask.isResizeable()) {
-                // Calculate the home stack bounds when in docked mode and the home stack is
-                // resizeable.
-                getDisplayContent().mDividerControllerLocked
-                        .getHomeStackBoundsInDockedMode(parentConfig,
-                                dockedSide, outStackBounds);
-            } else {
-                // Home stack isn't resizeable, so don't specify stack bounds.
-                outStackBounds.setEmpty();
-            }
-
-            outTempTaskBounds.set(outStackBounds);
-            return;
-        }
-
-        // When minimized state, the stack bounds for all non-home and docked stack bounds should
-        // match the passed task bounds
-        if (isMinimizedDockAndHomeStackResizable() && currentTempTaskBounds != null) {
-            outStackBounds.set(currentTempTaskBounds);
-            return;
-        }
-
-        if (dockedSide == DOCKED_INVALID) {
-            // Not sure how you got here...Only thing we can do is return current bounds.
-            Slog.e(TAG_WM, "Failed to get valid docked side for docked stack");
-            outStackBounds.set(getRawBounds());
-            return;
-        }
-
-        final boolean dockedOnTopOrLeft = dockedSide == DOCKED_TOP || dockedSide == DOCKED_LEFT;
-        getStackDockedModeBounds(parentConfig,
-                false /* primary */, outStackBounds, dockedBounds,
-                mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
-    }
-
-    /**
-     * Outputs the bounds a stack should be given the presence of a docked stack on the display.
-     * @param parentConfig The parent configuration.
-     * @param primary {@code true} if getting the primary stack bounds.
-     * @param outBounds Output bounds that should be used for the stack.
-     * @param dockedBounds Bounds of the docked stack.
-     * @param dockDividerWidth We need to know the width of the divider make to the output bounds
-     *                         close to the side of the dock.
-     * @param dockOnTopOrLeft If the docked stack is on the top or left side of the screen.
-     */
-    private void getStackDockedModeBounds(Configuration parentConfig, boolean primary,
-            Rect outBounds, Rect dockedBounds, int dockDividerWidth,
-            boolean dockOnTopOrLeft) {
-        final Rect displayRect = parentConfig.windowConfiguration.getBounds();
-        final boolean splitHorizontally = displayRect.width() > displayRect.height();
-
-        outBounds.set(displayRect);
-        if (primary) {
-            if (mWmService.mDockedStackCreateBounds != null) {
-                outBounds.set(mWmService.mDockedStackCreateBounds);
-                return;
-            }
-
-            // The initial bounds of the docked stack when it is created about half the screen space
-            // and its bounds can be adjusted after that. The bounds of all other stacks are
-            // adjusted to occupy whatever screen space the docked stack isn't occupying.
-            final DisplayCutout displayCutout = mDisplayContent.getDisplayInfo().displayCutout;
-            mDisplayContent.getDisplayPolicy().getStableInsetsLw(
-                    parentConfig.windowConfiguration.getRotation(),
-                    displayRect.width(), displayRect.height(), displayCutout, mTmpRect2);
-            final int position = new DividerSnapAlgorithm(mWmService.mContext.getResources(),
-                    displayRect.width(),
-                    displayRect.height(),
-                    dockDividerWidth,
-                    parentConfig.orientation == ORIENTATION_PORTRAIT,
-                    mTmpRect2).getMiddleTarget().position;
-
-            if (dockOnTopOrLeft) {
-                if (splitHorizontally) {
-                    outBounds.right = position;
-                } else {
-                    outBounds.bottom = position;
-                }
-            } else {
-                if (splitHorizontally) {
-                    outBounds.left = position + dockDividerWidth;
-                } else {
-                    outBounds.top = position + dockDividerWidth;
-                }
-            }
-            return;
-        }
-
-        // Other stacks occupy whatever space is left by the docked stack.
-        if (!dockOnTopOrLeft) {
-            if (splitHorizontally) {
-                outBounds.right = dockedBounds.left - dockDividerWidth;
-            } else {
-                outBounds.bottom = dockedBounds.top - dockDividerWidth;
-            }
-        } else {
-            if (splitHorizontally) {
-                outBounds.left = dockedBounds.right + dockDividerWidth;
-            } else {
-                outBounds.top = dockedBounds.bottom + dockDividerWidth;
-            }
-        }
-        DockedDividerUtils.sanitizeStackBounds(outBounds, !dockOnTopOrLeft);
-    }
-
-    void resetDockedStackToMiddle() {
-        if (!inSplitScreenPrimaryWindowingMode()) {
-            throw new IllegalStateException("Not a docked stack=" + this);
-        }
-
-        mWmService.mDockedStackCreateBounds = null;
-
-        final Rect bounds = new Rect();
-        final Rect tempBounds = new Rect();
-        getStackDockedModeBounds(null /* dockedBounds */, null /* currentTempTaskBounds */,
-                bounds, tempBounds);
-        // TODO(stack-merge): remove cast.
-        ((ActivityStack) this).mStackSupervisor.resizeDockedStackLocked(bounds,
-                null /* tempTaskBounds */,
-                null /* tempTaskInsetBounds */, null /* tempOtherTaskBounds */,
-                null /* tempOtherTaskInsetBounds */, false /* preserveWindows */,
-                false /* deferResume */);
-    }
-
-    @Override
-    void removeIfPossible() {
-        if (isAnimating(TRANSITION | CHILDREN)) {
-            mDeferRemoval = true;
-            return;
-        }
-        removeImmediately();
-    }
-
-    @Override
-    // TODO(stack-merge): This is mostly taking care of the case where the stask is removing from
-    // the display, so we should probably consolidate it there instead.
-    void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
-        super.onParentChanged(newParent, oldParent);
-
-        if (getParent() != null || mDisplayContent == null) {
-            return;
-        }
-
-        EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
-
-        mDisplayContent = null;
-        mWmService.mWindowPlacerLocked.requestTraversal();
-    }
-
-    /**
-     * Adjusts the stack bounds if the IME is visible.
-     *
-     * @param imeWin The IME window.
-     * @param keepLastAmount Use {@code true} to keep the last adjusted amount from
-     *                       {@link DockedStackDividerController} for adjusting the stack bounds,
-     *                       Use {@code false} to reset adjusted amount as 0.
-     * @see #updateAdjustForIme(float, float, boolean)
-     */
-    void setAdjustedForIme(WindowState imeWin, boolean keepLastAmount) {
-        mImeWin = imeWin;
-        mImeGoingAway = false;
-        if (!mAdjustedForIme || keepLastAmount) {
-            mAdjustedForIme = true;
-            DockedStackDividerController controller = getDisplayContent().mDividerControllerLocked;
-            final float adjustImeAmount = keepLastAmount ? controller.mLastAnimationProgress : 0f;
-            final float adjustDividerAmount = keepLastAmount ? controller.mLastDividerProgress : 0f;
-            updateAdjustForIme(adjustImeAmount, adjustDividerAmount, true /* force */);
-        }
-    }
-
-    boolean isAdjustedForIme() {
-        return mAdjustedForIme;
-    }
-
-    boolean isAnimatingForIme() {
-        return mImeWin != null && mImeWin.isAnimatingLw();
-    }
-
-    /**
-     * Update the stack's bounds (crop or position) according to the IME window's
-     * current position. When IME window is animated, the bottom stack is animated
-     * together to track the IME window's current position, and the top stack is
-     * cropped as necessary.
-     *
-     * @return true if a traversal should be performed after the adjustment.
-     */
-    boolean updateAdjustForIme(float adjustAmount, float adjustDividerAmount, boolean force) {
-        if (adjustAmount != mAdjustImeAmount
-                || adjustDividerAmount != mAdjustDividerAmount || force) {
-            mAdjustImeAmount = adjustAmount;
-            mAdjustDividerAmount = adjustDividerAmount;
-            updateAdjustedBounds();
-            return isVisible();
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Resets the adjustment after it got adjusted for the IME.
-     * @param adjustBoundsNow if true, reset and update the bounds immediately and forget about
-     *                        animations; otherwise, set flag and animates the window away together
-     *                        with IME window.
-     */
-    void resetAdjustedForIme(boolean adjustBoundsNow) {
-        if (adjustBoundsNow) {
-            mImeWin = null;
-            mImeGoingAway = false;
-            mAdjustImeAmount = 0f;
-            mAdjustDividerAmount = 0f;
-            if (!mAdjustedForIme) {
-                return;
-            }
-            mAdjustedForIme = false;
-            updateAdjustedBounds();
-            mWmService.setResizeDimLayer(false, getWindowingMode(), 1.0f);
-        } else {
-            mImeGoingAway |= mAdjustedForIme;
-        }
-    }
-
-    /**
-     * Sets the amount how much we currently minimize our stack.
-     *
-     * @param minimizeAmount The amount, between 0 and 1.
-     * @return Whether the amount has changed and a layout is needed.
-     */
-    boolean setAdjustedForMinimizedDock(float minimizeAmount) {
-        if (minimizeAmount != mMinimizeAmount) {
-            mMinimizeAmount = minimizeAmount;
-            updateAdjustedBounds();
-            return isVisible();
-        } else {
-            return false;
-        }
-    }
-
-    boolean shouldIgnoreInput() {
-        return isAdjustedForMinimizedDockedStack() ||
-                (inSplitScreenPrimaryWindowingMode() && isMinimizedDockAndHomeStackResizable());
-    }
-
-    /**
-     * Puts all visible tasks that are adjusted for IME into resizing mode and adds the windows
-     * to the list of to be drawn windows the service is waiting for.
-     */
-    void beginImeAdjustAnimation() {
-        for (int j = mChildren.size() - 1; j >= 0; j--) {
-            final Task task = mChildren.get(j);
-            if (task.hasContentToDisplay()) {
-                task.setDragResizing(true, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
-                task.setWaitingForDrawnIfResizingChanged();
-            }
-        }
-    }
-
-    /**
-     * Resets the resizing state of all windows.
-     */
-    void endImeAdjustAnimation() {
-        for (int j = mChildren.size() - 1; j >= 0; j--) {
-            mChildren.get(j).setDragResizing(false, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
-        }
-    }
-
-    int getMinTopStackBottom(final Rect displayContentRect, int originalStackBottom) {
-        return displayContentRect.top + (int)
-                ((originalStackBottom - displayContentRect.top) * ADJUSTED_STACK_FRACTION_MIN);
-    }
-
-    private boolean adjustForIME(final WindowState imeWin) {
-        // To prevent task stack resize animation may flicking when playing app transition
-        // animation & IME window enter animation in parallel, we need to make sure app
-        // transition is done and then adjust task size for IME, skip the new adjusted frame when
-        // app transition is still running.
-        if (getDisplayContent().mAppTransition.isRunning()) {
-            return false;
-        }
-
-        final int dockedSide = getDockSide();
-        final boolean dockedTopOrBottom = dockedSide == DOCKED_TOP || dockedSide == DOCKED_BOTTOM;
-        if (imeWin == null || !dockedTopOrBottom) {
-            return false;
-        }
-
-        final Rect displayStableRect = mTmpRect;
-        final Rect contentBounds = mTmpRect2;
-
-        // Calculate the content bounds excluding the area occupied by IME
-        getDisplayContent().getStableRect(displayStableRect);
-        contentBounds.set(displayStableRect);
-        int imeTop = Math.max(imeWin.getFrameLw().top, contentBounds.top);
-
-        imeTop += imeWin.getGivenContentInsetsLw().top;
-        if (contentBounds.bottom > imeTop) {
-            contentBounds.bottom = imeTop;
-        }
-
-        final int yOffset = displayStableRect.bottom - contentBounds.bottom;
-
-        final int dividerWidth =
-                getDisplayContent().mDividerControllerLocked.getContentWidth();
-        final int dividerWidthInactive =
-                getDisplayContent().mDividerControllerLocked.getContentWidthInactive();
-
-        if (dockedSide == DOCKED_TOP) {
-            // If this stack is docked on top, we make it smaller so the bottom stack is not
-            // occluded by IME. We shift its bottom up by the height of the IME, but
-            // leaves at least 30% of the top stack visible.
-            final int minTopStackBottom =
-                    getMinTopStackBottom(displayStableRect, getRawBounds().bottom);
-            final int bottom = Math.max(
-                    getRawBounds().bottom - yOffset + dividerWidth - dividerWidthInactive,
-                    minTopStackBottom);
-            mTmpAdjustedBounds.set(getRawBounds());
-            mTmpAdjustedBounds.bottom = (int) (mAdjustImeAmount * bottom + (1 - mAdjustImeAmount)
-                    * getRawBounds().bottom);
-            mFullyAdjustedImeBounds.set(getRawBounds());
-        } else {
-            // When the stack is on bottom and has no focus, it's only adjusted for divider width.
-            final int dividerWidthDelta = dividerWidthInactive - dividerWidth;
-
-            // When the stack is on bottom and has focus, it needs to be moved up so as to
-            // not occluded by IME, and at the same time adjusted for divider width.
-            // We try to move it up by the height of the IME window, but only to the extent
-            // that leaves at least 30% of the top stack visible.
-            // 'top' is where the top of bottom stack will move to in this case.
-            final int topBeforeImeAdjust =
-                    getRawBounds().top - dividerWidth + dividerWidthInactive;
-            final int minTopStackBottom =
-                    getMinTopStackBottom(displayStableRect,
-                            getRawBounds().top - dividerWidth);
-            final int top = Math.max(
-                    getRawBounds().top - yOffset, minTopStackBottom + dividerWidthInactive);
-
-            mTmpAdjustedBounds.set(getRawBounds());
-            // Account for the adjustment for IME and divider width separately.
-            // (top - topBeforeImeAdjust) is the amount of movement due to IME only,
-            // and dividerWidthDelta is due to divider width change only.
-            mTmpAdjustedBounds.top = getRawBounds().top +
-                    (int) (mAdjustImeAmount * (top - topBeforeImeAdjust) +
-                            mAdjustDividerAmount * dividerWidthDelta);
-            mFullyAdjustedImeBounds.set(getRawBounds());
-            mFullyAdjustedImeBounds.top = top;
-            mFullyAdjustedImeBounds.bottom = top + getRawBounds().height();
-        }
-        return true;
-    }
-
-    private boolean adjustForMinimizedDockedStack(float minimizeAmount) {
-        final int dockSide = getDockSide();
-        if (dockSide == DOCKED_INVALID && !mTmpAdjustedBounds.isEmpty()) {
-            return false;
-        }
-
-        if (dockSide == DOCKED_TOP) {
-            mWmService.getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect);
-            int topInset = mTmpRect.top;
-            mTmpAdjustedBounds.set(getRawBounds());
-            mTmpAdjustedBounds.bottom = (int) (minimizeAmount * topInset + (1 - minimizeAmount)
-                    * getRawBounds().bottom);
-        } else if (dockSide == DOCKED_LEFT) {
-            mTmpAdjustedBounds.set(getRawBounds());
-            final int width = getRawBounds().width();
-            mTmpAdjustedBounds.right =
-                    (int) (minimizeAmount * mDockedStackMinimizeThickness
-                            + (1 - minimizeAmount) * getRawBounds().right);
-            mTmpAdjustedBounds.left = mTmpAdjustedBounds.right - width;
-        } else if (dockSide == DOCKED_RIGHT) {
-            mTmpAdjustedBounds.set(getRawBounds());
-            mTmpAdjustedBounds.left = (int) (minimizeAmount *
-                    (getRawBounds().right - mDockedStackMinimizeThickness)
-                            + (1 - minimizeAmount) * getRawBounds().left);
-        }
-        return true;
-    }
-
-    private boolean isMinimizedDockAndHomeStackResizable() {
-        return mDisplayContent.mDividerControllerLocked.isMinimizedDock()
-                && mDisplayContent.mDividerControllerLocked.isHomeStackResizable();
-    }
-
-    /**
-     * @return the distance in pixels how much the stack gets minimized from it's original size
-     */
-    int getMinimizeDistance() {
-        final int dockSide = getDockSide();
-        if (dockSide == DOCKED_INVALID) {
-            return 0;
-        }
-
-        if (dockSide == DOCKED_TOP) {
-            mWmService.getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect);
-            int topInset = mTmpRect.top;
-            return getRawBounds().bottom - topInset;
-        } else if (dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT) {
-            return getRawBounds().width() - mDockedStackMinimizeThickness;
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * Updates the adjustment depending on it's current state.
-     */
-    private void updateAdjustedBounds() {
-        boolean adjust = false;
-        if (mMinimizeAmount != 0f) {
-            adjust = adjustForMinimizedDockedStack(mMinimizeAmount);
-        } else if (mAdjustedForIme) {
-            adjust = adjustForIME(mImeWin);
-        }
-        if (!adjust) {
-            mTmpAdjustedBounds.setEmpty();
-        }
-        setAdjustedBounds(mTmpAdjustedBounds);
-
-        final boolean isImeTarget = (mWmService.getImeFocusStackLocked() == this);
-        if (mAdjustedForIme && adjust && !isImeTarget) {
-            final float alpha = Math.max(mAdjustImeAmount, mAdjustDividerAmount)
-                    * IME_ADJUST_DIM_AMOUNT;
-            mWmService.setResizeDimLayer(true, getWindowingMode(), alpha);
-        }
-    }
-
-    void applyAdjustForImeIfNeeded(Task task) {
-        if (mMinimizeAmount != 0f || !mAdjustedForIme || mAdjustedBounds.isEmpty()) {
-            return;
-        }
-
-        final Rect insetBounds = mImeGoingAway ? getRawBounds() : mFullyAdjustedImeBounds;
-        task.alignToAdjustedBounds(mAdjustedBounds, insetBounds, getDockSide() == DOCKED_TOP);
-        mDisplayContent.setLayoutNeeded();
-    }
-
-
-    boolean isAdjustedForMinimizedDockedStack() {
-        return mMinimizeAmount != 0f;
-    }
-
-    /**
-     * @return {@code true} if we have a {@link Task} that is animating (currently only used for the
-     *         recents animation); {@code false} otherwise.
-     */
-    boolean isTaskAnimating() {
-        for (int j = mChildren.size() - 1; j >= 0; j--) {
-            final Task task = mChildren.get(j);
-            if (task.isTaskAnimating()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // TODO(proto-merge): Remove once protos for ActivityStack and TaskStack are merged.
-    void writeToProtoInnerStackOnly(ProtoOutputStream proto, long fieldId,
-            @WindowTraceLogLevel int logLevel) {
-        if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
-            return;
-        }
-
-        final long token = proto.start(fieldId);
-        super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
-        proto.write(ID, mStackId);
-        for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; taskNdx--) {
-            mChildren.get(taskNdx).writeToProtoInnerTaskOnly(proto, TASKS, logLevel);
-        }
-        proto.write(FILLS_PARENT, matchParentBounds());
-        getRawBounds().writeToProto(proto, BOUNDS);
-        proto.write(DEFER_REMOVAL, mDeferRemoval);
-        proto.write(MINIMIZE_AMOUNT, mMinimizeAmount);
-        proto.write(ADJUSTED_FOR_IME, mAdjustedForIme);
-        proto.write(ADJUST_IME_AMOUNT, mAdjustImeAmount);
-        proto.write(ADJUST_DIVIDER_AMOUNT, mAdjustDividerAmount);
-        mAdjustedBounds.writeToProto(proto, ADJUSTED_BOUNDS);
-        proto.write(ANIMATING_BOUNDS, mBoundsAnimating);
-        proto.end(token);
-    }
-
-    @Override
-     void dump(PrintWriter pw, String prefix, boolean dumpAll) {
-        pw.println(prefix + "mStackId=" + mStackId);
-        pw.println(prefix + "mDeferRemoval=" + mDeferRemoval);
-        pw.println(prefix + "mBounds=" + getRawBounds().toShortString());
-        if (mMinimizeAmount != 0f) {
-            pw.println(prefix + "mMinimizeAmount=" + mMinimizeAmount);
-        }
-        if (mAdjustedForIme) {
-            pw.println(prefix + "mAdjustedForIme=true");
-            pw.println(prefix + "mAdjustImeAmount=" + mAdjustImeAmount);
-            pw.println(prefix + "mAdjustDividerAmount=" + mAdjustDividerAmount);
-        }
-        if (!mAdjustedBounds.isEmpty()) {
-            pw.println(prefix + "mAdjustedBounds=" + mAdjustedBounds.toShortString());
-        }
-        for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; taskNdx--) {
-            mChildren.get(taskNdx).dump(pw, prefix + "  ", dumpAll);
-        }
-        if (!mExitingActivities.isEmpty()) {
-            pw.println();
-            pw.println("  Exiting application tokens:");
-            for (int i = mExitingActivities.size() - 1; i >= 0; i--) {
-                WindowToken token = mExitingActivities.get(i);
-                pw.print("  Exiting App #"); pw.print(i);
-                pw.print(' '); pw.print(token);
-                pw.println(':');
-                token.dump(pw, "    ", dumpAll);
-            }
-        }
-        mAnimatingActivityRegistry.dump(pw, "AnimatingApps:", prefix);
-    }
-
-    @Override
-    boolean fillsParent() {
-        return matchParentBounds();
-    }
-
-    String getName() {
-        return toShortString();
-    }
-
-    public String toShortString() {
-        return "Stack=" + mStackId;
-    }
-
-    /**
-     * For docked workspace (or workspace that's side-by-side to the docked), provides
-     * information which side of the screen was the dock anchored.
-     */
-    int getDockSide() {
-        return getDockSide(mDisplayContent.getConfiguration(), getRawBounds());
-    }
-
-    int getDockSideForDisplay(DisplayContent dc) {
-        return getDockSide(dc, dc.getConfiguration(), getRawBounds());
-    }
-
-    int getDockSide(Configuration parentConfig, Rect bounds) {
-        if (mDisplayContent == null) {
-            return DOCKED_INVALID;
-        }
-        return getDockSide(mDisplayContent, parentConfig, bounds);
-    }
-
-    private int getDockSide(DisplayContent dc, Configuration parentConfig, Rect bounds) {
-        return dc.getDockedDividerController().getDockSide(bounds,
-                parentConfig.windowConfiguration.getBounds(),
-                parentConfig.orientation, parentConfig.windowConfiguration.getRotation());
-    }
-
-    boolean hasTaskForUser(int userId) {
-        for (int i = mChildren.size() - 1; i >= 0; i--) {
-            final Task task = mChildren.get(i);
-            if (task.mUserId == userId) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    void findTaskForResizePoint(int x, int y, int delta,
-            DisplayContent.TaskForResizePointSearchResult results) {
-        if (!getWindowConfiguration().canResizeTask()) {
-            results.searchDone = true;
-            return;
-        }
-
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final Task task = mChildren.get(i);
-            if (task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
-                results.searchDone = true;
-                return;
-            }
-
-            // We need to use the task's dim bounds (which is derived from the visible bounds of
-            // its apps windows) for any touch-related tests. Can't use the task's original
-            // bounds because it might be adjusted to fit the content frame. One example is when
-            // the task is put to top-left quadrant, the actual visible area would not start at
-            // (0,0) after it's adjusted for the status bar.
-            task.getDimBounds(mTmpRect);
-            mTmpRect.inset(-delta, -delta);
-            if (mTmpRect.contains(x, y)) {
-                mTmpRect.inset(delta, delta);
-
-                results.searchDone = true;
-
-                if (!mTmpRect.contains(x, y)) {
-                    results.taskForResize = task;
-                    return;
-                }
-                // User touched inside the task. No need to look further,
-                // focus transfer will be handled in ACTION_UP.
-                return;
-            }
-        }
-    }
-
-    void setTouchExcludeRegion(Task focusedTask, int delta, Region touchExcludeRegion,
-            Rect contentRect, Rect postExclude) {
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final Task task = mChildren.get(i);
-            ActivityRecord topVisibleActivity = task.getTopVisibleActivity();
-            if (topVisibleActivity == null || !topVisibleActivity.hasContentToDisplay()) {
-                continue;
-            }
-
-            /**
-             * Exclusion region is the region that TapDetector doesn't care about.
-             * Here we want to remove all non-focused tasks from the exclusion region.
-             * We also remove the outside touch area for resizing for all freeform
-             * tasks (including the focused).
-             *
-             * We save the focused task region once we find it, and add it back at the end.
-             *
-             * If the task is home stack and it is resizable in the minimized state, we want to
-             * exclude the docked stack from touch so we need the entire screen area and not just a
-             * small portion which the home stack currently is resized to.
-             */
-
-            if (task.isActivityTypeHome() && isMinimizedDockAndHomeStackResizable()) {
-                mDisplayContent.getBounds(mTmpRect);
-            } else {
-                task.getDimBounds(mTmpRect);
-            }
-
-            if (task == focusedTask) {
-                // Add the focused task rect back into the exclude region once we are done
-                // processing stacks.
-                postExclude.set(mTmpRect);
-            }
-
-            final boolean isFreeformed = task.inFreeformWindowingMode();
-            if (task != focusedTask || isFreeformed) {
-                if (isFreeformed) {
-                    // If the task is freeformed, enlarge the area to account for outside
-                    // touch area for resize.
-                    mTmpRect.inset(-delta, -delta);
-                    // Intersect with display content rect. If we have system decor (status bar/
-                    // navigation bar), we want to exclude that from the tap detection.
-                    // Otherwise, if the app is partially placed under some system button (eg.
-                    // Recents, Home), pressing that button would cause a full series of
-                    // unwanted transfer focus/resume/pause, before we could go home.
-                    mTmpRect.intersect(contentRect);
-                }
-                touchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);
-            }
-        }
-    }
-
-    public boolean setPinnedStackSize(Rect stackBounds, Rect tempTaskBounds) {
-        // Hold the lock since this is called from the BoundsAnimator running on the UiThread
-        synchronized (mWmService.mGlobalLock) {
-            if (mCancelCurrentBoundsAnimation) {
-                return false;
-            }
-        }
-
-        try {
-            mWmService.mActivityTaskManager.resizePinnedStack(stackBounds, tempTaskBounds);
-        } catch (RemoteException e) {
-            // I don't believe you.
-        }
-        return true;
-    }
-
-    void onAllWindowsDrawn() {
-        if (!mBoundsAnimating && !mBoundsAnimatingRequested) {
-            return;
-        }
-
-        getDisplayContent().mBoundsAnimationController.onAllWindowsDrawn();
-    }
-
-    @Override  // AnimatesBounds
-    public boolean onAnimationStart(boolean schedulePipModeChangedCallback, boolean forceUpdate,
-            @BoundsAnimationController.AnimationType int animationType) {
-        // Hold the lock since this is called from the BoundsAnimator running on the UiThread
-        synchronized (mWmService.mGlobalLock) {
-            if (!isAttached()) {
-                // Don't run the animation if the stack is already detached
-                return false;
-            }
-
-            if (animationType == BoundsAnimationController.BOUNDS) {
-                mBoundsAnimatingRequested = false;
-                mBoundsAnimating = true;
-            }
-            mAnimationType = animationType;
-
-            // If we are changing UI mode, as in the PiP to fullscreen
-            // transition, then we need to wait for the window to draw.
-            if (schedulePipModeChangedCallback) {
-                forAllWindows((w) -> { w.mWinAnimator.resetDrawState(); },
-                        false /* traverseTopToBottom */);
-            }
-        }
-
-        if (inPinnedWindowingMode()) {
-            try {
-                mWmService.mActivityTaskManager.notifyPinnedStackAnimationStarted();
-            } catch (RemoteException e) {
-                // I don't believe you...
-            }
-
-            if ((schedulePipModeChangedCallback || animationType == FADE_IN)) {
-                // We need to schedule the PiP mode change before the animation up. It is possible
-                // in this case for the animation down to not have been completed, so always
-                // force-schedule and update to the client to ensure that it is notified that it
-                // is no longer in picture-in-picture mode
-                // TODO(stack-merge): Remove cast.
-                ((ActivityStack) this).updatePictureInPictureModeForPinnedStackAnimation(null,
-                        forceUpdate);
-            }
-        }
-        return true;
-    }
-
-    @Override  // AnimatesBounds
-    public void onAnimationEnd(boolean schedulePipModeChangedCallback, Rect finalStackSize,
-            boolean moveToFullscreen) {
-        synchronized (mWmService.mGlobalLock) {
-            if (inPinnedWindowingMode()) {
-                // Update to the final bounds if requested. This is done here instead of in the
-                // bounds animator to allow us to coordinate this after we notify the PiP mode changed
-
-                if (schedulePipModeChangedCallback) {
-                    // We need to schedule the PiP mode change after the animation down, so use the
-                    // final bounds
-                    // TODO(stack-merge): Remove cast.
-                    ((ActivityStack) this).updatePictureInPictureModeForPinnedStackAnimation(
-                            mBoundsAnimationTarget, false /* forceUpdate */);
-                }
-
-                if (mAnimationType == BoundsAnimationController.FADE_IN) {
-                    setPinnedStackAlpha(1f);
-                    mWmService.mAtmService.notifyPinnedStackAnimationEnded();
-                    return;
-                }
-
-                if (finalStackSize != null && !mCancelCurrentBoundsAnimation) {
-                    setPinnedStackSize(finalStackSize, null);
-                } else {
-                    // We have been canceled, so the final stack size is null, still run the
-                    // animation-end logic
-                    onPipAnimationEndResize();
-                }
-
-                mWmService.mAtmService.notifyPinnedStackAnimationEnded();
-                if (moveToFullscreen) {
-                    ((ActivityStack) this).dismissPip();
-                }
-            } else {
-                // No PiP animation, just run the normal animation-end logic
-                onPipAnimationEndResize();
-            }
-        }
-    }
-
-    /**
-     * Animates the pinned stack.
-     */
-    void animateResizePinnedStack(Rect toBounds, Rect sourceHintBounds,
-            int animationDuration, boolean fromFullscreen) {
-        if (!inPinnedWindowingMode()) {
-            return;
-        }
-        // Get the from-bounds
-        final Rect fromBounds = new Rect();
-        getBounds(fromBounds);
-
-        // Get non-null fullscreen to-bounds for animating if the bounds are null
-        @SchedulePipModeChangedState int schedulePipModeChangedState =
-                NO_PIP_MODE_CHANGED_CALLBACKS;
-        final boolean toFullscreen = toBounds == null;
-        if (toFullscreen) {
-            if (fromFullscreen) {
-                throw new IllegalArgumentException("Should not defer scheduling PiP mode"
-                        + " change on animation to fullscreen.");
-            }
-            schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_START;
-
-            mWmService.getStackBounds(
-                    WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mTmpToBounds);
-            if (!mTmpToBounds.isEmpty()) {
-                // If there is a fullscreen bounds, use that
-                toBounds = new Rect(mTmpToBounds);
-            } else {
-                // Otherwise, use the display bounds
-                toBounds = new Rect();
-                getDisplayContent().getBounds(toBounds);
-            }
-        } else if (fromFullscreen) {
-            schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_END;
-        }
-
-        setAnimationFinalBounds(sourceHintBounds, toBounds, toFullscreen);
-
-        final Rect finalToBounds = toBounds;
-        final @SchedulePipModeChangedState int finalSchedulePipModeChangedState =
-                schedulePipModeChangedState;
-        final DisplayContent displayContent = getDisplayContent();
-        @BoundsAnimationController.AnimationType int intendedAnimationType =
-                displayContent.mBoundsAnimationController.getAnimationType();
-        if (intendedAnimationType == FADE_IN) {
-            if (fromFullscreen) {
-                setPinnedStackAlpha(0f);
-            }
-            if (toBounds.width() == fromBounds.width()
-                    && toBounds.height() == fromBounds.height()) {
-                intendedAnimationType = BoundsAnimationController.BOUNDS;
-            } else if (!fromFullscreen && !toBounds.equals(fromBounds)) {
-                // intendedAnimationType may have been reset at the end of RecentsAnimation,
-                // force it to BOUNDS type if we know for certain we're animating to
-                // a different bounds, especially for expand and collapse of PiP window.
-                intendedAnimationType = BoundsAnimationController.BOUNDS;
-            }
-        }
-
-        final @BoundsAnimationController.AnimationType int animationType = intendedAnimationType;
-        mCancelCurrentBoundsAnimation = false;
-        displayContent.mBoundsAnimationController.getHandler().post(() -> {
-            displayContent.mBoundsAnimationController.animateBounds(this, fromBounds,
-                    finalToBounds, animationDuration, finalSchedulePipModeChangedState,
-                    fromFullscreen, toFullscreen, animationType);
-        });
-    }
-
-    /**
-     * Sets the current picture-in-picture aspect ratio.
-     */
-    void setPictureInPictureAspectRatio(float aspectRatio) {
-        if (!mWmService.mAtmService.mSupportsPictureInPicture) {
-            return;
-        }
-
-        final DisplayContent displayContent = getDisplayContent();
-        if (displayContent == null) {
-            return;
-        }
-
-        if (!inPinnedWindowingMode()) {
-            return;
-        }
-
-        final PinnedStackController pinnedStackController =
-                getDisplayContent().getPinnedStackController();
-
-        if (Float.compare(aspectRatio, pinnedStackController.getAspectRatio()) == 0) {
-            return;
-        }
-
-        // Notify the pinned stack controller about aspect ratio change.
-        // This would result a callback delivered from SystemUI to WM to start animation,
-        // if the bounds are ought to be altered due to aspect ratio change.
-        pinnedStackController.setAspectRatio(
-                pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio)
-                        ? aspectRatio : -1f);
-    }
-
-    /**
-     * Sets the current picture-in-picture actions.
-     */
-    void setPictureInPictureActions(List<RemoteAction> actions) {
-        if (!mWmService.mAtmService.mSupportsPictureInPicture) {
-            return;
-        }
-
-        if (!inPinnedWindowingMode()) {
-            return;
-        }
-
-        getDisplayContent().getPinnedStackController().setActions(actions);
-    }
-
-    /** Called immediately prior to resizing the tasks at the end of the pinned stack animation. */
-    void onPipAnimationEndResize() {
-        mBoundsAnimating = false;
-        for (int i = 0; i < mChildren.size(); i++) {
-            final Task t = mChildren.get(i);
-            t.clearPreserveNonFloatingState();
-        }
-        mWmService.requestTraversal();
-    }
-
-    @Override
-    public boolean shouldDeferStartOnMoveToFullscreen() {
-        synchronized (mWmService.mGlobalLock) {
-            if (!isAttached()) {
-                // Unnecessary to pause the animation because the stack is detached.
-                return false;
-            }
-
-            // Workaround for the recents animation -- normally we need to wait for the new activity
-            // to show before starting the PiP animation, but because we start and show the home
-            // activity early for the recents animation prior to the PiP animation starting, there
-            // is no subsequent all-drawn signal. In this case, we can skip the pause when the home
-            // stack is already visible and drawn.
-            final TaskStack homeStack = mDisplayContent.getHomeStack();
-            if (homeStack == null) {
-                return true;
-            }
-            final Task homeTask = homeStack.getTopChild();
-            if (homeTask == null) {
-                return true;
-            }
-            final ActivityRecord homeApp = homeTask.getTopVisibleActivity();
-            if (!homeTask.isVisible() || homeApp == null) {
-                return true;
-            }
-            return !homeApp.allDrawn;
-        }
-    }
-
-    /**
-     * @return True if we are currently animating the pinned stack from fullscreen to non-fullscreen
-     *         bounds and we have a deferred PiP mode changed callback set with the animation.
-     */
-    public boolean deferScheduleMultiWindowModeChanged() {
-        if (inPinnedWindowingMode()) {
-            // For the pinned stack, the deferring of the multi-window mode changed is tied to the
-            // transition animation into picture-in-picture, and is called once the animation
-            // completes, or is interrupted in a way that would leave the stack in a non-fullscreen
-            // state.
-            // @see BoundsAnimationController
-            // @see BoundsAnimationControllerTests
-            return (mBoundsAnimatingRequested || mBoundsAnimating);
-        }
-        return false;
-    }
-
-    public boolean isForceScaled() {
-        return mBoundsAnimating;
-    }
-
-    public boolean isAnimatingBounds() {
-        return mBoundsAnimating;
-    }
-
-    public boolean lastAnimatingBoundsWasToFullscreen() {
-        return mBoundsAnimatingToFullscreen;
-    }
-
-    public boolean isAnimatingBoundsToFullscreen() {
-        return isAnimatingBounds() && lastAnimatingBoundsWasToFullscreen();
-    }
-
-    public boolean pinnedStackResizeDisallowed() {
-        if (mBoundsAnimating && mCancelCurrentBoundsAnimation) {
-            return true;
-        }
-        return false;
-    }
-
-    /** Returns true if a removal action is still being deferred. */
-    boolean checkCompleteDeferredRemoval() {
-        if (isAnimating(TRANSITION | CHILDREN)) {
-            return true;
-        }
-        if (mDeferRemoval) {
-            removeImmediately();
-        }
-
-        return super.checkCompleteDeferredRemoval();
-    }
-
-    @Override
-    int getOrientation() {
-        return (canSpecifyOrientation()) ? super.getOrientation() : SCREEN_ORIENTATION_UNSET;
-    }
-
-    private boolean canSpecifyOrientation() {
-        final int windowingMode = getWindowingMode();
-        final int activityType = getActivityType();
-        return windowingMode == WINDOWING_MODE_FULLSCREEN
-                || activityType == ACTIVITY_TYPE_HOME
-                || activityType == ACTIVITY_TYPE_RECENTS
-                || activityType == ACTIVITY_TYPE_ASSISTANT;
-    }
-
-    @Override
-    Dimmer getDimmer() {
-        return mDimmer;
-    }
-
-    @Override
-    void prepareSurfaces() {
-        mDimmer.resetDimStates();
-        super.prepareSurfaces();
-        getDimBounds(mTmpDimBoundsRect);
-
-        // Bounds need to be relative, as the dim layer is a child.
-        mTmpDimBoundsRect.offsetTo(0, 0);
-        if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) {
-            scheduleAnimation();
-        }
-    }
-
-    @Override
-    public boolean setPinnedStackAlpha(float alpha) {
-        // Hold the lock since this is called from the BoundsAnimator running on the UiThread
-        synchronized (mWmService.mGlobalLock) {
-            final SurfaceControl sc = getSurfaceControl();
-            if (sc == null || !sc.isValid()) {
-                // If the stack is already removed, don't bother updating any stack animation
-                return false;
-            }
-            getPendingTransaction().setAlpha(sc, mCancelCurrentBoundsAnimation ? 1 : alpha);
-            scheduleAnimation();
-            return !mCancelCurrentBoundsAnimation;
-        }
-    }
-
-    public DisplayInfo getDisplayInfo() {
-        return mDisplayContent.getDisplayInfo();
-    }
-
-    void dim(float alpha) {
-        mDimmer.dimAbove(getPendingTransaction(), alpha);
-        scheduleAnimation();
-    }
-
-    void stopDimming() {
-        mDimmer.stopDim(getPendingTransaction());
-        scheduleAnimation();
-    }
-
-    AnimatingActivityRegistry getAnimatingActivityRegistry() {
-        return mAnimatingActivityRegistry;
-    }
-
-    @Override
-    void getAnimationFrames(Rect outFrame, Rect outInsets, Rect outStableInsets,
-            Rect outSurfaceInsets) {
-        final Task task = getTopChild();
-        if (task != null) {
-            task.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
-        } else {
-            super.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
-        }
-    }
-
-    @Override
-    RemoteAnimationTarget createRemoteAnimationTarget(
-            RemoteAnimationController.RemoteAnimationRecord record) {
-        final Task task = getTopChild();
-        return task != null ? task.createRemoteAnimationTarget(record) : null;
-    }
-}
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 6fed2cb..3e78d5e 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -92,16 +92,16 @@
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowContainer" : TAG_WM;
 
-    /** Animation layer that happens above all animating {@link TaskStack}s. */
+    /** Animation layer that happens above all animating {@link ActivityStack}s. */
     static final int ANIMATION_LAYER_STANDARD = 0;
 
-    /** Animation layer that happens above all {@link TaskStack}s. */
+    /** Animation layer that happens above all {@link ActivityStack}s. */
     static final int ANIMATION_LAYER_BOOSTED = 1;
 
     /**
      * Animation layer that is reserved for {@link WindowConfiguration#ACTIVITY_TYPE_HOME}
      * activities and all activities that are being controlled by the recents animation. This
-     * layer is generally below all {@link TaskStack}s.
+     * layer is generally below all {@link ActivityStack}s.
      */
     static final int ANIMATION_LAYER_HOME = 2;
 
diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java
index 70fc194..bafa38c 100644
--- a/services/core/java/com/android/server/wm/WindowFrames.java
+++ b/services/core/java/com/android/server/wm/WindowFrames.java
@@ -57,7 +57,7 @@
     public final Rect mParentFrame = new Rect();
 
     /**
-     * The entire screen area of the {@link TaskStack} this window is in. Usually equal to the
+     * The entire screen area of the {@link ActivityStack} this window is in. Usually equal to the
      * screen area of the device.
      *
      * TODO(b/111611553): The name is unclear and most likely should be swapped with
@@ -106,6 +106,16 @@
      */
     final Rect mLastFrame = new Rect();
 
+    /**
+     * mFrame but relative to the parent container.
+     */
+    final Rect mRelFrame = new Rect();
+
+    /**
+     * mLastFrame but relative to the parent container
+     */
+    final Rect mLastRelFrame = new Rect();
+
     private boolean mFrameSizeChanged = false;
 
     // Frame that is scaled to the application's coordinate space when in
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 88c0fad..519cc21 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1934,7 +1934,7 @@
                 // re-factor.
                 activity.firstWindowDrawn = false;
                 activity.clearAllDrawn();
-                final TaskStack stack = activity.getStack();
+                final ActivityStack stack = activity.getStack();
                 if (stack != null) {
                     stack.mExitingActivities.remove(activity);
                 }
@@ -2763,7 +2763,7 @@
     @Override
     public void getStackBounds(int windowingMode, int activityType, Rect bounds) {
         synchronized (mGlobalLock) {
-            final TaskStack stack = mRoot.getStack(windowingMode, activityType);
+            final ActivityStack stack = mRoot.getStack(windowingMode, activityType);
             if (stack != null) {
                 stack.getBounds(bounds);
                 return;
@@ -3217,7 +3217,7 @@
 
             // Notify whether the docked stack exists for the current user
             final DisplayContent displayContent = getDefaultDisplayContentLocked();
-            final TaskStack stack =
+            final ActivityStack stack =
                     displayContent.getSplitScreenPrimaryStackIgnoringVisibility();
             displayContent.mDividerControllerLocked.notifyDockedStackExistsChanged(
                     stack != null && stack.hasTaskForUser(newUserId));
@@ -4368,7 +4368,7 @@
         return mRoot.getTopFocusedDisplayContent().mCurrentFocus;
     }
 
-    TaskStack getImeFocusStackLocked() {
+    ActivityStack getImeFocusStackLocked() {
         // Don't use mCurrentFocus.getStack() because it returns home stack for system windows.
         // Also don't use mInputMethodTarget's stack, because some window with FLAG_NOT_FOCUSABLE
         // and FLAG_ALT_FOCUSABLE_IM flags both set might be set to IME target so they're moved
@@ -6388,7 +6388,7 @@
     @Override
     public int getDockedStackSide() {
         synchronized (mGlobalLock) {
-            final TaskStack dockedStack = getDefaultDisplayContentLocked()
+            final ActivityStack dockedStack = getDefaultDisplayContentLocked()
                     .getSplitScreenPrimaryStackIgnoringVisibility();
             return dockedStack == null ? DOCKED_INVALID : dockedStack.getDockSide();
         }
@@ -7642,7 +7642,7 @@
             return;
         }
 
-        final TaskStack stack = task.getTaskStack();
+        final ActivityStack stack = task.getTaskStack();
         // We ignore home stack since we don't want home stack to move to front when touched.
         // Specifically, in freeform we don't want tapping on home to cause the freeform apps to go
         // behind home. See b/117376413
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 8e955cf..2218366 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -20,19 +20,27 @@
 
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ShellCommand;
 import android.os.UserHandle;
 import android.util.DisplayMetrics;
+import android.util.Pair;
 import android.view.Display;
 import android.view.IWindowManager;
 import android.view.Surface;
+import android.view.ViewDebug;
 
+import com.android.internal.os.ByteTransferPipe;
 import com.android.server.protolog.ProtoLogImpl;
 
+import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
 /**
  * ShellCommands for WindowManagerService.
@@ -81,6 +89,8 @@
                     return runSetDisplayUserRotation(pw);
                 case "set-fix-to-user-rotation":
                     return runSetFixToUserRotation(pw);
+                case "dump-visible-window-views":
+                    return runDumpVisibleWindowViews(pw);
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -341,6 +351,50 @@
         return 0;
     }
 
+    private int runDumpVisibleWindowViews(PrintWriter pw) {
+        ParcelFileDescriptor outFile = openFileForSystem(getNextArgRequired(), "w");
+        try (ZipOutputStream out = new ZipOutputStream(
+                new ParcelFileDescriptor.AutoCloseOutputStream(outFile))) {
+            ArrayList<Pair<String, ByteTransferPipe>> requestList = new ArrayList<>();
+            synchronized (mInternal.mGlobalLock) {
+                // Request dump from all windows parallelly before writing to disk.
+                mInternal.mRoot.forAllWindows(w -> {
+                    if (w.isVisible()) {
+                        ByteTransferPipe pipe = null;
+                        try {
+                            pipe = new ByteTransferPipe();
+                            w.mClient.executeCommand(ViewDebug.REMOTE_COMMAND_DUMP_ENCODED, null,
+                                    pipe.getWriteFd());
+                            requestList.add(Pair.create(w.getName(), pipe));
+                        } catch (IOException | RemoteException e) {
+                            // Skip this window
+                            pw.println("Error for window " + w.getName() + " : " + e.getMessage());
+                            if (pipe != null) {
+                                pipe.kill();
+                            }
+                        }
+                    }
+                }, false /* traverseTopToBottom */);
+            }
+            for (Pair<String, ByteTransferPipe> entry : requestList) {
+                byte[] data;
+                try {
+                    data = entry.second.get();
+                } catch (IOException e) {
+                    // Ignore this window
+                    pw.println(
+                            "Error for window " + entry.first + " : " + e.getMessage());
+                    continue;
+                }
+                out.putNextEntry(new ZipEntry(entry.first));
+                out.write(data);
+            }
+        } catch (IOException e) {
+            pw.println("Error fetching dump " + e.getMessage());
+        }
+        return 0;
+    }
+
     @Override
     public void onHelp() {
         PrintWriter pw = getOutPrintWriter();
@@ -360,6 +414,8 @@
         pw.println("    Dismiss the keyguard, prompting user for auth if necessary.");
         pw.println("  set-user-rotation [free|lock] [-d DISPLAY_ID] [rotation]");
         pw.println("    Set user rotation mode and user rotation.");
+        pw.println("  dump-visible-window-views out-file");
+        pw.println("    Dumps the encoded view hierarchies of visible windows");
         pw.println("  set-fix-to-user-rotation [-d DISPLAY_ID] [enabled|disabled]");
         pw.println("    Enable or disable rotating display for app requested orientation.");
         if (!IS_USER) {
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index d63fbc21..41e88c8 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -554,7 +554,7 @@
             if (task == null) {
                 continue;
             }
-            ActivityRecord topActivity = task.getTopActivity();
+            ActivityRecord topActivity = task.getTopNonFinishingActivity();
             if (topActivity != null && topActivity.visible) {
                 return true;
             }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 62a3512..db0f3bc 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -212,7 +212,6 @@
 import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.protolog.common.ProtoLog;
 import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;
-import com.android.server.wm.utils.InsetUtils;
 import com.android.server.wm.utils.WmDisplayCutout;
 
 import java.io.PrintWriter;
@@ -1006,7 +1005,7 @@
                 }
             }
 
-            final TaskStack stack = getStack();
+            final ActivityStack stack = getStack();
             if (inPinnedWindowingMode() && stack != null
                     && stack.lastAnimatingBoundsWasToFullscreen()) {
                 // PIP edge case: When going from pinned to fullscreen, we apply a
@@ -1129,6 +1128,22 @@
             }
         }
 
+        // Calculate relative frame
+        mWindowFrames.mRelFrame.set(mWindowFrames.mFrame);
+        WindowContainer parent = getParent();
+        int parentLeft = 0;
+        int parentTop = 0;
+        if (mIsChildWindow) {
+            parentLeft = ((WindowState) parent).mWindowFrames.mFrame.left;
+            parentTop = ((WindowState) parent).mWindowFrames.mFrame.top;
+        } else if (parent != null) {
+            final Rect parentBounds = parent.getDisplayedBounds();
+            parentLeft = parentBounds.left;
+            parentTop = parentBounds.top;
+        }
+        mWindowFrames.mRelFrame.offsetTo(mWindowFrames.mFrame.left - parentLeft,
+                mWindowFrames.mFrame.top - parentTop);
+
         if (DEBUG_LAYOUT || DEBUG) {
             Slog.v(TAG, "Resolving (mRequestedWidth="
                             + mRequestedWidth + ", mRequestedheight="
@@ -1154,6 +1169,11 @@
         return mWindowFrames.mFrame;
     }
 
+    /** Accessor for testing */
+    Rect getRelativeFrameLw() {
+        return mWindowFrames.mRelFrame;
+    }
+
     @Override
     public Rect getDisplayFrameLw() {
         return mWindowFrames.mDisplayFrame;
@@ -1289,6 +1309,7 @@
         // We update mLastFrame always rather than in the conditional with the last inset
         // variables, because mFrameSizeChanged only tracks the width and height changing.
         mWindowFrames.mLastFrame.set(mWindowFrames.mFrame);
+        mWindowFrames.mLastRelFrame.set(mWindowFrames.mRelFrame);
 
         if (didFrameInsetsChange
                 || winAnimator.mSurfaceResized
@@ -1404,7 +1425,7 @@
         return mActivityRecord != null ? mActivityRecord.getTask() : null;
     }
 
-    TaskStack getStack() {
+    ActivityStack getStack() {
         Task task = getTask();
         if (task != null) {
             if (task.getTaskStack() != null) {
@@ -1427,7 +1448,7 @@
         bounds.setEmpty();
         mTmpRect.setEmpty();
         if (intersectWithStackBounds) {
-            final TaskStack stack = task.getTaskStack();
+            final ActivityStack stack = task.getTaskStack();
             if (stack != null) {
                 stack.getDimBounds(mTmpRect);
             } else {
@@ -1859,8 +1880,8 @@
     private boolean hasMoved() {
         return mHasSurface && (mWindowFrames.hasContentChanged() || mMovedByResize)
                 && !mAnimatingExit
-                && (mWindowFrames.mFrame.top != mWindowFrames.mLastFrame.top
-                    || mWindowFrames.mFrame.left != mWindowFrames.mLastFrame.left)
+                && (mWindowFrames.mRelFrame.top != mWindowFrames.mLastRelFrame.top
+                    || mWindowFrames.mRelFrame.left != mWindowFrames.mLastRelFrame.left)
                 && (!mIsChildWindow || !getParentWindow().hasMoved());
     }
 
@@ -2135,7 +2156,7 @@
             return false;
         }
 
-        final TaskStack stack = getStack();
+        final ActivityStack stack = getStack();
         if (stack != null && stack.shouldIgnoreInput()) {
             // Ignore when the stack shouldn't receive input event.
             // (i.e. the minimized stack in split screen mode.)
@@ -2539,7 +2560,7 @@
                             // just in case they have the divider at an unstable position. Better
                             // also reset drag resizing state, because the owner can't do it
                             // anymore.
-                            final TaskStack stack =
+                            final ActivityStack stack =
                                     dc.getSplitScreenPrimaryStackIgnoringVisibility();
                             if (stack != null) {
                                 stack.resetDockedStackToMiddle();
@@ -3136,7 +3157,7 @@
             return;
         }
 
-        final TaskStack stack = task.getTaskStack();
+        final ActivityStack stack = task.getTaskStack();
         if (stack == null) {
             return;
         }
@@ -3150,7 +3171,7 @@
             return;
         }
 
-        final TaskStack stack = task.getTaskStack();
+        final ActivityStack stack = task.getTaskStack();
         if (stack == null) {
             return;
         }
@@ -3399,7 +3420,7 @@
     }
 
     private int getStackId() {
-        final TaskStack stack = getStack();
+        final ActivityStack stack = getStack();
         if (stack == null) {
             return INVALID_STACK_ID;
         }
@@ -3630,7 +3651,7 @@
 
     @Override
     void dump(PrintWriter pw, String prefix, boolean dumpAll) {
-        final TaskStack stack = getStack();
+        final ActivityStack stack = getStack();
         pw.print(prefix + "mDisplayId=" + getDisplayId());
         if (stack != null) {
             pw.print(" stackId=" + stack.mStackId);
@@ -5080,7 +5101,7 @@
             outPoint.offset(-parentBounds.left, -parentBounds.top);
         }
 
-        TaskStack stack = getStack();
+        ActivityStack stack = getStack();
 
         // If we have stack outsets, that means the top-left
         // will be outset, and we need to inset ourselves
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index a853828..94aff7b 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1016,7 +1016,7 @@
                         mSurfaceController.deferTransactionUntil(mSurfaceController.mSurfaceControl,
                                 mWin.getFrameNumber());
                     } else {
-                        final TaskStack stack = mWin.getStack();
+                        final ActivityStack stack = mWin.getStack();
                         mTmpPos.x = 0;
                         mTmpPos.y = 0;
                         if (stack != null) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 9dac03f..99f484e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1945,7 +1945,7 @@
         }
 
         TelephonyManager getTelephonyManager() {
-            return TelephonyManager.from(mContext);
+            return mContext.getSystemService(TelephonyManager.class);
         }
 
         TrustManager getTrustManager() {
@@ -9724,13 +9724,9 @@
                     }
                 }
 
-                int userInfoFlags = 0;
-                if (ephemeral) {
-                    userInfoFlags |= UserInfo.FLAG_EPHEMERAL;
-                }
-                if (demo) {
-                    userInfoFlags |= UserInfo.FLAG_DEMO;
-                }
+                int userInfoFlags = ephemeral ? UserInfo.FLAG_EPHEMERAL : 0;
+                String userType = demo ? UserManager.USER_TYPE_FULL_DEMO
+                        : UserManager.USER_TYPE_FULL_SECONDARY;
                 String[] disallowedPackages = null;
                 if (!leaveAllSystemAppsEnabled) {
                     disallowedPackages = mOverlayPackagesProvider.getNonRequiredApps(admin,
@@ -9738,7 +9734,7 @@
                             new String[0]);
                 }
                 UserInfo userInfo = mUserManagerInternal.createUserEvenWhenDisallowed(name,
-                        userInfoFlags, disallowedPackages);
+                        userType, userInfoFlags, disallowedPackages);
                 if (userInfo != null) {
                     user = userInfo.getUserHandle();
                 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 2a364e6..3043b6f 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -83,6 +83,7 @@
 import com.android.server.appbinding.AppBindingService;
 import com.android.server.attention.AttentionManagerService;
 import com.android.server.audio.AudioService;
+import com.android.server.biometrics.AuthService;
 import com.android.server.biometrics.BiometricService;
 import com.android.server.biometrics.face.FaceService;
 import com.android.server.biometrics.fingerprint.FingerprintService;
@@ -1775,8 +1776,13 @@
                 t.traceBegin("StartBiometricService");
                 mSystemServiceManager.startService(BiometricService.class);
                 t.traceEnd();
+
+                t.traceBegin("StartAuthService");
+                mSystemServiceManager.startService(AuthService.class);
+                t.traceEnd();
             }
 
+
             t.traceBegin("StartBackgroundDexOptService");
             try {
                 BackgroundDexOptService.schedule(context);
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index 9c97305..45de451 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -33,6 +33,8 @@
 import static com.android.server.DeviceIdleController.LIGHT_STATE_PRE_IDLE;
 import static com.android.server.DeviceIdleController.LIGHT_STATE_WAITING_FOR_NETWORK;
 import static com.android.server.DeviceIdleController.MSG_REPORT_STATIONARY_STATUS;
+import static com.android.server.DeviceIdleController.MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR;
+import static com.android.server.DeviceIdleController.MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR;
 import static com.android.server.DeviceIdleController.STATE_ACTIVE;
 import static com.android.server.DeviceIdleController.STATE_IDLE;
 import static com.android.server.DeviceIdleController.STATE_IDLE_MAINTENANCE;
@@ -180,7 +182,9 @@
                 mHandler = controller.new MyHandler(getContext().getMainLooper());
                 spyOn(mHandler);
                 doNothing().when(mHandler).handleMessage(argThat((message) ->
-                        message.what != MSG_REPORT_STATIONARY_STATUS));
+                        message.what != MSG_REPORT_STATIONARY_STATUS
+                        && message.what != MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR
+                        && message.what != MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR));
                 doAnswer(new Answer<Boolean>() {
                     @Override
                     public Boolean answer(InvocationOnMock invocation) throws Throwable {
@@ -189,7 +193,9 @@
                         return true;
                     }
                 }).when(mHandler).sendMessageDelayed(
-                        argThat((message) -> message.what == MSG_REPORT_STATIONARY_STATUS),
+                        argThat((message) -> message.what == MSG_REPORT_STATIONARY_STATUS
+                                || message.what == MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR
+                                || message.what == MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR),
                         anyLong());
             }
 
@@ -1734,13 +1740,11 @@
             }
             //TODO(b/123045185): Mocked Handler of DeviceIdleController to make message loop
             //workable in this test class
-            mDeviceIdleController.updatePreIdleFactor();
             float expectedfactor = mDeviceIdleController.getPreIdleTimeoutByMode(mode);
             float curfactor = mDeviceIdleController.getPreIdleTimeoutFactor();
             assertEquals("Pre idle time factor of mode [" + mode + "].",
                     expectedfactor, curfactor, delta);
             mDeviceIdleController.resetPreIdleTimeoutMode();
-            mDeviceIdleController.updatePreIdleFactor();
 
             checkNextAlarmTimeWithNewPreIdleFactor(expectedfactor, STATE_INACTIVE);
             checkNextAlarmTimeWithNewPreIdleFactor(expectedfactor, STATE_IDLE_PENDING);
@@ -2088,14 +2092,11 @@
                         mDeviceIdleController.SET_IDLE_FACTOR_RESULT_OK, ret);
             }
             if (ret == mDeviceIdleController.SET_IDLE_FACTOR_RESULT_OK) {
-                mDeviceIdleController.updatePreIdleFactor();
                 long newAlarm = mDeviceIdleController.getNextAlarmTime();
                 long newDelay = (long) ((alarm - now) * factor);
                 assertTrue("setPreIdleTimeoutFactor: " + factor,
                         Math.abs(newDelay - (newAlarm - now)) <  errorTolerance);
                 mDeviceIdleController.resetPreIdleTimeoutMode();
-                mDeviceIdleController.updatePreIdleFactor();
-                mDeviceIdleController.maybeDoImmediateMaintenance();
                 newAlarm = mDeviceIdleController.getNextAlarmTime();
                 assertTrue("resetPreIdleTimeoutMode from: " + factor,
                         Math.abs(newAlarm - alarm) < errorTolerance);
@@ -2106,19 +2107,14 @@
                 assertTrue("setPreIdleTimeoutFactor: " + factor + " before step to idle",
                         Math.abs(newDelay - (newAlarm - now)) <  errorTolerance);
                 mDeviceIdleController.resetPreIdleTimeoutMode();
-                mDeviceIdleController.updatePreIdleFactor();
-                mDeviceIdleController.maybeDoImmediateMaintenance();
             }
         } else {
             mDeviceIdleController.setPreIdleTimeoutFactor(factor);
-            mDeviceIdleController.updatePreIdleFactor();
             long newAlarm = mDeviceIdleController.getNextAlarmTime();
             assertTrue("setPreIdleTimeoutFactor: " + factor
                     + " shounld not change next alarm" ,
                     (newAlarm == alarm));
             mDeviceIdleController.resetPreIdleTimeoutMode();
-            mDeviceIdleController.updatePreIdleFactor();
-            mDeviceIdleController.maybeDoImmediateMaintenance();
         }
     }
 
@@ -2138,18 +2134,15 @@
             long alarm = mDeviceIdleController.getNextAlarmTime();
             mDeviceIdleController.setIdleStartTimeForTest(
                     now - (long) (mConstants.IDLE_TIMEOUT * 0.6));
-            mDeviceIdleController.maybeDoImmediateMaintenance();
             long newAlarm = mDeviceIdleController.getNextAlarmTime();
             assertTrue("maintenance not reschedule IDLE_TIMEOUT * 0.6",
                     newAlarm == alarm);
             mDeviceIdleController.setIdleStartTimeForTest(
                     now - (long) (mConstants.IDLE_TIMEOUT * 1.2));
-            mDeviceIdleController.maybeDoImmediateMaintenance();
             newAlarm = mDeviceIdleController.getNextAlarmTime();
             assertTrue("maintenance not reschedule IDLE_TIMEOUT * 1.2",
                     (newAlarm - now) < minuteInMillis);
             mDeviceIdleController.resetPreIdleTimeoutMode();
-            mDeviceIdleController.updatePreIdleFactor();
         }
     }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
index 71f7d2c..f2e118d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
@@ -56,6 +56,7 @@
 import com.android.server.DeviceIdleInternal;
 import com.android.server.LocalServices;
 import com.android.server.job.controllers.JobStatus;
+import com.android.server.usage.AppStandbyInternal;
 
 import org.junit.After;
 import org.junit.Before;
@@ -100,6 +101,8 @@
         when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
         doReturn(mActivityMangerInternal)
                 .when(() -> LocalServices.getService(ActivityManagerInternal.class));
+        doReturn(mock(AppStandbyInternal.class))
+                .when(() -> LocalServices.getService(AppStandbyInternal.class));
         doReturn(mock(UsageStatsManagerInternal.class))
                 .when(() -> LocalServices.getService(UsageStatsManagerInternal.class));
         // Called in BackgroundJobsController constructor.
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
index 5bd08c0..bc0b184 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
@@ -78,6 +78,7 @@
 import com.android.server.job.JobStore;
 import com.android.server.job.controllers.QuotaController.ExecutionStats;
 import com.android.server.job.controllers.QuotaController.TimingSession;
+import com.android.server.usage.AppStandbyInternal;
 
 import org.junit.After;
 import org.junit.Before;
@@ -150,6 +151,8 @@
         when(mContext.getSystemService(Context.ALARM_SERVICE)).thenReturn(mAlarmManager);
         doReturn(mActivityMangerInternal)
                 .when(() -> LocalServices.getService(ActivityManagerInternal.class));
+        doReturn(mock(AppStandbyInternal.class))
+                .when(() -> LocalServices.getService(AppStandbyInternal.class));
         doReturn(mock(BatteryManagerInternal.class))
                 .when(() -> LocalServices.getService(BatteryManagerInternal.class));
         doReturn(mUsageStatsManager)
diff --git a/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java
index 0605d9e..50437b4 100644
--- a/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java
@@ -36,7 +36,7 @@
     public void test1() {
         assertTrue("dynamic_system service available", mService != null);
         try {
-            mService.startInstallation("userdata", 8L << 30, false);
+            mService.startInstallation();
             fail("DynamicSystemService did not throw SecurityException as expected");
         } catch (SecurityException e) {
             // expected
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
new file mode 100644
index 0000000..106a723
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
@@ -0,0 +1,194 @@
+/*
+ * 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.biometrics;
+
+import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_SUCCESS;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
+import android.hardware.biometrics.IBiometricService;
+import android.hardware.biometrics.IBiometricServiceReceiver;
+import android.os.Binder;
+import android.os.Bundle;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+public class AuthServiceTest {
+
+    private static final String TAG = "AuthServiceTest";
+    private static final String TEST_OP_PACKAGE_NAME = "test_package";
+
+    private AuthService mAuthService;
+
+    @Mock
+    private Context mContext;
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
+    IBiometricServiceReceiver mReceiver;
+    @Mock
+    AuthService.Injector mInjector;
+    @Mock
+    IBiometricService mBiometricService;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        when(mInjector.getBiometricService()).thenReturn(mBiometricService);
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
+                .thenReturn(true);
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_IRIS)).thenReturn(true);
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
+    }
+
+
+    // TODO(b/141025588): Check that an exception is thrown when the userId != callingUserId
+    @Test
+    public void testAuthenticate_callsBiometricServiceAuthenticate() throws
+            Exception {
+        mAuthService = new AuthService(mContext, mInjector);
+        mAuthService.onStart();
+
+        final Binder token = new Binder();
+        final Bundle bundle = new Bundle();
+        final long sessionId = 0;
+        final int userId = 0;
+
+        mAuthService.mImpl.authenticate(
+                token,
+                sessionId,
+                userId,
+                mReceiver,
+                TEST_OP_PACKAGE_NAME,
+                bundle);
+        waitForIdle();
+        verify(mBiometricService).authenticate(
+                eq(token),
+                eq(sessionId),
+                eq(userId),
+                eq(mReceiver),
+                eq(TEST_OP_PACKAGE_NAME),
+                eq(bundle));
+    }
+
+    @Test
+    public void testCanAuthenticate_callsBiometricServiceCanAuthenticate() throws
+            Exception {
+        mAuthService = new AuthService(mContext, mInjector);
+        mAuthService.onStart();
+
+        final int userId = 0;
+        final int expectedResult = BIOMETRIC_SUCCESS;
+        when(mBiometricService.canAuthenticate(anyString(), anyInt())).thenReturn(expectedResult);
+
+        final int result = mAuthService.mImpl.canAuthenticate(TEST_OP_PACKAGE_NAME, userId);
+
+        assertEquals(expectedResult, result);
+        waitForIdle();
+        verify(mBiometricService).canAuthenticate(
+                eq(TEST_OP_PACKAGE_NAME),
+                eq(userId));
+    }
+
+
+    @Test
+    public void testHasEnrolledBiometrics_callsBiometricServiceHasEnrolledBiometrics() throws
+            Exception {
+        mAuthService = new AuthService(mContext, mInjector);
+        mAuthService.onStart();
+
+        final int userId = 0;
+        final boolean expectedResult = true;
+        when(mBiometricService.hasEnrolledBiometrics(anyInt(), anyString())).thenReturn(
+                expectedResult);
+
+        final boolean result = mAuthService.mImpl.hasEnrolledBiometrics(userId,
+                TEST_OP_PACKAGE_NAME);
+
+        assertEquals(expectedResult, result);
+        waitForIdle();
+        verify(mBiometricService).hasEnrolledBiometrics(
+                eq(userId),
+                eq(TEST_OP_PACKAGE_NAME));
+    }
+
+
+    @Test
+    public void testRegisterKeyguardCallback_callsBiometricServiceRegisterKeyguardCallback()
+            throws Exception {
+        mAuthService = new AuthService(mContext, mInjector);
+        mAuthService.onStart();
+
+        final IBiometricEnabledOnKeyguardCallback callback =
+                new IBiometricEnabledOnKeyguardCallback.Default();
+
+        mAuthService.mImpl.registerEnabledOnKeyguardCallback(callback);
+
+        waitForIdle();
+        verify(mBiometricService).registerEnabledOnKeyguardCallback(eq(callback));
+    }
+
+    @Test
+    public void testSetActiveUser_callsBiometricServiceSetActiveUser() throws
+            Exception {
+        mAuthService = new AuthService(mContext, mInjector);
+        mAuthService.onStart();
+
+        final int userId = 0;
+
+        mAuthService.mImpl.setActiveUser(userId);
+
+        waitForIdle();
+        verify(mBiometricService).setActiveUser(eq(userId));
+    }
+
+    @Test
+    public void testResetLockout_callsBiometricServiceResetLockout() throws
+            Exception {
+        mAuthService = new AuthService(mContext, mInjector);
+        mAuthService.onStart();
+
+        final byte[] token = new byte[0];
+
+        mAuthService.mImpl.resetLockout(token);
+
+        waitForIdle();
+        verify(mBiometricService).resetLockout(token);
+    }
+
+    private static void waitForIdle() {
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index ec47a95..4ced421 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -36,7 +36,6 @@
 import android.app.IActivityManager;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.hardware.biometrics.Authenticator;
 import android.hardware.biometrics.BiometricAuthenticator;
@@ -82,6 +81,8 @@
 
     private static final String FINGERPRINT_ACQUIRED_SENSOR_DIRTY = "sensor_dirty";
 
+    private static final int STRENGTH_STRONG = 1;
+
     private BiometricService mBiometricService;
 
     @Mock
@@ -91,8 +92,6 @@
     @Mock
     private Resources mResources;
     @Mock
-    private PackageManager mPackageManager;
-    @Mock
     IBiometricServiceReceiver mReceiver1;
     @Mock
     IBiometricServiceReceiver mReceiver2;
@@ -107,14 +106,11 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        when(mContext.getPackageManager()).thenReturn(mPackageManager);
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
         when(mContext.getResources()).thenReturn(mResources);
 
         when(mInjector.getActivityManagerService()).thenReturn(mock(IActivityManager.class));
         when(mInjector.getStatusBarService()).thenReturn(mock(IStatusBarService.class));
-        when(mInjector.getFingerprintAuthenticator()).thenReturn(mFingerprintAuthenticator);
-        when(mInjector.getFaceAuthenticator()).thenReturn(mFaceAuthenticator);
         when(mInjector.getSettingObserver(any(), any(), any())).thenReturn(
                 mock(BiometricService.SettingObserver.class));
         when(mInjector.getKeyStore()).thenReturn(mock(KeyStore.class));
@@ -131,11 +127,6 @@
     @Test
     public void testAuthenticate_withoutHardware_returnsErrorHardwareNotPresent() throws
             Exception {
-        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
-                .thenReturn(false);
-        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_IRIS)).thenReturn(false);
-        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(false);
-
         mBiometricService = new BiometricService(mContext, mInjector);
         mBiometricService.onStart();
 
@@ -150,11 +141,13 @@
 
     @Test
     public void testAuthenticate_withoutEnrolled_returnsErrorNoBiometrics() throws Exception {
-        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true);
         when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
 
         mBiometricService = new BiometricService(mContext, mInjector);
         mBiometricService.onStart();
+        mBiometricService.mImpl.registerAuthenticator(0 /* id */, STRENGTH_STRONG,
+                BiometricAuthenticator.TYPE_FINGERPRINT, mFingerprintAuthenticator);
+
 
         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
                 false /* allowDeviceCredential */);
@@ -168,12 +161,13 @@
     @Test
     public void testAuthenticate_whenHalIsDead_returnsErrorHardwareUnavailable() throws
             Exception {
-        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true);
         when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
         when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(false);
 
         mBiometricService = new BiometricService(mContext, mInjector);
         mBiometricService.onStart();
+        mBiometricService.mImpl.registerAuthenticator(0 /* id */, STRENGTH_STRONG,
+                BiometricAuthenticator.TYPE_FINGERPRINT, mFingerprintAuthenticator);
 
         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
                 false /* allowDeviceCredential */);
@@ -187,12 +181,13 @@
     @Test
     public void testAuthenticateFace_respectsUserSetting()
             throws Exception {
-        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
         when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
         when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true);
 
         mBiometricService = new BiometricService(mContext, mInjector);
         mBiometricService.onStart();
+        mBiometricService.mImpl.registerAuthenticator(0 /* id */, STRENGTH_STRONG,
+                BiometricAuthenticator.TYPE_FACE, mFaceAuthenticator);
 
         // Disabled in user settings receives onError
         when(mBiometricService.mSettingObserver.getFaceEnabledForApps(anyInt())).thenReturn(false);
@@ -248,8 +243,6 @@
     @Test
     public void testAuthenticate_happyPathWithoutConfirmation() throws Exception {
         setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT);
-        mBiometricService = new BiometricService(mContext, mInjector);
-        mBiometricService.onStart();
 
         // Start testing the happy path
         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
@@ -861,27 +854,24 @@
     // Helper methods
 
     private void setupAuthForOnly(int modality) throws RemoteException {
-        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
-                .thenReturn(false);
-        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(false);
-
-        if (modality == BiometricAuthenticator.TYPE_FINGERPRINT) {
-            when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
-                    .thenReturn(true);
-            when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
-            when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
-        } else if (modality == BiometricAuthenticator.TYPE_FACE) {
-            when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
-            when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
-            when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true);
-        } else {
-            fail("Unknown modality: " + modality);
-        }
-
         mBiometricService = new BiometricService(mContext, mInjector);
         mBiometricService.onStart();
 
         when(mBiometricService.mSettingObserver.getFaceEnabledForApps(anyInt())).thenReturn(true);
+
+        if (modality == BiometricAuthenticator.TYPE_FINGERPRINT) {
+            when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
+            when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
+            mBiometricService.mImpl.registerAuthenticator(0 /* id */, STRENGTH_STRONG, modality,
+                    mFingerprintAuthenticator);
+        } else if (modality == BiometricAuthenticator.TYPE_FACE) {
+            when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
+            when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true);
+            mBiometricService.mImpl.registerAuthenticator(0 /* id */, STRENGTH_STRONG, modality,
+                    mFaceAuthenticator);
+        } else {
+            fail("Unknown modality: " + modality);
+        }
     }
 
     private void resetReceiver() {
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
index 7081d2e..1d04c83 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
@@ -37,6 +37,7 @@
 import android.hardware.SensorEventListener;
 import android.hardware.display.AmbientBrightnessDayStats;
 import android.hardware.display.BrightnessChangeEvent;
+import android.hardware.display.BrightnessConfiguration;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayedContentSample;
 import android.hardware.display.DisplayedContentSamplingAttributes;
@@ -78,6 +79,7 @@
 @RunWith(AndroidJUnit4.class)
 public class BrightnessTrackerTest {
     private static final float DEFAULT_INITIAL_BRIGHTNESS = 2.5f;
+    private static final boolean DEFAULT_COLOR_SAMPLING_ENABLED = true;
     private static final float FLOAT_DELTA = 0.01f;
 
     private BrightnessTracker mTracker;
@@ -151,6 +153,40 @@
     }
 
     @Test
+    public void testModifyBrightnessConfiguration() {
+        mInjector.mInteractive = true;
+        // Start with tracker not listening for color samples.
+        startTracker(mTracker, DEFAULT_INITIAL_BRIGHTNESS, /* collectColorSamples= */ false);
+        assertFalse(mInjector.mColorSamplingEnabled);
+
+        // Update brightness config to enabled color sampling.
+        mTracker.setBrightnessConfiguration(buildBrightnessConfiguration(
+                /* collectColorSamples= */ true));
+        mInjector.waitForHandler();
+        assertTrue(mInjector.mColorSamplingEnabled);
+
+        // Update brightness config to disable color sampling.
+        mTracker.setBrightnessConfiguration(buildBrightnessConfiguration(
+                /* collectColorSamples= */ false));
+        mInjector.waitForHandler();
+        assertFalse(mInjector.mColorSamplingEnabled);
+
+        // Pretend screen is off, update config to turn on color sampling.
+        mInjector.sendScreenChange(/*screen on */ false);
+        mTracker.setBrightnessConfiguration(buildBrightnessConfiguration(
+                /* collectColorSamples= */ true));
+        mInjector.waitForHandler();
+        assertFalse(mInjector.mColorSamplingEnabled);
+
+        // Pretend screen is on.
+        mInjector.sendScreenChange(/*screen on */ true);
+        assertTrue(mInjector.mColorSamplingEnabled);
+
+        mTracker.stop();
+        assertFalse(mInjector.mColorSamplingEnabled);
+    }
+
+    @Test
     public void testNoColorSampling_WrongPixelFormat() {
         mInjector.mDefaultSamplingAttributes =
                 new DisplayedContentSamplingAttributes(
@@ -278,7 +314,7 @@
         mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1);
         mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3333);
 
-        startTracker(mTracker, initialBrightness);
+        startTracker(mTracker, initialBrightness, DEFAULT_COLOR_SAMPLING_ENABLED);
         mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(),
                 batteryChangeEvent(30, 60));
         mInjector.mSensorListener.onSensorChanged(createSensorEvent(1000.0f));
@@ -311,7 +347,7 @@
     @Test
     public void testIgnoreAutomaticBrightnessChange() {
         final int initialBrightness = 30;
-        startTracker(mTracker, initialBrightness);
+        startTracker(mTracker, initialBrightness, DEFAULT_COLOR_SAMPLING_ENABLED);
         mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
         mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1));
 
@@ -750,11 +786,13 @@
     }
 
     private void startTracker(BrightnessTracker tracker) {
-        startTracker(tracker, DEFAULT_INITIAL_BRIGHTNESS);
+        startTracker(tracker, DEFAULT_INITIAL_BRIGHTNESS,  DEFAULT_COLOR_SAMPLING_ENABLED);
     }
 
-    private void startTracker(BrightnessTracker tracker, float initialBrightness) {
+    private void startTracker(BrightnessTracker tracker, float initialBrightness,
+            boolean collectColorSamples) {
         tracker.start(initialBrightness);
+        tracker.setBrightnessConfiguration(buildBrightnessConfiguration(collectColorSamples));
         mInjector.waitForHandler();
     }
 
@@ -772,6 +810,14 @@
         mInjector.waitForHandler();
     }
 
+    private BrightnessConfiguration buildBrightnessConfiguration(boolean collectColorSamples) {
+        BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder(
+                /* lux = */ new float[] {0f, 10f, 100f},
+                /* nits = */ new float[] {1f, 90f, 100f});
+        builder.setShouldCollectColorSamples(collectColorSamples);
+        return builder.build();
+    }
+
     private static final class Idle implements MessageQueue.IdleHandler {
         private boolean mIdle;
 
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 819091c..f6fb6e2 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
@@ -20,20 +20,17 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.annotation.Nullable;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
 import android.content.pm.PackageParser;
 import android.os.Build;
 import android.os.Process;
-import android.permission.IPermissionManager;
 import android.util.ArrayMap;
 
 import org.junit.Before;
@@ -43,20 +40,16 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import java.util.Map;
-
 @RunWith(JUnit4.class)
 public class AppsFilterTest {
 
     private static final int DUMMY_CALLING_UID = 10345;
-
-    @Mock
-    IPermissionManager mPermissionManagerMock;
+    private static final int DUMMY_TARGET_UID = 10556;
 
     @Mock
     AppsFilter.FeatureConfig mFeatureConfigMock;
 
-    private Map<String, PackageParser.Package> mExisting = new ArrayMap<>();
+    private ArrayMap<String, PackageSetting> mExisting = new ArrayMap<>();
 
     private static PackageBuilder pkg(String packageName) {
         return new PackageBuilder(packageName)
@@ -72,9 +65,10 @@
     }
 
     private static PackageBuilder pkg(String packageName, IntentFilter... filters) {
+        final ActivityInfo activityInfo = new ActivityInfo();
         final PackageBuilder packageBuilder = pkg(packageName).addActivity(
                 pkg -> new PackageParser.ParseComponentArgs(pkg, new String[1], 0, 0, 0, 0, 0, 0,
-                        new String[]{packageName}, 0, 0, 0), new ActivityInfo());
+                        new String[]{packageName}, 0, 0, 0), activityInfo);
         for (IntentFilter filter : filters) {
             packageBuilder.addActivityIntentInfo(0 /* index */, activity -> {
                 final PackageParser.ActivityIntentInfo info =
@@ -83,7 +77,7 @@
                     filter.actionsIterator().forEachRemaining(info::addAction);
                 }
                 if (filter.countCategories() > 0) {
-                    filter.actionsIterator().forEachRemaining(info::addAction);
+                    filter.actionsIterator().forEachRemaining(info::addCategory);
                 }
                 if (filter.countDataAuthorities() > 0) {
                     filter.authoritiesIterator().forEachRemaining(info::addDataAuthority);
@@ -91,6 +85,7 @@
                 if (filter.countDataSchemes() > 0) {
                     filter.schemesIterator().forEachRemaining(info::addDataScheme);
                 }
+                activityInfo.exported = true;
                 return info;
             });
         }
@@ -102,9 +97,6 @@
         mExisting = new ArrayMap<>();
 
         MockitoAnnotations.initMocks(this);
-        when(mPermissionManagerMock
-                .checkPermission(anyString(), anyString(), anyInt()))
-                .thenReturn(PackageManager.PERMISSION_DENIED);
         when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true);
         when(mFeatureConfigMock.packageIsEnabled(any(PackageParser.Package.class)))
                 .thenReturn(true);
@@ -113,7 +105,7 @@
     @Test
     public void testSystemReadyPropogates() throws Exception {
         final AppsFilter appsFilter =
-                new AppsFilter(mFeatureConfigMock, mPermissionManagerMock, new String[]{}, false);
+                new AppsFilter(mFeatureConfigMock, new String[]{}, false);
         appsFilter.onSystemReady();
         verify(mFeatureConfigMock).onSystemReady();
     }
@@ -121,12 +113,12 @@
     @Test
     public void testQueriesAction_FilterMatches() {
         final AppsFilter appsFilter =
-                new AppsFilter(mFeatureConfigMock, mPermissionManagerMock, new String[]{}, false);
+                new AppsFilter(mFeatureConfigMock, new String[]{}, false);
 
         PackageSetting target = simulateAddPackage(appsFilter,
-                pkg("com.some.package", new IntentFilter("TEST_ACTION"))).build();
+                pkg("com.some.package", new IntentFilter("TEST_ACTION")), DUMMY_TARGET_UID);
         PackageSetting calling = simulateAddPackage(appsFilter,
-                pkg("com.some.other.package", new Intent("TEST_ACTION"))).build();
+                pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_UID);
 
         assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
     }
@@ -134,12 +126,12 @@
     @Test
     public void testQueriesAction_NoMatchingAction_Filters() {
         final AppsFilter appsFilter =
-                new AppsFilter(mFeatureConfigMock, mPermissionManagerMock, new String[]{}, false);
+                new AppsFilter(mFeatureConfigMock, new String[]{}, false);
 
         PackageSetting target = simulateAddPackage(appsFilter,
-                pkg("com.some.package")).build();
+                pkg("com.some.package"), DUMMY_TARGET_UID);
         PackageSetting calling = simulateAddPackage(appsFilter,
-                pkg("com.some.other.package", new Intent("TEST_ACTION"))).build();
+                pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_UID);
 
         assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
     }
@@ -147,13 +139,17 @@
     @Test
     public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() {
         final AppsFilter appsFilter =
-                new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
-                        new String[]{}, false);
+                new AppsFilter(mFeatureConfigMock, new String[]{}, false);
 
-        PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
-        PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package",
-                new Intent("TEST_ACTION")).setApplicationInfoTargetSdkVersion(
-                Build.VERSION_CODES.P)).build();
+        PackageSetting target = simulateAddPackage(appsFilter,
+                pkg("com.some.package"), DUMMY_TARGET_UID);
+        PackageSetting calling = simulateAddPackage(appsFilter,
+                pkg("com.some.other.package",
+                        new Intent("TEST_ACTION"))
+                        .setApplicationInfoTargetSdkVersion(Build.VERSION_CODES.P),
+                DUMMY_CALLING_UID);
+
+        when(mFeatureConfigMock.packageIsEnabled(calling.pkg)).thenReturn(false);
 
         assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
     }
@@ -161,12 +157,12 @@
     @Test
     public void testNoQueries_Filters() {
         final AppsFilter appsFilter =
-                new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
-                        new String[]{}, false);
+                new AppsFilter(mFeatureConfigMock, new String[]{}, false);
 
-        PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
+        PackageSetting target = simulateAddPackage(appsFilter,
+                pkg("com.some.package"), DUMMY_TARGET_UID);
         PackageSetting calling = simulateAddPackage(appsFilter,
-                pkg("com.some.other.package")).build();
+                pkg("com.some.other.package"), DUMMY_CALLING_UID);
 
         assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
     }
@@ -174,14 +170,12 @@
     @Test
     public void testForceQueryable_DoesntFilter() {
         final AppsFilter appsFilter =
-                new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
-                        new String[]{}, false);
+                new AppsFilter(mFeatureConfigMock, new String[]{}, false);
 
-        PackageSetting target =
-                simulateAddPackage(appsFilter, pkg("com.some.package").setForceQueryable(true))
-                        .build();
+        PackageSetting target = simulateAddPackage(appsFilter,
+                        pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_UID);
         PackageSetting calling = simulateAddPackage(appsFilter,
-                pkg("com.some.other.package")).build();
+                pkg("com.some.other.package"), DUMMY_CALLING_UID);
 
         assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
     }
@@ -189,14 +183,13 @@
     @Test
     public void testForceQueryableByDevice_SystemCaller_DoesntFilter() {
         final AppsFilter appsFilter =
-                new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
-                        new String[]{"com.some.package"}, false);
+                new AppsFilter(mFeatureConfigMock, new String[]{"com.some.package"}, false);
 
-        PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"))
-                .setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
-                .build();
+        PackageSetting target = simulateAddPackage(appsFilter,
+                pkg("com.some.package"), DUMMY_TARGET_UID,
+                setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
         PackageSetting calling = simulateAddPackage(appsFilter,
-                pkg("com.some.other.package")).build();
+                pkg("com.some.other.package"), DUMMY_CALLING_UID);
 
         assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
     }
@@ -204,12 +197,12 @@
     @Test
     public void testForceQueryableByDevice_NonSystemCaller_Filters() {
         final AppsFilter appsFilter =
-                new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
-                        new String[]{"com.some.package"}, false);
+                new AppsFilter(mFeatureConfigMock, new String[]{"com.some.package"}, false);
 
-        PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
+        PackageSetting target = simulateAddPackage(appsFilter,
+                pkg("com.some.package"), DUMMY_TARGET_UID);
         PackageSetting calling = simulateAddPackage(appsFilter,
-                pkg("com.some.other.package")).build();
+                pkg("com.some.other.package"), DUMMY_CALLING_UID);
 
         assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
     }
@@ -218,14 +211,14 @@
     @Test
     public void testSystemQueryable_DoesntFilter() {
         final AppsFilter appsFilter =
-                new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
-                        new String[]{}, true /* system force queryable */);
+                new AppsFilter(mFeatureConfigMock, new String[]{},
+                        true /* system force queryable */);
 
-        PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"))
-                .setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
-                .build();
+        PackageSetting target = simulateAddPackage(appsFilter,
+                pkg("com.some.package"), DUMMY_TARGET_UID,
+                setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
         PackageSetting calling = simulateAddPackage(appsFilter,
-                pkg("com.some.other.package")).build();
+                pkg("com.some.other.package"), DUMMY_CALLING_UID);
 
         assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
     }
@@ -233,12 +226,12 @@
     @Test
     public void testQueriesPackage_DoesntFilter() {
         final AppsFilter appsFilter =
-                new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
-                        new String[]{}, false);
+                new AppsFilter(mFeatureConfigMock, new String[]{}, false);
 
-        PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
+        PackageSetting target = simulateAddPackage(appsFilter,
+                pkg("com.some.package"), DUMMY_TARGET_UID);
         PackageSetting calling = simulateAddPackage(appsFilter,
-                pkg("com.some.other.package", "com.some.package")).build();
+                pkg("com.some.other.package", "com.some.package"), DUMMY_CALLING_UID);
 
         assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
     }
@@ -248,12 +241,12 @@
         when(mFeatureConfigMock.packageIsEnabled(any(PackageParser.Package.class)))
                 .thenReturn(false);
         final AppsFilter appsFilter =
-                new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
-                        new String[]{}, false);
+                new AppsFilter(mFeatureConfigMock, new String[]{}, false);
 
-        PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
-        PackageSetting calling = simulateAddPackage(appsFilter,
-                pkg("com.some.other.package")).build();
+        PackageSetting target = simulateAddPackage(
+                appsFilter, pkg("com.some.package"), DUMMY_TARGET_UID);
+        PackageSetting calling = simulateAddPackage(
+                appsFilter, pkg("com.some.other.package"), DUMMY_CALLING_UID);
 
         assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
     }
@@ -261,10 +254,10 @@
     @Test
     public void testSystemUid_DoesntFilter() {
         final AppsFilter appsFilter =
-                new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
-                        new String[]{}, false);
+                new AppsFilter(mFeatureConfigMock, new String[]{}, false);
 
-        PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
+        PackageSetting target = simulateAddPackage(appsFilter,
+                pkg("com.some.package"), DUMMY_TARGET_UID);
 
         assertFalse(appsFilter.shouldFilterApplication(0, null, target, 0));
         assertFalse(appsFilter.shouldFilterApplication(
@@ -274,10 +267,10 @@
     @Test
     public void testNonSystemUid_NoCallingSetting_Filters() {
         final AppsFilter appsFilter =
-                new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
-                        new String[]{}, false);
+                new AppsFilter(mFeatureConfigMock, new String[]{}, false);
 
-        PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
+        PackageSetting target = simulateAddPackage(appsFilter,
+                pkg("com.some.package"), DUMMY_TARGET_UID);
 
         assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, null, target, 0));
     }
@@ -285,8 +278,7 @@
     @Test
     public void testNoTargetPackage_filters() {
         final AppsFilter appsFilter =
-                new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
-                        new String[]{}, false);
+                new AppsFilter(mFeatureConfigMock, new String[]{}, false);
 
         PackageSetting target = new PackageSettingBuilder()
                 .setName("com.some.package")
@@ -295,22 +287,36 @@
                 .setPVersionCode(1L)
                 .build();
         PackageSetting calling = simulateAddPackage(appsFilter,
-                pkg("com.some.other.package", new Intent("TEST_ACTION"))).build();
+                pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_UID);
 
         assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
     }
 
-    private PackageSettingBuilder simulateAddPackage(AppsFilter filter,
-            PackageBuilder newPkgBuilder) {
+    private interface WithSettingBuilder {
+        PackageSettingBuilder withBuilder(PackageSettingBuilder builder);
+    }
+
+    private PackageSetting simulateAddPackage(AppsFilter filter,
+            PackageBuilder newPkgBuilder, int appId) {
+        return simulateAddPackage(filter, newPkgBuilder, appId, null);
+    }
+
+    private PackageSetting simulateAddPackage(AppsFilter filter,
+            PackageBuilder newPkgBuilder, int appId, @Nullable WithSettingBuilder action) {
         PackageParser.Package newPkg = newPkgBuilder.build();
-        filter.addPackage(newPkg, mExisting);
-        mExisting.put(newPkg.packageName, newPkg);
-        return new PackageSettingBuilder()
+
+        final PackageSettingBuilder settingBuilder = new PackageSettingBuilder()
                 .setPackage(newPkg)
+                .setAppId(appId)
                 .setName(newPkg.packageName)
                 .setCodePath("/")
                 .setResourcePath("/")
                 .setPVersionCode(1L);
+        final PackageSetting setting =
+                (action == null ? settingBuilder : action.withBuilder(settingBuilder)).build();
+        filter.addPackage(setting, mExisting);
+        mExisting.put(newPkg.packageName, setting);
+        return setting;
     }
 
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
index 06c6314..8d476f6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
@@ -43,6 +43,7 @@
     private String mVolumeUuid;
     private SparseArray<PackageUserState> mUserStates = new SparseArray<>();
     private PackageParser.Package mPkg;
+    private int mAppId;
 
     public PackageSettingBuilder setPackage(PackageParser.Package pkg) {
         this.mPkg = pkg;
@@ -54,6 +55,11 @@
         return this;
     }
 
+    public PackageSettingBuilder setAppId(int appId) {
+        this.mAppId = appId;
+        return this;
+    }
+
     public PackageSettingBuilder setRealName(String realName) {
         this.mRealName = realName;
         return this;
@@ -152,6 +158,7 @@
                 mChildPackageNames, mSharedUserId, mUsesStaticLibraries,
                 mUsesStaticLibrariesVersions);
         packageSetting.pkg = mPkg;
+        packageSetting.appId = mAppId;
         packageSetting.volumeUuid = this.mVolumeUuid;
         for (int i = 0; i < mUserStates.size(); i++) {
             packageSetting.setUserState(mUserStates.keyAt(i), mUserStates.valueAt(i));
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java b/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java
index d6f7e37..7916bd3 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserLifecycleStressTest.java
@@ -71,7 +71,7 @@
             throws IOException, RemoteException, InterruptedException {
         for (int i = 0; i < NUM_ITERATIONS_STOP_USER; i++) {
             final UserInfo userInfo = mUserManager.createProfileForUser("TestUser",
-                    UserInfo.FLAG_MANAGED_PROFILE, mActivityManager.getCurrentUser());
+                    UserManager.USER_TYPE_PROFILE_MANAGED, 0, mActivityManager.getCurrentUser());
             assertNotNull(userInfo);
             try {
                 assertTrue(
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java
index 8dd8967..e375aef 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java
@@ -16,15 +16,15 @@
 
 package com.android.server.pm;
 
+import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import android.app.ApplicationPackageManager;
 import android.content.pm.UserInfo;
 import android.os.Looper;
 import android.os.UserHandle;
 import android.os.UserManagerInternal;
-import android.util.IconDrawableFactory;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.MediumTest;
@@ -71,6 +71,7 @@
         removeUsers();
     }
 
+    /** Tests UMS.getProfileIds() when no specific userType is specified. */
     @Test
     public void testGetProfiles() {
         // Pretend we have a secondary user with a profile.
@@ -93,38 +94,73 @@
                 || users.get(1).id == profile.id);
     }
 
+    /** Tests UMS.getProfileIds() when a specific userType is specified. */
+    @Test
+    public void testGetProfileIds_specifyType() {
+        // Pretend we have a secondary user with a profile.
+        UserInfo secondaryUser = addUser();
+        UserInfo profile = addProfile(secondaryUser);
+
+        // TODO: When there are multiple profiles types, ensure correct output for mixed types.
+        final String userType1 = USER_TYPE_PROFILE_MANAGED;
+
+        // System user should still have no userType1 profile so getProfileIds should be empty.
+        int[] users = mUserManagerService.getProfileIds(UserHandle.USER_SYSTEM, userType1, false);
+        assertEquals("System user should have no managed profiles", 0, users.length);
+
+        // Secondary user should have one userType1 profile, so return just that.
+        users = mUserManagerService.getProfileIds(secondaryUser.id, userType1, false);
+        assertEquals("Wrong number of profiles", 1, users.length);
+        assertEquals("Wrong profile id", profile.id, users[0]);
+
+        // The profile itself is a userType1 profile, so it should return just itself.
+        users = mUserManagerService.getProfileIds(profile.id, userType1, false);
+        assertEquals("Wrong number of profiles", 1, users.length);
+        assertEquals("Wrong profile id", profile.id, users[0]);
+    }
+
     @Test
     public void testProfileBadge() {
         // First profile for system user should get badge 0
         assertEquals("First profile isn't given badge index 0", 0,
-                mUserManagerService.getFreeProfileBadgeLU(UserHandle.USER_SYSTEM));
+                mUserManagerService.getFreeProfileBadgeLU(UserHandle.USER_SYSTEM,
+                        USER_TYPE_PROFILE_MANAGED));
 
         // Pretend we have a secondary user.
         UserInfo secondaryUser = addUser();
 
         // Check first profile badge for secondary user is also 0.
         assertEquals("First profile for secondary user isn't given badge index 0", 0,
-                mUserManagerService.getFreeProfileBadgeLU(secondaryUser.id));
+                mUserManagerService.getFreeProfileBadgeLU(secondaryUser.id,
+                        USER_TYPE_PROFILE_MANAGED));
 
         // Shouldn't impact the badge for profile in system user
         assertEquals("First profile isn't given badge index 0 with secondary user", 0,
-                mUserManagerService.getFreeProfileBadgeLU(UserHandle.USER_SYSTEM));
+                mUserManagerService.getFreeProfileBadgeLU(UserHandle.USER_SYSTEM,
+                        USER_TYPE_PROFILE_MANAGED));
 
         // Pretend a secondary user has a profile.
         addProfile(secondaryUser);
 
         // Shouldn't have impacted the badge for the system user
         assertEquals("First profile isn't given badge index 0 in secondary user", 0,
-                mUserManagerService.getFreeProfileBadgeLU(UserHandle.USER_SYSTEM));
+                mUserManagerService.getFreeProfileBadgeLU(UserHandle.USER_SYSTEM,
+                        USER_TYPE_PROFILE_MANAGED));
     }
 
     @Test
     public void testProfileBadgeUnique() {
         List<UserInfo> users = mUserManagerService.getUsers(/* excludeDying */ false);
         UserInfo system = users.get(0);
+        int max = mUserManagerService.getMaxUsersOfTypePerParent(USER_TYPE_PROFILE_MANAGED);
+        if (max < 0) {
+            // Indicates no max. Instead of infinite, we'll just do 10.
+            max = 10;
+        }
         // Badges should get allocated 0 -> max
-        for (int i = 0; i < UserManagerService.getMaxManagedProfiles(); ++i) {
-            int nextBadge = mUserManagerService.getFreeProfileBadgeLU(UserHandle.USER_SYSTEM);
+        for (int i = 0; i < max; ++i) {
+            int nextBadge = mUserManagerService.getFreeProfileBadgeLU(UserHandle.USER_SYSTEM,
+                    USER_TYPE_PROFILE_MANAGED);
             assertEquals("Wrong badge allocated", i, nextBadge);
             UserInfo profile = addProfile(system);
             profile.profileBadge = nextBadge;
@@ -140,30 +176,23 @@
         mUserManagerService.addRemovingUserIdLocked(profile.id);
         // We should reuse the badge from the profile being removed.
         assertEquals("Badge index not reused while removing a user", 0,
-                mUserManagerService.getFreeProfileBadgeLU(secondaryUser.id));
+                mUserManagerService.getFreeProfileBadgeLU(secondaryUser.id,
+                        USER_TYPE_PROFILE_MANAGED));
 
         // Edge case of reuse that only applies if we ever support 3 managed profiles
         // We should prioritise using lower badge indexes
-        if (UserManagerService.getMaxManagedProfiles() > 2) {
+        int max = mUserManagerService.getMaxUsersOfTypePerParent(USER_TYPE_PROFILE_MANAGED);
+        if (max < 0 || max > 2) {
             UserInfo profileBadgeOne = addProfile(secondaryUser);
             profileBadgeOne.profileBadge = 1;
             // 0 and 2 are free, we should reuse 0 rather than 2.
             assertEquals("Lower index not used", 0,
-                    mUserManagerService.getFreeProfileBadgeLU(secondaryUser.id));
+                    mUserManagerService.getFreeProfileBadgeLU(secondaryUser.id,
+                            USER_TYPE_PROFILE_MANAGED));
         }
     }
 
     @Test
-    public void testNumberOfBadges() {
-        assertTrue("Max profiles greater than number of badges",
-                UserManagerService.MAX_MANAGED_PROFILES
-                <= IconDrawableFactory.CORP_BADGE_COLORS.length);
-        assertEquals("Num colors doesn't match number of badge labels",
-                IconDrawableFactory.CORP_BADGE_COLORS.length,
-                ApplicationPackageManager.CORP_BADGE_LABEL_RES_ID.length);
-    }
-
-    @Test
     public void testCanAddMoreManagedProfiles_removeProfile() {
         // if device is low-ram or doesn't support managed profiles for some other reason, just
         // skip the test
@@ -171,6 +200,10 @@
                 false /* disallow remove */)) {
             return;
         }
+        if (mUserManagerService.getMaxUsersOfTypePerParent(USER_TYPE_PROFILE_MANAGED) < 0) {
+            // Indicates no limit, so we cannot run this test;
+            return;
+        }
 
         // GIVEN we've reached the limit of managed profiles possible on the system user
         while (mUserManagerService.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
@@ -192,6 +225,10 @@
                 false /* disallow remove */)) {
             return;
         }
+        if (mUserManagerService.getMaxUsersOfTypePerParent(USER_TYPE_PROFILE_MANAGED) < 0) {
+            // Indicates no limit, so we cannot run this test;
+            return;
+        }
 
         // GIVEN we've reached the limit of managed profiles possible on the system user
         // GIVEN that the profiles are not enabled yet
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
index 6d5b994..1e760cc 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
@@ -16,11 +16,29 @@
 
 package com.android.server.pm;
 
+import static android.content.pm.UserInfo.FLAG_DEMO;
+import static android.content.pm.UserInfo.FLAG_EPHEMERAL;
+import static android.content.pm.UserInfo.FLAG_FULL;
+import static android.content.pm.UserInfo.FLAG_GUEST;
+import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
+import static android.content.pm.UserInfo.FLAG_PROFILE;
+import static android.content.pm.UserInfo.FLAG_RESTRICTED;
+import static android.content.pm.UserInfo.FLAG_SYSTEM;
+import static android.os.UserManager.USER_TYPE_FULL_DEMO;
+import static android.os.UserManager.USER_TYPE_FULL_GUEST;
+import static android.os.UserManager.USER_TYPE_FULL_RESTRICTED;
+import static android.os.UserManager.USER_TYPE_FULL_SECONDARY;
+import static android.os.UserManager.USER_TYPE_FULL_SYSTEM;
+import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
+import static android.os.UserManager.USER_TYPE_SYSTEM_HEADLESS;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import android.annotation.UserIdInt;
 import android.content.pm.UserInfo;
+import android.content.pm.UserInfo.UserInfoFlag;
 import android.os.Looper;
 import android.os.Parcel;
 import android.os.UserHandle;
@@ -121,8 +139,61 @@
         assertEquals("A Name", mUserManagerService.getUserInfo(TEST_ID).name);
     }
 
+    /** Test UMS.getUserTypeForUser(). */
+    @Test
+    public void testGetUserTypeForUser() throws Exception {
+        final String typeSys = mUserManagerService.getUserTypeForUser(UserHandle.USER_SYSTEM);
+        assertTrue("System user was of invalid type " + typeSys,
+                typeSys.equals(USER_TYPE_SYSTEM_HEADLESS) || typeSys.equals(USER_TYPE_FULL_SYSTEM));
+
+        final int testId = 100;
+        final String typeName = "A type";
+        UserInfo userInfo = createUser(testId, 0, typeName);
+        mUserManagerService.putUserInfo(userInfo);
+        assertEquals(typeName, mUserManagerService.getUserTypeForUser(testId));
+    }
+
+    /** Tests upgradeIfNecessaryLP (but without locking) for upgrading from version 8 to 9+. */
+    @Test
+    public void testUpgradeIfNecessaryLP_9() {
+        final int versionToTest = 9;
+
+        mUserManagerService.putUserInfo(createUser(100, FLAG_MANAGED_PROFILE, null));
+        mUserManagerService.putUserInfo(createUser(101,
+                FLAG_GUEST | FLAG_EPHEMERAL | FLAG_FULL, null));
+        mUserManagerService.putUserInfo(createUser(102, FLAG_RESTRICTED | FLAG_FULL, null));
+        mUserManagerService.putUserInfo(createUser(103, FLAG_FULL, null));
+        mUserManagerService.putUserInfo(createUser(104, FLAG_SYSTEM, null));
+        mUserManagerService.putUserInfo(createUser(105, FLAG_SYSTEM | FLAG_FULL, null));
+        mUserManagerService.putUserInfo(createUser(106, FLAG_DEMO | FLAG_FULL, null));
+
+        mUserManagerService.upgradeIfNecessaryLP(null, versionToTest - 1);
+
+        assertEquals(USER_TYPE_PROFILE_MANAGED, mUserManagerService.getUserTypeForUser(100));
+        assertTrue((mUserManagerService.getUserInfo(100).flags & FLAG_PROFILE) != 0);
+
+        assertEquals(USER_TYPE_FULL_GUEST, mUserManagerService.getUserTypeForUser(101));
+
+        assertEquals(USER_TYPE_FULL_RESTRICTED, mUserManagerService.getUserTypeForUser(102));
+        assertTrue((mUserManagerService.getUserInfo(102).flags & FLAG_PROFILE) == 0);
+
+        assertEquals(USER_TYPE_FULL_SECONDARY, mUserManagerService.getUserTypeForUser(103));
+        assertTrue((mUserManagerService.getUserInfo(103).flags & FLAG_PROFILE) == 0);
+
+        assertEquals(USER_TYPE_SYSTEM_HEADLESS, mUserManagerService.getUserTypeForUser(104));
+
+        assertEquals(USER_TYPE_FULL_SYSTEM, mUserManagerService.getUserTypeForUser(105));
+
+        assertEquals(USER_TYPE_FULL_DEMO, mUserManagerService.getUserTypeForUser(106));
+    }
+
+    /** Creates a UserInfo with the given flags and userType. */
+    private UserInfo createUser(@UserIdInt int userId, @UserInfoFlag int flags, String userType) {
+        return new UserInfo(userId, "A Name", "A path", flags, userType);
+    }
+
     private UserInfo createUser() {
-        UserInfo user = new UserInfo(/*id*/ 21, "A Name", "A path", /*flags*/ 0x0ff0ff);
+        UserInfo user = new UserInfo(/*id*/ 21, "A Name", "A path", /*flags*/ 0x0ff0ff, "A type");
         user.serialNumber = 5;
         user.creationTime = 4L << 32;
         user.lastLoggedInTime = 5L << 32;
@@ -141,6 +212,7 @@
         assertEquals("Name not preserved", one.name, two.name);
         assertEquals("Icon path not preserved", one.iconPath, two.iconPath);
         assertEquals("Flags not preserved", one.flags, two.flags);
+        assertEquals("UserType not preserved", one.userType, two.userType);
         assertEquals("profile group not preserved", one.profileGroupId,
                 two.profileGroupId);
         assertEquals("restricted profile parent not preseved", one.restrictedProfileParentId,
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java
new file mode 100644
index 0000000..7aadd87
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java
@@ -0,0 +1,192 @@
+/*
+ * 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.pm;
+
+import static android.content.pm.UserInfo.FLAG_DEMO;
+import static android.content.pm.UserInfo.FLAG_EPHEMERAL;
+import static android.content.pm.UserInfo.FLAG_FULL;
+import static android.content.pm.UserInfo.FLAG_GUEST;
+import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
+import static android.content.pm.UserInfo.FLAG_PROFILE;
+import static android.content.pm.UserInfo.FLAG_RESTRICTED;
+import static android.content.pm.UserInfo.FLAG_SYSTEM;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.testng.Assert.assertThrows;
+
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.os.UserManager;
+
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Tests for {@link UserTypeDetails} and {@link UserTypeFactory}.
+ *
+ * <p>Run with: atest UserManagerServiceUserTypeTest
+ */
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class UserManagerServiceUserTypeTest {
+
+    @Test
+    public void testUserTypeBuilder_createUserType() {
+        UserTypeDetails type = new UserTypeDetails.Builder()
+                .setName("a.name")
+                .setEnabled(true)
+                .setMaxAllowed(21)
+                .setBaseType(FLAG_FULL)
+                .setDefaultUserInfoPropertyFlags(FLAG_EPHEMERAL)
+                .setBadgeLabels(23, 24, 25)
+                .setBadgeColors(26, 27)
+                .setIconBadge(28)
+                .setBadgePlain(29)
+                .setBadgeNoBackground(30)
+                .setLabel(31)
+                .setMaxAllowedPerParent(32)
+                .setDefaultRestrictions(new ArrayList<>(Arrays.asList("r1", "r2")))
+                .createUserTypeDetails();
+
+        assertEquals("a.name", type.getName());
+        assertTrue(type.isEnabled());
+        assertEquals(21, type.getMaxAllowed());
+        assertEquals(FLAG_FULL | FLAG_EPHEMERAL, type.getDefaultUserInfoFlags());
+        assertEquals(28, type.getIconBadge());
+        assertEquals(29, type.getBadgePlain());
+        assertEquals(30, type.getBadgeNoBackground());
+        assertEquals(31, type.getLabel());
+        assertEquals(32, type.getMaxAllowedPerParent());
+        assertEquals(new ArrayList<>(Arrays.asList("r1", "r2")), type.getDefaultRestrictions());
+
+
+        assertEquals(23, type.getBadgeLabel(0));
+        assertEquals(24, type.getBadgeLabel(1));
+        assertEquals(25, type.getBadgeLabel(2));
+        assertEquals(25, type.getBadgeLabel(3));
+        assertEquals(25, type.getBadgeLabel(4));
+        assertEquals(Resources.ID_NULL, type.getBadgeLabel(-1));
+
+        assertEquals(26, type.getBadgeColor(0));
+        assertEquals(27, type.getBadgeColor(1));
+        assertEquals(27, type.getBadgeColor(2));
+        assertEquals(27, type.getBadgeColor(3));
+        assertEquals(Resources.ID_NULL, type.getBadgeColor(-100));
+
+        assertTrue(type.hasBadge());
+    }
+
+    @Test
+    public void testUserTypeBuilder_defaults() {
+        UserTypeDetails type = new UserTypeDetails.Builder()
+                .setName("name") // Required (no default allowed)
+                .setBaseType(FLAG_FULL) // Required (no default allowed)
+                .createUserTypeDetails();
+
+        assertTrue(type.isEnabled());
+        assertEquals(UserTypeDetails.UNLIMITED_NUMBER_OF_USERS, type.getMaxAllowed());
+        assertEquals(UserTypeDetails.UNLIMITED_NUMBER_OF_USERS, type.getMaxAllowedPerParent());
+        assertEquals(FLAG_FULL, type.getDefaultUserInfoFlags());
+        assertEquals(Resources.ID_NULL, type.getIconBadge());
+        assertEquals(Resources.ID_NULL, type.getBadgePlain());
+        assertEquals(Resources.ID_NULL, type.getBadgeNoBackground());
+        assertEquals(Resources.ID_NULL, type.getBadgeLabel(0));
+        assertEquals(Resources.ID_NULL, type.getBadgeColor(0));
+        assertEquals(Resources.ID_NULL, type.getLabel());
+        assertTrue(type.getDefaultRestrictions().isEmpty());
+
+        assertFalse(type.hasBadge());
+    }
+
+    @Test
+    public void testUserTypeBuilder_nameIsRequired() {
+        assertThrows(IllegalArgumentException.class,
+                () -> new UserTypeDetails.Builder()
+                        .setMaxAllowed(21)
+                        .setBaseType(FLAG_FULL)
+                        .createUserTypeDetails());
+    }
+
+    @Test
+    public void testUserTypeBuilder_baseTypeIsRequired() {
+        assertThrows(IllegalArgumentException.class,
+                () -> new UserTypeDetails.Builder()
+                        .setName("name")
+                        .createUserTypeDetails());
+    }
+
+    @Test
+    public void testUserTypeBuilder_colorIsRequiredIfBadged() {
+        assertThrows(IllegalArgumentException.class,
+                () -> getMinimalBuilder()
+                        .setIconBadge(1)
+                        .setBadgeLabels(2)
+                        .createUserTypeDetails());
+    }
+
+    @Test
+    public void testUserTypeBuilder_badgeLabelIsRequiredIfBadged() {
+        assertThrows(IllegalArgumentException.class,
+                () -> getMinimalBuilder()
+                        .setIconBadge(1)
+                        .setBadgeColors(2)
+                        .createUserTypeDetails());
+    }
+
+    @Test
+    public void testCheckUserTypeConsistency() {
+        assertTrue(UserManagerService.checkUserTypeConsistency(FLAG_GUEST));
+        assertTrue(UserManagerService.checkUserTypeConsistency(FLAG_GUEST | FLAG_EPHEMERAL));
+        assertTrue(UserManagerService.checkUserTypeConsistency(FLAG_PROFILE));
+
+        assertFalse(UserManagerService.checkUserTypeConsistency(FLAG_DEMO | FLAG_RESTRICTED));
+        assertFalse(UserManagerService.checkUserTypeConsistency(FLAG_PROFILE | FLAG_SYSTEM));
+        assertFalse(UserManagerService.checkUserTypeConsistency(FLAG_PROFILE | FLAG_FULL));
+    }
+
+    @Test
+    public void testGetDefaultUserType() {
+        // Simple example.
+        assertEquals(UserManager.USER_TYPE_FULL_RESTRICTED,
+                UserInfo.getDefaultUserType(FLAG_RESTRICTED));
+
+        // Type plus a non-type flag.
+        assertEquals(UserManager.USER_TYPE_FULL_GUEST,
+                UserInfo.getDefaultUserType(FLAG_GUEST | FLAG_EPHEMERAL));
+
+        // Two types, which is illegal.
+        assertThrows(IllegalArgumentException.class,
+                () -> UserInfo.getDefaultUserType(FLAG_MANAGED_PROFILE | FLAG_GUEST));
+
+        // No type, which defaults to {@link UserManager#USER_TYPE_FULL_SECONDARY}.
+        assertEquals(UserManager.USER_TYPE_FULL_SECONDARY,
+                UserInfo.getDefaultUserType(FLAG_EPHEMERAL));
+    }
+
+    /** Returns a minimal {@link UserTypeDetails.Builder} that can legitimately be created. */
+    private UserTypeDetails.Builder getMinimalBuilder() {
+        return new UserTypeDetails.Builder().setName("name").setBaseType(FLAG_FULL);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index e9edba5..d071927 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.pm;
 
+import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -23,6 +24,7 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
+import android.content.res.Resources;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -196,6 +198,62 @@
         }
     }
 
+    /** Tests creating a FULL user via specifying userType. */
+    @MediumTest
+    public void testCreateUserViaTypes() throws Exception {
+        createUserWithTypeAndCheckFlags(UserManager.USER_TYPE_FULL_GUEST,
+                UserInfo.FLAG_GUEST | UserInfo.FLAG_FULL);
+
+        createUserWithTypeAndCheckFlags(UserManager.USER_TYPE_FULL_DEMO,
+                UserInfo.FLAG_DEMO | UserInfo.FLAG_FULL);
+
+        createUserWithTypeAndCheckFlags(UserManager.USER_TYPE_FULL_SECONDARY,
+                UserInfo.FLAG_FULL);
+    }
+
+    /** Tests creating a FULL user via specifying user flags. */
+    @MediumTest
+    public void testCreateUserViaFlags() throws Exception {
+        createUserWithFlagsAndCheckType(UserInfo.FLAG_GUEST, UserManager.USER_TYPE_FULL_GUEST,
+                UserInfo.FLAG_FULL);
+
+        createUserWithFlagsAndCheckType(0, UserManager.USER_TYPE_FULL_SECONDARY,
+                UserInfo.FLAG_FULL);
+
+        createUserWithFlagsAndCheckType(UserInfo.FLAG_FULL, UserManager.USER_TYPE_FULL_SECONDARY,
+                0);
+
+        createUserWithFlagsAndCheckType(UserInfo.FLAG_DEMO, UserManager.USER_TYPE_FULL_DEMO,
+                UserInfo.FLAG_FULL);
+    }
+
+    /** Creates a user of the given user type and checks that the result has the requiredFlags. */
+    private void createUserWithTypeAndCheckFlags(String userType,
+            @UserIdInt int requiredFlags) {
+        final UserInfo userInfo = createUser("Name", userType, 0);
+        assertEquals("Wrong user type", userType, userInfo.userType);
+        assertEquals(
+                "Flags " + userInfo.flags + " did not contain expected " + requiredFlags,
+                requiredFlags, userInfo.flags & requiredFlags);
+        removeUser(userInfo.id);
+    }
+
+    /**
+     * Creates a user of the given flags and checks that the result is of the expectedUserType type
+     * and that it has the expected flags (including both flags and any additionalRequiredFlags).
+     */
+    private void createUserWithFlagsAndCheckType(@UserIdInt int flags, String expectedUserType,
+            @UserIdInt int additionalRequiredFlags) {
+        final UserInfo userInfo = createUser("Name", flags);
+        assertEquals("Wrong user type", expectedUserType, userInfo.userType);
+        additionalRequiredFlags |= flags;
+        assertEquals(
+                "Flags " + userInfo.flags + " did not contain expected " + additionalRequiredFlags,
+                additionalRequiredFlags, userInfo.flags & additionalRequiredFlags);
+        removeUser(userInfo.id);
+    }
+
+
     @MediumTest
     public void testAddGuest() throws Exception {
         UserInfo userInfo1 = createUser("Guest 1", UserInfo.FLAG_GUEST);
@@ -234,7 +292,7 @@
         final int primaryUserId = mUserManager.getPrimaryUser().id;
 
         UserInfo userInfo = createProfileForUser("Profile",
-                UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
+                UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
         assertNotNull(userInfo);
         assertNull(mUserManager.getProfileParent(primaryUserId));
         UserInfo parentProfileInfo = mUserManager.getProfileParent(userInfo.id);
@@ -244,17 +302,61 @@
         assertNull(mUserManager.getProfileParent(primaryUserId));
     }
 
+    /** Test that UserManager returns the correct badge information for a managed profile. */
+    @MediumTest
+    public void testProfileTypeInformation() throws Exception {
+        final UserTypeDetails userTypeDetails =
+                UserTypeFactory.getUserTypes().get(UserManager.USER_TYPE_PROFILE_MANAGED);
+        assertNotNull("No " + UserManager.USER_TYPE_PROFILE_MANAGED + " type on device",
+                userTypeDetails);
+        assertEquals(UserManager.USER_TYPE_PROFILE_MANAGED, userTypeDetails.getName());
+
+        final int primaryUserId = mUserManager.getPrimaryUser().id;
+        UserInfo userInfo = createProfileForUser("Managed",
+                UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+        assertNotNull(userInfo);
+        final int userId = userInfo.id;
+        final UserHandle userHandle = new UserHandle(userId);
+
+        assertEquals(userTypeDetails.hasBadge(),
+                mUserManager.hasBadge(userId));
+        assertEquals(userTypeDetails.getIconBadge(),
+                mUserManager.getUserIconBadgeResId(userId));
+        assertEquals(userTypeDetails.getBadgePlain(),
+                mUserManager.getUserBadgeResId(userId));
+        assertEquals(userTypeDetails.getBadgeNoBackground(),
+                mUserManager.getUserBadgeNoBackgroundResId(userId));
+        assertEquals(userTypeDetails.isProfile(),
+                mUserManager.isProfile(userId));
+        assertEquals(userTypeDetails.getName(),
+                mUserManager.getUserTypeForUser(userHandle));
+
+        final int badgeIndex = userInfo.profileBadge;
+        assertEquals(
+                Resources.getSystem().getColor(userTypeDetails.getBadgeColor(badgeIndex), null),
+                mUserManager.getUserBadgeColor(userId));
+        assertEquals(
+                Resources.getSystem().getString(userTypeDetails.getBadgeLabel(badgeIndex), "Test"),
+                mUserManager.getBadgedLabelForUser("Test", userHandle));
+    }
+
     // Make sure only one managed profile can be created
     @MediumTest
     public void testAddManagedProfile() throws Exception {
         final int primaryUserId = mUserManager.getPrimaryUser().id;
         UserInfo userInfo1 = createProfileForUser("Managed 1",
-                UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
+                UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
         UserInfo userInfo2 = createProfileForUser("Managed 2",
-                UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
+                UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
 
         assertNotNull(userInfo1);
         assertNull(userInfo2);
+
+        assertEquals(userInfo1.userType, UserManager.USER_TYPE_PROFILE_MANAGED);
+        int requiredFlags = UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_PROFILE;
+        assertEquals("Wrong flags " + userInfo1.flags, requiredFlags,
+                userInfo1.flags & requiredFlags);
+
         // Verify that current user is not a managed profile
         assertFalse(mUserManager.isManagedProfile());
     }
@@ -264,7 +366,7 @@
     public void testAddManagedProfile_withDisallowedPackages() throws Exception {
         final int primaryUserId = mUserManager.getPrimaryUser().id;
         UserInfo userInfo1 = createProfileForUser("Managed1",
-                UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
+                UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
         // Verify that the packagesToVerify are installed by default.
         for (String pkg : PACKAGES) {
             assertTrue("Package should be installed in managed profile: " + pkg,
@@ -273,7 +375,7 @@
         removeUser(userInfo1.id);
 
         UserInfo userInfo2 = createProfileForUser("Managed2",
-                UserInfo.FLAG_MANAGED_PROFILE, primaryUserId, PACKAGES);
+                UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId, PACKAGES);
         // Verify that the packagesToVerify are not installed by default.
         for (String pkg : PACKAGES) {
             assertFalse("Package should not be installed in managed profile when disallowed: "
@@ -287,7 +389,7 @@
     public void testAddManagedProfile_disallowedPackagesInstalledLater() throws Exception {
         final int primaryUserId = mUserManager.getPrimaryUser().id;
         UserInfo userInfo = createProfileForUser("Managed",
-                UserInfo.FLAG_MANAGED_PROFILE, primaryUserId, PACKAGES);
+                UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId, PACKAGES);
         // Verify that the packagesToVerify are not installed by default.
         for (String pkg : PACKAGES) {
             assertFalse("Package should not be installed in managed profile when disallowed: "
@@ -326,7 +428,7 @@
                 primaryUserHandle);
         try {
             UserInfo userInfo = createProfileForUser("Managed",
-                    UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
+                    UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
             assertNull(userInfo);
         } finally {
             mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, false,
@@ -343,7 +445,7 @@
                 primaryUserHandle);
         try {
             UserInfo userInfo = createProfileEvenWhenDisallowedForUser("Managed",
-                    UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
+                    UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
             assertNotNull(userInfo);
         } finally {
             mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, false,
@@ -359,7 +461,7 @@
         mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER, true, primaryUserHandle);
         try {
             UserInfo userInfo = createProfileForUser("Managed",
-                    UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
+                    UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
             assertNotNull(userInfo);
         } finally {
             mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER, false,
@@ -396,7 +498,7 @@
         final int primaryUserId = mUserManager.getPrimaryUser().id;
         final long startTime = System.currentTimeMillis();
         UserInfo profile = createProfileForUser("Managed 1",
-                UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
+                UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
         final long endTime = System.currentTimeMillis();
         assertNotNull(profile);
         if (System.currentTimeMillis() > EPOCH_PLUS_30_YEARS) {
@@ -663,24 +765,32 @@
         return user;
     }
 
-    private UserInfo createProfileForUser(String name, int flags, int userHandle) {
-        return createProfileForUser(name, flags, userHandle, null);
+    private UserInfo createUser(String name, String userType, int flags) {
+        UserInfo user = mUserManager.createUser(name, userType, flags);
+        if (user != null) {
+            usersToRemove.add(user.id);
+        }
+        return user;
     }
 
-    private UserInfo createProfileForUser(String name, int flags, int userHandle,
+    private UserInfo createProfileForUser(String name, String userType, int userHandle) {
+        return createProfileForUser(name, userType, userHandle, null);
+    }
+
+    private UserInfo createProfileForUser(String name, String userType, int userHandle,
             String[] disallowedPackages) {
         UserInfo profile = mUserManager.createProfileForUser(
-                name, flags, userHandle, disallowedPackages);
+                name, userType, 0, userHandle, disallowedPackages);
         if (profile != null) {
             usersToRemove.add(profile.id);
         }
         return profile;
     }
 
-    private UserInfo createProfileEvenWhenDisallowedForUser(String name, int flags,
+    private UserInfo createProfileEvenWhenDisallowedForUser(String name, String userType,
             int userHandle) {
         UserInfo profile = mUserManager.createProfileForUserEvenWhenDisallowed(
-                name, flags, userHandle, null);
+                name, userType, 0, userHandle, null);
         if (profile != null) {
             usersToRemove.add(profile.id);
         }
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
index f0b0328..f492932 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
@@ -147,7 +147,7 @@
 
         final ArrayMap<String, Integer> expectedOutput = getNewPackageToWhitelistedFlagsMap();
         expectedOutput.put("com.android.package1",
-                UserInfo.PROFILE_FLAGS_MASK | FLAG_SYSTEM | FLAG_GUEST);
+                UserInfo.FLAG_PROFILE | FLAG_SYSTEM | FLAG_GUEST);
         expectedOutput.put("com.android.package2",
                 UserInfo.FLAG_MANAGED_PROFILE);
 
@@ -376,9 +376,9 @@
 
     /** Sets the whitelist mode to the desired value via adb's setprop. */
     private void setUserTypePackageWhitelistMode(int mode) {
-        UiDevice mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
         try {
-            String result = mUiDevice.executeShellCommand(String.format("setprop %s %d",
+            String result = uiDevice.executeShellCommand(String.format("setprop %s %d",
                     PACKAGE_WHITELIST_MODE_PROP, mode));
             assertFalse("Failed to set sysprop " + PACKAGE_WHITELIST_MODE_PROP + ": " + result,
                     result != null && result.contains("Failed"));
@@ -390,7 +390,7 @@
     private ArrayMap<String, Integer> getNewPackageToWhitelistedFlagsMap() {
         final ArrayMap<String, Integer> pkgFlagMap = new ArrayMap<>();
         // "android" is always treated as whitelisted, regardless of the xml file.
-        pkgFlagMap.put("android", FLAG_SYSTEM | UserInfo.FLAG_FULL | UserInfo.PROFILE_FLAGS_MASK);
+        pkgFlagMap.put("android", FLAG_SYSTEM | UserInfo.FLAG_FULL | UserInfo.FLAG_PROFILE);
         return pkgFlagMap;
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserTests.java b/services/tests/servicestests/src/com/android/server/pm/UserTests.java
new file mode 100644
index 0000000..525382d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/UserTests.java
@@ -0,0 +1,37 @@
+/*
+ * 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.pm;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+        UserDataPreparerTest.class,
+        UserLifecycleStressTest.class,
+        UserManagerServiceCreateProfileTest.class,
+        UserManagerServiceIdRecyclingTest.class,
+        UserManagerServiceTest.class,
+        UserManagerServiceUserInfoTest.class,
+        UserManagerServiceUserTypeTest.class,
+        UserManagerTest.class,
+        UserRestrictionsUtilsTest.class,
+        UserSystemPackageInstallerTest.class,
+})
+public class UserTests {
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 88de250..592f4ec 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -33,9 +33,11 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isA;
 import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -62,11 +64,13 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.test.mock.MockContentResolver;
 import android.view.Display;
 
 import androidx.test.InstrumentationRegistry;
 
 import com.android.internal.app.IBatteryStats;
+import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.lights.LightsManager;
@@ -109,6 +113,9 @@
     @Mock private WirelessChargerDetector mWirelessChargerDetectorMock;
     @Mock private AmbientDisplayConfiguration mAmbientDisplayConfigurationMock;
 
+    @Mock
+    private InattentiveSleepWarningController mInattentiveSleepWarningControllerMock;
+
     private PowerManagerService mService;
     private PowerSaveState mPowerSaveState;
     private DisplayPowerRequest mDisplayPowerRequest;
@@ -149,6 +156,9 @@
         when(mBatterySaverPolicyMock.getBatterySaverPolicy(
                 eq(PowerManager.ServiceType.SCREEN_BRIGHTNESS)))
                 .thenReturn(mPowerSaveState);
+        when(mBatteryManagerInternalMock.isPowered(anyInt())).thenReturn(false);
+        when(mInattentiveSleepWarningControllerMock.isShown()).thenReturn(false);
+        when(mDisplayManagerInternalMock.requestPowerState(any(), anyBoolean())).thenReturn(true);
 
         mDisplayPowerRequest = new DisplayPowerRequest();
         addLocalServiceMock(LightsManager.class, mLightsManagerMock);
@@ -161,7 +171,12 @@
         mResourcesSpy = spy(mContextSpy.getResources());
         when(mContextSpy.getResources()).thenReturn(mResourcesSpy);
 
-        when(mDisplayManagerInternalMock.requestPowerState(any(), anyBoolean())).thenReturn(true);
+        MockContentResolver cr = new MockContentResolver(mContextSpy);
+        cr.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        when(mContextSpy.getContentResolver()).thenReturn(cr);
+
+        Settings.Global.putInt(mContextSpy.getContentResolver(),
+                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
     }
 
     private PowerManagerService createService() {
@@ -198,6 +213,11 @@
             AmbientDisplayConfiguration createAmbientDisplayConfiguration(Context context) {
                 return mAmbientDisplayConfigurationMock;
             }
+
+            @Override
+            InattentiveSleepWarningController createInattentiveSleepWarningController() {
+                return mInattentiveSleepWarningControllerMock;
+            }
         });
         return mService;
     }
@@ -208,8 +228,12 @@
         LocalServices.removeServiceForTest(DisplayManagerInternal.class);
         LocalServices.removeServiceForTest(BatteryManagerInternal.class);
         LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+
         Settings.Global.putInt(
                 mContextSpy.getContentResolver(), Settings.Global.THEATER_MODE_ON, 0);
+        setAttentiveTimeout(-1);
+        Settings.Global.putInt(mContextSpy.getContentResolver(),
+                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
     }
 
     /**
@@ -263,12 +287,30 @@
 
     private void setPluggedIn(boolean isPluggedIn) {
         // Set the callback to return the new state
-        when(mBatteryManagerInternalMock.isPowered(BatteryManager.BATTERY_PLUGGED_ANY))
+        when(mBatteryManagerInternalMock.isPowered(anyInt()))
                 .thenReturn(isPluggedIn);
         // Trigger PowerManager to reread the plug-in state
         mBatteryReceiver.onReceive(mContextSpy, new Intent(Intent.ACTION_BATTERY_CHANGED));
     }
 
+    private void setAttentiveTimeout(int attentiveTimeoutMillis) {
+        Settings.Secure.putInt(
+                mContextSpy.getContentResolver(), Settings.Secure.ATTENTIVE_TIMEOUT,
+                attentiveTimeoutMillis);
+    }
+
+    private void setAttentiveWarningDuration(int attentiveWarningDurationMillis) {
+        when(mResourcesSpy.getInteger(
+                com.android.internal.R.integer.config_attentiveWarningDuration))
+                .thenReturn(attentiveWarningDurationMillis);
+    }
+
+    private void setMinimumScreenOffTimeoutConfig(int minimumScreenOffTimeoutConfigMillis) {
+        when(mResourcesSpy.getInteger(
+                com.android.internal.R.integer.config_minimumScreenOffTimeout))
+                .thenReturn(minimumScreenOffTimeoutConfigMillis);
+    }
+
     @Test
     public void testUpdatePowerScreenPolicy_UpdateDisplayPowerRequest() {
         createService();
@@ -615,4 +657,97 @@
                 .setDozeOverrideFromDreamManager(Display.STATE_ON, PowerManager.BRIGHTNESS_DEFAULT);
         assertTrue(isAcquired[0]);
     }
+
+    @Test
+    public void testInattentiveSleep_hideWarningIfStayOnIsEnabledAndPluggedIn() throws Exception {
+        setAttentiveTimeout(15000);
+        Settings.Global.putInt(mContextSpy.getContentResolver(),
+                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC);
+
+        createService();
+        startSystem();
+
+        verify(mInattentiveSleepWarningControllerMock, times(1)).show();
+        verify(mInattentiveSleepWarningControllerMock, never()).dismiss();
+        when(mInattentiveSleepWarningControllerMock.isShown()).thenReturn(true);
+
+        setPluggedIn(true);
+        verify(mInattentiveSleepWarningControllerMock, atLeastOnce()).dismiss();
+    }
+
+    @Test
+    public void testInattentive_userActivityDismissesWarning() throws Exception {
+        setMinimumScreenOffTimeoutConfig(5);
+        setAttentiveWarningDuration(30);
+        setAttentiveTimeout(100);
+
+        createService();
+        startSystem();
+
+        mService.getBinderServiceInstance().userActivity(SystemClock.uptimeMillis(),
+                PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
+        verify(mInattentiveSleepWarningControllerMock, never()).show();
+
+        SystemClock.sleep(70);
+        verify(mInattentiveSleepWarningControllerMock, times(1)).show();
+        verify(mInattentiveSleepWarningControllerMock, never()).dismiss();
+        when(mInattentiveSleepWarningControllerMock.isShown()).thenReturn(true);
+
+        mService.getBinderServiceInstance().userActivity(SystemClock.uptimeMillis(),
+                PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
+        verify(mInattentiveSleepWarningControllerMock, times(1)).dismiss();
+    }
+
+    @Test
+    public void testInattentiveSleep_warningHiddenAfterWakingUp() throws Exception {
+        setMinimumScreenOffTimeoutConfig(5);
+        setAttentiveWarningDuration(20);
+        setAttentiveTimeout(30);
+
+        createService();
+        startSystem();
+        SystemClock.sleep(10);
+        verify(mInattentiveSleepWarningControllerMock, atLeastOnce()).show();
+        when(mInattentiveSleepWarningControllerMock.isShown()).thenReturn(true);
+        SystemClock.sleep(30);
+        forceAwake();
+        verify(mInattentiveSleepWarningControllerMock, atLeastOnce()).dismiss();
+    }
+
+    @Test
+    public void testInattentiveSleep_noWarningShownIfInattentiveSleepDisabled() throws Exception {
+        setAttentiveTimeout(-1);
+        createService();
+        startSystem();
+        verify(mInattentiveSleepWarningControllerMock, never()).show();
+    }
+
+    @Test
+    public void testInattentiveSleep_goesToSleepAfterTimeout() throws Exception {
+        setMinimumScreenOffTimeoutConfig(5);
+        setAttentiveTimeout(5);
+        createService();
+        startSystem();
+        SystemClock.sleep(8);
+        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+    }
+
+    @Test
+    public void testInattentiveSleep_goesToSleepWithWakeLock() throws Exception {
+        final String pkg = mContextSpy.getOpPackageName();
+        final Binder token = new Binder();
+        final String tag = "sleep_testWithWakeLock";
+
+        setMinimumScreenOffTimeoutConfig(5);
+        setAttentiveTimeout(10);
+        createService();
+        startSystem();
+
+        mService.getBinderServiceInstance().acquireWakeLock(token,
+                PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg,
+                null /* workSource */, null /* historyTag */);
+
+        SystemClock.sleep(11);
+        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
index 9df7b45..24db657 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
@@ -38,12 +38,7 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.when;
 
-import android.app.TaskStackListener;
-import android.content.pm.ActivityInfo;
-import android.content.res.Configuration;
-import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
@@ -51,10 +46,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.ArrayList;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-
 /**
  * Tests for the {@link ActivityDisplay} class.
  *
@@ -181,7 +172,7 @@
         final ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
         final KeyguardController keyguard = mSupervisor.getKeyguardController();
         final ActivityStack stack = new StackBuilder(mRootActivityContainer).build();
-        final ActivityRecord activity = stack.getTopActivity();
+        final ActivityRecord activity = stack.getTopNonFinishingActivity();
 
         // Create empty stack on top.
         final ActivityStack emptyStack =
@@ -237,7 +228,7 @@
         display.positionChildAtTop(alwaysOnTopStack, false /* includingParents */);
         assertTrue(alwaysOnTopStack.isAlwaysOnTop());
         // Ensure always on top state is synced to the children of the stack.
-        assertTrue(alwaysOnTopStack.getTopActivity().isAlwaysOnTop());
+        assertTrue(alwaysOnTopStack.getTopNonFinishingActivity().isAlwaysOnTop());
         assertEquals(alwaysOnTopStack, display.getTopStack());
 
         final ActivityStack pinnedStack = display.createStack(
@@ -331,50 +322,4 @@
         verify(mSupervisor).removeTaskByIdLocked(eq(task1.mTaskId), anyBoolean(), anyBoolean(),
                 any());
     }
-
-    /**
-     * Ensures that {@link TaskStackListener} can receive callback about the activity in size
-     * compatibility mode.
-     */
-    @Test
-    public void testHandleActivitySizeCompatMode() throws Exception {
-        final ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
-        final ActivityRecord activity = createFullscreenStackWithSimpleActivityAt(
-                display).topRunningActivityLocked();
-        activity.setState(ActivityStack.ActivityState.RESUMED, "testHandleActivitySizeCompatMode");
-        when(activity.getRequestedOrientation()).thenReturn(
-                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-        activity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
-        activity.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-        activity.visible = true;
-        activity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
-
-        final ArrayList<CompletableFuture<IBinder>> resultWrapper = new ArrayList<>();
-        mService.getTaskChangeNotificationController().registerTaskStackListener(
-                new TaskStackListener() {
-                    @Override
-                    public void onSizeCompatModeActivityChanged(int displayId,
-                            IBinder activityToken) {
-                        resultWrapper.get(0).complete(activityToken);
-                    }
-                });
-
-        resultWrapper.add(new CompletableFuture<>());
-
-        // resize the display to exercise size-compat mode
-        final DisplayContent displayContent = display.mDisplayContent;
-        displayContent.mBaseDisplayHeight = (int) (0.8f * displayContent.mBaseDisplayHeight);
-        Configuration c = new Configuration();
-        displayContent.computeScreenConfiguration(c);
-        display.onRequestedOverrideConfigurationChanged(c);
-
-        assertEquals(activity.appToken, resultWrapper.get(0).get(2, TimeUnit.SECONDS));
-
-        // Expect null token when switching to non-size-compat mode activity.
-        activity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
-        resultWrapper.set(0, new CompletableFuture<>());
-        display.handleActivitySizeCompatModeIfNeeded(activity);
-
-        assertNull(resultWrapper.get(0).get(2, TimeUnit.SECONDS));
-    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index c51a46a..6c63d41 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -18,24 +18,18 @@
 
 import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.os.Process.NOBODY_UID;
 import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.Surface.ROTATION_0;
-import static android.view.Surface.ROTATION_90;
 import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeast;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
@@ -61,18 +55,13 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.when;
 
-import android.app.ActivityManager;
-import android.app.ActivityManagerInternal;
 import android.app.ActivityOptions;
-import android.app.WindowConfiguration;
 import android.app.servertransaction.ActivityConfigurationChangeItem;
 import android.app.servertransaction.ClientTransaction;
 import android.app.servertransaction.PauseActivityItem;
@@ -80,13 +69,11 @@
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.PersistableBundle;
 import android.platform.test.annotations.Presubmit;
 import android.util.MergedConfiguration;
 import android.util.MutableBoolean;
-import android.view.DisplayInfo;
 import android.view.IRemoteAnimationFinishedCallback;
 import android.view.IRemoteAnimationRunner.Stub;
 import android.view.RemoteAnimationAdapter;
@@ -120,7 +107,7 @@
     public void setUp() throws Exception {
         mStack = new StackBuilder(mRootActivityContainer).build();
         mTask = mStack.getChildAt(0);
-        mActivity = mTask.getTopActivity();
+        mActivity = mTask.getTopNonFinishingActivity();
 
         doReturn(false).when(mService).isBooting();
         doReturn(true).when(mService).isBooted();
@@ -219,23 +206,6 @@
     }
 
     @Test
-    public void testRestartProcessIfVisible() {
-        doNothing().when(mSupervisor).scheduleRestartTimeout(mActivity);
-        mActivity.visible = true;
-        mActivity.setSavedState(null /* savedState */);
-        mActivity.setState(ActivityStack.ActivityState.RESUMED, "testRestart");
-        prepareFixedAspectRatioUnresizableActivity();
-
-        final Rect originalOverrideBounds = new Rect(mActivity.getBounds());
-        setupDisplayAndParentSize(600, 1200);
-        // The visible activity should recompute configuration according to the last parent bounds.
-        mService.restartActivityProcessIfVisible(mActivity.appToken);
-
-        assertEquals(ActivityStack.ActivityState.RESTARTING_PROCESS, mActivity.getState());
-        assertNotEquals(originalOverrideBounds, mActivity.getBounds());
-    }
-
-    @Test
     public void testsApplyOptionsLocked() {
         ActivityOptions activityOptions = ActivityOptions.makeBasic();
 
@@ -484,214 +454,6 @@
     }
 
     @Test
-    public void testSizeCompatMode_KeepBoundsWhenChangingFromFreeformToFullscreen() {
-        setupDisplayContentForCompatDisplayInsets();
-
-        // put display in freeform mode
-        ActivityDisplay display = mActivity.getDisplay();
-        final Configuration c = new Configuration(display.getRequestedOverrideConfiguration());
-        c.windowConfiguration.setBounds(new Rect(0, 0, 2000, 1000));
-        c.densityDpi = 300;
-        c.windowConfiguration.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
-        display.onRequestedOverrideConfigurationChanged(c);
-
-        // launch compat activity in freeform and store bounds
-        when(mActivity.getRequestedOrientation()).thenReturn(
-                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-        mTask.getRequestedOverrideConfiguration().orientation = Configuration.ORIENTATION_PORTRAIT;
-        mTask.setBounds(100, 100, 400, 600);
-        mActivity.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-        mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
-        mActivity.visible = true;
-        ensureActivityConfiguration();
-
-        final Rect bounds = new Rect(mActivity.getBounds());
-        final int density = mActivity.getConfiguration().densityDpi;
-
-        // change display configuration to fullscreen
-        c.windowConfiguration.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
-        display.onRequestedOverrideConfigurationChanged(c);
-
-        // check if dimensions stay the same
-        assertTrue(mActivity.inSizeCompatMode());
-        assertEquals(bounds.width(), mActivity.getBounds().width());
-        assertEquals(bounds.height(), mActivity.getBounds().height());
-        assertEquals(density, mActivity.getConfiguration().densityDpi);
-        assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN, mActivity.getWindowingMode());
-    }
-
-    @Test
-    public void testSizeCompatMode_FixedAspectRatioBoundsWithDecor() {
-        setupDisplayContentForCompatDisplayInsets();
-        final int decorHeight = 200; // e.g. The device has cutout.
-        final DisplayPolicy policy = setupDisplayAndParentSize(600, 800).getDisplayPolicy();
-        spyOn(policy);
-        doAnswer(invocationOnMock -> {
-            final int rotation = invocationOnMock.<Integer>getArgument(0);
-            final Rect insets = invocationOnMock.<Rect>getArgument(4);
-            if (rotation == ROTATION_0) {
-                insets.top = decorHeight;
-            } else if (rotation == ROTATION_90) {
-                insets.left = decorHeight;
-            }
-            return null;
-        }).when(policy).getNonDecorInsetsLw(anyInt() /* rotation */, anyInt() /* width */,
-                anyInt() /* height */, any() /* displayCutout */, any() /* outInsets */);
-        // set appBounds to incorporate decor
-        final Configuration c =
-                new Configuration(mStack.getDisplay().getRequestedOverrideConfiguration());
-        c.windowConfiguration.getAppBounds().top = decorHeight;
-        mStack.getDisplay().onRequestedOverrideConfigurationChanged(c);
-
-        doReturn(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
-                .when(mActivity).getRequestedOrientation();
-        mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
-        mActivity.info.minAspectRatio = mActivity.info.maxAspectRatio = 1;
-        mActivity.visible = true;
-        ensureActivityConfiguration();
-        // The parent configuration doesn't change since the first resolved configuration, so the
-        // activity shouldn't be in the size compatibility mode.
-        assertFalse(mActivity.inSizeCompatMode());
-
-        final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds();
-        // Ensure the app bounds keep the declared aspect ratio.
-        assertEquals(appBounds.width(), appBounds.height());
-        // The decor height should be a part of the effective bounds.
-        assertEquals(mActivity.getBounds().height(), appBounds.height() + decorHeight);
-
-        mTask.getConfiguration().windowConfiguration.setRotation(ROTATION_90);
-        mActivity.onConfigurationChanged(mTask.getConfiguration());
-        // After changing orientation, the aspect ratio should be the same.
-        assertEquals(appBounds.width(), appBounds.height());
-        // The decor height will be included in width.
-        assertEquals(mActivity.getBounds().width(), appBounds.width() + decorHeight);
-    }
-
-    @Test
-    public void testSizeCompatMode_FixedScreenConfigurationWhenMovingToDisplay() {
-        // Initialize different bounds on a new display.
-        final Rect newDisplayBounds = new Rect(0, 0, 1000, 2000);
-        DisplayInfo info = new DisplayInfo();
-        mService.mContext.getDisplay().getDisplayInfo(info);
-        info.logicalWidth = newDisplayBounds.width();
-        info.logicalHeight = newDisplayBounds.height();
-        info.logicalDensityDpi = 300;
-
-        final ActivityDisplay newDisplay =
-                addNewActivityDisplayAt(info, ActivityDisplay.POSITION_TOP);
-
-        final Configuration c =
-                new Configuration(mStack.getDisplay().getRequestedOverrideConfiguration());
-        c.densityDpi = 200;
-        mStack.getDisplay().onRequestedOverrideConfigurationChanged(c);
-        mActivity = new ActivityBuilder(mService)
-                .setTask(mTask)
-                .setResizeMode(RESIZE_MODE_UNRESIZEABLE)
-                .setMaxAspectRatio(1.5f)
-                .build();
-        mActivity.visible = true;
-
-        final Rect originalBounds = new Rect(mActivity.getBounds());
-        final int originalDpi = mActivity.getConfiguration().densityDpi;
-
-        // Move the non-resizable activity to the new display.
-        mStack.reparent(newDisplay.mDisplayContent, true /* onTop */);
-
-        assertEquals(originalBounds.width(),
-                mActivity.getWindowConfiguration().getBounds().width());
-        assertEquals(originalBounds.height(),
-                mActivity.getWindowConfiguration().getBounds().height());
-        assertEquals(originalDpi, mActivity.getConfiguration().densityDpi);
-        assertTrue(mActivity.inSizeCompatMode());
-    }
-
-    @Test
-    public void testSizeCompatMode_FixedScreenBoundsWhenDisplaySizeChanged() {
-        setupDisplayContentForCompatDisplayInsets();
-        when(mActivity.getRequestedOrientation()).thenReturn(
-                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-        mTask.getWindowConfiguration().setAppBounds(mStack.getDisplay().getBounds());
-        mTask.getRequestedOverrideConfiguration().orientation = Configuration.ORIENTATION_PORTRAIT;
-        mActivity.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-        mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
-        mActivity.visible = true;
-
-        ensureActivityConfiguration();
-        final Rect originalBounds = new Rect(mActivity.getBounds());
-
-        // Change the size of current display.
-        setupDisplayAndParentSize(1000, 2000);
-        ensureActivityConfiguration();
-
-        assertEquals(originalBounds.width(),
-                mActivity.getWindowConfiguration().getBounds().width());
-        assertEquals(originalBounds.height(),
-                mActivity.getWindowConfiguration().getBounds().height());
-        assertTrue(mActivity.inSizeCompatMode());
-    }
-
-    @Test
-    public void testSizeCompatMode_FixedScreenLayoutSizeBits() {
-        final int fixedScreenLayout = Configuration.SCREENLAYOUT_LONG_NO
-                | Configuration.SCREENLAYOUT_SIZE_NORMAL;
-        final int layoutMask = Configuration.SCREENLAYOUT_LONG_MASK
-                | Configuration.SCREENLAYOUT_SIZE_MASK
-                | Configuration.SCREENLAYOUT_LAYOUTDIR_MASK;
-        mTask.getRequestedOverrideConfiguration().screenLayout = fixedScreenLayout
-                | Configuration.SCREENLAYOUT_LAYOUTDIR_LTR;
-        prepareFixedAspectRatioUnresizableActivity();
-
-        // The initial configuration should inherit from parent.
-        assertEquals(mTask.getConfiguration().screenLayout & layoutMask,
-                mActivity.getConfiguration().screenLayout & layoutMask);
-
-        mTask.getConfiguration().screenLayout = Configuration.SCREENLAYOUT_LAYOUTDIR_RTL
-                | Configuration.SCREENLAYOUT_LONG_YES | Configuration.SCREENLAYOUT_SIZE_LARGE;
-        mActivity.onConfigurationChanged(mTask.getConfiguration());
-
-        // The size and aspect ratio bits don't change, but the layout direction should be updated.
-        assertEquals(fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_RTL,
-                mActivity.getConfiguration().screenLayout & layoutMask);
-    }
-
-    @Test
-    public void testSizeCompatMode_ResetNonVisibleActivity() {
-        final ActivityDisplay display = mStack.getDisplay();
-        spyOn(display);
-
-        prepareFixedAspectRatioUnresizableActivity();
-        mActivity.setState(STOPPED, "testSizeCompatMode");
-        mActivity.visible = false;
-        mActivity.app.setReportedProcState(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY);
-        // Make the parent bounds to be different so the activity is in size compatibility mode.
-        setupDisplayAndParentSize(600, 1200);
-
-        // Simulate the display changes orientation.
-        doReturn(ActivityInfo.CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION
-                | ActivityInfo.CONFIG_WINDOW_CONFIGURATION)
-                        .when(display).getLastOverrideConfigurationChanges();
-        mActivity.onConfigurationChanged(mTask.getConfiguration());
-        when(display.getLastOverrideConfigurationChanges()).thenCallRealMethod();
-        // The override configuration should not change so it is still in size compatibility mode.
-        assertTrue(mActivity.inSizeCompatMode());
-
-        // Change display density
-        final DisplayContent displayContent = mStack.getDisplay().mDisplayContent;
-        displayContent.mBaseDisplayDensity = (int) (0.7f * displayContent.mBaseDisplayDensity);
-        final Configuration c = new Configuration();
-        displayContent.computeScreenConfiguration(c);
-        mService.mAmInternal = mock(ActivityManagerInternal.class);
-        mStack.getDisplay().onRequestedOverrideConfigurationChanged(c);
-
-        // The override configuration should be reset and the activity's process will be killed.
-        assertFalse(mActivity.inSizeCompatMode());
-        verify(mActivity).restartProcessIfVisible();
-        waitHandlerIdle(mService.mH);
-        verify(mService.mAmInternal).killProcess(
-                eq(mActivity.app.mName), eq(mActivity.app.mUid), anyString());
-    }
-
-    @Test
     public void testTakeOptions() {
         ActivityOptions opts = ActivityOptions.makeRemoteAnimation(
                 new RemoteAnimationAdapter(new Stub() {
@@ -1015,7 +777,7 @@
         // Simulates that {@code currentTop} starts an existing activity from background (so its
         // state is stopped) and the starting flow just goes to place it at top.
         final ActivityStack nextStack = new StackBuilder(mRootActivityContainer).build();
-        final ActivityRecord nextTop = nextStack.getTopActivity();
+        final ActivityRecord nextTop = nextStack.getTopNonFinishingActivity();
         nextTop.setState(STOPPED, "test");
 
         mStack.mPausingActivity = currentTop;
@@ -1340,33 +1102,4 @@
 
         verify(mActivity).removeFromHistory(anyString());
     }
-
-    /** Setup {@link #mActivity} as a size-compat-mode-able activity without fixed orientation. */
-    private void prepareFixedAspectRatioUnresizableActivity() {
-        setupDisplayContentForCompatDisplayInsets();
-        mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
-        mActivity.info.maxAspectRatio = 1.5f;
-        mActivity.visible = true;
-        ensureActivityConfiguration();
-    }
-
-    private void setupDisplayContentForCompatDisplayInsets() {
-        final Rect displayBounds = mStack.getDisplay().getBounds();
-        setupDisplayAndParentSize(displayBounds.width(), displayBounds.height());
-    }
-
-    private DisplayContent setupDisplayAndParentSize(int width, int height) {
-        final DisplayContent displayContent = mStack.getDisplay().mDisplayContent;
-        displayContent.mBaseDisplayWidth = width;
-        displayContent.mBaseDisplayHeight = height;
-        final Configuration c =
-                new Configuration(mStack.getDisplay().getRequestedOverrideConfiguration());
-        c.windowConfiguration.setBounds(new Rect(0, 0, width, height));
-        c.windowConfiguration.setAppBounds(0, 0, width, height);
-        c.windowConfiguration.setRotation(ROTATION_0);
-        c.orientation = width > height
-                ? Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT;
-        mStack.getDisplay().onRequestedOverrideConfigurationChanged(c);
-        return displayContent;
-    }
 }
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 128ed2a..0219539 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
@@ -115,7 +115,7 @@
         final ActivityDisplay newDisplay = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
         final ActivityStack stack = new StackBuilder(mRootActivityContainer)
                 .setDisplay(newDisplay).build();
-        final ActivityRecord unresizableActivity = stack.getTopActivity();
+        final ActivityRecord unresizableActivity = stack.getTopNonFinishingActivity();
         final Task task = unresizableActivity.getTask();
         unresizableActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
         task.setResizeMode(unresizableActivity.info.resizeMode);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index d0e07b6..aa9dd9d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -243,8 +243,8 @@
                 new RootActivityContainer.FindTaskResult();
         mStack.findTaskLocked(r, result);
 
-        assertEquals(r, task.getTopActivity(false /* includeOverlays */));
-        assertEquals(taskOverlay, task.getTopActivity(true /* includeOverlays */));
+        assertEquals(r, task.getTopNonFinishingActivity(false /* includeOverlays */));
+        assertEquals(taskOverlay, task.getTopNonFinishingActivity(true /* includeOverlays */));
         assertNotNull(result.mRecord);
     }
 
@@ -1006,7 +1006,7 @@
 
         // There is still an activity1 in stack1 so the activity2 should be added to finishing list
         // that will be destroyed until idle.
-        stack2.getTopActivity().visible = true;
+        stack2.getTopNonFinishingActivity().visible = true;
         final ActivityRecord activity2 = finishTopActivity(stack2);
         assertEquals(STOPPING, activity2.getState());
         assertThat(mSupervisor.mStoppingActivities).contains(activity2);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 39aa51a..e9546a2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -24,6 +25,7 @@
 import static org.junit.Assert.assertTrue;
 
 import android.app.Activity;
+import android.app.ActivityManager;
 import android.graphics.Rect;
 import android.view.WindowContainerTransaction;
 
@@ -53,7 +55,7 @@
     @Test
     public void testActivityFinish() {
         final ActivityStack stack = new StackBuilder(mRootActivityContainer).build();
-        final ActivityRecord activity = stack.getChildAt(0).getTopActivity();
+        final ActivityRecord activity = stack.getChildAt(0).getTopNonFinishingActivity();
         assertTrue("Activity must be finished", mService.finishActivity(activity.appToken,
                 0 /* resultCode */, null /* resultData */,
                 Activity.DONT_FINISH_TASK_WITH_ACTIVITY));
@@ -76,5 +78,20 @@
         mService.applyContainerTransaction(t);
         assertEquals(newBounds, task.getBounds());
     }
+
+    @Test
+    public void testStackTransaction() {
+        removeGlobalMinSizeRestriction();
+        final ActivityStack stack = new StackBuilder(mRootActivityContainer)
+                .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
+        ActivityManager.StackInfo info =
+                mService.getStackInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
+        WindowContainerTransaction t = new WindowContainerTransaction();
+        assertEquals(stack.mRemoteToken, info.stackToken);
+        Rect newBounds = new Rect(10, 10, 100, 100);
+        t.setBounds(info.stackToken, new Rect(10, 10, 100, 100));
+        mService.applyContainerTransaction(t);
+        assertEquals(newBounds, stack.getBounds());
+    }
 }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
index b6eaab7..c6203c5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
@@ -37,7 +37,7 @@
 import org.mockito.MockitoAnnotations;
 
 /**
- * Tests for the {@link TaskStack} class.
+ * Tests for the {@link ActivityStack} class.
  *
  * Build/Install/Run:
  *  atest FrameworksServicesTests:AnimatingActivityRegistryTest
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
index 6ee9621..fc94c5e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
@@ -28,7 +28,6 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-import android.graphics.Rect;
 import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
 import android.view.Display;
@@ -55,7 +54,7 @@
 @RunWith(WindowTestRunner.class)
 public class AppChangeTransitionTests extends WindowTestsBase {
 
-    private TaskStack mStack;
+    private ActivityStack mStack;
     private Task mTask;
     private ActivityRecord mActivity;
 
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 9f4143f..571f214 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -711,18 +711,14 @@
         final ActivityStack stack =
                 new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
                         .setDisplay(dc.mActivityDisplay).build();
-        final ActivityRecord activity = stack.topTask().getTopActivity();
+        final ActivityRecord activity = stack.topTask().getTopNonFinishingActivity();
 
         activity.setRequestedOrientation(newOrientation);
 
-        final ArgumentCaptor<Configuration> captor = ArgumentCaptor.forClass(Configuration.class);
-        verify(dc.mActivityDisplay).updateDisplayOverrideConfigurationLocked(captor.capture(),
-                same(activity), anyBoolean(), same(null));
-        final Configuration newDisplayConfig = captor.getValue();
         final int expectedOrientation = newOrientation == SCREEN_ORIENTATION_PORTRAIT
                 ? Configuration.ORIENTATION_PORTRAIT
                 : Configuration.ORIENTATION_LANDSCAPE;
-        assertEquals(expectedOrientation, newDisplayConfig.orientation);
+        assertEquals(expectedOrientation, dc.getConfiguration().orientation);
     }
 
     @Test
@@ -737,7 +733,7 @@
         final ActivityStack stack =
                 new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
                         .setDisplay(dc.mActivityDisplay).build();
-        final ActivityRecord activity = stack.topTask().getTopActivity();
+        final ActivityRecord activity = stack.topTask().getTopNonFinishingActivity();
 
         activity.setRequestedOrientation(newOrientation);
 
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 e0ffb0d..4f2d5d2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -61,6 +61,7 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.UserManager;
 import android.platform.test.annotations.Presubmit;
 import android.util.ArraySet;
 import android.util.SparseBooleanArray;
@@ -92,7 +93,9 @@
     private static final int TEST_USER_1_ID = 10;
     private static final int TEST_QUIET_USER_ID = 20;
     private static final UserInfo DEFAULT_USER_INFO = new UserInfo();
-    private static final UserInfo QUIET_USER_INFO = new UserInfo();
+    private static final UserInfo QUIET_PROFILE_USER_INFO = new UserInfo(TEST_QUIET_USER_ID,
+            "quiet_profile", null /* iconPath */, UserInfo.FLAG_QUIET_MODE,
+            UserManager.USER_TYPE_PROFILE_MANAGED);
     private static final int INVALID_STACK_ID = 999;
 
     private ActivityDisplay mDisplay;
@@ -125,7 +128,6 @@
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
         mCallbacksRecorder = new CallbacksRecorder();
         mRecentTasks.registerCallback(mCallbacksRecorder);
-        QUIET_USER_INFO.flags = UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_QUIET_MODE;
 
         mTasks = new ArrayList<>();
         mTasks.add(createTaskBuilder(".Task1").build());
@@ -1220,7 +1222,7 @@
                 case TEST_USER_1_ID:
                     return DEFAULT_USER_INFO;
                 case TEST_QUIET_USER_ID:
-                    return QUIET_USER_INFO;
+                    return QUIET_PROFILE_USER_INFO;
             }
             return null;
         }
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index 41cbd81..b2cb8c9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -154,7 +154,7 @@
                 ACTIVITY_TYPE_RECENTS);
         assertThat(recentsStack).isNotNull();
 
-        ActivityRecord recentsActivity = recentsStack.getTopActivity();
+        ActivityRecord recentsActivity = recentsStack.getTopNonFinishingActivity();
         // The activity is started in background so it should be invisible and will be stopped.
         assertThat(recentsActivity).isNotNull();
         assertThat(mSupervisor.mStoppingActivities).contains(recentsActivity);
@@ -211,7 +211,7 @@
         display.mDisplayContent.mBoundsAnimationController = mock(BoundsAnimationController.class);
         ActivityStack homeStack = display.getHomeStack();
         // Assume the home activity support recents.
-        ActivityRecord targetActivity = homeStack.getTopActivity();
+        ActivityRecord targetActivity = homeStack.getTopNonFinishingActivity();
         if (targetActivity == null) {
             targetActivity = new ActivityBuilder(mService)
                     .setCreateTask(true)
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
new file mode 100644
index 0000000..ecd9a83
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -0,0 +1,426 @@
+/*
+ * 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.wm;
+
+import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.app.TaskStackListener;
+import android.app.WindowConfiguration;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.MediumTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for Size Compatibility mode.
+ *
+ * Build/Install/Run:
+ *  atest WmTests:SizeCompatTests
+ */
+@MediumTest
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class SizeCompatTests extends ActivityTestsBase {
+    private ActivityStack mStack;
+    private Task mTask;
+    private ActivityRecord mActivity;
+
+    private void setUpApp(ActivityDisplay display) {
+        mStack = new StackBuilder(mRootActivityContainer).setDisplay(display).build();
+        mTask = mStack.getChildAt(0);
+        mActivity = mTask.getTopNonFinishingActivity();
+    }
+
+    private void ensureActivityConfiguration() {
+        mActivity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
+    }
+
+    @Test
+    public void testRestartProcessIfVisible() {
+        setUpApp(new TestActivityDisplay.Builder(mService, 1000, 2500).build());
+        doNothing().when(mSupervisor).scheduleRestartTimeout(mActivity);
+        mActivity.visible = true;
+        mActivity.setSavedState(null /* savedState */);
+        mActivity.setState(ActivityStack.ActivityState.RESUMED, "testRestart");
+        prepareUnresizable(1.5f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
+
+        final Rect originalOverrideBounds = new Rect(mActivity.getBounds());
+        resizeDisplay(mStack.getDisplay(), 600, 1200);
+        // The visible activity should recompute configuration according to the last parent bounds.
+        mService.restartActivityProcessIfVisible(mActivity.appToken);
+
+        assertEquals(ActivityStack.ActivityState.RESTARTING_PROCESS, mActivity.getState());
+        assertNotEquals(originalOverrideBounds, mActivity.getBounds());
+    }
+
+    @Test
+    public void testKeepBoundsWhenChangingFromFreeformToFullscreen() {
+        removeGlobalMinSizeRestriction();
+        // create freeform display and a freeform app
+        ActivityDisplay display = new TestActivityDisplay.Builder(mService, 2000, 1000)
+                .setCanRotate(false)
+                .setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM).build();
+        setUpApp(display);
+
+        // Put app window into freeform and then make it a compat app.
+        mTask.setBounds(100, 100, 400, 600);
+        prepareUnresizable(-1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+
+        final Rect bounds = new Rect(mActivity.getBounds());
+        final int density = mActivity.getConfiguration().densityDpi;
+
+        // change display configuration to fullscreen
+        Configuration c = new Configuration(display.getRequestedOverrideConfiguration());
+        c.windowConfiguration.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
+        display.onRequestedOverrideConfigurationChanged(c);
+
+        // check if dimensions stay the same
+        assertTrue(mActivity.inSizeCompatMode());
+        assertEquals(bounds.width(), mActivity.getBounds().width());
+        assertEquals(bounds.height(), mActivity.getBounds().height());
+        assertEquals(density, mActivity.getConfiguration().densityDpi);
+    }
+
+    @Test
+    public void testFixedAspectRatioBoundsWithDecor() {
+        final int decorHeight = 200; // e.g. The device has cutout.
+        setUpApp(new TestActivityDisplay.Builder(mService, 600, 800)
+                .setNotch(decorHeight).build());
+
+        mActivity.info.minAspectRatio = mActivity.info.maxAspectRatio = 1;
+        prepareUnresizable(-1f, SCREEN_ORIENTATION_UNSPECIFIED);
+
+        // The parent configuration doesn't change since the first resolved configuration, so the
+        // activity shouldn't be in the size compatibility mode.
+        assertFalse(mActivity.inSizeCompatMode());
+
+        final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds();
+        // Ensure the app bounds keep the declared aspect ratio.
+        assertEquals(appBounds.width(), appBounds.height());
+        // The decor height should be a part of the effective bounds.
+        assertEquals(mActivity.getBounds().height(), appBounds.height() + decorHeight);
+
+        mTask.getConfiguration().windowConfiguration.setRotation(ROTATION_90);
+        mActivity.onConfigurationChanged(mTask.getConfiguration());
+        // After changing orientation, the aspect ratio should be the same.
+        assertEquals(appBounds.width(), appBounds.height());
+        // The decor height will be included in width.
+        assertEquals(mActivity.getBounds().width(), appBounds.width() + decorHeight);
+    }
+
+    @Test
+    public void testFixedScreenConfigurationWhenMovingToDisplay() {
+        setUpApp(new TestActivityDisplay.Builder(mService, 1000, 2500).build());
+
+        // Make a new less-tall display with lower density
+        final ActivityDisplay newDisplay =
+                new TestActivityDisplay.Builder(mService, 1000, 2000)
+                        .setDensityDpi(200).build();
+
+        mActivity = new ActivityBuilder(mService)
+                .setTask(mTask)
+                .setResizeMode(RESIZE_MODE_UNRESIZEABLE)
+                .setMaxAspectRatio(1.5f)
+                .build();
+        mActivity.visible = true;
+
+        final Rect originalBounds = new Rect(mActivity.getBounds());
+        final int originalDpi = mActivity.getConfiguration().densityDpi;
+
+        // Move the non-resizable activity to the new display.
+        mStack.reparent(newDisplay.mDisplayContent, true /* onTop */);
+
+        assertEquals(originalBounds.width(), mActivity.getBounds().width());
+        assertEquals(originalBounds.height(), mActivity.getBounds().height());
+        assertEquals(originalDpi, mActivity.getConfiguration().densityDpi);
+        assertTrue(mActivity.inSizeCompatMode());
+    }
+
+    @Test
+    public void testFixedScreenBoundsWhenDisplaySizeChanged() {
+        setUpApp(new TestActivityDisplay.Builder(mService, 1000, 2500).build());
+        prepareUnresizable(-1f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+        assertFalse(mActivity.inSizeCompatMode());
+
+        final Rect origBounds = new Rect(mActivity.getBounds());
+
+        // Change the size of current display.
+        resizeDisplay(mStack.getDisplay(), 1000, 2000);
+        ensureActivityConfiguration();
+
+        assertEquals(origBounds.width(), mActivity.getWindowConfiguration().getBounds().width());
+        assertEquals(origBounds.height(), mActivity.getWindowConfiguration().getBounds().height());
+        assertTrue(mActivity.inSizeCompatMode());
+
+        // Change display size to a different orientation
+        resizeDisplay(mStack.getDisplay(), 2000, 1000);
+        ensureActivityConfiguration();
+        assertEquals(origBounds.width(), mActivity.getWindowConfiguration().getBounds().width());
+        assertEquals(origBounds.height(), mActivity.getWindowConfiguration().getBounds().height());
+    }
+
+    @Test
+    public void testLetterboxFullscreenBounds() {
+        setUpApp(new TestActivityDisplay.Builder(mService, 1000, 2500).build());
+
+        // Fill out required fields on default display since WM-side is mocked out
+        prepareUnresizable(-1.f /* maxAspect */, SCREEN_ORIENTATION_LANDSCAPE);
+        assertFalse(mActivity.inSizeCompatMode());
+        assertTrue(mActivity.getBounds().width() > mActivity.getBounds().height());
+    }
+
+    @Test
+    public void testMoveToDifferentOrientDisplay() {
+        setUpApp(new TestActivityDisplay.Builder(mService, 1000, 2500).build());
+
+        final ActivityDisplay newDisplay =
+                new TestActivityDisplay.Builder(mService, 2000, 1000)
+                        .setCanRotate(false).build();
+
+        prepareUnresizable(-1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+        assertFalse(mActivity.inSizeCompatMode());
+
+        final Rect origBounds = new Rect(mActivity.getBounds());
+
+        // Move the non-resizable activity to the new display.
+        mStack.reparent(newDisplay.mDisplayContent, true /* onTop */);
+        ensureActivityConfiguration();
+        assertEquals(origBounds.width(), mActivity.getWindowConfiguration().getBounds().width());
+        assertEquals(origBounds.height(), mActivity.getWindowConfiguration().getBounds().height());
+        assertTrue(mActivity.inSizeCompatMode());
+    }
+
+    @Test
+    public void testFixedOrientRotateCutoutDisplay() {
+        // Create a display with a notch/cutout
+        setUpApp(new TestActivityDisplay.Builder(mService, 1000, 2500).setNotch(60).build());
+        prepareUnresizable(1.4f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+
+        final Rect origBounds = new Rect(mActivity.getBounds());
+        final Rect origAppBounds = new Rect(mActivity.getWindowConfiguration().getAppBounds());
+
+        // Rotate the display
+        Configuration c = new Configuration();
+        mStack.getDisplay().mDisplayContent.getDisplayRotation().setRotation(ROTATION_270);
+        mStack.getDisplay().mDisplayContent.computeScreenConfiguration(c);
+        mStack.getDisplay().onRequestedOverrideConfigurationChanged(c);
+
+        // Make sure the app size is the same
+        assertEquals(ROTATION_270, mStack.getWindowConfiguration().getRotation());
+        assertEquals(origBounds.width(), mActivity.getWindowConfiguration().getBounds().width());
+        assertEquals(origBounds.height(), mActivity.getWindowConfiguration().getBounds().height());
+        assertEquals(origAppBounds.width(),
+                mActivity.getWindowConfiguration().getAppBounds().width());
+        assertEquals(origAppBounds.height(),
+                mActivity.getWindowConfiguration().getAppBounds().height());
+    }
+
+    @Test
+    public void testFixedAspOrientChangeOrient() {
+        setUpApp(new TestActivityDisplay.Builder(mService, 1000, 2500).build());
+
+        prepareUnresizable(1.4f /* maxAspect */, SCREEN_ORIENTATION_LANDSCAPE);
+        assertTrue(mActivity.inSizeCompatMode());
+
+        final Rect originalBounds = new Rect(mActivity.getBounds());
+        final Rect originalAppBounds = new Rect(mActivity.getWindowConfiguration().getAppBounds());
+
+        // Change the fixed orientation
+        mActivity.mOrientation = SCREEN_ORIENTATION_PORTRAIT;
+        mActivity.info.screenOrientation = SCREEN_ORIENTATION_PORTRAIT;
+        // TaskRecord's configuration actually depends on the activity config right now for
+        // pillarboxing.
+        mActivity.getTask().onRequestedOverrideConfigurationChanged(
+                mActivity.getTask().getRequestedOverrideConfiguration());
+
+        assertEquals(originalBounds.width(), mActivity.getBounds().height());
+        assertEquals(originalBounds.height(), mActivity.getBounds().width());
+        assertEquals(originalAppBounds.width(),
+                mActivity.getWindowConfiguration().getAppBounds().height());
+        assertEquals(originalAppBounds.height(),
+                mActivity.getWindowConfiguration().getAppBounds().width());
+    }
+
+    @Test
+    public void testFixedScreenLayoutSizeBits() {
+        setUpApp(new TestActivityDisplay.Builder(mService, 1000, 2500).build());
+        final int fixedScreenLayout = Configuration.SCREENLAYOUT_LONG_NO
+                | Configuration.SCREENLAYOUT_SIZE_NORMAL;
+        final int layoutMask = Configuration.SCREENLAYOUT_LONG_MASK
+                | Configuration.SCREENLAYOUT_SIZE_MASK
+                | Configuration.SCREENLAYOUT_LAYOUTDIR_MASK;
+        Configuration c = new Configuration(mTask.getRequestedOverrideConfiguration());
+        c.screenLayout = fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_LTR;
+        mTask.onRequestedOverrideConfigurationChanged(c);
+        prepareUnresizable(1.5f, SCREEN_ORIENTATION_UNSPECIFIED);
+
+        // The initial configuration should inherit from parent.
+        assertEquals(fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_LTR,
+                mActivity.getConfiguration().screenLayout & layoutMask);
+
+        mTask.getConfiguration().screenLayout = Configuration.SCREENLAYOUT_LAYOUTDIR_RTL
+                | Configuration.SCREENLAYOUT_LONG_YES | Configuration.SCREENLAYOUT_SIZE_LARGE;
+        mActivity.onConfigurationChanged(mTask.getConfiguration());
+
+        // The size and aspect ratio bits don't change, but the layout direction should be updated.
+        assertEquals(fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_RTL,
+                mActivity.getConfiguration().screenLayout & layoutMask);
+    }
+
+    @Test
+    public void testResetNonVisibleActivity() {
+        setUpApp(new TestActivityDisplay.Builder(mService, 1000, 2500).build());
+        final ActivityDisplay display = mStack.getDisplay();
+        spyOn(display);
+
+        prepareUnresizable(1.5f, SCREEN_ORIENTATION_UNSPECIFIED);
+        mActivity.setState(STOPPED, "testSizeCompatMode");
+        mActivity.visible = false;
+        mActivity.app.setReportedProcState(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY);
+        // Make the parent bounds to be different so the activity is in size compatibility mode.
+        mTask.getWindowConfiguration().setAppBounds(new Rect(0, 0, 600, 1200));
+
+        // Simulate the display changes orientation.
+        when(display.getLastOverrideConfigurationChanges()).thenReturn(
+                ActivityInfo.CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION
+                        | ActivityInfo.CONFIG_WINDOW_CONFIGURATION);
+        mActivity.onConfigurationChanged(mTask.getConfiguration());
+        when(display.getLastOverrideConfigurationChanges()).thenCallRealMethod();
+        // The override configuration should not change so it is still in size compatibility mode.
+        assertTrue(mActivity.inSizeCompatMode());
+
+        // Change display density
+        final DisplayContent displayContent = mStack.getDisplay().mDisplayContent;
+        displayContent.mBaseDisplayDensity = (int) (0.7f * displayContent.mBaseDisplayDensity);
+        final Configuration c = new Configuration();
+        displayContent.computeScreenConfiguration(c);
+        mService.mAmInternal = mock(ActivityManagerInternal.class);
+        mStack.getDisplay().onRequestedOverrideConfigurationChanged(c);
+
+        // The override configuration should be reset and the activity's process will be killed.
+        assertFalse(mActivity.inSizeCompatMode());
+        verify(mActivity).restartProcessIfVisible();
+        mLockRule.runWithScissors(mService.mH, () -> { }, TimeUnit.SECONDS.toMillis(3));
+        verify(mService.mAmInternal).killProcess(
+                eq(mActivity.app.mName), eq(mActivity.app.mUid), anyString());
+    }
+
+    /**
+     * Ensures that {@link TaskStackListener} can receive callback about the activity in size
+     * compatibility mode.
+     */
+    @Test
+    public void testHandleActivitySizeCompatMode() {
+        setUpApp(new TestActivityDisplay.Builder(mService, 1000, 2000).build());
+        ActivityRecord activity = mActivity;
+        activity.setState(ActivityStack.ActivityState.RESUMED, "testHandleActivitySizeCompatMode");
+        prepareUnresizable(-1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+        ensureActivityConfiguration();
+        assertFalse(mActivity.inSizeCompatMode());
+
+        final ArrayList<IBinder> compatTokens = new ArrayList<>();
+        mService.getTaskChangeNotificationController().registerTaskStackListener(
+                new TaskStackListener() {
+                    @Override
+                    public void onSizeCompatModeActivityChanged(int displayId,
+                            IBinder activityToken) {
+                        compatTokens.add(activityToken);
+                    }
+                });
+
+        // Resize the display so that the activity exercises size-compat mode.
+        resizeDisplay(mStack.getDisplay(), 1000, 2500);
+
+        // Expect the exact token when the activity is in size compatibility mode.
+        assertEquals(1, compatTokens.size());
+        assertEquals(activity.appToken, compatTokens.get(0));
+
+        compatTokens.clear();
+        // Make the activity resizable again by restarting it
+        activity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
+        activity.visible = true;
+        activity.restartProcessIfVisible();
+        // The full lifecycle isn't hooked up so manually set state to resumed
+        activity.setState(ActivityStack.ActivityState.RESUMED, "testHandleActivitySizeCompatMode");
+        mStack.getDisplay().handleActivitySizeCompatModeIfNeeded(activity);
+
+        // Expect null token when switching to non-size-compat mode activity.
+        assertEquals(1, compatTokens.size());
+        assertEquals(null, compatTokens.get(0));
+    }
+
+    /**
+     * Setup {@link #mActivity} as a size-compat-mode-able activity with fixed aspect and/or
+     * orientation.
+     */
+    private void prepareUnresizable(float maxAspect, int screenOrientation) {
+        mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
+        mActivity.visible = true;
+        if (maxAspect >= 0) {
+            mActivity.info.maxAspectRatio = maxAspect;
+        }
+        if (screenOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
+            mActivity.mOrientation = screenOrientation;
+            mActivity.info.screenOrientation = screenOrientation;
+            // TaskRecord's configuration actually depends on the activity config right now for
+            // pillarboxing.
+            mActivity.getTask().onRequestedOverrideConfigurationChanged(
+                    mActivity.getTask().getRequestedOverrideConfiguration());
+        }
+        ensureActivityConfiguration();
+    }
+
+    private void resizeDisplay(ActivityDisplay display, int width, int height) {
+        final DisplayContent displayContent = display.mDisplayContent;
+        displayContent.mBaseDisplayWidth = width;
+        displayContent.mBaseDisplayHeight = height;
+        Configuration c = new Configuration();
+        displayContent.computeScreenConfiguration(c);
+        display.onRequestedOverrideConfigurationChanged(c);
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index faa9f11..b07a27b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -45,6 +45,7 @@
 import static org.hamcrest.Matchers.sameInstance;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
@@ -161,12 +162,12 @@
         assertTrue(task.returnsToHomeStack());
     }
 
-    /** Ensures that empty bounds are not propagated to the configuration. */
+    /** Ensures that empty bounds cause appBounds to inherit from parent. */
     @Test
     public void testAppBounds_EmptyBounds() {
         final Rect emptyBounds = new Rect();
         testStackBoundsConfiguration(WINDOWING_MODE_FULLSCREEN, mParentBounds, emptyBounds,
-                null /*ExpectedBounds*/);
+                mParentBounds);
     }
 
     /** Ensures that bounds on freeform stacks are not clipped. */
@@ -280,7 +281,7 @@
         ActivityStack stack = new StackBuilder(mRootActivityContainer)
                 .setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
         Task task = stack.getChildAt(0);
-        ActivityRecord root = task.getTopActivity();
+        ActivityRecord root = task.getTopNonFinishingActivity();
 
         assertEquals(fullScreenBounds, task.getBounds());
 
@@ -293,7 +294,7 @@
 
         // Top activity gets used
         ActivityRecord top = new ActivityBuilder(mService).setTask(task).setStack(stack).build();
-        assertEquals(top, task.getTopActivity());
+        assertEquals(top, task.getTopNonFinishingActivity());
         top.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
         assertThat(task.getBounds().width()).isGreaterThan(task.getBounds().height());
         assertEquals(task.getBounds().width(), fullScreenBounds.width());
@@ -344,7 +345,7 @@
         ActivityStack stack = new StackBuilder(mRootActivityContainer)
                 .setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
         Task task = stack.getChildAt(0);
-        ActivityRecord root = task.getTopActivity();
+        ActivityRecord root = task.getTopNonFinishingActivity();
 
         final WindowContainer parentWindowContainer =
                 new WindowContainer(mSystemServicesTestRule.getWindowManagerService());
@@ -415,6 +416,24 @@
         assertEquals(Configuration.ORIENTATION_LANDSCAPE, inOutConfig.orientation);
     }
 
+    @Test
+    public void testComputeNestedConfigResourceOverrides() {
+        final Task task = new TaskBuilder(mSupervisor).build();
+        assertTrue(task.getResolvedOverrideBounds().isEmpty());
+        int origScreenH = task.getConfiguration().screenHeightDp;
+        Configuration stackConfig = new Configuration();
+        stackConfig.setTo(task.getStack().getRequestedOverrideConfiguration());
+        stackConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+
+        // Set bounds on stack (not task) and verify that the task resource configuration changes
+        // despite it's override bounds being empty.
+        Rect bounds = new Rect(task.getStack().getBounds());
+        bounds.bottom = (int) (bounds.bottom * 0.6f);
+        stackConfig.windowConfiguration.setBounds(bounds);
+        task.getStack().onRequestedOverrideConfigurationChanged(stackConfig);
+        assertNotEquals(origScreenH, task.getConfiguration().screenHeightDp);
+    }
+
     /** Ensures that the alias intent won't have target component resolved. */
     @Test
     public void testTaskIntentActivityAlias() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
index 8617fb2..dbf61db 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
@@ -68,8 +68,8 @@
     @Test
     public void testStackPositionChildAt() {
         // Test that always-on-top stack can't be moved to position other than top.
-        final TaskStack stack1 = createTaskStackOnDisplay(mDisplayContent);
-        final TaskStack stack2 = createTaskStackOnDisplay(mDisplayContent);
+        final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent);
+        final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent);
 
         final WindowContainer taskStackContainer = stack1.getParent();
 
@@ -93,7 +93,7 @@
     @Test
     public void testStackPositionBelowPinnedStack() {
         // Test that no stack can be above pinned stack.
-        final TaskStack stack1 = createTaskStackOnDisplay(mDisplayContent);
+        final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent);
 
         final WindowContainer taskStackContainer = stack1.getParent();
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
index 40ce363..5877041 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
@@ -41,7 +41,7 @@
 import org.junit.runner.RunWith;
 
 /**
- * Tests for the {@link TaskStack} class.
+ * Tests for the {@link ActivityStack} class.
  *
  * Build/Install/Run:
  *  atest WmTests:TaskStackTests
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestActivityDisplay.java b/services/tests/wmtests/src/com/android/server/wm/TestActivityDisplay.java
index 9c3ff65..48ec261 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestActivityDisplay.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestActivityDisplay.java
@@ -23,12 +23,17 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 
 import static org.mockito.ArgumentMatchers.any;
 
+import android.content.res.Configuration;
+import android.graphics.Insets;
+import android.graphics.Rect;
 import android.hardware.display.DisplayManagerGlobal;
 import android.view.Display;
+import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 
 class TestActivityDisplay extends ActivityDisplay {
@@ -107,4 +112,94 @@
                 .setCreateActivity(false)
                 .build();
     }
+
+    public static class Builder {
+        private final DisplayInfo mInfo;
+        private boolean mCanRotate = true;
+        private int mWindowingMode = WINDOWING_MODE_FULLSCREEN;
+        private int mPosition = POSITION_TOP;
+        private final ActivityTaskManagerService mService;
+        private boolean mSystemDecorations = false;
+
+        Builder(ActivityTaskManagerService service, int width, int height) {
+            mService = service;
+            mInfo = new DisplayInfo();
+            mService.mContext.getDisplay().getDisplayInfo(mInfo);
+            mInfo.logicalWidth = width;
+            mInfo.logicalHeight = height;
+            mInfo.logicalDensityDpi = 300;
+            mInfo.displayCutout = null;
+        }
+        Builder(ActivityTaskManagerService service, DisplayInfo info) {
+            mService = service;
+            mInfo = info;
+        }
+        Builder setSystemDecorations(boolean yes) {
+            mSystemDecorations = yes;
+            return this;
+        }
+        Builder setPosition(int position) {
+            mPosition = position;
+            return this;
+        }
+        Builder setUniqueId(String uniqueId) {
+            mInfo.uniqueId = uniqueId;
+            return this;
+        }
+        Builder setType(int type) {
+            mInfo.type = type;
+            return this;
+        }
+        Builder setOwnerUid(int ownerUid) {
+            mInfo.ownerUid = ownerUid;
+            return this;
+        }
+        Builder setNotch(int height) {
+            mInfo.displayCutout = new DisplayCutout(
+                    Insets.of(0, height, 0, 0), null, new Rect(20, 0, 80, height), null, null);
+            return this;
+        }
+        Builder setCanRotate(boolean canRotate) {
+            mCanRotate = canRotate;
+            return this;
+        }
+        Builder setWindowingMode(int windowingMode) {
+            mWindowingMode = windowingMode;
+            return this;
+        }
+        Builder setDensityDpi(int dpi) {
+            mInfo.logicalDensityDpi = dpi;
+            return this;
+        }
+        TestActivityDisplay build() {
+            final int displayId = SystemServicesTestRule.sNextDisplayId++;
+            final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
+                    mInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
+            final TestActivityDisplay newDisplay;
+            synchronized (mService.mGlobalLock) {
+                newDisplay = new TestActivityDisplay(mService.mStackSupervisor, display);
+                mService.mRootActivityContainer.addChild(newDisplay, mPosition);
+            }
+            // disable the normal system decorations
+            final DisplayPolicy displayPolicy = newDisplay.mDisplayContent.getDisplayPolicy();
+            spyOn(displayPolicy);
+            if (mSystemDecorations) {
+                doReturn(true).when(newDisplay).supportsSystemDecorations();
+            } else {
+                doReturn(false).when(displayPolicy).hasNavigationBar();
+                doReturn(false).when(displayPolicy).hasStatusBar();
+                doReturn(false).when(newDisplay).supportsSystemDecorations();
+            }
+            Configuration c = new Configuration();
+            newDisplay.mDisplayContent.computeScreenConfiguration(c);
+            c.windowConfiguration.setWindowingMode(mWindowingMode);
+            newDisplay.onRequestedOverrideConfigurationChanged(c);
+            // This is a rotating display
+            if (mCanRotate) {
+                doReturn(false).when(newDisplay.mDisplayContent)
+                        .handlesOrientationChangeFromDescendant();
+            }
+            return newDisplay;
+        }
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
index 0b8b6a1..7be05a3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
@@ -96,6 +96,10 @@
         assertRect(w.getFrameLw(), left, top, right, bottom);
     }
 
+    private void assertRelFrame(WindowState w, int left, int top, int right, int bottom) {
+        assertRect(w.getRelativeFrameLw(), left, top, right, bottom);
+    }
+
     private void assertContentFrame(WindowState w, Rect expectedRect) {
         assertRect(w.getContentFrameLw(), expectedRect.left, expectedRect.top, expectedRect.right,
                 expectedRect.bottom);
@@ -153,6 +157,7 @@
         w.getWindowFrames().setFrames(pf, df, cf, vf, dcf, sf);
         w.computeFrameLw();
         assertFrame(w, 0, 0, 1000, 1000);
+        assertRelFrame(w, 0, 0, 1000, 1000);
         assertContentInset(w, 0, topContentInset, 0, bottomContentInset);
         assertVisibleInset(w, 0, topVisibleInset, 0, bottomVisibleInset);
         assertStableInset(w, leftStableInset, 0, rightStableInset, 0);
@@ -167,6 +172,7 @@
         w.mRequestedHeight = 100;
         w.computeFrameLw();
         assertFrame(w, 100, 100, 200, 200);
+        assertRelFrame(w, 100, 100, 200, 200);
         assertContentInset(w, 0, 0, 0, 0);
         // In this case the frames are shrunk to the window frame.
         assertContentFrame(w, w.getFrameLw());
@@ -189,6 +195,7 @@
         w.getWindowFrames().setFrames(pf, pf, pf, pf, pf, pf);
         w.computeFrameLw();
         assertFrame(w, 0, 0, 1000, 1000);
+        assertRelFrame(w, 0, 0, 1000, 1000);
 
         // It can select various widths and heights within the bounds.
         // Strangely the window attribute width is ignored for normal windows
@@ -242,15 +249,18 @@
         w.mAttrs.gravity = Gravity.RIGHT | Gravity.TOP;
         w.computeFrameLw();
         assertFrame(w, 700, 0, 1000, 300);
+        assertRelFrame(w, 700, 0, 1000, 300);
         w.mAttrs.gravity = Gravity.RIGHT | Gravity.BOTTOM;
         w.computeFrameLw();
         assertFrame(w, 700, 700, 1000, 1000);
+        assertRelFrame(w, 700, 700, 1000, 1000);
         // Window specified  x and y are interpreted as offsets in the opposite
         // direction of gravity
         w.mAttrs.x = 100;
         w.mAttrs.y = 100;
         w.computeFrameLw();
         assertFrame(w, 600, 600, 900, 900);
+        assertRelFrame(w, 600, 600, 900, 900);
     }
 
     @Test
@@ -279,6 +289,8 @@
         // For non fullscreen tasks the containing frame is based off the
         // task bounds not the parent frame.
         assertEquals(resolvedTaskBounds, w.getFrameLw());
+        assertEquals(0, w.getRelativeFrameLw().left);
+        assertEquals(0, w.getRelativeFrameLw().top);
         assertContentFrame(w, resolvedTaskBounds);
         assertContentInset(w, 0, 0, 0, 0);
 
@@ -290,6 +302,8 @@
         windowFrames.setFrames(pf, pf, cf, cf, pf, cf);
         w.computeFrameLw();
         assertEquals(resolvedTaskBounds, w.getFrameLw());
+        assertEquals(0, w.getRelativeFrameLw().left);
+        assertEquals(0, w.getRelativeFrameLw().top);
         int contentInsetRight = resolvedTaskBounds.right - cfRight;
         int contentInsetBottom = resolvedTaskBounds.bottom - cfBottom;
         assertContentInset(w, 0, 0, contentInsetRight, contentInsetBottom);
@@ -309,6 +323,8 @@
         windowFrames.setFrames(pf, pf, cf, cf, pf, cf);
         w.computeFrameLw();
         assertEquals(resolvedTaskBounds, w.getFrameLw());
+        assertEquals(0, w.getRelativeFrameLw().left);
+        assertEquals(0, w.getRelativeFrameLw().top);
         contentInsetRight = insetRight - cfRight;
         contentInsetBottom = insetBottom - cfBottom;
         assertContentInset(w, 0, 0, contentInsetRight, contentInsetBottom);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index e1f92dd..9e0d3a7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -261,7 +261,7 @@
         // minimized and home stack is resizable, so that we should ignore input for the stack.
         final DockedStackDividerController controller =
                 mDisplayContent.getDockedDividerController();
-        final TaskStack stack = createTaskStackOnDisplay(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
+        final ActivityStack stack = createTaskStackOnDisplay(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
                 ACTIVITY_TYPE_STANDARD, mDisplayContent);
         spyOn(appWindow);
         spyOn(controller);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index a7a78e1..0da9dc4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -41,7 +41,6 @@
 import static org.mockito.Mockito.mock;
 
 import android.content.Context;
-import android.content.res.Configuration;
 import android.util.Log;
 import android.view.Display;
 import android.view.DisplayInfo;
@@ -314,7 +313,7 @@
         }
     }
 
-    /** Creates a {@link TaskStack} and adds it to the specified {@link DisplayContent}. */
+    /** Creates a {@link ActivityStack} and adds it to the specified {@link DisplayContent}. */
     ActivityStack createTaskStackOnDisplay(DisplayContent dc) {
         return createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, dc);
     }
diff --git a/startop/apps/test/Android.bp b/startop/apps/test/Android.bp
index 3f20273..f42c755 100644
--- a/startop/apps/test/Android.bp
+++ b/startop/apps/test/Android.bp
@@ -17,6 +17,7 @@
 android_app {
     name: "startop_test_app",
     srcs: [
+        "src/ApplicationBenchmarks.java",
         "src/ComplexLayoutInflationActivity.java",
         "src/CPUIntensiveBenchmarkActivity.java",
         "src/CPUIntensiveBenchmarks.java",
@@ -25,8 +26,8 @@
         "src/InitCheckOverheadBenchmarkActivity.java",
         "src/InitCheckOverheadBenchmarks.java",
         "src/LayoutInflationActivity.java",
-        "src/NonInteractiveSystemServerBenchmarkActivity.java",
-        "src/SystemServerBenchmarkActivity.java",
+        "src/NonInteractiveMicrobenchmarkActivity.java",
+        "src/InteractiveMicrobenchmarkActivity.java",
         "src/SystemServerBenchmarks.java",
         "src/TextViewInflationActivity.java",
     ],
diff --git a/startop/apps/test/AndroidManifest.xml b/startop/apps/test/AndroidManifest.xml
index 235aa0d..adaab61 100644
--- a/startop/apps/test/AndroidManifest.xml
+++ b/startop/apps/test/AndroidManifest.xml
@@ -97,8 +97,8 @@
         </activity>
 
         <activity
-            android:label="SystemServer Benchmark"
-            android:name=".SystemServerBenchmarkActivity"
+            android:label="Interactive Microbenchmarks"
+            android:name=".InteractiveMicrobenchmarkActivity"
             android:exported="true" >
 
             <intent-filter>
@@ -109,8 +109,8 @@
         </activity>
 
         <activity
-            android:label="Non-interactive SystemServer Benchmark"
-            android:name=".NonInteractiveSystemServerBenchmarkActivity"
+            android:label="Non-interactive Microbenchmarks"
+            android:name=".NonInteractiveMicrobenchmarkActivity"
             android:exported="true" />
 
     </application>
diff --git a/startop/apps/test/src/ApplicationBenchmarks.java b/startop/apps/test/src/ApplicationBenchmarks.java
new file mode 100644
index 0000000..7d71916
--- /dev/null
+++ b/startop/apps/test/src/ApplicationBenchmarks.java
@@ -0,0 +1,39 @@
+/*
+ * 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.startop.test;
+
+import android.app.Activity;
+import android.view.LayoutInflater;
+
+final class ApplicationBenchmarks {
+
+    public static final void initializeBenchmarks(Activity parent, BenchmarkRunner benchmarks) {
+        LayoutInflater inflater = LayoutInflater.from(parent);
+
+        benchmarks.addBenchmark("Complex Layout", () -> {
+            inflater.inflate(R.layout.activity_main, null);
+        });
+
+        benchmarks.addBenchmark("TextView List Layout", () -> {
+            inflater.inflate(R.layout.textview_list, null);
+        });
+
+        benchmarks.addBenchmark("FrameLayout List Layout", () -> {
+            inflater.inflate(R.layout.framelayout_list, null);
+        });
+    }
+}
diff --git a/startop/apps/test/src/CPUIntensiveBenchmarkActivity.java b/startop/apps/test/src/CPUIntensiveBenchmarkActivity.java
index 2ec5308..db3234a 100644
--- a/startop/apps/test/src/CPUIntensiveBenchmarkActivity.java
+++ b/startop/apps/test/src/CPUIntensiveBenchmarkActivity.java
@@ -18,7 +18,7 @@
 
 import android.os.Bundle;
 
-public class CPUIntensiveBenchmarkActivity extends SystemServerBenchmarkActivity {
+public class CPUIntensiveBenchmarkActivity extends InteractiveMicrobenchmarkActivity {
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.system_server_benchmark_page);
diff --git a/startop/apps/test/src/InitCheckOverheadBenchmarkActivity.java b/startop/apps/test/src/InitCheckOverheadBenchmarkActivity.java
index 3e0e3b1..92d8638 100644
--- a/startop/apps/test/src/InitCheckOverheadBenchmarkActivity.java
+++ b/startop/apps/test/src/InitCheckOverheadBenchmarkActivity.java
@@ -18,7 +18,7 @@
 
 import android.os.Bundle;
 
-public class InitCheckOverheadBenchmarkActivity extends SystemServerBenchmarkActivity {
+public class InitCheckOverheadBenchmarkActivity extends InteractiveMicrobenchmarkActivity {
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.system_server_benchmark_page);
diff --git a/startop/apps/test/src/SystemServerBenchmarkActivity.java b/startop/apps/test/src/InteractiveMicrobenchmarkActivity.java
similarity index 66%
rename from startop/apps/test/src/SystemServerBenchmarkActivity.java
rename to startop/apps/test/src/InteractiveMicrobenchmarkActivity.java
index 6be8df3..c3839c1 100644
--- a/startop/apps/test/src/SystemServerBenchmarkActivity.java
+++ b/startop/apps/test/src/InteractiveMicrobenchmarkActivity.java
@@ -18,12 +18,13 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.graphics.Typeface;
 import android.os.Bundle;
 import android.widget.Button;
 import android.widget.GridLayout;
 import android.widget.TextView;
 
-public class SystemServerBenchmarkActivity extends Activity implements BenchmarkRunner {
+public class InteractiveMicrobenchmarkActivity extends Activity implements BenchmarkRunner {
     protected GridLayout mBenchmarkList;
 
     protected void onCreate(Bundle savedInstanceState) {
@@ -32,10 +33,34 @@
 
         mBenchmarkList = findViewById(R.id.benchmark_list);
 
+        addBenchmark("Empty", () -> {
+        });
+        addHeader("Application Benchmarks");
+        ApplicationBenchmarks.initializeBenchmarks(this, this);
+        addHeader("CPU Intensive Benchmarks");
+        CPUIntensiveBenchmarks.initializeBenchmarks(this, this);
+        addHeader("Init Check Overhead Benchmarks");
+        InitCheckOverheadBenchmarks.initializeBenchmarks(this, this);
+        addHeader("System Server Benchmarks");
         SystemServerBenchmarks.initializeBenchmarks(this, this);
     }
 
     /**
+     * Add a heading for a group of related benchmarks
+     *
+     * @param name The name of this group of benchmarks
+     */
+    public void addHeader(CharSequence name) {
+        Context context = mBenchmarkList.getContext();
+        TextView header = new TextView(context);
+        header.setText(name);
+        header.setTypeface(header.getTypeface(), Typeface.BOLD);
+        GridLayout.LayoutParams params = new GridLayout.LayoutParams();
+        params.columnSpec = GridLayout.spec(0, 3);
+        mBenchmarkList.addView(header, params);
+    }
+
+    /**
      * Adds a benchmark to the set to run.
      *
      * @param name A short name that shows up in the UI or benchmark results
diff --git a/startop/apps/test/src/NonInteractiveSystemServerBenchmarkActivity.java b/startop/apps/test/src/NonInteractiveMicrobenchmarkActivity.java
similarity index 96%
rename from startop/apps/test/src/NonInteractiveSystemServerBenchmarkActivity.java
rename to startop/apps/test/src/NonInteractiveMicrobenchmarkActivity.java
index a2dc2cf..0162ac6 100644
--- a/startop/apps/test/src/NonInteractiveSystemServerBenchmarkActivity.java
+++ b/startop/apps/test/src/NonInteractiveMicrobenchmarkActivity.java
@@ -36,7 +36,7 @@
 import android.widget.GridLayout;
 import android.widget.TextView;
 
-public class NonInteractiveSystemServerBenchmarkActivity extends Activity {
+public class NonInteractiveMicrobenchmarkActivity extends Activity {
     ArrayList<CharSequence> benchmarkNames = new ArrayList();
     ArrayList<Runnable> benchmarkThunks = new ArrayList();
 
diff --git a/startop/apps/test/src/SystemServerBenchmarks.java b/startop/apps/test/src/SystemServerBenchmarks.java
index 25b43f4..8114bc2 100644
--- a/startop/apps/test/src/SystemServerBenchmarks.java
+++ b/startop/apps/test/src/SystemServerBenchmarks.java
@@ -57,9 +57,6 @@
     static void initializeBenchmarks(Activity parent, BenchmarkRunner benchmarks) {
         final String packageName = parent.getPackageName();
 
-        benchmarks.addBenchmark("Empty", () -> {
-        });
-
         PackageManager pm = parent.getPackageManager();
         benchmarks.addBenchmark("getInstalledApplications", () -> {
             pm.getInstalledApplications(PackageManager.MATCH_SYSTEM_ONLY);
diff --git a/telecomm/java/android/telecom/Logging/Session.java b/telecomm/java/android/telecom/Logging/Session.java
index 95a47e1..d82e93f 100644
--- a/telecomm/java/android/telecom/Logging/Session.java
+++ b/telecomm/java/android/telecom/Logging/Session.java
@@ -237,7 +237,10 @@
     // keep track of calls and bail if we hit the recursion limit
     private String getFullSessionId(int parentCount) {
         if (parentCount >= SESSION_RECURSION_LIMIT) {
-            Log.w(LOG_TAG, "getFullSessionId: Hit recursion limit!");
+            // Don't use Telecom's Log.w here or it will cause infinite recursion because it will
+            // try to add session information to this logging statement, which will cause it to hit
+            // this condition again and so on...
+            android.util.Slog.w(LOG_TAG, "getFullSessionId: Hit recursion limit!");
             return TRUNCATE_STRING + mSessionId;
         }
         // Cache mParentSession locally to prevent a concurrency problem where
@@ -265,7 +268,11 @@
         Session topNode = this;
         while (topNode.getParentSession() != null) {
             if (currParentCount >= SESSION_RECURSION_LIMIT) {
-                Log.w(LOG_TAG, "getRootSession: Hit recursion limit from " + callingMethod);
+                // Don't use Telecom's Log.w here or it will cause infinite recursion because it
+                // will try to add session information to this logging statement, which will cause
+                // it to hit this condition again and so on...
+                android.util.Slog.w(LOG_TAG, "getRootSession: Hit recursion limit from "
+                        + callingMethod);
                 break;
             }
             topNode = topNode.getParentSession();
@@ -289,7 +296,10 @@
     private void printSessionTree(int tabI, StringBuilder sb, int currChildCount) {
         // Prevent infinite recursion.
         if (currChildCount >= SESSION_RECURSION_LIMIT) {
-            Log.w(LOG_TAG, "printSessionTree: Hit recursion limit!");
+            // Don't use Telecom's Log.w here or it will cause infinite recursion because it will
+            // try to add session information to this logging statement, which will cause it to hit
+            // this condition again and so on...
+            android.util.Slog.w(LOG_TAG, "printSessionTree: Hit recursion limit!");
             sb.append(TRUNCATE_STRING);
             return;
         }
@@ -315,7 +325,10 @@
     private synchronized void getFullMethodPath(StringBuilder sb, boolean truncatePath,
             int parentCount) {
         if (parentCount >= SESSION_RECURSION_LIMIT) {
-            Log.w(LOG_TAG, "getFullMethodPath: Hit recursion limit!");
+            // Don't use Telecom's Log.w here or it will cause infinite recursion because it will
+            // try to add session information to this logging statement, which will cause it to hit
+            // this condition again and so on...
+            android.util.Slog.w(LOG_TAG, "getFullMethodPath: Hit recursion limit!");
             sb.append(TRUNCATE_STRING);
             return;
         }
diff --git a/telecomm/java/android/telecom/Logging/SessionManager.java b/telecomm/java/android/telecom/Logging/SessionManager.java
index 49c3a72..ac30058 100644
--- a/telecomm/java/android/telecom/Logging/SessionManager.java
+++ b/telecomm/java/android/telecom/Logging/SessionManager.java
@@ -202,7 +202,18 @@
         return createSubsession(false);
     }
 
-    private synchronized Session createSubsession(boolean isStartedFromActiveSession) {
+    /**
+     * Creates a new subsession based on an existing session. Will not be started until
+     * {@link #continueSession(Session, String)} or {@link #cancelSubsession(Session)} is called.
+     * <p>
+     * Only public for testing!
+     * @param isStartedFromActiveSession true if this subsession is being created for a task on the
+     *     same thread, false if it is being created for a related task on another thread.
+     * @return a new {@link Session}, call {@link #continueSession(Session, String)} to continue the
+     * session and {@link #endSession()} when done with this subsession.
+     */
+    @VisibleForTesting
+    public synchronized Session createSubsession(boolean isStartedFromActiveSession) {
         int threadId = getCallingThreadId();
         Session threadSession = mSessionMapper.get(threadId);
         if (threadSession == null) {
diff --git a/telephony/common/com/android/internal/telephony/PackageChangeReceiver.java b/telephony/common/com/android/internal/telephony/PackageChangeReceiver.java
new file mode 100644
index 0000000..922af12
--- /dev/null
+++ b/telephony/common/com/android/internal/telephony/PackageChangeReceiver.java
@@ -0,0 +1,167 @@
+/*
+ * 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.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.UserHandle;
+
+import com.android.internal.os.BackgroundThread;
+
+/**
+ * Helper class for monitoring the state of packages: adding, removing,
+ * updating, and disappearing and reappearing on the SD card.
+ */
+public abstract class PackageChangeReceiver extends BroadcastReceiver {
+    static final IntentFilter sPackageIntentFilter = new IntentFilter();
+    static {
+        sPackageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        sPackageIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        sPackageIntentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        sPackageIntentFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
+        sPackageIntentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
+        sPackageIntentFilter.addDataScheme("package");
+    }
+    Context mRegisteredContext;
+
+    /**
+     * To register the intents that needed for monitoring the state of packages
+     */
+    public void register(@NonNull Context context, @Nullable Looper thread,
+            @Nullable UserHandle user) {
+        if (mRegisteredContext != null) {
+            throw new IllegalStateException("Already registered");
+        }
+        Handler handler = (thread == null) ? BackgroundThread.getHandler() : new Handler(thread);
+        mRegisteredContext = context;
+        if (handler != null) {
+            if (user != null) {
+                context.registerReceiverAsUser(this, user, sPackageIntentFilter, null, handler);
+            } else {
+                context.registerReceiver(this, sPackageIntentFilter,
+                        null, handler);
+            }
+        } else {
+            throw new NullPointerException();
+        }
+    }
+
+    /**
+     * To unregister the intents for monitoring the state of packages
+     */
+    public void unregister() {
+        if (mRegisteredContext == null) {
+            throw new IllegalStateException("Not registered");
+        }
+        mRegisteredContext.unregisterReceiver(this);
+        mRegisteredContext = null;
+    }
+
+    /**
+     * This method is invoked when receive the Intent.ACTION_PACKAGE_ADDED
+     */
+    public void onPackageAdded(@Nullable String packageName) {
+    }
+
+    /**
+     * This method is invoked when receive the Intent.ACTION_PACKAGE_REMOVED
+     */
+    public void onPackageRemoved(@Nullable String packageName) {
+    }
+
+    /**
+     * This method is invoked when Intent.EXTRA_REPLACING as extra field is true
+     */
+    public void onPackageUpdateFinished(@Nullable String packageName) {
+    }
+
+    /**
+     * This method is invoked when receive the Intent.ACTION_PACKAGE_CHANGED or
+     * Intent.EXTRA_REPLACING as extra field is true
+     */
+    public void onPackageModified(@Nullable String packageName) {
+    }
+
+    /**
+     * This method is invoked when receive the Intent.ACTION_QUERY_PACKAGE_RESTART and
+     * Intent.ACTION_PACKAGE_RESTARTED
+     */
+    public void onHandleForceStop(@Nullable String[] packages, boolean doit) {
+    }
+
+    /**
+     * This method is invoked when receive the Intent.ACTION_PACKAGE_REMOVED
+     */
+    public void onPackageDisappeared() {
+    }
+
+    /**
+     * This method is invoked when receive the Intent.ACTION_PACKAGE_ADDED
+     */
+    public void onPackageAppeared() {
+    }
+
+    @Override
+    public void onReceive(@Nullable Context context, @Nullable Intent intent) {
+        String action = intent.getAction();
+
+        if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
+            String pkg = getPackageName(intent);
+            if (pkg != null) {
+                if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+                    onPackageUpdateFinished(pkg);
+                    onPackageModified(pkg);
+                } else {
+                    onPackageAdded(pkg);
+                }
+                onPackageAppeared();
+            }
+        } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+            String pkg = getPackageName(intent);
+            if (pkg != null) {
+                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+                    onPackageRemoved(pkg);
+                }
+                onPackageDisappeared();
+            }
+        } else if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
+            String pkg = getPackageName(intent);
+            if (pkg != null) {
+                onPackageModified(pkg);
+            }
+        } else if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) {
+            String[] disappearingPackages = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
+            onHandleForceStop(disappearingPackages, false);
+        } else if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
+            String[] disappearingPackages = new String[] {getPackageName(intent)};
+            onHandleForceStop(disappearingPackages, true);
+        }
+    }
+
+    String getPackageName(Intent intent) {
+        Uri uri = intent.getData();
+        String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
+        return pkg;
+    }
+}
diff --git a/telephony/common/com/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java
index f4eae8e..70ce1bf 100644
--- a/telephony/common/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/common/com/android/internal/telephony/SmsApplication.java
@@ -39,11 +39,11 @@
 import android.os.UserHandle;
 import android.provider.Telephony;
 import android.provider.Telephony.Sms.Intents;
+import android.telephony.PackageChangeReceiver;
 import android.telephony.Rlog;
 import android.telephony.TelephonyManager;
 import android.util.Log;
 
-import com.android.internal.content.PackageMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 
@@ -777,7 +777,7 @@
      * Tracks package changes and ensures that the default SMS app is always configured to be the
      * preferred activity for SENDTO sms/mms intents.
      */
-    private static final class SmsPackageMonitor extends PackageMonitor {
+    private static final class SmsPackageMonitor extends PackageChangeReceiver {
         final Context mContext;
 
         public SmsPackageMonitor(Context context) {
@@ -786,12 +786,12 @@
         }
 
         @Override
-        public void onPackageDisappeared(String packageName, int reason) {
+        public void onPackageDisappeared() {
             onPackageChanged();
         }
 
         @Override
-        public void onPackageAppeared(String packageName, int reason) {
+        public void onPackageAppeared() {
             onPackageChanged();
         }
 
@@ -824,7 +824,7 @@
 
     public static void initSmsPackageMonitor(Context context) {
         sSmsPackageMonitor = new SmsPackageMonitor(context);
-        sSmsPackageMonitor.register(context, context.getMainLooper(), UserHandle.ALL, false);
+        sSmsPackageMonitor.register(context, context.getMainLooper(), UserHandle.ALL);
     }
 
     @UnsupportedAppUsage
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index a315e6d..46c89d2 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -821,13 +821,6 @@
             "always_show_emergency_alert_onoff_bool";
 
     /**
-     * The flag to disable cell broadcast severe alert when extreme alert is disabled.
-     * @hide
-     */
-    public static final String KEY_DISABLE_SEVERE_WHEN_EXTREME_DISABLED_BOOL =
-            "disable_severe_when_extreme_disabled_bool";
-
-    /**
      * The data call retry configuration for different types of APN.
      * @hide
      */
@@ -3455,7 +3448,6 @@
         sDefaults.putStringArray(KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY, null);
         sDefaults.putBoolean(KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL, false);
         sDefaults.putBoolean(KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL, false);
-        sDefaults.putBoolean(KEY_DISABLE_SEVERE_WHEN_EXTREME_DISABLED_BOOL, true);
         sDefaults.putStringArray(KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS, new String[]{
                 "default:default_randomization=2000,5000,10000,20000,40000,80000:5000,160000:5000,"
                         + "320000:5000,640000:5000,1280000:5000,1800000:5000",
@@ -3797,7 +3789,8 @@
                         + " ICarrierConfigLoader is null");
                 return null;
             }
-            return loader.getConfigForSubId(subId, mContext.getOpPackageName());
+            return loader.getConfigForSubIdWithFeature(subId, mContext.getOpPackageName(),
+                    mContext.getFeatureId());
         } catch (RemoteException ex) {
             Rlog.e(TAG, "Error getting config for subId " + subId + ": "
                     + ex.toString());
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index 407ced7..270eafe 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -203,9 +203,12 @@
     }
 
     /**
+     * Get whether network has configured carrier aggregation or not.
+     *
      * @return {@code true} if using carrier aggregation.
      * @hide
      */
+    @SystemApi
     public boolean isUsingCarrierAggregation() {
         return mIsUsingCarrierAggregation;
     }
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 56b7236..fc717e7 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -323,9 +323,12 @@
     public @Domain int getDomain() { return mDomain; }
 
     /**
+     * Get the 5G NR connection state.
+     *
      * @return the 5G NR connection state.
      * @hide
      */
+    @SystemApi
     public @NRState int getNrState() {
         return mNrState;
     }
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index f503348..9ace86c 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1384,9 +1384,12 @@
     }
 
     /**
+     * Get the 5G NR frequency range the device is currently registered.
+     *
      * @return the frequency range of 5G NR.
      * @hide
      */
+    @SystemApi
     public @FrequencyRange int getNrFrequencyRange() {
         return mNrFrequencyRange;
     }
@@ -1464,44 +1467,44 @@
     /** @hide */
     public static int rilRadioTechnologyToNetworkType(@RilRadioTechnology int rat) {
         switch(rat) {
-            case ServiceState.RIL_RADIO_TECHNOLOGY_GPRS:
+            case RIL_RADIO_TECHNOLOGY_GPRS:
                 return TelephonyManager.NETWORK_TYPE_GPRS;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_EDGE:
+            case RIL_RADIO_TECHNOLOGY_EDGE:
                 return TelephonyManager.NETWORK_TYPE_EDGE;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_UMTS:
+            case RIL_RADIO_TECHNOLOGY_UMTS:
                 return TelephonyManager.NETWORK_TYPE_UMTS;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA:
+            case RIL_RADIO_TECHNOLOGY_HSDPA:
                 return TelephonyManager.NETWORK_TYPE_HSDPA;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA:
+            case RIL_RADIO_TECHNOLOGY_HSUPA:
                 return TelephonyManager.NETWORK_TYPE_HSUPA;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_HSPA:
+            case RIL_RADIO_TECHNOLOGY_HSPA:
                 return TelephonyManager.NETWORK_TYPE_HSPA;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_IS95A:
-            case ServiceState.RIL_RADIO_TECHNOLOGY_IS95B:
+            case RIL_RADIO_TECHNOLOGY_IS95A:
+            case RIL_RADIO_TECHNOLOGY_IS95B:
                 return TelephonyManager.NETWORK_TYPE_CDMA;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT:
+            case RIL_RADIO_TECHNOLOGY_1xRTT:
                 return TelephonyManager.NETWORK_TYPE_1xRTT;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0:
+            case RIL_RADIO_TECHNOLOGY_EVDO_0:
                 return TelephonyManager.NETWORK_TYPE_EVDO_0;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A:
+            case RIL_RADIO_TECHNOLOGY_EVDO_A:
                 return TelephonyManager.NETWORK_TYPE_EVDO_A;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B:
+            case RIL_RADIO_TECHNOLOGY_EVDO_B:
                 return TelephonyManager.NETWORK_TYPE_EVDO_B;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD:
+            case RIL_RADIO_TECHNOLOGY_EHRPD:
                 return TelephonyManager.NETWORK_TYPE_EHRPD;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_LTE:
+            case RIL_RADIO_TECHNOLOGY_LTE:
                 return TelephonyManager.NETWORK_TYPE_LTE;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP:
+            case RIL_RADIO_TECHNOLOGY_HSPAP:
                 return TelephonyManager.NETWORK_TYPE_HSPAP;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_GSM:
+            case RIL_RADIO_TECHNOLOGY_GSM:
                 return TelephonyManager.NETWORK_TYPE_GSM;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA:
+            case RIL_RADIO_TECHNOLOGY_TD_SCDMA:
                 return TelephonyManager.NETWORK_TYPE_TD_SCDMA;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN:
+            case RIL_RADIO_TECHNOLOGY_IWLAN:
                 return TelephonyManager.NETWORK_TYPE_IWLAN;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA:
+            case RIL_RADIO_TECHNOLOGY_LTE_CA:
                 return TelephonyManager.NETWORK_TYPE_LTE_CA;
-            case ServiceState.RIL_RADIO_TECHNOLOGY_NR:
+            case RIL_RADIO_TECHNOLOGY_NR:
                 return TelephonyManager.NETWORK_TYPE_NR;
             default:
                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
@@ -1546,45 +1549,45 @@
     public static int networkTypeToRilRadioTechnology(int networkType) {
         switch(networkType) {
             case TelephonyManager.NETWORK_TYPE_GPRS:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_GPRS;
+                return RIL_RADIO_TECHNOLOGY_GPRS;
             case TelephonyManager.NETWORK_TYPE_EDGE:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_EDGE;
+                return RIL_RADIO_TECHNOLOGY_EDGE;
             case TelephonyManager.NETWORK_TYPE_UMTS:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_UMTS;
+                return RIL_RADIO_TECHNOLOGY_UMTS;
             case TelephonyManager.NETWORK_TYPE_HSDPA:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA;
+                return RIL_RADIO_TECHNOLOGY_HSDPA;
             case TelephonyManager.NETWORK_TYPE_HSUPA:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA;
+                return RIL_RADIO_TECHNOLOGY_HSUPA;
             case TelephonyManager.NETWORK_TYPE_HSPA:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_HSPA;
+                return RIL_RADIO_TECHNOLOGY_HSPA;
             case TelephonyManager.NETWORK_TYPE_CDMA:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_IS95A;
+                return RIL_RADIO_TECHNOLOGY_IS95A;
             case TelephonyManager.NETWORK_TYPE_1xRTT:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT;
+                return RIL_RADIO_TECHNOLOGY_1xRTT;
             case TelephonyManager.NETWORK_TYPE_EVDO_0:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0;
+                return RIL_RADIO_TECHNOLOGY_EVDO_0;
             case TelephonyManager.NETWORK_TYPE_EVDO_A:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A;
+                return RIL_RADIO_TECHNOLOGY_EVDO_A;
             case TelephonyManager.NETWORK_TYPE_EVDO_B:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B;
+                return RIL_RADIO_TECHNOLOGY_EVDO_B;
             case TelephonyManager.NETWORK_TYPE_EHRPD:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD;
+                return RIL_RADIO_TECHNOLOGY_EHRPD;
             case TelephonyManager.NETWORK_TYPE_LTE:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
+                return RIL_RADIO_TECHNOLOGY_LTE;
             case TelephonyManager.NETWORK_TYPE_HSPAP:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP;
+                return RIL_RADIO_TECHNOLOGY_HSPAP;
             case TelephonyManager.NETWORK_TYPE_GSM:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_GSM;
+                return RIL_RADIO_TECHNOLOGY_GSM;
             case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA;
+                return RIL_RADIO_TECHNOLOGY_TD_SCDMA;
             case TelephonyManager.NETWORK_TYPE_IWLAN:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN;
+                return RIL_RADIO_TECHNOLOGY_IWLAN;
             case TelephonyManager.NETWORK_TYPE_LTE_CA:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA;
+                return RIL_RADIO_TECHNOLOGY_LTE_CA;
             case TelephonyManager.NETWORK_TYPE_NR:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_NR;
+                return RIL_RADIO_TECHNOLOGY_NR;
             default:
-                return ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
+                return RIL_RADIO_TECHNOLOGY_UNKNOWN;
         }
     }
 
@@ -1950,8 +1953,11 @@
     /**
      * The current registered raw data network operator name in long alphanumeric format.
      *
+     * @return long raw name of operator, null if unregistered or unknown
      * @hide
      */
+    @Nullable
+    @SystemApi
     public String getOperatorAlphaLongRaw() {
         return mOperatorAlphaLongRaw;
     }
@@ -1966,8 +1972,11 @@
     /**
      * The current registered raw data network operator name in short alphanumeric format.
      *
+     * @return short raw name of operator, null if unregistered or unknown
      * @hide
      */
+    @Nullable
+    @SystemApi
     public String getOperatorAlphaShortRaw() {
         return mOperatorAlphaShortRaw;
     }
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 1309b4d..89c4e90 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -514,7 +514,6 @@
             throw new IllegalArgumentException("Invalid message body");
         }
 
-        final Context context = ActivityThread.currentApplication().getApplicationContext();
         // We will only show the SMS disambiguation dialog in the case that the message is being
         // persisted. This is for two reasons:
         // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific
@@ -623,7 +622,6 @@
 
         final int finalPriority = priority;
         final int finalValidity = validityPeriod;
-        final Context context = ActivityThread.currentApplication().getApplicationContext();
         // We will only show the SMS disambiguation dialog in the case that the message is being
         // persisted. This is for two reasons:
         // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific
@@ -927,7 +925,6 @@
         }
 
         if (parts.size() > 1) {
-            final Context context = ActivityThread.currentApplication().getApplicationContext();
             // We will only show the SMS disambiguation dialog in the case that the message is being
             // persisted. This is for two reasons:
             // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific
@@ -1168,7 +1165,6 @@
         if (parts.size() > 1) {
             final int finalPriority = priority;
             final int finalValidity = validityPeriod;
-            final Context context = ActivityThread.currentApplication().getApplicationContext();
             if (persistMessage) {
                 resolveSubscriptionForOperation(new SubscriptionResolverResult() {
                     @Override
@@ -1325,7 +1321,6 @@
             throw new IllegalArgumentException("Invalid message data");
         }
 
-        final Context context = ActivityThread.currentApplication().getApplicationContext();
         resolveSubscriptionForOperation(new SubscriptionResolverResult() {
             @Override
             public void onSuccess(int subId) {
@@ -2659,7 +2654,7 @@
             ISms iccISms = getISmsServiceOrThrow();
             if (iccISms != null) {
                 return iccISms.checkSmsShortCodeDestination(getSubscriptionId(),
-                        ActivityThread.currentPackageName(), destAddress, countryIso);
+                        ActivityThread.currentPackageName(), null, destAddress, countryIso);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "checkSmsShortCodeDestination() RemoteException", e);
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index f527bc3..9eff809 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -654,6 +654,7 @@
      * Return whether the subscription's group is disabled.
      * @hide
      */
+    @SystemApi
     public boolean isGroupDisabled() {
         return mIsGroupDisabled;
     }
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 1770671..3d63e4a 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1154,7 +1154,8 @@
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                subInfo = iSub.getActiveSubscriptionInfo(subId, mContext.getOpPackageName());
+                subInfo = iSub.getActiveSubscriptionInfo(subId, mContext.getOpPackageName(),
+                        mContext.getFeatureId());
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1182,7 +1183,8 @@
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                result = iSub.getActiveSubscriptionInfoForIccId(iccId, mContext.getOpPackageName());
+                result = iSub.getActiveSubscriptionInfoForIccId(iccId, mContext.getOpPackageName(),
+                        mContext.getFeatureId());
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1216,7 +1218,7 @@
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
                 result = iSub.getActiveSubscriptionInfoForSimSlotIndex(slotIndex,
-                        mContext.getOpPackageName());
+                        mContext.getOpPackageName(), mContext.getFeatureId());
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1239,7 +1241,8 @@
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                result = iSub.getAllSubInfoList(mContext.getOpPackageName());
+                result = iSub.getAllSubInfoList(mContext.getOpPackageName(),
+                        mContext.getFeatureId());
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1283,18 +1286,39 @@
     }
 
     /**
-     * This is similar to {@link #getActiveSubscriptionInfoList()}, but if userVisibleOnly
-     * is true, it will filter out the hidden subscriptions.
+     * Get both hidden and visible SubscriptionInfo(s) of the currently active SIM(s).
+     * The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex}
+     * then by {@link SubscriptionInfo#getSubscriptionId}.
      *
-     * @hide
+     * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     * or that the calling app has carrier privileges (see
+     * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, only records accessible
+     * to the calling app are returned.
+     *
+     * @return Sorted list of the currently available {@link SubscriptionInfo}
+     * records on the device.
+     * This is similar to {@link #getActiveSubscriptionInfoList} except that it will return
+     * both active and hidden SubscriptionInfos.
+     *
      */
-    public List<SubscriptionInfo> getActiveSubscriptionInfoList(boolean userVisibleOnly) {
+    public @Nullable List<SubscriptionInfo> getActiveAndHiddenSubscriptionInfoList() {
+        return getActiveSubscriptionInfoList(/* userVisibleonly */false);
+    }
+
+    /**
+    * This is similar to {@link #getActiveSubscriptionInfoList()}, but if userVisibleOnly
+    * is true, it will filter out the hidden subscriptions.
+    *
+    * @hide
+    */
+    public @Nullable List<SubscriptionInfo> getActiveSubscriptionInfoList(boolean userVisibleOnly) {
         List<SubscriptionInfo> activeList = null;
 
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                activeList = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName());
+                activeList = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName(),
+                        mContext.getFeatureId());
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1344,7 +1368,8 @@
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                result = iSub.getAvailableSubscriptionInfoList(mContext.getOpPackageName());
+                result = iSub.getAvailableSubscriptionInfoList(mContext.getOpPackageName(),
+                        mContext.getFeatureId());
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1461,7 +1486,8 @@
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                result = iSub.getAllSubInfoCount(mContext.getOpPackageName());
+                result = iSub.getAllSubInfoCount(mContext.getOpPackageName(),
+                        mContext.getFeatureId());
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1489,7 +1515,8 @@
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                result = iSub.getActiveSubInfoCount(mContext.getOpPackageName());
+                result = iSub.getActiveSubInfoCount(mContext.getOpPackageName(),
+                        mContext.getFeatureId());
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -2227,7 +2254,7 @@
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
                 resultValue = iSub.getSubscriptionProperty(subId, propKey,
-                        context.getOpPackageName());
+                        context.getOpPackageName(), context.getFeatureId());
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -2350,7 +2377,8 @@
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                return iSub.isActiveSubId(subId, mContext.getOpPackageName());
+                return iSub.isActiveSubId(subId, mContext.getOpPackageName(),
+                        mContext.getFeatureId());
             }
         } catch (RemoteException ex) {
         }
@@ -2715,13 +2743,14 @@
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public @NonNull List<SubscriptionInfo> getOpportunisticSubscriptions() {
-        String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        String contextFeature = mContext != null ? mContext.getFeatureId() : null;
         List<SubscriptionInfo> subInfoList = null;
 
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                subInfoList = iSub.getOpportunisticSubscriptions(pkgForDebug);
+                subInfoList = iSub.getOpportunisticSubscriptions(contextPkg, contextFeature);
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -2959,7 +2988,8 @@
     @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
     public @NonNull List<SubscriptionInfo> getSubscriptionsInGroup(@NonNull ParcelUuid groupUuid) {
         Preconditions.checkNotNull(groupUuid, "groupUuid can't be null");
-        String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        String contextFeature = mContext != null ? mContext.getFeatureId() : null;
         if (VDBG) {
             logd("[getSubscriptionsInGroup]+ groupUuid:" + groupUuid);
         }
@@ -2968,7 +2998,7 @@
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                result = iSub.getSubscriptionsInGroup(groupUuid, pkgForDebug);
+                result = iSub.getSubscriptionsInGroup(groupUuid, contextPkg, contextFeature);
             } else {
                 if (!isSystemProcess()) {
                     throw new IllegalStateException("telephony service is null.");
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 864bf03..64b5aa5 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1689,7 +1689,8 @@
         if (telephony == null) return null;
 
         try {
-            return telephony.getDeviceSoftwareVersionForSlot(slotIndex, getOpPackageName());
+            return telephony.getDeviceSoftwareVersionForSlot(slotIndex, getOpPackageName(),
+                    getFeatureId());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -1730,7 +1731,8 @@
             ITelephony telephony = getITelephony();
             if (telephony == null)
                 return null;
-            return telephony.getDeviceId(mContext.getOpPackageName());
+            return telephony.getDeviceIdWithFeature(mContext.getOpPackageName(),
+                    mContext.getFeatureId());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -1774,7 +1776,8 @@
             IPhoneSubInfo info = getSubscriberInfo();
             if (info == null)
                 return null;
-            return info.getDeviceIdForPhone(slotIndex, mContext.getOpPackageName());
+            return info.getDeviceIdForPhone(slotIndex, mContext.getOpPackageName(),
+                    mContext.getFeatureId());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -1832,7 +1835,7 @@
         if (telephony == null) return null;
 
         try {
-            return telephony.getImeiForSlot(slotIndex, getOpPackageName());
+            return telephony.getImeiForSlot(slotIndex, getOpPackageName(), getFeatureId());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -1926,7 +1929,7 @@
         if (telephony == null) return null;
 
         try {
-            String meid = telephony.getMeidForSlot(slotIndex, getOpPackageName());
+            String meid = telephony.getMeidForSlot(slotIndex, getOpPackageName(), getFeatureId());
             if (TextUtils.isEmpty(meid)) {
                 Log.d(TAG, "getMeid: return null because MEID is not available");
                 return null;
@@ -2027,7 +2030,8 @@
             IPhoneSubInfo info = getSubscriberInfo();
             if (info == null)
                 return null;
-            String nai = info.getNaiForSubscriber(subId, mContext.getOpPackageName());
+            String nai = info.getNaiForSubscriber(subId, mContext.getOpPackageName(),
+                    mContext.getFeatureId());
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Rlog.v(TAG, "Nai = " + nai);
             }
@@ -2578,7 +2582,7 @@
             ITelephony telephony = getITelephony();
             if (telephony == null) return "";
             return telephony.getNetworkCountryIsoForPhone(getPhoneId(),
-                    null /* no permission check */);
+                    null /* no permission check */, null);
         } catch (RemoteException ex) {
             return "";
         }
@@ -2618,7 +2622,8 @@
 
             ITelephony telephony = getITelephony();
             if (telephony == null) return "";
-            return telephony.getNetworkCountryIsoForPhone(slotIndex, getOpPackageName());
+            return telephony.getNetworkCountryIsoForPhone(slotIndex, getOpPackageName(),
+                    getFeatureId());
         } catch (RemoteException ex) {
             return "";
         }
@@ -2722,7 +2727,8 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.getNetworkTypeForSubscriber(subId, getOpPackageName());
+                return telephony.getNetworkTypeForSubscriber(subId, getOpPackageName(),
+                        getFeatureId());
             } else {
                 // This can happen when the ITelephony interface is not up yet.
                 return NETWORK_TYPE_UNKNOWN;
@@ -2786,7 +2792,8 @@
         try{
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.getDataNetworkTypeForSubscriber(subId, getOpPackageName());
+                return telephony.getDataNetworkTypeForSubscriber(subId, getOpPackageName(),
+                        getFeatureId());
             } else {
                 // This can happen when the ITelephony interface is not up yet.
                 return NETWORK_TYPE_UNKNOWN;
@@ -2822,7 +2829,8 @@
         try{
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.getVoiceNetworkTypeForSubscriber(subId, getOpPackageName());
+                return telephony.getVoiceNetworkTypeForSubscriber(subId, getOpPackageName(),
+                        getFeatureId());
             } else {
                 // This can happen when the ITelephony interface is not up yet.
                 return NETWORK_TYPE_UNKNOWN;
@@ -3566,13 +3574,36 @@
     }
 
     /**
+     * Returns the ISO-3166 country code equivalent for the SIM provider's country code
+     * of the default subscription
+     * <p>
+     * The ISO-3166 country code is provided in lowercase 2 character format.
+     * @return the lowercase 2 character ISO-3166 country code, or empty string is not available.
+     * <p>
+     * Note: This API is introduced to unblock mainlining work as the following APIs in
+     * Linkify.java invokes getSimCountryIso() without a context. TODO(Bug 144576376): remove
+     * this API once the following APIs are redesigned to access telephonymanager with a context.
+     *
+     * {@link Linkify#addLinks(@NonNull Spannable text, @LinkifyMask int mask)}
+     * {@link Linkify#addLinks(@NonNull Spannable text, @LinkifyMask int mask,
+               @Nullable Function<String, URLSpan> urlSpanFactory)}
+     *
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    public static String getDefaultSimCountryIso() {
+        return getSimCountryIso(SubscriptionManager.getDefaultSubscriptionId());
+    }
+
+    /**
      * Returns the ISO country code equivalent for the SIM provider's country code.
      *
      * @param subId for which SimCountryIso is returned
      * @hide
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
-    public String getSimCountryIso(int subId) {
+    public static String getSimCountryIso(int subId) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
         return getSimCountryIsoForPhone(phoneId);
     }
@@ -3583,7 +3614,7 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public String getSimCountryIsoForPhone(int phoneId) {
+    public static String getSimCountryIsoForPhone(int phoneId) {
         return getTelephonyProperty(phoneId, TelephonyProperties.icc_operator_iso_country(), "");
     }
 
@@ -3647,7 +3678,8 @@
             IPhoneSubInfo info = getSubscriberInfo();
             if (info == null)
                 return null;
-            return info.getIccSerialNumberForSubscriber(subId, mContext.getOpPackageName());
+            return info.getIccSerialNumberForSubscriber(subId, mContext.getOpPackageName(),
+                    mContext.getFeatureId());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -3691,7 +3723,8 @@
             ITelephony telephony = getITelephony();
             if (telephony == null)
                 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
-            return telephony.getLteOnCdmaModeForSubscriber(subId, getOpPackageName());
+            return telephony.getLteOnCdmaModeForSubscriber(subId, getOpPackageName(),
+                    getFeatureId());
         } catch (RemoteException ex) {
             // Assume no ICC card if remote exception which shouldn't happen
             return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
@@ -3919,7 +3952,8 @@
             IPhoneSubInfo info = getSubscriberInfo();
             if (info == null)
                 return null;
-            return info.getSubscriberIdForSubscriber(subId, mContext.getOpPackageName());
+            return info.getSubscriberIdForSubscriber(subId, mContext.getOpPackageName(),
+                    mContext.getFeatureId());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -4086,7 +4120,8 @@
             IPhoneSubInfo info = getSubscriberInfo();
             if (info == null)
                 return null;
-            return info.getGroupIdLevel1ForSubscriber(getSubId(), mContext.getOpPackageName());
+            return info.getGroupIdLevel1ForSubscriber(getSubId(), mContext.getOpPackageName(),
+                    mContext.getFeatureId());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -4109,7 +4144,8 @@
             IPhoneSubInfo info = getSubscriberInfo();
             if (info == null)
                 return null;
-            return info.getGroupIdLevel1ForSubscriber(subId, mContext.getOpPackageName());
+            return info.getGroupIdLevel1ForSubscriber(subId, mContext.getOpPackageName(),
+                    mContext.getFeatureId());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -4159,7 +4195,8 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
-                number = telephony.getLine1NumberForDisplay(subId, mContext.getOpPackageName());
+                number = telephony.getLine1NumberForDisplay(subId, mContext.getOpPackageName(),
+                         mContext.getFeatureId());
         } catch (RemoteException ex) {
         } catch (NullPointerException ex) {
         }
@@ -4170,7 +4207,8 @@
             IPhoneSubInfo info = getSubscriberInfo();
             if (info == null)
                 return null;
-            return info.getLine1NumberForSubscriber(subId, mContext.getOpPackageName());
+            return info.getLine1NumberForSubscriber(subId, mContext.getOpPackageName(),
+                    mContext.getFeatureId());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -4249,7 +4287,7 @@
             ITelephony telephony = getITelephony();
             if (telephony != null)
                 alphaTag = telephony.getLine1AlphaTagForDisplay(subId,
-                        getOpPackageName());
+                        getOpPackageName(), getFeatureId());
         } catch (RemoteException ex) {
         } catch (NullPointerException ex) {
         }
@@ -4260,7 +4298,8 @@
             IPhoneSubInfo info = getSubscriberInfo();
             if (info == null)
                 return null;
-            return info.getLine1AlphaTagForSubscriber(subId, getOpPackageName());
+            return info.getLine1AlphaTagForSubscriber(subId, getOpPackageName(),
+                    getFeatureId());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -4289,7 +4328,8 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
-                return telephony.getMergedSubscriberIds(getSubId(), getOpPackageName());
+                return telephony.getMergedSubscriberIds(getSubId(), getOpPackageName(),
+                        getFeatureId());
         } catch (RemoteException ex) {
         } catch (NullPointerException ex) {
         }
@@ -4344,7 +4384,7 @@
             IPhoneSubInfo info = getSubscriberInfo();
             if (info == null)
                 return null;
-            return info.getMsisdnForSubscriber(subId, getOpPackageName());
+            return info.getMsisdnForSubscriber(subId, getOpPackageName(), getFeatureId());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -4378,7 +4418,8 @@
             IPhoneSubInfo info = getSubscriberInfo();
             if (info == null)
                 return null;
-            return info.getVoiceMailNumberForSubscriber(subId, getOpPackageName());
+            return info.getVoiceMailNumberForSubscriber(subId, getOpPackageName(),
+                    getFeatureId());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -4502,8 +4543,8 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony
-                        .getVisualVoicemailPackageName(mContext.getOpPackageName(), getSubId());
+                return telephony.getVisualVoicemailPackageName(mContext.getOpPackageName(),
+                        getFeatureId(), getSubId());
             }
         } catch (RemoteException ex) {
         } catch (NullPointerException ex) {
@@ -4950,7 +4991,8 @@
             ITelephony telephony = getITelephony();
             if (telephony == null)
                 return 0;
-            return telephony.getVoiceMessageCountForSubscriber(subId, getOpPackageName());
+            return telephony.getVoiceMessageCountForSubscriber(subId, getOpPackageName(),
+                    getFeatureId());
         } catch (RemoteException ex) {
             return 0;
         } catch (NullPointerException ex) {
@@ -4986,7 +5028,8 @@
             IPhoneSubInfo info = getSubscriberInfo();
             if (info == null)
                 return null;
-            return info.getVoiceMailAlphaTagForSubscriber(subId, getOpPackageName());
+            return info.getVoiceMailAlphaTagForSubscriber(subId, getOpPackageName(),
+                    getFeatureId());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -5365,7 +5408,7 @@
                 } else if (listener.mSubId != null) {
                     subId = listener.mSubId;
                 }
-                registry.listenForSubscriber(subId, getOpPackageName(),
+                registry.listenForSubscriber(subId, getOpPackageName(), getFeatureId(),
                         listener.callback, events, notifyNow);
             } else {
                 Rlog.w(TAG, "telephony registry not ready.");
@@ -5395,7 +5438,8 @@
             ITelephony telephony = getITelephony();
             if (telephony == null)
                 return -1;
-            return telephony.getCdmaEriIconIndexForSubscriber(subId, getOpPackageName());
+            return telephony.getCdmaEriIconIndexForSubscriber(subId, getOpPackageName(),
+                    getFeatureId());
         } catch (RemoteException ex) {
             // the phone process is restarting.
             return -1;
@@ -5430,7 +5474,8 @@
             ITelephony telephony = getITelephony();
             if (telephony == null)
                 return -1;
-            return telephony.getCdmaEriIconModeForSubscriber(subId, getOpPackageName());
+            return telephony.getCdmaEriIconModeForSubscriber(subId, getOpPackageName(),
+                    getFeatureId());
         } catch (RemoteException ex) {
             // the phone process is restarting.
             return -1;
@@ -5461,7 +5506,8 @@
             ITelephony telephony = getITelephony();
             if (telephony == null)
                 return null;
-            return telephony.getCdmaEriTextForSubscriber(subId, getOpPackageName());
+            return telephony.getCdmaEriTextForSubscriber(subId, getOpPackageName(),
+                    getFeatureId());
         } catch (RemoteException ex) {
             // the phone process is restarting.
             return null;
@@ -6964,7 +7010,8 @@
             ITelephony telephony = getITelephony();
             if (telephony == null)
                 return null;
-            return telephony.getForbiddenPlmns(subId, appType, mContext.getOpPackageName());
+            return telephony.getForbiddenPlmns(subId, appType, mContext.getOpPackageName(),
+                    getFeatureId());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -6997,7 +7044,7 @@
             ITelephony telephony = getITelephony();
             if (telephony == null) return 0;
             return telephony.setForbiddenPlmns(
-                    getSubId(), APPTYPE_USIM, fplmns, getOpPackageName());
+                    getSubId(), APPTYPE_USIM, fplmns, getOpPackageName(), getFeatureId());
         } catch (RemoteException ex) {
             Rlog.e(TAG, "setForbiddenPlmns RemoteException: " + ex.getMessage());
         } catch (NullPointerException ex) {
@@ -7018,7 +7065,7 @@
             ITelephony telephony = getITelephony();
             if (telephony == null)
                 return new String[0];
-            return telephony.getPcscfAddress(apnType, getOpPackageName());
+            return telephony.getPcscfAddress(apnType, getOpPackageName(), getFeatureId());
         } catch (RemoteException e) {
             return new String[0];
         }
@@ -8249,7 +8296,7 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
-                return telephony.isRadioOn(getOpPackageName());
+                return telephony.isRadioOnWithFeature(getOpPackageName(), getFeatureId());
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#isRadioOn", e);
         }
@@ -8524,7 +8571,8 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.getRadioPowerState(getSlotIndex(), mContext.getOpPackageName());
+                return telephony.getRadioPowerState(getSlotIndex(), mContext.getOpPackageName(),
+                        mContext.getFeatureId());
             }
         } catch (RemoteException ex) {
             // This could happen if binder process crashes.
@@ -8882,7 +8930,7 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
-                return telephony.isVideoCallingEnabled(getOpPackageName());
+                return telephony.isVideoCallingEnabled(getOpPackageName(), getFeatureId());
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#isVideoCallingEnabled", e);
         }
@@ -8898,7 +8946,8 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.canChangeDtmfToneLength(mSubId, getOpPackageName());
+                return telephony.canChangeDtmfToneLength(mSubId, getOpPackageName(),
+                        getFeatureId());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#canChangeDtmfToneLength", e);
@@ -8917,7 +8966,7 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.isWorldPhone(mSubId, getOpPackageName());
+                return telephony.isWorldPhone(mSubId, getOpPackageName(), getFeatureId());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#isWorldPhone", e);
@@ -9640,7 +9689,7 @@
             ITelephony service = getITelephony();
             if (service != null) {
                 retval = service.getSubIdForPhoneAccountHandle(
-                        phoneAccountHandle, mContext.getOpPackageName());
+                        phoneAccountHandle, mContext.getOpPackageName(), mContext.getFeatureId());
             }
         } catch (RemoteException ex) {
             Log.e(TAG, "getSubscriptionId RemoteException", ex);
@@ -10502,7 +10551,7 @@
         try {
             ITelephony service = getITelephony();
             if (service != null) {
-                return service.getClientRequestStats(getOpPackageName(), subId);
+                return service.getClientRequestStats(getOpPackageName(), getFeatureId(), subId);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#getClientRequestStats", e);
@@ -10790,7 +10839,7 @@
             ITelephony telephony = getITelephony();
             if (telephony != null) {
                 return telephony.getNumberOfModemsWithSimultaneousDataConnections(
-                        getSubId(), getOpPackageName());
+                        getSubId(), getOpPackageName(), getFeatureId());
             }
         } catch (RemoteException ex) {
             // This could happen if binder process crashes.
@@ -10813,6 +10862,7 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @SystemApi
     public boolean setOpportunisticNetworkState(boolean enable) {
         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
         boolean ret = false;
@@ -10840,6 +10890,7 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SystemApi
     public boolean isOpportunisticNetworkEnabled() {
         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
         boolean isEnabled = false;
@@ -11092,7 +11143,8 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.getEmergencyNumberList(mContext.getOpPackageName());
+                return telephony.getEmergencyNumberList(mContext.getOpPackageName(),
+                        mContext.getFeatureId());
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
@@ -11147,7 +11199,7 @@
             ITelephony telephony = getITelephony();
             if (telephony != null) {
                 emergencyNumberList = telephony.getEmergencyNumberList(
-                        mContext.getOpPackageName());
+                        mContext.getOpPackageName(), mContext.getFeatureId());
                 if (emergencyNumberList != null) {
                     for (Integer subscriptionId : emergencyNumberList.keySet()) {
                         List<EmergencyNumber> numberList = emergencyNumberList.get(subscriptionId);
@@ -11368,12 +11420,14 @@
             android.Manifest.permission.READ_PHONE_STATE
     })
     public int getPreferredOpportunisticDataSubscription() {
-        String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        String packageName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        String featureId = mContext != null ? mContext.getFeatureId() : null;
         int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
         try {
             IOns iOpportunisticNetworkService = getIOns();
             if (iOpportunisticNetworkService != null) {
-                subId = iOpportunisticNetworkService.getPreferredDataSubscriptionId(pkgForDebug);
+                subId = iOpportunisticNetworkService.getPreferredDataSubscriptionId(
+                        packageName, featureId);
             }
         } catch (RemoteException ex) {
             Rlog.e(TAG, "getPreferredDataSubscriptionId RemoteException", ex);
@@ -11477,11 +11531,13 @@
      * @param slotIndex which slot it's checking.
      * @hide
      */
+    @SystemApi
     public boolean isModemEnabledForSlot(int slotIndex) {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.isModemEnabledForSlot(slotIndex, mContext.getOpPackageName());
+                return telephony.isModemEnabledForSlot(slotIndex, mContext.getOpPackageName(),
+                        mContext.getFeatureId());
             }
         } catch (RemoteException ex) {
             Log.e(TAG, "enableModem RemoteException", ex);
@@ -11586,7 +11642,7 @@
         try {
             ITelephony service = getITelephony();
             if (service != null) {
-                return service.isMultiSimSupported(getOpPackageName());
+                return service.isMultiSimSupported(getOpPackageName(), getFeatureId());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "isMultiSimSupported RemoteException", e);
@@ -11638,7 +11694,7 @@
             ITelephony service = getITelephony();
             if (service != null) {
                 return service.doesSwitchMultiSimConfigTriggerReboot(getSubId(),
-                        getOpPackageName());
+                        getOpPackageName(), getFeatureId());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "doesSwitchMultiSimConfigTriggerReboot RemoteException", e);
diff --git a/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl b/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl
index 8e50a8f..ee09c1c 100644
--- a/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl
+++ b/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl
@@ -23,9 +23,13 @@
  */
 interface ICarrierConfigLoader {
 
+    /** @deprecated Use {@link #getConfigForSubIdWithFeature(int, String, String) instead */
     @UnsupportedAppUsage
     PersistableBundle getConfigForSubId(int subId, String callingPackage);
 
+    PersistableBundle getConfigForSubIdWithFeature(int subId, String callingPackage,
+            String callingFeatureId);
+
     void overrideConfig(int subId, in PersistableBundle overrides);
 
     void notifyConfigChangedForSubId(int subId);
diff --git a/telephony/java/com/android/internal/telephony/IOns.aidl b/telephony/java/com/android/internal/telephony/IOns.aidl
index 2c48b65..76b6951 100755
--- a/telephony/java/com/android/internal/telephony/IOns.aidl
+++ b/telephony/java/com/android/internal/telephony/IOns.aidl
@@ -83,7 +83,7 @@
      * subscription id
      *
      */
-    int getPreferredDataSubscriptionId(String callingPackage);
+    int getPreferredDataSubscriptionId(String callingPackage, String callingFeatureId);
 
     /**
      * Update availability of a list of networks in the current location.
diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
index 15e7fc2..28ef235 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
@@ -24,114 +24,128 @@
  */
 interface IPhoneSubInfo {
 
+    /** @deprecated Use {@link #getDeviceIdWithFeature(String, String) instead */
+    @UnsupportedAppUsage
+    String getDeviceId(String callingPackage);
+
     /**
      * Retrieves the unique device ID, e.g., IMEI for GSM phones.
      */
-    @UnsupportedAppUsage
-    String getDeviceId(String callingPackage);
+    String getDeviceIdWithFeature(String callingPackage, String callingFeatureId);
 
      /**
      * Retrieves the unique Network Access ID
      */
-    String getNaiForSubscriber(int subId, String callingPackage);
+    String getNaiForSubscriber(int subId, String callingPackage, String callingFeatureId);
 
     /**
      * Retrieves the unique device ID of a phone for the device, e.g., IMEI
      * for GSM phones.
      */
-    String getDeviceIdForPhone(int phoneId, String callingPackage);
+    String getDeviceIdForPhone(int phoneId, String callingPackage, String callingFeatureId);
 
     /**
      * Retrieves the IMEI.
      */
-    String getImeiForSubscriber(int subId, String callingPackage);
+    String getImeiForSubscriber(int subId, String callingPackage, String callingFeatureId);
 
     /**
      * Retrieves the software version number for the device, e.g., IMEI/SV
      * for GSM phones.
      */
-    String getDeviceSvn(String callingPackage);
+    String getDeviceSvn(String callingPackage, String callingFeatureId);
 
     /**
      * Retrieves the software version number of a subId for the device, e.g., IMEI/SV
      * for GSM phones.
      */
-    String getDeviceSvnUsingSubId(int subId, String callingPackage);
+    String getDeviceSvnUsingSubId(int subId, String callingPackage, String callingFeatureId);
 
-    /**
-     * Retrieves the unique sbuscriber ID, e.g., IMSI for GSM phones.
-     */
+    /** @deprecated Use {@link #getSubscriberIdWithFeature(String, String) instead */
     @UnsupportedAppUsage
     String getSubscriberId(String callingPackage);
 
     /**
+     * Retrieves the unique sbuscriber ID, e.g., IMSI for GSM phones.
+     */
+    String getSubscriberIdWithFeature(String callingPackage, String callingComponenId);
+
+    /**
      * Retrieves the unique subscriber ID of a given subId, e.g., IMSI for GSM phones.
      */
-    String getSubscriberIdForSubscriber(int subId, String callingPackage);
+    String getSubscriberIdForSubscriber(int subId, String callingPackage,
+            String callingFeatureId);
 
     /**
      * Retrieves the Group Identifier Level1 for GSM phones of a subId.
      */
-    String getGroupIdLevel1ForSubscriber(int subId, String callingPackage);
+    String getGroupIdLevel1ForSubscriber(int subId, String callingPackage,
+            String callingFeatureId);
 
-    /**
-     * Retrieves the serial number of the ICC, if applicable.
-     */
+    /** @deprecared Use {@link getIccSerialNumberWithFeature(String, String)} instead */
     @UnsupportedAppUsage
     String getIccSerialNumber(String callingPackage);
 
     /**
+     * Retrieves the serial number of the ICC, if applicable.
+     */
+    String getIccSerialNumberWithFeature(String callingPackage, String callingFeatureId);
+
+    /**
      * Retrieves the serial number of a given subId.
      */
-    String getIccSerialNumberForSubscriber(int subId, String callingPackage);
+    String getIccSerialNumberForSubscriber(int subId, String callingPackage,
+            String callingFeatureId);
 
     /**
      * Retrieves the phone number string for line 1.
      */
-    String getLine1Number(String callingPackage);
+    String getLine1Number(String callingPackage, String callingFeatureId);
 
     /**
      * Retrieves the phone number string for line 1 of a subcription.
      */
-    String getLine1NumberForSubscriber(int subId, String callingPackage);
+    String getLine1NumberForSubscriber(int subId, String callingPackage, String callingFeatureId);
 
 
     /**
      * Retrieves the alpha identifier for line 1.
      */
-    String getLine1AlphaTag(String callingPackage);
+    String getLine1AlphaTag(String callingPackage, String callingFeatureId);
 
     /**
      * Retrieves the alpha identifier for line 1 of a subId.
      */
-    String getLine1AlphaTagForSubscriber(int subId, String callingPackage);
+    String getLine1AlphaTagForSubscriber(int subId, String callingPackage,
+            String callingFeatureId);
 
 
     /**
      * Retrieves MSISDN Number.
      */
-    String getMsisdn(String callingPackage);
+    String getMsisdn(String callingPackage, String callingFeatureId);
 
     /**
      * Retrieves the Msisdn of a subId.
      */
-    String getMsisdnForSubscriber(int subId, String callingPackage);
+    String getMsisdnForSubscriber(int subId, String callingPackage, String callingFeatureId);
 
     /**
      * Retrieves the voice mail number.
      */
-    String getVoiceMailNumber(String callingPackage);
+    String getVoiceMailNumber(String callingPackage, String callingFeatureId);
 
     /**
      * Retrieves the voice mail number of a given subId.
      */
-    String getVoiceMailNumberForSubscriber(int subId, String callingPackage);
+    String getVoiceMailNumberForSubscriber(int subId, String callingPackage,
+            String callingFeatureId);
 
     /**
      * Retrieves the Carrier information used to encrypt IMSI and IMPI.
      */
     ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType,
-    String callingPackage);
+            String callingPackage);
 
     /**
      * Stores the Carrier information used to encrypt IMSI and IMPI.
@@ -149,13 +163,14 @@
     /**
      * Retrieves the alpha identifier associated with the voice mail number.
      */
-    String getVoiceMailAlphaTag(String callingPackage);
+    String getVoiceMailAlphaTag(String callingPackage, String callingFeatureId);
 
     /**
      * Retrieves the alpha identifier associated with the voice mail number
      * of a subId.
      */
-    String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage);
+    String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage,
+            String callingFeatureId);
 
     /**
      * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index 91aa3ce..ac4c8ec 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -573,7 +573,8 @@
      *
      * @param destAddress the destination address to test for possible short code
      */
-    int checkSmsShortCodeDestination(int subId, String callingApk, String destAddress, String countryIso);
+    int checkSmsShortCodeDestination(int subId, String callingApk, String callingFeatureId,
+            String destAddress, String countryIso);
 
     /**
      * Gets the SMSC address from (U)SIM.
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index d9d4b60..9865f76 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -18,7 +18,6 @@
 
 import android.app.PendingIntent;
 import android.net.Uri;
-import android.os.Bundle;
 
 import java.util.List;
 
@@ -197,8 +196,8 @@
     }
 
     @Override
-    public int checkSmsShortCodeDestination(
-            int subid, String callingApk, String destAddress, String countryIso) {
+    public int checkSmsShortCodeDestination(int subid, String callingPackage,
+            String callingFeatureId, String destAddress, String countryIso) {
         throw new UnsupportedOperationException();
     }
 
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 7cc37d0d2..151aae8 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -23,47 +23,56 @@
 interface ISub {
     /**
      * @param callingPackage The package maing the call.
+     * @param callingFeatureId The feature in the package
      * @return a list of all subscriptions in the database, this includes
      * all subscriptions that have been seen.
      */
-    List<SubscriptionInfo> getAllSubInfoList(String callingPackage);
+    List<SubscriptionInfo> getAllSubInfoList(String callingPackage, String callingFeatureId);
 
     /**
      * @param callingPackage The package maing the call.
+     * @param callingFeatureId The feature in the package
      * @return the count of all subscriptions in the database, this includes
      * all subscriptions that have been seen.
      */
-    int getAllSubInfoCount(String callingPackage);
+    int getAllSubInfoCount(String callingPackage, String callingFeatureId);
 
     /**
      * Get the active SubscriptionInfo with the subId key
      * @param subId The unique SubscriptionInfo key in database
      * @param callingPackage The package maing the call.
+     * @param callingFeatureId The feature in the package
      * @return SubscriptionInfo, maybe null if its not active
      */
-    SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage);
+    SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage,
+            String callingFeatureId);
 
     /**
      * Get the active SubscriptionInfo associated with the iccId
      * @param iccId the IccId of SIM card
      * @param callingPackage The package maing the call.
+     * @param callingFeatureId The feature in the package
      * @return SubscriptionInfo, maybe null if its not active
      */
-    SubscriptionInfo getActiveSubscriptionInfoForIccId(String iccId, String callingPackage);
+    SubscriptionInfo getActiveSubscriptionInfoForIccId(String iccId, String callingPackage,
+            String callingFeatureId);
 
     /**
      * Get the active SubscriptionInfo associated with the slotIndex
      * @param slotIndex the slot which the subscription is inserted
      * @param callingPackage The package making the call.
+     * @param callingFeatureId The feature in the package
      * @return SubscriptionInfo, null for Remote-SIMs or non-active slotIndex.
      */
-    SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex, String callingPackage);
+    SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex, String callingPackage,
+            String callingFeatureId);
 
     /**
      * Get the SubscriptionInfo(s) of the active subscriptions. The records will be sorted
      * by {@link SubscriptionInfo#getSimSlotIndex} then by {@link SubscriptionInfo#getSubscriptionId}.
      *
      * @param callingPackage The package maing the call.
+     * @param callingFeatureId The feature in the package
      * @return Sorted list of the currently {@link SubscriptionInfo} records available on the device.
      * <ul>
      * <li>
@@ -80,13 +89,15 @@
      * </li>
      * </ul>
      */
-    List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage);
+    List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage,
+            String callingFeatureId);
 
     /**
      * @param callingPackage The package making the call.
+     * @param callingFeatureId The feature in the package.
      * @return the number of active subscriptions
      */
-    int getActiveSubInfoCount(String callingPackage);
+    int getActiveSubInfoCount(String callingPackage, String callingFeatureId);
 
     /**
      * @return the maximum number of subscriptions this device will support at any one time.
@@ -96,7 +107,8 @@
     /**
      * @see android.telephony.SubscriptionManager#getAvailableSubscriptionInfoList
      */
-    List<SubscriptionInfo> getAvailableSubscriptionInfoList(String callingPackage);
+    List<SubscriptionInfo> getAvailableSubscriptionInfoList(String callingPackage,
+            String callingFeatureId);
 
     /**
      * @see android.telephony.SubscriptionManager#getAccessibleSubscriptionInfoList
@@ -225,7 +237,8 @@
      * Return opportunistic subscriptions that can be visible to the caller.
      * @return the list of opportunistic subscription info. If none exists, an empty list.
      */
-    List<SubscriptionInfo> getOpportunisticSubscriptions(String callingPackage);
+    List<SubscriptionInfo> getOpportunisticSubscriptions(String callingPackage,
+            String callingFeatureId);
 
     void removeSubscriptionsFromGroup(in int[] subIdList, in ParcelUuid groupUuid,
         String callingPackage);
@@ -233,7 +246,8 @@
     void addSubscriptionsIntoGroup(in int[] subIdList, in ParcelUuid groupUuid,
         String callingPackage);
 
-    List<SubscriptionInfo> getSubscriptionsInGroup(in ParcelUuid groupUuid, String callingPackage);
+    List<SubscriptionInfo> getSubscriptionsInGroup(in ParcelUuid groupUuid, String callingPackage,
+            String callingFeatureId);
 
     int getSlotIndex(int subId);
 
@@ -265,7 +279,8 @@
 
     int setSubscriptionProperty(int subId, String propKey, String propValue);
 
-    String getSubscriptionProperty(int subId, String propKey, String callingPackage);
+    String getSubscriptionProperty(int subId, String propKey, String callingPackage,
+            String callingFeatureId);
 
     boolean setSubscriptionEnabled(boolean enable, int subId);
 
@@ -278,7 +293,7 @@
      */
     int getSimStateForSlotIndex(int slotIndex);
 
-    boolean isActiveSubId(int subId, String callingPackage);
+    boolean isActiveSubId(int subId, String callingPackage, String callingFeatureId);
 
     boolean setAlwaysAllowMmsData(int subId, boolean alwaysAllow);
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 050388c..e96a078 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -89,22 +89,32 @@
     @UnsupportedAppUsage
     void call(String callingPackage, String number);
 
+    /** @deprecated Use {@link #isRadioOnWithFeature(String, String) instead */
+    @UnsupportedAppUsage
+    boolean isRadioOn(String callingPackage);
+
     /**
      * Check to see if the radio is on or not.
      * @param callingPackage the name of the package making the call.
+     * @param callingFeatureId The feature in the package.
      * @return returns true if the radio is on.
      */
+    boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId);
+
+    /**
+     * @deprecated Use {@link #isRadioOnForSubscriberWithFeature(int, String, String) instead
+     */
     @UnsupportedAppUsage
-    boolean isRadioOn(String callingPackage);
+    boolean isRadioOnForSubscriber(int subId, String callingPackage);
 
     /**
      * Check to see if the radio is on or not on particular subId.
      * @param subId user preferred subId.
      * @param callingPackage the name of the package making the call.
+     * @param callingFeatureId The feature in the package.
      * @return returns true if the radio is on.
      */
-    @UnsupportedAppUsage
-    boolean isRadioOnForSubscriber(int subId, String callingPackage);
+    boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage, String callingFeatureId);
 
     /**
      * Supply a pin to unlock the SIM.  Blocks until a result is determined.
@@ -302,7 +312,7 @@
      * operator's MCC (Mobile Country Code).
      * @see android.telephony.TelephonyManager#getNetworkCountryIso
      */
-    String getNetworkCountryIsoForPhone(int phoneId, String callingPkg);
+    String getNetworkCountryIsoForPhone(int phoneId, String callingPkg, String callingFeatureId);
 
     /**
      * Returns the neighboring cell information of the device.
@@ -371,23 +381,27 @@
     /**
      * Returns the CDMA ERI icon index to display
      * @param callingPackage package making the call.
+     * @param callingFeatureId The feature in the package.
      */
-    int getCdmaEriIconIndex(String callingPackage);
+    int getCdmaEriIconIndex(String callingPackage, String callingFeatureId);
 
     /**
      * Returns the CDMA ERI icon index to display on particular subId.
      * @param subId user preferred subId.
      * @param callingPackage package making the call.
+     * @param callingFeatureId The feature in the package.
      */
-    int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage);
+    int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
+            String callingFeatureId);
 
     /**
      * Returns the CDMA ERI icon mode,
      * 0 - ON
      * 1 - FLASHING
      * @param callingPackage package making the call.
+     * @param callingFeatureId The feature in the package.
      */
-    int getCdmaEriIconMode(String callingPackage);
+    int getCdmaEriIconMode(String callingPackage, String callingFeatureId);
 
     /**
      * Returns the CDMA ERI icon mode on particular subId,
@@ -395,21 +409,25 @@
      * 1 - FLASHING
      * @param subId user preferred subId.
      * @param callingPackage package making the call.
+     * @param callingFeatureId The feature in the package.
      */
-    int getCdmaEriIconModeForSubscriber(int subId, String callingPackage);
+    int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
+            String callingFeatureId);
 
     /**
      * Returns the CDMA ERI text,
      * @param callingPackage package making the call.
+     * @param callingFeatureId The feature in the package.
      */
-    String getCdmaEriText(String callingPackage);
+    String getCdmaEriText(String callingPackage, String callingFeatureId);
 
     /**
      * Returns the CDMA ERI text for particular subId,
      * @param subId user preferred subId.
      * @param callingPackage package making the call.
+     * @param callingFeatureId The feature in the package.
      */
-    String getCdmaEriTextForSubscriber(int subId, String callingPackage);
+    String getCdmaEriTextForSubscriber(int subId, String callingPackage, String callingFeatureId);
 
     /**
      * Returns true if OTA service provisioning needs to run.
@@ -452,7 +470,8 @@
      * @param subId user preferred subId.
      * Returns the unread count of voicemails
      */
-    int getVoiceMessageCountForSubscriber(int subId, String callingPackage);
+    int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
+            String callingFeatureId);
 
     /**
       * Returns true if current state supports both voice and data
@@ -462,7 +481,7 @@
 
     Bundle getVisualVoicemailSettings(String callingPackage, int subId);
 
-    String getVisualVoicemailPackageName(String callingPackage, int subId);
+    String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId, int subId);
 
     // Not oneway, caller needs to make sure the vaule is set before receiving a SMS
     void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
@@ -494,29 +513,35 @@
      * Returns the network type of a subId.
      * @param subId user preferred subId.
      * @param callingPackage package making the call.
+     * @param callingFeatureId The feature in the package.
      */
-    int getNetworkTypeForSubscriber(int subId, String callingPackage);
+    int getNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId);
 
     /**
      * Returns the network type for data transmission
      * @param callingPackage package making the call.
+     * @param callingFeatureId The feature in the package.
      */
-    int getDataNetworkType(String callingPackage);
+    int getDataNetworkType(String callingPackage, String callingFeatureId);
 
     /**
      * Returns the data network type of a subId
      * @param subId user preferred subId.
      * @param callingPackage package making the call.
+     * @param callingFeatureId The feature in the package.
      */
-    int getDataNetworkTypeForSubscriber(int subId, String callingPackage);
+    int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
+            String callingFeatureId);
 
     /**
       * Returns the voice network type of a subId
       * @param subId user preferred subId.
-      * @param callingPackage package making the call.
+      * @param callingPackage package making the call.getLteOnCdmaMode
+      * @param callingFeatureId The feature in the package.
       * Returns the network type
       */
-    int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage);
+    int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
+            String callingFeatureId);
 
     /**
      * Return true if an ICC card is present
@@ -537,10 +562,11 @@
      * the mode may be unknown.
      *
      * @param callingPackage the name of the calling package
+     * @param callingFeatureId The feature in the package.
      * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
      * or {@link PHone#LTE_ON_CDMA_TRUE}
      */
-    int getLteOnCdmaMode(String callingPackage);
+    int getLteOnCdmaMode(String callingPackage, String callingFeatureId);
 
     /**
      * Return if the current radio is LTE on CDMA. This
@@ -548,10 +574,11 @@
      * the mode may be unknown.
      *
      * @param callingPackage the name of the calling package
+     * @param callingFeatureId The feature in the package.
      * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
      * or {@link PHone#LTE_ON_CDMA_TRUE}
      */
-    int getLteOnCdmaModeForSubscriber(int subId, String callingPackage);
+    int getLteOnCdmaModeForSubscriber(int subId, String callingPackage, String callingFeatureId);
 
     /**
      * Returns all observed cell information of the device.
@@ -800,10 +827,11 @@
      * Get the calculated preferred network type.
      * Used for device configuration by some CDMA operators.
      * @param callingPackage The package making the call.
+     * @param callingFeatureId The feature in the package.
      *
      * @return the calculated preferred network type, defined in RILConstants.java.
      */
-    int getCalculatedPreferredNetworkType(String callingPackage);
+    int getCalculatedPreferredNetworkType(String callingPackage, String callingFeatureId);
 
     /*
      * Get the preferred network type.
@@ -981,8 +1009,9 @@
      * Get P-CSCF address from PCO after data connection is established or modified.
      * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
      * @param callingPackage The package making the call.
+     * @param callingFeatureId The feature in the package.
      */
-    String[] getPcscfAddress(String apnType, String callingPackage);
+    String[] getPcscfAddress(String apnType, String callingPackage, String callingFeatureId);
 
     /**
      * Set IMS registration state
@@ -1072,9 +1101,10 @@
      *
      * @param subId whose dialing number for line 1 is returned.
      * @param callingPackage The package making the call.
+     * @param callingFeatureId The feature in the package.
      * @return the displayed dialing number if set, or null if not set.
      */
-    String getLine1NumberForDisplay(int subId, String callingPackage);
+    String getLine1NumberForDisplay(int subId, String callingPackage, String callingFeatureId);
 
     /**
      * Returns the displayed alphatag of the dialing number if it was set
@@ -1082,10 +1112,11 @@
      *
      * @param subId whose alphatag associated with line 1 is returned.
      * @param callingPackage The package making the call.
+     * @param callingFeatureId The feature in the package.
      * @return the displayed alphatag of the dialing number if set, or null if
      *         not set.
      */
-    String getLine1AlphaTagForDisplay(int subId, String callingPackage);
+    String getLine1AlphaTagForDisplay(int subId, String callingPackage, String callingFeatureId);
 
     /**
      * Return the set of subscriber IDs that should be considered "merged together" for data usage
@@ -1097,7 +1128,7 @@
      *
      * @hide
      */
-    String[] getMergedSubscriberIds(int subId, String callingPackage);
+    String[] getMergedSubscriberIds(int subId, String callingPackage, String callingFeatureId);
 
     /**
      * @hide
@@ -1196,26 +1227,29 @@
      * Whether video calling has been enabled by the user.
      *
      * @param callingPackage The package making the call.
+     * @param callingFeatureId The feature in the package.
      * @return {@code true} if the user has enabled video calling, {@code false} otherwise.
      */
-    boolean isVideoCallingEnabled(String callingPackage);
+    boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId);
 
     /**
      * Whether the DTMF tone length can be changed.
      *
      * @param subId The subscription to use.
      * @param callingPackage The package making the call.
+     * @param callingFeatureId The feature in the package.
      * @return {@code true} if the DTMF tone length can be changed.
      */
-    boolean canChangeDtmfToneLength(int subId, String callingPackage);
+    boolean canChangeDtmfToneLength(int subId, String callingPackage, String callingFeatureId);
 
     /**
      * Whether the device is a world phone.
      *
      * @param callingPackage The package making the call.
+     * @param callingFeatureId The feature in the package.
      * @return {@code true} if the devices is a world phone.
      */
-    boolean isWorldPhone(int subId, String callingPackage);
+    boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId);
 
     /**
      * Whether the phone supports TTY mode.
@@ -1257,26 +1291,31 @@
     */
     int getImsRegTechnologyForMmTel(int subId);
 
+    /** @deprecated Use {@link #getDeviceIdWithFeature(String, String) instead */
+    @UnsupportedAppUsage
+    String getDeviceId(String callingPackage);
+
     /**
       * Returns the unique device ID of phone, for example, the IMEI for
       * GSM and the MEID for CDMA phones. Return null if device ID is not available.
       *
       * @param callingPackage The package making the call.
+      * @param callingFeatureId The feature in the package
       * <p>Requires Permission:
       *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
       */
-    @UnsupportedAppUsage
-    String getDeviceId(String callingPackage);
+    String getDeviceIdWithFeature(String callingPackage, String callingFeatureId);
 
     /**
      * Returns the IMEI for the given slot.
      *
      * @param slotIndex - device slot.
      * @param callingPackage The package making the call.
+     * @param callingFeatureId The feature in the package
      * <p>Requires Permission:
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
-    String getImeiForSlot(int slotIndex, String callingPackage);
+    String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId);
 
     /**
      * Returns the Type Allocation Code from the IMEI for the given slot.
@@ -1290,10 +1329,11 @@
      *
      * @param slotIndex - device slot.
      * @param callingPackage The package making the call.
+     * @param callingFeatureId The feature in the package
      * <p>Requires Permission:
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
-    String getMeidForSlot(int slotIndex, String callingPackage);
+    String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId);
 
     /**
      * Returns the Manufacturer Code from the MEID for the given slot.
@@ -1307,10 +1347,12 @@
      *
      * @param slotIndex - device slot.
      * @param callingPackage The package making the call.
+     * @param callingFeatureId The feature in the package.
      * <p>Requires Permission:
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
-    String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage);
+    String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
+            String callingFeatureId);
 
     /**
      * Returns the subscription ID associated with the specified PhoneAccount.
@@ -1321,7 +1363,7 @@
      * Returns the subscription ID associated with the specified PhoneAccountHandle.
      */
     int getSubIdForPhoneAccountHandle(in PhoneAccountHandle phoneAccountHandle,
-            String callingPackage);
+            String callingPackage, String callingFeatureId);
 
     /**
      * Returns the PhoneAccountHandle associated with a subscription ID.
@@ -1605,10 +1647,12 @@
      * Get Client request stats which will contain statistical information
      * on each request made by client.
      * @param callingPackage package making the call.
+     * @param callingFeatureId The feature in the package.
      * @param subId Subscription index
      * @hide
      */
-    List<ClientRequestStats> getClientRequestStats(String callingPackage, int subid);
+    List<ClientRequestStats> getClientRequestStats(String callingPackage, String callingFeatureId,
+            int subid);
 
     /**
      * Set SIM card power state.
@@ -1627,7 +1671,8 @@
      * @param subId subscription ID used for authentication
      * @param appType the icc application type, like {@link #APPTYPE_USIM}
      */
-    String[] getForbiddenPlmns(int subId, int appType, String callingPackage);
+    String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
+             String callingFeatureId);
 
     /**
      * Set the forbidden PLMN list from the givven app type (ex APPTYPE_USIM) on a particular
@@ -1636,10 +1681,12 @@
      * @param subId subId the id of the subscription
      * @param appType appType the uicc app type, must be USIM or SIM.
      * @param fplmns plmns the Forbiden plmns list that needed to be written to the SIM.
-     * @param content callingPackage the op Package name.
+     * @param callingPackage the op Package name.
+     * @param callingFeatureId the feature in the package.
      * @return number of fplmns that is successfully written to the SIM
      */
-    int setForbiddenPlmns(int subId, int appType, in List<String> fplmns, String callingPackage);
+    int setForbiddenPlmns(int subId, int appType, in List<String> fplmns, String callingPackage,
+            String callingFeatureId);
 
     /**
      * Check if phone is in emergency callback mode
@@ -1783,7 +1830,8 @@
      * How many modems can have simultaneous data connections.
      * @hide
      */
-    int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage);
+    int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
+            String callingFeatureId);
 
     /**
      * Return the network selection mode on the subscription with id {@code subId}.
@@ -1799,7 +1847,7 @@
      * Return the modem radio power state for slot index.
      *
      */
-    int getRadioPowerState(int slotIndex, String callingPackage);
+    int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId);
 
     // IMS specific AIDL commands, see ImsMmTelManager.java
 
@@ -1929,7 +1977,7 @@
     /**
      * Return the emergency number list from all the active subscriptions.
      */
-    Map getEmergencyNumberList(String callingPackage);
+    Map getEmergencyNumberList(String callingPackage, String callingFeatureId);
 
     /**
      * Identify if the number is emergency number, based on all the active subscriptions.
@@ -2014,12 +2062,13 @@
      * Returns if the usage of multiple SIM cards at the same time is supported.
      *
      * @param callingPackage The package making the call.
+     * @param callingFeatureId The feature in the package.
      * @return {@link #MULTISIM_ALLOWED} if the device supports multiple SIMs.
      * {@link #MULTISIM_NOT_SUPPORTED_BY_HARDWARE} if the device does not support multiple SIMs.
      * {@link #MULTISIM_NOT_SUPPORTED_BY_CARRIER} in the device supports multiple SIMs, but the
      * functionality is restricted by the carrier.
      */
-    int isMultiSimSupported(String callingPackage);
+    int isMultiSimSupported(String callingPackage, String callingFeatureId);
 
     /**
      * Switch configs to enable multi-sim or switch back to single-sim
@@ -2031,7 +2080,8 @@
      * Get if altering modems configurations will trigger reboot.
      * @hide
      */
-    boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage);
+    boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
+             String callingFeatureId);
 
     /**
      * Get the mapping from logical slots to physical slots.
@@ -2050,7 +2100,7 @@
      */
     boolean isApplicationOnUicc(int subId, int appType);
 
-    boolean isModemEnabledForSlot(int slotIndex, String callingPackage);
+    boolean isModemEnabledForSlot(int slotIndex, String callingPackage, String callingFeatureId);
 
     boolean isDataEnabledForApn(int apnType, int subId, String callingPackage);
 
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index 8a852ee..6e20621 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -18,6 +18,7 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 
 import android.Manifest;
+import android.annotation.Nullable;
 import android.app.AppOpsManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
@@ -95,16 +96,19 @@
      *              inaccesible to carrier-privileged apps).
      */
     public static boolean checkCallingOrSelfReadPhoneState(
-            Context context, int subId, String callingPackage, String message) {
+            Context context, int subId, String callingPackage, @Nullable String callingFeatureId,
+            String message) {
         return checkReadPhoneState(context, subId, Binder.getCallingPid(), Binder.getCallingUid(),
-                callingPackage, message);
+                callingPackage, callingFeatureId, message);
     }
 
     /** Identical to checkCallingOrSelfReadPhoneState but never throws SecurityException */
     public static boolean checkCallingOrSelfReadPhoneStateNoThrow(
-            Context context, int subId, String callingPackage, String message) {
+            Context context, int subId, String callingPackage, @Nullable String callingFeatureId,
+            String message) {
         try {
-            return checkCallingOrSelfReadPhoneState(context, subId, callingPackage, message);
+            return checkCallingOrSelfReadPhoneState(context, subId, callingPackage,
+                    callingFeatureId, message);
         } catch (SecurityException se) {
             return false;
         }
@@ -132,9 +136,11 @@
      * devices.
      */
     public static boolean checkReadPhoneState(
-            Context context, int subId, int pid, int uid, String callingPackage, String message) {
+            Context context, int subId, int pid, int uid, String callingPackage,
+            @Nullable  String callingFeatureId, String message) {
         return checkReadPhoneState(
-                context, TELEPHONY_SUPPLIER, subId, pid, uid, callingPackage, message);
+                context, TELEPHONY_SUPPLIER, subId, pid, uid, callingPackage, callingFeatureId,
+                message);
     }
 
     /**
@@ -153,7 +159,7 @@
     @VisibleForTesting
     public static boolean checkReadPhoneState(
             Context context, Supplier<ITelephony> telephonySupplier, int subId, int pid, int uid,
-            String callingPackage, String message) {
+            String callingPackage, @Nullable String callingFeatureId, String message) {
         try {
             context.enforcePermission(
                     android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid, uid, message);
@@ -178,8 +184,8 @@
         // We have READ_PHONE_STATE permission, so return true as long as the AppOps bit hasn't been
         // revoked.
         AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
-        return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, uid, callingPackage)
-                == AppOpsManager.MODE_ALLOWED;
+        return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, uid, callingPackage,
+                callingFeatureId, null) == AppOpsManager.MODE_ALLOWED;
     }
 
     /**
@@ -196,16 +202,16 @@
      * @return {@code true} if the app can read phone state or has carrier privilege;
      *         {@code false} otherwise.
      */
-    public static boolean checkReadPhoneStateOnAnyActiveSub(
-            Context context, int pid, int uid, String callingPackage, String message) {
+    public static boolean checkReadPhoneStateOnAnyActiveSub(Context context, int pid, int uid,
+            String callingPackage, @Nullable String callingFeatureId, String message) {
         return checkReadPhoneStateOnAnyActiveSub(context, TELEPHONY_SUPPLIER, pid, uid,
-                    callingPackage, message);
+                callingPackage, callingFeatureId, message);
     }
 
     @VisibleForTesting
     public static boolean checkReadPhoneStateOnAnyActiveSub(
             Context context, Supplier<ITelephony> telephonySupplier, int pid, int uid,
-            String callingPackage, String message) {
+            String callingPackage, @Nullable String callingFeatureId, String message) {
         try {
             context.enforcePermission(
                     android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid, uid, message);
@@ -226,8 +232,8 @@
         // We have READ_PHONE_STATE permission, so return true as long as the AppOps bit hasn't been
         // revoked.
         AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
-        return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, uid, callingPackage) ==
-                AppOpsManager.MODE_ALLOWED;
+        return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, uid, callingPackage,
+                callingFeatureId, null) == AppOpsManager.MODE_ALLOWED;
     }
 
     /**
@@ -248,9 +254,10 @@
      * </ul>
      */
     public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context,
-            String callingPackage, String message) {
+            String callingPackage, @Nullable String callingFeatureId, String message) {
         return checkCallingOrSelfReadDeviceIdentifiers(context,
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage, message);
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage, callingFeatureId,
+                message);
     }
 
     /**
@@ -271,9 +278,9 @@
      * </ul>
      */
     public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context, int subId,
-            String callingPackage, String message) {
+            String callingPackage, @Nullable String callingFeatureId, String message) {
         return checkPrivilegedReadPermissionOrCarrierPrivilegePermission(
-                context, subId, callingPackage, message, true);
+                context, subId, callingPackage, callingFeatureId, message, true);
     }
 
     /**
@@ -293,9 +300,9 @@
      * </ul>
      */
     public static boolean checkCallingOrSelfReadSubscriberIdentifiers(Context context, int subId,
-            String callingPackage, String message) {
+            String callingPackage, @Nullable String callingFeatureId, String message) {
         return checkPrivilegedReadPermissionOrCarrierPrivilegePermission(
-                context, subId, callingPackage, message, false);
+                context, subId, callingPackage, callingFeatureId, message, false);
     }
 
     /**
@@ -317,8 +324,8 @@
      * </ul>
      */
     private static boolean checkPrivilegedReadPermissionOrCarrierPrivilegePermission(
-            Context context, int subId, String callingPackage, String message,
-            boolean allowCarrierPrivilegeOnAnySub) {
+            Context context, int subId, String callingPackage, @Nullable String callingFeatureId,
+            String message, boolean allowCarrierPrivilegeOnAnySub) {
         int uid = Binder.getCallingUid();
         int pid = Binder.getCallingPid();
         // Allow system and root access to the device identifiers.
@@ -351,7 +358,7 @@
                     Context.APP_OPS_SERVICE);
             try {
                 if (appOpsManager.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, uid,
-                        callingPackage) == AppOpsManager.MODE_ALLOWED) {
+                        callingPackage, callingFeatureId, null) == AppOpsManager.MODE_ALLOWED) {
                     return true;
                 }
             } finally {
@@ -444,15 +451,16 @@
      *      to it, {@code false} otherwise.
      */
     public static boolean checkReadCallLog(
-            Context context, int subId, int pid, int uid, String callingPackage) {
+            Context context, int subId, int pid, int uid, String callingPackage,
+            @Nullable String callingPackageName) {
         return checkReadCallLog(
-                context, TELEPHONY_SUPPLIER, subId, pid, uid, callingPackage);
+                context, TELEPHONY_SUPPLIER, subId, pid, uid, callingPackage, callingPackageName);
     }
 
     @VisibleForTesting
     public static boolean checkReadCallLog(
             Context context, Supplier<ITelephony> telephonySupplier, int subId, int pid, int uid,
-            String callingPackage) {
+            String callingPackage, @Nullable String callingFeatureId) {
 
         if (context.checkPermission(Manifest.permission.READ_CALL_LOG, pid, uid)
                 != PERMISSION_GRANTED) {
@@ -468,8 +476,8 @@
         // We have READ_CALL_LOG permission, so return true as long as the AppOps bit hasn't been
         // revoked.
         AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
-        return appOps.noteOp(AppOpsManager.OPSTR_READ_CALL_LOG, uid, callingPackage) ==
-                AppOpsManager.MODE_ALLOWED;
+        return appOps.noteOp(AppOpsManager.OPSTR_READ_CALL_LOG, uid, callingPackage,
+                callingFeatureId, null) == AppOpsManager.MODE_ALLOWED;
     }
 
     /**
@@ -479,20 +487,21 @@
      * default SMS app and apps with READ_SMS or READ_PHONE_NUMBERS can also read phone numbers.
      */
     public static boolean checkCallingOrSelfReadPhoneNumber(
-            Context context, int subId, String callingPackage, String message) {
+            Context context, int subId, String callingPackage, @Nullable String callingFeatureId,
+            String message) {
         return checkReadPhoneNumber(
                 context, TELEPHONY_SUPPLIER, subId, Binder.getCallingPid(), Binder.getCallingUid(),
-                callingPackage, message);
+                callingPackage, callingFeatureId, message);
     }
 
     @VisibleForTesting
     public static boolean checkReadPhoneNumber(
             Context context, Supplier<ITelephony> telephonySupplier, int subId, int pid, int uid,
-            String callingPackage, String message) {
+            String callingPackage, @Nullable String callingFeatureId, String message) {
         // Default SMS app can always read it.
         AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
-        if (appOps.noteOp(AppOpsManager.OPSTR_WRITE_SMS, uid, callingPackage) ==
-                AppOpsManager.MODE_ALLOWED) {
+        if (appOps.noteOp(AppOpsManager.OPSTR_WRITE_SMS, uid, callingPackage, callingFeatureId,
+                null) == AppOpsManager.MODE_ALLOWED) {
             return true;
         }
 
@@ -502,14 +511,15 @@
         // First, check if we can read the phone state.
         try {
             return checkReadPhoneState(
-                    context, telephonySupplier, subId, pid, uid, callingPackage, message);
+                    context, telephonySupplier, subId, pid, uid, callingPackage, callingFeatureId,
+                    message);
         } catch (SecurityException readPhoneStateSecurityException) {
         }
         // Can be read with READ_SMS too.
         try {
             context.enforcePermission(android.Manifest.permission.READ_SMS, pid, uid, message);
-            return appOps.noteOp(AppOpsManager.OPSTR_READ_SMS, uid, callingPackage)
-                == AppOpsManager.MODE_ALLOWED;
+            return appOps.noteOp(AppOpsManager.OPSTR_READ_SMS, uid, callingPackage,
+                    callingFeatureId, null) == AppOpsManager.MODE_ALLOWED;
 
         } catch (SecurityException readSmsSecurityException) {
         }
@@ -517,8 +527,8 @@
         try {
             context.enforcePermission(android.Manifest.permission.READ_PHONE_NUMBERS, pid, uid,
                     message);
-            return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_NUMBERS, uid, callingPackage)
-                == AppOpsManager.MODE_ALLOWED;
+            return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_NUMBERS, uid, callingPackage,
+                    callingFeatureId, null) == AppOpsManager.MODE_ALLOWED;
 
         } catch (SecurityException readPhoneNumberSecurityException) {
         }
diff --git a/test-mock/src/android/test/mock/MockContentProvider.java b/test-mock/src/android/test/mock/MockContentProvider.java
index 9d3e120..85e5916 100644
--- a/test-mock/src/android/test/mock/MockContentProvider.java
+++ b/test-mock/src/android/test/mock/MockContentProvider.java
@@ -71,8 +71,8 @@
 
         @Override
         public int delete(String callingPackage, @Nullable String featureId, Uri url,
-                String selection, String[] selectionArgs) throws RemoteException {
-            return MockContentProvider.this.delete(url, selection, selectionArgs);
+                Bundle extras) throws RemoteException {
+            return MockContentProvider.this.delete(url, extras);
         }
 
         @Override
@@ -82,8 +82,8 @@
 
         @Override
         public Uri insert(String callingPackage, @Nullable String featureId, Uri url,
-                ContentValues initialValues) throws RemoteException {
-            return MockContentProvider.this.insert(url, initialValues);
+                ContentValues initialValues, Bundle extras) throws RemoteException {
+            return MockContentProvider.this.insert(url, initialValues, extras);
         }
 
         @Override
@@ -109,9 +109,8 @@
 
         @Override
         public int update(String callingPackage, @Nullable String featureId, Uri url,
-                ContentValues values, String selection, String[] selectionArgs)
-                throws RemoteException {
-            return MockContentProvider.this.update(url, values, selection, selectionArgs);
+                ContentValues values, Bundle extras) throws RemoteException {
+            return MockContentProvider.this.update(url, values, extras);
         }
 
         @Override
diff --git a/test-mock/src/android/test/mock/MockIContentProvider.java b/test-mock/src/android/test/mock/MockIContentProvider.java
index e512b52..464abfb 100644
--- a/test-mock/src/android/test/mock/MockIContentProvider.java
+++ b/test-mock/src/android/test/mock/MockIContentProvider.java
@@ -51,7 +51,7 @@
     @Override
     @SuppressWarnings("unused")
     public int delete(String callingPackage, @Nullable String featureId, Uri url,
-            String selection, String[] selectionArgs) throws RemoteException {
+            Bundle extras) throws RemoteException {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
@@ -63,7 +63,7 @@
     @Override
     @SuppressWarnings("unused")
     public Uri insert(String callingPackage, @Nullable String featureId, Uri url,
-            ContentValues initialValues) throws RemoteException {
+            ContentValues initialValues, Bundle extras) throws RemoteException {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
@@ -99,7 +99,7 @@
 
     @Override
     public int update(String callingPackage, @Nullable String featureId, Uri url,
-            ContentValues values, String selection, String[] selectionArgs) throws RemoteException {
+            ContentValues values, Bundle extras) throws RemoteException {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
diff --git a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
index cd04c2e..3d72ee6 100644
--- a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
@@ -18,13 +18,13 @@
 
 import android.app.Notification;
 import android.app.NotificationManager;
-import android.view.View;
-import android.content.Intent;
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
+import android.content.Intent;
 import android.os.Handler;
-import android.util.Log;
 import android.os.SystemClock;
+import android.util.Log;
+import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
 
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index 5f62c08..9e5717b 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -208,6 +208,12 @@
             if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
             return super.getSystemService(name);
         }
+
+        @Override
+        public String getSystemServiceName(Class<?> serviceClass) {
+            if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE;
+            return super.getSystemServiceName(serviceClass);
+        }
     }
 
     public class MockIpServerDependencies extends IpServer.Dependencies {
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 1d29a82..4d42a61 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -192,8 +192,8 @@
 
         mService = new NetworkStatsService(
                 mServiceContext, mNetManager, mAlarmManager, wakeLock, mClock,
-                TelephonyManager.getDefault(), mSettings, mStatsFactory,
-                new NetworkStatsObservers(),  mStatsDir, getBaseDir(mStatsDir));
+                mServiceContext.getSystemService(TelephonyManager.class), mSettings,
+                mStatsFactory, new NetworkStatsObservers(),  mStatsDir, getBaseDir(mStatsDir));
         mHandlerThread = new HandlerThread("HandlerThread");
         mHandlerThread.start();
         Handler.Callback callback = new NetworkStatsService.HandlerCallback(mService);
diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py
index e883c6b..46105f4 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists.py
@@ -241,8 +241,6 @@
             flags = csv[1:]
             if (FLAG_PUBLIC_API in flags) or (FLAG_SYSTEM_API in flags):
                 flags.append(FLAG_WHITELIST)
-            elif FLAG_TEST_API in flags:
-                flags.append(FLAG_GREYLIST)
             self._dict[csv[0]].update(flags)
 
     def assign_flag(self, flag, apis, source="<unknown>"):
diff --git a/tools/hiddenapi/generate_hiddenapi_lists_test.py b/tools/hiddenapi/generate_hiddenapi_lists_test.py
index 4dc880b..55c3a7d 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists_test.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists_test.py
@@ -53,14 +53,22 @@
         # Test new additions.
         flags.parse_and_merge_csv([
             'A,' + FLAG_GREYLIST,
-            'B,' + FLAG_BLACKLIST + ',' + FLAG_GREYLIST_MAX_O ])
-        self.assertEqual(flags.generate_csv(),
-            [ 'A,' + FLAG_GREYLIST,
-              'B,' + FLAG_BLACKLIST + "," + FLAG_GREYLIST_MAX_O ])
+            'B,' + FLAG_BLACKLIST + ',' + FLAG_GREYLIST_MAX_O,
+            'C,' + FLAG_SYSTEM_API + ',' + FLAG_WHITELIST,
+            'D,' + FLAG_GREYLIST+ ',' + FLAG_TEST_API,
+            'E,' + FLAG_BLACKLIST+ ',' + FLAG_TEST_API,
+        ])
+        self.assertEqual(flags.generate_csv(), [
+            'A,' + FLAG_GREYLIST,
+            'B,' + FLAG_BLACKLIST + "," + FLAG_GREYLIST_MAX_O,
+            'C,' + FLAG_SYSTEM_API + ',' + FLAG_WHITELIST,
+            'D,' + FLAG_GREYLIST+ ',' + FLAG_TEST_API,
+            'E,' + FLAG_BLACKLIST+ ',' + FLAG_TEST_API,
+        ])
 
         # Test unknown flag.
         with self.assertRaises(AssertionError):
-            flags.parse_and_merge_csv([ 'C,foo' ])
+            flags.parse_and_merge_csv([ 'Z,foo' ])
 
     def test_assign_flag(self):
         flags = FlagsDict()
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 90343d4..f7d2b40 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -384,12 +384,7 @@
     public void setSecurityParams(@SecurityType int securityType) {
         // Clear all the bitsets.
         allowedKeyManagement.clear();
-        allowedProtocols.clear();
         allowedAuthAlgorithms.clear();
-        allowedPairwiseCiphers.clear();
-        allowedGroupCiphers.clear();
-        allowedGroupManagementCiphers.clear();
-        allowedSuiteBCiphers.clear();
 
         switch (securityType) {
             case SECURITY_TYPE_OPEN:
@@ -412,6 +407,9 @@
                 requirePMF = true;
                 break;
             case SECURITY_TYPE_EAP_SUITE_B:
+                allowedGroupCiphers.clear();
+                allowedGroupManagementCiphers.clear();
+                allowedSuiteBCiphers.clear();
                 allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192);
                 allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
                 allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256);
@@ -947,6 +945,12 @@
     public int meteredOverride = METERED_OVERRIDE_NONE;
 
     /**
+     * This Wifi configuration is a clone of another network with lower security
+     * @hide
+     */
+    public String clonedNetworkConfigKey;
+
+    /**
      * Blend together all the various opinions to decide if the given network
      * should be considered metered or not.
      *
@@ -1804,6 +1808,7 @@
         shared = true;
         dtimInterval = 0;
         mRandomizedMacAddress = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
+        clonedNetworkConfigKey = null;
     }
 
     /**
@@ -2371,6 +2376,7 @@
 
     /** copy constructor {@hide} */
     @UnsupportedAppUsage
+
     public WifiConfiguration(WifiConfiguration source) {
         if (source != null) {
             networkId = source.networkId;
@@ -2454,6 +2460,7 @@
             requirePMF = source.requirePMF;
             updateIdentifier = source.updateIdentifier;
             carrierId = source.carrierId;
+            clonedNetworkConfigKey = source.clonedNetworkConfigKey;
         }
     }
 
@@ -2529,6 +2536,7 @@
         dest.writeInt(osu ? 1 : 0);
         dest.writeLong(randomizedMacExpirationTimeMs);
         dest.writeInt(carrierId);
+        dest.writeString(clonedNetworkConfigKey);
     }
 
     /** Implement the Parcelable interface {@hide} */
@@ -2606,6 +2614,7 @@
                 config.osu = in.readInt() != 0;
                 config.randomizedMacExpirationTimeMs = in.readLong();
                 config.carrierId = in.readInt();
+                config.clonedNetworkConfigKey = in.readString();
                 return config;
             }
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 93960de..16cb964 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -380,14 +380,6 @@
      * @hide
      */
     public static final String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
-    /**
-     * String representation of an URL.
-     *
-     * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
-     *
-     * @hide
-     */
-    public static final String EXTRA_URL = "android.net.wifi.extra.URL";
 
     /**
      * Broadcast intent action indicating a Passpoint subscription remediation frame has been
@@ -420,34 +412,49 @@
             "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
 
     /**
-     * Activity Action: lunch OSU (Online Sign Up) view.
+     * Activity Action: Receiver should launch Passpoint OSU (Online Sign Up) view.
      * Included extras:
      *
      * {@link #EXTRA_OSU_NETWORK}: {@link Network} instance associated with OSU AP.
      * {@link #EXTRA_URL}: String representation of a server URL used for OSU process.
      *
-     * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
-     * components will be launched.
-     *
      * @hide
      */
+    @SystemApi
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_PASSPOINT_LAUNCH_OSU_VIEW =
             "android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW";
 
     /**
-     * The lookup key for a {@link android.net.Network} associated with OSU server.
+     * The lookup key for a {@link android.net.Network} associated with a Passpoint OSU server.
+     * Included in the {@link #ACTION_PASSPOINT_LAUNCH_OSU_VIEW} broadcast.
      *
      * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
      *
      * @hide
      */
+    @SystemApi
     public static final String EXTRA_OSU_NETWORK = "android.net.wifi.extra.OSU_NETWORK";
 
     /**
+     * String representation of an URL for Passpoint OSU.
+     * Included in the {@link #ACTION_PASSPOINT_LAUNCH_OSU_VIEW} broadcast.
+     *
+     * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_URL = "android.net.wifi.extra.URL";
+
+    /**
      * Broadcast intent action indicating that Wi-Fi has been enabled, disabled,
      * enabling, disabling, or unknown. One extra provides this state as an int.
-     * Another extra provides the previous state, if available.
+     * Another extra provides the previous state, if available.  No network-related
+     * permissions are required to subscribe to this broadcast.
+     *
+     * <p class="note">This broadcast is not delivered to manifest receivers in
+     * applications that target API version 26 or later.
      *
      * @see #EXTRA_WIFI_STATE
      * @see #EXTRA_PREVIOUS_WIFI_STATE
@@ -656,6 +663,7 @@
      *
      *  @hide
      */
+    @SystemApi
     public static final int SAP_START_FAILURE_GENERAL= 0;
 
     /**
@@ -664,6 +672,7 @@
      *
      *  @hide
      */
+    @SystemApi
     public static final int SAP_START_FAILURE_NO_CHANNEL = 1;
 
     /** @hide */
@@ -748,7 +757,11 @@
     /**
      * Broadcast intent action indicating that the state of Wi-Fi connectivity
      * has changed. An extra provides the new state
-     * in the form of a {@link android.net.NetworkInfo} object.
+     * in the form of a {@link android.net.NetworkInfo} object.  No network-related
+     * permissions are required to subscribe to this broadcast.
+     *
+     * <p class="note">This broadcast is not delivered to manifest receivers in
+     * applications that target API version 26 or later.
      * @see #EXTRA_NETWORK_INFO
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@@ -917,7 +930,7 @@
      * The RSSI (signal strength) has changed.
      *
      * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
-     * @see {@link #EXTRA_NEW_RSSI}
+     * @see #EXTRA_NEW_RSSI
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
@@ -927,21 +940,37 @@
     public static final String EXTRA_NEW_RSSI = "newRssi";
 
     /**
-     * Broadcast intent action indicating that the link configuration
-     * changed on wifi.
+     * @see #ACTION_LINK_CONFIGURATION_CHANGED
      * @hide
      */
     @UnsupportedAppUsage
     public static final String LINK_CONFIGURATION_CHANGED_ACTION =
-        "android.net.wifi.LINK_CONFIGURATION_CHANGED";
+            "android.net.wifi.LINK_CONFIGURATION_CHANGED";
+
+    /**
+     * Broadcast intent action indicating that the link configuration changed on wifi.
+     * <br />Included Extras:
+     * <br />{@link #EXTRA_LINK_PROPERTIES}: {@link android.net.LinkProperties} object associated
+     * with the Wi-Fi network.
+     * <br /> No permissions are required to listen to this broadcast.
+     * @hide
+     */
+    @SystemApi
+    public static final String ACTION_LINK_CONFIGURATION_CHANGED =
+            // should be android.net.wifi.action.LINK_CONFIGURATION_CHANGED, but due to
+            // @UnsupportedAppUsage leaving it as android.net.wifi.LINK_CONFIGURATION_CHANGED.
+            LINK_CONFIGURATION_CHANGED_ACTION;
 
     /**
      * The lookup key for a {@link android.net.LinkProperties} object associated with the
-     * Wi-Fi network. Retrieve with
-     * {@link android.content.Intent#getParcelableExtra(String)}.
+     * Wi-Fi network.
+     * Included in the {@link #ACTION_LINK_CONFIGURATION_CHANGED} broadcast.
+     *
+     * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
      * @hide
      */
-    public static final String EXTRA_LINK_PROPERTIES = "linkProperties";
+    @SystemApi
+    public static final String EXTRA_LINK_PROPERTIES = "android.net.wifi.extra.LINK_PROPERTIES";
 
     /**
      * The lookup key for a {@link android.net.NetworkCapabilities} object associated with the
@@ -981,24 +1010,26 @@
     public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
 
     /**
-     * Activity Action: Show UI to get user approval to enable WiFi.
+     * Activity Action: Receiver should show UI to get user approval to enable WiFi.
      * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} string extra with
      *           the name of the app requesting the action.
      * <p>Output: Nothing.
-     *
+     * <p>No permissions are required to send this action.
      * @hide
      */
+    @SystemApi
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_REQUEST_ENABLE = "android.net.wifi.action.REQUEST_ENABLE";
 
     /**
-     * Activity Action: Show UI to get user approval to disable WiFi.
+     * Activity Action: Receiver should show UI to get user approval to disable WiFi.
      * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} string extra with
      *           the name of the app requesting the action.
      * <p>Output: Nothing.
-     *
+     * <p>No permissions are required to send this action.
      * @hide
      */
+    @SystemApi
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_REQUEST_DISABLE = "android.net.wifi.action.REQUEST_DISABLE";
 
@@ -1115,11 +1146,15 @@
     private static final int MAX_RSSI = -55;
 
     /**
-     * Number of RSSI levels used in the framework to initiate
-     * {@link #RSSI_CHANGED_ACTION} broadcast
+     * Number of RSSI levels used in the framework to initiate {@link #RSSI_CHANGED_ACTION}
+     * broadcast, where each level corresponds to a range of RSSI values.
+     * The {@link #RSSI_CHANGED_ACTION} broadcast will only fire if the RSSI
+     * change is significant enough to change the RSSI signal level.
      * @hide
      */
     @UnsupportedAppUsage
+    // TODO(b/140781184): need to support custom number of RSSI levels, as well as levels that are
+    //  not evenly spaced
     public static final int RSSI_LEVELS = 5;
 
     /**
@@ -1147,7 +1182,8 @@
     /** @hide */
     public static final boolean DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED = false;
 
-    /* Maximum number of active locks we allow.
+    /**
+     * Maximum number of active locks we allow.
      * This limit was added to prevent apps from creating a ridiculous number
      * of locks and crashing the system by overflowing the global ref table.
      */
@@ -1487,40 +1523,43 @@
      * {@link #reject()} to return the user's selection back to the platform via this callback.
      * @hide
      */
+    @SystemApi
     public interface NetworkRequestUserSelectionCallback {
         /**
          * User selected this network to connect to.
          * @param wifiConfiguration WifiConfiguration object corresponding to the network
          *                          user selected.
          */
-        void select(@NonNull WifiConfiguration wifiConfiguration);
+        default void select(@NonNull WifiConfiguration wifiConfiguration) {}
 
         /**
          * User rejected the app's request.
          */
-        void reject();
+        default void reject() {}
     }
 
     /**
      * Interface for network request callback. Should be implemented by applications and passed when
-     * calling {@link #registerNetworkRequestMatchCallback(NetworkRequestMatchCallback, Handler)}.
+     * calling {@link #registerNetworkRequestMatchCallback(Executor,
+     * WifiManager.NetworkRequestMatchCallback)}.
      *
      * This is meant to be implemented by a UI component to present the user with a list of networks
      * matching the app's request. The user is allowed to pick one of these networks to connect to
      * or reject the request by the app.
      * @hide
      */
+    @SystemApi
     public interface NetworkRequestMatchCallback {
         /**
          * Invoked to register a callback to be invoked to convey user selection. The callback
-         * object paased in this method is to be invoked by the UI component after the service sends
+         * object passed in this method is to be invoked by the UI component after the service sends
          * a list of matching scan networks using {@link #onMatch(List)} and user picks a network
          * from that list.
          *
          * @param userSelectionCallback Callback object to send back the user selection.
          */
-        void onUserSelectionCallbackRegistration(
-                @NonNull NetworkRequestUserSelectionCallback userSelectionCallback);
+        default void onUserSelectionCallbackRegistration(
+                @NonNull NetworkRequestUserSelectionCallback userSelectionCallback) {}
 
         /**
          * Invoked when the active network request is aborted, either because
@@ -1529,7 +1568,7 @@
          * This signals the end of processing for the current request and should stop the UI
          * component. No subsequent calls from the UI component will be handled by the platform.
          */
-        void onAbort();
+        default void onAbort() {}
 
         /**
          * Invoked when a network request initiated by an app matches some networks in scan results.
@@ -1539,7 +1578,7 @@
          * @param scanResults List of {@link ScanResult} objects corresponding to the networks
          *                    matching the request.
          */
-        void onMatch(@NonNull List<ScanResult> scanResults);
+        default void onMatch(@NonNull List<ScanResult> scanResults) {}
 
         /**
          * Invoked on a successful connection with the network that the user selected
@@ -1548,7 +1587,7 @@
          * @param wifiConfiguration WifiConfiguration object corresponding to the network that the
          *                          user selected.
          */
-        void onUserSelectionConnectSuccess(@NonNull WifiConfiguration wifiConfiguration);
+        default void onUserSelectionConnectSuccess(@NonNull WifiConfiguration wifiConfiguration) {}
 
         /**
          * Invoked on failure to establish connection with the network that the user selected
@@ -1557,7 +1596,7 @@
          * @param wifiConfiguration WifiConfiguration object corresponding to the network
          *                          user selected.
          */
-        void onUserSelectionConnectFailure(@NonNull WifiConfiguration wifiConfiguration);
+        default void onUserSelectionConnectFailure(@NonNull WifiConfiguration wifiConfiguration) {}
     }
 
     /**
@@ -1606,11 +1645,11 @@
      * @hide
      */
     private class NetworkRequestMatchCallbackProxy extends INetworkRequestMatchCallback.Stub {
-        private final Handler mHandler;
+        private final Executor mExecutor;
         private final NetworkRequestMatchCallback mCallback;
 
-        NetworkRequestMatchCallbackProxy(Looper looper, NetworkRequestMatchCallback callback) {
-            mHandler = new Handler(looper);
+        NetworkRequestMatchCallbackProxy(Executor executor, NetworkRequestMatchCallback callback) {
+            mExecutor = executor;
             mCallback = callback;
         }
 
@@ -1621,7 +1660,8 @@
                 Log.v(TAG, "NetworkRequestMatchCallbackProxy: "
                         + "onUserSelectionCallbackRegistration callback: " + userSelectionCallback);
             }
-            mHandler.post(() -> {
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> {
                 mCallback.onUserSelectionCallbackRegistration(
                         new NetworkRequestUserSelectionCallbackProxy(userSelectionCallback));
             });
@@ -1632,7 +1672,8 @@
             if (mVerboseLoggingEnabled) {
                 Log.v(TAG, "NetworkRequestMatchCallbackProxy: onAbort");
             }
-            mHandler.post(() -> {
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> {
                 mCallback.onAbort();
             });
         }
@@ -1643,7 +1684,8 @@
                 Log.v(TAG, "NetworkRequestMatchCallbackProxy: onMatch scanResults: "
                         + scanResults);
             }
-            mHandler.post(() -> {
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> {
                 mCallback.onMatch(scanResults);
             });
         }
@@ -1654,7 +1696,8 @@
                 Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectSuccess "
                         + " wificonfiguration: " + wifiConfiguration);
             }
-            mHandler.post(() -> {
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> {
                 mCallback.onUserSelectionConnectSuccess(wifiConfiguration);
             });
         }
@@ -1665,13 +1708,26 @@
                 Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectFailure"
                         + " wificonfiguration: " + wifiConfiguration);
             }
-            mHandler.post(() -> {
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> {
                 mCallback.onUserSelectionConnectFailure(wifiConfiguration);
             });
         }
     }
 
     /**
+     * Same as {@link #registerNetworkRequestMatchCallback(Executor, NetworkRequestMatchCallback)},
+     * except that the callback will be executed on the application's main thread.
+     * @param callback Callback for network match events to register.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
+    public void registerNetworkRequestMatchCallback(@NonNull NetworkRequestMatchCallback callback) {
+        registerNetworkRequestMatchCallback(mContext.getMainExecutor(), callback);
+    }
+
+    /**
      * Registers a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}.
      * Caller can unregister a previously registered callback using
      * {@link #unregisterNetworkRequestMatchCallback(NetworkRequestMatchCallback)}
@@ -1681,19 +1737,20 @@
      * without the permission will trigger a {@link java.lang.SecurityException}.
      * <p>
      *
-     * @param callback Callback for network match events
-     * @param handler  The Handler on whose thread to execute the callbacks of the {@code callback}
-     *                 object. If null, then the application's main thread will be used.
+     * @param executor The Executor on whose thread to execute the callbacks of the {@code callback}
+     *                 object.
+     * @param callback Callback for network match events to register.
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void registerNetworkRequestMatchCallback(@NonNull NetworkRequestMatchCallback callback,
-                                                    @Nullable Handler handler) {
+    public void registerNetworkRequestMatchCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull NetworkRequestMatchCallback callback) {
+        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
         if (callback == null) throw new IllegalArgumentException("callback cannot be null");
         Log.v(TAG, "registerNetworkRequestMatchCallback: callback=" + callback
-                + ", handler=" + handler);
+                + ", executor=" + executor);
 
-        Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
         Binder binder = new Binder();
         try {
             IWifiManager iWifiManager = getIWifiManager();
@@ -1701,7 +1758,7 @@
                 throw new RemoteException("Wifi service is not running");
             }
             iWifiManager.registerNetworkRequestMatchCallback(
-                    binder, new NetworkRequestMatchCallbackProxy(looper, callback),
+                    binder, new NetworkRequestMatchCallbackProxy(executor, callback),
                     callback.hashCode());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1716,9 +1773,10 @@
      * without the permission will trigger a {@link java.lang.SecurityException}.
      * <p>
      *
-     * @param callback Callback for network match events
+     * @param callback Callback for network match events to unregister.
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
     public void unregisterNetworkRequestMatchCallback(
             @NonNull NetworkRequestMatchCallback callback) {
@@ -2257,6 +2315,8 @@
     public static final long WIFI_FEATURE_MBO              = 0x800000000L; // MBO Support
     /** @hide */
     public static final long WIFI_FEATURE_OCE              = 0x1000000000L; // OCE Support
+    /** @hide */
+    public static final long WIFI_FEATURE_INFRA_6G         = 0x2000000000L; // Support 6 GHz band
 
     private long getSupportedFeatures() {
         try {
@@ -2271,6 +2331,7 @@
     private boolean isFeatureSupported(long feature) {
         return (getSupportedFeatures() & feature) == feature;
     }
+
     /**
      * @return true if this adapter supports 5 GHz band
      */
@@ -2279,6 +2340,14 @@
     }
 
     /**
+     * @return true if the device supports operating in the 6 GHz band and Wi-Fi is enabled,
+     *         false otherwise.
+     */
+    public boolean is6GHzBandSupported() {
+        return isFeatureSupported(WIFI_FEATURE_INFRA_6G);
+    }
+
+    /**
      * @return true if this adapter supports Passpoint
      * @hide
      */
@@ -2550,29 +2619,30 @@
     }
 
     /**
-    * get the country code.
-    * @return the country code in ISO 3166 format.
-    *
-    * @hide
-    */
-    @UnsupportedAppUsage
+     * Get the country code.
+     * @return the country code in ISO 3166 format, or null if there is no country code configured.
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
     public String getCountryCode() {
         try {
             IWifiManager iWifiManager = getIWifiManager();
             if (iWifiManager == null) return null;
-            String country = iWifiManager.getCountryCode();
-            return country;
+            return iWifiManager.getCountryCode();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     /**
-     * Check if the chipset supports dual frequency band (2.4 GHz and 5 GHz)
+     * Check if the chipset supports dual frequency band (2.4 GHz and 5 GHz).
+     * No permissions are required to call this method.
      * @return {@code true} if supported, {@code false} otherwise.
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public boolean isDualBandSupported() {
         try {
             IWifiManager iWifiManager = getIWifiManager();
@@ -2584,10 +2654,20 @@
     }
 
     /**
-     * Check if the chipset requires conversion of 5GHz Only apBand to ANY.
-     * @return {@code true} if required, {@code false} otherwise.
+     * Check if the device is dual mode capable i.e. supports concurrent STA + Soft AP.
+     *
+     * If the device is dual mode capable, it may require conversion of the user's Soft AP band
+     * selection {@link WifiConfiguration#apBand} from {@link WifiConfiguration#AP_BAND_5GHZ} to
+     * {@link WifiConfiguration#AP_BAND_ANY}, since if the device is connected to a 5GHz DFS
+     * channel as a STA, it may be unable to honor a request to start Soft AP on the same DFS
+     * channel.
+     *
+     * @return {@code true} if dual mode STA + AP is supported by this device, {@code false}
+     * otherwise.
      * @hide
      */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
     public boolean isDualModeSupported() {
         try {
             IWifiManager iWifiManager = getIWifiManager();
@@ -2674,6 +2754,7 @@
      *
      * @hide for CTS test only
      */
+    // TODO(b/144036594): add @TestApi
     public void getTxPacketCount(@NonNull TxPacketCountListener listener) {
         if (listener == null) throw new IllegalArgumentException("listener cannot be null");
         Binder binder = new Binder();
@@ -3123,10 +3204,12 @@
     }
 
     /**
-     * Method that triggers a notification to the user about a conversion to their saved AP config.
+     * Method that triggers a notification to the user about a band conversion
+     * (e.g. 5 GHz to 2.4 GHz) to their saved AP config.
      *
      * @hide
      */
+    // TODO(b/144218444): move the notification to Settings instead of making this @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
     public void notifyUserOfApBandConversion() {
         Log.d(TAG, "apBand was converted, notify the user");
@@ -3351,7 +3434,7 @@
 
     /**
      * Base class for soft AP callback. Should be extended by applications and set when calling
-     * {@link WifiManager#registerSoftApCallback(SoftApCallback, Handler)}.
+     * {@link WifiManager#registerSoftApCallback(Executor, SoftApCallback)}.
      *
      * @hide
      */
@@ -3360,22 +3443,21 @@
         /**
          * Called when soft AP state changes.
          *
-         * @param state         new new AP state. One of {@link #WIFI_AP_STATE_DISABLED},
+         * @param state         the new AP state. One of {@link #WIFI_AP_STATE_DISABLED},
          *                      {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
          *                      {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}
          * @param failureReason reason when in failed state. One of
          *                      {@link #SAP_START_FAILURE_GENERAL},
          *                      {@link #SAP_START_FAILURE_NO_CHANNEL}
          */
-        void onStateChanged(@WifiApState int state,
-                @SapStartFailure int failureReason);
+        default void onStateChanged(@WifiApState int state, @SapStartFailure int failureReason) {}
 
         /**
          * Called when the connected clients to soft AP changes.
          *
          * @param clients the currently connected clients
          */
-        void onConnectedClientsChanged(@NonNull List<WifiClient> clients);
+        default void onConnectedClientsChanged(@NonNull List<WifiClient> clients) {}
 
         /**
          * Called when information of softap changes.
@@ -3441,31 +3523,42 @@
     }
 
     /**
+     * Same as {@link #registerSoftApCallback(Executor, SoftApCallback)},
+     * except that the callback will be executed on the application's main thread.
+     * @param callback Callback for soft AP events
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
+    public void registerSoftApCallback(@NonNull SoftApCallback callback) {
+        registerSoftApCallback(mContext.getMainExecutor(), callback);
+    }
+
+    /**
      * Registers a callback for Soft AP. See {@link SoftApCallback}. Caller will receive the current
      * soft AP state and number of connected devices immediately after a successful call to this API
      * via callback. Note that receiving an immediate WIFI_AP_STATE_FAILED value for soft AP state
      * indicates that the latest attempt to start soft AP has failed. Caller can unregister a
-     * previously registered callback using {@link unregisterSoftApCallback}
+     * previously registered callback using {@link #unregisterSoftApCallback}
      * <p>
      * Applications should have the
      * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers
      * without the permission will trigger a {@link java.lang.SecurityException}.
      * <p>
      *
+     * @param executor The Executor on whose thread to execute the callbacks of the {@code callback}
+     *                 object.
      * @param callback Callback for soft AP events
-     * @param executor The executor to execute the callbacks of the {@code executor}
-     *                 object. If null, then the application's main executor will be used.
-     *
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void registerSoftApCallback(@NonNull SoftApCallback callback,
-                                       @Nullable @CallbackExecutor Executor executor) {
+    public void registerSoftApCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull SoftApCallback callback) {
+        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
         if (callback == null) throw new IllegalArgumentException("callback cannot be null");
         Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", executor=" + executor);
 
-        executor = (executor == null) ? mContext.getMainExecutor() : executor;
         Binder binder = new Binder();
         try {
             IWifiManager iWifiManager = getIWifiManager();
@@ -3487,6 +3580,7 @@
      *
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
     public void unregisterSoftApCallback(@NonNull SoftApCallback callback) {
         if (callback == null) throw new IllegalArgumentException("callback cannot be null");
@@ -4031,23 +4125,27 @@
     }
 
     /**
-     * Disable ephemeral Network
+     * Disable an ephemeral network.
      *
-     * @param SSID, in the format of WifiConfiguration's SSID.
+     * @param ssid in the format of WifiConfiguration's SSID.
+     *
      * @hide
      */
+    @SystemApi
     @RequiresPermission(anyOf = {
             android.Manifest.permission.NETWORK_SETTINGS,
             android.Manifest.permission.NETWORK_STACK
     })
-    public void disableEphemeralNetwork(String SSID) {
-        if (TextUtils.isEmpty(SSID)) throw new IllegalArgumentException("SSID cannot be null");
+    public void disableEphemeralNetwork(@NonNull String ssid) {
+        if (TextUtils.isEmpty(ssid)) {
+            throw new IllegalArgumentException("SSID cannot be null or empty!");
+        }
         try {
             IWifiManager iWifiManager = getIWifiManager();
             if (iWifiManager == null) {
                 throw new RemoteException("Wifi service is not running");
             }
-            iWifiManager.disableEphemeralNetwork(SSID, mContext.getOpPackageName());
+            iWifiManager.disableEphemeralNetwork(ssid, mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -4543,11 +4641,15 @@
     }
 
     /**
-     * Set wifi verbose log. Called from developer settings.
+     * Set Wi-Fi verbose logging level from developer settings.
+     *
+     * @param verbose the verbose logging level to set. 0 will disable verbose logging, a positive
+     *                integer will enable verbose logging.
+     *
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    @UnsupportedAppUsage
     public void enableVerboseLogging (int verbose) {
         try {
             IWifiManager iWifiManager = getIWifiManager();
@@ -4563,11 +4665,15 @@
     }
 
     /**
-     * Get the WiFi verbose logging level.This is used by settings
-     * to decide what to show within the picker.
+     * Get the persisted WiFi verbose logging level, set by {@link #enableVerboseLogging(int)}.
+     * No permissions are required to call this method.
+     *
+     * @return 0 to indicate that verbose logging is disabled, a positive integer to indicate that
+     * verbose logging is enabled.
+     *
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public int getVerboseLoggingLevel() {
         try {
             IWifiManager iWifiManager = getIWifiManager();
@@ -4579,10 +4685,13 @@
     }
 
     /**
-     * Removes all saved wifi networks.
+     * Removes all saved Wi-Fi networks, Passpoint configurations, ephemeral networks, Network
+     * Requests, and Network Suggestions.
      *
      * @hide
      */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
     public void factoryReset() {
         try {
             IWifiManager iWifiManager = getIWifiManager();
@@ -4596,11 +4705,12 @@
     }
 
     /**
-     * Get Network object of current wifi network
-     * @return Get Network object of current wifi network
+     * Get {@link Network} object of current wifi network, or null if not connected.
      * @hide
      */
-    @UnsupportedAppUsage
+    @Nullable
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE)
     public Network getCurrentNetwork() {
         try {
             IWifiManager iWifiManager = getIWifiManager();
@@ -4649,13 +4759,18 @@
     }
 
     /**
-     * Retrieve the data to be backed to save the current state.
+     * Returns a byte stream representing the data that needs to be backed up to save the
+     * current Wifi state.
+     * This Wifi state can be restored by calling {@link #restoreBackupData(byte[])}.
      * @hide
      */
+    @NonNull
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
     public byte[] retrieveBackupData() {
         try {
             IWifiManager iWifiManager = getIWifiManager();
-            if (iWifiManager == null) return null;
+            if (iWifiManager == null) return new byte[0];
             return iWifiManager.retrieveBackupData();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -4664,9 +4779,12 @@
 
     /**
      * Restore state from the backed up data.
+     * @param data byte stream in the same format produced by {@link #retrieveBackupData()}
      * @hide
      */
-    public void restoreBackupData(byte[] data) {
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
+    public void restoreBackupData(@NonNull byte[] data) {
         try {
             IWifiManager iWifiManager = getIWifiManager();
             if (iWifiManager == null) {
@@ -4683,11 +4801,16 @@
      * Restore state from the older version of back up data.
      * The old backup data was essentially a backup of wpa_supplicant.conf
      * and ipconfig.txt file.
+     * @param supplicantData bytes representing wpa_supplicant.conf
+     * @param ipConfigData bytes representing ipconfig.txt
      * @deprecated this is no longer supported.
      * @hide
      */
     @Deprecated
-    public void restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData) {
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
+    public void restoreSupplicantBackupData(
+            @NonNull byte[] supplicantData, @NonNull byte[] ipConfigData) {
         try {
             IWifiManager iWifiManager = getIWifiManager();
             if (iWifiManager == null) {
@@ -4763,22 +4886,29 @@
     }
 
     /**
-     * Base class for Traffic state callback. Should be extended by applications and set when
-     * calling {@link WifiManager#registerTrafficStateCallback(TrafficStateCallback, Handler)}.
+     * Interface for Traffic state callback. Should be extended by applications and set when
+     * calling {@link #registerTrafficStateCallback(Executor, WifiManager.TrafficStateCallback)}.
      * @hide
      */
+    @SystemApi
     public interface TrafficStateCallback {
-        /**
-         * Lowest bit indicates data reception and the second lowest
-         * bit indicates data transmitted
-         */
         /** @hide */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(prefix = {"DATA_ACTIVITY_"}, value = {
+                DATA_ACTIVITY_NONE,
+                DATA_ACTIVITY_IN,
+                DATA_ACTIVITY_OUT,
+                DATA_ACTIVITY_INOUT})
+        @interface DataActivity {}
+
+        // Lowest bit indicates data reception and the second lowest bit indicates data transmitted
+        /** No data in or out */
         int DATA_ACTIVITY_NONE         = 0x00;
-        /** @hide */
+        /** Data in, no data out */
         int DATA_ACTIVITY_IN           = 0x01;
-        /** @hide */
+        /** Data out, no data in */
         int DATA_ACTIVITY_OUT          = 0x02;
-        /** @hide */
+        /** Data in and out */
         int DATA_ACTIVITY_INOUT        = 0x03;
 
         /**
@@ -4786,9 +4916,8 @@
          *
          * @param state One of the values: {@link #DATA_ACTIVITY_NONE}, {@link #DATA_ACTIVITY_IN},
          * {@link #DATA_ACTIVITY_OUT} & {@link #DATA_ACTIVITY_INOUT}.
-         * @hide
          */
-        void onStateChanged(int state);
+        void onStateChanged(@DataActivity int state);
     }
 
     /**
@@ -4797,11 +4926,11 @@
      * @hide
      */
     private class TrafficStateCallbackProxy extends ITrafficStateCallback.Stub {
-        private final Handler mHandler;
+        private final Executor mExecutor;
         private final TrafficStateCallback mCallback;
 
-        TrafficStateCallbackProxy(Looper looper, TrafficStateCallback callback) {
-            mHandler = new Handler(looper);
+        TrafficStateCallbackProxy(Executor executor, TrafficStateCallback callback) {
+            mExecutor = executor;
             mCallback = callback;
         }
 
@@ -4810,13 +4939,26 @@
             if (mVerboseLoggingEnabled) {
                 Log.v(TAG, "TrafficStateCallbackProxy: onStateChanged state=" + state);
             }
-            mHandler.post(() -> {
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> {
                 mCallback.onStateChanged(state);
             });
         }
     }
 
     /**
+     * Same as {@link #registerTrafficStateCallback(Executor, TrafficStateCallback)},
+     * except that the callback will be executed on the application's main thread.
+     * @param callback Callback for traffic state events
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
+    public void registerTrafficStateCallback(@NonNull TrafficStateCallback callback) {
+        registerTrafficStateCallback(mContext.getMainExecutor(), callback);
+    }
+
+    /**
      * Registers a callback for monitoring traffic state. See {@link TrafficStateCallback}. These
      * callbacks will be invoked periodically by platform to inform clients about the current
      * traffic state. Caller can unregister a previously registered callback using
@@ -4827,18 +4969,19 @@
      * without the permission will trigger a {@link java.lang.SecurityException}.
      * <p>
      *
+     * @param executor The Executor on whose thread to execute the callbacks of the {@code callback}
+     *                 object.
      * @param callback Callback for traffic state events
-     * @param handler  The Handler on whose thread to execute the callbacks of the {@code callback}
-     *                 object. If null, then the application's main thread will be used.
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void registerTrafficStateCallback(@NonNull TrafficStateCallback callback,
-                                             @Nullable Handler handler) {
+    public void registerTrafficStateCallback(@NonNull @CallbackExecutor Executor executor,
+                                             @NonNull TrafficStateCallback callback) {
+        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
         if (callback == null) throw new IllegalArgumentException("callback cannot be null");
-        Log.v(TAG, "registerTrafficStateCallback: callback=" + callback + ", handler=" + handler);
+        Log.v(TAG, "registerTrafficStateCallback: callback=" + callback + ", executor=" + executor);
 
-        Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
         Binder binder = new Binder();
         try {
             IWifiManager iWifiManager = getIWifiManager();
@@ -4846,7 +4989,7 @@
                 throw new RemoteException("Wifi service is not running");
             }
             iWifiManager.registerTrafficStateCallback(
-                    binder, new TrafficStateCallbackProxy(looper, callback), callback.hashCode());
+                    binder, new TrafficStateCallbackProxy(executor, callback), callback.hashCode());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -4859,6 +5002,7 @@
      * @param callback Callback to unregister for traffic state events
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
     public void unregisterTrafficStateCallback(@NonNull TrafficStateCallback callback) {
         if (callback == null) throw new IllegalArgumentException("callback cannot be null");
@@ -4922,11 +5066,13 @@
      * if failed.
      * @hide
      */
+    @NonNull
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
     public String[] getFactoryMacAddresses() {
         try {
             IWifiManager iWifiManager = getIWifiManager();
-            if (iWifiManager == null) return null;
+            if (iWifiManager == null) return new String[0];
             return iWifiManager.getFactoryMacAddresses();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 7e14451..0d36718 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -960,6 +960,9 @@
      * Retrieve the most recent scan results from a single scan request.
      * {@hide}
      */
+    @NonNull
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
     public List<ScanResult> getSingleScanResults() {
         validateChannel();
         Bundle scanParams = new Bundle();
@@ -973,7 +976,7 @@
         OperationResult result = (OperationResult) reply.obj;
         Log.e(TAG, "Error retrieving SingleScan results reason: " + result.reason
                 + " description: " + result.description);
-        return new ArrayList<ScanResult>();
+        return new ArrayList<>();
     }
 
     private void startPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings, int key) {
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
index 0511f24..5a4ed3c 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
@@ -20,7 +20,6 @@
 
 import android.annotation.IntRange;
 import android.annotation.NonNull;
-import android.annotation.SystemApi;
 import android.net.NetworkSpecifier;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -337,7 +336,8 @@
          * Configure the PSK Passphrase for the Wi-Fi Aware connection being requested. This method
          * is optional - if not called, then an Open (unencrypted) connection will be created.
          *
-         * @param pskPassphrase The (optional) passphrase to be used to encrypt the link.
+         * @param pskPassphrase The (optional) passphrase to be used to encrypt the link. Use the
+         *                      {@link #setPmk(byte[])} to specify a PMK.
          * @return the current {@link Builder} builder, enabling chaining of builder
          *         methods.
          */
@@ -358,9 +358,7 @@
          *            specify a Passphrase.
          * @return the current {@link Builder} builder, enabling chaining of builder
          *         methods.
-         * @hide
          */
-        @SystemApi
         public @NonNull Builder setPmk(@NonNull byte[] pmk) {
             if (!WifiAwareUtils.validatePmk(pmk)) {
                 throw new IllegalArgumentException("PMK must 32 bytes");
@@ -377,7 +375,7 @@
          * <ul>
          *     <li>The server device must be the Publisher device!
          *     <li>The port information can only be specified on secure links, specified using
-         *     {@link #setPskPassphrase(String)}.
+         *     {@link #setPskPassphrase(String)} or {@link #setPmk(byte[])}.
          * </ul>
          *
          * @param port A positive integer indicating the port to be used for communication.
@@ -400,7 +398,7 @@
          * <ul>
          *     <li>The server device must be the Publisher device!
          *     <li>The transport protocol information can only be specified on secure links,
-         *     specified using {@link #setPskPassphrase(String)}.
+         *     specified using {@link #setPskPassphrase(String)} or {@link #setPmk(byte[])}.
          * </ul>
          * The transport protocol number is assigned by the Internet Assigned Numbers Authority
          * (IANA) https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml.
@@ -426,7 +424,7 @@
          * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
          * <p> The default builder constructor will initialize a NetworkSpecifier which requests an
          * open (non-encrypted) link. To request an encrypted link use the
-         * {@link #setPskPassphrase(String)} builder method.
+         * {@link #setPskPassphrase(String)} or {@link #setPmk(byte[])} builder methods.
          *
          * @return A {@link NetworkSpecifier} to be used to construct
          * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
index c3cfb02..767055f 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
@@ -66,12 +66,6 @@
     public int groupOwnerBand = GROUP_OWNER_BAND_AUTO;
 
     /** @hide */
-    public static final int MAX_GROUP_OWNER_INTENT   =   15;
-    /** @hide */
-    @UnsupportedAppUsage
-    public static final int MIN_GROUP_OWNER_INTENT   =   0;
-
-    /** @hide */
     @IntDef(flag = false, prefix = { "GROUP_OWNER_BAND_" }, value = {
         GROUP_OWNER_BAND_AUTO,
         GROUP_OWNER_BAND_2GHZ,
@@ -94,13 +88,35 @@
     public static final int GROUP_OWNER_BAND_5GHZ = 2;
 
     /**
-     * This is an integer value between 0 and 15 where 0 indicates the least
-     * inclination to be a group owner and 15 indicates the highest inclination
-     * to be a group owner.
-     *
-     * A value of -1 indicates the system can choose an appropriate value.
+     * The least inclination to be a group owner, to be filled in the field
+     * {@link #groupOwnerIntent}.
      */
-    public int groupOwnerIntent = -1;
+    public static final int GROUP_OWNER_INTENT_MIN = 0;
+
+    /**
+     * The most inclination to be a group owner, to be filled in the field
+     * {@link #groupOwnerIntent}.
+     */
+    public static final int GROUP_OWNER_INTENT_MAX = 15;
+
+    /**
+     * The system can choose an appropriate owner intent value, to be filled in the field
+     * {@link #groupOwnerIntent}.
+     */
+    public static final int GROUP_OWNER_INTENT_AUTO = -1;
+
+    /**
+     * This is an integer value between {@link #GROUP_OWNER_INTENT_MIN} and
+     * {@link #GROUP_OWNER_INTENT_MAX} where
+     * {@link #GROUP_OWNER_INTENT_MIN} indicates the least inclination to be a group owner and
+     * {@link #GROUP_OWNER_INTENT_MAX} indicates the highest inclination to be a group owner.
+     *
+     * A value of {@link #GROUP_OWNER_INTENT_AUTO} indicates the system can choose an appropriate
+     * value.
+     *
+     * By default this field is set to {@link #GROUP_OWNER_INTENT_AUTO}.
+     */
+    public int groupOwnerIntent = GROUP_OWNER_INTENT_AUTO;
 
     /** @hide */
     @UnsupportedAppUsage
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
index c5318a9..13b2520 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
@@ -16,6 +16,8 @@
 
 package android.net.wifi.p2p;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -237,6 +239,12 @@
         }
     }
 
+    /** The Wifi Display information for this device, or null if unavailable. */
+    @Nullable
+    public WifiP2pWfdInfo getWfdInfo() {
+        return wfdInfo;
+    }
+
     /** Returns true if WPS push button configuration is supported */
     public boolean wpsPbcSupported() {
         return (wpsConfigMethodsSupported & WPS_CONFIG_PUSHBUTTON) != 0;
@@ -278,14 +286,15 @@
     }
 
     /**
-     * Update device details. This will be throw an exception if the device address
-     * does not match.
+     * Update device details. This will throw an exception if the device address does not match.
+     *
      * @param device to be updated
-     * @throws IllegalArgumentException if the device is null or device address does not match
+     * @throws IllegalArgumentException if the device is null or the device address does not match
+     *
      * @hide
      */
     @UnsupportedAppUsage
-    public void update(WifiP2pDevice device) {
+    public void update(@NonNull WifiP2pDevice device) {
         updateSupplicantDetails(device);
         status = device.status;
     }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
index 4866bd4..f9d1266 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
@@ -16,6 +16,7 @@
 
 package android.net.wifi.p2p;
 
+import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -36,15 +37,21 @@
  */
 public class WifiP2pGroup implements Parcelable {
 
-    /** The temporary network id.
-     * {@hide} */
+    /**
+     * The temporary network id.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
     public static final int TEMPORARY_NET_ID = -1;
 
-    /** The persistent network id.
+    /**
+     * The persistent network id.
      * If a matching persistent profile is found, use it.
      * Otherwise, create a new persistent profile.
-     * {@hide} */
+     *
+     * @hide
+     */
     public static final int PERSISTENT_NET_ID = -2;
 
     /** The network name */
@@ -64,7 +71,7 @@
 
     private String mInterface;
 
-    /** The network id in the wpa_supplicant */
+    /** The network ID in wpa_supplicant */
     private int mNetId;
 
     /** The frequency (in MHz) used by this group */
@@ -225,10 +232,13 @@
         return mClients.size() == 0;
     }
 
-    /** @hide Returns {@code true} if the device is part of the group */
-    public boolean contains(WifiP2pDevice device) {
-        if (mOwner.equals(device) || mClients.contains(device)) return true;
-        return false;
+    /**
+     * Returns {@code true} if the device is part of the group, {@code false} otherwise.
+     *
+     * @hide
+     */
+    public boolean contains(@Nullable WifiP2pDevice device) {
+        return mOwner.equals(device) || mClients.contains(device);
     }
 
     /** Get the list of clients currently part of the p2p group */
@@ -261,8 +271,7 @@
         return mInterface;
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
+    /** The network ID of the P2P group in wpa_supplicant. */
     public int getNetworkId() {
         return mNetId;
     }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
index 62524d9..10fd09a 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
@@ -15,14 +15,16 @@
  */
 package android.net.wifi.p2p;
 
-import java.util.Collection;
-import java.util.Map;
-
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.LruCache;
 
+import java.util.Collection;
+import java.util.Map;
+
 
 /**
  * A class representing a Wi-Fi P2p group list
@@ -30,7 +32,8 @@
  * {@see WifiP2pManager}
  * @hide
  */
-public class WifiP2pGroupList implements Parcelable {
+@SystemApi
+public final class WifiP2pGroupList implements Parcelable {
 
     private static final int CREDENTIAL_MAX_NUM             =   32;
 
@@ -40,6 +43,7 @@
 
     private boolean isClearCalled = false;
 
+    /** @hide */
     public interface GroupDeleteListener {
         public void onDeleteGroup(int netId);
     }
@@ -71,11 +75,9 @@
     }
 
     /**
-     * Return the list of p2p group.
-     *
-     * @return the list of p2p group.
+     * Get the list of P2P groups.
      */
-    @UnsupportedAppUsage
+    @NonNull
     public Collection<WifiP2pGroup> getGroupList() {
         return mGroups.snapshot().values();
     }
@@ -206,6 +208,7 @@
         return false;
     }
 
+    @Override
     public String toString() {
         StringBuffer sbuf = new StringBuffer();
 
@@ -217,12 +220,14 @@
     }
 
     /** Implement the Parcelable interface */
+    @Override
     public int describeContents() {
         return 0;
     }
 
     /** Implement the Parcelable interface */
-    public void writeToParcel(Parcel dest, int flags) {
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
         dest.writeInt(groups.size());
         for(WifiP2pGroup group : groups) {
@@ -231,7 +236,7 @@
     }
 
     /** Implement the Parcelable interface */
-    public static final @android.annotation.NonNull Creator<WifiP2pGroupList> CREATOR =
+    public static final @NonNull Creator<WifiP2pGroupList> CREATOR =
         new Creator<WifiP2pGroupList>() {
             public WifiP2pGroupList createFromParcel(Parcel in) {
                 WifiP2pGroupList grpList = new WifiP2pGroupList();
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 3178519..1c20679 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -22,6 +22,7 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
@@ -327,8 +328,9 @@
      * Broadcast intent action indicating that remembered persistent groups have changed.
      * @hide
      */
-    public static final String WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION =
-        "android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED";
+    @SystemApi
+    public static final String ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED =
+            "android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED";
 
     /**
      * The lookup key for a handover message returned by the WifiP2pService.
@@ -756,13 +758,18 @@
     }
 
 
-    /** Interface for callback invocation when stored group info list is available {@hide}*/
+    /**
+     * Interface for callback invocation when stored group info list is available
+     *
+     * @hide
+     */
+    @SystemApi
     public interface PersistentGroupInfoListener {
         /**
          * The requested stored p2p group info list is available
          * @param groups Wi-Fi p2p group info list
          */
-        public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups);
+        void onPersistentGroupInfoAvailable(@NonNull WifiP2pGroupList groups);
     }
 
     /**
@@ -1202,7 +1209,7 @@
         c.mAsyncChannel.sendMessage(DISCOVER_PEERS, 0, c.putListener(listener));
     }
 
-   /**
+    /**
      * Stop an ongoing peer discovery
      *
      * <p> The function call immediately returns after sending a stop request
@@ -1347,20 +1354,36 @@
      *
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void listen(Channel c, boolean enable, ActionListener listener) {
+    public void listen(@NonNull Channel c, boolean enable, @Nullable ActionListener listener) {
         checkChannel(c);
         c.mAsyncChannel.sendMessage(enable ? START_LISTEN : STOP_LISTEN,
                 0, c.putListener(listener));
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setWifiP2pChannels(Channel c, int lc, int oc, ActionListener listener) {
+    /**
+     * Set P2P listening and operating channel.
+     *
+     * @param c is the channel created at {@link #initialize}
+     * @param listeningChannel the listening channel's Wifi channel number. e.g. 1, 6, 11.
+     * @param operatingChannel the operating channel's Wifi channel number. e.g. 1, 6, 11.
+     * @param listener for callbacks on success or failure. Can be null.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_SETTINGS,
+            android.Manifest.permission.NETWORK_STACK,
+            android.Manifest.permission.OVERRIDE_WIFI_CONFIG
+    })
+    public void setWifiP2pChannels(@NonNull Channel c, int listeningChannel, int operatingChannel,
+            @Nullable ActionListener listener) {
         checkChannel(c);
         Bundle p2pChannels = new Bundle();
-        p2pChannels.putInt("lc", lc);
-        p2pChannels.putInt("oc", oc);
+        p2pChannels.putInt("lc", listeningChannel);
+        p2pChannels.putInt("oc", operatingChannel);
         c.mAsyncChannel.sendMessage(SET_CHANNEL, 0, c.putListener(listener), p2pChannels);
     }
 
@@ -1618,23 +1641,47 @@
 
     /**
      * Set p2p device name.
-     * @hide
+     *
      * @param c is the channel created at {@link #initialize}
      * @param listener for callback when group info is available. Can be null.
+     *
+     * @hide
      */
-    @UnsupportedAppUsage
-    public void setDeviceName(Channel c, String devName, ActionListener listener) {
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_SETTINGS,
+            android.Manifest.permission.NETWORK_STACK,
+            android.Manifest.permission.OVERRIDE_WIFI_CONFIG
+    })
+    public void setDeviceName(@NonNull Channel c, @NonNull String devName,
+            @Nullable ActionListener listener) {
         checkChannel(c);
         WifiP2pDevice d = new WifiP2pDevice();
         d.deviceName = devName;
         c.mAsyncChannel.sendMessage(SET_DEVICE_NAME, 0, c.putListener(listener), d);
     }
 
+    /**
+     * Set Wifi Display information.
+     *
+     * @param c is the channel created at {@link #initialize}
+     * @param wfdInfo the Wifi Display information to set
+     * @param listener for callbacks on success or failure. Can be null.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
+    public void setWfdInfo(@NonNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo,
+            @Nullable ActionListener listener) {
+        setWFDInfo(c, wfdInfo, listener);
+    }
+
     /** @hide */
     @UnsupportedAppUsage
-    public void setWFDInfo(
-            Channel c, WifiP2pWfdInfo wfdInfo,
-            ActionListener listener) {
+    @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
+    public void setWFDInfo(@NonNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo,
+            @Nullable ActionListener listener) {
         checkChannel(c);
         try {
             mService.checkConfigureWifiDisplayPermission();
@@ -1658,12 +1705,19 @@
      *  a network id can be obtained by {@link WifiP2pGroup#getNetworkId()}.
      *
      * @param c is the channel created at {@link #initialize}
-     * @param netId he network id of the p2p group.
+     * @param netId the network id of the p2p group.
      * @param listener for callbacks on success or failure. Can be null.
+     *
      * @hide
      */
-    @UnsupportedAppUsage
-    public void deletePersistentGroup(Channel c, int netId, ActionListener listener) {
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_SETTINGS,
+            android.Manifest.permission.NETWORK_STACK,
+            android.Manifest.permission.OVERRIDE_WIFI_CONFIG
+    })
+    public void deletePersistentGroup(@NonNull Channel c, int netId,
+            @Nullable ActionListener listener) {
         checkChannel(c);
         c.mAsyncChannel.sendMessage(DELETE_PERSISTENT_GROUP, netId, c.putListener(listener));
     }
@@ -1673,23 +1727,68 @@
      *
      * @param c is the channel created at {@link #initialize}
      * @param listener for callback when persistent group info list is available. Can be null.
+     *
      * @hide
      */
-    @UnsupportedAppUsage
-    public void requestPersistentGroupInfo(Channel c, PersistentGroupInfoListener listener) {
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_SETTINGS,
+            android.Manifest.permission.NETWORK_STACK,
+            android.Manifest.permission.READ_WIFI_CREDENTIAL
+    })
+    public void requestPersistentGroupInfo(@NonNull Channel c,
+            @Nullable PersistentGroupInfoListener listener) {
         checkChannel(c);
         c.mAsyncChannel.sendMessage(REQUEST_PERSISTENT_GROUP_INFO, 0, c.putListener(listener));
     }
 
     /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"MIRACAST_"}, value = {
+            MIRACAST_DISABLED,
+            MIRACAST_SOURCE,
+            MIRACAST_SINK})
+    public @interface MiracastMode {}
+
+    /**
+     * Miracast is disabled.
+     * @hide
+     */
+    @SystemApi
     public static final int MIRACAST_DISABLED = 0;
-    /** @hide */
+    /**
+     * Device acts as a Miracast source.
+     * @hide
+     */
+    @SystemApi
     public static final int MIRACAST_SOURCE   = 1;
-    /** @hide */
+    /**
+     * Device acts as a Miracast sink.
+     * @hide
+     */
+    @SystemApi
     public static final int MIRACAST_SINK     = 2;
-    /** Internal use only @hide */
-    @UnsupportedAppUsage
-    public void setMiracastMode(int mode) {
+
+    /**
+     * This is used to provide information to drivers to optimize performance depending
+     * on the current mode of operation.
+     * {@link #MIRACAST_DISABLED} - disabled
+     * {@link #MIRACAST_SOURCE} - source operation
+     * {@link #MIRACAST_SINK} - sink operation
+     *
+     * As an example, the driver could reduce the channel dwell time during scanning
+     * when acting as a source or sink to minimize impact on Miracast.
+     *
+     * @param mode mode of operation. One of {@link #MIRACAST_DISABLED}, {@link #MIRACAST_SOURCE},
+     * or {@link #MIRACAST_SINK}
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(allOf = {
+            android.Manifest.permission.CONNECTIVITY_INTERNAL,
+            android.Manifest.permission.CONFIGURE_WIFI_DISPLAY})
+    public void setMiracastMode(@MiracastMode int mode) {
         try {
             mService.setMiracastMode(mode);
         } catch (RemoteException e) {
@@ -1778,8 +1877,10 @@
      *
      * @param c is the channel created at {@link #initialize}.
      * @param listener for callback on success or failure. Can be null.
+     *
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
     public void factoryReset(@NonNull Channel c, @Nullable ActionListener listener) {
         checkChannel(c);
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
index 3caa280..48b0703 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
@@ -16,49 +16,68 @@
 
 package android.net.wifi.p2p;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcelable;
 import android.os.Parcel;
+import android.os.Parcelable;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Locale;
 
 /**
- * A class representing Wifi Display information for a device
- * @hide
+ * A class representing Wifi Display information for a device.
+ *
+ * See Wifi Display technical specification v1.0.0, section 5.1.2.
  */
-public class WifiP2pWfdInfo implements Parcelable {
-
-    private static final String TAG = "WifiP2pWfdInfo";
+public final class WifiP2pWfdInfo implements Parcelable {
 
     private boolean mWfdEnabled;
 
+    /** Device information bitmap */
     private int mDeviceInfo;
 
-    public static final int WFD_SOURCE              = 0;
-    public static final int PRIMARY_SINK            = 1;
-    public static final int SECONDARY_SINK          = 2;
-    public static final int SOURCE_OR_PRIMARY_SINK  = 3;
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "DEVICE_TYPE_" }, value = {
+            DEVICE_TYPE_WFD_SOURCE,
+            DEVICE_TYPE_PRIMARY_SINK,
+            DEVICE_TYPE_SECONDARY_SINK,
+            DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK})
+    public @interface DeviceType {}
 
-    /* Device information bitmap */
-    /** One of {@link #WFD_SOURCE}, {@link #PRIMARY_SINK}, {@link #SECONDARY_SINK}
-     * or {@link #SOURCE_OR_PRIMARY_SINK}
+    /** The device is a Wifi Display Source. */
+    public static final int DEVICE_TYPE_WFD_SOURCE = 0;
+    /** The device is a primary sink. */
+    public static final int DEVICE_TYPE_PRIMARY_SINK = 1;
+    /** The device is a secondary sink. */
+    public static final int DEVICE_TYPE_SECONDARY_SINK = 2;
+    /** The device is dual-role capable i.e. either a WFD source or a primary sink. */
+    public static final int DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK = 3;
+
+    /**
+     * {@link #mDeviceInfo} & {@link #DEVICE_TYPE} is one of {@link #DEVICE_TYPE_WFD_SOURCE},
+     * {@link #DEVICE_TYPE_PRIMARY_SINK}, {@link #DEVICE_TYPE_SECONDARY_SINK} or
+     * {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}.
      */
-    private static final int DEVICE_TYPE                            = 0x3;
-    private static final int COUPLED_SINK_SUPPORT_AT_SOURCE         = 0x4;
-    private static final int COUPLED_SINK_SUPPORT_AT_SINK           = 0x8;
-    private static final int SESSION_AVAILABLE                      = 0x30;
-    private static final int SESSION_AVAILABLE_BIT1                 = 0x10;
-    private static final int SESSION_AVAILABLE_BIT2                 = 0x20;
+    private static final int DEVICE_TYPE                            = 1 << 1 | 1 << 0;
+    private static final int COUPLED_SINK_SUPPORT_AT_SOURCE         = 1 << 2;
+    private static final int COUPLED_SINK_SUPPORT_AT_SINK           = 1 << 3;
+    private static final int SESSION_AVAILABLE_BIT1                 = 1 << 4;
+    private static final int SESSION_AVAILABLE_BIT2                 = 1 << 5;
+    private static final int SESSION_AVAILABLE                      =
+            SESSION_AVAILABLE_BIT2 | SESSION_AVAILABLE_BIT1;
 
     private int mCtrlPort;
 
     private int mMaxThroughput;
 
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    public WifiP2pWfdInfo() {
-    }
+    /** Default constructor. */
+    public WifiP2pWfdInfo() {}
 
+    /** @hide */
     @UnsupportedAppUsage
     public WifiP2pWfdInfo(int devInfo, int ctrlPort, int maxTput) {
         mWfdEnabled = true;
@@ -67,24 +86,40 @@
         mMaxThroughput = maxTput;
     }
 
-    @UnsupportedAppUsage
+    /** Returns true is Wifi Display is enabled, false otherwise. */
     public boolean isWfdEnabled() {
         return mWfdEnabled;
     }
 
-    @UnsupportedAppUsage
+    /**
+     * Sets whether Wifi Display should be enabled.
+     *
+     * @param enabled true to enable Wifi Display, false to disable
+     */
     public void setWfdEnabled(boolean enabled) {
         mWfdEnabled = enabled;
     }
 
-    @UnsupportedAppUsage
+    /**
+     * Get the type of the device.
+     * One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK},
+     * {@link #DEVICE_TYPE_SECONDARY_SINK}, {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}
+     */
+    @DeviceType
     public int getDeviceType() {
-        return (mDeviceInfo & DEVICE_TYPE);
+        return mDeviceInfo & DEVICE_TYPE;
     }
 
-    @UnsupportedAppUsage
-    public boolean setDeviceType(int deviceType) {
-        if (deviceType >= WFD_SOURCE && deviceType <= SOURCE_OR_PRIMARY_SINK) {
+    /**
+     * Sets the type of the device.
+     *
+     * @param deviceType One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK},
+     * {@link #DEVICE_TYPE_SECONDARY_SINK}, {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}
+     * @return true if the device type was successfully set, false otherwise
+     */
+    public boolean setDeviceType(@DeviceType int deviceType) {
+        if (DEVICE_TYPE_WFD_SOURCE <= deviceType
+                && deviceType <= DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK) {
             mDeviceInfo &= ~DEVICE_TYPE;
             mDeviceInfo |= deviceType;
             return true;
@@ -92,35 +127,16 @@
         return false;
     }
 
-    public boolean isCoupledSinkSupportedAtSource() {
-        return (mDeviceInfo & COUPLED_SINK_SUPPORT_AT_SINK) != 0;
-    }
-
-    public void setCoupledSinkSupportAtSource(boolean enabled) {
-        if (enabled ) {
-            mDeviceInfo |= COUPLED_SINK_SUPPORT_AT_SINK;
-        } else {
-            mDeviceInfo &= ~COUPLED_SINK_SUPPORT_AT_SINK;
-        }
-    }
-
-    public boolean isCoupledSinkSupportedAtSink() {
-        return (mDeviceInfo & COUPLED_SINK_SUPPORT_AT_SINK) != 0;
-    }
-
-    public void setCoupledSinkSupportAtSink(boolean enabled) {
-        if (enabled ) {
-            mDeviceInfo |= COUPLED_SINK_SUPPORT_AT_SINK;
-        } else {
-            mDeviceInfo &= ~COUPLED_SINK_SUPPORT_AT_SINK;
-        }
-    }
-
+    /** Returns true if a session is available, false otherwise. */
     public boolean isSessionAvailable() {
         return (mDeviceInfo & SESSION_AVAILABLE) != 0;
     }
 
-    @UnsupportedAppUsage
+    /**
+     * Sets whether a session is available.
+     *
+     * @param enabled true to indicate that a session is available, false otherwise.
+     */
     public void setSessionAvailable(boolean enabled) {
         if (enabled) {
             mDeviceInfo |= SESSION_AVAILABLE_BIT1;
@@ -130,29 +146,33 @@
         }
     }
 
+    /** Returns the TCP port at which the WFD Device listens for RTSP messages. */
     public int getControlPort() {
         return mCtrlPort;
     }
 
-    @UnsupportedAppUsage
+    /** Sets the TCP port at which the WFD Device listens for RTSP messages. */
     public void setControlPort(int port) {
         mCtrlPort = port;
     }
 
-    @UnsupportedAppUsage
+    /** Sets the maximum average throughput capability of the WFD Device, in megabits/second. */
     public void setMaxThroughput(int maxThroughput) {
         mMaxThroughput = maxThroughput;
     }
 
+    /** Returns the maximum average throughput capability of the WFD Device, in megabits/second. */
     public int getMaxThroughput() {
         return mMaxThroughput;
     }
 
+    /** @hide */
     public String getDeviceInfoHex() {
         return String.format(
                 Locale.US, "%04x%04x%04x", mDeviceInfo, mCtrlPort, mMaxThroughput);
     }
 
+    @Override
     public String toString() {
         StringBuffer sbuf = new StringBuffer();
         sbuf.append("WFD enabled: ").append(mWfdEnabled);
@@ -167,9 +187,8 @@
         return 0;
     }
 
-    /** copy constructor */
-    @UnsupportedAppUsage
-    public WifiP2pWfdInfo(WifiP2pWfdInfo source) {
+    /** Copy constructor. */
+    public WifiP2pWfdInfo(@Nullable WifiP2pWfdInfo source) {
         if (source != null) {
             mWfdEnabled = source.mWfdEnabled;
             mDeviceInfo = source.mDeviceInfo;
@@ -179,14 +198,15 @@
     }
 
     /** Implement the Parcelable interface */
-    public void writeToParcel(Parcel dest, int flags) {
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeInt(mWfdEnabled ? 1 : 0);
         dest.writeInt(mDeviceInfo);
         dest.writeInt(mCtrlPort);
         dest.writeInt(mMaxThroughput);
     }
 
-    public void readFromParcel(Parcel in) {
+    private void readFromParcel(Parcel in) {
         mWfdEnabled = (in.readInt() == 1);
         mDeviceInfo = in.readInt();
         mCtrlPort = in.readInt();
@@ -194,8 +214,7 @@
     }
 
     /** Implement the Parcelable interface */
-    @UnsupportedAppUsage
-    public static final @android.annotation.NonNull Creator<WifiP2pWfdInfo> CREATOR =
+    public static final @NonNull Creator<WifiP2pWfdInfo> CREATOR =
         new Creator<WifiP2pWfdInfo>() {
             public WifiP2pWfdInfo createFromParcel(Parcel in) {
                 WifiP2pWfdInfo device = new WifiP2pWfdInfo();
diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java
index 6a6e7a1..cf74ff0 100644
--- a/wifi/java/com/android/server/wifi/BaseWifiService.java
+++ b/wifi/java/com/android/server/wifi/BaseWifiService.java
@@ -289,18 +289,6 @@
         throw new UnsupportedOperationException();
     }
 
-    /** @deprecated replaced by {@link #startLocalOnlyHotspot(ILocalOnlyHotspotCallback, String)} */
-    @Deprecated
-    public int startLocalOnlyHotspot(Messenger messenger, IBinder binder, String packageName) {
-        throw new UnsupportedOperationException();
-    }
-
-    /** @deprecated replaced by newer signature */
-    @Deprecated
-    public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName) {
-        return startLocalOnlyHotspot(callback, packageName, null, null);
-    }
-
     @Override
     public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName,
             String featureId, SoftApConfiguration customConfig) {
@@ -312,12 +300,6 @@
         throw new UnsupportedOperationException();
     }
 
-    /** @deprecated replaced by {@link #startWatchLocalOnlyHotspot(ILocalOnlyHotspotCallback)} */
-    @Deprecated
-    public void startWatchLocalOnlyHotspot(Messenger messenger, IBinder binder) {
-        throw new UnsupportedOperationException();
-    }
-
     @Override
     public void startWatchLocalOnlyHotspot(ILocalOnlyHotspotCallback callback) {
         throw new UnsupportedOperationException();
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 17f3bb2..06ebc1b 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -702,7 +702,19 @@
     @Test
     public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() {
         try {
-            mWifiManager.registerSoftApCallback(null, new HandlerExecutor(mHandler));
+            mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), null);
+            fail("expected IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    /**
+     * Verify an IllegalArgumentException is thrown if executor is null.
+     */
+    @Test
+    public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForExecutor() {
+        try {
+            mWifiManager.registerSoftApCallback(null, mSoftApCallback);
             fail("expected IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
         }
@@ -724,9 +736,10 @@
      * Verify main looper is used when handler is not provided.
      */
     @Test
-    public void registerSoftApCallbackUsesMainLooperOnNullArgumentForHandler() {
-        when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
-        mWifiManager.registerSoftApCallback(mSoftApCallback, null);
+    public void registerSoftApCallbackUsesMainExecutorOnNoExecutorProvided() {
+        when(mContext.getMainExecutor()).thenReturn(
+                new HandlerExecutor(new Handler(mLooper.getLooper())));
+        mWifiManager.registerSoftApCallback(mSoftApCallback);
         verify(mContext).getMainExecutor();
     }
 
@@ -735,7 +748,7 @@
      */
     @Test
     public void registerSoftApCallbackCallGoesToWifiServiceImpl() throws Exception {
-        mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler));
+        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
         verify(mWifiService).registerSoftApCallback(any(IBinder.class),
                 any(ISoftApCallback.Stub.class), anyInt());
     }
@@ -746,7 +759,7 @@
     @Test
     public void unregisterSoftApCallbackCallGoesToWifiServiceImpl() throws Exception {
         ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
-        mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler));
+        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
         verify(mWifiService).registerSoftApCallback(any(IBinder.class),
                 any(ISoftApCallback.Stub.class), callbackIdentifier.capture());
 
@@ -761,7 +774,7 @@
     public void softApCallbackProxyCallsOnStateChanged() throws Exception {
         ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
                 ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler));
+        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
         verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
                 anyInt());
 
@@ -777,7 +790,7 @@
     public void softApCallbackProxyCallsOnConnectedClientsChanged() throws Exception {
         ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
                 ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler));
+        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
         verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
                 anyInt());
 
@@ -798,7 +811,7 @@
         testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH);
         ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
                 ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler));
+        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
         verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
                 anyInt());
 
@@ -817,7 +830,7 @@
         testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH);
         ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
                 ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
-        mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler));
+        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
         verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
                 anyInt());
 
@@ -843,7 +856,7 @@
                 ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
         TestLooper altLooper = new TestLooper();
         Handler altHandler = new Handler(altLooper.getLooper());
-        mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(altHandler));
+        mWifiManager.registerSoftApCallback(new HandlerExecutor(altHandler), mSoftApCallback);
         verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
                 anyInt());
 
@@ -857,7 +870,7 @@
      */
     @Test
     public void testCorrectLooperIsUsedForSoftApCallbackHandler() throws Exception {
-        mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler));
+        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
         mLooper.dispatchAll();
         verify(mWifiService).registerSoftApCallback(any(IBinder.class),
                 any(ISoftApCallback.Stub.class), anyInt());
@@ -1147,10 +1160,11 @@
     @Test
     public void registerTrafficStateCallbackUsesMainLooperOnNullArgumentForHandler()
             throws Exception {
-        when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
+        when(mContext.getMainExecutor()).thenReturn(
+                new HandlerExecutor(new Handler(mLooper.getLooper())));
         ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor =
                 ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
-        mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, null);
+        mWifiManager.registerTrafficStateCallback(mTrafficStateCallback);
         verify(mWifiService).registerTrafficStateCallback(
                 any(IBinder.class), callbackCaptor.capture(), anyInt());
 
@@ -1166,7 +1180,8 @@
     @Test
     public void unregisterTrafficStateCallbackCallGoesToWifiServiceImpl() throws Exception {
         ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
-        mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, mHandler);
+        mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler),
+                mTrafficStateCallback);
         verify(mWifiService).registerTrafficStateCallback(any(IBinder.class),
                 any(ITrafficStateCallback.Stub.class), callbackIdentifier.capture());
 
@@ -1182,7 +1197,8 @@
     public void trafficStateCallbackProxyCallsOnMultipleUpdates() throws Exception {
         ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor =
                 ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
-        mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, mHandler);
+        mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler),
+                mTrafficStateCallback);
         verify(mWifiService).registerTrafficStateCallback(
                 any(IBinder.class), callbackCaptor.capture(), anyInt());
 
@@ -1201,7 +1217,7 @@
                 TrafficStateCallback.DATA_ACTIVITY_OUT);
     }
 
-    /*
+    /**
      * Verify client-provided callback is being called on the correct thread
      */
     @Test
@@ -1210,7 +1226,8 @@
                 ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class);
         TestLooper altLooper = new TestLooper();
         Handler altHandler = new Handler(altLooper.getLooper());
-        mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, altHandler);
+        mWifiManager.registerTrafficStateCallback(new HandlerExecutor(altHandler),
+                mTrafficStateCallback);
         verify(mContext, never()).getMainLooper();
         verify(mContext, never()).getMainExecutor();
         verify(mWifiService).registerTrafficStateCallback(
@@ -1228,10 +1245,11 @@
     @Test
     public void registerNetworkRequestMatchCallbackCallGoesToWifiServiceImpl()
             throws Exception {
-        when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
+        when(mContext.getMainExecutor()).thenReturn(
+                new HandlerExecutor(new Handler(mLooper.getLooper())));
         ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor =
                 ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class);
-        mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, null);
+        mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback);
         verify(mWifiService).registerNetworkRequestMatchCallback(
                 any(IBinder.class), callbackCaptor.capture(), anyInt());
 
@@ -1265,7 +1283,8 @@
     @Test
     public void unregisterNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception {
         ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
-        mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, mHandler);
+        mWifiManager.registerNetworkRequestMatchCallback(new HandlerExecutor(mHandler),
+                mNetworkRequestMatchCallback);
         verify(mWifiService).registerNetworkRequestMatchCallback(
                 any(IBinder.class), any(INetworkRequestMatchCallback.class),
                 callbackIdentifier.capture());
@@ -1282,10 +1301,11 @@
     @Test
     public void networkRequestUserSelectionCallbackCallGoesToWifiServiceImpl()
             throws Exception {
-        when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
+        when(mContext.getMainExecutor()).thenReturn(
+                new HandlerExecutor(new Handler(mLooper.getLooper())));
         ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor =
                 ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class);
-        mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, null);
+        mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback);
         verify(mWifiService).registerNetworkRequestMatchCallback(
                 any(IBinder.class), callbackCaptor.capture(), anyInt());
 
@@ -1586,6 +1606,7 @@
         assertTrue(mWifiManager.isP2pSupported());
         assertFalse(mWifiManager.isPortableHotspotSupported());
         assertFalse(mWifiManager.is5GHzBandSupported());
+        assertFalse(mWifiManager.is6GHzBandSupported());
         assertFalse(mWifiManager.isDeviceToDeviceRttSupported());
         assertFalse(mWifiManager.isDeviceToApRttSupported());
         assertFalse(mWifiManager.isPreferredNetworkOffloadSupported());
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
index d2f1168..cea73ef 100644
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
+++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
@@ -43,7 +43,7 @@
     @Before
     public void setUp() {
         // initialize device info flags.
-        mSourceInfo.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE);
+        mSourceInfo.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE);
         mSourceInfo.setSessionAvailable(true);
     }
 
@@ -57,14 +57,8 @@
         info.setWfdEnabled(true);
         assertTrue(info.isWfdEnabled());
 
-        info.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE);
-        assertEquals(WifiP2pWfdInfo.WFD_SOURCE, info.getDeviceType());
-
-        info.setCoupledSinkSupportAtSource(true);
-        assertTrue(info.isCoupledSinkSupportedAtSource());
-
-        info.setCoupledSinkSupportAtSink(true);
-        assertTrue(info.isCoupledSinkSupportedAtSink());
+        info.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE);
+        assertEquals(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE, info.getDeviceType());
 
         info.setSessionAvailable(true);
         assertTrue(info.isSessionAvailable());
@@ -75,7 +69,7 @@
         info.setMaxThroughput(TEST_MAX_TPUT);
         assertEquals(TEST_MAX_TPUT, info.getMaxThroughput());
 
-        assertEquals("0018270f0400", info.getDeviceInfoHex());
+        assertEquals("0010270f0400", info.getDeviceInfoHex());
     }
 
     /**