Merge "Move permission request messages to PermissionController"
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/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 44a6229..8b1df00 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -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";
@@ -30511,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;
@@ -30531,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();
@@ -30567,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();
@@ -30691,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 {
@@ -39009,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";
@@ -39025,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";
   }
diff --git a/api/system-current.txt b/api/system-current.txt
index 427c150..fd6afea 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,14 +4835,14 @@
 
   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_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 @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 @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState();
@@ -4846,20 +4852,20 @@
     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(@Nullable java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerSoftApCallback(@Nullable java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback);
     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(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(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 int CHANGE_REASON_ADDED = 0; // 0x0
     field public static final int CHANGE_REASON_CONFIG_CHANGE = 2; // 0x2
@@ -5151,6 +5157,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 {
diff --git a/api/system-lint-baseline.txt b/api/system-lint-baseline.txt
index 21526d0..6c659c8 100644
--- a/api/system-lint-baseline.txt
+++ b/api/system-lint-baseline.txt
@@ -7,6 +7,22 @@
     
 
 
+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 +33,7 @@
     
 
 
-InterfaceConstant: android.service.storage.ExternalStorageService#SERVICE_INTERFACE:
-    
+
 
 
 KotlinKeyword: android.app.Notification#when:
@@ -198,9 +213,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):
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/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/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 4fb2196..33ea32b 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;
@@ -194,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}.
@@ -216,6 +216,8 @@
             new ArrayMap<String, ServiceFetcher<?>>();
     private static int sServiceCacheSize;
 
+    private static volatile boolean sInitializing;
+
     // Not instantiable.
     private SystemServiceRegistry() { }
 
@@ -1292,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];
@@ -1307,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);
@@ -1315,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);
@@ -1324,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());
                     }});
     }
 
@@ -1517,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/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/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/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/UserManager.java b/core/java/android/os/UserManager.java
index ed21b72..bb62eb2 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1359,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;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 50dac46..3ac7deb 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -14099,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/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/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/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/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9c1d20e..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" />
@@ -1601,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"
@@ -1608,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"
@@ -3569,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/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/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/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/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/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/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/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/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 741c95f..87fe3a2 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -103,14 +103,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) {
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/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/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/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/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/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/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/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
index b5a7847..322b23f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
@@ -175,7 +175,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);
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..6d6a1fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java
@@ -188,6 +188,7 @@
                 boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP;
                 boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL;
 
+                boolean expandingBelowNotch = mExpandingBelowNotch;
                 if (isUp || isCancel) {
                     mExpandingBelowNotch = false;
                 }
@@ -236,8 +237,9 @@
                 // regular view bounds.
                 if (isDown && ev.getY() >= mView.getBottom()) {
                     mExpandingBelowNotch = true;
+                    expandingBelowNotch = true;
                 }
-                if (mExpandingBelowNotch) {
+                if (expandingBelowNotch) {
                     return mStatusBarView.dispatchTouchEvent(ev);
                 }
 
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/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/notification/collection/NotifListBuilderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImplTest.java
index 7326cd4..a25af84 100644
--- 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
@@ -34,7 +34,6 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.util.ArrayMap;
-import android.util.Log;
 
 import androidx.test.filters.SmallTest;
 
@@ -121,7 +120,7 @@
         addNotif(6, PACKAGE_1).setRank(0);
         dispatchBuild();
 
-        // The final output is sorted based on rank
+        // The final output is sorted based first by rank and then by when
         verifyBuiltList(
                 notif(6),
                 notif(5),
@@ -204,7 +203,7 @@
         addGroupSummary(6, PACKAGE_1, GROUP_1).setRank(3);
         dispatchBuild();
 
-        // THEN the notifs are grouped together
+        // THEN the children are sorted by rank and when
         verifyBuiltList(
                 group(
                         summary(6),
@@ -503,10 +502,6 @@
         addNotif(5, PACKAGE_3);
         dispatchBuild();
 
-        for (NotificationEntry entry : mEntrySet) {
-            Log.d("pizza", "entry: " + entry.getKey() + " " + entry);
-        }
-
         // THEN both promoters are called on each child, except for children that a previous
         // promoter has already promoted
         verify(promoter1).shouldPromoteToTopLevel(mEntrySet.get(1));
@@ -840,6 +835,9 @@
                 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)
@@ -860,14 +858,14 @@
 
     @Test(expected = IllegalStateException.class)
     public void testOutOfOrderPrompterInvalidationThrows() {
-        // GIVEN a NotifFilter that gets invalidated during the grouping stage
+        // 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 filter is invalidated
+        // WHEN we try to run the pipeline and the promoter is invalidated
         addNotif(0, PACKAGE_1);
         dispatchBuild();
 
@@ -876,14 +874,14 @@
 
     @Test(expected = IllegalStateException.class)
     public void testOutOfOrderComparatorInvalidationThrows() {
-        // GIVEN a NotifFilter that gets invalidated during the grouping stage
+        // 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 filter is invalidated
+        // WHEN we try to run the pipeline and the comparator is invalidated
         addNotif(0, PACKAGE_1);
         dispatchBuild();
 
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/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..07be0d7 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
@@ -141,13 +141,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;
 
@@ -194,7 +194,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 +228,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 +257,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 +287,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/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/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/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 8d2fc17..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()");
@@ -2009,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/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/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/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 91c909d..a91998a 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -539,6 +539,7 @@
         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.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 3ef848c..79c76b9 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -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
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index 5a21016..06cce52 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -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.
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/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index f1dbd7b..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() {
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/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/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 39aa51a..a23e2f1 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;
 
@@ -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/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/startop/apps/test/Android.bp b/startop/apps/test/Android.bp
index c7c70db..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",
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/InteractiveMicrobenchmarkActivity.java b/startop/apps/test/src/InteractiveMicrobenchmarkActivity.java
index 8ed7f6a..c3839c1 100644
--- a/startop/apps/test/src/InteractiveMicrobenchmarkActivity.java
+++ b/startop/apps/test/src/InteractiveMicrobenchmarkActivity.java
@@ -36,6 +36,8 @@
         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);
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 3f95a81..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) {
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index e6fe5f6..3d63e4a 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1297,7 +1297,7 @@
      *
      * @return Sorted list of the currently available {@link SubscriptionInfo}
      * records on the device.
-     * This is similar to {@link getActiveSubscriptionInfoList} except that it will return
+     * This is similar to {@link #getActiveSubscriptionInfoList} except that it will return
      * both active and hidden SubscriptionInfos.
      *
      */
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/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/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/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());
     }
 
     /**