Merge "Add a new system service for blob store management."
diff --git a/api/current.txt b/api/current.txt
index 0c30d0e..fdd30db 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -30010,6 +30010,7 @@
     method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int addNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
     method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void addScanResultsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.ScanResultsListener);
+    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public void addSuggestionConnectionStatusListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
     method public static int calculateSignalLevel(int, int);
     method @Deprecated public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
     method public static int compareSignalLevel(int, int);
@@ -30046,6 +30047,7 @@
     method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int removeNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
     method @Deprecated @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", "android.permission.NETWORK_CARRIER_PROVISIONING"}) public void removePasspointConfiguration(String);
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeScanResultsListener(@NonNull android.net.wifi.WifiManager.ScanResultsListener);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeSuggestionConnectionStatusListener(@NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
     method @Deprecated public boolean saveConfiguration();
     method public void setTdlsEnabled(java.net.InetAddress, boolean);
     method public void setTdlsEnabledWithMacAddress(String, boolean);
@@ -30079,6 +30081,10 @@
     field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL = 1; // 0x1
     field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5; // 0x5
     field public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0; // 0x0
+    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1; // 0x1
+    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2; // 0x2
+    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3; // 0x3
+    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0; // 0x0
     field @Deprecated public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE";
     field @Deprecated public static final String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE";
     field @Deprecated public static final int WIFI_MODE_FULL = 1; // 0x1
@@ -30125,6 +30131,10 @@
     method public void onScanResultsAvailable();
   }
 
+  public static interface WifiManager.SuggestionConnectionStatusListener {
+    method public void onConnectionStatus(@NonNull android.net.wifi.WifiNetworkSuggestion, int);
+  }
+
   public class WifiManager.WifiLock {
     method public void acquire();
     method public boolean isHeld();
@@ -44280,6 +44290,9 @@
     field public static final int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
     field public static final String EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX";
     field public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX";
+    field public static final String KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrp_thresholds_int_array";
+    field public static final String KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrq_thresholds_int_array";
+    field public static final String KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY = "5g_nr_sssinr_thresholds_int_array";
     field public static final String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
     field public static final String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
     field public static final String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL = "allow_add_call_during_video_call";
@@ -44411,6 +44424,7 @@
     field public static final String KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT = "opportunistic_network_entry_threshold_rssnr_int";
     field public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSRP_INT = "opportunistic_network_exit_threshold_rsrp_int";
     field public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT = "opportunistic_network_exit_threshold_rssnr_int";
+    field public static final String KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT = "parameters_use_for_5g_nr_signal_bar_int";
     field public static final String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
     field public static final String KEY_PREVENT_CLIR_ACTIVATION_AND_DEACTIVATION_CODE_BOOL = "prevent_clir_activation_and_deactivation_code_bool";
     field public static final String KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY = "radio_restart_failure_causes_int_array";
diff --git a/api/lint-baseline.txt b/api/lint-baseline.txt
index 2ca8cf4..4a37e67 100644
--- a/api/lint-baseline.txt
+++ b/api/lint-baseline.txt
@@ -534,7 +534,7 @@
 MissingNullability: android.media.MediaMetadataRetriever#getFrameAtTime(long, int, android.media.MediaMetadataRetriever.BitmapParams):
     
 MissingNullability: android.media.MediaMetadataRetriever#getScaledFrameAtTime(long, int, int, int, android.media.MediaMetadataRetriever.BitmapParams):
-    
+
 
 
 RequiresPermission: android.accounts.AccountManager#getAccountsByTypeAndFeatures(String, String[], android.accounts.AccountManagerCallback<android.accounts.Account[]>, android.os.Handler):
@@ -1160,7 +1160,7 @@
 SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(String, long, float, java.util.concurrent.Executor, android.location.LocationListener):
     
 SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(long, float, android.location.Criteria, java.util.concurrent.Executor, android.location.LocationListener):
-    
+
 
 
 StreamFiles: android.content.res.loader.DirectoryResourceLoader#DirectoryResourceLoader(java.io.File):
diff --git a/api/system-current.txt b/api/system-current.txt
index 463521c..5d3ecf5 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -250,6 +250,7 @@
 
   public static final class R.drawable {
     field public static final int ic_info = 17301684; // 0x10800b4
+    field public static final int stat_notify_wifi_in_range = 17301685; // 0x10800b5
   }
 
   public static final class R.raw {
@@ -268,6 +269,9 @@
     field public static final int config_helpIntentNameKey = 17039390; // 0x104001e
     field public static final int config_helpPackageNameKey = 17039387; // 0x104001b
     field public static final int config_helpPackageNameValue = 17039388; // 0x104001c
+    field public static final int notification_channel_network_alerts = 17039398; // 0x1040026
+    field public static final int notification_channel_network_available = 17039399; // 0x1040027
+    field public static final int notification_channel_network_status = 17039397; // 0x1040025
   }
 
   public static final class R.style {
@@ -4828,6 +4832,8 @@
     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();
+    method public boolean isApMacRandomizationSupported();
+    method public boolean isConnectedMacRandomizationSupported();
     method @Deprecated public boolean isDeviceToDeviceRttSupported();
     method public boolean isPortableHotspotSupported();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled();
@@ -7484,13 +7490,6 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallQuality> CREATOR;
   }
 
-  public class CallerInfo {
-    method @Nullable public android.net.Uri getContactDisplayPhotoUri();
-    method public long getContactId();
-    method @Nullable public String getName();
-    method @Nullable public String getPhoneNumber();
-  }
-
   public class CarrierConfigManager {
     method @NonNull public static android.os.PersistableBundle getDefaultConfig();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle);
@@ -8122,6 +8121,12 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhoneNumberRange> CREATOR;
   }
 
+  public class PhoneNumberUtils {
+    method @NonNull public static String getUsernameFromUriNumber(@NonNull String);
+    method public static boolean isUriNumber(@Nullable String);
+    method public static boolean isVoiceMailNumber(@NonNull android.content.Context, int, @Nullable String);
+  }
+
   public class PhoneStateListener {
     method public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
     method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onCallDisconnectCauseChanged(int, int);
@@ -8354,6 +8359,7 @@
   }
 
   public final class SmsCbLocation implements android.os.Parcelable {
+    ctor public SmsCbLocation(@NonNull String, int, int);
     method public int describeContents();
     method public int getCid();
     method public int getLac();
@@ -8403,6 +8409,7 @@
   public final class SmsManager {
     method public boolean disableCellBroadcastRange(int, int, int);
     method public boolean enableCellBroadcastRange(int, int, int);
+    method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>);
   }
 
@@ -8420,6 +8427,7 @@
     method public void requestEmbeddedSubscriptionInfoListRefresh(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultDataSubId(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultSmsSubId(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSubscriptionEnabled(int, boolean);
     field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI;
@@ -8489,11 +8497,13 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getDataActivationState();
     method @Deprecated public boolean getDataEnabled();
     method @Deprecated public boolean getDataEnabled(int);
+    method @Nullable public static android.content.ComponentName getDefaultRespondViaMessageApplication(@NonNull android.content.Context, boolean);
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping();
+    method public int getMaxNumberOfSimultaneouslyActiveSims();
     method public static long getMaxNumberVerificationTimeoutMillis();
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getNetworkCountryIso(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getPreferredNetworkTypeBitmask();
diff --git a/api/test-current.txt b/api/test-current.txt
index e4f2409..b735f05 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -756,6 +756,7 @@
   public abstract class PackageManager {
     method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void addOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener);
     method public abstract boolean arePermissionsIndividuallyControlled();
+    method @Nullable public String getContentCaptureServicePackageName();
     method @Nullable @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract String getDefaultBrowserPackageNameAsUser(int);
     method @Nullable public String getIncidentReportApproverPackageName();
     method public abstract int getInstallReason(@NonNull String, @NonNull android.os.UserHandle);
@@ -3021,6 +3022,9 @@
 
   public class PhoneNumberUtils {
     method public static int getMinMatchForTest();
+    method @NonNull public static String getUsernameFromUriNumber(@NonNull String);
+    method public static boolean isUriNumber(@Nullable String);
+    method public static boolean isVoiceMailNumber(@NonNull android.content.Context, int, @Nullable String);
     method public static void setMinMatchForTest(int);
   }
 
@@ -3044,6 +3048,7 @@
 
   public final class SmsManager {
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int checkSmsShortCodeDestination(String, String);
+    method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
     field public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1; // 0x1
     field public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0; // 0x0
     field public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3; // 0x3
@@ -3052,6 +3057,7 @@
   }
 
   public class SubscriptionManager {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int);
     field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI;
     field @NonNull public static final android.net.Uri VT_ENABLED_CONTENT_URI;
     field @NonNull public static final android.net.Uri WFC_ENABLED_CONTENT_URI;
@@ -3064,6 +3070,7 @@
     method public int checkCarrierPrivilegesForPackage(String);
     method public int getCarrierIdListVersion();
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
+    method @Nullable public static android.content.ComponentName getDefaultRespondViaMessageApplication(@NonNull android.content.Context, boolean);
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getLine1AlphaTag();
     method @NonNull @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getNetworkCountryIso(int);
     method public android.util.Pair<java.lang.Integer,java.lang.Integer> getRadioHalVersion();
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 3cb2273..3d4eea5 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -793,7 +793,6 @@
 Lcom/android/internal/R$id;->message:I
 Lcom/android/internal/R$id;->minute:I
 Lcom/android/internal/R$id;->month:I
-Lcom/android/internal/R$id;->name:I
 Lcom/android/internal/R$id;->notification_header:I
 Lcom/android/internal/R$id;->ok:I
 Lcom/android/internal/R$id;->overlay:I
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 65f9678..6182def 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3931,6 +3931,26 @@
     }
 
     /**
+     * Update the forced status bar color.
+     * @hide
+     */
+    @Override
+    public void updateStatusBarColor(int color) {
+        mTaskDescription.setStatusBarColor(color);
+        setTaskDescription(mTaskDescription);
+    }
+
+    /**
+     * Update the forced navigation bar color.
+     * @hide
+     */
+    @Override
+    public void updateNavigationBarColor(int color) {
+        mTaskDescription.setNavigationBarColor(color);
+        setTaskDescription(mTaskDescription);
+    }
+
+    /**
      * Puts the activity in picture-in-picture mode if the activity supports.
      * @see android.R.attr#supportsPictureInPicture
      * @hide
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 1e78fc1..2e9b2af 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
 
 import android.Manifest;
 import android.annotation.DrawableRes;
@@ -31,6 +32,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ConfigurationInfo;
 import android.content.pm.IPackageDataObserver;
@@ -981,6 +983,9 @@
         private int mNavigationBarColor;
         private boolean mEnsureStatusBarContrastWhenTransparent;
         private boolean mEnsureNavigationBarContrastWhenTransparent;
+        private int mResizeMode;
+        private int mMinWidth;
+        private int mMinHeight;
 
         /**
          * Creates the TaskDescription to the specified values.
@@ -993,7 +998,8 @@
          */
         @Deprecated
         public TaskDescription(String label, Bitmap icon, int colorPrimary) {
-            this(label, icon, 0, null, colorPrimary, 0, 0, 0, false, false);
+            this(label, icon, 0, null, colorPrimary, 0, 0, 0, false, false,
+                    RESIZE_MODE_RESIZEABLE, -1, -1);
             if ((colorPrimary != 0) && (Color.alpha(colorPrimary) != 255)) {
                 throw new RuntimeException("A TaskDescription's primary color should be opaque");
             }
@@ -1009,7 +1015,8 @@
          *                     opaque.
          */
         public TaskDescription(String label, @DrawableRes int iconRes, int colorPrimary) {
-            this(label, null, iconRes, null, colorPrimary, 0, 0, 0, false, false);
+            this(label, null, iconRes, null, colorPrimary, 0, 0, 0, false, false,
+                    RESIZE_MODE_RESIZEABLE, -1, -1);
             if ((colorPrimary != 0) && (Color.alpha(colorPrimary) != 255)) {
                 throw new RuntimeException("A TaskDescription's primary color should be opaque");
             }
@@ -1024,7 +1031,7 @@
          */
         @Deprecated
         public TaskDescription(String label, Bitmap icon) {
-            this(label, icon, 0, null, 0, 0, 0, 0, false, false);
+            this(label, icon, 0, null, 0, 0, 0, 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1);
         }
 
         /**
@@ -1035,7 +1042,8 @@
          *                activity.
          */
         public TaskDescription(String label, @DrawableRes int iconRes) {
-            this(label, null, iconRes, null, 0, 0, 0, 0, false, false);
+            this(label, null, iconRes, null, 0, 0, 0, 0, false, false,
+                    RESIZE_MODE_RESIZEABLE, -1, -1);
         }
 
         /**
@@ -1044,21 +1052,22 @@
          * @param label A label and description of the current state of this activity.
          */
         public TaskDescription(String label) {
-            this(label, null, 0, null, 0, 0, 0, 0, false, false);
+            this(label, null, 0, null, 0, 0, 0, 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1);
         }
 
         /**
          * Creates an empty TaskDescription.
          */
         public TaskDescription() {
-            this(null, null, 0, null, 0, 0, 0, 0, false, false);
+            this(null, null, 0, null, 0, 0, 0, 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1);
         }
 
         /** @hide */
         public TaskDescription(String label, Bitmap bitmap, int iconRes, String iconFilename,
                 int colorPrimary, int colorBackground, int statusBarColor, int navigationBarColor,
                 boolean ensureStatusBarContrastWhenTransparent,
-                boolean ensureNavigationBarContrastWhenTransparent) {
+                boolean ensureNavigationBarContrastWhenTransparent, int resizeMode, int minWidth,
+                int minHeight) {
             mLabel = label;
             mIcon = bitmap;
             mIconRes = iconRes;
@@ -1070,6 +1079,9 @@
             mEnsureStatusBarContrastWhenTransparent = ensureStatusBarContrastWhenTransparent;
             mEnsureNavigationBarContrastWhenTransparent =
                     ensureNavigationBarContrastWhenTransparent;
+            mResizeMode = resizeMode;
+            mMinWidth = minWidth;
+            mMinHeight = minHeight;
         }
 
         /**
@@ -1095,6 +1107,9 @@
             mEnsureStatusBarContrastWhenTransparent = other.mEnsureStatusBarContrastWhenTransparent;
             mEnsureNavigationBarContrastWhenTransparent =
                     other.mEnsureNavigationBarContrastWhenTransparent;
+            mResizeMode = other.mResizeMode;
+            mMinWidth = other.mMinWidth;
+            mMinHeight = other.mMinHeight;
         }
 
         /**
@@ -1120,6 +1135,9 @@
             mEnsureStatusBarContrastWhenTransparent = other.mEnsureStatusBarContrastWhenTransparent;
             mEnsureNavigationBarContrastWhenTransparent =
                     other.mEnsureNavigationBarContrastWhenTransparent;
+            mResizeMode = other.mResizeMode;
+            mMinWidth = other.mMinWidth;
+            mMinHeight = other.mMinHeight;
         }
 
         private TaskDescription(Parcel source) {
@@ -1200,6 +1218,33 @@
         }
 
         /**
+         * Sets the resize mode for this task description. Resize mode as in
+         * {@link android.content.pm.ActivityInfo}.
+         * @hide
+         */
+        public void setResizeMode(int resizeMode) {
+            mResizeMode = resizeMode;
+        }
+
+        /**
+         * The minimal width size to show the app content in freeform mode.
+         * @param minWidth minimal width, -1 for system default.
+         * @hide
+         */
+        public void setMinWidth(int minWidth) {
+            mMinWidth = minWidth;
+        }
+
+        /**
+         * The minimal height size to show the app content in freeform mode.
+         * @param minHeight minimal height, -1 for system default.
+         * @hide
+         */
+        public void setMinHeight(int minHeight) {
+            mMinHeight = minHeight;
+        }
+
+        /**
          * @return The label and description of the current state of this task.
          */
         public String getLabel() {
@@ -1309,6 +1354,27 @@
                     ensureNavigationBarContrastWhenTransparent;
         }
 
+        /**
+         * @hide
+         */
+        public int getResizeMode() {
+            return mResizeMode;
+        }
+
+        /**
+         * @hide
+         */
+        public int getMinWidth() {
+            return mMinWidth;
+        }
+
+        /**
+         * @hide
+         */
+        public int getMinHeight() {
+            return mMinHeight;
+        }
+
         /** @hide */
         public void saveToXml(XmlSerializer out) throws IOException {
             if (mLabel != null) {
@@ -1371,6 +1437,9 @@
             dest.writeInt(mNavigationBarColor);
             dest.writeBoolean(mEnsureStatusBarContrastWhenTransparent);
             dest.writeBoolean(mEnsureNavigationBarContrastWhenTransparent);
+            dest.writeInt(mResizeMode);
+            dest.writeInt(mMinWidth);
+            dest.writeInt(mMinHeight);
             if (mIconFilename == null) {
                 dest.writeInt(0);
             } else {
@@ -1389,6 +1458,9 @@
             mNavigationBarColor = source.readInt();
             mEnsureStatusBarContrastWhenTransparent = source.readBoolean();
             mEnsureNavigationBarContrastWhenTransparent = source.readBoolean();
+            mResizeMode = source.readInt();
+            mMinWidth = source.readInt();
+            mMinHeight = source.readInt();
             mIconFilename = source.readInt() > 0 ? source.readString() : null;
         }
 
@@ -1404,14 +1476,16 @@
 
         @Override
         public String toString() {
-            return "TaskDescription Label: " + mLabel + " Icon: " + mIcon +
-                    " IconRes: " + mIconRes + " IconFilename: " + mIconFilename +
-                    " colorPrimary: " + mColorPrimary + " colorBackground: " + mColorBackground +
-                    " statusBarColor: " + mStatusBarColor + (
-                    mEnsureStatusBarContrastWhenTransparent ? " (contrast when transparent)"
-                            : "") + " navigationBarColor: " + mNavigationBarColor + (
-                    mEnsureNavigationBarContrastWhenTransparent
-                            ? " (contrast when transparent)" : "");
+            return "TaskDescription Label: " + mLabel + " Icon: " + mIcon
+                    + " IconRes: " + mIconRes + " IconFilename: " + mIconFilename
+                    + " colorPrimary: " + mColorPrimary + " colorBackground: " + mColorBackground
+                    + " statusBarColor: " + mStatusBarColor
+                    + (mEnsureStatusBarContrastWhenTransparent ? " (contrast when transparent)"
+                            : "") + " navigationBarColor: " + mNavigationBarColor
+                    + (mEnsureNavigationBarContrastWhenTransparent
+                            ? " (contrast when transparent)" : "")
+                    + " resizeMode: " + ActivityInfo.resizeModeToString(mResizeMode)
+                    + " minWidth: " + mMinWidth + " minHeight: " + mMinHeight;
         }
     }
 
@@ -1523,6 +1597,9 @@
                 pw.print(" iconRes=" + (td.getIconResource() != 0));
                 pw.print(" iconBitmap=" + (td.getIconFilename() != null
                         || td.getInMemoryIcon() != null));
+                pw.print(" resizeMode=" + ActivityInfo.resizeModeToString(td.getResizeMode()));
+                pw.print(" minWidth=" + td.getMinWidth());
+                pw.print(" minHeight=" + td.getMinHeight());
                 pw.println(" }");
             }
         }
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 03ef286..008c4c1 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -3196,6 +3196,15 @@
     }
 
     @Override
+    public String getContentCaptureServicePackageName() {
+        try {
+            return mPM.getContentCaptureServicePackageName();
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    @Override
     public boolean isPackageStateProtected(String packageName, int userId) {
         try {
             return mPM.isPackageStateProtected(packageName, userId);
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 1d78e2c..af0b357 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -692,6 +692,8 @@
 
     String getIncidentReportApproverPackageName();
 
+    String getContentCaptureServicePackageName();
+
     boolean isPackageStateProtected(String packageName, int userId);
 
     void sendDeviceCustomizationReadyBroadcast();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 7509065..51b9e24 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -7458,6 +7458,18 @@
     }
 
     /**
+     * @return the system defined content capture package name, or null if there's none.
+     *
+     * @hide
+     */
+    @TestApi
+    @Nullable
+    public String getContentCaptureServicePackageName() {
+        throw new UnsupportedOperationException(
+                "getContentCaptureServicePackageName not implemented in subclass");
+    }
+
+    /**
      * @return the incident report approver app package name, or null if it's not defined
      * by the OEM.
      *
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index b79cf65..38df3175 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -360,8 +360,9 @@
     /**
      * Retrieve the boolean value for the attribute at <var>index</var>.
      * <p>
-     * If the attribute is an integer value, this method will return whether
-     * it is equal to zero. If the attribute is not a boolean or integer value,
+     * If the attribute is an integer value, this method returns false if the
+     * attribute is equal to zero, and true otherwise.
+     * If the attribute is not a boolean or integer value,
      * this method will attempt to coerce it to an integer using
      * {@link Integer#decode(String)} and return whether it is equal to zero.
      *
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 43ea589..ff4bf2d 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -16,6 +16,7 @@
 
 package android.net;
 
+import android.annotation.NonNull;
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.Build;
@@ -418,7 +419,16 @@
         if (score < 0) {
             throw new IllegalArgumentException("Score must be >= 0");
         }
-        queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED,  score, 0);
+        final NetworkScore ns = new NetworkScore();
+        ns.putIntExtension(NetworkScore.LEGACY_SCORE, score);
+        updateScore(ns);
+    }
+
+    /**
+     * Called by the bearer code when it has a new NetworkScore for this network.
+     */
+    public void updateScore(@NonNull NetworkScore ns) {
+        queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new NetworkScore(ns));
     }
 
     /**
diff --git a/core/java/android/net/NetworkScore.java b/core/java/android/net/NetworkScore.java
new file mode 100644
index 0000000..1ab6335
--- /dev/null
+++ b/core/java/android/net/NetworkScore.java
@@ -0,0 +1,157 @@
+/*
+ * 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.net;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Object representing the quality of a network as perceived by the user.
+ *
+ * A NetworkScore object represents the characteristics of a network that affects how good the
+ * network is considered for a particular use.
+ * @hide
+ */
+public final class NetworkScore implements Parcelable {
+
+    // The key of bundle which is used to get the legacy network score of NetworkAgentInfo.
+    // TODO: Remove this when the transition to NetworkScore is over.
+    public static final String LEGACY_SCORE = "LEGACY_SCORE";
+    @NonNull
+    private final Bundle mExtensions;
+
+    public NetworkScore() {
+        mExtensions = new Bundle();
+    }
+
+    public NetworkScore(@NonNull NetworkScore source) {
+        mExtensions = new Bundle(source.mExtensions);
+    }
+
+    /**
+     * Put the value of parcelable inside the bundle by key.
+     */
+    public void putExtension(@Nullable String key, @Nullable Parcelable value) {
+        mExtensions.putParcelable(key, value);
+    }
+
+    /**
+     * Put the value of int inside the bundle by key.
+     */
+    public void putIntExtension(@Nullable String key, int value) {
+        mExtensions.putInt(key, value);
+    }
+
+    /**
+     * Get the value of non primitive type by key.
+     */
+    public <T extends Parcelable> T getExtension(@Nullable String key) {
+        return mExtensions.getParcelable(key);
+    }
+
+    /**
+     * Get the value of int by key.
+     */
+    public int getIntExtension(@Nullable String key) {
+        return mExtensions.getInt(key);
+    }
+
+    /**
+     * Remove the entry by given key.
+     */
+    public void removeExtension(@Nullable String key) {
+        mExtensions.remove(key);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        synchronized (this) {
+            dest.writeBundle(mExtensions);
+        }
+    }
+
+    public static final @NonNull Creator<NetworkScore> CREATOR = new Creator<NetworkScore>() {
+        @Override
+        public NetworkScore createFromParcel(@NonNull Parcel in) {
+            return new NetworkScore(in);
+        }
+
+        @Override
+        public NetworkScore[] newArray(int size) {
+            return new NetworkScore[size];
+        }
+    };
+
+    private NetworkScore(@NonNull Parcel in) {
+        mExtensions = in.readBundle();
+    }
+
+    // TODO: Modify this method once new fields are added into this class.
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (!(obj instanceof NetworkScore)) {
+            return false;
+        }
+        final NetworkScore other = (NetworkScore) obj;
+        return bundlesEqual(mExtensions, other.mExtensions);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 29;
+        for (String key : mExtensions.keySet()) {
+            final Object value = mExtensions.get(key);
+            // The key may be null, so call Objects.hash() is safer.
+            result += 31 * value.hashCode() + 37 * Objects.hash(key);
+        }
+        return result;
+    }
+
+    // mExtensions won't be null since the constructor will create it.
+    private boolean bundlesEqual(@NonNull Bundle bundle1, @NonNull Bundle bundle2) {
+        if (bundle1 == bundle2) {
+            return true;
+        }
+
+        // This is unlikely but it's fine to add this clause here.
+        if (null == bundle1 || null == bundle2) {
+            return false;
+        }
+
+        if (bundle1.size() != bundle2.size()) {
+            return false;
+        }
+
+        for (String key : bundle1.keySet()) {
+            final Object value1 = bundle1.get(key);
+            final Object value2 = bundle2.get(key);
+            if (!Objects.equals(value1, value2)) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 1643a21..c91d42b 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -35,10 +35,10 @@
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.DataUsageFeedback;
+import android.telecom.CallerInfo;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
-import android.telephony.CallerInfo;
 import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
 import android.util.Log;
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 73e0e4b..fa2dbc9 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -636,6 +636,16 @@
 
         /** Returns whether the window belongs to the task root. */
         boolean isTaskRoot();
+
+        /**
+         * Update the status bar color to a forced one.
+         */
+        void updateStatusBarColor(int color);
+
+        /**
+         * Update the navigation bar color to a forced one.
+         */
+        void updateNavigationBarColor(int color);
     }
 
     /**
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index daa57e0..21bb664 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -3829,6 +3829,10 @@
         if (mDecor != null) {
             mDecor.updateColorViews(null, false /* animate */);
         }
+        final WindowControllerCallback callback = getWindowControllerCallback();
+        if (callback != null) {
+            getWindowControllerCallback().updateStatusBarColor(color);
+        }
     }
 
     @Override
@@ -3843,6 +3847,10 @@
         if (mDecor != null) {
             mDecor.updateColorViews(null, false /* animate */);
         }
+        final WindowControllerCallback callback = getWindowControllerCallback();
+        if (callback != null) {
+            getWindowControllerCallback().updateNavigationBarColor(color);
+        }
     }
 
     @Override
diff --git a/core/res/res/drawable/ic_wifi_settings.xml b/core/res/res/drawable/ic_wifi_settings.xml
deleted file mode 100644
index c678ad4..0000000
--- a/core/res/res/drawable/ic_wifi_settings.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2017 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12.584,15.93c0.026-0.194,0.044-0.397,0.044-0.608c0-0.211-0.018-0.405-0.044-0.608l1.304-1.022
-c0.115-0.088,0.15-0.256,0.071-0.397l-1.234-2.133c-0.071-0.132-0.238-0.185-0.379-0.132l-1.533,0.617
-c-0.317-0.247-0.67-0.449-1.04-0.608L9.535,9.4c-0.018-0.132-0.141-0.247-0.3-0.247H6.768c-0.15,0-0.282,0.115-0.3,0.256
-L6.23,11.048c-0.379,0.159-0.723,0.361-1.04,0.608l-1.533-0.617c-0.141-0.053-0.3,0-0.379,0.132l-1.234,2.133
-c-0.079,0.132-0.044,0.3,0.07,0.397l1.304,1.022c-0.026,0.194-0.044,0.405-0.044,0.608s0.018,0.405,0.044,0.608l-1.304,1.022
-c-0.115,0.088-0.15,0.256-0.07,0.397l1.234,2.133c0.07,0.132,0.238,0.185,0.379,0.132l1.533-0.617
-c0.317,0.247,0.67,0.449,1.04,0.608l0.238,1.639c0.018,0.15,0.15,0.256,0.3,0.256h2.467c0.159,0,0.282-0.115,0.3-0.256
-l0.238-1.639c0.379-0.15,0.723-0.361,1.04-0.608l1.533,0.617c0.141,0.053,0.3,0,0.379-0.132l1.234-2.133
-c0.071-0.132,0.044-0.3-0.07-0.397L12.584,15.93z
-M8.002,17.481c-1.19,0-2.159-0.969-2.159-2.159s0.969-2.159,2.159-2.159
-s2.159,0.969,2.159,2.159C10.161,16.512,9.191,17.481,8.002,17.481z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.003,12.026l5.995-7.474c-0.229-0.172-2.537-2.06-6-2.06s-5.771,1.889-6,2.06l5.995,7.469l0.005,0.01L16.003,12.026z" />
-</vector>
\ No newline at end of file
diff --git a/core/res/res/layout/wifi_p2p_dialog.xml b/core/res/res/layout/wifi_p2p_dialog.xml
deleted file mode 100644
index 86dcbfa..0000000
--- a/core/res/res/layout/wifi_p2p_dialog.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content">
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical">
-
-        <LinearLayout android:id="@+id/info"
-            style="@style/wifi_section" />
-
-        <LinearLayout android:id="@+id/enter_pin_section"
-            style="@style/wifi_section"
-            android:visibility="gone">
-
-            <LinearLayout
-                style="@style/wifi_item">
-                <TextView
-                    android:text="@string/wifi_p2p_enter_pin_message"
-                    style="@style/wifi_item_label" />
-
-                <EditText android:id="@+id/wifi_p2p_wps_pin"
-                        android:singleLine="true"
-                        android:maxLines="8"
-                        android:inputType="number"
-                        style="@style/wifi_item_content" />
-            </LinearLayout>
-        </LinearLayout>
-    </LinearLayout>
-
-</ScrollView>
diff --git a/core/res/res/layout/wifi_p2p_dialog_row.xml b/core/res/res/layout/wifi_p2p_dialog_row.xml
deleted file mode 100644
index 2c88b10..0000000
--- a/core/res/res/layout/wifi_p2p_dialog_row.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/wifi_item">
-    <TextView
-            style="@style/wifi_item_label"
-            android:id="@+id/name" />
-
-    <TextView
-            android:id="@+id/value"
-            style="@style/wifi_item_content"
-            android:textStyle="bold"
-            android:textAlignment="viewStart" />
-</LinearLayout>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9ca98c5..b5e14d6 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -570,209 +570,6 @@
     <string-array translatable="false" name="config_cdma_dun_supported_types">
     </string-array>
 
-    <!-- Boolean indicating whether the wifi chipset has dual frequency band support -->
-    <bool translatable="false" name="config_wifi_dual_band_support">false</bool>
-
-    <!-- Maximum number of concurrent WiFi interfaces in AP mode -->
-    <integer translatable="false" name="config_wifi_max_ap_interfaces">1</integer>
-
-    <!-- Boolean indicating whether the wifi chipset requires the softap band be -->
-    <!-- converted from 5GHz to ANY due to hardware restrictions -->
-    <bool translatable="false" name="config_wifi_convert_apband_5ghz_to_any">false</bool>
-
-    <!-- Boolean indicating whether 802.11r Fast BSS Transition is enabled on this platform -->
-    <bool translatable="false" name="config_wifi_fast_bss_transition_enabled">false</bool>
-
-    <!-- Device type information conforming to Annex B format in WiFi Direct specification.
-         The default represents a dual-mode smartphone -->
-    <string translatable="false" name="config_wifi_p2p_device_type">10-0050F204-5</string>
-
-    <!-- Boolean indicating whether the wifi chipset supports background scanning mechanism.
-         This mechanism allows the host to remain in suspend state and the dongle to actively
-         scan and wake the host when a configured SSID is detected by the dongle. This chipset
-         capability can provide power savings when wifi needs to be always kept on. -->
-    <bool translatable="false" name="config_wifi_background_scan_support">false</bool>
-
-    <!-- Boolean indicating we re-try re-associating once upon disconnection and RSSI is high failure  -->
-    <bool translatable="true" name="config_wifi_enable_disconnection_debounce">true</bool>
-
-    <!-- Boolean indicating whether or not to revert to default country code when cellular
-         radio is unable to find any MCC information to infer wifi country code from -->
-    <bool translatable="false" name="config_wifi_revert_country_code_on_cellular_loss">false</bool>
-
-    <!-- Integer size limit, in KB, for a single WifiLogger ringbuffer, in default logging mode -->
-    <integer translatable="false" name="config_wifi_logger_ring_buffer_default_size_limit_kb">32</integer>
-
-    <!-- Integer size limit, in KB, for a single WifiLogger ringbuffer, in verbose logging mode -->
-    <integer translatable="false" name="config_wifi_logger_ring_buffer_verbose_size_limit_kb">1024</integer>
-
-    <!-- Array indicating wifi fatal firmware alert error code list from driver -->
-    <integer-array translatable="false" name="config_wifi_fatal_firmware_alert_error_code_list">
-        <!-- Example:
-        <item>0</item>
-        <item>1</item>
-        <item>2</item>
-        -->
-    </integer-array>
-
-    <!-- Boolean indicating whether or not wifi should turn off when emergency call is made -->
-    <bool translatable="false" name="config_wifi_turn_off_during_emergency_call">false</bool>
-
-    <!-- Integer specifying the basic autojoin parameters -->
-    <integer translatable="false" name="config_wifi_framework_5GHz_preference_boost_threshold">-65</integer>
-    <integer translatable="false" name="config_wifi_framework_5GHz_preference_boost_factor">40</integer>
-    <integer translatable="false" name="config_wifi_framework_5GHz_preference_penalty_threshold">-75</integer>
-    <integer translatable="false" name="config_wifi_framework_RSSI_SCORE_OFFSET">85</integer>
-    <integer translatable="false" name="config_wifi_framework_RSSI_SCORE_SLOPE">4</integer>
-    <integer translatable="false" name="config_wifi_framework_SAME_BSSID_AWARD">24</integer>
-    <integer translatable="false" name="config_wifi_framework_LAST_SELECTION_AWARD">480</integer>
-    <integer translatable="false" name="config_wifi_framework_PASSPOINT_SECURITY_AWARD">40</integer>
-    <integer translatable="false" name="config_wifi_framework_SECURITY_AWARD">80</integer>
-    <!-- Integer specifying the base interval in seconds for the exponential backoff scan for autojoin -->
-    <integer translatable="false" name="config_wifi_framework_exponential_backoff_scan_base_interval">20</integer>
-    <!-- Integers specifying the max packet Tx/Rx rates for full scan -->
-    <integer translatable="false" name="config_wifi_framework_max_tx_rate_for_full_scan">8</integer>
-    <integer translatable="false" name="config_wifi_framework_max_rx_rate_for_full_scan">16</integer>
-    <!-- Integers specifying the min packet Tx/Rx rates in packets per second for staying on the same network -->
-    <integer translatable="false" name="config_wifi_framework_min_tx_rate_for_staying_on_network">16</integer>
-    <integer translatable="false" name="config_wifi_framework_min_rx_rate_for_staying_on_network">16</integer>
-    <!-- Integer parameters of the wifi to cellular handover feature
-         wifi should not stick to bad networks -->
-    <!-- Integer threshold for low network score, should be somewhat less than the entry threshhold -->
-    <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz">-80</integer>
-    <!-- Integer threshold, do not connect to APs with RSSI lower than the entry threshold -->
-    <integer translatable="false" name="config_wifi_framework_wifi_score_entry_rssi_threshold_5GHz">-77</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_low_rssi_threshold_5GHz">-70</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_good_rssi_threshold_5GHz">-57</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz">-83</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_entry_rssi_threshold_24GHz">-80</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_low_rssi_threshold_24GHz">-73</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_good_rssi_threshold_24GHz">-60</integer>
-
-    <!-- Integer delay in milliseconds before shutting down soft AP when there
-         are no connected devices. Framework will enforce a minimum limit on
-         this value and this setting will be overridden if the provided value is
-         smaller than the limit. -->
-    <integer translatable="false" name="config_wifi_framework_soft_ap_timeout_delay">600000</integer>
-
-    <string  translatable="false" name="config_wifi_random_mac_oui">DA-A1-19</string>
-    <string  translatable="false" name="config_wifi_framework_sap_2G_channel_list">1,6,11</string>
-
-    <bool translatable="false" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment">true</bool>
-
-    <!-- Integer packet threshold used to allow scan while associated -->
-    <integer translatable="false" name="config_wifi_framework_associated_full_scan_tx_packet_threshold">5</integer>
-    <integer translatable="false" name="config_wifi_framework_associated_full_scan_rx_packet_threshold">10</integer>
-    <integer translatable="false" name="config_wifi_framework_associated_partial_scan_tx_packet_threshold">40</integer>
-    <integer translatable="false" name="config_wifi_framework_associated_partial_scan_rx_packet_threshold">80</integer>
-    <integer translatable="false" name="config_wifi_framework_network_switch_tx_packet_threshold">2</integer>
-    <integer translatable="false" name="config_wifi_framework_network_switch_rx_packet_threshold">20</integer>
-
-    <!-- Integer indicating wpa_supplicant scan interval in milliseconds -->
-    <integer translatable="false" name="config_wifi_supplicant_scan_interval">15000</integer>
-
-    <!-- Integer indicating amount of time failed networks areblacklisted for the purpose
-         of network switching in milliseconds -->
-    <integer translatable="false" name="config_wifi_network_switching_blacklist_time">172800000</integer>
-
-    <!-- Integer indicating wpa_supplicant scan interval when p2p is connected in milliseconds -->
-    <integer translatable="false" name="config_wifi_scan_interval_p2p_connected">60000</integer>
-
-    <!-- Integer indicating disconnect mode short scan interval in milliseconds -->
-    <integer translatable="false" name="config_wifi_disconnected_short_scan_interval">15000</integer>
-
-    <!-- Integer indicating associated partial scan short interval in milliseconds -->
-    <integer translatable="false" name="config_wifi_associated_short_scan_interval">20000</integer>
-
-    <!-- Integer indicating associated full scan backoff, representing a fraction: xx/8 -->
-    <integer translatable="false" name="config_wifi_framework_associated_full_scan_backoff">12</integer>
-
-    <!-- Integer indicating associated full scan max interval in milliseconds -->
-    <integer translatable="false" name="config_wifi_framework_associated_full_scan_max_interval">300000</integer>
-
-    <!-- Integer indicating associated full scan max total dwell time in milliseconds -->
-    <integer translatable="false" name="config_wifi_framework_associated_full_scan_max_total_dwell_time">500</integer>
-
-    <!-- Integer indicating associated full scan max num active channels -->
-    <integer translatable="false" name="config_wifi_framework_associated_partial_scan_max_num_active_channels">6</integer>
-
-    <!-- Integer indicating RSSI boost given to current network -->
-    <integer translatable="false" name="config_wifi_framework_current_network_boost">16</integer>
-
-    <!-- Integer delay in milliseconds before set wlan interface up during watchdog recovery -->
-    <integer translatable="false" name="config_wifi_framework_recovery_timeout_delay">2000</integer>
-
-    <!-- Integer indicating how to handle beacons with uninitialized RSSI value of 0 -->
-    <integer translatable="false" name="config_wifi_framework_scan_result_rssi_level_patchup_value">-85</integer>
-
-    <!-- Boolean indicating associated network selection is allowed -->
-    <bool translatable="false" name="config_wifi_framework_enable_associated_network_selection">true</bool>
-
-    <!-- Boolean indicating whether single radio chain scan results are to be used for network selection -->
-    <bool translatable="false" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection">true</bool>
-
-    <!-- Boolean indicating that wifi only link configuratios that have exact same credentials (i.e PSK) -->
-    <bool translatable="false" name="config_wifi_only_link_same_credential_configurations">true</bool>
-
-    <!-- Boolean indicating whether framework needs to set the tx power limit for meeting SAR requirements -->
-    <bool translatable="false" name="config_wifi_framework_enable_sar_tx_power_limit">false</bool>
-
-    <!-- Boolean indicating whether framework should use detection of softAP mode to set the tx
-         power limit for meeting SAR requirements -->
-    <bool translatable="false" name="config_wifi_framework_enable_soft_ap_sar_tx_power_limit">false</bool>
-
-    <!-- Boolean indicating whether framework needs to use body proximity to set the tx power limit
-         for meeting SAR requirements -->
-    <bool translatable="false" name="config_wifi_framework_enable_body_proximity_sar_tx_power_limit">false</bool>
-
-    <!-- String for the sensor type for body/head proximity for SAR -->
-    <string translatable="false" name="config_wifi_sar_sensor_type"></string>
-
-    <!-- Integer indicating event id by sar sensor for free space -->
-    <integer translatable="false" name="config_wifi_framework_sar_free_space_event_id">1</integer>
-
-    <!-- Integer indicating event id by sar sensor for near hand -->
-    <integer translatable="false" name="config_wifi_framework_sar_near_hand_event_id">2</integer>
-
-    <!-- Integer indicating event id by sar sensor for near head -->
-    <integer translatable="false" name="config_wifi_framework_sar_near_head_event_id">3</integer>
-
-    <!-- Integer indicating event id by sar sensor for near body -->
-    <integer translatable="false" name="config_wifi_framework_sar_near_body_event_id">4</integer>
-
-    <!-- Wifi driver supports batched scan -->
-    <bool translatable="false" name="config_wifi_batched_scan_supported">false</bool>
-
-    <!-- Wifi driver supports Automatic channel selection (ACS) for softap -->
-    <bool translatable="false" name="config_wifi_softap_acs_supported">false</bool>
-
-    <!-- Channel list restriction to Automatic channel selection (ACS) for softap. If the device
-         doesn't want to restrict channels this should be empty. Value is a comma separated channel
-         string and/or channel range string like '1-6,11' -->
-    <string translatable="false" name="config_wifi_softap_acs_supported_channel_list"></string>
-
-    <!-- Wifi driver supports IEEE80211AC for softap -->
-    <bool translatable="false" name="config_wifi_softap_ieee80211ac_supported">false</bool>
-
-    <!-- Indicates that local-only hotspot should be brought up at 5GHz.  This option is
-         for automotive builds only (the one that have PackageManager#FEATURE_AUTOMOTIVE) -->
-    <bool translatable="false" name="config_wifi_local_only_hotspot_5ghz">false</bool>
-
-    <!-- Indicates that connected MAC randomization is supported on this device -->
-    <bool translatable="false" name="config_wifi_connected_mac_randomization_supported">false</bool>
-
-    <!-- Indicates that p2p MAC randomization is supported on this device -->
-    <bool translatable="false" name="config_wifi_p2p_mac_randomization_supported">false</bool>
-
-    <!-- Indicates that AP mode MAC randomization is supported on this device -->
-    <bool translatable="false" name="config_wifi_ap_mac_randomization_supported">true</bool>
-
-    <!-- flag for activating paranoid MAC randomization on a limited set of SSIDs -->
-    <bool translatable="false" name="config_wifi_aggressive_randomization_ssid_whitelist_enabled">false</bool>
-
-    <!-- Indicates that wifi link probing is supported on this device -->
-    <bool translatable="false" name="config_wifi_link_probing_supported">false</bool>
-
     <!-- Flag indicating whether we should enable the automatic brightness.
          Software implementation will be used if config_hardware_auto_brightness_available is not set -->
     <bool name="config_automatic_brightness_available">false</bool>
@@ -2613,10 +2410,6 @@
          rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max -->
     <string name="config_ethernet_tcp_buffers" translatable="false">524288,1048576,3145728,524288,1048576,2097152</string>
 
-    <!-- Configure wifi tcp buffersizes in the form:
-         rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max -->
-    <string name="config_wifi_tcp_buffers" translatable="false">524288,1048576,2097152,262144,524288,1048576</string>
-
     <!-- Whether WiFi display is supported by this device.
          There are many prerequisites for this feature to work correctly.
          Here are a few of them:
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 9724c41..9b89eab 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3005,6 +3005,8 @@
     </public-group>
 
     <public-group type="drawable" first-id="0x010800b5">
+      <!-- @hide @SystemApi -->
+      <public name="stat_notify_wifi_in_range" />
     </public-group>
 
     <public-group type="style" first-id="0x010302e5">
@@ -3014,6 +3016,12 @@
     </public-group>
 
     <public-group type="string" first-id="0x01040025">
+      <!-- @hide @SystemApi -->
+      <public name="notification_channel_network_status" />
+      <!-- @hide @SystemApi -->
+      <public name="notification_channel_network_alerts" />
+      <!-- @hide @SystemApi -->
+      <public name="notification_channel_network_available" />
     </public-group>
 
     <public-group type="bool" first-id="0x01110005">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b39fa13..5f2bbac 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3379,52 +3379,6 @@
     <!-- If there is ever a ringtone set for some setting, but that ringtone can no longer be resolved, t his is shown instead.  For example, if the ringtone was on a SD card and it had been removed, this woudl be shown for ringtones on that SD card. -->
     <string name="ringtone_unknown">Unknown</string>
 
-    <!-- A notification is shown when there are open wireless networks nearby.  This is the notification's title. -->
-    <plurals name="wifi_available">
-        <item quantity="one">Wi-Fi network available</item>
-        <item quantity="other">Wi-Fi networks available</item>
-    </plurals>
-    <!-- A notification is shown when there are open wireless networks nearby.  This is the notification's message. -->
-    <plurals name="wifi_available_detailed">
-        <item quantity="one">Open Wi-Fi network available</item>
-        <item quantity="other">Open Wi-Fi networks available</item>
-    </plurals>
-
-    <!-- Notification title for a nearby open wireless network.-->
-    <string name="wifi_available_title">Connect to open Wi\u2011Fi network</string>
-    <!-- Notification title when the system is connecting to the specified network. The network name is specified in the notification content. -->
-    <string name="wifi_available_title_connecting">Connecting to Wi\u2011Fi network</string>
-    <!-- Notification title when the system has connected to the network. The network name is specified in the notification content. -->
-    <string name="wifi_available_title_connected">Connected to Wi\u2011Fi network</string>
-    <!-- Notification title when the system failed to connect to the specified network. -->
-    <string name="wifi_available_title_failed_to_connect">Could not connect to Wi\u2011Fi network</string>
-    <!-- Notification content when the system failed to connect to the specified network. This informs the user that tapping on this notification will open the wifi picker. -->
-    <string name="wifi_available_content_failed_to_connect">Tap to see all networks</string>
-    <!-- Notification action name for connecting to the network specified in the notification body. -->
-    <string name="wifi_available_action_connect">Connect</string>
-    <!-- Notification action name for opening the wifi picker, showing the user all the nearby networks. -->
-    <string name="wifi_available_action_all_networks">All networks</string>
-
-    <!-- Notification title for a connection to a app suggested wireless network.-->
-    <string name="wifi_suggestion_title">Allow suggested Wi\u2011Fi networks?</string>
-    <!-- Notification content for a connection to a app suggested wireless network.-->
-    <string name="wifi_suggestion_content"><xliff:g id="name" example="App123">%s</xliff:g> suggested networks. Device may connect automatically. </string>
-    <!-- Notification action for allowing app specified in the notification body.-->
-    <string name="wifi_suggestion_action_allow_app">Allow</string>
-    <!-- Notification action for disallowing app specified in the notification body.-->
-    <string name="wifi_suggestion_action_disallow_app">No thanks</string>
-
-    <!--Notification title for Wi-Fi Wake onboarding. This is displayed the first time a user disables Wi-Fi with the feature enabled. -->
-    <string name="wifi_wakeup_onboarding_title">Wi\u2011Fi will turn on automatically</string>
-    <!--Notification subtext for Wi-Fi Wake onboarding.-->
-    <string name="wifi_wakeup_onboarding_subtext">When you\'re near a high quality saved network</string>
-    <!--Notification action to disable Wi-Fi Wake during onboarding.-->
-    <string name="wifi_wakeup_onboarding_action_disable">Don\'t turn back on</string>
-    <!--Notification title for when Wi-Fi Wake enables Wi-Fi.-->
-    <string name="wifi_wakeup_enabled_title">Wi\u2011Fi turned on automatically</string>
-    <!--Notification content for when Wi-Fi Wake enables Wi-Fi. %1$s is the SSID of the nearby saved network that triggered the wakeup. -->
-    <string name="wifi_wakeup_enabled_content">You\u0027re near a saved network: <xliff:g id="network_ssid">%1$s</xliff:g></string>
-
     <!-- A notification is shown when a wifi captive portal network is detected.  This is the notification's title. -->
     <string name="wifi_available_sign_in">Sign in to Wi-Fi network</string>
 
@@ -3457,21 +3411,6 @@
     <!-- A notification is shown when the user connects to a network that doesn't have access to some services (e.g. Push notifications may not work). This is the notification's message. [CHAR LIMIT=50] -->
     <string name="network_partial_connectivity_detailed">Tap to connect anyway</string>
 
-    <!-- A notification is shown when the user's softap config has been changed due to underlying
-         hardware restrictions. This is the notifications's title.
-         [CHAR_LIMIT=NONE] -->
-    <string name="wifi_softap_config_change">Changes to your hotspot settings</string>
-
-    <!-- A notification is shown when the user's softap config has been changed due to underlying
-         hardware restrictions. This is the notification's summary message.
-         [CHAR_LIMIT=NONE] -->
-    <string name="wifi_softap_config_change_summary">Your hotspot band has changed.</string>
-
-    <!-- A notification is shown when the user's softap config has been changed due to underlying
-         hardware restrictions. This is the notification's full message.
-         [CHAR_LIMIT=NONE] -->
-    <string name="wifi_softap_config_change_detailed">This device doesn\u2019t support your preference for 5GHz only. Instead, this device will use the 5GHz band when available.</string>
-
     <!-- A notification might be shown if the device switches to another network type (e.g., mobile data) because it detects that the network it was using (e.g., Wi-Fi) has lost Internet connectivity. This is the notification's title. %1$s is the network type that the device switched to, e.g., cellular data. It is one of the strings in the network_switch_type_name array. -->
     <string name="network_switch_metered">Switched to <xliff:g id="network_type">%1$s</xliff:g></string>
 
@@ -3493,43 +3432,8 @@
     <!-- Network type name displayed if one of the types is not found in network_switch_type_name. -->
     <string name="network_switch_type_name_unknown">an unknown network type</string>
 
-     <!-- A notification is shown when a user's selected SSID is later disabled due to connectivity problems.  This is the notification's title / ticker. -->
-     <string name="wifi_watchdog_network_disabled">Couldn\'t connect to Wi-Fi</string>
-     <!-- A notification is shown when a user's selected SSID is later disabled due to connectivity problems.  The complete alert msg is: <hotspot name> + this string, i.e. "Linksys has a poor internet connection" -->
-    <string name="wifi_watchdog_network_disabled_detailed">\u0020has a poor internet connection.</string>
-
-    <!-- Do not translate. Default access point SSID used for tethering -->
-    <string name="wifi_tether_configure_ssid_default" translatable="false">AndroidAP</string>
-    <!-- Do not translate. Default access point SSID used for local only hotspot -->
-    <string name="wifi_localhotspot_configure_ssid_default" translatable="false">AndroidShare</string>
-
-    <!-- A notification is shown the first time a connection is attempted on an app owned AP -->
-    <!-- title for this message -->
-    <string name="wifi_connect_alert_title">Allow connection?</string>
-    <!-- message explaining who is connecting to what -->
-    <string name="wifi_connect_alert_message">Application %1$s would like to connect to Wifi Network %2$s</string>
-    <!-- default application in case name can not be found -->
-    <string name="wifi_connect_default_application">An application</string>
-
-    <string name="wifi_p2p_dialog_title">Wi-Fi Direct</string>
-    <string name="wifi_p2p_turnon_message">Start Wi-Fi Direct. This will turn off Wi-Fi client/hotspot.</string>
-    <string name="wifi_p2p_failed_message">Couldn\'t start Wi-Fi Direct.</string>
-    <string name="wifi_p2p_enabled_notification_title">Wi-Fi Direct is on</string>
-    <string name="wifi_p2p_enabled_notification_message">Tap for settings</string>
-
     <string name="accept">Accept</string>
     <string name="decline">Decline</string>
-    <string name="wifi_p2p_invitation_sent_title">Invitation sent</string>
-    <string name="wifi_p2p_invitation_to_connect_title">Invitation to connect</string>
-
-    <string name="wifi_p2p_from_message">From: </string>
-    <string name="wifi_p2p_to_message">To: </string>
-    <string name="wifi_p2p_enter_pin_message">Type the required PIN: </string>
-    <string name="wifi_p2p_show_pin_message">PIN: </string>
-
-    <string name="wifi_p2p_frequency_conflict_message" product="tablet">The tablet will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
-    <string name="wifi_p2p_frequency_conflict_message" product="tv">Your Android TV device will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
-    <string name="wifi_p2p_frequency_conflict_message" product="default">The phone will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
 
     <!-- Name of the dialog that lets the user choose an accented character to insert -->
     <string name="select_character">Insert character</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 18f7e48..bcce1f0 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1443,39 +1443,6 @@
         <item name="drawableTintMode">src_atop</item>
     </style>
 
-    <!-- Wifi dialog styles -->
-    <!-- @hide -->
-    <style name="wifi_item">
-        <item name="layout_width">200dip</item>
-        <item name="layout_height">wrap_content</item>
-        <item name="layout_marginTop">8dip</item>
-        <item name="layout_marginStart">16dip</item>
-        <item name="layout_marginEnd">16dip</item>
-        <item name="orientation">vertical</item>
-        <item name="gravity">start</item>
-    </style>
-
-    <!-- @hide -->
-    <style name="wifi_item_label">
-        <item name="layout_width">wrap_content</item>
-        <item name="layout_height">wrap_content</item>
-        <item name="textSize">14sp</item>
-    </style>
-
-    <!-- @hide -->
-    <style name="wifi_item_content">
-        <item name="layout_width">match_parent</item>
-        <item name="layout_height">wrap_content</item>
-        <item name="textSize">18sp</item>
-    </style>
-
-    <!-- @hide -->
-    <style name="wifi_section">
-        <item name="layout_width">match_parent</item>
-        <item name="layout_height">wrap_content</item>
-        <item name="orientation">vertical</item>
-    </style>
-
     <style name="Widget.FastScroll">
         <item name="thumbDrawable">?attr/fastScrollThumbDrawable</item>
         <item name="trackDrawable">?attr/fastScrollTrackDrawable</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1313912..8e10b00 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -82,7 +82,6 @@
   <java-symbol type="id" name="divider" />
   <java-symbol type="id" name="edit_query" />
   <java-symbol type="id" name="edittext_container" />
-  <java-symbol type="id" name="enter_pin_section" />
   <java-symbol type="id" name="expand_activities_button" />
   <java-symbol type="id" name="expires_on" />
   <java-symbol type="id" name="find_next" />
@@ -100,7 +99,6 @@
   <java-symbol type="id" name="image" />
   <java-symbol type="id" name="increment" />
   <java-symbol type="id" name="internalEmpty" />
-  <java-symbol type="id" name="info" />
   <java-symbol type="id" name="inputExtractAccessories" />
   <java-symbol type="id" name="inputExtractAction" />
   <java-symbol type="id" name="issued_on" />
@@ -117,7 +115,6 @@
   <java-symbol type="id" name="mode_normal" />
   <java-symbol type="id" name="month" />
   <java-symbol type="id" name="month_name" />
-  <java-symbol type="id" name="name" />
   <java-symbol type="id" name="next" />
   <java-symbol type="id" name="next_button" />
   <java-symbol type="id" name="new_app_action" />
@@ -193,7 +190,6 @@
   <java-symbol type="id" name="up" />
   <java-symbol type="id" name="value" />
   <java-symbol type="id" name="websearch" />
-  <java-symbol type="id" name="wifi_p2p_wps_pin" />
   <java-symbol type="id" name="year" />
   <java-symbol type="id" name="zoomControls" />
   <java-symbol type="id" name="zoomIn" />
@@ -356,10 +352,6 @@
   <java-symbol type="bool" name="config_requireRadioPowerOffOnSimRefreshReset" />
   <java-symbol type="bool" name="config_speed_up_audio_on_mt_calls" />
   <java-symbol type="bool" name="config_useFixedVolume" />
-  <java-symbol type="bool" name="config_wifi_batched_scan_supported" />
-  <java-symbol type="bool" name="config_wifi_softap_acs_supported" />
-  <java-symbol type="string" name="config_wifi_softap_acs_supported_channel_list" />
-  <java-symbol type="bool" name="config_wifi_softap_ieee80211ac_supported" />
   <java-symbol type="bool" name="config_enableMultiUserUI"/>
   <java-symbol type="bool" name="config_enableNewAutoSelectNetworkUI"/>
   <java-symbol type="bool" name="config_disableUsbPermissionDialogs"/>
@@ -376,23 +368,6 @@
   <java-symbol type="integer" name="config_activeTaskDurationHours" />
   <java-symbol type="bool" name="config_windowShowCircularMask" />
   <java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" />
-  <java-symbol type="bool" name="config_wifi_framework_enable_associated_network_selection" />
-  <java-symbol type="bool" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection" />
-  <java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" />
-  <java-symbol type="bool" name="config_wifi_framework_enable_sar_tx_power_limit" />
-  <java-symbol type="bool" name="config_wifi_framework_enable_soft_ap_sar_tx_power_limit" />
-  <java-symbol type="bool" name="config_wifi_framework_enable_body_proximity_sar_tx_power_limit" />
-  <java-symbol type="string" name="config_wifi_sar_sensor_type" />
-  <java-symbol type="integer" name="config_wifi_framework_sar_free_space_event_id" />
-  <java-symbol type="integer" name="config_wifi_framework_sar_near_hand_event_id" />
-  <java-symbol type="integer" name="config_wifi_framework_sar_near_head_event_id" />
-  <java-symbol type="integer" name="config_wifi_framework_sar_near_body_event_id" />
-  <java-symbol type="bool" name="config_wifi_enable_disconnection_debounce" />
-  <java-symbol type="bool" name="config_wifi_revert_country_code_on_cellular_loss" />
-  <java-symbol type="integer" name="config_wifi_logger_ring_buffer_default_size_limit_kb" />
-  <java-symbol type="integer" name="config_wifi_logger_ring_buffer_verbose_size_limit_kb" />
-  <java-symbol type="array" name="config_wifi_fatal_firmware_alert_error_code_list" />
-  <java-symbol type="bool" name="config_wifi_turn_off_during_emergency_call" />
   <java-symbol type="bool" name="config_supportMicNearUltrasound" />
   <java-symbol type="bool" name="config_supportSpeakerNearUltrasound" />
   <java-symbol type="bool" name="config_supportAudioSourceUnprocessed" />
@@ -416,51 +391,6 @@
   <java-symbol type="dimen" name="config_pictureInPictureMinAspectRatio" />
   <java-symbol type="dimen" name="config_pictureInPictureMaxAspectRatio" />
   <java-symbol type="dimen" name="config_closeToSquareDisplayMaxAspectRatio" />
-  <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_factor" />
-  <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_penalty_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_penalty_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_RSSI_SCORE_OFFSET" />
-  <java-symbol type="integer" name="config_wifi_framework_RSSI_SCORE_SLOPE" />
-  <java-symbol type="integer" name="config_wifi_framework_SAME_BSSID_AWARD" />
-  <java-symbol type="integer" name="config_wifi_framework_LAST_SELECTION_AWARD" />
-  <java-symbol type="integer" name="config_wifi_framework_PASSPOINT_SECURITY_AWARD" />
-  <java-symbol type="integer" name="config_wifi_framework_SECURITY_AWARD" />
-  <java-symbol type="integer" name="config_wifi_disconnected_short_scan_interval" />
-  <java-symbol type="integer" name="config_wifi_associated_short_scan_interval" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_backoff" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_max_interval" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_max_total_dwell_time" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_partial_scan_max_num_active_channels" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_entry_rssi_threshold_24GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_low_rssi_threshold_24GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_good_rssi_threshold_24GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_entry_rssi_threshold_5GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_low_rssi_threshold_5GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_good_rssi_threshold_5GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_scan_result_rssi_level_patchup_value" />
-  <java-symbol type="integer" name="config_wifi_framework_current_network_boost" />
-  <java-symbol type="string"  name="config_wifi_random_mac_oui" />
-  <java-symbol type="integer"  name="config_wifi_network_switching_blacklist_time" />
-  <java-symbol type="string"  name="config_wifi_framework_sap_2G_channel_list" />
-  <java-symbol type="integer" name="config_wifi_framework_max_tx_rate_for_full_scan" />
-  <java-symbol type="integer" name="config_wifi_framework_max_rx_rate_for_full_scan" />
-  <java-symbol type="integer" name="config_wifi_framework_min_tx_rate_for_staying_on_network" />
-  <java-symbol type="integer" name="config_wifi_framework_min_rx_rate_for_staying_on_network" />
-
-  <java-symbol type="integer" name="config_wifi_framework_soft_ap_timeout_delay" />
-
-  <java-symbol type="bool" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_tx_packet_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_rx_packet_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_partial_scan_tx_packet_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_partial_scan_rx_packet_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_network_switch_tx_packet_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_network_switch_rx_packet_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_current_network_boost" />
-  <java-symbol type="integer" name="config_wifi_framework_recovery_timeout_delay" />
   <java-symbol type="integer" name="config_bluetooth_max_advertisers" />
   <java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
   <java-symbol type="integer" name="config_bluetooth_max_connected_audio_devices" />
@@ -499,8 +429,6 @@
   <java-symbol type="integer" name="config_toastDefaultGravity" />
   <java-symbol type="integer" name="config_triplePressOnPowerBehavior" />
   <java-symbol type="integer" name="config_shortPressOnSleepBehavior" />
-  <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
-  <java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" />
   <java-symbol type="integer" name="config_windowOutsetBottom" />
   <java-symbol type="integer" name="db_connection_pool_size" />
   <java-symbol type="integer" name="db_journal_size_limit" />
@@ -757,7 +685,6 @@
   <java-symbol type="string" name="config_mms_user_agent_profile_url" />
   <java-symbol type="string" name="config_ntpServer" />
   <java-symbol type="string" name="config_useragentprofile_url" />
-  <java-symbol type="string" name="config_wifi_p2p_device_type" />
   <java-symbol type="string" name="config_appsNotReportingCrashes" />
   <java-symbol type="string" name="contentServiceSync" />
   <java-symbol type="string" name="contentServiceSyncNotificationTitle" />
@@ -1119,27 +1046,6 @@
   <java-symbol type="string" name="network_switch_type_name_unknown" />
   <java-symbol type="string" name="wifi_no_internet" />
   <java-symbol type="string" name="wifi_no_internet_detailed" />
-  <java-symbol type="string" name="wifi_softap_config_change" />
-  <java-symbol type="string" name="wifi_softap_config_change_summary" />
-  <java-symbol type="string" name="wifi_softap_config_change_detailed" />
-  <java-symbol type="string" name="wifi_connect_alert_title" />
-  <java-symbol type="string" name="wifi_connect_alert_message" />
-  <java-symbol type="string" name="wifi_connect_default_application" />
-  <java-symbol type="string" name="wifi_p2p_dialog_title" />
-  <java-symbol type="string" name="wifi_p2p_enabled_notification_message" />
-  <java-symbol type="string" name="wifi_p2p_enabled_notification_title" />
-  <java-symbol type="string" name="wifi_p2p_failed_message" />
-  <java-symbol type="string" name="wifi_p2p_from_message" />
-  <java-symbol type="string" name="wifi_p2p_invitation_sent_title" />
-  <java-symbol type="string" name="wifi_p2p_invitation_to_connect_title" />
-  <java-symbol type="string" name="wifi_p2p_show_pin_message" />
-  <java-symbol type="string" name="wifi_p2p_to_message" />
-  <java-symbol type="string" name="wifi_p2p_turnon_message" />
-  <java-symbol type="string" name="wifi_p2p_frequency_conflict_message" />
-  <java-symbol type="string" name="wifi_tether_configure_ssid_default" />
-  <java-symbol type="string" name="wifi_localhotspot_configure_ssid_default" />
-  <java-symbol type="string" name="wifi_watchdog_network_disabled" />
-  <java-symbol type="string" name="wifi_watchdog_network_disabled_detailed" />
   <java-symbol type="string" name="imei" />
   <java-symbol type="string" name="meid" />
   <java-symbol type="string" name="granularity_label_character" />
@@ -1289,7 +1195,6 @@
   <java-symbol type="string" name="lockscreen_transport_play_description" />
   <java-symbol type="string" name="lockscreen_transport_pause_description" />
   <java-symbol type="string" name="config_ethernet_tcp_buffers" />
-  <java-symbol type="string" name="config_wifi_tcp_buffers" />
   <java-symbol type="string" name="demo_starting_message" />
   <java-symbol type="string" name="demo_restarting_message" />
   <java-symbol type="string" name="conference_call" />
@@ -1417,8 +1322,6 @@
   <java-symbol type="drawable" name="picture_emergency" />
   <java-symbol type="drawable" name="platlogo" />
   <java-symbol type="drawable" name="stat_notify_sync_error" />
-  <java-symbol type="drawable" name="stat_notify_wifi_in_range" />
-  <java-symbol type="drawable" name="ic_wifi_settings" />
   <java-symbol type="drawable" name="ic_wifi_signal_0" />
   <java-symbol type="drawable" name="ic_wifi_signal_1" />
   <java-symbol type="drawable" name="ic_wifi_signal_2" />
@@ -1611,8 +1514,6 @@
   <java-symbol type="layout" name="web_text_view_dropdown" />
   <java-symbol type="layout" name="webview_find" />
   <java-symbol type="layout" name="webview_select_singlechoice" />
-  <java-symbol type="layout" name="wifi_p2p_dialog" />
-  <java-symbol type="layout" name="wifi_p2p_dialog_row" />
   <java-symbol type="layout" name="zoom_container" />
   <java-symbol type="layout" name="zoom_controls" />
   <java-symbol type="layout" name="zoom_magnify" />
@@ -1968,17 +1869,6 @@
   <java-symbol type="bool" name="config_allowTheaterModeWakeFromWindowLayout" />
   <java-symbol type="bool" name="config_goToSleepOnButtonPressTheaterMode" />
   <java-symbol type="bool" name="config_supportLongPressPowerWhenNonInteractive" />
-  <java-symbol type="bool" name="config_wifi_background_scan_support" />
-  <java-symbol type="bool" name="config_wifi_dual_band_support" />
-  <java-symbol type="integer" name="config_wifi_max_ap_interfaces" />
-  <java-symbol type="bool" name="config_wifi_convert_apband_5ghz_to_any" />
-  <java-symbol type="bool" name="config_wifi_local_only_hotspot_5ghz" />
-  <java-symbol type="bool" name="config_wifi_connected_mac_randomization_supported" />
-  <java-symbol type="bool" name="config_wifi_p2p_mac_randomization_supported" />
-  <java-symbol type="bool" name="config_wifi_ap_mac_randomization_supported" />
-  <java-symbol type="bool" name="config_wifi_aggressive_randomization_ssid_whitelist_enabled" />
-  <java-symbol type="bool" name="config_wifi_link_probing_supported" />
-  <java-symbol type="bool" name="config_wifi_fast_bss_transition_enabled" />
   <java-symbol type="bool" name="config_wimaxEnabled" />
   <java-symbol type="bool" name="show_ongoing_ime_switcher" />
   <java-symbol type="color" name="config_defaultNotificationColor" />
@@ -2078,24 +1968,6 @@
   <java-symbol type="layout" name="safe_mode" />
   <java-symbol type="layout" name="simple_list_item_2_single_choice" />
   <java-symbol type="layout" name="app_error_dialog" />
-  <java-symbol type="plurals" name="wifi_available" />
-  <java-symbol type="plurals" name="wifi_available_detailed" />
-  <java-symbol type="string" name="wifi_available_title" />
-  <java-symbol type="string" name="wifi_available_title_connecting" />
-  <java-symbol type="string" name="wifi_available_title_connected" />
-  <java-symbol type="string" name="wifi_available_title_failed_to_connect" />
-  <java-symbol type="string" name="wifi_available_content_failed_to_connect" />
-  <java-symbol type="string" name="wifi_available_action_connect" />
-  <java-symbol type="string" name="wifi_available_action_all_networks" />
-  <java-symbol type="string" name="wifi_suggestion_title" />
-  <java-symbol type="string" name="wifi_suggestion_content" />
-  <java-symbol type="string" name="wifi_suggestion_action_allow_app" />
-  <java-symbol type="string" name="wifi_suggestion_action_disallow_app" />
-  <java-symbol type="string" name="wifi_wakeup_onboarding_title" />
-  <java-symbol type="string" name="wifi_wakeup_onboarding_subtext" />
-  <java-symbol type="string" name="wifi_wakeup_onboarding_action_disable" />
-  <java-symbol type="string" name="wifi_wakeup_enabled_title" />
-  <java-symbol type="string" name="wifi_wakeup_enabled_content" />
   <java-symbol type="string" name="accessibility_binding_label" />
   <java-symbol type="string" name="adb_active_notification_message" />
   <java-symbol type="string" name="adb_active_notification_title" />
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 4ed8f42..7d68d02 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -33,6 +33,8 @@
     private static final boolean DEBUG = false;
 
     private static final int MSG_ON_FRONTEND_EVENT = 1;
+    private static final int MSG_ON_FILTER_EVENT = 2;
+    private static final int MSG_ON_FILTER_STATUS = 3;
 
     static {
         System.loadLibrary("media_tv_tuner");
@@ -86,6 +88,16 @@
         void onEvent(int frontendEventType);
     }
 
+    /**
+     * Frontend Callback.
+     */
+    public interface FilterCallback {
+        /**
+         * Invoked when filter status changed.
+         */
+        void onFilterStatus(int status);
+    }
+
     @Nullable
     private EventHandler createEventHandler() {
         Looper looper;
@@ -110,6 +122,13 @@
                         mFrontend.mCallback.onEvent(msg.arg1);
                     }
                     break;
+                case MSG_ON_FILTER_STATUS: {
+                    Filter filter = (Filter) msg.obj;
+                    if (filter.mCallback != null) {
+                        filter.mCallback.onFilterStatus(msg.arg1);
+                    }
+                    break;
+                }
                 default:
                     // fall through
             }
@@ -171,13 +190,29 @@
     }
 
     protected class Filter {
+        private long mNativeContext;
+        private FilterCallback mCallback;
         int mId;
         private Filter(int id) {
             mId = id;
         }
+
+        private void onFilterStatus(int status) {
+            if (mHandler != null) {
+                mHandler.sendMessage(
+                        mHandler.obtainMessage(MSG_ON_FILTER_STATUS, status, 0, this));
+            }
+        }
     }
 
-    private Filter openFilter(int type, int subType, int bufferSize) {
-        return nativeOpenFilter(type, subType, bufferSize);
+    private Filter openFilter(int type, int subType, int bufferSize, FilterCallback cb) {
+        Filter filter = nativeOpenFilter(type, subType, bufferSize);
+        if (filter != null) {
+            filter.mCallback = cb;
+            if (mHandler == null) {
+                mHandler = createEventHandler();
+            }
+        }
+        return filter;
     }
 }
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index f815097..2640572 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -34,9 +34,11 @@
 
 struct fields_t {
     jfieldID context;
+    jfieldID filterContext;
     jmethodID frontendInitID;
     jmethodID filterInitID;
     jmethodID onFrontendEventID;
+    jmethodID onFilterStatusID;
 };
 
 static fields_t gFields;
@@ -44,15 +46,27 @@
 namespace android {
 /////////////// FilterCallback ///////////////////////
 //TODO: implement filter callback
-Return<void> FilterCallback::onFilterEvent(const DemuxFilterEvent& /* filterEvent */) {
+Return<void> FilterCallback::onFilterEvent(const DemuxFilterEvent& /*filterEvent*/) {
     ALOGD("FilterCallback::onFilterEvent");
     return Void();
 }
-Return<void> FilterCallback::onFilterStatus(const DemuxFilterStatus /*status*/) {
-    ALOGD("FilterCallback::onFilterStatu");
+
+Return<void> FilterCallback::onFilterStatus(const DemuxFilterStatus status) {
+    ALOGD("FilterCallback::onFilterStatus");
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    env->CallVoidMethod(
+            mFilter,
+            gFields.onFilterStatusID,
+            (jint)status);
     return Void();
 }
 
+void FilterCallback::setFilter(const jobject filter) {
+    ALOGD("FilterCallback::setFilter");
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    mFilter = env->NewWeakGlobalRef(filter);
+}
+
 /////////////// FrontendCallback ///////////////////////
 
 FrontendCallback::FrontendCallback(jweak tunerObj, FrontendId id) : mObject(tunerObj), mId(id) {}
@@ -186,27 +200,35 @@
         }
     }
 
-    sp<IFilter> f;
-    mDemux->openFilter(type, bufferSize, new FilterCallback,
+    sp<IFilter> filterSp;
+    sp<FilterCallback> callback = new FilterCallback();
+    mDemux->openFilter(type, bufferSize, callback,
             [&](Result, const sp<IFilter>& filter) {
-                f = filter;
+                filterSp = filter;
             });
-    if (f == NULL) {
+    if (filterSp == NULL) {
         ALOGD("Failed to open filter, type = %d", type.mainType);
         return NULL;
     }
     int fId;
-    f->getId([&](Result, uint32_t filterId) {
+    filterSp->getId([&](Result, uint32_t filterId) {
         fId = filterId;
     });
-    mFilters[fId] = f;
 
     JNIEnv *env = AndroidRuntime::getJNIEnv();
-    return env->NewObject(
-            env->FindClass("android/media/tv/tuner/Tuner$Filter"),
-            gFields.filterInitID,
-            mObject,
-            (jint) fId);
+    jobject filterObj =
+            env->NewObject(
+                    env->FindClass("android/media/tv/tuner/Tuner$Filter"),
+                    gFields.filterInitID,
+                    mObject,
+                    (jint) fId);
+
+    filterSp->incStrong(filterObj);
+    env->SetLongField(filterObj, gFields.filterContext, (jlong)filterSp.get());
+
+    callback->setFilter(filterObj);
+
+    return filterObj;
 }
 
 }  // namespace android
@@ -233,6 +255,10 @@
     return (JTuner *)env->GetLongField(thiz, gFields.context);
 }
 
+static sp<IFilter> getFilter(JNIEnv *env, jobject filter) {
+    return (IFilter *)env->GetLongField(filter, gFields.filterContext);
+}
+
 static void android_media_tv_Tuner_native_init(JNIEnv *env) {
     jclass clazz = env->FindClass("android/media/tv/tuner/Tuner");
     CHECK(clazz != NULL);
@@ -247,8 +273,11 @@
             env->GetMethodID(frontendClazz, "<init>", "(Landroid/media/tv/tuner/Tuner;I)V");
 
     jclass filterClazz = env->FindClass("android/media/tv/tuner/Tuner$Filter");
+    gFields.filterContext = env->GetFieldID(filterClazz, "mNativeContext", "J");
     gFields.filterInitID =
             env->GetMethodID(filterClazz, "<init>", "(Landroid/media/tv/tuner/Tuner;I)V");
+    gFields.onFilterStatusID =
+            env->GetMethodID(filterClazz, "onFilterStatus", "(I)V");
 }
 
 static void android_media_tv_Tuner_native_setup(JNIEnv *env, jobject thiz) {
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index 7a889c3..ab48761 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -44,6 +44,10 @@
 struct FilterCallback : public IFilterCallback {
     virtual Return<void> onFilterEvent(const DemuxFilterEvent& filterEvent);
     virtual Return<void> onFilterStatus(const DemuxFilterStatus status);
+
+    void setFilter(const jobject filter);
+private:
+    jweak mFilter;
 };
 
 struct FrontendCallback : public IFrontendCallback {
@@ -76,7 +80,6 @@
     sp<IFrontend> mFe;
     sp<IDemux> mDemux;
     int mDemuxId;
-    std::unordered_map<int, sp<IFilter>> mFilters;
 };
 
 }  // namespace android
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
index d3d9b28..0bd2e06 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -24,6 +24,8 @@
 import com.android.systemui.power.PowerUI;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsModule;
+import com.android.systemui.shortcut.ShortcutKeyDispatcher;
+import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.car.CarStatusBar;
 import com.android.systemui.statusbar.car.CarStatusBarModule;
 import com.android.systemui.statusbar.notification.InstantAppNotifier;
@@ -45,7 +47,13 @@
     @Binds
     @IntoMap
     @ClassKey(AuthController.class)
-    public abstract SystemUI bindAuthController(AuthController service);
+    public abstract SystemUI bindAuthController(AuthController sysui);
+
+    /** Inject into Divider. */
+    @Binds
+    @IntoMap
+    @ClassKey(Divider.class)
+    public abstract SystemUI bindDivider(Divider sysui);
 
     /** */
     @Binds
@@ -57,7 +65,7 @@
     @Binds
     @IntoMap
     @ClassKey(GarbageMonitor.Service.class)
-    public abstract SystemUI bindGarbageMonitorService(GarbageMonitor.Service service);
+    public abstract SystemUI bindGarbageMonitorService(GarbageMonitor.Service sysui);
 
     /** Inject into GlobalActionsComponent. */
     @Binds
@@ -107,6 +115,12 @@
     @ClassKey(ScreenDecorations.class)
     public abstract SystemUI bindScreenDecorations(ScreenDecorations sysui);
 
+    /** Inject into ShortcutKeyDispatcher. */
+    @Binds
+    @IntoMap
+    @ClassKey(ShortcutKeyDispatcher.class)
+    public abstract SystemUI bindsShortcutKeyDispatcher(ShortcutKeyDispatcher sysui);
+
     /** Inject into SizeCompatModeActivityController. */
     @Binds
     @IntoMap
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
index be4b889..c35303e 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
@@ -18,12 +18,8 @@
 
 import android.content.Context;
 
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.dagger.SystemUIRootComponent;
 import com.android.systemui.navigationbar.car.CarFacetButtonController;
-import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 
 import javax.inject.Singleton;
 
@@ -50,11 +46,6 @@
         return mCarDependencyComponent;
     }
 
-    public StatusBarKeyguardViewManager createStatusBarKeyguardViewManager(Context context,
-            ViewMediatorCallback viewMediatorCallback, LockPatternUtils lockPatternUtils) {
-        return new CarStatusBarKeyguardViewManager(context, viewMediatorCallback, lockPatternUtils);
-    }
-
     @Singleton
     @Component(modules = ContextHolder.class)
     public interface CarDependencyComponent {
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index a6377b0..3b63e79 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -35,12 +35,14 @@
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
 import com.android.systemui.statusbar.car.CarStatusBar;
+import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.collection.NotificationData;
 import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.volume.CarVolumeDialogComponent;
 import com.android.systemui.volume.VolumeDialogComponent;
 
@@ -122,4 +124,8 @@
     @Binds
     abstract VolumeDialogComponent bindVolumeDialogComponent(
             CarVolumeDialogComponent carVolumeDialogComponent);
+
+    @Binds
+    abstract StatusBarKeyguardViewManager bindStatusBarKeyguardViewManager(
+            CarStatusBarKeyguardViewManager keyguardViewManager);
 }
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index c1515fc..1d14c34 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -55,22 +55,21 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.statusbar.RegisterStatusBarResult;
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.CarSystemUIFactory;
 import com.android.systemui.Dependency;
-import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.doze.DozeLog;
 import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -104,7 +103,6 @@
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.phone.AutoHideController;
@@ -123,6 +121,7 @@
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -133,7 +132,6 @@
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
 import com.android.systemui.statusbar.policy.RemoteInputUriController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -246,7 +244,6 @@
             AutoHideController autoHideController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             StatusBarIconController statusBarIconController,
-            DozeLog dozeLog,
             PulseExpansionHandler pulseExpansionHandler,
             NotificationWakeUpCoordinator notificationWakeUpCoordinator,
             KeyguardBypassController keyguardBypassController,
@@ -264,10 +261,7 @@
             NotificationEntryManager notificationEntryManager,
             NotificationInterruptionStateProvider notificationInterruptionStateProvider,
             NotificationViewHierarchyManager notificationViewHierarchyManager,
-            ForegroundServiceController foregroundServiceController,
-            AppOpsController appOpsController,
             KeyguardViewMediator keyguardViewMediator,
-            ZenModeController zenModeController,
             NotificationAlertingManager notificationAlertingManager,
             DisplayMetrics displayMetrics,
             MetricsLogger metricsLogger,
@@ -294,7 +288,6 @@
             ConfigurationController configurationController,
             StatusBarWindowController statusBarWindowController,
             StatusBarWindowViewController.Builder statusBarWindowViewControllerBuild,
-            NotifLog notifLog,
             DozeParameters dozeParameters,
             ScrimController scrimController,
             Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
@@ -308,6 +301,9 @@
             Optional<Divider> dividerOptional,
             SuperStatusBarViewFactory superStatusBarViewFactory,
             LightsOutNotifController lightsOutNotifController,
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+            ViewMediatorCallback viewMediatorCallback,
+            DismissCallbackRegistry dismissCallbackRegistry,
             /* Car Settings injected components. */
             CarNavigationBarController carNavigationBarController) {
         super(
@@ -317,7 +313,6 @@
                 autoHideController,
                 keyguardUpdateMonitor,
                 statusBarIconController,
-                dozeLog,
                 pulseExpansionHandler,
                 notificationWakeUpCoordinator,
                 keyguardBypassController,
@@ -335,10 +330,7 @@
                 notificationEntryManager,
                 notificationInterruptionStateProvider,
                 notificationViewHierarchyManager,
-                foregroundServiceController,
-                appOpsController,
                 keyguardViewMediator,
-                zenModeController,
                 notificationAlertingManager,
                 displayMetrics,
                 metricsLogger,
@@ -365,7 +357,6 @@
                 configurationController,
                 statusBarWindowController,
                 statusBarWindowViewControllerBuild,
-                notifLog,
                 dozeParameters,
                 scrimController,
                 null /* keyguardLiftController */,
@@ -379,7 +370,10 @@
                 remoteInputUriController,
                 dividerOptional,
                 lightsOutNotifController,
-                superStatusBarViewFactory);
+                superStatusBarViewFactory,
+                statusBarKeyguardViewManager,
+                viewMediatorCallback,
+                dismissCallbackRegistry);
         mScrimController = scrimController;
         mCarNavigationBarController = carNavigationBarController;
     }
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
index 5921868..0ad0992 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
@@ -20,18 +20,43 @@
 import android.view.View;
 
 import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.R;
+import com.android.systemui.dock.DockManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.phone.NavigationModeController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarWindowController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/** Car implementation of the {@link StatusBarKeyguardViewManager}. */
+@Singleton
 public class CarStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager {
 
     protected boolean mShouldHideNavBar;
 
+    @Inject
     public CarStatusBarKeyguardViewManager(Context context,
             ViewMediatorCallback callback,
-            LockPatternUtils lockPatternUtils) {
-        super(context, callback, lockPatternUtils);
+            LockPatternUtils lockPatternUtils,
+            SysuiStatusBarStateController sysuiStatusBarStateController,
+            ConfigurationController configurationController,
+            KeyguardUpdateMonitor keyguardUpdateMonitor,
+            NavigationModeController navigationModeController,
+            DockManager dockManager,
+            StatusBarWindowController statusBarWindowController,
+            KeyguardStateController keyguardStateController,
+            NotificationMediaManager notificationMediaManager) {
+        super(context, callback, lockPatternUtils, sysuiStatusBarStateController,
+                configurationController, keyguardUpdateMonitor, navigationModeController,
+                dockManager, statusBarWindowController, keyguardStateController,
+                notificationMediaManager);
         mShouldHideNavBar = context.getResources()
                 .getBoolean(R.bool.config_hideNavWhenKeyguardBouncerShown);
     }
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
index 9b91843..542fa44 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
@@ -24,14 +24,13 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.ForegroundServiceController;
+import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.doze.DozeLog;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -60,7 +59,6 @@
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.phone.AutoHideController;
@@ -77,6 +75,7 @@
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -87,7 +86,6 @@
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
 import com.android.systemui.statusbar.policy.RemoteInputUriController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
 
 import java.util.Optional;
 
@@ -115,7 +113,6 @@
             AutoHideController autoHideController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             StatusBarIconController statusBarIconController,
-            DozeLog dozeLog,
             PulseExpansionHandler pulseExpansionHandler,
             NotificationWakeUpCoordinator notificationWakeUpCoordinator,
             KeyguardBypassController keyguardBypassController,
@@ -133,10 +130,7 @@
             NotificationEntryManager notificationEntryManager,
             NotificationInterruptionStateProvider notificationInterruptionStateProvider,
             NotificationViewHierarchyManager notificationViewHierarchyManager,
-            ForegroundServiceController foregroundServiceController,
-            AppOpsController appOpsController,
             KeyguardViewMediator keyguardViewMediator,
-            ZenModeController zenModeController,
             NotificationAlertingManager notificationAlertingManager,
             DisplayMetrics displayMetrics,
             MetricsLogger metricsLogger,
@@ -163,7 +157,6 @@
             ConfigurationController configurationController,
             StatusBarWindowController statusBarWindowController,
             StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder,
-            NotifLog notifLog,
             DozeParameters dozeParameters,
             ScrimController scrimController,
             Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
@@ -177,6 +170,9 @@
             Optional<Divider> dividerOptional,
             SuperStatusBarViewFactory superStatusBarViewFactory,
             LightsOutNotifController lightsOutNotifController,
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+            ViewMediatorCallback viewMediatorCallback,
+            DismissCallbackRegistry dismissCallbackRegistry,
             CarNavigationBarController carNavigationBarController) {
         return new CarStatusBar(
                 context,
@@ -185,7 +181,6 @@
                 autoHideController,
                 keyguardUpdateMonitor,
                 statusBarIconController,
-                dozeLog,
                 pulseExpansionHandler,
                 notificationWakeUpCoordinator,
                 keyguardBypassController,
@@ -203,10 +198,7 @@
                 notificationEntryManager,
                 notificationInterruptionStateProvider,
                 notificationViewHierarchyManager,
-                foregroundServiceController,
-                appOpsController,
                 keyguardViewMediator,
-                zenModeController,
                 notificationAlertingManager,
                 displayMetrics,
                 metricsLogger,
@@ -233,7 +225,6 @@
                 configurationController,
                 statusBarWindowController,
                 statusBarWindowViewControllerBuilder,
-                notifLog,
                 dozeParameters,
                 scrimController,
                 lockscreenWallpaperLazy,
@@ -247,6 +238,9 @@
                 dividerOptional,
                 superStatusBarViewFactory,
                 lightsOutNotifController,
+                statusBarKeyguardViewManager,
+                viewMediatorCallback,
+                dismissCallbackRegistry,
                 carNavigationBarController);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
index 795a8ce3..c2d090e 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
@@ -15,12 +15,14 @@
 package com.android.systemui;
 
 import android.annotation.Nullable;
+import android.app.AppOpsManager;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.util.ArraySet;
 import android.util.SparseArray;
 
 import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.systemui.appops.AppOpsController;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
@@ -33,14 +35,21 @@
  */
 @Singleton
 public class ForegroundServiceController {
+    private static final int[] APP_OPS = new int[] {AppOpsManager.OP_CAMERA,
+            AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
+            AppOpsManager.OP_RECORD_AUDIO,
+            AppOpsManager.OP_COARSE_LOCATION,
+            AppOpsManager.OP_FINE_LOCATION};
 
     private final SparseArray<ForegroundServicesUserState> mUserServices = new SparseArray<>();
     private final Object mMutex = new Object();
     private final NotificationEntryManager mEntryManager;
 
     @Inject
-    public ForegroundServiceController(NotificationEntryManager entryManager) {
+    public ForegroundServiceController(NotificationEntryManager entryManager,
+            AppOpsController appOpsController) {
         mEntryManager = entryManager;
+        appOpsController.addCallback(APP_OPS, this::onAppOpChanged);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index b524597..0d400fe 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -43,7 +43,6 @@
 import com.android.systemui.statusbar.phone.LockIcon;
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
 import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import dagger.Module;
@@ -120,11 +119,6 @@
         return mRootComponent;
     }
 
-    public StatusBarKeyguardViewManager createStatusBarKeyguardViewManager(Context context,
-            ViewMediatorCallback viewMediatorCallback, LockPatternUtils lockPatternUtils) {
-        return new StatusBarKeyguardViewManager(context, viewMediatorCallback, lockPatternUtils);
-    }
-
     /**
      * Creates an instance of ScreenshotNotificationSmartActionsProvider.
      * This method is overridden in vendor specific implementation of Sys UI.
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 6d61b2f..741c95f 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -35,12 +35,14 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.BgHandler;
 import com.android.systemui.dagger.qualifiers.BgLooper;
 import com.android.systemui.dagger.qualifiers.MainHandler;
 import com.android.systemui.dagger.qualifiers.MainLooper;
 import com.android.systemui.doze.AlwaysOnDisplayPolicy;
+import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.plugins.PluginInitializerImpl;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.shared.plugins.PluginManagerImpl;
@@ -249,4 +251,10 @@
     public UserManager providesUserManager(Context context) {
         return context.getSystemService(UserManager.class);
     }
+
+    /** */
+    @Provides
+    public ViewMediatorCallback providesViewMediatorCallback(KeyguardViewMediator viewMediator) {
+        return viewMediator.getViewMediatorCallback();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java b/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
index 7bec5c0..25ac8f8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
@@ -22,14 +22,21 @@
 
 import java.util.ArrayList;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /**
  * Registry holding the current set of {@link IKeyguardDismissCallback}s.
  */
+@Singleton
 public class DismissCallbackRegistry {
 
     private final ArrayList<DismissCallbackWrapper> mDismissCallbacks = new ArrayList<>();
     private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
 
+    @Inject
+    public DismissCallbackRegistry() {}
+
     public void addCallback(IKeyguardDismissCallback callback) {
         mDismissCallbacks.add(new DismissCallbackWrapper(callback));
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 3b1edcc..c876fa6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -68,7 +68,6 @@
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.policy.IKeyguardDrawnCallback;
 import com.android.internal.policy.IKeyguardExitCallback;
@@ -104,6 +103,8 @@
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
+import dagger.Lazy;
+
 /**
  * Mediates requests related to the keyguard.  This includes queries about the
  * state of the keyguard, power management events that effect whether the keyguard
@@ -236,7 +237,7 @@
      */
     private PowerManager.WakeLock mShowKeyguardWakeLock;
 
-    private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    private final Lazy<StatusBarKeyguardViewManager> mStatusBarKeyguardViewManagerLazy;
 
     // these are protected by synchronized (this)
 
@@ -282,7 +283,7 @@
      * var being non-null as an indicator that there is an in progress request.
      */
     private IKeyguardExitCallback mExitSecureCallback;
-    private final DismissCallbackRegistry mDismissCallbackRegistry = new DismissCallbackRegistry();
+    private final DismissCallbackRegistry mDismissCallbackRegistry;
 
     // the properties of the keyguard
 
@@ -587,7 +588,7 @@
 
         @Override
         public void setNeedsInput(boolean needsInput) {
-            mStatusBarKeyguardViewManager.setNeedsInput(needsInput);
+            mStatusBarKeyguardViewManagerLazy.get().setNeedsInput(needsInput);
         }
 
         @Override
@@ -601,7 +602,8 @@
             mKeyguardDonePending = true;
             mHideAnimationRun = true;
             mHideAnimationRunning = true;
-            mStatusBarKeyguardViewManager.startPreHideAnimation(mHideAnimationFinishedRunnable);
+            mStatusBarKeyguardViewManagerLazy.get()
+                    .startPreHideAnimation(mHideAnimationFinishedRunnable);
             mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_PENDING_TIMEOUT,
                     KEYGUARD_DONE_PENDING_TIMEOUT_MS);
             Trace.endSection();
@@ -631,7 +633,7 @@
 
         @Override
         public void onCancelClicked() {
-            mStatusBarKeyguardViewManager.onCancelClicked();
+            mStatusBarKeyguardViewManagerLazy.get().onCancelClicked();
         }
 
         @Override
@@ -688,26 +690,15 @@
             Context context,
             FalsingManager falsingManager,
             LockPatternUtils lockPatternUtils,
-            BroadcastDispatcher broadcastDispatcher) {
-        this(context, falsingManager, lockPatternUtils, broadcastDispatcher,
-                SystemUIFactory.getInstance());
-    }
-
-    @VisibleForTesting
-    KeyguardViewMediator(
-            Context context,
-            FalsingManager falsingManager,
-            LockPatternUtils lockPatternUtils,
             BroadcastDispatcher broadcastDispatcher,
-            SystemUIFactory systemUIFactory) {
+            Lazy<StatusBarKeyguardViewManager> statusBarKeyguardViewManagerLazy,
+            DismissCallbackRegistry dismissCallbackRegistry) {
         super(context);
         mFalsingManager = falsingManager;
         mLockPatternUtils = lockPatternUtils;
         mBroadcastDispatcher = broadcastDispatcher;
-        mStatusBarKeyguardViewManager = systemUIFactory.createStatusBarKeyguardViewManager(
-                mContext,
-                mViewMediatorCallback,
-                mLockPatternUtils);
+        mStatusBarKeyguardViewManagerLazy = statusBarKeyguardViewManagerLazy;
+        mDismissCallbackRegistry = dismissCallbackRegistry;
     }
 
     public void userActivity() {
@@ -1259,7 +1250,7 @@
             if (mOccluded != isOccluded) {
                 mOccluded = isOccluded;
                 mUpdateMonitor.setKeyguardOccluded(isOccluded);
-                mStatusBarKeyguardViewManager.setOccluded(isOccluded, animate
+                mStatusBarKeyguardViewManagerLazy.get().setOccluded(isOccluded, animate
                         && mDeviceInteractive);
                 adjustStatusBarLocked();
             }
@@ -1330,7 +1321,7 @@
         }
 
         // if the keyguard is already showing, don't bother
-        if (mStatusBarKeyguardViewManager.isShowing()) {
+        if (mStatusBarKeyguardViewManagerLazy.get().isShowing()) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
             resetStateLocked();
             return;
@@ -1394,7 +1385,7 @@
                 mDismissCallbackRegistry.addCallback(callback);
             }
             mCustomMessage = message;
-            mStatusBarKeyguardViewManager.dismissAndCollapse();
+            mStatusBarKeyguardViewManagerLazy.get().dismissAndCollapse();
         } else if (callback != null) {
             new DismissCallbackWrapper(callback).notifyDismissError();
         }
@@ -1661,7 +1652,8 @@
         } else if (!mHideAnimationRun) {
             mHideAnimationRun = true;
             mHideAnimationRunning = true;
-            mStatusBarKeyguardViewManager.startPreHideAnimation(mHideAnimationFinishedRunnable);
+            mStatusBarKeyguardViewManagerLazy.get()
+                    .startPreHideAnimation(mHideAnimationFinishedRunnable);
         }
     }
 
@@ -1817,7 +1809,7 @@
             mHiding = false;
             mWakeAndUnlocking = false;
             setShowingLocked(true);
-            mStatusBarKeyguardViewManager.show(options);
+            mStatusBarKeyguardViewManagerLazy.get().show(options);
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
             adjustStatusBarLocked();
@@ -1835,22 +1827,22 @@
         public void run() {
             Trace.beginSection("KeyguardViewMediator.mKeyGuardGoingAwayRunnable");
             if (DEBUG) Log.d(TAG, "keyguardGoingAway");
-            mStatusBarKeyguardViewManager.keyguardGoingAway();
+            mStatusBarKeyguardViewManagerLazy.get().keyguardGoingAway();
 
             int flags = 0;
-            if (mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock()
+            if (mStatusBarKeyguardViewManagerLazy.get().shouldDisableWindowAnimationsForUnlock()
                     || (mWakeAndUnlocking && !mPulsing)) {
                 flags |= WindowManagerPolicyConstants
                         .KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
             }
-            if (mStatusBarKeyguardViewManager.isGoingToNotificationShade()
+            if (mStatusBarKeyguardViewManagerLazy.get().isGoingToNotificationShade()
                     || (mWakeAndUnlocking && mPulsing)) {
                 flags |= WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
             }
-            if (mStatusBarKeyguardViewManager.isUnlockWithWallpaper()) {
+            if (mStatusBarKeyguardViewManagerLazy.get().isUnlockWithWallpaper()) {
                 flags |= WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
             }
-            if (mStatusBarKeyguardViewManager.shouldSubtleWindowAnimationsForUnlock()) {
+            if (mStatusBarKeyguardViewManagerLazy.get().shouldSubtleWindowAnimationsForUnlock()) {
                 flags |= WindowManagerPolicyConstants
                         .KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS;
             }
@@ -1936,7 +1928,7 @@
                 // Hack level over 9000: To speed up wake-and-unlock sequence, force it to report
                 // the next draw from here so we don't have to wait for window manager to signal
                 // this to our ViewRootImpl.
-                mStatusBarKeyguardViewManager.getViewRootImpl().setReportNextDraw();
+                mStatusBarKeyguardViewManagerLazy.get().getViewRootImpl().setReportNextDraw();
                 notifyDrawn(mDrawnCallback);
                 mDrawnCallback = null;
             }
@@ -1950,7 +1942,7 @@
             setShowingLocked(false);
             mWakeAndUnlocking = false;
             mDismissCallbackRegistry.notifyDismissSucceeded();
-            mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
+            mStatusBarKeyguardViewManagerLazy.get().hide(startTime, fadeoutDuration);
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
             adjustStatusBarLocked();
@@ -1996,7 +1988,7 @@
     private void handleReset() {
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleReset");
-            mStatusBarKeyguardViewManager.reset(true /* hideBouncerWhenShowing */);
+            mStatusBarKeyguardViewManagerLazy.get().reset(true /* hideBouncerWhenShowing */);
         }
     }
 
@@ -2009,7 +2001,7 @@
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
             setShowingLocked(true);
-            mStatusBarKeyguardViewManager.dismissAndCollapse();
+            mStatusBarKeyguardViewManagerLazy.get().dismissAndCollapse();
         }
         Trace.endSection();
     }
@@ -2017,7 +2009,7 @@
     private void handleNotifyStartedGoingToSleep() {
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleNotifyStartedGoingToSleep");
-            mStatusBarKeyguardViewManager.onStartedGoingToSleep();
+            mStatusBarKeyguardViewManagerLazy.get().onStartedGoingToSleep();
         }
     }
 
@@ -2028,7 +2020,7 @@
     private void handleNotifyFinishedGoingToSleep() {
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleNotifyFinishedGoingToSleep");
-            mStatusBarKeyguardViewManager.onFinishedGoingToSleep();
+            mStatusBarKeyguardViewManagerLazy.get().onFinishedGoingToSleep();
         }
     }
 
@@ -2036,7 +2028,7 @@
         Trace.beginSection("KeyguardViewMediator#handleMotifyStartedWakingUp");
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleNotifyWakingUp");
-            mStatusBarKeyguardViewManager.onStartedWakingUp();
+            mStatusBarKeyguardViewManagerLazy.get().onStartedWakingUp();
         }
         Trace.endSection();
     }
@@ -2045,7 +2037,7 @@
         Trace.beginSection("KeyguardViewMediator#handleNotifyScreenTurningOn");
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleNotifyScreenTurningOn");
-            mStatusBarKeyguardViewManager.onScreenTurningOn();
+            mStatusBarKeyguardViewManagerLazy.get().onScreenTurningOn();
             if (callback != null) {
                 if (mWakeAndUnlocking) {
                     mDrawnCallback = callback;
@@ -2064,7 +2056,7 @@
         }
         synchronized (this) {
             if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOn");
-            mStatusBarKeyguardViewManager.onScreenTurnedOn();
+            mStatusBarKeyguardViewManagerLazy.get().onScreenTurnedOn();
         }
         Trace.endSection();
     }
@@ -2113,10 +2105,10 @@
             ViewGroup container, NotificationPanelView panelView,
             BiometricUnlockController biometricUnlockController, ViewGroup lockIconContainer,
             View notificationContainer, KeyguardBypassController bypassController) {
-        mStatusBarKeyguardViewManager.registerStatusBar(statusBar, container, panelView,
+        mStatusBarKeyguardViewManagerLazy.get().registerStatusBar(statusBar, container, panelView,
                 biometricUnlockController, mDismissCallbackRegistry, lockIconContainer,
                 notificationContainer, bypassController, mFalsingManager);
-        return mStatusBarKeyguardViewManager;
+        return mStatusBarKeyguardViewManagerLazy.get();
     }
 
     public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java b/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
index 4d18312..4501b8f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
@@ -65,6 +65,8 @@
         mMobileRoaming = findViewById(R.id.mobile_roaming);
         mCarrierText = findViewById(R.id.qs_carrier_text);
 
+        mMobileSignal.setImageDrawable(new SignalDrawable(mContext));
+
         int colorForeground = Utils.getColorAttrDefaultColor(mContext,
                 android.R.attr.colorForeground);
         mColorForegroundStateList = ColorStateList.valueOf(colorForeground);
@@ -78,7 +80,6 @@
             ColorStateList colorStateList = ColorStateList.valueOf(
                     mDualToneHandler.getSingleColor(mColorForegroundIntensity));
             mMobileRoaming.setImageTintList(colorStateList);
-            mMobileSignal.setImageDrawable(new SignalDrawable(mContext));
             mMobileSignal.setImageTintList(colorStateList);
             mMobileSignal.setImageLevel(state.mobileSignalIconId);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 404087d..13d90ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -261,6 +261,7 @@
             boolean isNew = mNotificationData.get(entry.getKey()) == null;
             if (isNew) {
                 for (NotificationEntryListener listener : mNotificationEntryListeners) {
+                    mNotifLog.log(NotifEvent.INFLATED, entry);
                     listener.onEntryInflated(entry, inflatedFlags);
                 }
                 mNotificationData.add(entry);
@@ -270,6 +271,7 @@
                 }
             } else {
                 for (NotificationEntryListener listener : mNotificationEntryListeners) {
+                    mNotifLog.log(NotifEvent.INFLATED, entry);
                     listener.onEntryReinflated(entry);
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
index 2eefe29..3f7fd1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
@@ -19,7 +19,6 @@
 import static com.android.internal.util.Preconditions.checkNotNull;
 
 import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -34,17 +33,14 @@
 public class NotificationListController {
     private final NotificationEntryManager mEntryManager;
     private final NotificationListContainer mListContainer;
-    private final ForegroundServiceController mForegroundServiceController;
     private final DeviceProvisionedController mDeviceProvisionedController;
 
     public NotificationListController(
             NotificationEntryManager entryManager,
             NotificationListContainer listContainer,
-            ForegroundServiceController foregroundServiceController,
             DeviceProvisionedController deviceProvisionedController) {
         mEntryManager = checkNotNull(entryManager);
         mListContainer = checkNotNull(listContainer);
-        mForegroundServiceController = checkNotNull(foregroundServiceController);
         mDeviceProvisionedController = checkNotNull(deviceProvisionedController);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
index 0ef75165..52fd079 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
@@ -41,8 +41,6 @@
 import com.android.systemui.statusbar.notification.InflationException;
 import com.android.systemui.statusbar.notification.NotificationClicker;
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
-import com.android.systemui.statusbar.notification.logging.NotifEvent;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationContentInflater;
@@ -74,7 +72,6 @@
     private final boolean mAllowLongPress;
     private final KeyguardBypassController mKeyguardBypassController;
     private final StatusBarStateController mStatusBarStateController;
-    private final NotifLog mNotifLog;
 
     private NotificationRemoteInputManager mRemoteInputManager;
     private NotificationPresenter mPresenter;
@@ -88,14 +85,12 @@
 
     public NotificationRowBinderImpl(Context context, boolean allowLongPress,
             KeyguardBypassController keyguardBypassController,
-            StatusBarStateController statusBarStateController,
-            NotifLog notifLog) {
+            StatusBarStateController statusBarStateController) {
         mContext = context;
         mMessagingUtil = new NotificationMessagingUtil(context);
         mAllowLongPress = allowLongPress;
         mKeyguardBypassController = keyguardBypassController;
         mStatusBarStateController = statusBarStateController;
-        mNotifLog = notifLog;
     }
 
     private NotificationRemoteInputManager getRemoteInputManager() {
@@ -149,7 +144,6 @@
                     row -> {
                         bindRow(entry, pmUser, sbn, row, onDismissRunnable);
                         updateNotification(entry, pmUser, sbn, row);
-                        mNotifLog.log(NotifEvent.INFLATED, sbn);
                     });
         }
     }
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 2b9912c..8d50f58 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
@@ -142,6 +142,7 @@
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 import com.android.systemui.statusbar.policy.HeadsUpUtil;
 import com.android.systemui.statusbar.policy.ScrollAdapter;
+import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.util.Assert;
 
@@ -344,6 +345,7 @@
     private boolean mForceNoOverlappingRendering;
     private final ArrayList<Pair<ExpandableNotificationRow, Boolean>> mTmpList = new ArrayList<>();
     private FalsingManager mFalsingManager;
+    private final ZenModeController mZenController;
     private boolean mAnimationRunning;
     private ViewTreeObserver.OnPreDrawListener mRunningAnimationUpdater
             = new ViewTreeObserver.OnPreDrawListener() {
@@ -520,7 +522,8 @@
             NotificationLockscreenUserManager notificationLockscreenUserManager,
             NotificationGutsManager notificationGutsManager,
             NotificationSectionsFeatureManager sectionsFeatureManager,
-            PeopleHubSectionFooterViewAdapter peopleHubViewAdapter) {
+            PeopleHubSectionFooterViewAdapter peopleHubViewAdapter,
+            ZenModeController zenController) {
         super(context, attrs, 0, 0);
         Resources res = getResources();
 
@@ -535,6 +538,7 @@
         mHeadsUpManager.setAnimationStateHandler(this::setHeadsUpGoingAwayAnimationsAllowed);
         mKeyguardBypassController = keyguardBypassController;
         mFalsingManager = falsingManager;
+        mZenController = zenController;
 
         int[] buckets = sectionsFeatureManager.getNotificationBuckets();
         mSectionsManager =
@@ -4882,7 +4886,7 @@
         mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled);
 
         int oldTextRes = mEmptyShadeView.getTextResource();
-        int newTextRes = mStatusBar.areNotificationsHidden()
+        int newTextRes = mZenController.areNotificationsHiddenInShade()
                 ? R.string.dnd_suppressing_shade_text : R.string.empty_shade_text;
         if (oldTextRes != newTextRes) {
             mEmptyShadeView.setText(newTextRes);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 6be8816..910300c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -51,7 +51,6 @@
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
-import android.app.AppOpsManager;
 import android.app.IWallpaperManager;
 import android.app.KeyguardManager;
 import android.app.Notification;
@@ -136,7 +135,6 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
 import com.android.systemui.EventLogTags;
-import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.InitController;
 import com.android.systemui.Interpolators;
 import com.android.systemui.Prefs;
@@ -144,7 +142,6 @@
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.bubbles.BubbleController;
@@ -152,9 +149,9 @@
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.doze.DozeHost;
-import com.android.systemui.doze.DozeLog;
 import com.android.systemui.fragments.ExtensionFragmentListener;
 import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.keyguard.KeyguardSliceProvider;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
@@ -213,7 +210,6 @@
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationRowBinderImpl;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
@@ -236,7 +232,6 @@
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.volume.VolumeComponent;
 
 import java.io.FileDescriptor;
@@ -253,10 +248,10 @@
 
 public class StatusBar extends SystemUI implements DemoMode,
         ActivityStarter, KeyguardStateController.Callback,
-        OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
+        OnHeadsUpChangedListener, CommandQueue.Callbacks,
         ColorExtractor.OnColorsChangedListener, ConfigurationListener,
         StatusBarStateController.StateListener, ShadeController,
-        ActivityLaunchAnimator.Callback, AppOpsController.Callback {
+        ActivityLaunchAnimator.Callback {
     public static final boolean MULTIUSER_DEBUG = false;
 
     public static final boolean ENABLE_CHILD_NOTIFICATIONS
@@ -375,7 +370,6 @@
 
     private final FeatureFlags mFeatureFlags;
     private final StatusBarIconController mIconController;
-    private final DozeLog mDozeLog;
     private final PulseExpansionHandler mPulseExpansionHandler;
     private final NotificationWakeUpCoordinator mWakeUpCoordinator;
     private final KeyguardBypassController mKeyguardBypassController;
@@ -389,7 +383,6 @@
     private final BroadcastDispatcher mBroadcastDispatcher;
     private final ConfigurationController mConfigurationController;
     private final StatusBarWindowViewController.Builder mStatusBarWindowViewControllerBuilder;
-    private final NotifLog mNotifLog;
     private final DozeParameters mDozeParameters;
     private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
     private final PluginManager mPluginManager;
@@ -397,6 +390,7 @@
     private final Optional<Divider> mDividerOptional;
     private final SuperStatusBarViewFactory mSuperStatusBarViewFactory;
     private final LightsOutNotifController mLightsOutNotifController;
+    private final DismissCallbackRegistry mDismissCallbackRegistry;
 
     // expanded notifications
     protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -424,10 +418,7 @@
     private NotificationListController mNotificationListController;
     private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
     private final NotificationViewHierarchyManager mViewHierarchyManager;
-    private final ForegroundServiceController mForegroundServiceController;
-    private final AppOpsController mAppOpsController;
     private final KeyguardViewMediator mKeyguardViewMediator;
-    private final ZenModeController mZenController;
     private final NotificationAlertingManager mNotificationAlertingManager;
 
     // for disabling the status bar
@@ -614,19 +605,6 @@
 
     private ActivityIntentHelper mActivityIntentHelper;
 
-    @Override
-    public void onActiveStateChanged(int code, int uid, String packageName, boolean active) {
-        Dependency.get(MAIN_HANDLER).post(() -> {
-            mForegroundServiceController.onAppOpChanged(code, uid, packageName, active);
-        });
-    }
-
-    protected static final int[] APP_OPS = new int[] {AppOpsManager.OP_CAMERA,
-            AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
-            AppOpsManager.OP_RECORD_AUDIO,
-            AppOpsManager.OP_COARSE_LOCATION,
-            AppOpsManager.OP_FINE_LOCATION};
-
     /**
      * Public constructor for StatusBar.
      *
@@ -641,7 +619,6 @@
             AutoHideController autoHideController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             StatusBarIconController statusBarIconController,
-            DozeLog dozeLog,
             PulseExpansionHandler pulseExpansionHandler,
             NotificationWakeUpCoordinator notificationWakeUpCoordinator,
             KeyguardBypassController keyguardBypassController,
@@ -659,10 +636,7 @@
             NotificationEntryManager notificationEntryManager,
             NotificationInterruptionStateProvider notificationInterruptionStateProvider,
             NotificationViewHierarchyManager notificationViewHierarchyManager,
-            ForegroundServiceController foregroundServiceController,
-            AppOpsController appOpsController,
             KeyguardViewMediator keyguardViewMediator,
-            ZenModeController zenModeController,
             NotificationAlertingManager notificationAlertingManager,
             DisplayMetrics displayMetrics,
             MetricsLogger metricsLogger,
@@ -689,7 +663,6 @@
             ConfigurationController configurationController,
             StatusBarWindowController statusBarWindowController,
             StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder,
-            NotifLog notifLog,
             DozeParameters dozeParameters,
             ScrimController scrimController,
             @Nullable KeyguardLiftController keyguardLiftController,
@@ -703,14 +676,16 @@
             RemoteInputUriController remoteInputUriController,
             Optional<Divider> dividerOptional,
             LightsOutNotifController lightsOutNotifController,
-            SuperStatusBarViewFactory superStatusBarViewFactory) {
+            SuperStatusBarViewFactory superStatusBarViewFactory,
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+            ViewMediatorCallback viewMediatorCallback,
+            DismissCallbackRegistry dismissCallbackRegistry) {
         super(context);
         mFeatureFlags = featureFlags;
         mLightBarController = lightBarController;
         mAutoHideController = autoHideController;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mIconController = statusBarIconController;
-        mDozeLog = dozeLog;
         mPulseExpansionHandler = pulseExpansionHandler;
         mWakeUpCoordinator = notificationWakeUpCoordinator;
         mKeyguardBypassController = keyguardBypassController;
@@ -728,10 +703,7 @@
         mEntryManager = notificationEntryManager;
         mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
         mViewHierarchyManager = notificationViewHierarchyManager;
-        mForegroundServiceController = foregroundServiceController;
-        mAppOpsController = appOpsController;
         mKeyguardViewMediator = keyguardViewMediator;
-        mZenController = zenModeController;
         mNotificationAlertingManager = notificationAlertingManager;
         mDisplayMetrics = displayMetrics;
         mMetricsLogger = metricsLogger;
@@ -758,7 +730,6 @@
         mConfigurationController = configurationController;
         mStatusBarWindowController = statusBarWindowController;
         mStatusBarWindowViewControllerBuilder = statusBarWindowViewControllerBuilder;
-        mNotifLog = notifLog;
         mDozeServiceHost = dozeServiceHost;
         mPowerManager = powerManager;
         mDozeParameters = dozeParameters;
@@ -774,6 +745,10 @@
 
         mSuperStatusBarViewFactory = superStatusBarViewFactory;
         mLightsOutNotifController =  lightsOutNotifController;
+        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+        mKeyguardViewMediatorCallback = viewMediatorCallback;
+        mDismissCallbackRegistry = dismissCallbackRegistry;
+
         mBubbleExpandListener =
                 (isExpanding, key) -> {
                     mEntryManager.updateNotifications("onBubbleExpandChanged");
@@ -995,7 +970,6 @@
         mNotificationPanel = mStatusBarWindow.findViewById(R.id.notification_panel);
 
         mStackScroller = mStatusBarWindow.findViewById(R.id.notification_stack_scroller);
-        mZenController.addCallback(this);
         NotificationListContainer notifListContainer = (NotificationListContainer) mStackScroller;
         mNotificationLogger.setUpWithContainer(notifListContainer);
 
@@ -1255,8 +1229,7 @@
                         mContext,
                         mAllowNotificationLongPress,
                         mKeyguardBypassController,
-                        mStatusBarStateController,
-                        mNotifLog);
+                        mStatusBarStateController);
 
         mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanel,
                 mHeadsUpManager, mStatusBarWindow, mStackScroller, mDozeScrimController,
@@ -1267,10 +1240,8 @@
                 new NotificationListController(
                         mEntryManager,
                         (NotificationListContainer) mStackScroller,
-                        mForegroundServiceController,
                         mDeviceProvisionedController);
 
-        mAppOpsController.addCallback(APP_OPS, this);
         mNotificationShelf.setOnActivatedListener(mPresenter);
         mRemoteInputManager.getController().addCallback(mStatusBarWindowController);
 
@@ -1428,17 +1399,17 @@
     protected void startKeyguard() {
         Trace.beginSection("StatusBar#startKeyguard");
         mBiometricUnlockController = mBiometricUnlockControllerLazy.get();
-        mStatusBarKeyguardViewManager = mKeyguardViewMediator.registerStatusBar(this,
-                getBouncerContainer(), mNotificationPanel, mBiometricUnlockController,
+        mStatusBarKeyguardViewManager.registerStatusBar(
+                /* statusBar= */ this, getBouncerContainer(), mNotificationPanel,
+                mBiometricUnlockController, mDismissCallbackRegistry,
                 mStatusBarWindow.findViewById(R.id.lock_icon_container), mStackScroller,
-                mKeyguardBypassController);
+                mKeyguardBypassController, mFalsingManager);
         mKeyguardIndicationController
                 .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
         mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
         mRemoteInputManager.getController().addCallback(mStatusBarKeyguardViewManager);
         mDynamicPrivacyController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
 
-        mKeyguardViewMediatorCallback = mKeyguardViewMediator.getViewMediatorCallback();
         mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
         mMediaManager.setBiometricUnlockController(mBiometricUnlockController);
         Dependency.get(KeyguardDismissUtil.class).setDismissHandler(this::executeWhenUnlocked);
@@ -1525,10 +1496,6 @@
         mQSPanel.clickTile(tile);
     }
 
-    public boolean areNotificationsHidden() {
-        return mZenController.areNotificationsHiddenInShade();
-    }
-
     /**
      * Request a notification update
      * @param reason why we're requesting a notification update
@@ -2479,10 +2446,6 @@
         pw.print("  mStatusBarMode=");
         pw.println(BarTransitions.modeToString(mStatusBarMode));
         pw.print("  mDozing="); pw.println(mDozing);
-        pw.print("  mZenMode=");
-        pw.println(Settings.Global.zenModeToString(Settings.Global.getInt(
-                mContext.getContentResolver(), Settings.Global.ZEN_MODE,
-                Settings.Global.ZEN_MODE_OFF)));
         pw.print("  mWallpaperSupported= "); pw.println(mWallpaperSupported);
 
         if (mStatusBarView != null) {
@@ -2519,8 +2482,6 @@
         final boolean lightWpTheme = mContext.getThemeResId() == R.style.Theme_SystemUI_Light;
         pw.println("    light wallpaper theme: " + lightWpTheme);
 
-        mDozeLog.dump(pw);
-
         if (mKeyguardIndicationController != null) {
             mKeyguardIndicationController.dump(fd, pw, args);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 8683586..31d0362 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -42,7 +42,6 @@
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.settingslib.animation.AppearAnimationUtils;
 import com.android.systemui.DejankUtils;
-import com.android.systemui.Dependency;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
@@ -63,12 +62,16 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /**
  * Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back
  * via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done,
  * which is in turn, reported to this class by the current
  * {@link com.android.keyguard.KeyguardViewBase}.
  */
+@Singleton
 public class StatusBarKeyguardViewManager implements RemoteInputController.Callback,
         StatusBarStateController.StateListener, ConfigurationController.ConfigurationListener,
         PanelExpansionListener, NavigationModeController.ModeChangedListener {
@@ -167,13 +170,11 @@
 
     // Dismiss action to be launched when we stop dozing or the keyguard is gone.
     private DismissWithActionRequest mPendingWakeupAction;
-    private final KeyguardStateController mKeyguardStateController = Dependency.get(
-            KeyguardStateController.class);
-    private final NotificationMediaManager mMediaManager =
-            Dependency.get(NotificationMediaManager.class);
-    private final SysuiStatusBarStateController mStatusBarStateController =
-            (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class);
+    private final KeyguardStateController mKeyguardStateController;
+    private final NotificationMediaManager mMediaManager;
+    private final SysuiStatusBarStateController mStatusBarStateController;
     private final DockManager mDockManager;
+    private final KeyguardUpdateMonitor mKeyguardUpdateManager;
     private KeyguardBypassController mBypassController;
 
     private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
@@ -189,18 +190,33 @@
         }
     };
 
-    public StatusBarKeyguardViewManager(Context context, ViewMediatorCallback callback,
-            LockPatternUtils lockPatternUtils) {
+    @Inject
+    public StatusBarKeyguardViewManager(
+            Context context,
+            ViewMediatorCallback callback,
+            LockPatternUtils lockPatternUtils,
+            SysuiStatusBarStateController sysuiStatusBarStateController,
+            ConfigurationController configurationController,
+            KeyguardUpdateMonitor keyguardUpdateMonitor,
+            NavigationModeController navigationModeController,
+            DockManager dockManager,
+            StatusBarWindowController statusBarWindowController,
+            KeyguardStateController keyguardStateController,
+            NotificationMediaManager notificationMediaManager) {
         mContext = context;
         mViewMediatorCallback = callback;
         mLockPatternUtils = lockPatternUtils;
-        mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
-        Dependency.get(KeyguardUpdateMonitor.class).registerCallback(mUpdateMonitorCallback);
+        mStatusBarWindowController = statusBarWindowController;
+        mKeyguardStateController = keyguardStateController;
+        mMediaManager = notificationMediaManager;
+        mKeyguardUpdateManager = keyguardUpdateMonitor;
+        mKeyguardUpdateManager.registerCallback(mUpdateMonitorCallback);
+        mStatusBarStateController = sysuiStatusBarStateController;
         mStatusBarStateController.addCallback(this);
-        Dependency.get(ConfigurationController.class).addCallback(this);
+        configurationController.addCallback(this);
         mGesturalNav = QuickStepContract.isGesturalMode(
-                Dependency.get(NavigationModeController.class).addListener(this));
-        mDockManager = Dependency.get(DockManager.class);
+                navigationModeController.addListener(this));
+        mDockManager = dockManager;
         if (mDockManager != null) {
             mDockManager.addListener(mDockEventListener);
             mIsDocked = mDockManager.isDocked();
@@ -409,7 +425,7 @@
             } else {
                 showBouncerOrKeyguard(hideBouncerWhenShowing);
             }
-            Dependency.get(KeyguardUpdateMonitor.class).sendKeyguardReset();
+            mKeyguardUpdateManager.sendKeyguardReset();
             updateStates();
         }
     }
@@ -547,7 +563,7 @@
                 mKeyguardStateController.isOccluded());
         launchPendingWakeupAction();
 
-        if (Dependency.get(KeyguardUpdateMonitor.class).needsSlowUnlockTransition()) {
+        if (mKeyguardUpdateManager.needsSlowUnlockTransition()) {
             fadeoutDuration = KEYGUARD_DISMISS_DURATION_LOCKED;
         }
         long uptimeMillis = SystemClock.uptimeMillis();
@@ -800,12 +816,11 @@
             updateLockIcon();
         }
 
-        KeyguardUpdateMonitor updateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
         if ((showing && !occluded) != (mLastShowing && !mLastOccluded) || mFirstUpdate) {
-            updateMonitor.onKeyguardVisibilityChanged(showing && !occluded);
+            mKeyguardUpdateManager.onKeyguardVisibilityChanged(showing && !occluded);
         }
         if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
-            updateMonitor.sendKeyguardBouncerChanged(bouncerShowing);
+            mKeyguardUpdateManager.sendKeyguardBouncerChanged(bouncerShowing);
         }
 
         mFirstUpdate = false;
@@ -889,8 +904,7 @@
     }
 
     public boolean isGoingToNotificationShade() {
-        return ((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class))
-                .leaveOpenOnKeyguardHide();
+        return mStatusBarStateController.leaveOpenOnKeyguardHide();
     }
 
     public boolean isSecure(int userId) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
index 2364c33..9811f96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
@@ -26,14 +26,13 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.ForegroundServiceController;
+import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.doze.DozeLog;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -61,7 +60,6 @@
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -72,7 +70,6 @@
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
 import com.android.systemui.statusbar.policy.RemoteInputUriController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
 
 import java.util.Optional;
 
@@ -100,7 +97,6 @@
             AutoHideController autoHideController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             StatusBarIconController statusBarIconController,
-            DozeLog dozeLog,
             PulseExpansionHandler pulseExpansionHandler,
             NotificationWakeUpCoordinator notificationWakeUpCoordinator,
             KeyguardBypassController keyguardBypassController,
@@ -118,10 +114,7 @@
             NotificationEntryManager notificationEntryManager,
             NotificationInterruptionStateProvider notificationInterruptionStateProvider,
             NotificationViewHierarchyManager notificationViewHierarchyManager,
-            ForegroundServiceController foregroundServiceController,
-            AppOpsController appOpsController,
             KeyguardViewMediator keyguardViewMediator,
-            ZenModeController zenModeController,
             NotificationAlertingManager notificationAlertingManager,
             DisplayMetrics displayMetrics,
             MetricsLogger metricsLogger,
@@ -148,7 +141,6 @@
             ConfigurationController configurationController,
             StatusBarWindowController statusBarWindowController,
             StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder,
-            NotifLog notifLog,
             DozeParameters dozeParameters,
             ScrimController scrimController,
             @Nullable KeyguardLiftController keyguardLiftController,
@@ -162,7 +154,10 @@
             RemoteInputUriController remoteInputUriController,
             Optional<Divider> dividerOptional,
             LightsOutNotifController lightsOutNotifController,
-            SuperStatusBarViewFactory superStatusBarViewFactory) {
+            SuperStatusBarViewFactory superStatusBarViewFactory,
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+            ViewMediatorCallback viewMediatorCallback,
+            DismissCallbackRegistry dismissCallbackRegistry) {
         return new StatusBar(
                 context,
                 featureFlags,
@@ -170,7 +165,6 @@
                 autoHideController,
                 keyguardUpdateMonitor,
                 statusBarIconController,
-                dozeLog,
                 pulseExpansionHandler,
                 notificationWakeUpCoordinator,
                 keyguardBypassController,
@@ -188,10 +182,7 @@
                 notificationEntryManager,
                 notificationInterruptionStateProvider,
                 notificationViewHierarchyManager,
-                foregroundServiceController,
-                appOpsController,
                 keyguardViewMediator,
-                zenModeController,
                 notificationAlertingManager,
                 displayMetrics,
                 metricsLogger,
@@ -218,7 +209,6 @@
                 configurationController,
                 statusBarWindowController,
                 statusBarWindowViewControllerBuilder,
-                notifLog,
                 dozeParameters,
                 scrimController,
                 keyguardLiftController,
@@ -232,6 +222,9 @@
                 remoteInputUriController,
                 dividerOptional,
                 lightsOutNotifController,
-                superStatusBarViewFactory);
+                superStatusBarViewFactory,
+                statusBarKeyguardViewManager,
+                viewMediatorCallback,
+                dismissCallbackRegistry);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
index 768bd13..bb4387eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
@@ -41,6 +41,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.systemui.appops.AppOpsController;
 import com.android.systemui.statusbar.NotificationEntryBuilder;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -52,6 +53,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -59,12 +62,13 @@
     private ForegroundServiceController mFsc;
     private ForegroundServiceNotificationListener mListener;
     private NotificationEntryListener mEntryListener;
-    private NotificationEntryManager mEntryManager;
+    @Mock private NotificationEntryManager mEntryManager;
+    @Mock private AppOpsController mAppOpsController;
 
     @Before
     public void setUp() throws Exception {
-        mEntryManager = mock(NotificationEntryManager.class);
-        mFsc = new ForegroundServiceController(mEntryManager);
+        MockitoAnnotations.initMocks(this);
+        mFsc = new ForegroundServiceController(mEntryManager, mAppOpsController);
         mListener = new ForegroundServiceNotificationListener(
                 mContext, mFsc, mEntryManager);
         ArgumentCaptor<NotificationEntryListener> entryListenerCaptor =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index c815279..cbfcfdd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -18,14 +18,12 @@
 
 import static android.view.WindowManagerPolicyConstants.OFF_BECAUSE_OF_USER;
 
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.admin.DevicePolicyManager;
-import android.content.Context;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
@@ -34,8 +32,6 @@
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.ViewMediatorCallback;
-import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.classifier.FalsingManagerFake;
@@ -60,8 +56,8 @@
     private @Mock KeyguardUpdateMonitor mUpdateMonitor;
     private @Mock StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private @Mock StatusBarWindowController mStatusBarWindowController;
-    private @Mock SystemUIFactory mSystemUIFactory;
     private @Mock BroadcastDispatcher mBroadcastDispatcher;
+    private @Mock DismissCallbackRegistry mDismissCallbackRegistry;
 
     private FalsingManagerFake mFalsingManager;
 
@@ -76,15 +72,11 @@
                 mStatusBarWindowController);
 
         when(mLockPatternUtils.getDevicePolicyManager()).thenReturn(mDevicePolicyManager);
-        when(mSystemUIFactory.createStatusBarKeyguardViewManager(
-                any(Context.class),
-                any(ViewMediatorCallback.class),
-                any(LockPatternUtils.class))).thenReturn(mStatusBarKeyguardViewManager);
 
         TestableLooper.get(this).runWithLooper(() -> {
             mViewMediator = new KeyguardViewMediator(
                     mContext, mFalsingManager, mLockPatternUtils, mBroadcastDispatcher,
-                    mSystemUIFactory);
+                    () -> mStatusBarKeyguardViewManager, mDismissCallbackRegistry);
         });
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index b2a5109..86ef6e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -258,8 +258,7 @@
         NotificationRowBinderImpl notificationRowBinder =
                 new NotificationRowBinderImpl(mContext, true, /* allowLongPress */
                         mock(KeyguardBypassController.class),
-                        mock(StatusBarStateController.class),
-                        mock(NotifLog.class));
+                        mock(StatusBarStateController.class));
         notificationRowBinder.setUpWithPresenter(
                 mPresenter, mListContainer, mHeadsUpManager, mEntryManager, mBindCallback);
         notificationRowBinder.setNotificationClicker(mock(NotificationClicker.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
index c2d2e31..cc56949 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
@@ -30,7 +30,6 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.NotificationEntryBuilder;
@@ -60,7 +59,6 @@
 
     @Mock private NotificationEntryManager mEntryManager;
     @Mock private NotificationListContainer mListContainer;
-    @Mock private ForegroundServiceController mForegroundServiceController;
     @Mock private DeviceProvisionedController mDeviceProvisionedController;
 
     @Captor private ArgumentCaptor<NotificationEntryListener> mEntryListenerCaptor;
@@ -88,7 +86,6 @@
         mController = new NotificationListController(
                 mEntryManager,
                 mListContainer,
-                mForegroundServiceController,
                 mDeviceProvisionedController);
         mController.bind();
 
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 012ebf72..6f52e4a 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
@@ -82,6 +82,7 @@
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarTest.TestableNotificationEntryManager;
 import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.util.DeviceConfigProxyFake;
 
 import org.junit.After;
@@ -123,6 +124,7 @@
     @Mock private MetricsLogger mMetricsLogger;
     @Mock private NotificationRoundnessManager mNotificationRoundnessManager;
     @Mock private KeyguardBypassController mKeyguardBypassController;
+    @Mock private ZenModeController mZenModeController;
     private TestableNotificationEntryManager mEntryManager;
     private int mOriginalInterruptionModelSetting;
 
@@ -173,7 +175,8 @@
                 mock(NotificationLockscreenUserManager.class),
                 mock(NotificationGutsManager.class),
                 new NotificationSectionsFeatureManager(new DeviceConfigProxyFake(), mContext),
-                mock(PeopleHubSectionFooterViewAdapter.class));
+                mock(PeopleHubSectionFooterViewAdapter.class),
+                mZenModeController);
         mStackScroller = spy(mStackScrollerInternal);
         mStackScroller.setShelf(notificationShelf);
         mStackScroller.setStatusBar(mBar);
@@ -211,7 +214,7 @@
     @Test
     public void updateEmptyView_dndSuppressing() {
         when(mEmptyShadeView.willBeGone()).thenReturn(true);
-        when(mBar.areNotificationsHidden()).thenReturn(true);
+        when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(true);
 
         mStackScroller.updateEmptyShadeView(true);
 
@@ -222,7 +225,7 @@
     public void updateEmptyView_dndNotSuppressing() {
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
         when(mEmptyShadeView.willBeGone()).thenReturn(true);
-        when(mBar.areNotificationsHidden()).thenReturn(false);
+        when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(false);
 
         mStackScroller.updateEmptyShadeView(true);
 
@@ -233,11 +236,11 @@
     public void updateEmptyView_noNotificationsToDndSuppressing() {
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
         when(mEmptyShadeView.willBeGone()).thenReturn(true);
-        when(mBar.areNotificationsHidden()).thenReturn(false);
+        when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(false);
         mStackScroller.updateEmptyShadeView(true);
         verify(mEmptyShadeView).setText(R.string.empty_shade_text);
 
-        when(mBar.areNotificationsHidden()).thenReturn(true);
+        when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(true);
         mStackScroller.updateEmptyShadeView(true);
         verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 3e07cff..61e5058 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -41,12 +41,13 @@
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
+import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import org.junit.Before;
@@ -91,16 +92,21 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mDependency.injectMockDependency(StatusBarWindowController.class);
-        mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
-        mDependency.injectMockDependency(NotificationMediaManager.class);
-        mDependency.injectTestDependency(StatusBarStateController.class, mStatusBarStateController);
-        mDependency.injectTestDependency(KeyguardStateController.class, mKeyguardStateController);
         when(mLockIconContainer.getParent()).thenReturn(mock(ViewGroup.class));
         when(mLockIconContainer.animate()).thenReturn(mock(ViewPropertyAnimator.class,
                 RETURNS_DEEP_STUBS));
-        mStatusBarKeyguardViewManager = new TestableStatusBarKeyguardViewManager(getContext(),
-                mViewMediatorCallback, mLockPatternUtils);
+        mStatusBarKeyguardViewManager = new TestableStatusBarKeyguardViewManager(
+                getContext(),
+                mViewMediatorCallback,
+                mLockPatternUtils,
+                mStatusBarStateController,
+                mock(ConfigurationController.class),
+                mock(KeyguardUpdateMonitor.class),
+                mock(NavigationModeController.class),
+                mock(DockManager.class),
+                mock(StatusBarWindowController.class),
+                mKeyguardStateController,
+                mock(NotificationMediaManager.class));
         mStatusBarKeyguardViewManager.registerStatusBar(mStatusBar, mContainer,
                 mNotificationPanelView, mBiometrucUnlockController, mDismissCallbackRegistry,
                 mLockIconContainer, mNotificationContainer, mBypassController,
@@ -258,8 +264,19 @@
 
         public TestableStatusBarKeyguardViewManager(Context context,
                 ViewMediatorCallback callback,
-                LockPatternUtils lockPatternUtils) {
-            super(context, callback, lockPatternUtils);
+                LockPatternUtils lockPatternUtils,
+                SysuiStatusBarStateController sysuiStatusBarStateController,
+                ConfigurationController configurationController,
+                KeyguardUpdateMonitor keyguardUpdateMonitor,
+                NavigationModeController navigationModeController,
+                DockManager dockManager,
+                StatusBarWindowController statusBarWindowController,
+                KeyguardStateController keyguardStateController,
+                NotificationMediaManager notificationMediaManager) {
+            super(context, callback, lockPatternUtils, sysuiStatusBarStateController,
+                    configurationController, keyguardUpdateMonitor, navigationModeController,
+                    dockManager, statusBarWindowController, keyguardStateController,
+                    notificationMediaManager);
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 7d6f006..62fd0c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -74,18 +74,16 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.Dependency;
-import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.InitController;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.doze.DozeLog;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -200,13 +198,10 @@
     @Mock private AssistManager mAssistManager;
     @Mock private NotificationGutsManager mNotificationGutsManager;
     @Mock private NotificationMediaManager mNotificationMediaManager;
-    @Mock private ForegroundServiceController mForegroundServiceController;
-    @Mock private AppOpsController mAppOpsController;
     @Mock private NavigationBarController mNavigationBarController;
     @Mock private BypassHeadsUpNotifier mBypassHeadsUpNotifier;
     @Mock private SysuiColorExtractor mColorExtractor;
     @Mock private ColorExtractor.GradientColors mGradientColors;
-    @Mock private DozeLog mDozeLog;
     @Mock private PulseExpansionHandler mPulseExpansionHandler;
     @Mock private NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
     @Mock private KeyguardBypassController mKeyguardBypassController;
@@ -238,6 +233,8 @@
     @Mock private Divider mDivider;
     @Mock private SuperStatusBarViewFactory mSuperStatusBarViewFactory;
     @Mock private LightsOutNotifController mLightsOutNotifController;
+    @Mock private ViewMediatorCallback mViewMediatorCallback;
+    @Mock private DismissCallbackRegistry mDismissCallbackRegistry;
 
     @Before
     public void setup() throws Exception {
@@ -312,7 +309,6 @@
                 mAutoHideController,
                 mKeyguardUpdateMonitor,
                 mStatusBarIconController,
-                mDozeLog,
                 mPulseExpansionHandler,
                 mNotificationWakeUpCoordinator,
                 mKeyguardBypassController,
@@ -334,10 +330,7 @@
                 entryManager,
                 mNotificationInterruptionStateProvider,
                 mNotificationViewHierarchyManager,
-                mForegroundServiceController,
-                mAppOpsController,
                 mKeyguardViewMediator,
-                mZenModeController,
                 mNotificationAlertingManager,
                 new DisplayMetrics(),
                 mMetricsLogger,
@@ -364,7 +357,6 @@
                 configurationController,
                 mStatusBarWindowController,
                 mStatusBarWindowViewControllerBuilder,
-                mNotifLog,
                 mDozeParameters,
                 mScrimController,
                 mKeyguardLiftController,
@@ -378,7 +370,10 @@
                 mRemoteInputUriController,
                 Optional.of(mDivider),
                 mLightsOutNotifController,
-                mSuperStatusBarViewFactory);
+                mSuperStatusBarViewFactory,
+                mStatusBarKeyguardViewManager,
+                mViewMediatorCallback,
+                mDismissCallbackRegistry);
 
         when(mStatusBarWindowView.findViewById(R.id.lock_icon_container)).thenReturn(
                 mLockIconContainer);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index ce0e9e7..81eb4b3 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -97,6 +97,7 @@
 import android.net.NetworkPolicyManager;
 import android.net.NetworkQuotaInfo;
 import android.net.NetworkRequest;
+import android.net.NetworkScore;
 import android.net.NetworkSpecifier;
 import android.net.NetworkStack;
 import android.net.NetworkStackClient;
@@ -2643,7 +2644,8 @@
                     break;
                 }
                 case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
-                    updateNetworkScore(nai, msg.arg1);
+                    final NetworkScore ns = (NetworkScore) msg.obj;
+                    updateNetworkScore(nai, ns);
                     break;
                 }
                 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
@@ -5594,9 +5596,11 @@
         // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
         // satisfies mDefaultRequest.
         final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
+        final NetworkScore ns = new NetworkScore();
+        ns.putIntExtension(NetworkScore.LEGACY_SCORE, currentScore);
         final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
                 new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
-                currentScore, mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd,
+                ns, mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd,
                 mDnsResolver, mNMS, factorySerialNumber);
         // Make sure the network capabilities reflect what the agent info says.
         nai.setNetworkCapabilities(mixInCapabilities(nai, nc));
@@ -6729,7 +6733,8 @@
         }
     }
 
-    private void updateNetworkScore(NetworkAgentInfo nai, int score) {
+    private void updateNetworkScore(NetworkAgentInfo nai, NetworkScore ns) {
+        int score = ns.getIntExtension(NetworkScore.LEGACY_SCORE);
         if (VDBG || DDBG) log("updateNetworkScore for " + nai.name() + " to " + score);
         if (score < 0) {
             loge("updateNetworkScore for " + nai.name() + " got a negative score (" + score +
@@ -6738,7 +6743,7 @@
         }
 
         final int oldScore = nai.getCurrentScore();
-        nai.setCurrentScore(score);
+        nai.setNetworkScore(ns);
 
         rematchAllNetworksAndRequests(nai, oldScore);
 
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 96b7cb3..24a5b7f 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -28,6 +28,7 @@
 import android.net.NetworkMisc;
 import android.net.NetworkMonitorManager;
 import android.net.NetworkRequest;
+import android.net.NetworkScore;
 import android.net.NetworkState;
 import android.os.Handler;
 import android.os.INetworkManagementService;
@@ -227,8 +228,10 @@
     // validated).
     private boolean mLingering;
 
-    // This represents the last score received from the NetworkAgent.
-    private int currentScore;
+    // This represents the characteristics of a network that affects how good the network is
+    // considered for a particular use.
+    @NonNull
+    private NetworkScore mNetworkScore;
 
     // The list of NetworkRequests being satisfied by this Network.
     private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>();
@@ -257,8 +260,8 @@
     private final Handler mHandler;
 
     public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info,
-            LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler,
-            NetworkMisc misc, ConnectivityService connService, INetd netd,
+            LinkProperties lp, NetworkCapabilities nc, @NonNull NetworkScore ns, Context context,
+            Handler handler, NetworkMisc misc, ConnectivityService connService, INetd netd,
             IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber) {
         this.messenger = messenger;
         asyncChannel = ac;
@@ -266,7 +269,7 @@
         networkInfo = info;
         linkProperties = lp;
         networkCapabilities = nc;
-        currentScore = score;
+        mNetworkScore = ns;
         clatd = new Nat464Xlat(this, netd, dnsResolver, nms);
         mConnService = connService;
         mContext = context;
@@ -483,7 +486,7 @@
             return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE;
         }
 
-        int score = currentScore;
+        int score = mNetworkScore.getIntExtension(NetworkScore.LEGACY_SCORE);
         if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty() && !isVPN()) {
             score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY;
         }
@@ -512,8 +515,13 @@
         return getCurrentScore(true);
     }
 
-    public void setCurrentScore(int newScore) {
-        currentScore = newScore;
+    public void setNetworkScore(@NonNull NetworkScore ns) {
+        mNetworkScore = ns;
+    }
+
+    @NonNull
+    public NetworkScore getNetworkScore() {
+        return mNetworkScore;
     }
 
     public NetworkState getNetworkState() {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 15e76fb..3c49afb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -19764,6 +19764,23 @@
     }
 
     @Override
+    public String getContentCaptureServicePackageName() {
+        final String flattenedContentCaptureService =
+                mContext.getString(R.string.config_defaultContentCaptureService);
+
+        if (TextUtils.isEmpty(flattenedContentCaptureService)) {
+            return null;
+        }
+
+        final ComponentName contentCaptureServiceComponentName =
+                ComponentName.unflattenFromString(flattenedContentCaptureService);
+        if (contentCaptureServiceComponentName == null) {
+            return null;
+        }
+        return contentCaptureServiceComponentName.getPackageName();
+    }
+
+    @Override
     public void setApplicationEnabledSetting(String appPackageName,
             int newState, int flags, int userId, String callingPackage) {
         if (!mUserManager.exists(userId)) return;
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index f1c84b8..cc443cb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -115,6 +115,7 @@
 import java.io.PrintWriter;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.LinkedList;
@@ -438,8 +439,14 @@
         }
     }
 
-    private void setParamsSize(InstallParams params, String inPath) {
-        if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) {
+    private void setParamsSize(InstallParams params, List<String> inPaths) {
+        if (params.sessionParams.sizeBytes != -1 || STDIN_PATH.equals(inPaths.get(0))) {
+            return;
+        }
+
+        long sessionSize = 0;
+
+        for (String inPath : inPaths) {
             final ParcelFileDescriptor fd = openFileForSystem(inPath, "r");
             if (fd == null) {
                 getErrPrintWriter().println("Error: Can't open file: " + inPath);
@@ -449,8 +456,8 @@
                 ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0);
                 PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
                         null, null);
-                params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
-                        pkgLite, params.sessionParams.abiOverride, fd.getFileDescriptor()));
+                sessionSize += PackageHelper.calculateInstalledSize(pkgLite,
+                        params.sessionParams.abiOverride, fd.getFileDescriptor());
             } catch (PackageParserException | IOException e) {
                 getErrPrintWriter().println("Error: Failed to parse APK file: " + inPath);
                 throw new IllegalArgumentException(
@@ -462,6 +469,7 @@
                 }
             }
         }
+        params.sessionParams.setSize(sessionSize);
     }
     /**
      * Displays the package file for a package.
@@ -1148,23 +1156,45 @@
     private int runInstall() throws RemoteException {
         final PrintWriter pw = getOutPrintWriter();
         final InstallParams params = makeInstallParams();
-        final String inPath = getNextArg();
 
-        setParamsSize(params, inPath);
+        ArrayList<String> inPaths = getRemainingArgs();
+        if (inPaths.isEmpty()) {
+            pw.println("Error: must either specify APK files or '-' to read from stdin");
+            return 1;
+        }
+
+        final boolean hasSplits = inPaths.size() > 1;
+
+        if (STDIN_PATH.equals(inPaths.get(0))) {
+            if (hasSplits) {
+                pw.println("Error: can't specify SPLIT(s) along with '-'");
+                return 1;
+            }
+            if (params.sessionParams.sizeBytes == -1) {
+                pw.println("Error: must either specify a package size or an APK file");
+                return 1;
+            }
+        }
+
+        final boolean isApex =
+                (params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0;
+        if (isApex && hasSplits) {
+            pw.println("Error: can't specify SPLIT(s) for APEX");
+            return 1;
+        }
+
+        setParamsSize(params, inPaths);
         final int sessionId = doCreateSession(params.sessionParams,
                 params.installerPackageName, params.userId);
         boolean abandonSession = true;
         try {
-            if (inPath == null && params.sessionParams.sizeBytes == -1) {
-                pw.println("Error: must either specify a package size or an APK file");
-                return 1;
-            }
-            final boolean isApex =
-                    (params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0;
-            String splitName = "base." + (isApex ? "apex" : "apk");
-            if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, splitName,
-                    false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
-                return 1;
+            for (String inPath : inPaths) {
+                String splitName = hasSplits ? (new File(inPath)).getName()
+                        : "base." + (isApex ? "apex" : "apk");
+                if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, splitName,
+                        false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
+                    return 1;
+                }
             }
             if (doCommitSession(sessionId, false /*logSuccess*/)
                     != PackageInstaller.STATUS_SUCCESS) {
@@ -1283,12 +1313,12 @@
 
         final int sessionId = Integer.parseInt(getNextArg());
 
-        final String splitName = getNextArg();
-        if (splitName == null) {
+        ArrayList<String> splitNames = getRemainingArgs();
+        if (splitNames.isEmpty()) {
             pw.println("Error: split name not specified");
             return 1;
         }
-        return doRemoveSplit(sessionId, splitName, true /*logSuccess*/);
+        return doRemoveSplits(sessionId, splitNames, true /*logSuccess*/);
     }
 
     private int runInstallExisting() throws RemoteException {
@@ -1731,6 +1761,15 @@
         return 0;
     }
 
+    private ArrayList<String> getRemainingArgs() {
+        ArrayList<String> args = new ArrayList<>();
+        String arg;
+        while ((arg = getNextArg()) != null) {
+            args.add(arg);
+        }
+        return args;
+    }
+
     private static class SnapshotRuntimeProfileCallback
             extends ISnapshotRuntimeProfileCallback.Stub {
         private boolean mSuccess = false;
@@ -1802,9 +1841,9 @@
         }
 
         // if a split is specified, just remove it and not the whole package
-        final String splitName = getNextArg();
-        if (splitName != null) {
-            return runRemoveSplit(packageName, splitName);
+        ArrayList<String> splitNames = getRemainingArgs();
+        if (!splitNames.isEmpty()) {
+            return runRemoveSplits(packageName, splitNames);
         }
 
         userId = translateUserId(userId, true /*allowAll*/, "runUninstall");
@@ -1852,7 +1891,8 @@
         }
     }
 
-    private int runRemoveSplit(String packageName, String splitName) throws RemoteException {
+    private int runRemoveSplits(String packageName, Collection<String> splitNames)
+            throws RemoteException {
         final PrintWriter pw = getOutPrintWriter();
         final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
         sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
@@ -1861,7 +1901,7 @@
                 doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL);
         boolean abandonSession = true;
         try {
-            if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/)
+            if (doRemoveSplits(sessionId, splitNames, false /*logSuccess*/)
                     != PackageInstaller.STATUS_SUCCESS) {
                 return 1;
             }
@@ -2945,14 +2985,17 @@
         }
     }
 
-    private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess)
+    private int doRemoveSplits(int sessionId, Collection<String> splitNames, boolean logSuccess)
             throws RemoteException {
         final PrintWriter pw = getOutPrintWriter();
         PackageInstaller.Session session = null;
         try {
             session = new PackageInstaller.Session(
                     mInterface.getPackageInstaller().openSession(sessionId));
-            session.removeSplit(splitName);
+
+            for (String splitName : splitNames) {
+                session.removeSplit(splitName);
+            }
 
             if (logSuccess) {
                 pw.println("Success");
@@ -3237,9 +3280,9 @@
         pw.println("       [--enable-rollback]");
         pw.println("       [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
         pw.println("       [--apex] [--wait TIMEOUT]");
-        pw.println("       [PATH|-]");
-        pw.println("    Install an application.  Must provide the apk data to install, either as a");
-        pw.println("    file path or '-' to read from stdin.  Options are:");
+        pw.println("       [PATH [SPLIT...]|-]");
+        pw.println("    Install an application.  Must provide the apk data to install, either as");
+        pw.println("    file path(s) or '-' to read from stdin.  Options are:");
         pw.println("      -R: disallow replacement of existing application");
         pw.println("      -t: allow test packages");
         pw.println("      -i: specify package name of installer owning the app");
@@ -3293,6 +3336,9 @@
         pw.println("    will be read from stdin.  Options are:");
         pw.println("      -S: size in bytes of package, required for stdin");
         pw.println("");
+        pw.println("  install-remove SESSION_ID SPLIT...");
+        pw.println("    Mark SPLIT(s) as removed in the given install session.");
+        pw.println("");
         pw.println("  install-add-session MULTI_PACKAGE_SESSION_ID CHILD_SESSION_IDs");
         pw.println("    Add one or more session IDs to a multi-package session.");
         pw.println("");
@@ -3317,9 +3363,10 @@
         pw.println("");
         pw.println("  move-primary-storage [internal|UUID]");
         pw.println("");
-        pw.println("  pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE [SPLIT]");
+        pw.println("  uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE]");
+        pw.println("       PACKAGE [SPLIT...]");
         pw.println("    Remove the given package name from the system.  May remove an entire app");
-        pw.println("    if no SPLIT name is specified, otherwise will remove only the split of the");
+        pw.println("    if no SPLIT names specified, otherwise will remove only the splits of the");
         pw.println("    given app.  Options are:");
         pw.println("      -k: keep the data and cache directories around after package removal.");
         pw.println("      --user: remove the app from the given user.");
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index f247037..603b01a 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -150,6 +150,12 @@
         ALWAYS_LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION);
     }
 
+    private static final Set<String> COARSE_BACKGROUND_LOCATION_PERMISSIONS = new ArraySet<>();
+    static {
+        COARSE_BACKGROUND_LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_COARSE_LOCATION);
+        COARSE_BACKGROUND_LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION);
+    }
+
     private static final Set<String> ACTIVITY_RECOGNITION_PERMISSIONS = new ArraySet<>();
     static {
         ACTIVITY_RECOGNITION_PERMISSIONS.add(Manifest.permission.ACTIVITY_RECOGNITION);
@@ -724,8 +730,16 @@
                 mContext.getPackageManager().getSystemTextClassifierPackageName();
         if (!TextUtils.isEmpty(textClassifierPackageName)) {
             grantPermissionsToSystemPackage(textClassifierPackageName, userId,
-                    PHONE_PERMISSIONS, SMS_PERMISSIONS, CALENDAR_PERMISSIONS,
-                    ALWAYS_LOCATION_PERMISSIONS, CONTACTS_PERMISSIONS);
+                    COARSE_BACKGROUND_LOCATION_PERMISSIONS, CONTACTS_PERMISSIONS);
+        }
+
+        // Content capture
+        String contentCapturePackageName =
+                mContext.getPackageManager().getContentCaptureServicePackageName();
+        if (!TextUtils.isEmpty(contentCapturePackageName)) {
+            grantPermissionsToSystemPackage(contentCapturePackageName, userId,
+                    PHONE_PERMISSIONS, SMS_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS,
+                    CONTACTS_PERMISSIONS);
         }
 
         // Atthention Service
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 3cc6428..dd561e1 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -77,6 +77,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.UserManagerInternal;
 import android.os.storage.StorageManager;
 import android.service.wallpaper.IWallpaperConnection;
 import android.service.wallpaper.IWallpaperEngine;
@@ -2818,12 +2819,19 @@
             return false;   // callingPackage was faked.
         }
 
+        // TODO(b/144048540): DPM needs to take into account the userId, not just the package.
         final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
         if (dpm.isDeviceOwnerApp(callingPackage) || dpm.isProfileOwnerApp(callingPackage)) {
             return true;
         }
-        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        return !um.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER);
+        final int callingUserId = UserHandle.getCallingUserId();
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
+            return !umi.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER, callingUserId);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 7df1c15..99659b0 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -149,6 +149,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.os.logging.MetricsLoggerWrapper;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityManagerService;
@@ -789,14 +790,6 @@
                 return;
             }
 
-            if (windowingMode == WINDOWING_MODE_PINNED || currentMode == WINDOWING_MODE_PINNED) {
-                // TODO: Need to remove use of PinnedActivityStack for this to be supported.
-                // NOTE: Need to ASS.scheduleUpdatePictureInPictureModeIfNeeded() in
-                // setWindowModeUnchecked() when this support is added. See TaskRecord.reparent()
-                throw new IllegalArgumentException(
-                        "Changing pinned windowing mode not currently supported");
-            }
-
             if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && splitScreenStack != null) {
                 // We already have a split-screen stack in this display, so just move the tasks over.
                 // TODO: Figure-out how to do all the stuff in
@@ -4915,7 +4908,7 @@
                 // The final orientation of this activity will change after moving to full screen.
                 // Start freezing screen here to prevent showing a temporary full screen window.
                 top.startFreezingScreenLocked(CONFIG_SCREEN_LAYOUT);
-                mService.moveTasksToFullscreenStack(mStackId, true /* onTop */);
+                dismissPip();
                 return;
             }
         }
@@ -4924,6 +4917,34 @@
                 animationDuration, fromFullscreen);
     }
 
+    void dismissPip() {
+        if (!isActivityTypeStandardOrUndefined()) {
+            throw new IllegalArgumentException(
+                    "You can't move tasks from non-standard stacks.");
+        }
+        if (getWindowingMode() != WINDOWING_MODE_PINNED) {
+            throw new IllegalArgumentException(
+                    "Can't exit pinned mode if it's not pinned already.");
+        }
+
+        final ArrayList<TaskRecord> tasks = getAllTasks();
+
+        if (tasks.size() != 1) {
+            throw new RuntimeException("There should be only one task in a pinned stack.");
+        }
+
+        mWindowManager.inSurfaceTransaction(() -> {
+            final TaskRecord task = tasks.get(0);
+            setWindowingMode(WINDOWING_MODE_UNDEFINED);
+
+            getDisplay().positionChildAtTop(this, false /* includingParents */);
+
+            mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, this);
+            MetricsLoggerWrapper.logPictureInPictureFullScreen(mService.mContext,
+                    task.effectiveUid, task.realActivity.flattenToString());
+        });
+    }
+
     /**
      * Get current bounds of this stack, return empty when it is unavailable.
      * @see TaskStack#getAnimationOrCurrentBounds(Rect)
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index f8a7397..5f1c001 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -1499,7 +1499,6 @@
         mService.deferWindowLayout();
         try {
             final int windowingMode = fromStack.getWindowingMode();
-            final boolean inPinnedWindowingMode = windowingMode == WINDOWING_MODE_PINNED;
             final ActivityDisplay toDisplay =
                     mRootActivityContainer.getActivityDisplay(toDisplayId);
 
@@ -1526,7 +1525,8 @@
 
             // If we are moving from the pinned stack, then the animation takes care of updating
             // the picture-in-picture mode.
-            final boolean schedulePictureInPictureModeChange = inPinnedWindowingMode;
+            final boolean schedulePictureInPictureModeChange =
+                    windowingMode == WINDOWING_MODE_PINNED;
             final ArrayList<TaskRecord> tasks = fromStack.getAllTasks();
 
             if (!tasks.isEmpty()) {
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 6edcb02..77165f2 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1477,10 +1477,8 @@
 
         mIntent.setFlags(mLaunchFlags);
 
-        ActivityRecord reusedActivity = getReusableIntentActivity();
-
-        mSupervisor.getLaunchParamsController().calculate(
-                reusedActivity != null ? reusedActivity.getTaskRecord() : mInTask,
+        final TaskRecord reusedTask = getReusableTask();
+        mSupervisor.getLaunchParamsController().calculate(reusedTask != null ? reusedTask : mInTask,
                 r.info.windowLayout, r, sourceRecord, options, PHASE_BOUNDS, mLaunchParams);
         mPreferredDisplayId =
                 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
@@ -1495,7 +1493,7 @@
         }
 
         // Compute if there is an existing task that should be used for.
-        final TaskRecord targetTask = computeTargetTask(reusedActivity);
+        final TaskRecord targetTask = reusedTask != null ? reusedTask : computeTargetTask();
         final boolean newTask = targetTask == null;
 
         // Check if starting activity on given task or on a new task is allowed.
@@ -1507,10 +1505,12 @@
         final ActivityRecord targetTaskTop = newTask ? null : targetTask.getTopActivity();
         if (targetTaskTop != null) {
             // Recycle the target task for this launch.
-            startResult = recycleTask(targetTask, targetTaskTop, reusedActivity);
+            startResult = recycleTask(targetTask, targetTaskTop, reusedTask);
             if (startResult != START_SUCCESS) {
                 return startResult;
             }
+        } else {
+            mAddingToTask = true;
         }
 
         // If the activity being launched is the same as the one currently at the top, then
@@ -1601,10 +1601,8 @@
         return START_SUCCESS;
     }
 
-    private TaskRecord computeTargetTask(ActivityRecord reusedActivity) {
-        if (reusedActivity != null) {
-            return reusedActivity.getTaskRecord();
-        } else if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
+    private TaskRecord computeTargetTask() {
+        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
             // A new task should be created instead of using existing one.
             return null;
@@ -1669,7 +1667,7 @@
      * - Determine whether need to add a new activity on top or just brought the task to front.
      */
     private int recycleTask(TaskRecord targetTask, ActivityRecord targetTaskTop,
-            ActivityRecord reusedActivity) {
+            TaskRecord reusedTask) {
         // True if we are clearing top and resetting of a standard (default) launch mode
         // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
         final boolean clearTopAndResetStandardLaunchMode =
@@ -1678,12 +1676,12 @@
                         && mLaunchMode == LAUNCH_MULTIPLE;
 
         boolean clearTaskForReuse = false;
-        if (reusedActivity != null) {
+        if (reusedTask != null) {
             // If mStartActivity does not have a task associated with it, associate it with the
             // reused activity's task. Do not do so if we're clearing top and resetting for a
             // standard launchMode activity.
             if (mStartActivity.getTaskRecord() == null && !clearTopAndResetStandardLaunchMode) {
-                mStartActivity.setTaskForReuse(reusedActivity.getTaskRecord());
+                mStartActivity.setTaskForReuse(reusedTask);
                 clearTaskForReuse = true;
             }
 
@@ -1730,7 +1728,7 @@
             return START_RETURN_INTENT_TO_CALLER;
         }
 
-        complyActivityFlags(targetTask, reusedActivity);
+        complyActivityFlags(targetTask, reusedTask != null ? reusedTask.getTopActivity() : null);
 
         if (clearTaskForReuse) {
             // Clear task for re-use so later code to methods
@@ -2223,7 +2221,7 @@
      * Decide whether the new activity should be inserted into an existing task. Returns null
      * if not or an ActivityRecord with the task into which the new activity should be added.
      */
-    private ActivityRecord getReusableIntentActivity() {
+    private TaskRecord getReusableTask() {
         // We may want to try to place the new activity in to an existing task.  We always
         // do this if the target activity is singleTask or singleInstance; we will also do
         // this if NEW_TASK has been requested, and there is not an additional qualifier telling
@@ -2238,8 +2236,10 @@
         putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
         ActivityRecord intentActivity = null;
         if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
-            final TaskRecord task = mRootActivityContainer.anyTaskForId(mOptions.getLaunchTaskId());
-            intentActivity = task != null ? task.getTopActivity() : null;
+            TaskRecord launchTask = mRootActivityContainer.anyTaskForId(mOptions.getLaunchTaskId());
+            if (launchTask != null) {
+                return launchTask;
+            }
         } else if (putIntoExistingTask) {
             if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
                 // There can be one and only one instance of single instance activity in the
@@ -2265,7 +2265,7 @@
             intentActivity = null;
         }
 
-        return intentActivity;
+        return intentActivity != null ? intentActivity.getTaskRecord() : null;
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index a683ccb..80232d3 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2945,7 +2945,6 @@
                 r.setTaskDescription(td);
                 final TaskRecord task = r.getTaskRecord();
                 task.updateTaskDescription();
-                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.getTaskInfo());
             }
         }
     }
@@ -4001,7 +4000,7 @@
                     stack.animateResizePinnedStack(null /* sourceHintBounds */,
                             null /* destBounds */, animationDuration, false /* fromFullscreen */);
                 } else {
-                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
+                    stack.dismissPip();
                 }
             }
         } finally {
@@ -4017,11 +4016,6 @@
         }
     }
 
-    /**
-     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
-     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
-     *       activity and clearing the task at the same time.
-     */
     @Override
     // TODO: API should just be about changing windowing modes...
     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index df40419..3eef749 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -48,7 +48,6 @@
 import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
 import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
 import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
-import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
 import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
 import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
@@ -965,30 +964,29 @@
         mService.deferWindowLayout();
 
         final ActivityDisplay display = r.getActivityStack().getDisplay();
-        ActivityStack stack = display.getPinnedStack();
-
-        // This will clear the pinned stack by moving an existing task to the full screen stack,
-        // ensuring only one task is present.
-        if (stack != null) {
-            mStackSupervisor.moveTasksToFullscreenStackLocked(stack, !ON_TOP);
-        }
-
-        // Need to make sure the pinned stack exist so we can resize it below...
-        stack = display.getOrCreateStack(WINDOWING_MODE_PINNED, r.getActivityType(), ON_TOP);
 
         try {
             final TaskRecord task = r.getTaskRecord();
-            // Resize the pinned stack to match the current size of the task the activity we are
-            // going to be moving is currently contained in. We do this to have the right starting
-            // animation bounds for the pinned stack to the desired bounds the caller wants.
-            stack.resize(task.getRequestedOverrideBounds(), null /* tempTaskBounds */,
-                    null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, !DEFER_RESUME);
 
-            if (task.getChildCount() == 1) {
-                // Defer resume until below, and do not schedule PiP changes until we animate below
-                task.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE, DEFER_RESUME,
-                        false /* schedulePictureInPictureModeChange */, reason);
+            final ActivityStack pinnedStack = display.getPinnedStack();
+            // This will change the pinned stack's windowing mode to its original mode, ensuring
+            // we only have one stack that is in pinned mode.
+            if (pinnedStack != null) {
+                pinnedStack.dismissPip();
+            }
+
+            final boolean singleActivity = task.getChildCount() == 1;
+
+            final ActivityStack stack;
+            if (singleActivity) {
+                stack = r.getActivityStack();
             } else {
+                // In the case of multiple activities, we will create a new stack for it and then
+                // move the PIP activity into the stack.
+                // We will then perform a windowing mode change for both scenarios.
+                stack = display.createStack(
+                        r.getActivityStack().getRequestedOverrideWindowingMode(),
+                        r.getActivityType(), ON_TOP);
                 // There are multiple activities in the task and moving the top activity should
                 // reveal/leave the other activities in their original task.
 
@@ -1007,6 +1005,8 @@
                         DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
             }
 
+            stack.setWindowingMode(WINDOWING_MODE_PINNED);
+
             // Reset the state that indicates it can enter PiP while pausing after we've moved it
             // to the pinned stack
             r.supportsEnterPipOnTaskSwitch = false;
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 56f4d32..2975d0a 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -424,6 +424,7 @@
         mResizeMode = resizeMode;
         mAtmService.mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
         mAtmService.mRootActivityContainer.resumeFocusedStacksTopActivities();
+        updateTaskDescription();
     }
 
     boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
@@ -791,7 +792,10 @@
         } else {
             autoRemoveRecents = false;
         }
-        mResizeMode = info.resizeMode;
+        if (mResizeMode != info.resizeMode) {
+            mResizeMode = info.resizeMode;
+            updateTaskDescription();
+        }
         mSupportsPictureInPicture = info.supportsPictureInPicture();
     }
 
@@ -1550,12 +1554,15 @@
             }
             final TaskDescription taskDescription = new TaskDescription(label, null, iconResource,
                     iconFilename, colorPrimary, colorBackground, statusBarColor, navigationBarColor,
-                    statusBarContrastWhenTransparent, navigationBarContrastWhenTransparent);
+                    statusBarContrastWhenTransparent, navigationBarContrastWhenTransparent,
+                    mResizeMode, mMinWidth, mMinHeight);
             setTaskDescription(taskDescription);
             // Update the task affiliation color if we are the parent of the group
             if (mTaskId == mAffiliatedTaskId) {
                 mAffiliatedTaskColor = taskDescription.getPrimaryColor();
             }
+            mAtmService.getTaskChangeNotificationController().notifyTaskDescriptionChanged(
+                    getTaskInfo());
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index e82525a..95a908f 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -1571,7 +1571,7 @@
 
             mActivityStack.mService.notifyPinnedStackAnimationEnded();
             if (moveToFullscreen) {
-                mActivityStack.mService.moveTasksToFullscreenStack(mStackId, true /* onTop */);
+                mActivityStack.dismissPip();
             }
         } else {
             // No PiP animation, just run the normal animation-end logic
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index 51bea1f..3726228 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -67,7 +67,11 @@
     Return<bool> supportsAmplitudeControl() override {
         int32_t cap = 0;
         if (!mVib->getCapabilities(&cap).isOk()) return false;
-        return (cap & aidl::IVibrator::CAP_AMPLITUDE_CONTROL) > 0;
+        if (mUnderExternalControl) {
+           return (cap & aidl::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0;
+        } else {
+           return (cap & aidl::IVibrator::CAP_AMPLITUDE_CONTROL) > 0;
+        }
     }
 
     Return<V1_0::Status> setAmplitude(uint8_t amplitude) override {
@@ -96,7 +100,11 @@
     }
 
     Return<V1_0::Status> setExternalControl(bool enabled) override {
-        return toHidlStatus(mVib->setExternalControl(enabled));
+        Return<V1_0::Status> status = toHidlStatus(mVib->setExternalControl(enabled));
+        if (status.isOk() && status == V1_0::Status::OK) {
+            mUnderExternalControl = enabled;
+        }
+        return status;
     }
 
     Return<void> perform_1_3(V1_3::Effect effect, V1_0::EffectStrength strength,
@@ -167,6 +175,7 @@
     }
   private:
     sp<aidl::IVibrator> mVib;
+    bool mUnderExternalControl = false;
 
     Return<V1_0::Status> toHidlStatus(const android::binder::Status& status) {
         switch(status.exceptionCode()) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 63f70c0..e0e9a58 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -114,16 +114,15 @@
     public void testReplacingTaskInPinnedStack() {
         final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
                 .setStack(mFullscreenStack).build();
-        final TaskRecord firstTask = firstActivity.getTaskRecord();
+        final TaskRecord task = firstActivity.getTaskRecord();
 
-        final ActivityRecord secondActivity = new ActivityBuilder(mService).setCreateTask(true)
+        final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(task)
                 .setStack(mFullscreenStack).build();
-        final TaskRecord secondTask = secondActivity.getTaskRecord();
 
         mFullscreenStack.moveToFront("testReplacingTaskInPinnedStack");
 
         // Ensure full screen stack has both tasks.
-        ensureStackPlacement(mFullscreenStack, firstTask, secondTask);
+        ensureStackPlacement(mFullscreenStack, firstActivity, secondActivity);
 
         // Move first activity to pinned stack.
         final Rect sourceBounds = new Rect();
@@ -133,8 +132,8 @@
         final ActivityDisplay display = mFullscreenStack.getDisplay();
         ActivityStack pinnedStack = display.getPinnedStack();
         // Ensure a task has moved over.
-        ensureStackPlacement(pinnedStack, firstTask);
-        ensureStackPlacement(mFullscreenStack, secondTask);
+        ensureStackPlacement(pinnedStack, firstActivity);
+        ensureStackPlacement(mFullscreenStack, secondActivity);
 
         // Move second activity to pinned stack.
         mRootActivityContainer.moveActivityToPinnedStack(secondActivity, sourceBounds,
@@ -144,21 +143,27 @@
         pinnedStack = display.getPinnedStack();
         mFullscreenStack = display.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         // Ensure stacks have swapped tasks.
-        ensureStackPlacement(pinnedStack, secondTask);
-        ensureStackPlacement(mFullscreenStack, firstTask);
+        ensureStackPlacement(pinnedStack, secondActivity);
+        ensureStackPlacement(mFullscreenStack, firstActivity);
     }
 
-    private static void ensureStackPlacement(ActivityStack stack, TaskRecord... tasks) {
-        final ArrayList<TaskRecord> stackTasks = stack.getAllTasks();
-        assertEquals("Expecting " + Arrays.deepToString(tasks) + " got " + stackTasks,
-                stackTasks.size(), tasks != null ? tasks.length : 0);
+    private static void ensureStackPlacement(ActivityStack stack, ActivityRecord... activities) {
+        final TaskRecord task = stack.getAllTasks().get(0);
+        final ArrayList<ActivityRecord> stackActivities = new ArrayList<>();
 
-        if (tasks == null) {
+        for (int i = 0; i < task.getChildCount(); i++) {
+            stackActivities.add(task.getChildAt(i));
+        }
+
+        assertEquals("Expecting " + Arrays.deepToString(activities) + " got " + stackActivities,
+                stackActivities.size(), activities != null ? activities.length : 0);
+
+        if (activities == null) {
             return;
         }
 
-        for (TaskRecord task : tasks) {
-            assertTrue(stackTasks.contains(task));
+        for (ActivityRecord activity : activities) {
+            assertTrue(stackActivities.contains(activity));
         }
     }
 
diff --git a/telephony/java/android/telephony/CallerInfo.java b/telecomm/java/android/telecom/CallerInfo.java
similarity index 91%
rename from telephony/java/android/telephony/CallerInfo.java
rename to telecomm/java/android/telecom/CallerInfo.java
index f87ac50..a5d25e2 100644
--- a/telephony/java/android/telephony/CallerInfo.java
+++ b/telecomm/java/android/telecom/CallerInfo.java
@@ -14,10 +14,9 @@
  * limitations under the License.
  */
 
-package android.telephony;
+package android.telecom;
 
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -33,8 +32,10 @@
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.PhoneLookup;
 import android.provider.ContactsContract.RawContacts;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
-import android.util.Log;
 
 import com.android.i18n.phonenumbers.NumberParseException;
 import com.android.i18n.phonenumbers.PhoneNumberUtil;
@@ -50,10 +51,9 @@
  *
  * {@hide}
  */
-@SystemApi
 public class CallerInfo {
     private static final String TAG = "CallerInfo";
-    private static final boolean VDBG = Rlog.isLoggable(TAG, Log.VERBOSE);
+    private static final boolean VDBG = Log.VERBOSE;
 
     /** @hide */
     public static final long USER_TYPE_CURRENT = 0;
@@ -215,7 +215,7 @@
         info.contactExists = false;
         info.userType = USER_TYPE_CURRENT;
 
-        if (VDBG) Rlog.v(TAG, "getCallerInfo() based on cursor...");
+        if (VDBG) Log.v(TAG, "getCallerInfo() based on cursor...");
 
         if (cursor != null) {
             if (cursor.moveToFirst()) {
@@ -263,7 +263,7 @@
                     if (contactId != 0 && !Contacts.isEnterpriseContactId(contactId)) {
                         info.contactIdOrZero = contactId;
                         if (VDBG) {
-                            Rlog.v(TAG, "==> got info.contactIdOrZero: " + info.contactIdOrZero);
+                            Log.v(TAG, "==> got info.contactIdOrZero: " + info.contactIdOrZero);
                         }
                     }
                     if (Contacts.isEnterpriseContactId(contactId)) {
@@ -271,7 +271,7 @@
                     }
                 } else {
                     // No valid columnIndex, so we can't look up person_id.
-                    Rlog.w(TAG, "Couldn't find contact_id column for " + contactRef);
+                    Log.w(TAG, "Couldn't find contact_id column for " + contactRef);
                     // Watch out: this means that anything that depends on
                     // person_id will be broken (like contact photo lookups in
                     // the in-call UI, for example.)
@@ -356,7 +356,7 @@
                 info = getCallerInfo(context, contactRef,
                         cr.query(contactRef, null, null, null, null));
             } catch (RuntimeException re) {
-                Rlog.e(TAG, "Error getting caller info.", re);
+                Log.e(TAG, re, "Error getting caller info.");
             }
         }
         return info;
@@ -376,7 +376,7 @@
      */
     @UnsupportedAppUsage
     public static CallerInfo getCallerInfo(Context context, String number) {
-        if (VDBG) Rlog.v(TAG, "getCallerInfo() based on number...");
+        if (VDBG) Log.v(TAG, "getCallerInfo() based on number...");
 
         int subId = SubscriptionManager.getDefaultSubscriptionId();
         return getCallerInfo(context, number, subId);
@@ -407,8 +407,8 @@
         // shortcut and skip the query.
         if (PhoneNumberUtils.isLocalEmergencyNumber(context, number)) {
             return new CallerInfo().markAsEmergency(context);
-        } else if (PhoneNumberUtils.isVoiceMailNumber(subId, number)) {
-            return new CallerInfo().markAsVoiceMail();
+        } else if (PhoneNumberUtils.isVoiceMailNumber(null, subId, number)) {
+            return new CallerInfo().markAsVoiceMail(context, subId);
         }
 
         Uri contactUri = Uri.withAppendedPath(PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI,
@@ -542,36 +542,20 @@
     }
 
 
-    /**
-     * Mark this CallerInfo as a voicemail call. The voicemail label
-     * is obtained from the telephony manager. Caller must hold the
-     * READ_PHONE_STATE permission otherwise the phoneNumber will be
-     * set to null.
-     * @return this instance.
-     */
-    // TODO: As in the emergency number handling, we end up writing a
-    // string in the phone number field.
-    /* package */ CallerInfo markAsVoiceMail() {
-
-        int subId = SubscriptionManager.getDefaultSubscriptionId();
-        return markAsVoiceMail(subId);
-
-    }
-
-    /* package */ CallerInfo markAsVoiceMail(int subId) {
+    /* package */ CallerInfo markAsVoiceMail(Context context, int subId) {
         mIsVoiceMail = true;
 
         try {
-            String voiceMailLabel = TelephonyManager.getDefault().getVoiceMailAlphaTag(subId);
-
-            phoneNumber = voiceMailLabel;
+            phoneNumber = context.getSystemService(TelephonyManager.class)
+                    .createForSubscriptionId(subId)
+                    .getVoiceMailAlphaTag();
         } catch (SecurityException se) {
             // Should never happen: if this process does not have
             // permission to retrieve VM tag, it should not have
             // permission to retrieve VM number and would not call
             // this method.
             // Leave phoneNumber untouched.
-            Rlog.e(TAG, "Cannot access VoiceMail.", se);
+            Log.e(TAG, se, "Cannot access VoiceMail.");
         }
         // TODO: There is no voicemail picture?
         // FIXME: FIND ANOTHER ICON
@@ -630,10 +614,10 @@
         // So instead, figure out the column to use for person_id by just
         // looking at the URI itself.
 
-        if (VDBG) Rlog.v(TAG, "- getColumnIndexForPersonId: contactRef URI = '"
+        if (VDBG) Log.v(TAG, "- getColumnIndexForPersonId: contactRef URI = '"
                         + contactRef + "'...");
         // Warning: Do not enable the following logging (due to ANR risk.)
-        // if (VDBG) Rlog.v(TAG, "- MIME type: "
+        // if (VDBG) Log.v(TAG, "- MIME type: "
         //                 + context.getContentResolver().getType(contactRef));
 
         String url = contactRef.toString();
@@ -641,25 +625,25 @@
         if (url.startsWith("content://com.android.contacts/data/phones")) {
             // Direct lookup in the Phone table.
             // MIME type: Phone.CONTENT_ITEM_TYPE (= "vnd.android.cursor.item/phone_v2")
-            if (VDBG) Rlog.v(TAG, "'data/phones' URI; using RawContacts.CONTACT_ID");
+            if (VDBG) Log.v(TAG, "'data/phones' URI; using RawContacts.CONTACT_ID");
             columnName = RawContacts.CONTACT_ID;
         } else if (url.startsWith("content://com.android.contacts/data")) {
             // Direct lookup in the Data table.
             // MIME type: Data.CONTENT_TYPE (= "vnd.android.cursor.dir/data")
-            if (VDBG) Rlog.v(TAG, "'data' URI; using Data.CONTACT_ID");
+            if (VDBG) Log.v(TAG, "'data' URI; using Data.CONTACT_ID");
             // (Note Data.CONTACT_ID and RawContacts.CONTACT_ID are equivalent.)
             columnName = Data.CONTACT_ID;
         } else if (url.startsWith("content://com.android.contacts/phone_lookup")) {
             // Lookup in the PhoneLookup table, which provides "fuzzy matching"
             // for phone numbers.
             // MIME type: PhoneLookup.CONTENT_TYPE (= "vnd.android.cursor.dir/phone_lookup")
-            if (VDBG) Rlog.v(TAG, "'phone_lookup' URI; using PhoneLookup._ID");
+            if (VDBG) Log.v(TAG, "'phone_lookup' URI; using PhoneLookup._ID");
             columnName = PhoneLookup._ID;
         } else {
-            Rlog.w(TAG, "Unexpected prefix for contactRef '" + url + "'");
+            Log.w(TAG, "Unexpected prefix for contactRef '" + url + "'");
         }
         int columnIndex = (columnName != null) ? cursor.getColumnIndex(columnName) : -1;
-        if (VDBG) Rlog.v(TAG, "==> Using column '" + columnName
+        if (VDBG) Log.v(TAG, "==> Using column '" + columnName
                         + "' (columnIndex = " + columnIndex + ") for person_id lookup...");
         return columnIndex;
     }
@@ -689,7 +673,7 @@
      * @hide
      */
     public static String getGeoDescription(Context context, String number) {
-        if (VDBG) Rlog.v(TAG, "getGeoDescription('" + number + "')...");
+        if (VDBG) Log.v(TAG, "getGeoDescription('" + number + "')...");
 
         if (TextUtils.isEmpty(number)) {
             return null;
@@ -702,18 +686,18 @@
         String countryIso = getCurrentCountryIso(context, locale);
         PhoneNumber pn = null;
         try {
-            if (VDBG) Rlog.v(TAG, "parsing '" + number
+            if (VDBG) Log.v(TAG, "parsing '" + number
                             + "' for countryIso '" + countryIso + "'...");
             pn = util.parse(number, countryIso);
-            if (VDBG) Rlog.v(TAG, "- parsed number: " + pn);
+            if (VDBG) Log.v(TAG, "- parsed number: " + pn);
         } catch (NumberParseException e) {
-            Rlog.w(TAG, "getGeoDescription: NumberParseException for incoming number '"
-                    + Rlog.pii(TAG, number) + "'");
+            Log.w(TAG, "getGeoDescription: NumberParseException for incoming number '"
+                    + Log.pii(number) + "'");
         }
 
         if (pn != null) {
             String description = geocoder.getDescriptionForNumber(pn, locale);
-            if (VDBG) Rlog.v(TAG, "- got description: '" + description + "'");
+            if (VDBG) Log.v(TAG, "- got description: '" + description + "'");
             return description;
         } else {
             return null;
@@ -733,12 +717,12 @@
             if (country != null) {
                 countryIso = country.getCountryIso();
             } else {
-                Rlog.e(TAG, "CountryDetector.detectCountry() returned null.");
+                Log.e(TAG, new Exception(), "CountryDetector.detectCountry() returned null.");
             }
         }
         if (countryIso == null) {
             countryIso = locale.getCountry();
-            Rlog.w(TAG, "No CountryDetector; falling back to countryIso based on locale: "
+            Log.w(TAG, "No CountryDetector; falling back to countryIso based on locale: "
                     + countryIso);
         }
         return countryIso;
diff --git a/telephony/java/android/telephony/CallerInfoAsyncQuery.java b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
similarity index 91%
rename from telephony/java/android/telephony/CallerInfoAsyncQuery.java
rename to telecomm/java/android/telecom/CallerInfoAsyncQuery.java
index 88b471e..4a50e98 100644
--- a/telephony/java/android/telephony/CallerInfoAsyncQuery.java
+++ b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.telephony;
+package android.telecom;
 
 import android.app.ActivityManager;
 import android.content.AsyncQueryHandler;
@@ -31,6 +31,8 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.ContactsContract.PhoneLookup;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.SubscriptionManager;
 import android.text.TextUtils;
 
 import dalvik.annotation.compat.UnsupportedAppUsage;
@@ -107,12 +109,12 @@
      */
     static ContentResolver getCurrentProfileContentResolver(Context context) {
 
-        if (DBG) Rlog.d(LOG_TAG, "Trying to get current content resolver...");
+        if (DBG) Log.d(LOG_TAG, "Trying to get current content resolver...");
 
         final int currentUser = ActivityManager.getCurrentUser();
         final int myUser = UserManager.get(context).getUserHandle();
 
-        if (DBG) Rlog.d(LOG_TAG, "myUser=" + myUser + "currentUser=" + currentUser);
+        if (DBG) Log.d(LOG_TAG, "myUser=" + myUser + "currentUser=" + currentUser);
 
         if (myUser != currentUser) {
             final Context otherContext;
@@ -121,7 +123,7 @@
                         /* flags =*/ 0, UserHandle.of(currentUser));
                 return otherContext.getContentResolver();
             } catch (NameNotFoundException e) {
-                Rlog.e(LOG_TAG, "Can't find self package", e);
+                Log.e(LOG_TAG, e, "Can't find self package");
                 // Fall back to the primary user.
             }
         }
@@ -186,13 +188,13 @@
                     // However, if there is any code that this Handler calls (such as in
                     // super.handleMessage) that DOES place unexpected messages on the
                     // queue, then we need pass these messages on.
-                    Rlog.i(LOG_TAG, "Unexpected command (CookieWrapper is null): " + msg.what +
+                    Log.i(LOG_TAG, "Unexpected command (CookieWrapper is null): " + msg.what +
                             " ignored by CallerInfoWorkerHandler, passing onto parent.");
 
                     super.handleMessage(msg);
                 } else {
 
-                    Rlog.d(LOG_TAG, "Processing event: " + cw.event + " token (arg1): " + msg.arg1 +
+                    Log.d(LOG_TAG, "Processing event: " + cw.event + " token (arg1): " + msg.arg1 +
                         " command: " + msg.what + " query URI: " + sanitizeUriToString(args.uri));
 
                     switch (cw.event) {
@@ -233,7 +235,7 @@
                     cw.geoDescription = CallerInfo.getGeoDescription(mContext, cw.number);
                     final long duration = SystemClock.elapsedRealtime() - startTimeMillis;
                     if (duration > 500) {
-                        if (DBG) Rlog.d(LOG_TAG, "[handleGeoDescription]" +
+                        if (DBG) Log.d(LOG_TAG, "[handleGeoDescription]" +
                                 "Spends long time to retrieve Geo description: " + duration);
                     }
                 }
@@ -270,7 +272,7 @@
          */
         @Override
         protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
-            Rlog.d(LOG_TAG, "##### onQueryComplete() #####   query complete for token: " + token);
+            Log.d(LOG_TAG, "##### onQueryComplete() #####   query complete for token: " + token);
 
             //get the cookie and notify the listener.
             CookieWrapper cw = (CookieWrapper) cookie;
@@ -279,7 +281,7 @@
                 // from within this code.
                 // However, if there is any code that calls this method, we should
                 // check the parameters to make sure they're viable.
-                Rlog.i(LOG_TAG, "Cookie is null, ignoring onQueryComplete() request.");
+                Log.i(LOG_TAG, "Cookie is null, ignoring onQueryComplete() request.");
                 if (cursor != null) {
                     cursor.close();
                 }
@@ -328,16 +330,16 @@
                     // comments at the top of CallerInfo class).
                     mCallerInfo = new CallerInfo().markAsEmergency(mContext);
                 } else if (cw.event == EVENT_VOICEMAIL_NUMBER) {
-                    mCallerInfo = new CallerInfo().markAsVoiceMail(cw.subId);
+                    mCallerInfo = new CallerInfo().markAsVoiceMail(mContext, cw.subId);
                 } else {
                     mCallerInfo = CallerInfo.getCallerInfo(mContext, mQueryUri, cursor);
-                    if (DBG) Rlog.d(LOG_TAG, "==> Got mCallerInfo: " + mCallerInfo);
+                    if (DBG) Log.d(LOG_TAG, "==> Got mCallerInfo: " + mCallerInfo);
 
                     CallerInfo newCallerInfo = CallerInfo.doSecondaryLookupIfNecessary(
                             mContext, cw.number, mCallerInfo);
                     if (newCallerInfo != mCallerInfo) {
                         mCallerInfo = newCallerInfo;
-                        if (DBG) Rlog.d(LOG_TAG, "#####async contact look up with numeric username"
+                        if (DBG) Log.d(LOG_TAG, "#####async contact look up with numeric username"
                                 + mCallerInfo);
                     }
 
@@ -353,7 +355,7 @@
                     // the geo description, so it would be unnecessary to query it.
                     if (ENABLE_UNKNOWN_NUMBER_GEO_DESCRIPTION) {
                         if (TextUtils.isEmpty(mCallerInfo.getName())) {
-                            if (DBG) Rlog.d(LOG_TAG, "start querying geo description");
+                            if (DBG) Log.d(LOG_TAG, "start querying geo description");
                             cw.event = EVENT_GET_GEO_DESCRIPTION;
                             startQuery(token, cw, null, null, null, null, null);
                             return;
@@ -361,7 +363,7 @@
                     }
                 }
 
-                if (DBG) Rlog.d(LOG_TAG, "constructing CallerInfo object for token: " + token);
+                if (DBG) Log.d(LOG_TAG, "constructing CallerInfo object for token: " + token);
 
                 //notify that we can clean up the queue after this.
                 CookieWrapper endMarker = new CookieWrapper();
@@ -374,14 +376,14 @@
                 mPendingListenerCallbacks.add(new Runnable() {
                     @Override
                     public void run() {
-                        if (DBG) Rlog.d(LOG_TAG, "notifying listener: "
+                        if (DBG) Log.d(LOG_TAG, "notifying listener: "
                                 + cw.listener.getClass().toString() + " for token: " + token
                                 + mCallerInfo);
                         cw.listener.onQueryComplete(token, cw.cookie, mCallerInfo);
                     }
                 });
             } else {
-                Rlog.w(LOG_TAG, "There is no listener to notify for this query.");
+                Log.w(LOG_TAG, "There is no listener to notify for this query.");
             }
 
             if (cursor != null) {
@@ -406,7 +408,7 @@
         CallerInfoAsyncQuery c = new CallerInfoAsyncQuery();
         c.allocate(context, contactRef);
 
-        if (DBG) Rlog.d(LOG_TAG, "starting query for URI: " + contactRef + " handler: " + c.toString());
+        if (DBG) Log.d(LOG_TAG, "starting query for URI: " + contactRef + " handler: " + c.toString());
 
         //create cookieWrapper, start query
         CookieWrapper cw = new CookieWrapper();
@@ -452,9 +454,9 @@
             OnQueryCompleteListener listener, Object cookie, int subId) {
 
         if (DBG) {
-            Rlog.d(LOG_TAG, "##### CallerInfoAsyncQuery startQuery()... #####");
-            Rlog.d(LOG_TAG, "- number: " + /*number*/ "xxxxxxx");
-            Rlog.d(LOG_TAG, "- cookie: " + cookie);
+            Log.d(LOG_TAG, "##### CallerInfoAsyncQuery startQuery()... #####");
+            Log.d(LOG_TAG, "- number: " + /*number*/ "xxxxxxx");
+            Log.d(LOG_TAG, "- cookie: " + cookie);
         }
 
         // Construct the URI object and query params, and start the query.
@@ -466,7 +468,7 @@
                 .build();
 
         if (DBG) {
-            Rlog.d(LOG_TAG, "==> contactRef: " + sanitizeUriToString(contactRef));
+            Log.d(LOG_TAG, "==> contactRef: " + sanitizeUriToString(contactRef));
         }
 
         CallerInfoAsyncQuery c = new CallerInfoAsyncQuery();
@@ -503,8 +505,8 @@
      */
     public void addQueryListener(int token, OnQueryCompleteListener listener, Object cookie) {
 
-        if (DBG) Rlog.d(LOG_TAG, "adding listener to query: " + sanitizeUriToString(mHandler.mQueryUri) +
-                " handler: " + mHandler.toString());
+        if (DBG) Log.d(LOG_TAG, "adding listener to query: "
+                + sanitizeUriToString(mHandler.mQueryUri) + " handler: " + mHandler.toString());
 
         //create cookieWrapper, add query request to end of queue.
         CookieWrapper cw = new CookieWrapper();
diff --git a/telephony/common/com/google/android/mms/pdu/PduPersister.java b/telephony/common/com/google/android/mms/pdu/PduPersister.java
index 93f3065..95ae409 100755
--- a/telephony/common/com/google/android/mms/pdu/PduPersister.java
+++ b/telephony/common/com/google/android/mms/pdu/PduPersister.java
@@ -1548,6 +1548,7 @@
     public void release() {
         Uri uri = Uri.parse(TEMPORARY_DRM_OBJECT_URI);
         SqliteWrapper.delete(mContext, mContentResolver, uri, null, null);
+        mDrmManagerClient.release();
     }
 
     /**
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 1e24558..a315e6d 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2287,6 +2287,77 @@
             "use_only_rsrp_for_lte_signal_bar_bool";
 
     /**
+     * List of 4 customized 5G SS reference signal received power (SSRSRP) thresholds.
+     *
+     * Reference: 3GPP TS 38.215
+     *
+     * 4 threshold integers must be within the boundaries [-140 dB, -44 dB], and the levels are:
+     *     "NONE: [-140, threshold1]"
+     *     "POOR: (threshold1, threshold2]"
+     *     "MODERATE: (threshold2, threshold3]"
+     *     "GOOD:  (threshold3, threshold4]"
+     *     "EXCELLENT:  (threshold4, -44]"
+     *
+     * This key is considered invalid if the format is violated. If the key is invalid or
+     * not configured, a default value set will apply.
+     */
+    public static final String KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY =
+            "5g_nr_ssrsrp_thresholds_int_array";
+
+    /**
+     * List of 4 customized 5G SS reference signal received quality (SSRSRQ) thresholds.
+     *
+     * Reference: 3GPP TS 38.215
+     *
+     * 4 threshold integers must be within the boundaries [-20 dB, -3 dB], and the levels are:
+     *     "NONE: [-23, threshold1]"
+     *     "POOR: (threshold1, threshold2]"
+     *     "MODERATE: (threshold2, threshold3]"
+     *     "GOOD:  (threshold3, threshold4]"
+     *     "EXCELLENT:  (threshold4, -3]"
+     *
+     * This key is considered invalid if the format is violated. If the key is invalid or
+     * not configured, a default value set will apply.
+     */
+    public static final String KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY =
+            "5g_nr_ssrsrq_thresholds_int_array";
+
+    /**
+     * List of 4 customized 5G SS signal-to-noise and interference ratio (SSSINR) thresholds.
+     *
+     * Reference: 3GPP TS 38.215,
+     *            3GPP TS 38.133 10.1.16.1
+     *
+     * 4 threshold integers must be within the boundaries [-23 dB, 40 dB], and the levels are:
+     *     "NONE: [-23, threshold1]"
+     *     "POOR: (threshold1, threshold2]"
+     *     "MODERATE: (threshold2, threshold3]"
+     *     "GOOD:  (threshold3, threshold4]"
+     *     "EXCELLENT:  (threshold4, 40]"
+     *
+     * This key is considered invalid if the format is violated. If the key is invalid or
+     * not configured, a default value set will apply.
+     */
+    public static final String KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY =
+            "5g_nr_sssinr_thresholds_int_array";
+
+    /**
+     * Bit-field integer to determine whether to use SS reference signal received power (SSRSRP),
+     * SS reference signal received quality (SSRSRQ), or/and SS signal-to-noise and interference
+     * ratio (SSSINR) for the number of 5G NR signal bars. If multiple measures are set bit, the
+     * parameter whose value is smallest is used to indicate the signal bar.
+     *
+     *  SSRSRP = 1 << 0,
+     *  SSRSRQ = 1 << 1,
+     *  SSSINR = 1 << 2,
+     *
+     *  Reference: 3GPP TS 38.215,
+     *             3GPP TS 38.133 10.1.16.1
+     */
+    public static final String KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT =
+            "parameters_use_for_5g_nr_signal_bar_int";
+
+    /**
      * Key identifying if voice call barring notification is required to be shown to the user.
      * @hide
      */
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index aa7e21a..85110c2 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -16,6 +16,7 @@
 
 package android.telephony;
 
+import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 
@@ -369,7 +370,7 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public static String toString(int cause) {
+    public static @NonNull String toString(int cause) {
         switch (cause) {
         case NOT_DISCONNECTED:
             return "NOT_DISCONNECTED";
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index af3ba5e..4a1bc1f 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -16,12 +16,12 @@
 
 package android.telephony;
 
-import com.android.i18n.phonenumbers.NumberParseException;
-import com.android.i18n.phonenumbers.PhoneNumberUtil;
-import com.android.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
-import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_IDP_STRING;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
@@ -42,7 +42,10 @@
 import android.text.style.TtsSpan;
 import android.util.SparseIntArray;
 
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_IDP_STRING;
+import com.android.i18n.phonenumbers.NumberParseException;
+import com.android.i18n.phonenumbers.PhoneNumberUtil;
+import com.android.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
+import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -2247,8 +2250,10 @@
      * to read the VM number.
      * @hide
      */
-    @UnsupportedAppUsage
-    public static boolean isVoiceMailNumber(Context context, int subId, String number) {
+    @SystemApi
+    @TestApi
+    public static boolean isVoiceMailNumber(@NonNull Context context, int subId,
+            @Nullable String number) {
         String vmNumber, mdn;
         try {
             final TelephonyManager tm;
@@ -2734,8 +2739,9 @@
      * @param number
      * @return true if number contains @
      */
-    @UnsupportedAppUsage
-    public static boolean isUriNumber(String number) {
+    @SystemApi
+    @TestApi
+    public static boolean isUriNumber(@Nullable String number) {
         // Note we allow either "@" or "%40" to indicate a URI, in case
         // the passed-in string is URI-escaped.  (Neither "@" nor "%40"
         // will ever be found in a legal PSTN number.)
@@ -2752,8 +2758,9 @@
      *
      * @hide
      */
-    @UnsupportedAppUsage
-    public static String getUsernameFromUriNumber(String number) {
+    @SystemApi
+    @TestApi
+    public static @NonNull String getUsernameFromUriNumber(@NonNull String number) {
         // The delimiter between username and domain name can be
         // either "@" or "%40" (the URI-escaped equivalent.)
         int delimiterIndex = number.indexOf('@');
diff --git a/telephony/java/android/telephony/SmsCbLocation.java b/telephony/java/android/telephony/SmsCbLocation.java
index adf7154..d8a4754 100644
--- a/telephony/java/android/telephony/SmsCbLocation.java
+++ b/telephony/java/android/telephony/SmsCbLocation.java
@@ -65,9 +65,8 @@
     /**
      * Construct a location object for the PLMN, LAC, and Cell ID. This class is immutable, so
      * the same object can be reused for multiple broadcasts.
-     * @hide
      */
-    public SmsCbLocation(String plmn, int lac, int cid) {
+    public SmsCbLocation(@NonNull String plmn, int lac, int cid) {
         mPlmn = plmn;
         mLac = lac;
         mCid = cid;
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 0bf2aa7..1309b4d 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -903,10 +903,12 @@
      * {@link ActivityThread#currentPackageName()} is null.
      * @hide
      */
-    public void sendMultipartTextMessageExternal(
-            String destinationAddress, String scAddress, ArrayList<String> parts,
-            ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents,
-            String packageName) {
+    @SystemApi
+    @TestApi
+    public void sendMultipartTextMessage(
+            @NonNull String destinationAddress, @NonNull String scAddress,
+            @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
+            @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName) {
         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
                 deliveryIntents, true /* persistMessage*/,
                 ActivityThread.currentPackageName() == null
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 352d507..dfcfed7 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1826,13 +1826,27 @@
         return subId;
     }
 
-    /** @hide */
-    public void setDefaultVoiceSubId(int subId) {
-        if (VDBG) logd("setDefaultVoiceSubId sub id = " + subId);
+    /**
+     * Sets the system's default voice subscription id.
+     *
+     * On a data-only device, this is a no-op.
+     *
+     * May throw a {@link RuntimeException} if the provided subscription id is equal to
+     * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}
+     *
+     * @param subscriptionId A valid subscription ID to set as the system default, or
+     *                       {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setDefaultVoiceSubscriptionId(int subscriptionId) {
+        if (VDBG) logd("setDefaultVoiceSubId sub id = " + subscriptionId);
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                iSub.setDefaultVoiceSubId(subId);
+                iSub.setDefaultVoiceSubId(subscriptionId);
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1840,6 +1854,15 @@
     }
 
     /**
+     * Same as {@link #setDefaultVoiceSubscriptionId(int)}, but preserved for backwards
+     * compatibility.
+     * @hide
+     */
+    public void setDefaultVoiceSubId(int subId) {
+        setDefaultVoiceSubscriptionId(subId);
+    }
+
+    /**
      * Return the SubscriptionInfo for default voice subscription.
      *
      * Will return null on data only devices, or on error.
@@ -2923,6 +2946,7 @@
      * permission or had carrier privilege permission on the subscription.
      * {@link TelephonyManager#hasCarrierPrivileges()}
      *
+     * @throws IllegalStateException if Telephony service is in bad state.
      * @throws SecurityException if the caller doesn't meet the requirements
      *             outlined above.
      *
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 5a63eb0..baa6953 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -38,6 +38,7 @@
 import android.annotation.WorkerThread;
 import android.app.ActivityThread;
 import android.app.PendingIntent;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.net.ConnectivityManager;
@@ -96,6 +97,7 @@
 import com.android.internal.telephony.OperatorInfo;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.RILConstants;
+import com.android.internal.telephony.SmsApplication;
 import com.android.internal.telephony.TelephonyProperties;
 
 import dalvik.system.VMRuntime;
@@ -460,6 +462,25 @@
                 getActiveModemCount());
     }
 
+    /**
+     * Gets the maximum number of SIMs that can be active, based on the device's multisim
+     * configuration.
+     * @return 1 for single-SIM, DSDS, and TSTS devices. 2 for DSDA devices.
+     * @hide
+     */
+    @SystemApi
+    public int getMaxNumberOfSimultaneouslyActiveSims() {
+        switch (getMultiSimConfiguration()) {
+            case UNKNOWN:
+            case DSDS:
+            case TSTS:
+                return 1;
+            case DSDA:
+                return 2;
+        }
+        return 1;
+    }
+
     /** {@hide} */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     public static TelephonyManager from(Context context) {
@@ -9407,6 +9428,21 @@
     }
 
     /**
+     * Gets the default Respond Via Message application
+     * @param context context from the calling app
+     * @param updateIfNeeded update the default app if there is no valid default app configured.
+     * @return component name of the app and class to direct Respond Via Message intent to, or
+     * {@code null} if the functionality is not supported.
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    public static @Nullable ComponentName getDefaultRespondViaMessageApplication(
+            @NonNull Context context, boolean updateIfNeeded) {
+        return SmsApplication.getDefaultRespondViaMessageApplication(context, updateIfNeeded);
+    }
+
+    /**
      * Set the alphabetic name of current registered operator.
      * @param name the alphabetic name of current registered operator.
      * @hide
@@ -9508,7 +9544,7 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
+    public int getSubIdForPhoneAccount(@Nullable PhoneAccount phoneAccount) {
         int retval = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
         try {
             ITelephony service = getITelephony();
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
index 5766287..5ce42fd 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
@@ -215,7 +215,7 @@
     private static Pair<Integer, List<Geometry>> parseWarningAreaCoordinates(
             byte[] pdu, int wacOffset) {
         // little-endian
-        int wacDataLength = (pdu[wacOffset + 1] << 8) | pdu[wacOffset];
+        int wacDataLength = ((pdu[wacOffset + 1] & 0xff) << 8) | (pdu[wacOffset] & 0xff);
         int offset = wacOffset + 2;
 
         if (offset + wacDataLength > pdu.length) {
diff --git a/tests/Gating/Android.bp b/tests/Gating/Android.bp
deleted file mode 100644
index b6c0094..0000000
--- a/tests/Gating/Android.bp
+++ /dev/null
@@ -1,17 +0,0 @@
-android_test {
-    name: "Gating",
-    // Only compile source java files in this apk.
-    srcs: ["src/**/*.java"],
-    certificate: "platform",
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-    ],
-    static_libs: [
-        "junit",
-        "android-support-test",
-        "mockito-target-minus-junit4",
-        "truth-prebuilt",
-        "platform_compat-test-rules"
-    ],
-}
diff --git a/tests/Gating/AndroidManifest.xml b/tests/Gating/AndroidManifest.xml
deleted file mode 100644
index 7f14b83..0000000
--- a/tests/Gating/AndroidManifest.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.tests.gating">
-    <application android:label="GatingTest">
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.tests.gating"/>
-</manifest>
diff --git a/tests/Gating/AndroidTest.xml b/tests/Gating/AndroidTest.xml
deleted file mode 100644
index 730e74a..0000000
--- a/tests/Gating/AndroidTest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!-- Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Test compatibility change gating.">
-    <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
-    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
-        <option name="test-file-name" value="Gating.apk"/>
-    </target_preparer>
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
-    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
-    <option name="test-suite-tag" value="apct"/>
-    <option name="test-tag" value="Gating"/>
-
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest">
-        <option name="package" value="com.android.tests.gating"/>
-        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
-        <option name="hidden-api-checks" value="false"/>
-    </test>
-</configuration>
diff --git a/tests/Gating/src/com/android/compat/testing/DummyApi.java b/tests/Gating/src/com/android/compat/testing/DummyApi.java
deleted file mode 100644
index 25106f9..0000000
--- a/tests/Gating/src/com/android/compat/testing/DummyApi.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compat.testing;
-
-import android.compat.Compatibility;
-import android.content.Context;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-
-import com.android.internal.compat.IPlatformCompat;
-
-/**
- * This is a dummy API to test gating
- *
- * @hide
- */
-public class DummyApi {
-
-    public static final long CHANGE_ID = 666013;
-    public static final long CHANGE_ID_1 = 666014;
-    public static final long CHANGE_ID_2 = 666015;
-    public static final long CHANGE_SYSTEM_SERVER = 666016;
-
-    /**
-     * Dummy method
-     * @return "A" if change is enabled, "B" otherwise.
-     */
-    public static String dummyFunc() {
-        if (Compatibility.isChangeEnabled(CHANGE_ID)) {
-            return "A";
-        }
-        return "B";
-    }
-
-    /**
-     * Dummy combined method
-     * @return "0" if {@link CHANGE_ID_1} is disabled and {@link CHANGE_ID_2} is disabled,
-               "1" if {@link CHANGE_ID_1} is disabled and {@link CHANGE_ID_2} is enabled,
-               "2" if {@link CHANGE_ID_1} is enabled and {@link CHANGE_ID_2} is disabled,
-               "3" if {@link CHANGE_ID_1} is enabled and {@link CHANGE_ID_2} is enabled.
-     */
-    public static String dummyCombinedFunc() {
-        if (!Compatibility.isChangeEnabled(CHANGE_ID_1)
-                && !Compatibility.isChangeEnabled(CHANGE_ID_2)) {
-            return "0";
-        } else if (!Compatibility.isChangeEnabled(CHANGE_ID_1)
-                && Compatibility.isChangeEnabled(CHANGE_ID_2)) {
-            return "1";
-        } else if (Compatibility.isChangeEnabled(CHANGE_ID_1)
-                && !Compatibility.isChangeEnabled(CHANGE_ID_2)) {
-            return "2";
-        }
-        return "3";
-    }
-
-    /**
-     * Dummy api using system server API.
-     */
-    public static String dummySystemServer(Context context) {
-        IPlatformCompat platformCompat = IPlatformCompat.Stub
-                .asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
-        if (platformCompat == null) {
-            throw new RuntimeException("Could not obtain IPlatformCompat instance!");
-        }
-        String packageName = context.getPackageName();
-        try {
-            if (platformCompat.isChangeEnabledByPackageName(CHANGE_SYSTEM_SERVER, packageName,
-                                                            context.getUserId())) {
-                return "True";
-            } else {
-                return "False";
-            }
-        } catch (RemoteException e) {
-            throw new RuntimeException("Could not get change value!", e);
-        }
-    }
-}
diff --git a/tests/Gating/src/com/android/tests/gating/GatingTest.java b/tests/Gating/src/com/android/tests/gating/GatingTest.java
deleted file mode 100644
index 1e3f9ed..0000000
--- a/tests/Gating/src/com/android/tests/gating/GatingTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tests.gating;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.compat.testing.CompatChangeRule;
-import android.compat.testing.CompatChangeRule.DisableCompatChanges;
-import android.compat.testing.CompatChangeRule.EnableCompatChanges;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import com.android.compat.testing.DummyApi;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestRule;
-import org.junit.runner.RunWith;
-
-/**
- * Tests for platform compatibility change gating.
- */
-@RunWith(AndroidJUnit4.class)
-public class GatingTest {
-
-    @Rule
-    public TestRule compatChangeRule = new CompatChangeRule();
-
-    @Test
-    @EnableCompatChanges({DummyApi.CHANGE_ID})
-    public void testDummyGatingPositive() {
-        assertThat(DummyApi.dummyFunc()).isEqualTo("A");
-    }
-
-    @Test
-    @DisableCompatChanges({DummyApi.CHANGE_ID})
-    public void testDummyGatingNegative() {
-        assertThat(DummyApi.dummyFunc()).isEqualTo("B");
-    }
-
-    @Test
-    @DisableCompatChanges({DummyApi.CHANGE_ID_1, DummyApi.CHANGE_ID_2})
-    public void testDummyGatingCombined0() {
-        assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("0");
-    }
-
-    @Test
-    @DisableCompatChanges({DummyApi.CHANGE_ID_1})
-    @EnableCompatChanges({DummyApi.CHANGE_ID_2})
-    public void testDummyGatingCombined1() {
-        assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("1");
-    }
-
-    @Test
-    @EnableCompatChanges({DummyApi.CHANGE_ID_1})
-    @DisableCompatChanges({DummyApi.CHANGE_ID_2})
-    public void testDummyGatingCombined2() {
-        assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("2");
-    }
-
-    @Test
-    @EnableCompatChanges({DummyApi.CHANGE_ID_1, DummyApi.CHANGE_ID_2})
-    public void testDummyGatingCombined3() {
-        assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("3");
-    }
-
-    @Test
-    @EnableCompatChanges({DummyApi.CHANGE_SYSTEM_SERVER})
-    public void testDummyGatingPositiveSystemServer() {
-        assertThat(
-                DummyApi.dummySystemServer(InstrumentationRegistry.getTargetContext())).isEqualTo(
-                "True");
-    }
-
-    @Test
-    @DisableCompatChanges({DummyApi.CHANGE_SYSTEM_SERVER})
-    public void testDummyGatingNegativeSystemServer() {
-        assertThat(
-                DummyApi.dummySystemServer(InstrumentationRegistry.getTargetContext())).isEqualTo(
-                "False");
-    }
-}
diff --git a/tests/net/common/java/android/net/NetworkScoreTest.kt b/tests/net/common/java/android/net/NetworkScoreTest.kt
new file mode 100644
index 0000000..30836b7
--- /dev/null
+++ b/tests/net/common/java/android/net/NetworkScoreTest.kt
@@ -0,0 +1,104 @@
+/*
+ * 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.net
+
+import android.os.Parcelable
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.testutils.assertParcelSane
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNotEquals
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private const val TEST_SCORE = 80
+private const val KEY_DEFAULT_CAPABILITIES = "DEFAULT_CAPABILITIES"
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class NetworkScoreTest {
+    @Test
+    fun testParcelNetworkScore() {
+        val networkScore = NetworkScore()
+        val defaultCap = NetworkCapabilities()
+        networkScore.putExtension(KEY_DEFAULT_CAPABILITIES, defaultCap)
+        assertEquals(defaultCap, networkScore.getExtension(KEY_DEFAULT_CAPABILITIES))
+        networkScore.putIntExtension(NetworkScore.LEGACY_SCORE, TEST_SCORE)
+        assertEquals(TEST_SCORE, networkScore.getIntExtension(NetworkScore.LEGACY_SCORE))
+        assertParcelSane(networkScore, 1)
+    }
+
+    @Test
+    fun testNullKeyAndValue() {
+        val networkScore = NetworkScore()
+        val defaultCap = NetworkCapabilities()
+        networkScore.putIntExtension(null, TEST_SCORE)
+        assertEquals(TEST_SCORE, networkScore.getIntExtension(null))
+        networkScore.putExtension(null, defaultCap)
+        assertEquals(defaultCap, networkScore.getExtension(null))
+        networkScore.putExtension(null, null)
+        val result: Parcelable? = networkScore.getExtension(null)
+        assertEquals(null, result)
+    }
+
+    @Test
+    fun testRemoveExtension() {
+        val networkScore = NetworkScore()
+        val defaultCap = NetworkCapabilities()
+        networkScore.putExtension(KEY_DEFAULT_CAPABILITIES, defaultCap)
+        networkScore.putIntExtension(NetworkScore.LEGACY_SCORE, TEST_SCORE)
+        assertEquals(defaultCap, networkScore.getExtension(KEY_DEFAULT_CAPABILITIES))
+        assertEquals(TEST_SCORE, networkScore.getIntExtension(NetworkScore.LEGACY_SCORE))
+        networkScore.removeExtension(KEY_DEFAULT_CAPABILITIES)
+        networkScore.removeExtension(NetworkScore.LEGACY_SCORE)
+        val result: Parcelable? = networkScore.getExtension(KEY_DEFAULT_CAPABILITIES)
+        assertEquals(null, result)
+        assertEquals(0, networkScore.getIntExtension(NetworkScore.LEGACY_SCORE))
+    }
+
+    @Test
+    fun testEqualsNetworkScore() {
+        val ns1 = NetworkScore()
+        val ns2 = NetworkScore()
+        assertTrue(ns1.equals(ns2))
+        assertEquals(ns1.hashCode(), ns2.hashCode())
+
+        ns1.putIntExtension(NetworkScore.LEGACY_SCORE, TEST_SCORE)
+        assertFalse(ns1.equals(ns2))
+        assertNotEquals(ns1.hashCode(), ns2.hashCode())
+        ns2.putIntExtension(NetworkScore.LEGACY_SCORE, TEST_SCORE)
+        assertTrue(ns1.equals(ns2))
+        assertEquals(ns1.hashCode(), ns2.hashCode())
+
+        val defaultCap = NetworkCapabilities()
+        ns1.putExtension(KEY_DEFAULT_CAPABILITIES, defaultCap)
+        assertFalse(ns1.equals(ns2))
+        assertNotEquals(ns1.hashCode(), ns2.hashCode())
+        ns2.putExtension(KEY_DEFAULT_CAPABILITIES, defaultCap)
+        assertTrue(ns1.equals(ns2))
+        assertEquals(ns1.hashCode(), ns2.hashCode())
+
+        ns1.putIntExtension(null, 10)
+        assertFalse(ns1.equals(ns2))
+        assertNotEquals(ns1.hashCode(), ns2.hashCode())
+        ns2.putIntExtension(null, 10)
+        assertTrue(ns1.equals(ns2))
+        assertEquals(ns1.hashCode(), ns2.hashCode())
+    }
+}
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 142769f..535298f 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -39,6 +39,7 @@
 import android.net.NetworkFactory;
 import android.net.NetworkInfo;
 import android.net.NetworkMisc;
+import android.net.NetworkScore;
 import android.os.INetworkManagementService;
 import android.text.format.DateUtils;
 
@@ -354,8 +355,10 @@
         NetworkCapabilities caps = new NetworkCapabilities();
         caps.addCapability(0);
         caps.addTransportType(transport);
+        NetworkScore ns = new NetworkScore();
+        ns.putIntExtension(NetworkScore.LEGACY_SCORE, 50);
         NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null,
-                caps, 50, mCtx, null, mMisc, mConnService, mNetd, mDnsResolver, mNMS,
+                caps, ns, mCtx, null, mMisc, mConnService, mNetd, mDnsResolver, mNMS,
                 NetworkFactory.SerialNumber.NONE);
         nai.everValidated = true;
         return nai;
diff --git a/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl b/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl
new file mode 100644
index 0000000..b49e49b
--- /dev/null
+++ b/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.net.wifi;
+
+import android.net.wifi.WifiNetworkSuggestion;
+
+/**
+ * Interface for suggestion network connection listener.
+ *
+ * @hide
+ */
+oneway interface ISuggestionConnectionStatusListener
+{
+   void onConnectionStatus(in WifiNetworkSuggestion wifiNetworkSuggestion, int failureReason);
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 023df70..bc73a93f1 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -30,6 +30,7 @@
 import android.net.wifi.INetworkRequestMatchCallback;
 import android.net.wifi.IScanResultsListener;
 import android.net.wifi.ISoftApCallback;
+import android.net.wifi.ISuggestionConnectionStatusListener;
 import android.net.wifi.ITrafficStateCallback;
 import android.net.wifi.ITxPacketCountListener;
 import android.net.wifi.IOnWifiUsabilityStatsListener;
@@ -236,4 +237,8 @@
     void registerScanResultsListener(in IBinder binder, in IScanResultsListener Listener, int listenerIdentifier);
 
     void unregisterScanResultsListener(int listenerIdentifier);
+
+    void registerSuggestionConnectionStatusListener(in IBinder binder, in ISuggestionConnectionStatusListener listener, int listenerIdentifier, String packageName);
+
+    void unregisterSuggestionConnectionStatusListener(int listenerIdentifier, String packageName);
 }
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 8108fef..2cf3b59 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -208,6 +208,33 @@
     public @interface NetworkSuggestionsStatusCode {}
 
     /**
+     * Reason code if suggested network connection attempt failed with an unknown failure.
+     */
+    public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0;
+    /**
+     * Reason code if suggested network connection attempt failed with association failure.
+     */
+    public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1;
+    /**
+     * Reason code if suggested network connection attempt failed with an authentication failure.
+     */
+    public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2;
+    /**
+     * Reason code if suggested network connection attempt failed with an IP provision failure.
+     */
+    public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3;
+
+    /** @hide */
+    @IntDef(prefix = {"STATUS_SUGGESTION_CONNECTION_FAILURE_"},
+            value = {STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN,
+                    STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION,
+                    STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION,
+                    STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SuggestionConnectionStatusCode {}
+
+    /**
      * Broadcast intent action indicating whether Wi-Fi scanning is allowed currently
      * @hide
      */
@@ -2220,6 +2247,10 @@
     public static final long WIFI_FEATURE_DPP              = 0x80000000L; // DPP (Easy-Connect)
     /** @hide */
     public static final long WIFI_FEATURE_P2P_RAND_MAC    = 0x100000000L; // Random P2P MAC
+    /** @hide */
+    public static final long WIFI_FEATURE_CONNECTED_RAND_MAC    = 0x200000000L; // Random STA MAC
+    /** @hide */
+    public static final long WIFI_FEATURE_AP_RAND_MAC    = 0x400000000L; // Random AP MAC
 
     private long getSupportedFeatures() {
         try {
@@ -2345,6 +2376,24 @@
     }
 
     /**
+     * @return true if this device supports connected MAC randomization.
+     * @hide
+     */
+    @SystemApi
+    public boolean isConnectedMacRandomizationSupported() {
+        return isFeatureSupported(WIFI_FEATURE_CONNECTED_RAND_MAC);
+    }
+
+    /**
+     * @return true if this device supports connected MAC randomization.
+     * @hide
+     */
+    @SystemApi
+    public boolean isApMacRandomizationSupported() {
+        return isFeatureSupported(WIFI_FEATURE_AP_RAND_MAC);
+    }
+
+    /**
      * Return the record of {@link WifiActivityEnergyInfo} object that
      * has the activity and energy info. This can be used to ascertain what
      * the controller has been up to, since the last sample.
@@ -5229,7 +5278,7 @@
     }
 
     /**
-     * Base class for scan results listener. Should be implemented by applications and set when
+     * Interface for scan results listener. Should be implemented by applications and set when
      * calling {@link WifiManager#addScanResultsListener(Executor, ScanResultsListener)}.
      */
     public interface ScanResultsListener {
@@ -5315,4 +5364,108 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Interface for suggestion connection status listener.
+     * Should be implemented by applications and set when calling
+     * {@link WifiManager#addSuggestionConnectionStatusListener(
+     * Executor, SuggestionConnectionStatusListener)}.
+     */
+    public interface SuggestionConnectionStatusListener {
+
+        /**
+         * Called when the framework attempted to connect to a suggestion provided by the
+         * registering app, but the connection to the suggestion failed.
+         * @param wifiNetworkSuggestion The suggestion which failed to connect.
+         * @param failureReason the connection failure reason code. One of
+         * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION},
+         * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION},
+         * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING}
+         * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN}
+         */
+        void onConnectionStatus(
+                @NonNull WifiNetworkSuggestion wifiNetworkSuggestion,
+                @SuggestionConnectionStatusCode int failureReason);
+    }
+
+    private class SuggestionConnectionStatusListenerProxy extends
+            ISuggestionConnectionStatusListener.Stub {
+        private final Executor mExecutor;
+        private final SuggestionConnectionStatusListener mListener;
+
+        SuggestionConnectionStatusListenerProxy(@NonNull Executor executor,
+                @NonNull SuggestionConnectionStatusListener listener) {
+            mExecutor = executor;
+            mListener = listener;
+        }
+
+        @Override
+        public void onConnectionStatus(@NonNull WifiNetworkSuggestion wifiNetworkSuggestion,
+                int failureReason) {
+            mExecutor.execute(() ->
+                    mListener.onConnectionStatus(wifiNetworkSuggestion, failureReason));
+        }
+
+    }
+
+    /**
+     * Add a listener for suggestion networks. See {@link SuggestionConnectionStatusListener}.
+     * Caller will receive the event when suggested network have connection failure.
+     * Caller can remove a previously registered listener using
+     * {@link WifiManager#removeSuggestionConnectionStatusListener(
+     * SuggestionConnectionStatusListener)}
+     * Same caller can add multiple listeners to monitor the event.
+     * <p>
+     * Applications should have the
+     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
+     * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permissions.
+     * Callers without the permission will trigger a {@link java.lang.SecurityException}.
+     * <p>
+     *
+     * @param executor The executor to execute the listener of the {@code listener} object.
+     * @param listener listener for suggestion network connection failure.
+     */
+    @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
+    public void addSuggestionConnectionStatusListener(@NonNull @CallbackExecutor Executor executor,
+            @NonNull SuggestionConnectionStatusListener listener) {
+        if (listener == null) throw new IllegalArgumentException("Listener cannot be null");
+        if (executor == null) throw new IllegalArgumentException("Executor cannot be null");
+        Log.v(TAG, "addSuggestionConnectionStatusListener listener=" + listener
+                + ", executor=" + executor);
+        try {
+            IWifiManager iWifiManager = getIWifiManager();
+            if (iWifiManager == null) {
+                throw new RemoteException("Wifi service is not running");
+            }
+            iWifiManager.registerSuggestionConnectionStatusListener(new Binder(),
+                    new SuggestionConnectionStatusListenerProxy(executor, listener),
+                    listener.hashCode(), mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+
+    }
+
+    /**
+     * Allow callers to remove a previously registered listener. After calling this method,
+     * applications will no longer receive suggestion connection events through that listener.
+     *
+     * @param listener listener to remove.
+     */
+    @RequiresPermission(ACCESS_WIFI_STATE)
+    public void removeSuggestionConnectionStatusListener(
+            @NonNull SuggestionConnectionStatusListener listener) {
+        if (listener == null) throw new IllegalArgumentException("Listener cannot be null");
+        Log.v(TAG, "removeSuggestionConnectionStatusListener: listener=" + listener);
+        try {
+            IWifiManager iWifiManager = getIWifiManager();
+            if (iWifiManager == null) {
+                throw new RemoteException("Wifi service is not running");
+            }
+            iWifiManager.unregisterSuggestionConnectionStatusListener(listener.hashCode(),
+                    mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 67993e1..0a99326 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -138,7 +138,8 @@
     public List<Integer> getAvailableChannels(@WifiBand int band) {
         try {
             Bundle bundle = mService.getAvailableChannels(band, mContext.getOpPackageName());
-            return bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA);
+            List<Integer> channels = bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA);
+            return channels == null ? new ArrayList<>() : channels;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java
index 4b7d205..671708f 100644
--- a/wifi/java/com/android/server/wifi/BaseWifiService.java
+++ b/wifi/java/com/android/server/wifi/BaseWifiService.java
@@ -28,6 +28,7 @@
 import android.net.wifi.IOnWifiUsabilityStatsListener;
 import android.net.wifi.IScanResultsListener;
 import android.net.wifi.ISoftApCallback;
+import android.net.wifi.ISuggestionConnectionStatusListener;
 import android.net.wifi.ITrafficStateCallback;
 import android.net.wifi.ITxPacketCountListener;
 import android.net.wifi.IWifiManager;
@@ -540,4 +541,17 @@
     public void unregisterScanResultsListener(int listenerIdentifier) {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public void registerSuggestionConnectionStatusListener(IBinder binder,
+            ISuggestionConnectionStatusListener listener,
+            int listenerIdentifier, String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unregisterSuggestionConnectionStatusListener(int listenerIdentifier,
+            String packageName) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 14e994c..a78cca3 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -61,6 +61,7 @@
 import android.net.wifi.WifiManager.OnWifiUsabilityStatsListener;
 import android.net.wifi.WifiManager.ScanResultsListener;
 import android.net.wifi.WifiManager.SoftApCallback;
+import android.net.wifi.WifiManager.SuggestionConnectionStatusListener;
 import android.net.wifi.WifiManager.TrafficStateCallback;
 import android.os.Binder;
 import android.os.Build;
@@ -109,12 +110,14 @@
     @Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback;
     @Mock OnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener;
     @Mock ScanResultsListener mScanResultListener;
+    @Mock SuggestionConnectionStatusListener mListener;
     @Mock Executor mCallbackExecutor;
     @Mock Executor mExecutor;
 
     private Handler mHandler;
     private TestLooper mLooper;
     private WifiManager mWifiManager;
+    private WifiNetworkSuggestion mWifiNetworkSuggestion;
 
     @Before
     public void setUp() throws Exception {
@@ -126,6 +129,7 @@
         when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
         mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper());
         verify(mWifiService).getVerboseLoggingLevel();
+        mWifiNetworkSuggestion = new WifiNetworkSuggestion();
     }
 
     /**
@@ -1803,4 +1807,69 @@
     public void testRemoveScanResultsListenerWithNullListener() throws Exception {
         mWifiManager.removeScanResultsListener(null);
     }
+
+    /**
+     * Verify an IllegalArgumentException is thrown if executor not provided.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testAddSuggestionConnectionStatusListenerWithNullExecutor() {
+        mWifiManager.addSuggestionConnectionStatusListener(null, mListener);
+    }
+
+    /**
+     * Verify an IllegalArgumentException is thrown if listener is not provided.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testAddSuggestionConnectionStatusListenerWithNullListener() {
+        mWifiManager.addSuggestionConnectionStatusListener(mExecutor, null);
+    }
+
+    /**
+     * Verify client provided listener is being called to the right listener.
+     */
+    @Test
+    public void testAddSuggestionConnectionStatusListenerAndReceiveEvent() throws Exception {
+        int errorCode = WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
+        ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor =
+                ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class);
+        Executor executor = new SynchronousExecutor();
+        mWifiManager.addSuggestionConnectionStatusListener(executor, mListener);
+        verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class),
+                callbackCaptor.capture(), anyInt(), anyString());
+        callbackCaptor.getValue().onConnectionStatus(mWifiNetworkSuggestion, errorCode);
+        verify(mListener).onConnectionStatus(any(WifiNetworkSuggestion.class), eq(errorCode));
+    }
+
+    /**
+     * Verify client provided listener is being called to the right executor.
+     */
+    @Test
+    public void testAddSuggestionConnectionStatusListenerWithTheTargetExecutor() throws Exception {
+        int errorCode = WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
+        ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor =
+                ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class);
+        mWifiManager.addSuggestionConnectionStatusListener(mExecutor, mListener);
+        verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class),
+                callbackCaptor.capture(), anyInt(), anyString());
+        callbackCaptor.getValue().onConnectionStatus(any(WifiNetworkSuggestion.class), errorCode);
+        verify(mExecutor).execute(any(Runnable.class));
+    }
+
+    /**
+     * Verify an IllegalArgumentException is thrown if listener is not provided.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testRemoveSuggestionConnectionListenerWithNullListener() {
+        mWifiManager.removeSuggestionConnectionStatusListener(null);
+    }
+
+    /**
+     * Verify removeSuggestionConnectionListener.
+     */
+    @Test
+    public void testRemoveSuggestionConnectionListener() throws Exception {
+
+        mWifiManager.removeSuggestionConnectionStatusListener(mListener);
+        verify(mWifiService).unregisterSuggestionConnectionStatusListener(anyInt(), anyString());
+    }
 }