Merge "Added UserManager#getUserSwitchability."
diff --git a/api/current.txt b/api/current.txt
index 3489335..e717271 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5262,7 +5262,7 @@
     method public int describeContents();
     method public boolean getAllowSystemGeneratedContextualActions();
     method public int getBadgeIconType();
-    method public android.app.Notification.BubbleMetadata getBubbleMetadata();
+    method @Nullable public android.app.Notification.BubbleMetadata getBubbleMetadata();
     method public String getChannelId();
     method public String getGroup();
     method public int getGroupAlertBehavior();
@@ -5479,25 +5479,25 @@
   public static final class Notification.BubbleMetadata implements android.os.Parcelable {
     method public int describeContents();
     method public boolean getAutoExpandBubble();
-    method public android.app.PendingIntent getDeleteIntent();
+    method @Nullable public android.app.PendingIntent getDeleteIntent();
     method public int getDesiredHeight();
-    method public android.graphics.drawable.Icon getIcon();
-    method public android.app.PendingIntent getIntent();
+    method @NonNull public android.graphics.drawable.Icon getIcon();
+    method @NonNull public android.app.PendingIntent getIntent();
     method public boolean getSuppressInitialNotification();
     method @Deprecated public CharSequence getTitle();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.Notification.BubbleMetadata> CREATOR;
   }
 
-  public static class Notification.BubbleMetadata.Builder {
+  public static final class Notification.BubbleMetadata.Builder {
     ctor public Notification.BubbleMetadata.Builder();
-    method public android.app.Notification.BubbleMetadata build();
-    method public android.app.Notification.BubbleMetadata.Builder setAutoExpandBubble(boolean);
-    method public android.app.Notification.BubbleMetadata.Builder setDeleteIntent(android.app.PendingIntent);
-    method public android.app.Notification.BubbleMetadata.Builder setDesiredHeight(int);
-    method public android.app.Notification.BubbleMetadata.Builder setIcon(android.graphics.drawable.Icon);
-    method public android.app.Notification.BubbleMetadata.Builder setIntent(android.app.PendingIntent);
-    method public android.app.Notification.BubbleMetadata.Builder setSuppressInitialNotification(boolean);
+    method @NonNull public android.app.Notification.BubbleMetadata build();
+    method @NonNull public android.app.Notification.BubbleMetadata.Builder setAutoExpandBubble(boolean);
+    method @NonNull public android.app.Notification.BubbleMetadata.Builder setDeleteIntent(@Nullable android.app.PendingIntent);
+    method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeight(int);
+    method @NonNull public android.app.Notification.BubbleMetadata.Builder setIcon(@NonNull android.graphics.drawable.Icon);
+    method @NonNull public android.app.Notification.BubbleMetadata.Builder setIntent(@NonNull android.app.PendingIntent);
+    method @NonNull public android.app.Notification.BubbleMetadata.Builder setSuppressInitialNotification(boolean);
     method @Deprecated public android.app.Notification.BubbleMetadata.Builder setTitle(CharSequence);
   }
 
@@ -5522,7 +5522,7 @@
     method @NonNull public android.app.Notification.Builder setAllowSystemGeneratedContextualActions(boolean);
     method @NonNull public android.app.Notification.Builder setAutoCancel(boolean);
     method @NonNull public android.app.Notification.Builder setBadgeIconType(int);
-    method @NonNull public android.app.Notification.Builder setBubbleMetadata(android.app.Notification.BubbleMetadata);
+    method @NonNull public android.app.Notification.Builder setBubbleMetadata(@Nullable android.app.Notification.BubbleMetadata);
     method @NonNull public android.app.Notification.Builder setCategory(String);
     method @NonNull public android.app.Notification.Builder setChannelId(String);
     method @NonNull public android.app.Notification.Builder setChronometerCountDown(boolean);
@@ -6752,7 +6752,8 @@
     method public void setDelegatedScopes(@NonNull android.content.ComponentName, @NonNull String, @NonNull java.util.List<java.lang.String>);
     method public void setDeviceOwnerLockScreenInfo(@NonNull android.content.ComponentName, CharSequence);
     method public void setEndUserSessionMessage(@NonNull android.content.ComponentName, @Nullable CharSequence);
-    method public int setGlobalPrivateDns(@NonNull android.content.ComponentName, int, @Nullable String);
+    method public int setGlobalPrivateDnsModeOpportunistic(@NonNull android.content.ComponentName);
+    method @WorkerThread public int setGlobalPrivateDnsModeSpecifiedHost(@NonNull android.content.ComponentName, @NonNull String);
     method public void setGlobalSetting(@NonNull android.content.ComponentName, String, String);
     method public void setKeepUninstalledPackages(@Nullable android.content.ComponentName, @NonNull java.util.List<java.lang.String>);
     method public boolean setKeyPairCertificate(@Nullable android.content.ComponentName, @NonNull String, @NonNull java.util.List<java.security.cert.Certificate>, boolean);
@@ -14249,7 +14250,7 @@
     method @NonNull public static android.graphics.Insets subtract(@NonNull android.graphics.Insets, @NonNull android.graphics.Insets);
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.graphics.Insets> CREATOR;
-    field public static final android.graphics.Insets NONE;
+    field @NonNull public static final android.graphics.Insets NONE;
     field public final int bottom;
     field public final int left;
     field public final int right;
@@ -30256,16 +30257,6 @@
     field public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; // 0x1
   }
 
-  public static final class WifiAwareManager.NetworkSpecifierBuilder {
-    ctor public WifiAwareManager.NetworkSpecifierBuilder();
-    method @NonNull public android.net.NetworkSpecifier build();
-    method @NonNull public android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder setDiscoverySession(@NonNull android.net.wifi.aware.DiscoverySession);
-    method @NonNull public android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder setPeerHandle(@NonNull android.net.wifi.aware.PeerHandle);
-    method @NonNull public android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder setPort(int);
-    method @NonNull public android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder setPskPassphrase(@NonNull String);
-    method @NonNull public android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder setTransportProtocol(int);
-  }
-
   public final class WifiAwareNetworkInfo implements android.os.Parcelable android.net.TransportInfo {
     method public int describeContents();
     method @Nullable public java.net.Inet6Address getPeerIpv6Addr();
@@ -30275,6 +30266,22 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.WifiAwareNetworkInfo> CREATOR;
   }
 
+  public final class WifiAwareNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.WifiAwareNetworkSpecifier> CREATOR;
+  }
+
+  public static final class WifiAwareNetworkSpecifier.Builder {
+    ctor public WifiAwareNetworkSpecifier.Builder();
+    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier build();
+    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setDiscoverySession(@NonNull android.net.wifi.aware.DiscoverySession);
+    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPeerHandle(@NonNull android.net.wifi.aware.PeerHandle);
+    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPort(int);
+    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPskPassphrase(@NonNull String);
+    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setTransportProtocol(int);
+  }
+
   public class WifiAwareSession implements java.lang.AutoCloseable {
     method public void close();
     method public android.net.NetworkSpecifier createNetworkSpecifierOpen(int, @NonNull byte[]);
@@ -35486,6 +35493,7 @@
     field public static final String DISALLOW_CONFIG_VPN = "no_config_vpn";
     field public static final String DISALLOW_CONFIG_WIFI = "no_config_wifi";
     field public static final String DISALLOW_CONTENT_CAPTURE = "no_content_capture";
+    field public static final String DISALLOW_CONTENT_SUGGESTIONS = "no_content_suggestions";
     field public static final String DISALLOW_CREATE_WINDOWS = "no_create_windows";
     field public static final String DISALLOW_CROSS_PROFILE_COPY_PASTE = "no_cross_profile_copy_paste";
     field public static final String DISALLOW_DATA_ROAMING = "no_data_roaming";
@@ -50836,8 +50844,8 @@
     method public final boolean startDragAndDrop(android.content.ClipData, android.view.View.DragShadowBuilder, Object, int);
     method public boolean startNestedScroll(int);
     method public void stopNestedScroll();
-    method public void transformMatrixToGlobal(android.graphics.Matrix);
-    method public void transformMatrixToLocal(android.graphics.Matrix);
+    method public void transformMatrixToGlobal(@NonNull android.graphics.Matrix);
+    method public void transformMatrixToLocal(@NonNull android.graphics.Matrix);
     method public void unscheduleDrawable(@NonNull android.graphics.drawable.Drawable, @NonNull Runnable);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable);
     method public final void updateDragShadow(android.view.View.DragShadowBuilder);
@@ -53457,11 +53465,6 @@
 
 package android.view.inspector {
 
-  public class GeneratedInspectionCompanionProvider implements android.view.inspector.InspectionCompanionProvider {
-    ctor public GeneratedInspectionCompanionProvider();
-    method @Nullable public <T> android.view.inspector.InspectionCompanion<T> provide(@NonNull Class<T>);
-  }
-
   public interface InspectionCompanion<T> {
     method @Nullable public default String getNodeName();
     method public void mapProperties(@NonNull android.view.inspector.PropertyMapper);
@@ -53542,6 +53545,11 @@
     ctor public PropertyReader.PropertyTypeMismatchException(int, @NonNull String, @NonNull String);
   }
 
+  public class StaticInspectionCompanionProvider implements android.view.inspector.InspectionCompanionProvider {
+    ctor public StaticInspectionCompanionProvider();
+    method @Nullable public <T> android.view.inspector.InspectionCompanion<T> provide(@NonNull Class<T>);
+  }
+
   public final class WindowInspector {
     method @NonNull public static java.util.List<android.view.View> getGlobalWindowViews();
   }
@@ -56261,7 +56269,7 @@
     method public String[] getDisplayedValues();
     method public int getMaxValue();
     method public int getMinValue();
-    method public int getSelectionDividerHeight();
+    method @Px public int getSelectionDividerHeight();
     method @ColorInt public int getTextColor();
     method @FloatRange(from=0.0, fromInclusive=false) public float getTextSize();
     method public int getValue();
diff --git a/api/system-current.txt b/api/system-current.txt
index 316f7b8..f2a81c7 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4976,8 +4976,8 @@
     method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierPmk(@NonNull android.net.wifi.aware.PeerHandle, @NonNull byte[]);
   }
 
-  public static final class WifiAwareManager.NetworkSpecifierBuilder {
-    method @NonNull public android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder setPmk(@NonNull byte[]);
+  public static final class WifiAwareNetworkSpecifier.Builder {
+    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPmk(@NonNull byte[]);
   }
 
   public class WifiAwareSession implements java.lang.AutoCloseable {
@@ -5619,7 +5619,7 @@
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isManagedProfile(int);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isPrimaryUser();
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isRestrictedProfile();
-    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean removeUser(android.os.UserHandle);
+    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean removeUser(@NonNull android.os.UserHandle);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserIcon(@NonNull android.graphics.Bitmap);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserName(@Nullable String);
     field public static final String ACTION_USER_RESTRICTIONS_CHANGED = "android.os.action.USER_RESTRICTIONS_CHANGED";
@@ -5849,6 +5849,7 @@
   }
 
   public final class DeviceConfig {
+    method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static void addOnPropertiesChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
     method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static void addOnPropertyChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
     method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static boolean getBoolean(String, String, boolean);
     method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static float getFloat(String, String, float);
@@ -5856,7 +5857,8 @@
     method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static long getLong(String, String, long);
     method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getProperty(String, String);
     method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getString(String, String, String);
-    method public static void removeOnPropertyChangedListener(android.provider.DeviceConfig.OnPropertyChangedListener);
+    method public static void removeOnPropertiesChangedListener(@NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
+    method public static void removeOnPropertyChangedListener(@NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
     method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static void resetToDefaults(int, @Nullable String);
     method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperty(String, String, String, boolean);
     field public static final String NAMESPACE_ACTIVITY_MANAGER = "activity_manager";
@@ -5891,8 +5893,11 @@
     field public static final String NAMESPACE = "intelligence_attention";
   }
 
+  public static interface DeviceConfig.OnPropertiesChangedListener {
+    method public void onPropertiesChanged(@NonNull android.provider.DeviceConfig.Properties);
+  }
+
   public static interface DeviceConfig.OnPropertyChangedListener {
-    method public default void onPropertiesChanged(@NonNull android.provider.DeviceConfig.Properties);
     method public void onPropertyChanged(String, String, String);
   }
 
diff --git a/api/test-current.txt b/api/test-current.txt
index 1856b45..97f5ffe 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2002,6 +2002,7 @@
   }
 
   public final class DeviceConfig {
+    method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static void addOnPropertiesChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
     method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static void addOnPropertyChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
     method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static boolean getBoolean(String, String, boolean);
     method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static float getFloat(String, String, float);
@@ -2009,15 +2010,19 @@
     method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static long getLong(String, String, long);
     method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getProperty(String, String);
     method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getString(String, String, String);
-    method public static void removeOnPropertyChangedListener(android.provider.DeviceConfig.OnPropertyChangedListener);
+    method public static void removeOnPropertiesChangedListener(@NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
+    method public static void removeOnPropertyChangedListener(@NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
     method @RequiresPermission("android.permission.WRITE_DEVICE_CONFIG") public static void resetToDefaults(int, @Nullable String);
     method @RequiresPermission("android.permission.WRITE_DEVICE_CONFIG") public static boolean setProperty(String, String, String, boolean);
     field public static final String NAMESPACE_AUTOFILL = "autofill";
     field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
   }
 
+  public static interface DeviceConfig.OnPropertiesChangedListener {
+    method public void onPropertiesChanged(@NonNull android.provider.DeviceConfig.Properties);
+  }
+
   public static interface DeviceConfig.OnPropertyChangedListener {
-    method public default void onPropertiesChanged(@NonNull android.provider.DeviceConfig.Properties);
     method public void onPropertyChanged(String, String, String);
   }
 
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 03806fa..a8a34d2 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3177,6 +3177,7 @@
      * Returns the bubble metadata that will be used to display app content in a floating window
      * over the existing foreground activity.
      */
+    @Nullable
     public BubbleMetadata getBubbleMetadata() {
         return mBubbleMetadata;
     }
@@ -3568,7 +3569,7 @@
          * collapsed state, the bubble intent will be invoked and displayed.</b>
          */
         @NonNull
-        public Builder setBubbleMetadata(BubbleMetadata data) {
+        public Builder setBubbleMetadata(@Nullable BubbleMetadata data) {
             mN.mBubbleMetadata = data;
             return this;
         }
@@ -8562,6 +8563,7 @@
         /**
          * @return the pending intent used to populate the floating window for this bubble.
          */
+        @NonNull
         public PendingIntent getIntent() {
             return mPendingIntent;
         }
@@ -8569,6 +8571,7 @@
         /**
          * @return the pending intent to send when the bubble is dismissed by a user, if one exists.
          */
+        @Nullable
         public PendingIntent getDeleteIntent() {
             return mDeleteIntent;
         }
@@ -8583,9 +8586,11 @@
         public CharSequence getTitle() {
             return "";
         }
+
         /**
          * @return the icon that will be displayed for this bubble when it is collapsed.
          */
+        @NonNull
         public Icon getIcon() {
             return mIcon;
         }
@@ -8654,7 +8659,7 @@
         /**
          * Builder to construct a {@link BubbleMetadata} object.
          */
-        public static class Builder {
+        public static final class Builder {
 
             private PendingIntent mPendingIntent;
             private Icon mIcon;
@@ -8672,7 +8677,8 @@
              * Sets the intent that will be used when the bubble is expanded. This will display the
              * app content in a floating window over the existing foreground activity.
              */
-            public BubbleMetadata.Builder setIntent(PendingIntent intent) {
+            @NonNull
+            public BubbleMetadata.Builder setIntent(@NonNull PendingIntent intent) {
                 if (intent == null) {
                     throw new IllegalArgumentException("Bubble requires non-null pending intent");
                 }
@@ -8700,7 +8706,8 @@
              * If your app produces multiple bubbles, the image should be unique for each of them.
              * </p>
              */
-            public BubbleMetadata.Builder setIcon(Icon icon) {
+            @NonNull
+            public BubbleMetadata.Builder setIcon(@NonNull Icon icon) {
                 if (icon == null) {
                     throw new IllegalArgumentException("Bubbles require non-null icon");
                 }
@@ -8713,6 +8720,7 @@
              * {@link #setIntent(PendingIntent)}, this height may not be respected if there is not
              * enough space on the screen or if the provided height is too small to be useful.
              */
+            @NonNull
             public BubbleMetadata.Builder setDesiredHeight(int height) {
                 mDesiredHeight = Math.max(height, 0);
                 return this;
@@ -8729,6 +8737,7 @@
              * <p>Generally this flag should only be set if the user has performed an action to
              * request or create a bubble.</p>
              */
+            @NonNull
             public BubbleMetadata.Builder setAutoExpandBubble(boolean shouldExpand) {
                 setFlag(FLAG_AUTO_EXPAND_BUBBLE, shouldExpand);
                 return this;
@@ -8745,6 +8754,7 @@
              * <p>Generally this flag should only be set if the user has performed an action to
              * request or create a bubble.</p>
              */
+            @NonNull
             public BubbleMetadata.Builder setSuppressInitialNotification(
                     boolean shouldSupressNotif) {
                 setFlag(FLAG_SUPPRESS_INITIAL_NOTIFICATION, shouldSupressNotif);
@@ -8754,7 +8764,8 @@
             /**
              * Sets an optional intent to send when this bubble is explicitly removed by the user.
              */
-            public BubbleMetadata.Builder setDeleteIntent(PendingIntent deleteIntent) {
+            @NonNull
+            public BubbleMetadata.Builder setDeleteIntent(@Nullable PendingIntent deleteIntent) {
                 mDeleteIntent = deleteIntent;
                 return this;
             }
@@ -8764,6 +8775,7 @@
              * <p>Will throw {@link IllegalStateException} if required fields have not been set
              * on this builder.</p>
              */
+            @NonNull
             public BubbleMetadata build() {
                 if (mPendingIntent == null) {
                     throw new IllegalStateException("Must supply pending intent to bubble");
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 095d014..7cdd227 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -84,7 +84,6 @@
 import android.service.restrictions.RestrictionsReceiver;
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
-import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
 
@@ -2210,7 +2209,7 @@
             PRIVATE_DNS_SET_ERROR_FAILURE_SETTING
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface SetPrivateDnsModeResultConstants {}
+    public @interface PrivateDnsModeErrorCodes {}
 
     /**
      * Activity action: Starts the administrator to get the mode for the provisioning.
@@ -10450,13 +10449,41 @@
     }
 
     /**
-     * Sets the global Private DNS mode and host to be used.
+     * Sets the global Private DNS mode to opportunistic.
      * May only be called by the device owner.
      *
-     * <p>Note that in case a Private DNS resolver is specified, the method is blocking as it
-     * will perform a connectivity check to the resolver, to ensure it is valid. Because of that,
-     * the method should not be called on any thread that relates to user interaction, such as the
-     * UI thread.
+     * <p>In this mode, the DNS subsystem will attempt a TLS handshake to the network-supplied
+     * resolver prior to attempting name resolution in cleartext.
+     *
+     * @param admin which {@link DeviceAdminReceiver} this request is associated with.
+     *
+     * @return {@code PRIVATE_DNS_SET_SUCCESS} if the mode was set successfully, or
+     *         {@code PRIVATE_DNS_SET_ERROR_FAILURE_SETTING} if it could not be set.
+     *
+     * @throws SecurityException if the caller is not the device owner.
+     */
+    public @PrivateDnsModeErrorCodes int setGlobalPrivateDnsModeOpportunistic(
+            @NonNull ComponentName admin) {
+        throwIfParentInstance("setGlobalPrivateDnsModeOpportunistic");
+
+        if (mService == null) {
+            return PRIVATE_DNS_SET_ERROR_FAILURE_SETTING;
+        }
+
+        try {
+            return mService.setGlobalPrivateDns(admin, PRIVATE_DNS_MODE_OPPORTUNISTIC, null);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Sets the global Private DNS host to be used.
+     * May only be called by the device owner.
+     *
+     * <p>Note that the method is blocking as it will perform a connectivity check to the resolver,
+     * to ensure it is valid. Because of that, the method should not be called on any thread that
+     * relates to user interaction, such as the UI thread.
      *
      * <p>In case a VPN is used in conjunction with Private DNS resolver, the Private DNS resolver
      * must be reachable both from within and outside the VPN. Otherwise, the device may lose
@@ -10464,41 +10491,35 @@
      * VPN.
      *
      * @param admin which {@link DeviceAdminReceiver} this request is associated with.
-     * @param mode Which mode to set - either {@code PRIVATE_DNS_MODE_OPPORTUNISTIC} or
-     *             {@code PRIVATE_DNS_MODE_PROVIDER_HOSTNAME}.
-     *             Since the opportunistic mode defaults to ordinary DNS lookups, the
-     *             option to turn it completely off is not available, so this method
-     *             may not be called with {@code PRIVATE_DNS_MODE_OFF}.
-     * @param privateDnsHost The hostname of a server that implements DNS over TLS (RFC7858), if
-     *                       {@code PRIVATE_DNS_MODE_PROVIDER_HOSTNAME} was specified as the mode,
-     *                       null otherwise.
+     * @param privateDnsHost The hostname of a server that implements DNS over TLS (RFC7858).
      *
-     * @return One of the values in {@link SetPrivateDnsModeResultConstants}.
+     * @return {@code PRIVATE_DNS_SET_SUCCESS} if the mode was set successfully,
+     *         {@code PRIVATE_DNS_SET_ERROR_FAILURE_SETTING} if it could not be set or
+     *         {@code PRIVATE_DNS_SET_ERROR_HOST_NOT_SERVING} if the specified host does not
+     *         implement RFC7858.
      *
-     * @throws IllegalArgumentException in the following cases: if a {@code privateDnsHost} was
-     * provided but the mode was not {@code PRIVATE_DNS_MODE_PROVIDER_HOSTNAME}, if the mode
-     * specified was {@code PRIVATE_DNS_MODE_PROVIDER_HOSTNAME} but {@code privateDnsHost} does
-     * not look like a valid hostname, or if the mode specified is not one of the two valid modes.
+     * @throws IllegalArgumentException if the {@code privateDnsHost} is not a valid hostname.
      *
      * @throws SecurityException if the caller is not the device owner.
      */
-    public int setGlobalPrivateDns(@NonNull ComponentName admin,
-            @PrivateDnsMode int mode, @Nullable String privateDnsHost) {
-        throwIfParentInstance("setGlobalPrivateDns");
+    @WorkerThread public @PrivateDnsModeErrorCodes int setGlobalPrivateDnsModeSpecifiedHost(
+            @NonNull ComponentName admin, @NonNull String privateDnsHost) {
+        throwIfParentInstance("setGlobalPrivateDnsModeSpecifiedHost");
+        Preconditions.checkNotNull(privateDnsHost, "dns resolver is null");
 
         if (mService == null) {
             return PRIVATE_DNS_SET_ERROR_FAILURE_SETTING;
         }
 
-        if (mode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME && !TextUtils.isEmpty(privateDnsHost)
-                && NetworkUtils.isWeaklyValidatedHostname(privateDnsHost)) {
+        if (NetworkUtils.isWeaklyValidatedHostname(privateDnsHost)) {
             if (!PrivateDnsConnectivityChecker.canConnectToPrivateDnsServer(privateDnsHost)) {
                 return PRIVATE_DNS_SET_ERROR_HOST_NOT_SERVING;
             }
         }
 
         try {
-            return mService.setGlobalPrivateDns(admin, mode, privateDnsHost);
+            return mService.setGlobalPrivateDns(
+                    admin, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, privateDnsHost);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c4a574a..89c0690 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1843,7 +1843,8 @@
             }
         }
 
-        final boolean extractNativeLibsDefault = targetSdkVersion < Build.VERSION_CODES.Q;
+        // TODO: flip the default based on targetSdkVersion when possible.  See b/128335904.
+        final boolean extractNativeLibsDefault = true;
         final boolean extractNativeLibs = (extractNativeLibsProvided != null)
                 ? extractNativeLibsProvided : extractNativeLibsDefault;
 
@@ -3718,11 +3719,10 @@
             ai.flags |= ApplicationInfo.FLAG_MULTIARCH;
         }
 
-        final boolean extractNativeLibsDefault =
-                owner.applicationInfo.targetSdkVersion < Build.VERSION_CODES.Q;
+        // TODO: flip the default based on targetSdkVersion when possible.  See b/128335904.
         if (sa.getBoolean(
                 com.android.internal.R.styleable.AndroidManifestApplication_extractNativeLibs,
-                extractNativeLibsDefault)) {
+                true)) {
             ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS;
         }
 
diff --git a/core/java/android/os/BatterySaverPolicyConfig.java b/core/java/android/os/BatterySaverPolicyConfig.java
index af7d11d..bda4e27 100644
--- a/core/java/android/os/BatterySaverPolicyConfig.java
+++ b/core/java/android/os/BatterySaverPolicyConfig.java
@@ -476,10 +476,6 @@
          */
         @NonNull
         public BatterySaverPolicyConfig build() {
-            if (!mEnableAdjustBrightness && Float.compare(1f, mAdjustBrightnessFactor) != 0) {
-                throw new IllegalArgumentException("Brightness adjustment factor changed without "
-                        + "enabling brightness adjustment");
-            }
             return new BatterySaverPolicyConfig(this);
         }
     }
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index b7e65b9..e4277e4 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -4761,6 +4761,9 @@
         sb.append(")");
         pw.println(sb.toString());
 
+        printControllerActivity(pw, sb, prefix, CELLULAR_CONTROLLER_NAME,
+                getModemControllerActivity(), which);
+
         pw.print("     Cellular data received: "); pw.println(formatBytesLocked(mobileRxTotalBytes));
         pw.print("     Cellular data sent: "); pw.println(formatBytesLocked(mobileTxTotalBytes));
         pw.print("     Cellular packets received: "); pw.println(mobileRxTotalPackets);
@@ -4818,9 +4821,6 @@
         if (!didOne) sb.append(" (no activity)");
         pw.println(sb.toString());
 
-        printControllerActivity(pw, sb, prefix, CELLULAR_CONTROLLER_NAME,
-            getModemControllerActivity(), which);
-
         pw.print(prefix);
         sb.setLength(0);
         sb.append(prefix);
@@ -4837,6 +4837,9 @@
         sb.append(")");
         pw.println(sb.toString());
 
+        printControllerActivity(pw, sb, prefix, WIFI_CONTROLLER_NAME,
+                getWifiControllerActivity(), which);
+
         pw.print("     Wifi data received: "); pw.println(formatBytesLocked(wifiRxTotalBytes));
         pw.print("     Wifi data sent: "); pw.println(formatBytesLocked(wifiTxTotalBytes));
         pw.print("     Wifi packets received: "); pw.println(wifiRxTotalPackets);
@@ -4914,9 +4917,6 @@
         if (!didOne) sb.append(" (no activity)");
         pw.println(sb.toString());
 
-        printControllerActivity(pw, sb, prefix, WIFI_CONTROLLER_NAME,
-            getWifiControllerActivity(), which);
-
         pw.print(prefix);
         sb.setLength(0);
         sb.append(prefix);
@@ -4949,8 +4949,10 @@
             pw.print(prefix);
             sb.setLength(0);
             sb.append(prefix);
-            sb.append("     Battery Drain (mAh): ");
-            sb.append(Double.toString(((double) gpsBatteryDrainMaMs)/(3600 * 1000)));
+            sb.append("     GPS Battery Drain: ");
+            sb.append(new DecimalFormat("#.##").format(
+                    ((double) gpsBatteryDrainMaMs) / (3600 * 1000)));
+            sb.append("mAh");
             pw.println(sb.toString());
         }
 
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 3725879..185df5e 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -955,6 +955,21 @@
     public static final String DISALLOW_CONTENT_CAPTURE = "no_content_capture";
 
     /**
+     * Specifies if the current user is able to receive content suggestions for selections based on
+     * the contents of their screen.
+     *
+     * <p>Device owner and profile owner can set this restriction. When it is set by device owner,
+     * only the target user will be affected.
+     *
+     * <p>The default value is <code>false</code>.
+     *
+     * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
+     * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
+     * @see #getUserRestrictions()
+     */
+    public static final String DISALLOW_CONTENT_SUGGESTIONS = "no_content_suggestions";
+
+    /**
      * Specifies if user switching is blocked on the current user.
      *
      * <p> This restriction can only be set by the device owner, it will be applied to all users.
@@ -2732,11 +2747,16 @@
      * Removes a user and all associated data.
      *
      * @param user the user that needs to be removed.
+     * @return {@code true} if the user was successfully removed, {@code false} otherwise.
+     * @throws IllegalArgumentException if {@code user} is {@code null}
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
-    public boolean removeUser(UserHandle user) {
+    public boolean removeUser(@NonNull UserHandle user) {
+        if (user == null) {
+            throw new IllegalArgumentException("user cannot be null");
+        }
         return removeUser(user.getIdentifier());
     }
 
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 0ac7c37..e4593e5 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -30,6 +30,7 @@
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.provider.Settings.ResetMode;
+import android.util.ArrayMap;
 import android.util.Pair;
 
 import com.android.internal.annotations.GuardedBy;
@@ -398,8 +399,11 @@
 
     private static final Object sLock = new Object();
     @GuardedBy("sLock")
-    private static Map<OnPropertyChangedListener, Pair<String, Executor>> sListeners =
-            new HashMap<>();
+    private static ArrayMap<OnPropertyChangedListener, Pair<String, Executor>> sSingleListeners =
+            new ArrayMap<>();
+    @GuardedBy("sLock")
+    private static ArrayMap<OnPropertiesChangedListener, Pair<String, Executor>> sListeners =
+            new ArrayMap<>();
     @GuardedBy("sLock")
     private static Map<String, Pair<ContentObserver, Integer>> sNamespaces = new HashMap<>();
 
@@ -597,20 +601,58 @@
             @NonNull String namespace,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull OnPropertyChangedListener onPropertyChangedListener) {
-        // TODO enforce READ_DEVICE_CONFIG permission
         synchronized (sLock) {
-            Pair<String, Executor> oldNamespace = sListeners.get(onPropertyChangedListener);
+            Pair<String, Executor> oldNamespace = sSingleListeners.get(onPropertyChangedListener);
             if (oldNamespace == null) {
                 // Brand new listener, add it to the list.
-                sListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
+                sSingleListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
                 incrementNamespace(namespace);
             } else if (namespace.equals(oldNamespace.first)) {
                 // Listener is already registered for this namespace, update executor just in case.
-                sListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
+                sSingleListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
             } else {
                 // Update this listener from an old namespace to the new one.
-                decrementNamespace(sListeners.get(onPropertyChangedListener).first);
-                sListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
+                decrementNamespace(sSingleListeners.get(onPropertyChangedListener).first);
+                sSingleListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
+                incrementNamespace(namespace);
+            }
+        }
+    }
+
+    /**
+     * Add a listener for property changes.
+     * <p>
+     * This listener will be called whenever properties in the specified namespace change. Callbacks
+     * will be made on the specified executor. Future calls to this method with the same listener
+     * will replace the old namespace and executor. Remove the listener entirely by calling
+     * {@link #removeOnPropertiesChangedListener(OnPropertiesChangedListener)}.
+     *
+     * @param namespace                   The namespace containing properties to monitor.
+     * @param executor                    The executor which will be used to run callbacks.
+     * @param onPropertiesChangedListener The listener to add.
+     * @hide
+     * @see #removeOnPropertiesChangedListener(OnPropertiesChangedListener)
+     */
+    @SystemApi
+    @TestApi
+    @RequiresPermission(READ_DEVICE_CONFIG)
+    public static void addOnPropertiesChangedListener(
+            @NonNull String namespace,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnPropertiesChangedListener onPropertiesChangedListener) {
+        synchronized (sLock) {
+            Pair<String, Executor> oldNamespace = sListeners.get(onPropertiesChangedListener);
+            if (oldNamespace == null) {
+                // Brand new listener, add it to the list.
+                sListeners.put(onPropertiesChangedListener, new Pair<>(namespace, executor));
+                incrementNamespace(namespace);
+            } else if (namespace.equals(oldNamespace.first)) {
+                // Listener is already registered for this namespace, update executor just in case.
+                sListeners.put(onPropertiesChangedListener, new Pair<>(namespace, executor));
+            } else {
+                // Update this listener from an old namespace to the new one.
+                decrementNamespace(sListeners.get(onPropertiesChangedListener).first);
+                sListeners.put(onPropertiesChangedListener, new Pair<>(namespace, executor));
                 incrementNamespace(namespace);
             }
         }
@@ -627,11 +669,33 @@
     @SystemApi
     @TestApi
     public static void removeOnPropertyChangedListener(
-            OnPropertyChangedListener onPropertyChangedListener) {
+            @NonNull OnPropertyChangedListener onPropertyChangedListener) {
+        Preconditions.checkNotNull(onPropertyChangedListener);
         synchronized (sLock) {
-            if (sListeners.containsKey(onPropertyChangedListener)) {
-                decrementNamespace(sListeners.get(onPropertyChangedListener).first);
-                sListeners.remove(onPropertyChangedListener);
+            if (sSingleListeners.containsKey(onPropertyChangedListener)) {
+                decrementNamespace(sSingleListeners.get(onPropertyChangedListener).first);
+                sSingleListeners.remove(onPropertyChangedListener);
+            }
+        }
+    }
+
+    /**
+     * Remove a listener for property changes. The listener will receive no further notification of
+     * property changes.
+     *
+     * @param onPropertiesChangedListener The listener to remove.
+     * @hide
+     * @see #addOnPropertiesChangedListener(String, Executor, OnPropertiesChangedListener)
+     */
+    @SystemApi
+    @TestApi
+    public static void removeOnPropertiesChangedListener(
+            @NonNull OnPropertiesChangedListener onPropertiesChangedListener) {
+        Preconditions.checkNotNull(onPropertiesChangedListener);
+        synchronized (sLock) {
+            if (sListeners.containsKey(onPropertiesChangedListener)) {
+                decrementNamespace(sListeners.get(onPropertiesChangedListener).first);
+                sListeners.remove(onPropertiesChangedListener);
             }
         }
     }
@@ -700,14 +764,30 @@
         final String name = pathSegments.get(2);
         final String value = getProperty(namespace, name);
         synchronized (sLock) {
-            for (final OnPropertyChangedListener listener : sListeners.keySet()) {
-                if (namespace.equals(sListeners.get(listener).first)) {
-                    sListeners.get(listener).second.execute(new Runnable() {
+            // OnPropertiesChangedListeners
+            for (int i = 0; i < sListeners.size(); i++) {
+                if (namespace.equals(sListeners.valueAt(i).first)) {
+                    final int j = i;
+                    sListeners.valueAt(i).second.execute(new Runnable() {
                         @Override
                         public void run() {
                             Map<String, String> propertyMap = new HashMap(1);
                             propertyMap.put(name, value);
-                            listener.onPropertiesChanged(new Properties(namespace, propertyMap));
+                            sListeners.keyAt(j)
+                                    .onPropertiesChanged(new Properties(namespace, propertyMap));
+                        }
+
+                    });
+                }
+            }
+            // OnPropertyChangedListeners
+            for (int i = 0; i < sSingleListeners.size(); i++) {
+                if (namespace.equals(sSingleListeners.valueAt(i).first)) {
+                    final int j = i;
+                    sSingleListeners.valueAt(i).second.execute(new Runnable() {
+                        @Override
+                        public void run() {
+                            sSingleListeners.keyAt(j).onPropertyChanged(namespace, name, value);
                         }
 
                     });
@@ -717,7 +797,7 @@
     }
 
     /**
-     * Interface for monitoring to properties.
+     * Interface for monitoring single property changes.
      * <p>
      * Override {@link #onPropertyChanged(String, String, String)} to handle callbacks for changes.
      *
@@ -734,22 +814,25 @@
          * @param value     The new value of the property which has changed.
          */
         void onPropertyChanged(String namespace, String name, String value);
+    }
 
+    /**
+     * Interface for monitoring changes to properties.
+     * <p>
+     * Override {@link #onPropertiesChanged(Properties)} to handle callbacks for changes.
+     *
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    public interface OnPropertiesChangedListener {
         /**
          * Called when one or more properties have changed.
          *
          * @param properties Contains the complete collection of properties which have changed for a
-         *         single namespace.
+         *                   single namespace.
          */
-        default void onPropertiesChanged(@NonNull Properties properties) {
-            // During the transitional period, this method calls the old one to ensure legacy
-            // callers continue to function as expected. Ignore this if you are implementing it for
-            // yourself.
-            String namespace = properties.getNamespace();
-            for (String name : properties.getKeyset()) {
-                onPropertyChanged(namespace, name, properties.getString(name, null));
-            }
-        }
+        void onPropertiesChanged(@NonNull Properties properties);
     }
 
     /**
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index 87bdfe0..780b576 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -373,7 +373,10 @@
                     args.recycle();
                     Adjustment adjustment = onNotificationEnqueued(sbn, channel);
                     if (adjustment != null) {
-                        if (!isBound()) return;
+                        if (!isBound()) {
+                            Log.w(TAG, "MSG_ON_NOTIFICATION_ENQUEUED: service not bound, skip.");
+                            return;
+                        }
                         try {
                             getNotificationInterface().applyEnqueuedAdjustmentFromAssistant(
                                     mWrapper, adjustment);
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 4315100..cc74e1a 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -63,9 +63,6 @@
 
     private Context mContext; // used for inflation & icon expansion
 
-    // Contains the basic logging data of the notification.
-    private LogMaker mLogMaker;
-
     /** @hide */
     public StatusBarNotification(String pkg, String opPkg, int id,
             String tag, int uid, int initialPid, Notification notification, UserHandle user,
@@ -404,24 +401,15 @@
      * @hide
      */
     public LogMaker getLogMaker() {
-        if (mLogMaker == null) {
-            // Initialize fields that only change on update (so a new record).
-            mLogMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN)
-                .setPackageName(getPackageName())
+        return new LogMaker(MetricsEvent.VIEW_UNKNOWN).setPackageName(getPackageName())
                 .addTaggedData(MetricsEvent.NOTIFICATION_ID, getId())
                 .addTaggedData(MetricsEvent.NOTIFICATION_TAG, getTag())
-                .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID, getChannelIdLogTag());
-        }
-        // Reset fields that can change between updates, or are used by multiple logs.
-        return mLogMaker
-            .clearCategory()
-            .clearType()
-            .clearSubtype()
-            .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID, getGroupLogTag())
-            .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_SUMMARY,
-                getNotification().isGroupSummary() ? 1 : 0)
-            .addTaggedData(MetricsProto.MetricsEvent.FIELD_NOTIFICATION_CATEGORY,
-                    getNotification().category);
+                .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID, getChannelIdLogTag())
+                .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID, getGroupLogTag())
+                .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_SUMMARY,
+                        getNotification().isGroupSummary() ? 1 : 0)
+                .addTaggedData(MetricsProto.MetricsEvent.FIELD_NOTIFICATION_CATEGORY,
+                        getNotification().category);
     }
 
     private String getGroupLogTag() {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2479497..7fcce6d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -24116,7 +24116,7 @@
      *
      * @param matrix input matrix to modify
      */
-    public void transformMatrixToGlobal(Matrix matrix) {
+    public void transformMatrixToGlobal(@NonNull Matrix matrix) {
         final ViewParent parent = mParent;
         if (parent instanceof View) {
             final View vp = (View) parent;
@@ -24141,7 +24141,7 @@
      *
      * @param matrix input matrix to modify
      */
-    public void transformMatrixToLocal(Matrix matrix) {
+    public void transformMatrixToLocal(@NonNull Matrix matrix) {
         final ViewParent parent = mParent;
         if (parent instanceof View) {
             final View vp = (View) parent;
diff --git a/core/java/android/view/inspector/GeneratedInspectionCompanionProvider.java b/core/java/android/view/inspector/StaticInspectionCompanionProvider.java
similarity index 76%
rename from core/java/android/view/inspector/GeneratedInspectionCompanionProvider.java
rename to core/java/android/view/inspector/StaticInspectionCompanionProvider.java
index d4b7e85..42a892d 100644
--- a/core/java/android/view/inspector/GeneratedInspectionCompanionProvider.java
+++ b/core/java/android/view/inspector/StaticInspectionCompanionProvider.java
@@ -20,15 +20,15 @@
 import android.annotation.Nullable;
 
 /**
- * An inspection companion provider that loads pre-generated inspection companions
+ * An inspection companion provider that finds companions as inner classes or generated code.
  *
  * @see android.processor.view.inspector.PlatformInspectableProcessor
  */
-public class GeneratedInspectionCompanionProvider implements InspectionCompanionProvider {
+public class StaticInspectionCompanionProvider implements InspectionCompanionProvider {
     /**
-     * The suffix used for the generated class
+     * The suffix used for the generated classes and inner classes
      */
-    private static final String COMPANION_SUFFIX = "$$InspectionCompanion";
+    private static final String COMPANION_SUFFIX = "$InspectionCompanion";
 
     @Override
     @Nullable
@@ -39,7 +39,12 @@
         try {
             final Class<InspectionCompanion<T>> companionClass =
                     (Class<InspectionCompanion<T>>) cls.getClassLoader().loadClass(companionName);
-            return companionClass.newInstance();
+
+            if (InspectionCompanion.class.isAssignableFrom(companionClass)) {
+                return companionClass.newInstance();
+            } else {
+                return null;
+            }
         } catch (ClassNotFoundException e) {
             return null;
         } catch (IllegalAccessException e) {
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 090640e..150fa88 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -102,9 +102,11 @@
 
     /**
      * Notify the host application that a page has finished loading. This method
-     * is called only for main frame. When onPageFinished() is called, the
-     * rendering picture may not be updated yet. To get the notification for the
-     * new Picture, use {@link WebView.PictureListener#onNewPicture}.
+     * is called only for main frame. Receiving an {@code onPageFinished()} callback does not
+     * guarantee that the next frame drawn by WebView will reflect the state of the DOM at this
+     * point. In order to be notified that the current DOM state is ready to be rendered, request a
+     * visual state callback with {@link WebView#postVisualStateCallback} and wait for the supplied
+     * callback to be triggered.
      *
      * @param view The WebView that is initiating the callback.
      * @param url The url of the page.
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index dad2669..685e8de 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -1587,6 +1587,7 @@
      * others.
      * @return The height of the divider
      */
+    @Px
     public int getSelectionDividerHeight() {
         return mSelectionDividerHeight;
     }
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 17ed2a0..c095376 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1687,8 +1687,21 @@
      *
      * @return a unique 64-bit token handle which is needed to refer to this token later.
      */
-    public long addEscrowToken(byte[] token, int userId) {
-        return getLockSettingsInternal().addEscrowToken(token, userId);
+    public long addEscrowToken(byte[] token, int userId,
+            @Nullable EscrowTokenStateChangeCallback callback) {
+        return getLockSettingsInternal().addEscrowToken(token, userId, callback);
+    }
+
+    /**
+     * Callback interface to notify when an added escrow token has been activated.
+     */
+    public interface EscrowTokenStateChangeCallback {
+        /**
+         * The method to be called when the token is activated.
+         * @param handle 64 bit handle corresponding to the escrow token
+         * @param userid user for whom the escrow token has been added
+         */
+        void onEscrowTokenActivated(long handle, int userid);
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/LockSettingsInternal.java b/core/java/com/android/internal/widget/LockSettingsInternal.java
index 90397df..d459bfb 100644
--- a/core/java/com/android/internal/widget/LockSettingsInternal.java
+++ b/core/java/com/android/internal/widget/LockSettingsInternal.java
@@ -29,15 +29,18 @@
      * or change user password.
      *
      * After adding, if the user currently has lockscreen password, he will need to perform a
-     * confirm credential operation in order to activate the token for future use. If the user
+     * confirm credential operation in order to activate the token for future use.
+     * Once the token is activated, the callback that is passed here is called.   If the user
      * has no secure lockscreen, then the token is activated immediately.
      *
      * @return a unique 64-bit token handle which is needed to refer to this token later.
      */
-    public abstract long addEscrowToken(byte[] token, int userId);
+    public abstract long addEscrowToken(byte[] token, int userId,
+            LockPatternUtils.EscrowTokenStateChangeCallback callback);
 
     /**
      * Remove an escrow token.
+     *
      * @return true if the given handle refers to a valid token previously returned from
      * {@link #addEscrowToken}, whether it's active or not. return false otherwise.
      */
@@ -51,6 +54,7 @@
 
     /**
      * Set the lock credential.
+     *
      * @return true if password is set.
      */
     public abstract boolean setLockCredentialWithToken(byte[] credential, int type,
diff --git a/core/tests/coretests/src/android/provider/DeviceConfigTest.java b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
index d100f40..04fa524 100644
--- a/core/tests/coretests/src/android/provider/DeviceConfigTest.java
+++ b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
@@ -16,6 +16,7 @@
 
 package android.provider;
 
+import static android.provider.DeviceConfig.OnPropertiesChangedListener;
 import static android.provider.DeviceConfig.OnPropertyChangedListener;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -224,29 +225,31 @@
     }
 
     @Test
-    public void testListener_propertiesCallback() throws InterruptedException {
+    public void testOnPropertiesChangedListener() throws InterruptedException {
         final CountDownLatch countDownLatch = new CountDownLatch(1);
 
-        OnPropertyChangedListener changeListener = new OnPropertyChangedListener() {
-            public void onPropertyChanged(String namespace, String name, String value) {
-                // ignore legacy callback
-            }
-
-            @Override
-            public void onPropertiesChanged(DeviceConfig.Properties properties) {
-                assertThat(properties.getNamespace()).isEqualTo(sNamespace);
-                assertThat(properties.getKeyset().size()).isEqualTo(1);
-                assertThat(properties.getKeyset()).contains(sKey);
-                assertThat(properties.getString(sKey, "default_value")).isEqualTo(sValue);
-                countDownLatch.countDown();
-            }
+        OnPropertiesChangedListener changeListener = (properties) -> {
+            assertThat(properties.getNamespace()).isEqualTo(sNamespace);
+            assertThat(properties.getKeyset()).contains(sKey);
+            assertThat(properties.getString(sKey, "default_value")).isEqualTo(sValue);
+            countDownLatch.countDown();
         };
 
-        testListener(countDownLatch, changeListener);
+        try {
+            DeviceConfig.addOnPropertiesChangedListener(sNamespace,
+                    ActivityThread.currentApplication().getMainExecutor(), changeListener);
+            DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
+            assertThat(countDownLatch.await(
+                    WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
+        } catch (InterruptedException e) {
+            Assert.fail(e.getMessage());
+        } finally {
+            DeviceConfig.removeOnPropertiesChangedListener(changeListener);
+        }
     }
 
     @Test
-    public void testListener_legacyCallback() throws InterruptedException {
+    public void testOnPropertyChangedListener() throws InterruptedException {
         CountDownLatch countDownLatch = new CountDownLatch(1);
 
         OnPropertyChangedListener changeListener = (namespace, name, value) -> {
@@ -256,12 +259,6 @@
             countDownLatch.countDown();
         };
 
-        testListener(countDownLatch, changeListener);
-
-    }
-
-    private void testListener(CountDownLatch countDownLatch,
-            OnPropertyChangedListener changeListener) {
         try {
             DeviceConfig.addOnPropertyChangedListener(sNamespace,
                     ActivityThread.currentApplication().getMainExecutor(), changeListener);
@@ -273,6 +270,7 @@
         } finally {
             DeviceConfig.removeOnPropertyChangedListener(changeListener);
         }
+
     }
 
     private static boolean deleteViaContentProvider(String namespace, String key) {
diff --git a/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java b/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
index c99777b..0f32a82 100644
--- a/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
+++ b/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
@@ -89,6 +89,17 @@
         assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CATEGORY));
     }
 
+    /** Verify that modifying the returned logMaker won't leave stale data behind for
+     * the next caller.*/
+    @Test
+    public void testLogMakerNoStaleData() {
+        StatusBarNotification sbn = getNotification(PKG, GROUP_ID_1, CHANNEL_ID);
+        final LogMaker logMaker = sbn.getLogMaker();
+        int extraTag = MetricsEvent.FIELD_NOTIFICATION_CHANNEL_GROUP_ID;  // An arbitrary new tag
+        logMaker.addTaggedData(extraTag, 1);
+        assertNull(sbn.getLogMaker().getTaggedData(extraTag));
+    }
+
     @Test
     public void testLogMakerWithCategory() {
         Notification.Builder builder = getNotificationBuilder(GROUP_ID_1, CHANNEL_ID)
diff --git a/graphics/java/android/graphics/Insets.java b/graphics/java/android/graphics/Insets.java
index c6dc239..1e03c53 100644
--- a/graphics/java/android/graphics/Insets.java
+++ b/graphics/java/android/graphics/Insets.java
@@ -30,7 +30,7 @@
  *
  */
 public final class Insets implements Parcelable {
-    public static final Insets NONE = new Insets(0, 0, 0, 0);
+    public static final @NonNull Insets NONE = new Insets(0, 0, 0, 0);
 
     public final int left;
     public final int top;
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index a15ff22..c174c24 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -19,8 +19,6 @@
 #include "renderstate/RenderState.h"
 #include "utils/Color.h"
 
-#include <SkToSRGBColorFilter.h>
-
 namespace android {
 namespace uirenderer {
 
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index 2ffda83..fe633e9 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -20,7 +20,6 @@
 #include "renderthread/EglManager.h"
 #include "renderthread/VulkanManager.h"
 
-#include <SkToSRGBColorFilter.h>
 #include <gui/Surface.h>
 #include <ui/Fence.h>
 #include <ui/GraphicBuffer.h>
diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java
index 58dbea4..69b4672 100644
--- a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java
+++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java
@@ -32,6 +32,7 @@
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.util.Slog;
 
 import com.android.server.LocalServices;
@@ -63,7 +64,8 @@
 
     public ContentSuggestionsManagerService(Context context) {
         super(context, new FrameworkResourcesServiceNameResolver(context,
-                com.android.internal.R.string.config_defaultContentSuggestionsService), null);
+                com.android.internal.R.string.config_defaultContentSuggestionsService),
+                UserManager.DISALLOW_CONTENT_SUGGESTIONS);
         mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
     }
 
diff --git a/services/core/java/com/android/server/am/BroadcastDispatcher.java b/services/core/java/com/android/server/am/BroadcastDispatcher.java
index b0b1840..d029482 100644
--- a/services/core/java/com/android/server/am/BroadcastDispatcher.java
+++ b/services/core/java/com/android/server/am/BroadcastDispatcher.java
@@ -450,6 +450,8 @@
             return mCurrentBroadcast;
         }
 
+        final boolean someQueued = !mOrderedBroadcasts.isEmpty();
+
         BroadcastRecord next = null;
         if (!mAlarmBroadcasts.isEmpty()) {
             next = popLocked(mAlarmBroadcasts);
@@ -459,10 +461,18 @@
         }
 
         if (next == null && !mDeferredBroadcasts.isEmpty()) {
+            // We're going to deliver either:
+            // 1. the next "overdue" deferral; or
+            // 2. the next ordinary ordered broadcast; *or*
+            // 3. the next not-yet-overdue deferral.
+
             for (int i = 0; i < mDeferredBroadcasts.size(); i++) {
                 Deferrals d = mDeferredBroadcasts.get(i);
-                if (now < d.deferUntil) {
-                    // No more deferrals due
+                if (now < d.deferUntil && someQueued) {
+                    // stop looking when we haven't hit the next time-out boundary
+                    // but only if we have un-deferred broadcasts waiting,
+                    // otherwise we can deliver whatever deferred broadcast
+                    // is next available.
                     break;
                 }
 
@@ -483,7 +493,7 @@
             }
         }
 
-        if (next == null && !mOrderedBroadcasts.isEmpty()) {
+        if (next == null && someQueued) {
             next = mOrderedBroadcasts.remove(0);
             if (DEBUG_BROADCAST_DEFERRAL) {
                 Slog.i(TAG, "Next broadcast from main queue: " + next);
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index af4db07..b0d8813 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -664,6 +664,12 @@
 
         private void updateDisplayModes(int displayId) {
             Display d = mContext.getSystemService(DisplayManager.class).getDisplay(displayId);
+            if (d == null) {
+                // We can occasionally get a display added or changed event for a display that was
+                // subsequently removed, which means this returns null. Check this case and bail
+                // out early; if it gets re-attached we'll eventually get another call back for it.
+                return;
+            }
             DisplayInfo info = new DisplayInfo();
             d.getDisplayInfo(info);
             boolean changed = false;
diff --git a/services/core/java/com/android/server/location/GnssConfiguration.java b/services/core/java/com/android/server/location/GnssConfiguration.java
index 91b5234..0e9ee40 100644
--- a/services/core/java/com/android/server/location/GnssConfiguration.java
+++ b/services/core/java/com/android/server/location/GnssConfiguration.java
@@ -52,7 +52,6 @@
 
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    //TODO(b/33112647): Create gps_debug.conf with commented career parameters.
     private static final String DEBUG_PROPERTIES_FILE = "/etc/gps_debug.conf";
 
     // config.xml properties
@@ -191,8 +190,6 @@
             return Collections.EMPTY_LIST;
         }
 
-        // TODO(b/122856486): Validate proxy app names so that a system app or some popular app
-        //                    with location permission is not specified as a proxy app.
         ArrayList proxyApps = new ArrayList(proxyAppsArray.length);
         for (String proxyApp : proxyAppsArray) {
             proxyApps.add(proxyApp);
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 29030fa..c173d66 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -67,6 +67,7 @@
 import android.util.Log;
 import android.util.StatsLog;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.location.GpsNetInitiatedHandler;
 import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
@@ -890,12 +891,14 @@
         return GPS_POSITION_MODE_STANDALONE;
     }
 
-    private boolean handleEnable() {
-        if (DEBUG) Log.d(TAG, "handleEnable");
+    @GuardedBy("mLock")
+    private void handleEnableLocked() {
+        if (DEBUG) Log.d(TAG, "handleEnableLocked");
 
         boolean inited = native_init();
 
         if (inited) {
+            mEnabled = true;
             mSupportsXtra = native_supports_xtra();
 
             // TODO: remove the following native calls if we can make sure they are redundant.
@@ -912,15 +915,16 @@
             mGnssNavigationMessageProvider.onGpsEnabledChanged();
             mGnssBatchingProvider.enable();
         } else {
+            mEnabled = false;
             Log.w(TAG, "Failed to enable location provider");
         }
-
-        return inited;
     }
 
-    private void handleDisable() {
-        if (DEBUG) Log.d(TAG, "handleDisable");
+    @GuardedBy("mLock")
+    private void handleDisableLocked() {
+        if (DEBUG) Log.d(TAG, "handleDisableLocked");
 
+        mEnabled = false;
         updateClientUids(new WorkSource());
         stopNavigating();
         mAlarmManager.cancel(mWakeupIntent);
@@ -946,10 +950,9 @@
             }
 
             if (enabled) {
-                mEnabled = handleEnable();
+                handleEnableLocked();
             } else {
-                mEnabled = false;
-                handleDisable();
+                handleDisableLocked();
             }
         }
     }
diff --git a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
index 90d16cb..c06b03b 100644
--- a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
+++ b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
@@ -373,8 +373,8 @@
         networkAttributes = new NetworkAttributes();
         networkAttributes.mCapabilities = capabilities;
 
-        // TODO(b/119278134): The synchronous method ConnectivityManager.getNetworkInfo() must
-        // not be called inside the asynchronous ConnectivityManager.NetworkCallback methods.
+        // TODO: The synchronous method ConnectivityManager.getNetworkInfo() should not be called
+        //       inside the asynchronous ConnectivityManager.NetworkCallback methods.
         NetworkInfo info = mConnMgr.getNetworkInfo(network);
         if (info != null) {
             networkAttributes.mApn = info.getExtraInfo();
@@ -387,8 +387,8 @@
     }
 
     private void handleSuplConnectionAvailable(Network network) {
-        // TODO(b/119278134): The synchronous method ConnectivityManager.getNetworkInfo() must
-        // not be called inside the asynchronous ConnectivityManager.NetworkCallback methods.
+        // TODO: The synchronous method ConnectivityManager.getNetworkInfo() should not be called
+        //       inside the asynchronous ConnectivityManager.NetworkCallback methods.
         NetworkInfo info = mConnMgr.getNetworkInfo(network);
         String apn = null;
         if (info != null) {
@@ -509,8 +509,8 @@
         }
     }
 
-    // TODO(25876485): Delete this method when all devices upgrade to HAL @2.0::IAGnssCallback
-    //                 interface which does not require setting route to host.
+    // TODO: Delete this method when all devices upgrade to HAL @2.0::IAGnssCallback
+    //       interface which does not require setting route to host.
     private void setRouting() {
         boolean result = mConnMgr.requestRouteToHostAddress(
                 ConnectivityManager.TYPE_MOBILE_SUPL,
diff --git a/services/core/java/com/android/server/location/GnssVisibilityControl.java b/services/core/java/com/android/server/location/GnssVisibilityControl.java
index 20f872a..24ee389 100644
--- a/services/core/java/com/android/server/location/GnssVisibilityControl.java
+++ b/services/core/java/com/android/server/location/GnssVisibilityControl.java
@@ -18,7 +18,6 @@
 
 import android.annotation.SuppressLint;
 import android.app.AppOpsManager;
-import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -32,11 +31,11 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.StatsLog;
 
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -76,9 +75,9 @@
     private boolean mIsDeviceLocationSettingsEnabled;
 
     // Number of non-framework location access proxy apps is expected to be small (< 5).
-    private static final int HASH_MAP_INITIAL_CAPACITY_PROXY_APP_TO_LOCATION_PERMISSIONS = 7;
-    private HashMap<String, Boolean> mProxyAppToLocationPermissions = new HashMap<>(
-            HASH_MAP_INITIAL_CAPACITY_PROXY_APP_TO_LOCATION_PERMISSIONS);
+    private static final int ARRAY_MAP_INITIAL_CAPACITY_PROXY_APP_TO_LOCATION_PERMISSIONS = 7;
+    private ArrayMap<String, Boolean> mProxyAppToLocationPermissions = new ArrayMap<>(
+            ARRAY_MAP_INITIAL_CAPACITY_PROXY_APP_TO_LOCATION_PERMISSIONS);
 
     private PackageManager.OnPermissionsChangedListener mOnPermissionsChangedListener =
             uid -> runOnHandler(() -> handlePermissionsChanged(uid));
@@ -97,10 +96,6 @@
     }
 
     void updateProxyApps(List<String> nfwLocationAccessProxyApps) {
-        // NOTE: This class doesn't explicitly register and listen for SIM_STATE_CHANGED event
-        //       but rather piggy backs on the GnssLocationProvider SIM_STATE_CHANGED handling
-        //       so that the order of processing is preserved. GnssLocationProvider should
-        //       first load the new config parameters for the new SIM and then call this method.
         runOnHandler(() -> handleUpdateProxyApps(nfwLocationAccessProxyApps));
     }
 
@@ -246,15 +241,7 @@
 
     // Represents NfwNotification structure in IGnssVisibilityControlCallback.hal
     private static class NfwNotification {
-        private static final String KEY_PROTOCOL_STACK = "ProtocolStack";
-        private static final String KEY_OTHER_PROTOCOL_STACK_NAME = "OtherProtocolStackName";
-        private static final String KEY_REQUESTOR = "Requestor";
-        private static final String KEY_REQUESTOR_ID = "RequestorId";
-        private static final String KEY_RESPONSE_TYPE = "ResponseType";
-        private static final String KEY_IN_EMERGENCY_MODE = "InEmergencyMode";
-        private static final String KEY_IS_CACHED_LOCATION = "IsCachedLocation";
-
-        // This must match with NfwResponseType enum in IGnssVisibilityControlCallback.hal.
+        // These must match with NfwResponseType enum in IGnssVisibilityControlCallback.hal.
         private static final byte NFW_RESPONSE_TYPE_REJECTED = 0;
         private static final byte NFW_RESPONSE_TYPE_ACCEPTED_NO_LOCATION_PROVIDED = 1;
         private static final byte NFW_RESPONSE_TYPE_ACCEPTED_LOCATION_PROVIDED = 2;
@@ -281,30 +268,14 @@
             mIsCachedLocation = isCachedLocation;
         }
 
-        private void copyFieldsToIntent(Intent intent) {
-            intent.putExtra(KEY_PROTOCOL_STACK, mProtocolStack);
-            if (!TextUtils.isEmpty(mOtherProtocolStackName)) {
-                intent.putExtra(KEY_OTHER_PROTOCOL_STACK_NAME, mOtherProtocolStackName);
-            }
-            intent.putExtra(KEY_REQUESTOR, mRequestor);
-            if (!TextUtils.isEmpty(mRequestorId)) {
-                intent.putExtra(KEY_REQUESTOR_ID, mRequestorId);
-            }
-            intent.putExtra(KEY_RESPONSE_TYPE, mResponseType);
-            intent.putExtra(KEY_IN_EMERGENCY_MODE, mInEmergencyMode);
-            if (mResponseType == NFW_RESPONSE_TYPE_ACCEPTED_LOCATION_PROVIDED) {
-                intent.putExtra(KEY_IS_CACHED_LOCATION, mIsCachedLocation);
-            }
-        }
-
         @SuppressLint("DefaultLocale")
         public String toString() {
             return String.format(
-                    "[Notification] proxyAppPackageName: %s, protocolStack: %d"
-                            + ", otherProtocolStackName: %s, requestor: %d, requestorId: %s"
-                            + ", responseType: %d, inEmergencyMode: %b, isCachedLocation: %b",
-                    mProxyAppPackageName, mProtocolStack, mOtherProtocolStackName,
-                    mRequestor, mRequestorId, mResponseType, mInEmergencyMode, mIsCachedLocation);
+                    "{proxyAppPackageName: %s, protocolStack: %d, otherProtocolStackName: %s, "
+                            + "requestor: %d, requestorId: %s, responseType: %s, inEmergencyMode:"
+                            + " %b, isCachedLocation: %b}",
+                    mProxyAppPackageName, mProtocolStack, mOtherProtocolStackName, mRequestor,
+                    mRequestorId, getResponseTypeAsString(), mInEmergencyMode, mIsCachedLocation);
         }
 
         private String getResponseTypeAsString() {
@@ -405,7 +376,7 @@
     }
 
     private void handleNfwNotification(NfwNotification nfwNotification) {
-        if (DEBUG) Log.d(TAG, nfwNotification.toString());
+        if (DEBUG) Log.d(TAG, "Non-framework location access notification: " + nfwNotification);
 
         final String proxyAppPackageName = nfwNotification.mProxyAppPackageName;
         Boolean isLocationPermissionEnabled = mProxyAppToLocationPermissions.get(
@@ -421,39 +392,27 @@
         logEvent(nfwNotification, isPermissionMismatched);
 
         if (TextUtils.isEmpty(proxyAppPackageName)) {
-            Log.e(TAG, "ProxyAppPackageName field is not set. Not sending intent to proxy app for "
-                    + nfwNotification);
+            Log.e(TAG, "ProxyAppPackageName field is not set. AppOps service not notified "
+                    + "for non-framework location access notification: " + nfwNotification);
             return;
         }
 
         if (isLocationPermissionEnabled == null) {
-            // App is not in the configured list.
-            Log.e(TAG, "Could not find proxy app with name: " + proxyAppPackageName + " in the "
+            Log.w(TAG, "Could not find proxy app with name: " + proxyAppPackageName + " in the "
                     + "value specified for config parameter: "
-                    + GnssConfiguration.CONFIG_NFW_PROXY_APPS + ". Not sending intent to proxy app"
-                    + " for " + nfwNotification);
-            return;
-        }
-
-        // Send intent to non-framework location proxy app with notification information.
-        final Intent intent = new Intent(
-                proxyAppPackageName + NFW_INTENT_ACTION_NFW_LOCATION_ACCESS_SUFFIX);
-        final String proxAppActivityName =
-                proxyAppPackageName + NFW_PROXY_APP_PKG_ACTIVITY_NAME_SUFFIX;
-        intent.setClassName(proxyAppPackageName, proxAppActivityName);
-        intent.setType(NFW_INTENT_TYPE);
-        nfwNotification.copyFieldsToIntent(intent);
-
-        // Check if the proxy app is still installed.
-        final Integer clsAppUid = getApplicationUid(proxyAppPackageName);
-        if (clsAppUid == null || intent.resolveActivity(mPackageManager) == null) {
-            Log.i(TAG, "Proxy application " + proxyAppPackageName + " and/or activity "
-                    + proxAppActivityName + " is not found. Not sending"
-                    + " intent to proxy app for " + nfwNotification);
+                    + GnssConfiguration.CONFIG_NFW_PROXY_APPS + ". AppOps service not notified "
+                    + "for non-framework location access notification: " + nfwNotification);
             return;
         }
 
         // Display location icon attributed to this proxy app.
+        final Integer clsAppUid = getApplicationUid(proxyAppPackageName);
+        if (clsAppUid == null) {
+            Log.e(TAG, "Proxy app " + proxyAppPackageName + " is not found. AppOps service not "
+                    + "notified for non-framework location access notification: "
+                    + nfwNotification);
+            return;
+        }
         mAppOps.noteOpNoThrow(AppOpsManager.OP_FINE_LOCATION, clsAppUid, proxyAppPackageName);
 
         // Log proxy app permission mismatch between framework and GNSS HAL.
@@ -461,18 +420,8 @@
             Log.w(TAG, "Permission mismatch. Framework proxy app " + proxyAppPackageName
                     + " location permission is set to " + isLocationPermissionEnabled
                     + " but GNSS non-framework location access response type is "
-                    + nfwNotification.getResponseTypeAsString() + " for " + nfwNotification);
-        }
-
-        // Notify proxy app.
-        try {
-            if (DEBUG) {
-                Log.d(TAG, "Sending non-framework location access notification intent: " + intent);
-            }
-            mContext.startActivityAsUser(intent, UserHandle.getUserHandleForUid(clsAppUid));
-        } catch (ActivityNotFoundException e) {
-            Log.w(TAG, "Activity not found. Failed to send non-framework location access"
-                    + " notification intent to proxy app activity: " + proxAppActivityName);
+                    + nfwNotification.getResponseTypeAsString() + " for notification: "
+                    + nfwNotification);
         }
     }
 
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index b6995db..a53ab84 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -21,6 +21,7 @@
 import static android.content.Context.KEYGUARD_SERVICE;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 
+import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
 import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
 import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
@@ -2648,7 +2649,8 @@
         }
     }
 
-    private long addEscrowToken(byte[] token, int userId) throws RemoteException {
+    private long addEscrowToken(byte[] token, int userId, EscrowTokenStateChangeCallback callback)
+            throws RemoteException {
         if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId);
         synchronized (mSpManager) {
             enableSyntheticPasswordLocked();
@@ -2672,7 +2674,7 @@
                     throw new SecurityException("Escrow token is disabled on the current user");
                 }
             }
-            long handle = mSpManager.createTokenBasedSyntheticPassword(token, userId);
+            long handle = mSpManager.createTokenBasedSyntheticPassword(token, userId, callback);
             if (auth != null) {
                 mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
             }
@@ -2943,9 +2945,10 @@
     private final class LocalService extends LockSettingsInternal {
 
         @Override
-        public long addEscrowToken(byte[] token, int userId) {
+        public long addEscrowToken(byte[] token, int userId,
+                EscrowTokenStateChangeCallback callback) {
             try {
-                return LockSettingsService.this.addEscrowToken(token, userId);
+                return LockSettingsService.this.addEscrowToken(token, userId, callback);
             } catch (RemoteException re) {
                 throw re.rethrowFromSystemServer();
             }
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index dbcfbcd..142ad53 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -16,6 +16,8 @@
 
 package com.android.server.locksettings;
 
+import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.admin.DevicePolicyManager;
@@ -281,6 +283,7 @@
         byte[] secdiscardableOnDisk;
         byte[] weaverSecret;
         byte[] aggregatedSecret;
+        EscrowTokenStateChangeCallback mCallback;
     }
 
     private final Context mContext;
@@ -746,7 +749,12 @@
 
     private ArrayMap<Integer, ArrayMap<Long, TokenData>> tokenMap = new ArrayMap<>();
 
-    public long createTokenBasedSyntheticPassword(byte[] token, int userId) {
+    /**
+     * Create a token based Synthetic password for the given user.
+     * @return
+     */
+    public long createTokenBasedSyntheticPassword(byte[] token, int userId,
+            @Nullable EscrowTokenStateChangeCallback changeCallback) {
         long handle = generateHandle();
         if (!tokenMap.containsKey(userId)) {
             tokenMap.put(userId, new ArrayMap<>());
@@ -762,6 +770,7 @@
             tokenData.weaverSecret = null;
         }
         tokenData.aggregatedSecret = transformUnderSecdiscardable(token, secdiscardable);
+        tokenData.mCallback = changeCallback;
 
         tokenMap.get(userId).put(handle, tokenData);
         return handle;
@@ -810,6 +819,9 @@
         createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED, authToken,
                 tokenData.aggregatedSecret, 0L, userId);
         tokenMap.get(userId).remove(handle);
+        if (tokenData.mCallback != null) {
+            tokenData.mCallback.onEscrowTokenActivated(handle, userId);
+        }
         return true;
     }
 
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 7a87a57..0c0c23a 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -1112,7 +1112,7 @@
                             binder.linkToDeath(info, 0);
                             added = mServices.add(info);
                         } catch (RemoteException e) {
-                            // already dead
+                            Slog.e(TAG, "Failed to linkToDeath, already dead", e);
                         }
                     }
                     if (added) {
@@ -1144,6 +1144,11 @@
                         }
                     }
                 }
+
+                @Override
+                public void onNullBinding(ComponentName name) {
+                    Slog.v(TAG, "onNullBinding() called with: name = [" + name + "]");
+                }
             };
             if (!mContext.bindServiceAsUser(intent,
                     serviceConnection,
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d25360a..88e697c 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -251,7 +251,6 @@
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import java.util.function.BiConsumer;
-import java.util.function.Predicate;
 
 /** {@hide} */
 public class NotificationManagerService extends SystemService {
@@ -759,7 +758,7 @@
             synchronized (mNotificationLock) {
                 NotificationRecord r = mNotificationsByKey.get(key);
                 if (r == null) {
-                    Log.w(TAG, "No notification with key: " + key);
+                    Slog.w(TAG, "No notification with key: " + key);
                     return;
                 }
                 final long now = System.currentTimeMillis();
@@ -789,7 +788,7 @@
             synchronized (mNotificationLock) {
                 NotificationRecord r = mNotificationsByKey.get(key);
                 if (r == null) {
-                    Log.w(TAG, "No notification with key: " + key);
+                    Slog.w(TAG, "No notification with key: " + key);
                     return;
                 }
                 final long now = System.currentTimeMillis();
@@ -3133,7 +3132,7 @@
                 synchronized (mNotificationLock) {
                     final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
                     if (info.supportsProfiles()) {
-                        Log.e(TAG, "Ignoring deprecated cancelNotification(pkg, tag, id) "
+                        Slog.e(TAG, "Ignoring deprecated cancelNotification(pkg, tag, id) "
                                 + "from " + info.component
                                 + " use cancelNotification(key) instead.");
                     } else {
@@ -4553,7 +4552,7 @@
                     + ", incomingUserId=" + incomingUserId
                     + ", notificationUid=" + notificationUid
                     + ", notification=" + notification;
-            Log.e(TAG, noChannelStr);
+            Slog.e(TAG, noChannelStr);
             boolean appNotificationsOff = mPreferencesHelper.getImportance(pkg, notificationUid)
                     == NotificationManager.IMPORTANCE_NONE;
 
@@ -4650,7 +4649,7 @@
                     android.Manifest.permission.USE_FULL_SCREEN_INTENT, pkg);
             if (fullscreenIntentPermission != PERMISSION_GRANTED) {
                 notification.fullScreenIntent = null;
-                Log.w(TAG, "Package " + pkg +
+                Slog.w(TAG, "Package " + pkg +
                         ": Use of fullScreenIntent requires the USE_FULL_SCREEN_INTENT permission");
             }
         }
@@ -5179,7 +5178,7 @@
         // Ignore summary updates because we don't display most of the information.
         if (r.sbn.isGroup() && r.sbn.getNotification().isGroupSummary()) {
             if (DEBUG_INTERRUPTIVENESS) {
-                Log.v(TAG, "INTERRUPTIVENESS: "
+                Slog.v(TAG, "INTERRUPTIVENESS: "
                         +  r.getKey() + " is not interruptive: summary");
             }
             return false;
@@ -5187,7 +5186,7 @@
 
         if (old == null) {
             if (DEBUG_INTERRUPTIVENESS) {
-                Log.v(TAG, "INTERRUPTIVENESS: "
+                Slog.v(TAG, "INTERRUPTIVENESS: "
                         +  r.getKey() + " is interruptive: new notification");
             }
             return true;
@@ -5195,7 +5194,7 @@
 
         if (r == null) {
             if (DEBUG_INTERRUPTIVENESS) {
-                Log.v(TAG, "INTERRUPTIVENESS: "
+                Slog.v(TAG, "INTERRUPTIVENESS: "
                         +  r.getKey() + " is not interruptive: null");
             }
             return false;
@@ -5206,7 +5205,7 @@
 
         if (oldN.extras == null || newN.extras == null) {
             if (DEBUG_INTERRUPTIVENESS) {
-                Log.v(TAG, "INTERRUPTIVENESS: "
+                Slog.v(TAG, "INTERRUPTIVENESS: "
                         +  r.getKey() + " is not interruptive: no extras");
             }
             return false;
@@ -5216,7 +5215,7 @@
         // consider them one 'session'. Count them for everything else.
         if ((r.sbn.getNotification().flags & FLAG_FOREGROUND_SERVICE) != 0) {
             if (DEBUG_INTERRUPTIVENESS) {
-                Log.v(TAG, "INTERRUPTIVENESS: "
+                Slog.v(TAG, "INTERRUPTIVENESS: "
                         +  r.getKey() + " is not interruptive: foreground service");
             }
             return false;
@@ -5226,11 +5225,11 @@
         final String newTitle = String.valueOf(newN.extras.get(Notification.EXTRA_TITLE));
         if (!Objects.equals(oldTitle, newTitle)) {
             if (DEBUG_INTERRUPTIVENESS) {
-                Log.v(TAG, "INTERRUPTIVENESS: "
+                Slog.v(TAG, "INTERRUPTIVENESS: "
                         +  r.getKey() + " is interruptive: changed title");
-                Log.v(TAG, "INTERRUPTIVENESS: " + String.format("   old title: %s (%s@0x%08x)",
+                Slog.v(TAG, "INTERRUPTIVENESS: " + String.format("   old title: %s (%s@0x%08x)",
                         oldTitle, oldTitle.getClass(), oldTitle.hashCode()));
-                Log.v(TAG, "INTERRUPTIVENESS: " + String.format("   new title: %s (%s@0x%08x)",
+                Slog.v(TAG, "INTERRUPTIVENESS: " + String.format("   new title: %s (%s@0x%08x)",
                         newTitle, newTitle.getClass(), newTitle.hashCode()));
             }
             return true;
@@ -5240,18 +5239,18 @@
         final String newText = String.valueOf(newN.extras.get(Notification.EXTRA_TEXT));
         if (!Objects.equals(oldText, newText)) {
             if (DEBUG_INTERRUPTIVENESS) {
-                Log.v(TAG, "INTERRUPTIVENESS: "
+                Slog.v(TAG, "INTERRUPTIVENESS: "
                         + r.getKey() + " is interruptive: changed text");
-                Log.v(TAG, "INTERRUPTIVENESS: " + String.format("   old text: %s (%s@0x%08x)",
+                Slog.v(TAG, "INTERRUPTIVENESS: " + String.format("   old text: %s (%s@0x%08x)",
                         oldText, oldText.getClass(), oldText.hashCode()));
-                Log.v(TAG, "INTERRUPTIVENESS: " + String.format("   new text: %s (%s@0x%08x)",
+                Slog.v(TAG, "INTERRUPTIVENESS: " + String.format("   new text: %s (%s@0x%08x)",
                         newText, newText.getClass(), newText.hashCode()));
             }
             return true;
         }
         if (oldN.hasCompletedProgress() != newN.hasCompletedProgress()) {
             if (DEBUG_INTERRUPTIVENESS) {
-                Log.v(TAG, "INTERRUPTIVENESS: "
+                Slog.v(TAG, "INTERRUPTIVENESS: "
                     +  r.getKey() + " is interruptive: completed progress");
             }
             return true;
@@ -5259,7 +5258,7 @@
         // Actions
         if (Notification.areActionsVisiblyDifferent(oldN, newN)) {
             if (DEBUG_INTERRUPTIVENESS) {
-                Log.v(TAG, "INTERRUPTIVENESS: "
+                Slog.v(TAG, "INTERRUPTIVENESS: "
                         +  r.getKey() + " is interruptive: changed actions");
             }
             return true;
@@ -5272,7 +5271,7 @@
             // Style based comparisons
             if (Notification.areStyledNotificationsVisiblyDifferent(oldB, newB)) {
                 if (DEBUG_INTERRUPTIVENESS) {
-                    Log.v(TAG, "INTERRUPTIVENESS: "
+                    Slog.v(TAG, "INTERRUPTIVENESS: "
                             +  r.getKey() + " is interruptive: styles differ");
                 }
                 return true;
@@ -5281,7 +5280,7 @@
             // Remote views
             if (Notification.areRemoteViewsChanged(oldB, newB)) {
                 if (DEBUG_INTERRUPTIVENESS) {
-                    Log.v(TAG, "INTERRUPTIVENESS: "
+                    Slog.v(TAG, "INTERRUPTIVENESS: "
                             +  r.getKey() + " is interruptive: remoteviews differ");
                 }
                 return true;
@@ -5510,12 +5509,12 @@
             // Ignore summary updates because we don't display most of the information.
             if (record.sbn.isGroup() && record.sbn.getNotification().isGroupSummary()) {
                 if (DEBUG_INTERRUPTIVENESS) {
-                    Log.v(TAG, "INTERRUPTIVENESS: "
+                    Slog.v(TAG, "INTERRUPTIVENESS: "
                             + record.getKey() + " is not interruptive: summary");
                 }
             } else {
                 if (DEBUG_INTERRUPTIVENESS) {
-                    Log.v(TAG, "INTERRUPTIVENESS: "
+                    Slog.v(TAG, "INTERRUPTIVENESS: "
                             + record.getKey() + " is interruptive: alerted");
                 }
                 record.setInterruptive(true);
@@ -6603,7 +6602,7 @@
         String pkg = r.sbn.getPackageName();
 
         if (pkg == null) {
-            if (DBG) Log.e(TAG, "No package for group summary: " + r.getKey());
+            if (DBG) Slog.e(TAG, "No package for group summary: " + r.getKey());
             return;
         }
 
@@ -6862,7 +6861,7 @@
                 return;
             }
         } catch (RemoteException re) {
-            if (DBG) Log.e(TAG, "Unable to confirm if it's safe to skip category "
+            if (DBG) Slog.e(TAG, "Unable to confirm if it's safe to skip category "
                     + "restrictions check thus the check will be done anyway");
         }
         if (Notification.CATEGORY_CAR_EMERGENCY.equals(notification.category)
@@ -7104,7 +7103,7 @@
                     canUseManagedServices = false;
                 }
             } catch (RemoteException e) {
-                Log.e(TAG, "can't talk to pm", e);
+                Slog.e(TAG, "can't talk to pm", e);
             }
         }
 
@@ -7247,21 +7246,29 @@
             try {
                 assistant.onNotificationsSeen(keys);
             } catch (RemoteException ex) {
-                Log.e(TAG, "unable to notify assistant (seen): " + assistant, ex);
+                Slog.e(TAG, "unable to notify assistant (seen): " + assistant, ex);
             }
         }
 
         @GuardedBy("mNotificationLock")
         private void onNotificationEnqueuedLocked(final NotificationRecord r) {
+            final boolean debug = isVerboseLogEnabled();
+            if (debug) {
+                Slog.v(TAG, "onNotificationEnqueuedLocked() called with: r = [" + r + "]");
+            }
             final StatusBarNotification sbn = r.sbn;
             notifyAssistantLocked(
                     sbn,
                     true /* sameUserOnly */,
                     (assistant, sbnHolder) -> {
                         try {
+                            if (debug) {
+                                Slog.v(TAG,
+                                        "calling onNotificationEnqueuedWithChannel " + sbnHolder);
+                            }
                             assistant.onNotificationEnqueuedWithChannel(sbnHolder, r.getChannel());
                         } catch (RemoteException ex) {
-                            Log.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex);
+                            Slog.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex);
                         }
                     });
         }
@@ -7279,7 +7286,7 @@
                         try {
                             assistant.onNotificationExpansionChanged(key, isUserAction, isExpanded);
                         } catch (RemoteException ex) {
-                            Log.e(TAG, "unable to notify assistant (expanded): " + assistant, ex);
+                            Slog.e(TAG, "unable to notify assistant (expanded): " + assistant, ex);
                         }
                     });
         }
@@ -7295,7 +7302,7 @@
                         try {
                             assistant.onNotificationDirectReply(key);
                         } catch (RemoteException ex) {
-                            Log.e(TAG, "unable to notify assistant (expanded): " + assistant, ex);
+                            Slog.e(TAG, "unable to notify assistant (expanded): " + assistant, ex);
                         }
                     });
         }
@@ -7316,7 +7323,7 @@
                                             ? NotificationAssistantService.SOURCE_FROM_ASSISTANT
                                             : NotificationAssistantService.SOURCE_FROM_APP);
                         } catch (RemoteException ex) {
-                            Log.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex);
+                            Slog.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex);
                         }
                     });
         }
@@ -7338,7 +7345,7 @@
                                             ? NotificationAssistantService.SOURCE_FROM_ASSISTANT
                                             : NotificationAssistantService.SOURCE_FROM_APP);
                         } catch (RemoteException ex) {
-                            Log.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex);
+                            Slog.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex);
                         }
                     });
         }
@@ -7358,7 +7365,7 @@
                             assistant.onNotificationSnoozedUntilContext(
                                     sbnHolder, snoozeCriterionId);
                         } catch (RemoteException ex) {
-                            Log.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex);
+                            Slog.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex);
                         }
                     });
         }
@@ -7380,9 +7387,19 @@
             TrimCache trimCache = new TrimCache(sbn);
             // There should be only one, but it's a list, so while we enforce
             // singularity elsewhere, we keep it general here, to avoid surprises.
+
+            final boolean debug = isVerboseLogEnabled();
+            if (debug) {
+                Slog.v(TAG,
+                        "notifyAssistantLocked() called with: sbn = [" + sbn + "], sameUserOnly = ["
+                                + sameUserOnly + "], callback = [" + callback + "]");
+            }
             for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) {
                 boolean sbnVisible = isVisibleToListener(sbn, info)
                         && (!sameUserOnly || info.isSameUser(sbn.getUserId()));
+                if (debug) {
+                    Slog.v(TAG, "notifyAssistantLocked info=" + info + " snbVisible=" + sbnVisible);
+                }
                 if (!sbnVisible) {
                     continue;
                 }
@@ -7436,6 +7453,10 @@
                 }
             }
         }
+
+        private boolean isVerboseLogEnabled() {
+            return Log.isLoggable("notification_assistant", Log.VERBOSE);
+        }
     }
 
     public class NotificationListeners extends ManagedServices {
@@ -7530,7 +7551,7 @@
                      try {
                         listener.onStatusBarIconsBehaviorChanged(hideSilentStatusIcons);
                     } catch (RemoteException ex) {
-                        Log.e(TAG, "unable to notify listener "
+                        Slog.e(TAG, "unable to notify listener "
                                 + "(hideSilentStatusIcons): " + listener, ex);
                     }
                 });
@@ -7824,7 +7845,7 @@
             try {
                 listener.onNotificationPosted(sbnHolder, rankingUpdate);
             } catch (RemoteException ex) {
-                Log.e(TAG, "unable to notify listener (posted): " + listener, ex);
+                Slog.e(TAG, "unable to notify listener (posted): " + listener, ex);
             }
         }
 
@@ -7838,7 +7859,7 @@
             try {
                 listener.onNotificationRemoved(sbnHolder, rankingUpdate, stats, reason);
             } catch (RemoteException ex) {
-                Log.e(TAG, "unable to notify listener (removed): " + listener, ex);
+                Slog.e(TAG, "unable to notify listener (removed): " + listener, ex);
             }
         }
 
@@ -7848,7 +7869,7 @@
             try {
                 listener.onNotificationRankingUpdate(rankingUpdate);
             } catch (RemoteException ex) {
-                Log.e(TAG, "unable to notify listener (ranking update): " + listener, ex);
+                Slog.e(TAG, "unable to notify listener (ranking update): " + listener, ex);
             }
         }
 
@@ -7857,7 +7878,7 @@
             try {
                 listener.onListenerHintsChanged(hints);
             } catch (RemoteException ex) {
-                Log.e(TAG, "unable to notify listener (listener hints): " + listener, ex);
+                Slog.e(TAG, "unable to notify listener (listener hints): " + listener, ex);
             }
         }
 
@@ -7867,7 +7888,7 @@
             try {
                 listener.onInterruptionFilterChanged(interruptionFilter);
             } catch (RemoteException ex) {
-                Log.e(TAG, "unable to notify listener (interruption filter): " + listener, ex);
+                Slog.e(TAG, "unable to notify listener (interruption filter): " + listener, ex);
             }
         }
 
@@ -7878,7 +7899,7 @@
             try {
                 listener.onNotificationChannelModification(pkg, user, channel, modificationType);
             } catch (RemoteException ex) {
-                Log.e(TAG, "unable to notify listener (channel changed): " + listener, ex);
+                Slog.e(TAG, "unable to notify listener (channel changed): " + listener, ex);
             }
         }
 
@@ -7889,7 +7910,7 @@
             try {
                 listener.onNotificationChannelGroupModification(pkg, user, group, modificationType);
             } catch (RemoteException ex) {
-                Log.e(TAG, "unable to notify listener (channel group changed): " + listener, ex);
+                Slog.e(TAG, "unable to notify listener (channel group changed): " + listener, ex);
             }
         }
 
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 48818f5..46ce4bf 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -637,25 +637,17 @@
                     final ArrayList<String> people =
                             adjustment.getSignals().getStringArrayList(Adjustment.KEY_PEOPLE);
                     setPeopleOverride(people);
-                    MetricsLogger.action(getAdjustmentLogMaker()
-                            .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_PEOPLE, people.size()));
                 }
                 if (signals.containsKey(Adjustment.KEY_SNOOZE_CRITERIA)) {
                     final ArrayList<SnoozeCriterion> snoozeCriterionList =
                             adjustment.getSignals().getParcelableArrayList(
                                     Adjustment.KEY_SNOOZE_CRITERIA);
                     setSnoozeCriteria(snoozeCriterionList);
-                    MetricsLogger.action(getAdjustmentLogMaker()
-                            .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SNOOZE_CRITERIA,
-                                    snoozeCriterionList.size()));
                 }
                 if (signals.containsKey(Adjustment.KEY_GROUP_KEY)) {
                     final String groupOverrideKey =
                             adjustment.getSignals().getString(Adjustment.KEY_GROUP_KEY);
                     setOverrideGroupKey(groupOverrideKey);
-                    MetricsLogger.action(getAdjustmentLogMaker()
-                            .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_GROUP_KEY,
-                                    groupOverrideKey));
                 }
                 if (signals.containsKey(Adjustment.KEY_USER_SENTIMENT)) {
                     // Only allow user sentiment update from assistant if user hasn't already
@@ -664,32 +656,20 @@
                             && (getChannel().getUserLockedFields() & USER_LOCKED_IMPORTANCE) == 0) {
                         setUserSentiment(adjustment.getSignals().getInt(
                                 Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEUTRAL));
-                        MetricsLogger.action(getAdjustmentLogMaker()
-                                .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_USER_SENTIMENT,
-                                        getUserSentiment()));
                     }
                 }
                 if (signals.containsKey(Adjustment.KEY_CONTEXTUAL_ACTIONS)) {
                     setSystemGeneratedSmartActions(
                             signals.getParcelableArrayList(Adjustment.KEY_CONTEXTUAL_ACTIONS));
-                    MetricsLogger.action(getAdjustmentLogMaker()
-                            .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SMART_ACTIONS,
-                                    getSystemGeneratedSmartActions().size()));
                 }
                 if (signals.containsKey(Adjustment.KEY_TEXT_REPLIES)) {
                     setSmartReplies(signals.getCharSequenceArrayList(Adjustment.KEY_TEXT_REPLIES));
-                    MetricsLogger.action(getAdjustmentLogMaker()
-                            .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SMART_REPLIES,
-                                    getSmartReplies().size()));
                 }
                 if (signals.containsKey(Adjustment.KEY_IMPORTANCE)) {
                     int importance = signals.getInt(Adjustment.KEY_IMPORTANCE);
                     importance = Math.max(IMPORTANCE_UNSPECIFIED, importance);
                     importance = Math.min(IMPORTANCE_HIGH, importance);
                     setAssistantImportance(importance);
-                    MetricsLogger.action(getAdjustmentLogMaker()
-                            .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_IMPORTANCE,
-                                    importance));
                 }
             }
             // We have now gotten all the information out of the adjustments and can forget them.
@@ -1280,12 +1260,6 @@
         return getLogMaker().setCategory(MetricsEvent.NOTIFICATION_ITEM);
     }
 
-    public LogMaker getAdjustmentLogMaker() {
-        return getLogMaker()
-                .setCategory(MetricsEvent.NOTIFICATION_ITEM)
-                .setType(MetricsEvent.TYPE_NOTIFICATION_ASSISTANT_ADJUSTMENT);
-    }
-
     @VisibleForTesting
     static final class Light {
         public final int color;
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 22a85eb..4ee6eaf 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -35,6 +35,7 @@
 import android.content.pm.ParceledListSlice;
 import android.content.pm.Signature;
 import android.content.rollback.IRollbackManager;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -117,9 +118,11 @@
         final PackageInfo packageInfo = mApexManager.getActivePackage(packageName);
 
         if (packageInfo == null) {
-            // TODO: What is the right thing to do here ? This implies there's no active package
-            // with the given name. This should never be the case in production (where we only
-            // accept updates to existing APEXes) but may be required for testing.
+            // Only allow installing new apexes if on a debuggable build.
+            if (!Build.IS_DEBUGGABLE) {
+                Slog.w(TAG, "Attempted to install new apex " + packageName + " on user build");
+                return false;
+            }
             return true;
         }
 
@@ -498,19 +501,21 @@
             Slog.w(TAG, "Cannot abort applied session!");
             return;
         }
-        if (isStagedSessionFinalized(session.sessionId)) {
-            Slog.w(TAG, "Cannot abort session because it is not active or APEXD is not reachable");
-            return;
-        }
-
-        mApexManager.abortActiveSession();
-
         abortSession(session);
+
+        boolean hasApex = sessionContainsApex(session);
+        if (hasApex) {
+            ApexSessionInfo apexSession = mApexManager.getStagedSessionInfo(session.sessionId);
+            if (apexSession == null || isApexSessionFinalized(apexSession)) {
+                Slog.w(TAG,
+                        "Cannot abort session because it is not active or APEXD is not reachable");
+                return;
+            }
+            mApexManager.abortActiveSession();
+        }
     }
 
-    private boolean isStagedSessionFinalized(int sessionId) {
-        ApexSessionInfo session = mApexManager.getStagedSessionInfo(sessionId);
-
+    private boolean isApexSessionFinalized(ApexSessionInfo session) {
         /* checking if the session is in a final state, i.e., not active anymore */
         return session.isUnknown || session.isActivationFailed || session.isSuccess
                 || session.isRolledBack;
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 7e4365d..ae4ff03 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -120,6 +120,7 @@
             UserManager.DISALLOW_UNMUTE_DEVICE,
             UserManager.DISALLOW_AUTOFILL,
             UserManager.DISALLOW_CONTENT_CAPTURE,
+            UserManager.DISALLOW_CONTENT_SUGGESTIONS,
             UserManager.DISALLOW_USER_SWITCH,
             UserManager.DISALLOW_UNIFIED_PASSWORD,
             UserManager.DISALLOW_CONFIG_LOCATION,
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index 7d03d82..16d11ef 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -89,9 +89,6 @@
     @GuardedBy("mLock")
     private ArrayMap<String, Temperature> mTemperatureMap = new ArrayMap<>();
 
-    /** Local PMS handle. */
-    private final PowerManager mPowerManager;
-
     /** HAL wrapper. */
     private ThermalHalWrapper mHalWrapper;
 
@@ -109,7 +106,6 @@
     @VisibleForTesting
     ThermalManagerService(Context context, @Nullable ThermalHalWrapper halWrapper) {
         super(context);
-        mPowerManager = context.getSystemService(PowerManager.class);
         mHalWrapper = halWrapper;
         // Initialize to invalid to send status onActivityManagerReady
         mStatus = INVALID_THROTTLING;
@@ -254,10 +250,11 @@
         }
     }
 
-    private void shutdownIfNeededLocked(Temperature temperature) {
+    private void shutdownIfNeeded(Temperature temperature) {
         if (temperature.getStatus() != Temperature.THROTTLING_SHUTDOWN) {
             return;
         }
+        final PowerManager powerManager = getContext().getSystemService(PowerManager.class);
         switch (temperature.getType()) {
             case Temperature.TYPE_CPU:
                 // Fall through
@@ -266,17 +263,17 @@
             case Temperature.TYPE_NPU:
                 // Fall through
             case Temperature.TYPE_SKIN:
-                mPowerManager.shutdown(false, PowerManager.SHUTDOWN_THERMAL_STATE, false);
+                powerManager.shutdown(false, PowerManager.SHUTDOWN_THERMAL_STATE, false);
                 break;
             case Temperature.TYPE_BATTERY:
-                mPowerManager.shutdown(false, PowerManager.SHUTDOWN_BATTERY_THERMAL_STATE, false);
+                powerManager.shutdown(false, PowerManager.SHUTDOWN_BATTERY_THERMAL_STATE, false);
                 break;
         }
     }
 
     private void onTemperatureChanged(Temperature temperature, boolean sendStatus) {
+        shutdownIfNeeded(temperature);
         synchronized (mLock) {
-            shutdownIfNeededLocked(temperature);
             Temperature old = mTemperatureMap.put(temperature.getName(), temperature);
             if (old != null) {
                 if (old.getStatus() != temperature.getStatus()) {
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index 28fee4e..4614355 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -43,8 +43,6 @@
 import android.util.Log;
 import android.util.Slog;
 
-import com.android.internal.policy.IKeyguardDismissCallback;
-
 import java.util.Collections;
 import java.util.List;
 
@@ -495,6 +493,21 @@
         }
     }
 
+    /**
+     * @see android.service.trust.TrustAgentService#onTokenStateReceived()
+     *
+     */
+    public void onEscrowTokenActivated(long handle, int userId) {
+        if (DEBUG) Slog.d(TAG, "onEscrowTokenActivated: " + handle + " user: " + userId);
+        if (mTrustAgentService != null) {
+            try {
+                mTrustAgentService.onTokenStateReceived(handle,
+                        TrustAgentService.TOKEN_STATE_ACTIVE);
+            } catch (RemoteException e) {
+                onError(e);
+            }
+        }
+    }
     private void setCallback(ITrustAgentServiceCallback callback) {
         try {
             if (mTrustAgentService != null) {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index c7044a1..3a39053 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -409,7 +409,10 @@
     }
 
     public long addEscrowToken(byte[] token, int userId) {
-        return mLockPatternUtils.addEscrowToken(token, userId);
+        return mLockPatternUtils.addEscrowToken(token, userId,
+                (long handle, int userid) -> {
+                    dispatchEscrowTokenActivatedLocked(handle, userid);
+                });
     }
 
     public boolean removeEscrowToken(long handle, int userId) {
@@ -662,6 +665,15 @@
         }
     }
 
+    private void dispatchEscrowTokenActivatedLocked(long handle, int userId) {
+        for (int i = 0; i < mActiveAgents.size(); i++) {
+            AgentInfo agent = mActiveAgents.valueAt(i);
+            if (agent.userId == userId) {
+                agent.agent.onEscrowTokenActivated(handle, userId);
+            }
+        }
+    }
+
     void updateDevicePolicyFeatures() {
         boolean changed = false;
         for (int i = 0; i < mActiveAgents.size(); i++) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 36251f5..d7922b15 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -13352,8 +13352,8 @@
                 if (policy.mPasswordTokenHandle != 0) {
                     mLockPatternUtils.removeEscrowToken(policy.mPasswordTokenHandle, userHandle);
                 }
-
-                policy.mPasswordTokenHandle = mLockPatternUtils.addEscrowToken(token, userHandle);
+                policy.mPasswordTokenHandle = mLockPatternUtils.addEscrowToken(token,
+                        userHandle, /*EscrowTokenStateChangeCallback*/ null);
                 saveSettingsLocked(userHandle);
                 return policy.mPasswordTokenHandle != 0;
             } finally {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 4293247..039a4b7 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -29,6 +29,7 @@
 import static android.os.UserManagerInternal.CAMERA_DISABLED_LOCALLY;
 import static android.os.UserManagerInternal.CAMERA_NOT_DISABLED;
 
+import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
 import static com.android.server.testutils.TestUtils.assertExpectException;
 
 import static org.mockito.Matchers.any;
@@ -4157,8 +4158,9 @@
         final byte[] token = new byte[32];
         final long handle = 123456;
         final String password = "password";
-        when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM)))
-            .thenReturn(handle);
+        when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM),
+                nullable(EscrowTokenStateChangeCallback.class)))
+                .thenReturn(handle);
         assertTrue(dpm.setResetPasswordToken(admin1, token));
 
         // test password activation
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index d343ac1..77515258 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -338,7 +338,7 @@
         initializeCredentialUnderSP(password, PRIMARY_USER_ID);
         final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
 
-        long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
+        long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
         assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
 
         mService.verifyCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
@@ -367,7 +367,7 @@
         initializeCredentialUnderSP(password, PRIMARY_USER_ID);
         final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
 
-        long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
+        long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
         assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
 
         mService.verifyCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
@@ -393,7 +393,7 @@
         initializeCredentialUnderSP(password, PRIMARY_USER_ID);
         final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
 
-        long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
+        long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
         assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
 
         mService.verifyCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
@@ -417,7 +417,7 @@
             throws RemoteException {
         final String token = "some-high-entropy-secure-token";
         enableSyntheticPassword();
-        long handle = mLocalService.addEscrowToken(token.getBytes(), PRIMARY_USER_ID);
+        long handle = mLocalService.addEscrowToken(token.getBytes(), PRIMARY_USER_ID, null);
         assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
         assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
         assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
@@ -427,7 +427,7 @@
             throws RemoteException {
         final String token = "some-high-entropy-secure-token";
         initializeCredentialUnderSP(null, PRIMARY_USER_ID);
-        long handle = mLocalService.addEscrowToken(token.getBytes(), PRIMARY_USER_ID);
+        long handle = mLocalService.addEscrowToken(token.getBytes(), PRIMARY_USER_ID, null);
         assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
         assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
         assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
@@ -443,7 +443,7 @@
                 PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
         enableSyntheticPassword();
 
-        long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
+        long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
         // Token not activated immediately since user password exists
         assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
         // Activate token (password gets migrated to SP at the same time)
@@ -461,7 +461,7 @@
 
         mHasSecureLockScreen = false;
         enableSyntheticPassword();
-        long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID);
+        long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
         assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
 
         try {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 0de807d..e9edba5 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -185,6 +185,18 @@
     }
 
     @MediumTest
+    public void testRemoveUserByHandle_ThrowsException() {
+        synchronized (mUserRemoveLock) {
+            try {
+                mUserManager.removeUser(null);
+                fail("Expected IllegalArgumentException on passing in a null UserHandle.");
+            } catch (IllegalArgumentException expected) {
+                // Do nothing - exception is expected.
+            }
+        }
+    }
+
+    @MediumTest
     public void testAddGuest() throws Exception {
         UserInfo userInfo1 = createUser("Guest 1", UserInfo.FLAG_GUEST);
         UserInfo userInfo2 = createUser("Guest 2", UserInfo.FLAG_GUEST);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
old mode 100644
new mode 100755
index 5262cf8..d79a168
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2653,6 +2653,18 @@
      */
     public static final String KEY_USE_USIM_BOOL = "use_usim_bool";
 
+    /**
+     * Determines whether the carrier wants to cancel the cs reject notification automatically
+     * when the voice registration state changes.
+     * If true, the notification will be automatically removed
+     *          when the voice registration state changes.
+     * If false, the notification will persist until the user dismisses it,
+     *           the SIM is removed, or the device is rebooted.
+     * @hide
+     */
+    public static final String KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION =
+            "carrier_auto_cancel_cs_notification";
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -3039,6 +3051,7 @@
                 });
         sDefaults.putStringArray(KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY, new String[0]);
         sDefaults.putBoolean(KEY_USE_USIM_BOOL, false);
+        sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false);
     }
 
     /**
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 251ca0c..5336141 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -183,11 +183,11 @@
   EXPECT_THAT(str->untranslatable_sections, IsEmpty());
 
   // Preserve non-ASCII whitespace including extended ASCII characters
-  EXPECT_TRUE(TestParse(R"(<string name="foo3">&#160;Hello&#160;</string>)"));
+  EXPECT_TRUE(TestParse(R"(<string name="foo3">&#160;Hello&#x202F;World&#160;</string>)"));
 
   str = test::GetValue<String>(&table_, "string/foo3");
   ASSERT_THAT(str, NotNull());
-  EXPECT_THAT(*str->value, StrEq("\xC2\xA0Hello\xC2\xA0"));
+  EXPECT_THAT(*str->value, StrEq("\xC2\xA0Hello\xE2\x80\xAFWorld\xC2\xA0"));
   EXPECT_THAT(str->untranslatable_sections, IsEmpty());
 
   EXPECT_TRUE(TestParse(R"(<string name="foo4">2005年6月1日</string>)"));
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index f0e4d9e..a571aee 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -40,8 +40,6 @@
 namespace aapt {
 namespace ResourceUtils {
 
-constexpr int32_t kNonBreakingSpace = 0xa0;
-
 Maybe<ResourceName> ToResourceName(
     const android::ResTable::resource_name& name_in) {
   // TODO: Remove this when ResTable and AssetManager(1) are removed from AAPT2
@@ -854,7 +852,8 @@
   Utf8Iterator iter(text);
   while (iter.HasNext()) {
     char32_t codepoint = iter.Next();
-    if (!preserve_spaces_ && !quote_ && codepoint != kNonBreakingSpace && iswspace(codepoint)) {
+    if (!preserve_spaces_ && !quote_ && (codepoint <= std::numeric_limits<char>::max())
+                                         && isspace(static_cast<char>(codepoint))) {
       if (!last_codepoint_was_space_) {
         // Emit a space if it's the first.
         xml_string_.text += ' ';
diff --git a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
index 44d88bb..6f6c1aa 100644
--- a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
+++ b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
@@ -97,7 +97,7 @@
     /**
      * The suffix of the generated class name after the class's binary name.
      */
-    private static final String GENERATED_CLASS_SUFFIX = "$$InspectionCompanion";
+    private static final String GENERATED_CLASS_SUFFIX = "$InspectionCompanion";
 
     /**
      * The null resource ID, copied to avoid a host dependency on platform code.
diff --git a/tools/processors/view_inspector/src/java/android/processor/view/inspector/PlatformInspectableProcessor.java b/tools/processors/view_inspector/src/java/android/processor/view/inspector/PlatformInspectableProcessor.java
index 01d9430..fd142c6 100644
--- a/tools/processors/view_inspector/src/java/android/processor/view/inspector/PlatformInspectableProcessor.java
+++ b/tools/processors/view_inspector/src/java/android/processor/view/inspector/PlatformInspectableProcessor.java
@@ -34,6 +34,7 @@
 import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.Modifier;
 import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
 
 
 /**
@@ -127,13 +128,38 @@
 
             final InspectableClassModel model = modelMap.computeIfAbsent(
                     classElement.get().getQualifiedName().toString(),
-                    k -> new InspectableClassModel(ClassName.get(classElement.get())));
+                    k -> {
+                        if (hasNestedInspectionCompanion(classElement.get())) {
+                            fail(
+                                    String.format(
+                                            "Class %s already has an inspection companion.",
+                                            classElement.get().getQualifiedName().toString()),
+                                    element);
+                        }
+                        return new InspectableClassModel(ClassName.get(classElement.get()));
+                    });
 
             processor.process(element, model);
         }
     }
 
     /**
+     * Determine if a class has a nested class named {@code InspectionCompanion}.
+     *
+     * @param typeElement A type element representing the class to check
+     * @return f the class contains a class named {@code InspectionCompanion}
+     */
+    private static boolean hasNestedInspectionCompanion(TypeElement typeElement) {
+        for (TypeElement nestedClass : ElementFilter.typesIn(typeElement.getEnclosedElements())) {
+            if (nestedClass.getSimpleName().toString().equals("InspectionCompanion")) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
      * Get the nearest enclosing class if there is one.
      *
      * If {@param element} represents a class, it will be returned wrapped in an optional.
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/FieldProperty.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/FieldProperty.java.txt
index a44c43e..9a0fe5b 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/FieldProperty.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/FieldProperty.java.txt
@@ -12,7 +12,7 @@
  * Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
  * on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
  */
-public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+public final class TestNode$InspectionCompanion implements InspectionCompanion<TestNode> {
     /**
      * Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
      */
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntEnum.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntEnum.java.txt
index 764aa8b..b491de1 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntEnum.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntEnum.java.txt
@@ -13,7 +13,7 @@
  * Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
  * on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
  */
-public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+public final class TestNode$InspectionCompanion implements InspectionCompanion<TestNode> {
     /**
      * Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
      */
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntFlag.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntFlag.java.txt
index 75f2813..7d18058 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntFlag.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/IntFlag.java.txt
@@ -12,7 +12,7 @@
  * Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
  * on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
  */
-public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+public final class TestNode$InspectionCompanion implements InspectionCompanion<TestNode> {
     /**
      * Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
      */
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NestedClass.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NestedClass.java.txt
index 0cac462..dc27abb 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NestedClass.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NestedClass.java.txt
@@ -11,7 +11,7 @@
  * Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
  * on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
  */
-public final class Outer$Inner$$InspectionCompanion implements InspectionCompanion<Outer.Inner> {
+public final class Outer$Inner$InspectionCompanion implements InspectionCompanion<Outer.Inner> {
     /**
      * Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
      */
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NoAttributeId.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NoAttributeId.java.txt
index ce0f867..738bcd3 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NoAttributeId.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NoAttributeId.java.txt
@@ -11,7 +11,7 @@
  * Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
  * on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
  */
-public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+public final class TestNode$InspectionCompanion implements InspectionCompanion<TestNode> {
     /**
      * Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
      */
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NodeName.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NodeName.java.txt
index f7357fe..82dd66e 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NodeName.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NodeName.java.txt
@@ -12,7 +12,7 @@
  * Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
  * on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
  */
-public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+public final class TestNode$InspectionCompanion implements InspectionCompanion<TestNode> {
     /**
      * Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
      */
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt
index 556d8dd..08ea696 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt
@@ -12,7 +12,7 @@
  * Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
  * on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
  */
-public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+public final class TestNode$InspectionCompanion implements InspectionCompanion<TestNode> {
     /**
      * Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
      */
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SuppliedAttributeId.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SuppliedAttributeId.java.txt
index d72cdd5..3bfa78a 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SuppliedAttributeId.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SuppliedAttributeId.java.txt
@@ -11,7 +11,7 @@
  * Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
  * on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
  */
-public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+public final class TestNode$InspectionCompanion implements InspectionCompanion<TestNode> {
     /**
      * Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
      */
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySession.java b/wifi/java/android/net/wifi/aware/DiscoverySession.java
index a47e70b..d97f6fb 100644
--- a/wifi/java/android/net/wifi/aware/DiscoverySession.java
+++ b/wifi/java/android/net/wifi/aware/DiscoverySession.java
@@ -36,7 +36,7 @@
  * <ul>
  *      <li>Sending messages: {@link #sendMessage(PeerHandle, int, byte[])} method.
  *      <li>Creating a network-specifier when requesting a Aware connection using
- *      {@link WifiAwareManager.NetworkSpecifierBuilder}.
+ *      {@link WifiAwareNetworkSpecifier.Builder}.
  * </ul>
  * <p>
  * The {@link #close()} method must be called to destroy discovery sessions once they are
@@ -270,7 +270,7 @@
      * <p>
      * To set up an encrypted link use the
      * {@link #createNetworkSpecifierPassphrase(PeerHandle, String)} API.
-     * @deprecated Use the replacement {@link WifiAwareManager.NetworkSpecifierBuilder}.
+     * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}.
      *
      * @param peerHandle The peer's handle obtained through
      * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}
@@ -320,7 +320,7 @@
      * <p>
      * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
      * and a Publisher is a RESPONDER.
-     * @deprecated Use the replacement {@link WifiAwareManager.NetworkSpecifierBuilder}.
+     * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}.
      *
      * @param peerHandle The peer's handle obtained through
      * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
@@ -380,7 +380,7 @@
      * <p>
      * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
      * and a Publisher is a RESPONDER.
-     * @deprecated Use the replacement {@link WifiAwareManager.NetworkSpecifierBuilder}.
+     * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}.
      *
      * @param peerHandle The peer's handle obtained through
      * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index 1a5cd5a..c9b0b12 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -21,7 +21,6 @@
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.content.Context;
 import android.net.ConnectivityManager;
@@ -35,7 +34,6 @@
 import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
-import android.text.TextUtils;
 import android.util.Log;
 
 import libcore.util.HexEncoding;
@@ -59,7 +57,7 @@
  * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback, Handler)}.
  * <li>Create a Aware network specifier to be used with
  * {@link ConnectivityManager#requestNetwork(NetworkRequest, ConnectivityManager.NetworkCallback)}
- * to set-up a Aware connection with a peer. Refer to {@link NetworkSpecifierBuilder}.
+ * to set-up a Aware connection with a peer. Refer to {@link WifiAwareNetworkSpecifier.Builder}.
  * </ul>
  * <p>
  *     Aware may not be usable when Wi-Fi is disabled (and other conditions). To validate that
@@ -108,7 +106,7 @@
  *        <li>{@link NetworkRequest.Builder#addTransportType(int)} of
  *        {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
  *        <li>{@link NetworkRequest.Builder#setNetworkSpecifier(String)} using
- *        {@link NetworkSpecifierBuilder}.
+ *        {@link WifiAwareNetworkSpecifier.Builder}.
  *    </ul>
  */
 @SystemService(Context.WIFI_AWARE_SERVICE)
@@ -408,7 +406,7 @@
 
         if (!WifiAwareUtils.isLegacyVersion(mContext, Build.VERSION_CODES.Q)) {
             throw new UnsupportedOperationException(
-                    "API not deprecated - use WifiAwareManager.NetworkSpecifierBuilder");
+                    "API not deprecated - use WifiAwareNetworkSpecifier.Builder");
         }
 
         if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
@@ -813,198 +811,4 @@
             mOriginalCallback.onSessionTerminated();
         }
     }
-
-    /**
-     * A builder class for a Wi-Fi Aware network specifier to set up an Aware connection with a
-     * peer.
-     * <p>
-     * Note that all Wi-Fi Aware connection specifier objects must call the
-     * {@link NetworkSpecifierBuilder#setDiscoverySession(DiscoverySession)} to specify the context
-     * within which the connection is created, and
-     * {@link NetworkSpecifierBuilder#setPeerHandle(PeerHandle)} to specify the peer to which the
-     * connection is created.
-     */
-    public static final class NetworkSpecifierBuilder {
-        private DiscoverySession mDiscoverySession;
-        private PeerHandle mPeerHandle;
-        private String mPskPassphrase;
-        private byte[] mPmk;
-        private int mPort = 0; // invalid value
-        private int mTransportProtocol = -1; // invalid value
-
-        /**
-         * Configure the {@link PublishDiscoverySession} or {@link SubscribeDiscoverySession}
-         * discovery session in whose context the connection is created.
-         * <p>
-         * Note: this method must be called for any connection request!
-         *
-         * @param discoverySession A Wi-Fi Aware discovery session.
-         * @return the current {@link NetworkSpecifierBuilder} builder, enabling chaining of builder
-         *         methods.
-         */
-        public @NonNull NetworkSpecifierBuilder setDiscoverySession(
-                @NonNull DiscoverySession discoverySession) {
-            if (discoverySession == null) {
-                throw new IllegalArgumentException("Non-null discoverySession required");
-            }
-            mDiscoverySession = discoverySession;
-            return this;
-        }
-
-        /**
-         * Configure the {@link PeerHandle} of the peer to which the Wi-Fi Aware connection is
-         * requested. The peer is discovered through Wi-Fi Aware discovery,
-         * <p>
-         * Note: this method must be called for any connection request!
-         *
-         * @param peerHandle The peer's handle obtained through
-         * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}
-         *                   or
-         *                   {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])}.
-         * @return the current {@link NetworkSpecifierBuilder} builder, enabling chaining of builder
-         *         methods.
-         */
-        public @NonNull NetworkSpecifierBuilder setPeerHandle(@NonNull PeerHandle peerHandle) {
-            if (peerHandle == null) {
-                throw new IllegalArgumentException("Non-null peerHandle required");
-            }
-            mPeerHandle = peerHandle;
-            return this;
-        }
-
-        /**
-         * Configure the PSK Passphrase for the Wi-Fi Aware connection being requested. This method
-         * is optional - if not called, then an Open (unencrypted) connection will be created.
-         *
-         * @param pskPassphrase The (optional) passphrase to be used to encrypt the link.
-         * @return the current {@link NetworkSpecifierBuilder} builder, enabling chaining of builder
-         *         methods.
-         */
-        public @NonNull NetworkSpecifierBuilder setPskPassphrase(@NonNull String pskPassphrase) {
-            if (!WifiAwareUtils.validatePassphrase(pskPassphrase)) {
-                throw new IllegalArgumentException("Passphrase must meet length requirements");
-            }
-            mPskPassphrase = pskPassphrase;
-            return this;
-        }
-
-        /**
-         * Configure the PMK for the Wi-Fi Aware connection being requested. This method
-         * is optional - if not called, then an Open (unencrypted) connection will be created.
-         *
-         * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
-         *            encrypting the data-path. Use the {@link #setPskPassphrase(String)} to
-         *            specify a Passphrase.
-         * @return the current {@link NetworkSpecifierBuilder} builder, enabling chaining of builder
-         *         methods.
-         * @hide
-         */
-        @SystemApi
-        public @NonNull NetworkSpecifierBuilder setPmk(@NonNull byte[] pmk) {
-            if (!WifiAwareUtils.validatePmk(pmk)) {
-                throw new IllegalArgumentException("PMK must 32 bytes");
-            }
-            mPmk = pmk;
-            return this;
-        }
-
-        /**
-         * Configure the port number which will be used to create a connection over this link. This
-         * configuration should only be done on the server device, e.g. the device creating the
-         * {@link java.net.ServerSocket}.
-         * <p>Notes:
-         * <ul>
-         *     <li>The server device must be the Publisher device!
-         *     <li>The port information can only be specified on secure links, specified using
-         *     {@link #setPskPassphrase(String)}.
-         * </ul>
-         *
-         * @param port A positive integer indicating the port to be used for communication.
-         * @return the current {@link NetworkSpecifierBuilder} builder, enabling chaining of builder
-         *         methods.
-         */
-        public @NonNull NetworkSpecifierBuilder setPort(int port) {
-            if (port <= 0 || port > 65535) {
-                throw new IllegalArgumentException("The port must be a positive value (0, 65535]");
-            }
-            mPort = port;
-            return this;
-        }
-
-        /**
-         * Configure the transport protocol which will be used to create a connection over this
-         * link. This configuration should only be done on the server device, e.g. the device
-         * creating the {@link java.net.ServerSocket} for TCP.
-         * <p>Notes:
-         * <ul>
-         *     <li>The server device must be the Publisher device!
-         *     <li>The transport protocol information can only be specified on secure links,
-         *     specified using {@link #setPskPassphrase(String)}.
-         * </ul>
-         * The transport protocol number is assigned by the Internet Assigned Numbers Authority
-         * (IANA) https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml.
-         *
-         * @param transportProtocol The transport protocol to be used for communication.
-         * @return the current {@link NetworkSpecifierBuilder} builder, enabling chaining of builder
-         *         methods.
-         */
-        public @NonNull NetworkSpecifierBuilder setTransportProtocol(int transportProtocol) {
-            if (transportProtocol < 0 || transportProtocol > 255) {
-                throw new IllegalArgumentException(
-                        "The transport protocol must be in range [0, 255]");
-            }
-            mTransportProtocol = transportProtocol;
-            return this;
-        }
-
-        /**
-         * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)}
-         * for a WiFi Aware connection (link) to the specified peer. The
-         * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
-         * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
-         * <p> The default builder constructor will initialize a NetworkSpecifier which requests an
-         * open (non-encrypted) link. To request an encrypted link use the
-         * {@link #setPskPassphrase(String)} builder method.
-         *
-         * @return A {@link NetworkSpecifier} to be used to construct
-         * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass
-         * to {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
-         * android.net.ConnectivityManager.NetworkCallback)}
-         * [or other varieties of that API].
-         */
-        public @NonNull NetworkSpecifier build() {
-            if (mDiscoverySession == null) {
-                throw new IllegalStateException("Null discovery session!?");
-            }
-            if (mPskPassphrase != null & mPmk != null) {
-                throw new IllegalStateException(
-                        "Can only specify a Passphrase or a PMK - not both!");
-            }
-
-            int role = mDiscoverySession instanceof SubscribeDiscoverySession
-                    ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
-                    : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-
-            if (mPort != 0 || mTransportProtocol != -1) {
-                if (role != WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
-                    throw new IllegalStateException(
-                            "Port and transport protocol information can only "
-                                    + "be specified on the Publisher device (which is the server");
-                }
-                if (TextUtils.isEmpty(mPskPassphrase) && mPmk == null) {
-                    throw new IllegalStateException("Port and transport protocol information can "
-                            + "only be specified on a secure link");
-                }
-            }
-
-            if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR && mPeerHandle == null) {
-                throw new IllegalStateException("Null peerHandle!?");
-            }
-
-            return new WifiAwareNetworkSpecifier(
-                    WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB, role,
-                    mDiscoverySession.mClientId, mDiscoverySession.mSessionId, mPeerHandle.peerId,
-                    null, mPmk, mPskPassphrase, mPort, mTransportProtocol, Process.myUid());
-        }
-    }
 }
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java
index 020cb56..fd26817b 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java
@@ -75,7 +75,7 @@
     /**
      * Get the port number to be used to create a network connection to the Wi-Fi Aware peer.
      * The port information is provided by the app running on the peer which requested the
-     * connection, using the {@link WifiAwareManager.NetworkSpecifierBuilder#setPort(int)}.
+     * connection, using the {@link WifiAwareNetworkSpecifier.Builder#setPort(int)}.
      *
      * @return A port number on the peer. A value of 0 indicates that no port was specified by the
      *         peer.
@@ -88,7 +88,7 @@
      * Get the transport protocol to be used to communicate over a network connection to the Wi-Fi
      * Aware peer. The transport protocol is provided by the app running on the peer which requested
      * the connection, using the
-     * {@link WifiAwareManager.NetworkSpecifierBuilder#setTransportProtocol(int)}.
+     * {@link WifiAwareNetworkSpecifier.Builder#setTransportProtocol(int)}.
      * <p>
      * The transport protocol number is assigned by the Internet Assigned Numbers Authority
      * (IANA) https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml.
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
index 59f534a..b225116 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
@@ -16,9 +16,15 @@
 
 package android.net.wifi.aware;
 
+import static android.net.wifi.aware.WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.net.NetworkSpecifier;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.Process;
+import android.text.TextUtils;
 
 import java.util.Arrays;
 import java.util.Objects;
@@ -29,8 +35,6 @@
  * {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])} or
  * {@link DiscoverySession#createNetworkSpecifierOpen(PeerHandle)} or their secure (Passphrase)
  * versions.
- *
- * @hide
  */
 public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable {
     /**
@@ -138,6 +142,8 @@
      * device they all get the same link. However, the link is only set up on the first request -
      * hence only the first can transmit the port information. But we don't want to expose that
      * information to other apps. Limiting to secure links would (usually) imply single app usage.
+     *
+     * @hide
      */
     public final int transportProtocol;
 
@@ -292,4 +298,197 @@
             throw new SecurityException("mismatched UIDs");
         }
     }
+
+    /**
+     * A builder class for a Wi-Fi Aware network specifier to set up an Aware connection with a
+     * peer.
+     * <p>
+     * Note that all Wi-Fi Aware connection specifier objects must call the
+     * {@link Builder#setDiscoverySession(DiscoverySession)} to specify the context
+     * within which the connection is created, and
+     * {@link Builder#setPeerHandle(PeerHandle)} to specify the peer to which the
+     * connection is created.
+     */
+    public static final class Builder {
+        private DiscoverySession mDiscoverySession;
+        private PeerHandle mPeerHandle;
+        private String mPskPassphrase;
+        private byte[] mPmk;
+        private int mPort = 0; // invalid value
+        private int mTransportProtocol = -1; // invalid value
+
+        /**
+         * Configure the {@link PublishDiscoverySession} or {@link SubscribeDiscoverySession}
+         * discovery session in whose context the connection is created.
+         * <p>
+         * Note: this method must be called for any connection request!
+         *
+         * @param discoverySession A Wi-Fi Aware discovery session.
+         * @return the current {@link Builder} builder, enabling chaining of builder
+         *         methods.
+         */
+        public @NonNull Builder setDiscoverySession(@NonNull DiscoverySession discoverySession) {
+            if (discoverySession == null) {
+                throw new IllegalArgumentException("Non-null discoverySession required");
+            }
+            mDiscoverySession = discoverySession;
+            return this;
+        }
+
+        /**
+         * Configure the {@link PeerHandle} of the peer to which the Wi-Fi Aware connection is
+         * requested. The peer is discovered through Wi-Fi Aware discovery,
+         * <p>
+         * Note: this method must be called for any connection request!
+         *
+         * @param peerHandle The peer's handle obtained through
+         * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}
+         *                   or
+         *                   {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])}.
+         * @return the current {@link Builder} builder, enabling chaining of builder
+         *         methods.
+         */
+        public @NonNull Builder setPeerHandle(@NonNull PeerHandle peerHandle) {
+            if (peerHandle == null) {
+                throw new IllegalArgumentException("Non-null peerHandle required");
+            }
+            mPeerHandle = peerHandle;
+            return this;
+        }
+
+        /**
+         * Configure the PSK Passphrase for the Wi-Fi Aware connection being requested. This method
+         * is optional - if not called, then an Open (unencrypted) connection will be created.
+         *
+         * @param pskPassphrase The (optional) passphrase to be used to encrypt the link.
+         * @return the current {@link Builder} builder, enabling chaining of builder
+         *         methods.
+         */
+        public @NonNull Builder setPskPassphrase(@NonNull String pskPassphrase) {
+            if (!WifiAwareUtils.validatePassphrase(pskPassphrase)) {
+                throw new IllegalArgumentException("Passphrase must meet length requirements");
+            }
+            mPskPassphrase = pskPassphrase;
+            return this;
+        }
+
+        /**
+         * Configure the PMK for the Wi-Fi Aware connection being requested. This method
+         * is optional - if not called, then an Open (unencrypted) connection will be created.
+         *
+         * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
+         *            encrypting the data-path. Use the {@link #setPskPassphrase(String)} to
+         *            specify a Passphrase.
+         * @return the current {@link Builder} builder, enabling chaining of builder
+         *         methods.
+         * @hide
+         */
+        @SystemApi
+        public @NonNull Builder setPmk(@NonNull byte[] pmk) {
+            if (!WifiAwareUtils.validatePmk(pmk)) {
+                throw new IllegalArgumentException("PMK must 32 bytes");
+            }
+            mPmk = pmk;
+            return this;
+        }
+
+        /**
+         * Configure the port number which will be used to create a connection over this link. This
+         * configuration should only be done on the server device, e.g. the device creating the
+         * {@link java.net.ServerSocket}.
+         * <p>Notes:
+         * <ul>
+         *     <li>The server device must be the Publisher device!
+         *     <li>The port information can only be specified on secure links, specified using
+         *     {@link #setPskPassphrase(String)}.
+         * </ul>
+         *
+         * @param port A positive integer indicating the port to be used for communication.
+         * @return the current {@link Builder} builder, enabling chaining of builder
+         *         methods.
+         */
+        public @NonNull Builder setPort(int port) {
+            if (port <= 0 || port > 65535) {
+                throw new IllegalArgumentException("The port must be a positive value (0, 65535]");
+            }
+            mPort = port;
+            return this;
+        }
+
+        /**
+         * Configure the transport protocol which will be used to create a connection over this
+         * link. This configuration should only be done on the server device, e.g. the device
+         * creating the {@link java.net.ServerSocket} for TCP.
+         * <p>Notes:
+         * <ul>
+         *     <li>The server device must be the Publisher device!
+         *     <li>The transport protocol information can only be specified on secure links,
+         *     specified using {@link #setPskPassphrase(String)}.
+         * </ul>
+         * The transport protocol number is assigned by the Internet Assigned Numbers Authority
+         * (IANA) https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml.
+         *
+         * @param transportProtocol The transport protocol to be used for communication.
+         * @return the current {@link Builder} builder, enabling chaining of builder
+         *         methods.
+         */
+        public @NonNull Builder setTransportProtocol(int transportProtocol) {
+            if (transportProtocol < 0 || transportProtocol > 255) {
+                throw new IllegalArgumentException(
+                        "The transport protocol must be in range [0, 255]");
+            }
+            mTransportProtocol = transportProtocol;
+            return this;
+        }
+
+        /**
+         * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)}
+         * for a WiFi Aware connection (link) to the specified peer. The
+         * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
+         * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
+         * <p> The default builder constructor will initialize a NetworkSpecifier which requests an
+         * open (non-encrypted) link. To request an encrypted link use the
+         * {@link #setPskPassphrase(String)} builder method.
+         *
+         * @return A {@link NetworkSpecifier} to be used to construct
+         * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass
+         * to {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
+         * android.net.ConnectivityManager.NetworkCallback)}
+         * [or other varieties of that API].
+         */
+        public @NonNull WifiAwareNetworkSpecifier build() {
+            if (mDiscoverySession == null) {
+                throw new IllegalStateException("Null discovery session!?");
+            }
+            if (mPskPassphrase != null & mPmk != null) {
+                throw new IllegalStateException(
+                        "Can only specify a Passphrase or a PMK - not both!");
+            }
+
+            int role = mDiscoverySession instanceof SubscribeDiscoverySession
+                    ? WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
+                    : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
+
+            if (mPort != 0 || mTransportProtocol != -1) {
+                if (role != WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
+                    throw new IllegalStateException(
+                            "Port and transport protocol information can only "
+                                    + "be specified on the Publisher device (which is the server");
+                }
+                if (TextUtils.isEmpty(mPskPassphrase) && mPmk == null) {
+                    throw new IllegalStateException("Port and transport protocol information can "
+                            + "only be specified on a secure link");
+                }
+            }
+
+            if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR && mPeerHandle == null) {
+                throw new IllegalStateException("Null peerHandle!?");
+            }
+
+            return new WifiAwareNetworkSpecifier(
+                    WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB, role,
+                    mDiscoverySession.mClientId, mDiscoverySession.mSessionId, mPeerHandle.peerId,
+                    null, mPmk, mPskPassphrase, mPort, mTransportProtocol, Process.myUid());
+        }
+    }
 }
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
index 245b304..3c97813 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
@@ -213,7 +213,7 @@
      *     This API is targeted for applications which can obtain the peer MAC address using OOB
      *     (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
      *     when using Aware discovery use the alternative network specifier method -
-     *     {@link android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder}.
+     *     {@link android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder}.
      * <p>
      * To set up an encrypted link use the
      * {@link #createNetworkSpecifierPassphrase(int, byte[], String)} API.
@@ -254,7 +254,7 @@
      *     This API is targeted for applications which can obtain the peer MAC address using OOB
      *     (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
      *     when using Aware discovery use the alternative network specifier method -
-     *     {@link android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder}.
+     *     {@link android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder}.
      *
      * @param role  The role of this device:
      *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
@@ -300,7 +300,7 @@
      *     This API is targeted for applications which can obtain the peer MAC address using OOB
      *     (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
      *     when using Aware discovery use the alternative network specifier method -
-     *     {@link android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder}.
+     *     {@link android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder}.
      *
      * @param role  The role of this device:
      *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index 3cc96bf..657a338 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -958,9 +958,8 @@
         WifiAwareNetworkSpecifier ns =
                 (WifiAwareNetworkSpecifier) publishSession.getValue().createNetworkSpecifierOpen(
                         peerHandle);
-        WifiAwareNetworkSpecifier nsb = (WifiAwareNetworkSpecifier) new WifiAwareManager
-                .NetworkSpecifierBuilder().setDiscoverySession(publishSession.getValue())
-                .setPeerHandle(peerHandle).build();
+        WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
+                publishSession.getValue()).setPeerHandle(peerHandle).build();
 
         // validate format
         collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
@@ -980,9 +979,9 @@
         // (4) request an encrypted (PMK) network specifier from the session
         ns = (WifiAwareNetworkSpecifier) publishSession.getValue().createNetworkSpecifierPmk(
                 peerHandle, pmk);
-        nsb = (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
-                .setDiscoverySession(publishSession.getValue()).setPeerHandle(peerHandle)
-                .setPmk(pmk).setPort(port).setTransportProtocol(transportProtocol).build();
+        nsb = new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
+                publishSession.getValue()).setPeerHandle(peerHandle).setPmk(pmk).setPort(
+                port).setTransportProtocol(transportProtocol).build();
 
         // validate format
         collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
@@ -1006,10 +1005,9 @@
                 (WifiAwareNetworkSpecifier) publishSession.getValue()
                         .createNetworkSpecifierPassphrase(
                         peerHandle, passphrase);
-        nsb = (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
-                .setDiscoverySession(publishSession.getValue()).setPeerHandle(peerHandle)
-                .setPskPassphrase(passphrase).setPort(port).setTransportProtocol(transportProtocol)
-                .build();
+        nsb = new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
+                publishSession.getValue()).setPeerHandle(peerHandle).setPskPassphrase(
+                passphrase).setPort(port).setTransportProtocol(transportProtocol).build();
 
         // validate format
         collector.checkThat("role", WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
@@ -1257,14 +1255,14 @@
         // (3) create network specifier
         if (doPmk) {
             if (useBuilder) {
-                new WifiAwareManager.NetworkSpecifierBuilder().setDiscoverySession(
+                new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
                         publishSession.getValue()).setPeerHandle(peerHandle).setPmk(pmk).build();
             } else {
                 publishSession.getValue().createNetworkSpecifierPmk(peerHandle, pmk);
             }
         } else {
             if (useBuilder) {
-                new WifiAwareManager.NetworkSpecifierBuilder().setDiscoverySession(
+                new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
                         publishSession.getValue()).setPeerHandle(peerHandle).setPskPassphrase(
                         passphrase).build();
             } else {
@@ -1355,10 +1353,8 @@
 
         DiscoverySession publishSession = executeSessionStartup(true);
 
-        WifiAwareNetworkSpecifier nsb =
-                (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
-                        .setDiscoverySession(publishSession).setPeerHandle(peerHandle)
-                        .setPmk(pmk).setPort(port).build();
+        WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
+                publishSession).setPeerHandle(peerHandle).setPmk(pmk).setPort(port).build();
     }
 
     /**
@@ -1372,10 +1368,8 @@
 
         DiscoverySession publishSession = executeSessionStartup(true);
 
-        WifiAwareNetworkSpecifier nsb =
-                (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
-                        .setDiscoverySession(publishSession).setPeerHandle(peerHandle)
-                        .setPort(port).build();
+        WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
+                publishSession).setPeerHandle(peerHandle).setPort(port).build();
     }
 
     /**
@@ -1389,10 +1383,8 @@
 
         DiscoverySession subscribeSession = executeSessionStartup(false);
 
-        WifiAwareNetworkSpecifier nsb =
-                (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
-                        .setDiscoverySession(subscribeSession).setPeerHandle(peerHandle)
-                        .setPort(port).build();
+        WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
+                subscribeSession).setPeerHandle(peerHandle).setPort(port).build();
     }
 
     /**
@@ -1411,8 +1403,7 @@
         DiscoverySession publishSession = executeSessionStartup(true);
 
         try {
-            WifiAwareNetworkSpecifier nsb =
-                    (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
+            WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder()
                             .setDiscoverySession(publishSession).setPeerHandle(peerHandle)
                             .setPmk(pmk).setTransportProtocol(tpNegative).build();
             assertTrue("No exception on negative transport protocol!", false);
@@ -1420,23 +1411,19 @@
             // nop - exception is correct!
         }
         try {
-            WifiAwareNetworkSpecifier nsb =
-                    (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
+            WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder()
                             .setDiscoverySession(publishSession).setPeerHandle(peerHandle)
                             .setPmk(pmk).setTransportProtocol(tpTooLarge).build();
             assertTrue("No exception on >255 transport protocol!", false);
         } catch (IllegalArgumentException e) {
             // nop - exception is correct!
         }
-        WifiAwareNetworkSpecifier nsb =
-                (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
+        WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder()
                         .setDiscoverySession(publishSession).setPeerHandle(peerHandle)
                         .setPmk(pmk).setTransportProtocol(tpSmallest).build();
-        nsb =
-                (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
-                        .setDiscoverySession(
-                                publishSession).setPeerHandle(peerHandle).setPmk(
-                        pmk).setTransportProtocol(tpLargest).build();
+        nsb = new WifiAwareNetworkSpecifier.Builder().setDiscoverySession(
+                publishSession).setPeerHandle(peerHandle).setPmk(pmk).setTransportProtocol(
+                tpLargest).build();
     }
 
     /**
@@ -1450,8 +1437,7 @@
 
         DiscoverySession publishSession = executeSessionStartup(true);
 
-        WifiAwareNetworkSpecifier nsb =
-                (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
+        WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder()
                         .setDiscoverySession(publishSession).setPeerHandle(peerHandle)
                         .setTransportProtocol(transportProtocol).build();
     }
@@ -1467,8 +1453,7 @@
 
         DiscoverySession subscribeSession = executeSessionStartup(false);
 
-        WifiAwareNetworkSpecifier nsb =
-                (WifiAwareNetworkSpecifier) new WifiAwareManager.NetworkSpecifierBuilder()
+        WifiAwareNetworkSpecifier nsb = new WifiAwareNetworkSpecifier.Builder()
                         .setDiscoverySession(subscribeSession).setPeerHandle(peerHandle)
                         .setTransportProtocol(transportProtocol).build();
     }