Merge "Private DNS API: Follow-up on review"
diff --git a/api/current.txt b/api/current.txt
index 5efa1ec..fb588dc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -130,7 +130,7 @@
     field public static final String REQUEST_DELETE_PACKAGES = "android.permission.REQUEST_DELETE_PACKAGES";
     field public static final String REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
     field public static final String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
-    field public static final String REQUEST_SCREEN_LOCK_COMPLEXITY = "android.permission.REQUEST_SCREEN_LOCK_COMPLEXITY";
+    field public static final String REQUEST_PASSWORD_COMPLEXITY = "android.permission.REQUEST_PASSWORD_COMPLEXITY";
     field @Deprecated public static final String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
     field public static final String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
     field public static final String SEND_SMS = "android.permission.SEND_SMS";
@@ -6656,7 +6656,7 @@
     method @Nullable public CharSequence getOrganizationName(@NonNull android.content.ComponentName);
     method public java.util.List<android.telephony.data.ApnSetting> getOverrideApns(@NonNull android.content.ComponentName);
     method @NonNull public android.app.admin.DevicePolicyManager getParentProfileInstance(@NonNull android.content.ComponentName);
-    method @RequiresPermission(android.Manifest.permission.REQUEST_SCREEN_LOCK_COMPLEXITY) public int getPasswordComplexity();
+    method @RequiresPermission(android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY) public int getPasswordComplexity();
     method public long getPasswordExpiration(@Nullable android.content.ComponentName);
     method public long getPasswordExpirationTimeout(@Nullable android.content.ComponentName);
     method public int getPasswordHistoryLength(@Nullable android.content.ComponentName);
@@ -6851,7 +6851,7 @@
     field public static final String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION";
     field public static final String EXTRA_DELEGATION_SCOPES = "android.app.extra.DELEGATION_SCOPES";
     field public static final String EXTRA_DEVICE_ADMIN = "android.app.extra.DEVICE_ADMIN";
-    field @RequiresPermission(android.Manifest.permission.REQUEST_SCREEN_LOCK_COMPLEXITY) public static final String EXTRA_PASSWORD_COMPLEXITY = "android.app.extra.PASSWORD_COMPLEXITY";
+    field @RequiresPermission(android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY) public static final String EXTRA_PASSWORD_COMPLEXITY = "android.app.extra.PASSWORD_COMPLEXITY";
     field public static final String EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE = "android.app.extra.PROVISIONING_ACCOUNT_TO_MIGRATE";
     field public static final String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE = "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE";
     field public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME = "android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME";
@@ -11271,11 +11271,11 @@
     method public boolean shouldHideFromSuggestions(@NonNull String, @NonNull android.os.UserHandle);
     method public void startAppDetailsActivity(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle);
     method public void startMainActivity(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle);
-    method public void startPackageInstallerSessionDetailsActivity(android.content.pm.PackageInstaller.SessionInfo, android.graphics.Rect, android.os.Bundle);
+    method public void startPackageInstallerSessionDetailsActivity(@NonNull android.content.pm.PackageInstaller.SessionInfo, @Nullable android.graphics.Rect, @Nullable android.os.Bundle);
     method public void startShortcut(@NonNull String, @NonNull String, @Nullable android.graphics.Rect, @Nullable android.os.Bundle, @NonNull android.os.UserHandle);
     method public void startShortcut(@NonNull android.content.pm.ShortcutInfo, @Nullable android.graphics.Rect, @Nullable android.os.Bundle);
     method public void unregisterCallback(android.content.pm.LauncherApps.Callback);
-    method public void unregisterPackageInstallerSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
+    method public void unregisterPackageInstallerSessionCallback(@NonNull android.content.pm.PackageInstaller.SessionCallback);
     field public static final String ACTION_CONFIRM_PIN_APPWIDGET = "android.content.pm.action.CONFIRM_PIN_APPWIDGET";
     field public static final String ACTION_CONFIRM_PIN_SHORTCUT = "android.content.pm.action.CONFIRM_PIN_SHORTCUT";
     field public static final String EXTRA_PIN_ITEM_REQUEST = "android.content.pm.extra.PIN_ITEM_REQUEST";
@@ -11465,7 +11465,7 @@
     method public long getSize();
     method public int getStagedSessionErrorCode();
     method @NonNull public String getStagedSessionErrorMessage();
-    method public android.os.UserHandle getUser();
+    method @NonNull public android.os.UserHandle getUser();
     method public boolean isActive();
     method public boolean isMultiPackage();
     method public boolean isSealed();
@@ -11945,6 +11945,7 @@
     field public static final int FOREGROUND_SERVICE_TYPE_LOCATION = 8; // 0x8
     field public static final int FOREGROUND_SERVICE_TYPE_MANIFEST = -1; // 0xffffffff
     field public static final int FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK = 2; // 0x2
+    field public static final int FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION = 32; // 0x20
     field public static final int FOREGROUND_SERVICE_TYPE_NONE = 0; // 0x0
     field public static final int FOREGROUND_SERVICE_TYPE_PHONE_CALL = 4; // 0x4
     field public int flags;
@@ -36845,7 +36846,7 @@
     field public static final String CALENDAR_LOCATION = "calendar_location";
     field public static final android.net.Uri CONTENT_URI;
     field public static final String DEFAULT_SORT_ORDER = "calendar_displayName";
-    field public static final android.net.Uri ENTERPRISE_CONTENT_URI;
+    field @NonNull public static final android.net.Uri ENTERPRISE_CONTENT_URI;
     field public static final String NAME = "name";
   }
 
@@ -36874,7 +36875,7 @@
   public static final class CalendarContract.Events implements android.provider.BaseColumns android.provider.CalendarContract.CalendarColumns android.provider.CalendarContract.EventsColumns android.provider.CalendarContract.SyncColumns {
     field public static final android.net.Uri CONTENT_EXCEPTION_URI;
     field public static final android.net.Uri CONTENT_URI;
-    field public static final android.net.Uri ENTERPRISE_CONTENT_URI;
+    field @NonNull public static final android.net.Uri ENTERPRISE_CONTENT_URI;
   }
 
   protected static interface CalendarContract.EventsColumns {
@@ -36966,10 +36967,10 @@
     field public static final String END = "end";
     field public static final String END_DAY = "endDay";
     field public static final String END_MINUTE = "endMinute";
-    field public static final android.net.Uri ENTERPRISE_CONTENT_BY_DAY_URI;
-    field public static final android.net.Uri ENTERPRISE_CONTENT_SEARCH_BY_DAY_URI;
-    field public static final android.net.Uri ENTERPRISE_CONTENT_SEARCH_URI;
-    field public static final android.net.Uri ENTERPRISE_CONTENT_URI;
+    field @NonNull public static final android.net.Uri ENTERPRISE_CONTENT_BY_DAY_URI;
+    field @NonNull public static final android.net.Uri ENTERPRISE_CONTENT_SEARCH_BY_DAY_URI;
+    field @NonNull public static final android.net.Uri ENTERPRISE_CONTENT_SEARCH_URI;
+    field @NonNull public static final android.net.Uri ENTERPRISE_CONTENT_URI;
     field public static final String EVENT_ID = "event_id";
     field public static final String START_DAY = "startDay";
     field public static final String START_MINUTE = "startMinute";
diff --git a/api/system-current.txt b/api/system-current.txt
index b2030ec..96c9c752 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -546,10 +546,10 @@
 
   public class NotificationManager {
     method @Nullable public android.content.ComponentName getAllowedNotificationAssistant();
-    method @Nullable public android.content.ComponentName getAllowedNotificationAssistantForUser(android.os.UserHandle);
+    method @Nullable public android.content.ComponentName getAllowedNotificationAssistantForUser(@NonNull android.os.UserHandle);
     method public boolean isNotificationAssistantAccessGranted(@NonNull android.content.ComponentName);
-    method public void setNotificationAssistantAccessGranted(android.content.ComponentName, boolean);
-    method public void setNotificationAssistantAccessGrantedForUser(android.content.ComponentName, android.os.UserHandle, boolean);
+    method public void setNotificationAssistantAccessGranted(@Nullable android.content.ComponentName, boolean);
+    method public void setNotificationAssistantAccessGrantedForUser(@Nullable android.content.ComponentName, @NonNull android.os.UserHandle, boolean);
   }
 
   public final class StatsManager {
@@ -1836,10 +1836,8 @@
 
   public final class RollbackManager {
     method @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void commitRollback(int, @NonNull java.util.List<android.content.pm.VersionedPackage>, @NonNull android.content.IntentSender);
-    method @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void expireRollbackForPackage(@NonNull String);
     method @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) @NonNull public java.util.List<android.content.rollback.RollbackInfo> getAvailableRollbacks();
     method @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) @NonNull public java.util.List<android.content.rollback.RollbackInfo> getRecentlyCommittedRollbacks();
-    method @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void reloadPersistedData();
     field public static final String EXTRA_STATUS = "android.content.rollback.extra.STATUS";
     field public static final String EXTRA_STATUS_MESSAGE = "android.content.rollback.extra.STATUS_MESSAGE";
     field public static final int STATUS_FAILURE = 1; // 0x1
@@ -5214,7 +5212,7 @@
   }
 
   public static class Build.VERSION {
-    field public static final String PREVIEW_SDK_FINGERPRINT;
+    field @NonNull public static final String PREVIEW_SDK_FINGERPRINT;
   }
 
   public final class ConfigUpdate {
diff --git a/api/test-current.txt b/api/test-current.txt
index 46e061b..2913743 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -11,8 +11,10 @@
     field public static final String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS";
     field public static final String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES";
     field public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS";
+    field public static final String MANAGE_ROLLBACKS = "android.permission.MANAGE_ROLLBACKS";
     field public static final String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS";
     field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS";
+    field public static final String WRITE_DEVICE_CONFIG = "android.permission.WRITE_DEVICE_CONFIG";
     field public static final String WRITE_MEDIA_STORAGE = "android.permission.WRITE_MEDIA_STORAGE";
     field public static final String WRITE_OBB = "android.permission.WRITE_OBB";
   }
@@ -596,6 +598,7 @@
     method public int getUserId();
     method public void setAutofillOptions(@Nullable android.content.AutofillOptions);
     method public void setContentCaptureOptions(@Nullable android.content.ContentCaptureOptions);
+    field public static final String ROLLBACK_SERVICE = "rollback";
   }
 
   public class ContextWrapper extends android.content.Context {
@@ -603,6 +606,7 @@
   }
 
   public class Intent implements java.lang.Cloneable android.os.Parcelable {
+    field public static final String ACTION_ROLLBACK_COMMITTED = "android.intent.action.ROLLBACK_COMMITTED";
     field public static final String EXTRA_ROLE_NAME = "android.intent.extra.ROLE_NAME";
   }
 
@@ -626,6 +630,12 @@
     ctor public LauncherApps(android.content.Context);
   }
 
+  public static class PackageInstaller.SessionParams implements android.os.Parcelable {
+    method public void setEnableRollback(boolean);
+    method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setInstallAsApex();
+    method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged();
+  }
+
   public abstract class PackageManager {
     method public abstract boolean arePermissionsIndividuallyControlled();
     method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract String getDefaultBrowserPackageNameAsUser(int);
@@ -686,6 +696,44 @@
 
 }
 
+package android.content.rollback {
+
+  public final class PackageRollbackInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public String getPackageName();
+    method @NonNull public android.content.pm.VersionedPackage getVersionRolledBackFrom();
+    method @NonNull public android.content.pm.VersionedPackage getVersionRolledBackTo();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.content.rollback.PackageRollbackInfo> CREATOR;
+  }
+
+  public final class RollbackInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.List<android.content.pm.VersionedPackage> getCausePackages();
+    method public int getCommittedSessionId();
+    method @NonNull public java.util.List<android.content.rollback.PackageRollbackInfo> getPackages();
+    method public int getRollbackId();
+    method public boolean isStaged();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.content.rollback.RollbackInfo> CREATOR;
+  }
+
+  public final class RollbackManager {
+    method @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void commitRollback(int, @NonNull java.util.List<android.content.pm.VersionedPackage>, @NonNull android.content.IntentSender);
+    method @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void expireRollbackForPackage(@NonNull String);
+    method @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) @NonNull public java.util.List<android.content.rollback.RollbackInfo> getAvailableRollbacks();
+    method @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) @NonNull public java.util.List<android.content.rollback.RollbackInfo> getRecentlyCommittedRollbacks();
+    method @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void reloadPersistedData();
+    field public static final String EXTRA_STATUS = "android.content.rollback.extra.STATUS";
+    field public static final String EXTRA_STATUS_MESSAGE = "android.content.rollback.extra.STATUS_MESSAGE";
+    field public static final int STATUS_FAILURE = 1; // 0x1
+    field public static final int STATUS_FAILURE_INSTALL = 3; // 0x3
+    field public static final int STATUS_FAILURE_ROLLBACK_UNAVAILABLE = 2; // 0x2
+    field public static final int STATUS_SUCCESS = 0; // 0x0
+  }
+
+}
+
 package android.database.sqlite {
 
   public class SQLiteCompatibilityWalFlags {
@@ -2015,8 +2063,8 @@
     method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getString(String, String, String);
     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);
+    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_AUTOFILL = "autofill";
     field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
   }
@@ -2044,6 +2092,13 @@
     method @Nullable public String getString(@NonNull String, @Nullable String);
   }
 
+  public static interface DeviceConfig.Rollback {
+    field public static final String BOOT_NAMESPACE = "rollback_boot";
+    field public static final String ENABLE_ROLLBACK_TIMEOUT = "enable_rollback_timeout";
+    field public static final String NAMESPACE = "rollback";
+    field public static final String ROLLBACK_LIFETIME_IN_MILLIS = "rollback_lifetime_in_millis";
+  }
+
   public final class MediaStore {
     method @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA) public static void deleteContributedMedia(android.content.Context, String, android.os.UserHandle) throws java.io.IOException;
     method @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA) public static long getContributedMediaSize(android.content.Context, String, android.os.UserHandle) throws java.io.IOException;
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index b812c80..4856f77 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -249,6 +249,7 @@
         TouchGestureClassified touch_gesture_classified = 177;
         HiddenApiUsed hidden_api_used = 178 [(allow_from_any_uid) = true];
         StyleUIChanged style_ui_changed = 179;
+        PrivacyIndicatorsInteracted privacy_indicators_interacted = 180;
     }
 
     // Pulled events will start at field 10000.
@@ -3395,6 +3396,32 @@
     optional bool access_denied = 4;
 }
 
+/**
+ * Logs user interaction with the Privacy Indicators added in Q. In particular:
+ * - When user sees privacy chip
+ * - When user clicks privacy chip
+ * - How does the user exit the Privacy Dialog
+ * Logged from:
+ *   packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
+ *   packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+ */
+message PrivacyIndicatorsInteracted {
+
+    enum Type {
+        UNKNOWN = 0;
+        CHIP_VIEWED = 1;
+        CHIP_CLICKED = 2;
+        DIALOG_PRIVACY_SETTINGS = 3;
+        DIALOG_DISMISS = 4;
+        DIALOG_LINE_ITEM = 5;
+    }
+
+    optional Type type = 1 [(state_field_option).option = EXCLUSIVE];
+
+    // Used if the type is LINE_ITEM
+    optional string package_name = 2;
+}
+
 //////////////////////////////////////////////////////////////////////
 // Pulled atoms below this line //
 //////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index ed7aa4a..204fb6a 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1277,7 +1277,8 @@
      * @hide
      */
     @SystemApi
-    public void setNotificationAssistantAccessGranted(ComponentName assistant, boolean granted) {
+    public void setNotificationAssistantAccessGranted(@Nullable ComponentName assistant,
+            boolean granted) {
         INotificationManager service = getService();
         try {
             service.setNotificationAssistantAccessGranted(assistant, granted);
@@ -1296,8 +1297,8 @@
      * @hide
      */
     @SystemApi
-    public void setNotificationAssistantAccessGrantedForUser(ComponentName assistant,
-            UserHandle user, boolean granted) {
+    public void setNotificationAssistantAccessGrantedForUser(@Nullable ComponentName assistant,
+            @NonNull UserHandle user, boolean granted) {
         INotificationManager service = getService();
         try {
             service.setNotificationAssistantAccessGrantedForUser(assistant, user.getIdentifier(),
@@ -1319,7 +1320,8 @@
 
     /** @hide */
     @SystemApi
-    public @Nullable ComponentName getAllowedNotificationAssistantForUser(UserHandle user) {
+    public @Nullable ComponentName getAllowedNotificationAssistantForUser(
+            @NonNull UserHandle user) {
         INotificationManager service = getService();
         try {
             return service.getAllowedNotificationAssistantForUser(user.getIdentifier());
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 22ba39c..f8ccb13 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1377,7 +1377,7 @@
      * complexity, and use this activity with extra {@link #EXTRA_PASSWORD_COMPLEXITY} to suggest
      * to users how complex the app wants the new screen lock to be. Note that both {@link
      * #getPasswordComplexity()} and the extra {@link #EXTRA_PASSWORD_COMPLEXITY} require the
-     * calling app to have the permission {@link permission#REQUEST_SCREEN_LOCK_COMPLEXITY}.
+     * calling app to have the permission {@link permission#REQUEST_PASSWORD_COMPLEXITY}.
      *
      * <p>If the intent is launched from within a managed profile with a profile
      * owner built against {@link android.os.Build.VERSION_CODES#M} or before,
@@ -1405,7 +1405,7 @@
      *
      * <p>If an invalid value is used, it will be treated as {@link #PASSWORD_COMPLEXITY_NONE}.
      */
-    @RequiresPermission(android.Manifest.permission.REQUEST_SCREEN_LOCK_COMPLEXITY)
+    @RequiresPermission(android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY)
     public static final String EXTRA_PASSWORD_COMPLEXITY =
             "android.app.extra.PASSWORD_COMPLEXITY";
 
@@ -3331,27 +3331,48 @@
     }
 
     /**
-     * Determine whether the current password the user has set is sufficient to meet the policy
-     * requirements (e.g. quality, minimum length) that have been requested by the admins of this
-     * user and its participating profiles. Restrictions on profiles that have a separate challenge
-     * are not taken into account. The user must be unlocked in order to perform the check.
-     * <p>
-     * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
-     * password is always treated as empty - i.e. this method will always return false on such
-     * devices, provided any password requirements were set.
-     * <p>
-     * The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has
-     * not, a security exception will be thrown.
-     * <p>
-     * This method can be called on the {@link DevicePolicyManager} instance returned by
+     * Determines whether the calling user's current password meets policy requirements
+     * (e.g. quality, minimum length). The user must be unlocked to perform this check.
+     *
+     * <p>Policy requirements which affect this check can be set by admins of the user, but also
+     * by the admin of a managed profile associated with the calling user (when the managed profile
+     * doesn't have a separate work challenge). When a managed profile has a separate work
+     * challenge, its policy requirements only affect the managed profile.
+     *
+     * <p>Depending on the user, this method checks the policy requirement against one of the
+     * following passwords:
+     * <ul>
+     * <li>For the primary user or secondary users: the personal keyguard password.
+     * <li>For managed profiles: a work challenge if set, otherwise the parent user's personal
+     *     keyguard password.
+     * <ul/>
+     * In other words, it's always checking the requirement against the password that is protecting
+     * the calling user.
+     *
+     * <p>Note that this method considers all policy requirements targeting the password in
+     * question. For example a profile owner might set a requirement on the parent profile i.e.
+     * personal keyguard but not on the profile itself. When the device has a weak personal keyguard
+     * password and no separate work challenge, calling this method will return {@code false}
+     * despite the profile owner not setting a policy on the profile itself. This is because the
+     * profile's current password is the personal keyguard password, and it does not meet all policy
+     * requirements.
+     *
+     * <p>Device admins must request {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} before
+     * calling this method. Note, this policy type is deprecated for device admins in Android 9.0
+     * (API level 28) or higher.
+     *
+     * <p>This method can be called on the {@link DevicePolicyManager} instance returned by
      * {@link #getParentProfileInstance(ComponentName)} in order to determine if the password set on
      * the parent profile is sufficient.
      *
-     * @return Returns true if the password meets the current requirements, else false.
-     * @throws SecurityException if the calling application does not own an active administrator
-     *             that uses {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD}
-     * @throws IllegalStateException if the user is not unlocked.
+     * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
+     * password is always treated as empty - i.e. this method will always return false on such
+     * devices, provided any password requirements were set.
+     *
+     * @return {@code true} if the password meets the policy requirements, {@code false} otherwise
+     * @throws SecurityException if the calling application isn't an active admin that uses
+     *     {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD}
+     * @throws IllegalStateException if the user isn't unlocked
      */
     public boolean isActivePasswordSufficient() {
         if (mService != null) {
@@ -3377,10 +3398,10 @@
      *
      * @throws IllegalStateException if the user is not unlocked.
      * @throws SecurityException if the calling application does not have the permission
-     *                           {@link permission#REQUEST_SCREEN_LOCK_COMPLEXITY}
+     *                           {@link permission#REQUEST_PASSWORD_COMPLEXITY}
      */
     @PasswordComplexity
-    @RequiresPermission(android.Manifest.permission.REQUEST_SCREEN_LOCK_COMPLEXITY)
+    @RequiresPermission(android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY)
     public int getPasswordComplexity() {
         throwIfParentInstance("getPasswordComplexity");
         if (mService == null) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index f896274..0c76f3f 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4089,7 +4089,7 @@
      * @see #getSystemService(String)
      * @hide
      */
-    @SystemApi
+    @SystemApi @TestApi
     public static final String ROLLBACK_SERVICE = "rollback";
 
     /**
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 0715572..a2d3f6a 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2441,7 +2441,7 @@
      *
      * @hide
      */
-    @SystemApi
+    @SystemApi @TestApi
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_ROLLBACK_COMMITTED =
             "android.intent.action.ROLLBACK_COMMITTED";
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 0cc5f39..2a19763 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -585,8 +585,8 @@
      * @param sourceBounds The Rect containing the source bounds of the clicked icon
      * @param opts Options to pass to startActivity
      */
-    public void startPackageInstallerSessionDetailsActivity(SessionInfo sessionInfo,
-            Rect sourceBounds, Bundle opts) {
+    public void startPackageInstallerSessionDetailsActivity(@NonNull SessionInfo sessionInfo,
+            @Nullable Rect sourceBounds, @Nullable Bundle opts) {
         try {
             mService.startSessionDetailsActivityAsUser(mContext.getIApplicationThread(),
                     mContext.getPackageName(), sessionInfo, sourceBounds, opts,
@@ -1503,7 +1503,7 @@
      * @param callback The callback to unregister.
      * @see #registerPackageInstallerSessionCallback(Executor, SessionCallback)
      */
-    public void unregisterPackageInstallerSessionCallback(SessionCallback callback) {
+    public void unregisterPackageInstallerSessionCallback(@NonNull SessionCallback callback) {
         synchronized (mDelegates) {
             for (Iterator<SessionCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) {
                 final SessionCallbackDelegate delegate = i.next();
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 7b4dd19..33b9c72 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -24,6 +24,7 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
 import android.app.AppGlobals;
@@ -1465,7 +1466,7 @@
          * @param enable set to {@code true} to enable, {@code false} to disable
          * @hide
          */
-        @SystemApi
+        @SystemApi @TestApi
         public void setEnableRollback(boolean enable) {
             if (enable) {
                 installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK;
@@ -1591,7 +1592,7 @@
          *
          * {@hide}
          */
-        @SystemApi
+        @SystemApi @TestApi
         @RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
         public void setStaged() {
             this.isStaged = true;
@@ -1602,7 +1603,7 @@
          *
          * {@hide}
          */
-        @SystemApi
+        @SystemApi @TestApi
         @RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
         public void setInstallAsApex() {
             installFlags |= PackageManager.INSTALL_APEX;
@@ -1833,7 +1834,7 @@
         /**
          * Return the user associated with this session.
          */
-        public UserHandle getUser() {
+        public @NonNull UserHandle getUser() {
             return new UserHandle(userId);
         }
 
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index cd40c95..00507e1 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -140,6 +140,13 @@
     public static final int FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE = 1 << 4;
 
     /**
+     * Constant corresponding to {@code mediaProjection} in
+     * the {@link android.R.attr#foregroundServiceType} attribute.
+     * Managing a media projection session, e.g for screen recording or taking screenshots.
+     */
+    public static final int FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION = 1 << 5;
+
+    /**
      * A special value indicates to use all types set in manifest file.
      */
     public static final int FOREGROUND_SERVICE_TYPE_MANIFEST = -1;
@@ -158,6 +165,7 @@
             FOREGROUND_SERVICE_TYPE_PHONE_CALL,
             FOREGROUND_SERVICE_TYPE_LOCATION,
             FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE,
+            FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ForegroundServiceType {}
diff --git a/core/java/android/content/rollback/PackageRollbackInfo.java b/core/java/android/content/rollback/PackageRollbackInfo.java
index c0414fc..2014751 100644
--- a/core/java/android/content/rollback/PackageRollbackInfo.java
+++ b/core/java/android/content/rollback/PackageRollbackInfo.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.content.pm.VersionedPackage;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -31,7 +32,7 @@
  *
  * @hide
  */
-@SystemApi
+@SystemApi @TestApi
 public final class PackageRollbackInfo implements Parcelable {
 
     private final VersionedPackage mVersionRolledBackFrom;
@@ -211,7 +212,7 @@
         out.writeBoolean(mIsApex);
     }
 
-    public static final @android.annotation.NonNull Parcelable.Creator<PackageRollbackInfo> CREATOR =
+    public static final @NonNull Parcelable.Creator<PackageRollbackInfo> CREATOR =
             new Parcelable.Creator<PackageRollbackInfo>() {
         public PackageRollbackInfo createFromParcel(Parcel in) {
             return new PackageRollbackInfo(in);
diff --git a/core/java/android/content/rollback/RollbackInfo.java b/core/java/android/content/rollback/RollbackInfo.java
index a363718..c09cfd5 100644
--- a/core/java/android/content/rollback/RollbackInfo.java
+++ b/core/java/android/content/rollback/RollbackInfo.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.content.pm.VersionedPackage;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -30,7 +31,7 @@
  *
  * @hide
  */
-@SystemApi
+@SystemApi @TestApi
 public final class RollbackInfo implements Parcelable {
 
     /**
diff --git a/core/java/android/content/rollback/RollbackManager.java b/core/java/android/content/rollback/RollbackManager.java
index 4e8c254..9038b03 100644
--- a/core/java/android/content/rollback/RollbackManager.java
+++ b/core/java/android/content/rollback/RollbackManager.java
@@ -16,16 +16,20 @@
 
 package android.content.rollback;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.annotation.TestApi;
 import android.content.Context;
 import android.content.IntentSender;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.VersionedPackage;
 import android.os.RemoteException;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -38,7 +42,7 @@
  * @see PackageInstaller.SessionParams#setEnableRollback()
  * @hide
  */
-@SystemApi
+@SystemApi @TestApi
 @SystemService(Context.ROLLBACK_SERVICE)
 public final class RollbackManager {
     private final String mCallerPackageName;
@@ -112,6 +116,20 @@
             "android.content.rollback.extra.STATUS_MESSAGE";
 
     /**
+     * Status result of committing a rollback.
+     *
+     * @hide
+     */
+    @IntDef(prefix = "STATUS_", value = {
+            STATUS_SUCCESS,
+            STATUS_FAILURE,
+            STATUS_FAILURE_ROLLBACK_UNAVAILABLE,
+            STATUS_FAILURE_INSTALL,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Status {};
+
+    /**
      * The rollback was successfully committed.
      */
     public static final int STATUS_SUCCESS = 0;
@@ -175,8 +193,11 @@
      *
      * @throws SecurityException if the caller does not have the
      *            MANAGE_ROLLBACKS permission.
+     *
+     * @hide
      */
     @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS)
+    @TestApi
     public void reloadPersistedData() {
         try {
             mBinder.reloadPersistedData();
@@ -194,8 +215,11 @@
      * @param packageName the name of the package to expire data for.
      * @throws SecurityException if the caller does not have the
      *            MANAGE_ROLLBACKS permission.
+     *
+     * @hide
      */
     @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS)
+    @TestApi
     public void expireRollbackForPackage(@NonNull String packageName) {
         try {
             mBinder.expireRollbackForPackage(packageName);
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index 45860b3..95d66bb 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -62,7 +62,7 @@
  *
  * The handshake timeout does not apply to actual TCP socket connection.
  * If you want a connection timeout as well, use {@link #createSocket()}
- * and {@link Socket#connect(SocketAddress, int)}, after which you
+ * and {@link Socket#connect(java.net.SocketAddress, int)}, after which you
  * must verify the identity of the server you are connected to.
  *
  * <p class="caution"><b>Most {@link SSLSocketFactory} implementations do not
@@ -211,14 +211,14 @@
     }
 
     /**
-     * Verify the hostname of the certificate used by the other end of a
-     * connected socket.  You MUST call this if you did not supply a hostname
-     * to {@link #createSocket()}.  It is harmless to call this method
-     * redundantly if the hostname has already been verified.
+     * Verify the hostname of the certificate used by the other end of a connected socket using the
+     * {@link HostnameVerifier} obtained from {@code
+     * HttpsURLConnection.getDefaultHostnameVerifier()}. You MUST call this if you did not supply a
+     * hostname to {@link #createSocket()}.  It is harmless to call this method redundantly if the
+     * hostname has already been verified.
      *
-     * <p>Wildcard certificates are allowed to verify any matching hostname,
-     * so "foo.bar.example.com" is verified if the peer has a certificate
-     * for "*.example.com".
+     * <p>Wildcard certificates are allowed to verify any matching hostname, so
+     * "foo.bar.example.com" is verified if the peer has a certificate for "*.example.com".
      *
      * @param socket An SSL socket which has been connected to a server
      * @param hostname The expected hostname of the remote server
@@ -483,7 +483,8 @@
      * {@inheritDoc}
      *
      * <p>By default, this method returns a <i>connected</i> socket and verifies the peer's
-     * certificate hostname after connecting; if this instance was created with
+     * certificate hostname after connecting using the {@link HostnameVerifier} obtained from
+     * {@code HttpsURLConnection.getDefaultHostnameVerifier()}; if this instance was created with
      * {@link #getInsecure(int, SSLSessionCache)}, it returns a socket that is <i>not connected</i>
      * instead.
      */
@@ -562,7 +563,8 @@
      * {@inheritDoc}
      *
      * <p>By default, this method returns a <i>connected</i> socket and verifies the peer's
-     * certificate hostname after connecting; if this instance was created with
+     * certificate hostname after connecting using the {@link HostnameVerifier} obtained from
+     * {@code HttpsURLConnection.getDefaultHostnameVerifier()}; if this instance was created with
      * {@link #getInsecure(int, SSLSessionCache)}, it returns a socket that is <i>not connected</i>
      * instead.
      */
@@ -585,7 +587,8 @@
      * {@inheritDoc}
      *
      * <p>By default, this method returns a <i>connected</i> socket and verifies the peer's
-     * certificate hostname after connecting; if this instance was created with
+     * certificate hostname after connecting using the {@link HostnameVerifier} obtained from
+     * {@code HttpsURLConnection.getDefaultHostnameVerifier()}; if this instance was created with
      * {@link #getInsecure(int, SSLSessionCache)}, it returns a socket that is <i>not connected</i>
      * instead.
      */
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 0425c62..0de4ddc 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -306,7 +306,7 @@
          * @hide
          */
         @SystemApi
-        public static final String PREVIEW_SDK_FINGERPRINT = SystemProperties.get(
+        @NonNull public static final String PREVIEW_SDK_FINGERPRINT = SystemProperties.get(
                 "ro.build.version.preview_sdk_fingerprint", "REL");
 
         /**
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 5d34aa6..fa244e4 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -766,15 +766,13 @@
         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/calendars");
 
         /**
-         * The content:// style URL for querying Calendars table in the managed profile. Appending a
-         * calendar id using {@link ContentUris#withAppendedId(Uri, long)} will
-         * specify a single calendar.
+         * The content:// style URL for querying Calendars table in the managed profile. Appending
+         * a calendar id using {@link ContentUris#withAppendedId(Uri, long)} specifies
+         * a single calendar.
          *
          * <p>The following columns are allowed to be queried via this uri:
          * <ul>
          * <li>{@link #_ID}</li>
-         * <li>{@link #NAME}</li>
-         * <li>{@link #CALENDAR_DISPLAY_NAME}</li>
          * <li>{@link #CALENDAR_COLOR}</li>
          * <li>{@link #VISIBLE}</li>
          * <li>{@link #CALENDAR_LOCATION}</li>
@@ -782,18 +780,22 @@
          * <li>{@link #IS_PRIMARY}</li>
          * </ul>
          *
-         * <p>{@link IllegalArgumentException} will be thrown if there exist columns in the
+         * <p>{@link IllegalArgumentException} is thrown if there exists columns in the
          * projection of the query to this uri that are not contained in the above list.
          *
-         * <p>This uri will return an empty cursor if the calling user is not a parent profile
-         * of a managed profile, or cross-profile calendar is disabled in Settings, or this uri is
-         * queried from a package that is not whitelisted by profile owner of the managed profile
-         * via
+         * <p>This uri returns an empty cursor if the calling user is not a parent profile
+         * of a managed profile, or the managed profile is disabled, or cross-profile calendar is
+         * disabled in Settings, or this uri is queried from a package that is not allowed by
+         * the profile owner of the managed profile via
          * {@link DevicePolicyManager#setCrossProfileCalendarPackages(ComponentName, Set)}.
          *
+         * <p>Apps can register a {@link android.database.ContentObserver} for this URI to listen
+         * to changes.
+         *
          * @see DevicePolicyManager#getCrossProfileCalendarPackages(ComponentName)
          * @see Settings.Secure#CROSS_PROFILE_CALENDAR_ENABLED
          */
+        @NonNull
         public static final Uri ENTERPRISE_CONTENT_URI =
                 Uri.parse("content://" + AUTHORITY + "/enterprise/calendars");
 
@@ -1747,8 +1749,7 @@
 
         /**
          * The content:// style URL for querying Events table in the managed profile. Appending an
-         * event id using {@link ContentUris#withAppendedId(Uri, long)} will
-         * specify a single event.
+         * event id using {@link ContentUris#withAppendedId(Uri, long)} specifies a single event.
          *
          * <p>The following columns are allowed to be queried via this uri:
          * <ul>
@@ -1767,26 +1768,33 @@
          * <li>{@link #AVAILABILITY}</li>
          * <li>{@link #RRULE}</li>
          * <li>{@link #RDATE}</li>
+         * <li>{@link #LAST_DATE}</li>
          * <li>{@link #EXRULE}</li>
          * <li>{@link #EXDATE}</li>
-         * <li>{@link #CALENDAR_DISPLAY_NAME}</li>
+         * <li>{@link #SELF_ATTENDEE_STATUS}</li>
+         * <li>{@link #DISPLAY_COLOR}</li>
          * <li>{@link #CALENDAR_COLOR}</li>
          * <li>{@link #VISIBLE}</li>
          * <li>{@link #CALENDAR_TIME_ZONE}</li>
+         * <li>{@link #IS_PRIMARY}</li>
          * </ul>
          *
-         * <p>{@link IllegalArgumentException} will be thrown if there exist columns in the
+         * <p>{@link IllegalArgumentException} is thrown if there exists columns in the
          * projection of the query to this uri that are not contained in the above list.
          *
-         * <p>This uri will return an empty cursor if the calling user is not a parent profile
-         * of a managed profile, or cross-profile calendar is disabled in Settings, or this uri is
-         * queried from a package that is not whitelisted by profile owner of the managed profile
-         * via
+         * <p>This uri returns an empty cursor if the calling user is not a parent profile
+         * of a managed profile, or the managed profile is disabled, or cross-profile calendar is
+         * disabled in Settings, or this uri is queried from a package that is not allowed by
+         * the profile owner of the managed profile via
          * {@link DevicePolicyManager#setCrossProfileCalendarPackages(ComponentName, Set)}.
          *
+         * <p>Apps can register a {@link android.database.ContentObserver} for this URI to listen
+         * to changes.
+         *
          * @see DevicePolicyManager#getCrossProfileCalendarPackages(ComponentName)
          * @see Settings.Secure#CROSS_PROFILE_CALENDAR_ENABLED
          */
+        @NonNull
         public static final Uri ENTERPRISE_CONTENT_URI =
                 Uri.parse("content://" + AUTHORITY + "/enterprise/events");
 
@@ -1974,7 +1982,7 @@
          * The content:// style URL for querying an instance range in the managed profile.
          * It supports similar semantics as {@link #CONTENT_URI}.
          *
-         * <p>The following columns plus the columns that are whitelisted by
+         * <p>The following columns plus the columns that are allowed by
          * {@link Events#ENTERPRISE_CONTENT_URI} are allowed to be queried via this uri:
          * <ul>
          * <li>{@link #_ID}</li>
@@ -1987,18 +1995,19 @@
          * <li>{@link #END_MINUTE}</li>
          * </ul>
          *
-         * <p>{@link IllegalArgumentException} will be thrown if there exist columns in the
+         * <p>{@link IllegalArgumentException} is thrown if there exists columns in the
          * projection of the query to this uri that are not contained in the above list.
          *
-         * <p>This uri will return an empty cursor if the calling user is not a parent profile
-         * of a managed profile, or cross-profile calendar for the managed profile is disabled in
-         * Settings, or this uri is queried from a package that is not whitelisted by
-         * profile owner of the managed profile via
+         * <p>This uri returns an empty cursor if the calling user is not a parent profile
+         * of a managed profile, or the managed profile is disabled, or cross-profile calendar is
+         * disabled in Settings, or this uri is queried from a package that is not allowed by
+         * the profile owner of the managed profile via
          * {@link DevicePolicyManager#setCrossProfileCalendarPackages(ComponentName, Set)}.
          *
          * @see DevicePolicyManager#getCrossProfileCalendarPackages(ComponentName)
          * @see Settings.Secure#CROSS_PROFILE_CALENDAR_ENABLED
          */
+        @NonNull
         public static final Uri ENTERPRISE_CONTENT_URI =
                 Uri.parse("content://" + AUTHORITY + "/enterprise/instances/when");
 
@@ -2007,6 +2016,7 @@
          * Day in the managed profile. It supports similar semantics as {@link #CONTENT_BY_DAY_URI}
          * and performs similar checks as {@link #ENTERPRISE_CONTENT_URI}.
          */
+        @NonNull
         public static final Uri ENTERPRISE_CONTENT_BY_DAY_URI =
                 Uri.parse("content://" + AUTHORITY + "/enterprise/instances/whenbyday");
 
@@ -2015,6 +2025,7 @@
          * term in the managed profile. It supports similar semantics as {@link #CONTENT_SEARCH_URI}
          * and performs similar checks as {@link #ENTERPRISE_CONTENT_URI}.
          */
+        @NonNull
         public static final Uri ENTERPRISE_CONTENT_SEARCH_URI =
                 Uri.parse("content://" + AUTHORITY + "/enterprise/instances/search");
 
@@ -2024,6 +2035,7 @@
          * {@link #CONTENT_SEARCH_BY_DAY_URI} and performs similar checks as
          * {@link #ENTERPRISE_CONTENT_URI}.
          */
+        @NonNull
         public static final Uri ENTERPRISE_CONTENT_SEARCH_BY_DAY_URI =
                 Uri.parse("content://" + AUTHORITY + "/enterprise/instances/searchbyday");
 
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index e4593e5..261e5db 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -322,7 +322,7 @@
      *
      * @hide
      */
-    @SystemApi
+    @SystemApi @TestApi
     public interface Rollback {
 
         /**
diff --git a/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java b/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java
index efdc968..ddbff7b 100644
--- a/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java
+++ b/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java
@@ -18,9 +18,11 @@
 
 import android.annotation.Nullable;
 import android.app.Person;
+import android.app.RemoteAction;
 import android.content.Context;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.Pair;
 
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -118,12 +120,60 @@
     @Nullable
     public static LabeledIntent.TitleChooser createTitleChooser(String actionType) {
         if (ConversationAction.TYPE_OPEN_URL.equals(actionType)) {
-            return (labeledIntent, resolveInfo) -> resolveInfo.handleAllWebDataURI
-                    ? labeledIntent.titleWithEntity : labeledIntent.titleWithoutEntity;
+            return (labeledIntent, resolveInfo) -> {
+                if (resolveInfo.handleAllWebDataURI) {
+                    return labeledIntent.titleWithEntity;
+                }
+                if ("android".equals(resolveInfo.activityInfo.packageName)) {
+                    return labeledIntent.titleWithEntity;
+                }
+                return labeledIntent.titleWithoutEntity;
+            };
         }
         return null;
     }
 
+    /**
+     * Returns a list of {@link ConversationAction}s that have 0 duplicates. Two actions are
+     * duplicates if they may look the same to users. This function assumes every
+     * ConversationActions with a non-null RemoteAction also have a non-null intent in the extras.
+     */
+    public static List<ConversationAction> removeActionsWithDuplicates(
+            List<ConversationAction> conversationActions) {
+        // Ideally, we should compare title and icon here, but comparing icon is expensive and thus
+        // we use the component name of the target handler as the heuristic.
+        Map<Pair<String, String>, Integer> counter = new ArrayMap<>();
+        for (ConversationAction conversationAction : conversationActions) {
+            Pair<String, String> representation = getRepresentation(conversationAction);
+            if (representation == null) {
+                continue;
+            }
+            Integer existingCount = counter.getOrDefault(representation, 0);
+            counter.put(representation, existingCount + 1);
+        }
+        List<ConversationAction> result = new ArrayList<>();
+        for (ConversationAction conversationAction : conversationActions) {
+            Pair<String, String> representation = getRepresentation(conversationAction);
+            if (representation == null || counter.getOrDefault(representation, 0) == 1) {
+                result.add(conversationAction);
+            }
+        }
+        return result;
+    }
+
+    @Nullable
+    private static Pair<String, String> getRepresentation(
+            ConversationAction conversationAction) {
+        RemoteAction remoteAction = conversationAction.getAction();
+        if (remoteAction == null) {
+            return null;
+        }
+        return new Pair<>(
+                conversationAction.getAction().getTitle().toString(),
+                ExtrasUtils.getActionIntent(
+                        conversationAction.getExtras()).getComponent().getPackageName());
+    }
+
     private static final class PersonEncoder {
         private final Map<Person, Integer> mMapping = new ArrayMap<>();
         private int mNextUserId = FIRST_NON_LOCAL_USER;
diff --git a/core/java/android/view/textclassifier/ExtrasUtils.java b/core/java/android/view/textclassifier/ExtrasUtils.java
index 2ad17a8..df548ae 100644
--- a/core/java/android/view/textclassifier/ExtrasUtils.java
+++ b/core/java/android/view/textclassifier/ExtrasUtils.java
@@ -29,6 +29,7 @@
  */
 public final class ExtrasUtils {
 
+    private static final String ACTION_INTENT = "action-intent";
     private static final String ACTIONS_INTENTS = "actions-intents";
     private static final String FOREIGN_LANGUAGE = "foreign-language";
     private static final String ENTITY_TYPE = "entity-type";
@@ -77,6 +78,22 @@
     }
 
     /**
+     * Stores {@code actionIntents} information in TextClassifier response object's extras
+     * {@code container}.
+     */
+    public static void putActionIntent(Bundle container, @Nullable Intent actionIntent) {
+        container.putParcelable(ACTION_INTENT, actionIntent);
+    }
+
+    /**
+     * Returns {@code actionIntent} information contained in a TextClassifier response object.
+     */
+    @Nullable
+    public static Intent getActionIntent(Bundle container) {
+        return container.getParcelable(ACTION_INTENT);
+    }
+
+    /**
      * Returns {@code actionIntents} information contained in the TextClassification object.
      */
     @Nullable
diff --git a/core/java/android/view/textclassifier/LabeledIntent.java b/core/java/android/view/textclassifier/LabeledIntent.java
index 7544dc1..d2897b2 100644
--- a/core/java/android/view/textclassifier/LabeledIntent.java
+++ b/core/java/android/view/textclassifier/LabeledIntent.java
@@ -91,15 +91,22 @@
             Context context, @Nullable TitleChooser titleChooser) {
         final PackageManager pm = context.getPackageManager();
         final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
-        final String packageName = resolveInfo != null && resolveInfo.activityInfo != null
-                ? resolveInfo.activityInfo.packageName : null;
-        Icon icon = null;
+
+        if (resolveInfo == null || resolveInfo.activityInfo == null) {
+            Log.w(TAG, "resolveInfo or activityInfo is null");
+            return null;
+        }
+        final String packageName = resolveInfo.activityInfo.packageName;
+        final String className = resolveInfo.activityInfo.name;
+        if (packageName == null || className == null) {
+            Log.w(TAG, "packageName or className is null");
+            return null;
+        }
         Intent resolvedIntent = new Intent(intent);
+        resolvedIntent.setComponent(new ComponentName(packageName, className));
         boolean shouldShowIcon = false;
-        if (packageName != null && !"android".equals(packageName)) {
-            // There is a default activity handling the intent.
-            resolvedIntent.setComponent(
-                    new ComponentName(packageName, resolveInfo.activityInfo.name));
+        Icon icon = null;
+        if (!"android".equals(packageName)) {
             if (resolveInfo.activityInfo.getIconResource() != 0) {
                 icon = Icon.createWithResource(
                         packageName, resolveInfo.activityInfo.getIconResource());
@@ -113,9 +120,6 @@
         }
         final PendingIntent pendingIntent =
                 TextClassification.createPendingIntent(context, resolvedIntent, requestCode);
-        if (pendingIntent == null) {
-            return null;
-        }
         if (titleChooser == null) {
             titleChooser = DEFAULT_TITLE_CHOOSER;
         }
@@ -150,6 +154,7 @@
     public interface TitleChooser {
         /**
          * Picks a title from a {@link LabeledIntent} by looking into resolved info.
+         * {@code resolveInfo} is guaranteed to have a non-null {@code activityInfo}.
          */
         @Nullable
         CharSequence chooseTitle(LabeledIntent labeledIntent, ResolveInfo resolveInfo);
diff --git a/core/java/android/view/textclassifier/TextClassification.java b/core/java/android/view/textclassifier/TextClassification.java
index 034da01..a275f0f 100644
--- a/core/java/android/view/textclassifier/TextClassification.java
+++ b/core/java/android/view/textclassifier/TextClassification.java
@@ -25,8 +25,6 @@
 import android.app.RemoteAction;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.graphics.BitmapFactory;
 import android.graphics.drawable.AdaptiveIconDrawable;
@@ -304,53 +302,10 @@
      * @throws IllegalArgumentException if context or intent is null
      * @hide
      */
-    @Nullable
     public static PendingIntent createPendingIntent(
             @NonNull final Context context, @NonNull final Intent intent, int requestCode) {
-        final int flags = PendingIntent.FLAG_UPDATE_CURRENT;
-        switch (getIntentType(intent, context)) {
-            case IntentType.ACTIVITY:
-                return PendingIntent.getActivity(context, requestCode, intent, flags);
-            case IntentType.SERVICE:
-                return PendingIntent.getService(context, requestCode, intent, flags);
-            default:
-                return null;
-        }
-    }
-
-    @IntentType
-    private static int getIntentType(@NonNull Intent intent, @NonNull Context context) {
-        Preconditions.checkArgument(context != null);
-        Preconditions.checkArgument(intent != null);
-
-        final ResolveInfo activityRI = context.getPackageManager().resolveActivity(intent, 0);
-        if (activityRI != null) {
-            if (context.getPackageName().equals(activityRI.activityInfo.packageName)) {
-                return IntentType.ACTIVITY;
-            }
-            final boolean exported = activityRI.activityInfo.exported;
-            if (exported && hasPermission(context, activityRI.activityInfo.permission)) {
-                return IntentType.ACTIVITY;
-            }
-        }
-
-        final ResolveInfo serviceRI = context.getPackageManager().resolveService(intent, 0);
-        if (serviceRI != null) {
-            if (context.getPackageName().equals(serviceRI.serviceInfo.packageName)) {
-                return IntentType.SERVICE;
-            }
-            final boolean exported = serviceRI.serviceInfo.exported;
-            if (exported && hasPermission(context, serviceRI.serviceInfo.permission)) {
-                return IntentType.SERVICE;
-            }
-        }
-
-        return IntentType.UNSUPPORTED;
-    }
-
-    private static boolean hasPermission(@NonNull Context context, @NonNull String permission) {
-        return permission == null
-                || context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
+        return PendingIntent.getActivity(
+                context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     /**
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 632328b..35cd678 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -84,12 +84,17 @@
     private final GenerateLinksLogger mGenerateLinksLogger;
 
     private final Object mLock = new Object();
+
     @GuardedBy("mLock") // Do not access outside this lock.
     private ModelFileManager.ModelFile mAnnotatorModelInUse;
     @GuardedBy("mLock") // Do not access outside this lock.
     private AnnotatorModel mAnnotatorImpl;
+
+    @GuardedBy("mLock") // Do not access outside this lock.
+    private ModelFileManager.ModelFile mLangIdModelInUse;
     @GuardedBy("mLock") // Do not access outside this lock.
     private LangIdModel mLangIdImpl;
+
     @GuardedBy("mLock") // Do not access outside this lock.
     private ModelFileManager.ModelFile mActionModelInUse;
     @GuardedBy("mLock") // Do not access outside this lock.
@@ -403,6 +408,12 @@
         return mFallback.suggestConversationActions(request);
     }
 
+    /**
+     * Returns the {@link ConversationAction} result, with a non-null extras.
+     * <p>
+     * Whenever the RemoteAction is non-null, you can expect its corresponding intent
+     * with a non-null component name is in the extras.
+     */
     private ConversationActions createConversationActionResult(
             ConversationActions.Request request,
             ActionsSuggestionsModel.ActionSuggestion[] nativeSuggestions) {
@@ -419,6 +430,7 @@
             }
             List<LabeledIntent> labeledIntents =
                     mTemplateIntentFactory.create(nativeSuggestion.getRemoteActionTemplates());
+            Bundle extras = new Bundle();
             RemoteAction remoteAction = null;
             // Given that we only support implicit intent here, we should expect there is just one
             // intent for each action type.
@@ -428,6 +440,7 @@
                 LabeledIntent.Result result = labeledIntents.get(0).resolve(mContext, titleChooser);
                 if (result != null) {
                     remoteAction = result.remoteAction;
+                    ExtrasUtils.putActionIntent(extras, result.resolvedIntent);
                 }
             }
             conversationActions.add(
@@ -435,8 +448,11 @@
                             .setConfidenceScore(nativeSuggestion.getScore())
                             .setTextReply(nativeSuggestion.getResponseText())
                             .setAction(remoteAction)
+                            .setExtras(extras)
                             .build());
         }
+        conversationActions =
+                ActionsSuggestionsHelper.removeActionsWithDuplicates(conversationActions);
         String resultId = ActionsSuggestionsHelper.createResultId(
                 mContext,
                 request.getConversation(),
@@ -504,17 +520,19 @@
 
     private LangIdModel getLangIdImpl() throws FileNotFoundException {
         synchronized (mLock) {
-            if (mLangIdImpl == null) {
-                final ModelFileManager.ModelFile bestModel =
-                        mLangIdModelFileManager.findBestModelFile(null);
-                if (bestModel == null) {
-                    throw new FileNotFoundException("No LangID model is found");
-                }
+            final ModelFileManager.ModelFile bestModel =
+                    mLangIdModelFileManager.findBestModelFile(null);
+            if (bestModel == null) {
+                throw new FileNotFoundException("No LangID model is found");
+            }
+            if (mLangIdImpl == null || !Objects.equals(mLangIdModelInUse, bestModel)) {
+                Log.d(DEFAULT_LOG_TAG, "Loading " + bestModel);
                 final ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
                         new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
                 try {
                     if (pfd != null) {
                         mLangIdImpl = new LangIdModel(pfd.getFd());
+                        mLangIdModelInUse = bestModel;
                     }
                 } finally {
                     maybeCloseAndLogError(pfd);
@@ -527,13 +545,14 @@
     @Nullable
     private ActionsSuggestionsModel getActionsImpl() throws FileNotFoundException {
         synchronized (mLock) {
-            if (mActionsImpl == null) {
-                // TODO: Use LangID to determine the locale we should use here?
-                final ModelFileManager.ModelFile bestModel =
-                        mActionsModelFileManager.findBestModelFile(LocaleList.getDefault());
-                if (bestModel == null) {
-                    return null;
-                }
+            // TODO: Use LangID to determine the locale we should use here?
+            final ModelFileManager.ModelFile bestModel =
+                    mActionsModelFileManager.findBestModelFile(LocaleList.getDefault());
+            if (bestModel == null) {
+                return null;
+            }
+            if (mActionsImpl == null || !Objects.equals(mActionModelInUse, bestModel)) {
+                Log.d(DEFAULT_LOG_TAG, "Loading " + bestModel);
                 final ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
                         new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
                 try {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d176260..ea300aa 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2152,9 +2152,9 @@
      screen lock to a certain complexity level.
      <p>Protection level: normal
     -->
-    <permission android:name="android.permission.REQUEST_SCREEN_LOCK_COMPLEXITY"
-                android:label="@string/permlab_requestScreenLockComplexity"
-                android:description="@string/permdesc_requestScreenLockComplexity"
+    <permission android:name="android.permission.REQUEST_PASSWORD_COMPLEXITY"
+                android:label="@string/permlab_requestPasswordComplexity"
+                android:description="@string/permdesc_requestPasswordComplexity"
                 android:protectionLevel="normal" />
 
     <!-- ================================== -->
@@ -2524,7 +2524,7 @@
     <permission android:name="android.permission.WRITE_GSERVICES"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi @hide Allows an application to modify config settings.
+    <!-- @SystemApi @TestApi @hide Allows an application to modify config settings.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.WRITE_DEVICE_CONFIG"
         android:protectionLevel="signature|configurator"/>
@@ -3917,7 +3917,7 @@
     <permission android:name="android.permission.PACKAGE_ROLLBACK_AGENT"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi @hide Allows managing apk level rollbacks. -->
+    <!-- @SystemApi @TestApi @hide Allows managing apk level rollbacks. -->
     <permission android:name="android.permission.MANAGE_ROLLBACKS"
         android:protectionLevel="signature|verifier" />
 
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index fc7b4cf..dbea13e 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1473,6 +1473,9 @@
         <flag name="location" value="0x08" />
         <!-- Auto, bluetooth, TV or other devices connection, monitoring and interaction. -->
         <flag name="connectedDevice" value="0x10" />
+        <!-- Managing a media projection session, e.g, for screen recording or taking
+             screenshots.-->
+        <flag name="mediaProjection" value="0x20" />
     </attr>
 
 
@@ -1993,7 +1996,9 @@
          {@link #AndroidManifestApplication application} tag. -->
     <declare-styleable name="AndroidManifestUsesPackage" parent="AndroidManifestApplication">
         <!-- Required type of association with the package, for example "android.package.ad_service"
-             if it provides an advertising service. -->
+             if it provides an advertising service.  This should use the standard scoped naming
+             convention as used for other things such as package names, based on the Java naming
+             convention. -->
         <attr name="packageType" format="string" />
         <!-- Required name of the package you use. -->
         <attr name="name" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f7b27f0..a69655a 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1406,9 +1406,9 @@
       re-enables the keylock when the call is finished.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=NONE] -->
-    <string name="permlab_requestScreenLockComplexity">request screen lock complexity</string>
+    <string name="permlab_requestPasswordComplexity">request screen lock complexity</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=NONE] -->
-    <string name="permdesc_requestScreenLockComplexity">Allows the app to learn the screen
+    <string name="permdesc_requestPasswordComplexity">Allows the app to learn the screen
         lock complexity level (high, medium, low or none), which indicates the possible range of
         length and type of the screen lock. The app can also suggest to users that they update the
         screen lock to a certain level but users can freely ignore and navigate away. Note that the
diff --git a/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java b/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
index 5022e30..f440953 100644
--- a/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
@@ -21,8 +21,15 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.app.PendingIntent;
 import android.app.Person;
+import android.app.RemoteAction;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
 
+import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -36,6 +43,7 @@
 import java.time.ZonedDateTime;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.List;
 import java.util.Locale;
 import java.util.function.Function;
 
@@ -129,6 +137,73 @@
         assertNativeMessage(conversationMessages[2], thirdMessage.getText(), 1, 2000);
     }
 
+    @Test
+    public void testDeduplicateActions() {
+        Bundle phoneExtras = new Bundle();
+        Intent phoneIntent = new Intent();
+        phoneIntent.setComponent(new ComponentName("phone", "intent"));
+        ExtrasUtils.putActionIntent(phoneExtras, phoneIntent);
+
+        Bundle anotherPhoneExtras = new Bundle();
+        Intent anotherPhoneIntent = new Intent();
+        anotherPhoneIntent.setComponent(new ComponentName("phone", "another.intent"));
+        ExtrasUtils.putActionIntent(anotherPhoneExtras, anotherPhoneIntent);
+
+        Bundle urlExtras = new Bundle();
+        Intent urlIntent = new Intent();
+        urlIntent.setComponent(new ComponentName("url", "intent"));
+        ExtrasUtils.putActionIntent(urlExtras, urlIntent);
+
+        PendingIntent pendingIntent = PendingIntent.getActivity(
+                InstrumentationRegistry.getTargetContext(),
+                0,
+                phoneIntent,
+                0);
+        Icon icon = Icon.createWithData(new byte[0], 0, 0);
+        ConversationAction action =
+                new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+                        .setAction(new RemoteAction(icon, "label", "1", pendingIntent))
+                        .setExtras(phoneExtras)
+                        .build();
+        ConversationAction actionWithSameLabel =
+                new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+                        .setAction(new RemoteAction(
+                                icon, "label", "2", pendingIntent))
+                        .setExtras(phoneExtras)
+                        .build();
+        ConversationAction actionWithSamePackageButDifferentClass =
+                new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+                        .setAction(new RemoteAction(
+                                icon, "label", "3", pendingIntent))
+                        .setExtras(anotherPhoneExtras)
+                        .build();
+        ConversationAction actionWithDifferentLabel =
+                new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+                        .setAction(new RemoteAction(
+                                icon, "another_label", "4", pendingIntent))
+                        .setExtras(phoneExtras)
+                        .build();
+        ConversationAction actionWithDifferentPackage =
+                new ConversationAction.Builder(ConversationAction.TYPE_OPEN_URL)
+                        .setAction(new RemoteAction(icon, "label", "5", pendingIntent))
+                        .setExtras(urlExtras)
+                        .build();
+        ConversationAction actionWithoutRemoteAction =
+                new ConversationAction.Builder(ConversationAction.TYPE_CREATE_REMINDER)
+                        .build();
+
+        List<ConversationAction> conversationActions =
+                ActionsSuggestionsHelper.removeActionsWithDuplicates(
+                        Arrays.asList(action, actionWithSameLabel,
+                                actionWithSamePackageButDifferentClass, actionWithDifferentLabel,
+                                actionWithDifferentPackage, actionWithoutRemoteAction));
+
+        assertThat(conversationActions).hasSize(3);
+        assertThat(conversationActions.get(0).getAction().getContentDescription()).isEqualTo("4");
+        assertThat(conversationActions.get(1).getAction().getContentDescription()).isEqualTo("5");
+        assertThat(conversationActions.get(2).getAction()).isNull();
+    }
+
     private ZonedDateTime createZonedDateTimeFromMsUtc(long msUtc) {
         return ZonedDateTime.ofInstant(Instant.ofEpochMilli(msUtc), ZoneId.of("UTC"));
     }
diff --git a/core/tests/coretests/src/android/view/textclassifier/LabeledIntentTest.java b/core/tests/coretests/src/android/view/textclassifier/LabeledIntentTest.java
index e4e9cde..6520c8f 100644
--- a/core/tests/coretests/src/android/view/textclassifier/LabeledIntentTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/LabeledIntentTest.java
@@ -132,7 +132,6 @@
         assertThat(intent.getComponent()).isNotNull();
     }
 
-
     @Test
     public void resolve_missingTitle() {
         assertThrows(
@@ -146,4 +145,19 @@
                                 REQUEST_CODE
                         ));
     }
+
+    @Test
+    public void resolve_noIntentHandler() {
+        Intent intent = new Intent("some.thing.does.not.exist");
+        LabeledIntent labeledIntent = new LabeledIntent(
+                TITLE_WITHOUT_ENTITY,
+                null,
+                DESCRIPTION,
+                intent,
+                REQUEST_CODE);
+
+        LabeledIntent.Result result = labeledIntent.resolve(mContext, null);
+
+        assertThat(result).isNull();
+    }
 }
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java
index d2d03e5..bcaf663 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java
@@ -24,6 +24,7 @@
 import android.app.RemoteAction;
 import android.content.Context;
 import android.content.Intent;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.LocaleList;
 import android.text.Spannable;
@@ -32,6 +33,8 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
+import com.google.common.truth.Truth;
+
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
@@ -403,7 +406,6 @@
 
         ConversationActions conversationActions = mClassifier.suggestConversationActions(request);
         assertTrue(conversationActions.getConversationActions().size() > 0);
-        assertTrue(conversationActions.getConversationActions().size() == 1);
         for (ConversationAction conversationAction :
                 conversationActions.getConversationActions()) {
             assertThat(conversationAction,
@@ -438,6 +440,34 @@
         }
     }
 
+    @Test
+    public void testSuggestConversationActions_openUrl() {
+        if (isTextClassifierDisabled()) return;
+        ConversationActions.Message message =
+                new ConversationActions.Message.Builder(
+                        ConversationActions.Message.PERSON_USER_OTHERS)
+                        .setText("Check this out: https://www.android.com")
+                        .build();
+        TextClassifier.EntityConfig typeConfig =
+                new TextClassifier.EntityConfig.Builder().includeTypesFromTextClassifier(false)
+                        .setIncludedTypes(
+                                Collections.singletonList(ConversationAction.TYPE_OPEN_URL))
+                        .build();
+        ConversationActions.Request request =
+                new ConversationActions.Request.Builder(Collections.singletonList(message))
+                        .setMaxSuggestions(1)
+                        .setTypeConfig(typeConfig)
+                        .build();
+
+        ConversationActions conversationActions = mClassifier.suggestConversationActions(request);
+        Truth.assertThat(conversationActions.getConversationActions()).hasSize(1);
+        ConversationAction conversationAction = conversationActions.getConversationActions().get(0);
+        Truth.assertThat(conversationAction.getType()).isEqualTo(ConversationAction.TYPE_OPEN_URL);
+        Intent actionIntent = ExtrasUtils.getActionIntent(conversationAction.getExtras());
+        Truth.assertThat(actionIntent.getAction()).isEqualTo(Intent.ACTION_VIEW);
+        Truth.assertThat(actionIntent.getData()).isEqualTo(Uri.parse("https://www.android.com"));
+    }
+
 
     private boolean isTextClassifierDisabled() {
         return mClassifier == null || mClassifier == TextClassifier.NO_OP;
diff --git a/libs/hwui/surfacetexture/ImageConsumer.cpp b/libs/hwui/surfacetexture/ImageConsumer.cpp
index 624c290..077a8f7 100644
--- a/libs/hwui/surfacetexture/ImageConsumer.cpp
+++ b/libs/hwui/surfacetexture/ImageConsumer.cpp
@@ -23,6 +23,7 @@
 #include "renderthread/RenderThread.h"
 #include "renderthread/VulkanManager.h"
 #include "utils/Color.h"
+#include <GrAHardwareBufferUtils.h>
 
 // Macro for including the SurfaceTexture name in log messages
 #define IMG_LOGE(x, ...) ALOGE("[%s] " x, st.mName.string(), ##__VA_ARGS__)
@@ -30,31 +31,67 @@
 namespace android {
 
 void ImageConsumer::onFreeBufferLocked(int slotIndex) {
-    mImageSlots[slotIndex].mImage.reset();
+    mImageSlots[slotIndex].clear();
 }
 
 void ImageConsumer::onAcquireBufferLocked(BufferItem* item) {
     // If item->mGraphicBuffer is not null, this buffer has not been acquired
     // before, so any prior SkImage is created with a stale buffer. This resets the stale SkImage.
     if (item->mGraphicBuffer != nullptr) {
-        mImageSlots[item->mSlot].mImage.reset();
+        mImageSlots[item->mSlot].clear();
     }
 }
 
 void ImageConsumer::onReleaseBufferLocked(int buf) {
-    mImageSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
+    mImageSlots[buf].eglFence() = EGL_NO_SYNC_KHR;
 }
 
 void ImageConsumer::ImageSlot::createIfNeeded(sp<GraphicBuffer> graphicBuffer,
-                                              android_dataspace dataspace, bool forceCreate) {
+                                              android_dataspace dataspace, bool forceCreate,
+                                              GrContext* context) {
     if (!mImage.get() || dataspace != mDataspace || forceCreate) {
-        mImage = graphicBuffer.get()
-                         ? SkImage::MakeFromAHardwareBuffer(
-                                   reinterpret_cast<AHardwareBuffer*>(graphicBuffer.get()),
-                                   kPremul_SkAlphaType,
-                                   uirenderer::DataSpaceToColorSpace(dataspace))
-                         : nullptr;
+        if (!graphicBuffer.get()) {
+            clear();
+            return;
+        }
+
+        if (!mBackendTexture.isValid()) {
+            clear();
+            bool createProtectedImage =
+                0 != (graphicBuffer->getUsage() & GraphicBuffer::USAGE_PROTECTED);
+            GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat(
+                context,
+                reinterpret_cast<AHardwareBuffer*>(graphicBuffer.get()),
+                graphicBuffer->getPixelFormat(),
+                false);
+            mBackendTexture = GrAHardwareBufferUtils::MakeBackendTexture(
+                context,
+                reinterpret_cast<AHardwareBuffer*>(graphicBuffer.get()),
+                graphicBuffer->getWidth(),
+                graphicBuffer->getHeight(),
+                &mDeleteProc,
+                &mDeleteCtx,
+                createProtectedImage,
+                backendFormat,
+                false);
+        }
         mDataspace = dataspace;
+        SkColorType colorType = GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(
+            graphicBuffer->getPixelFormat());
+        mImage = SkImage::MakeFromTexture(context,
+            mBackendTexture,
+            kTopLeft_GrSurfaceOrigin,
+            colorType,
+            kPremul_SkAlphaType,
+            uirenderer::DataSpaceToColorSpace(dataspace));
+    }
+}
+
+void ImageConsumer::ImageSlot::clear() {
+    mImage.reset();
+    if (mBackendTexture.isValid()) {
+        mDeleteProc(mDeleteCtx);
+        mBackendTexture = {};
     }
 }
 
@@ -71,8 +108,8 @@
             if (slot != BufferItem::INVALID_BUFFER_SLOT) {
                 *queueEmpty = true;
                 mImageSlots[slot].createIfNeeded(st.mSlots[slot].mGraphicBuffer,
-                        st.mCurrentDataSpace, false);
-                return mImageSlots[slot].mImage;
+                        st.mCurrentDataSpace, false, renderState.getRenderThread().getGrContext());
+                return mImageSlots[slot].getImage();
             }
         }
         return nullptr;
@@ -104,7 +141,7 @@
             uirenderer::RenderPipelineType::SkiaGL) {
             auto& eglManager = renderState.getRenderThread().eglManager();
             display = eglManager.eglDisplay();
-            err = eglManager.createReleaseFence(st.mUseFenceSync, &mImageSlots[slot].mEglFence,
+            err = eglManager.createReleaseFence(st.mUseFenceSync, &mImageSlots[slot].eglFence(),
                                                 releaseFence);
         } else {
             err = renderState.getRenderThread().vulkanManager().createReleaseFence(releaseFence);
@@ -129,7 +166,7 @@
         // Finally release the old buffer.
         status_t status = st.releaseBufferLocked(
                 st.mCurrentTexture, st.mSlots[st.mCurrentTexture].mGraphicBuffer, display,
-                mImageSlots[st.mCurrentTexture].mEglFence);
+                mImageSlots[st.mCurrentTexture].eglFence());
         if (status < NO_ERROR) {
             IMG_LOGE("dequeueImage: failed to release buffer: %s (%d)", strerror(-status), status);
             err = status;
@@ -150,8 +187,9 @@
     st.computeCurrentTransformMatrixLocked();
 
     *queueEmpty = false;
-    mImageSlots[slot].createIfNeeded(st.mSlots[slot].mGraphicBuffer, item.mDataSpace, true);
-    return mImageSlots[slot].mImage;
+    mImageSlots[slot].createIfNeeded(st.mSlots[slot].mGraphicBuffer, item.mDataSpace, true,
+        renderState.getRenderThread().getGrContext());
+    return mImageSlots[slot].getImage();
 }
 
 } /* namespace android */
diff --git a/libs/hwui/surfacetexture/ImageConsumer.h b/libs/hwui/surfacetexture/ImageConsumer.h
index 5c41903..eee0a0a 100644
--- a/libs/hwui/surfacetexture/ImageConsumer.h
+++ b/libs/hwui/surfacetexture/ImageConsumer.h
@@ -25,6 +25,12 @@
 #include <cutils/compiler.h>
 #include <gui/BufferItem.h>
 #include <system/graphics.h>
+#include <GrBackendSurface.h>
+
+namespace GrAHardwareBufferUtils {
+typedef void* DeleteImageCtx;
+typedef void (*DeleteImageProc)(DeleteImageCtx);
+}
 
 namespace android {
 
@@ -67,9 +73,21 @@
      * ImageSlot contains the information and object references that
      * ImageConsumer maintains about a BufferQueue buffer slot.
      */
-    struct ImageSlot {
+    class ImageSlot {
+    public:
         ImageSlot() : mDataspace(HAL_DATASPACE_UNKNOWN), mEglFence(EGL_NO_SYNC_KHR) {}
 
+        ~ImageSlot() { clear(); }
+
+        void createIfNeeded(sp<GraphicBuffer> graphicBuffer, android_dataspace dataspace,
+                            bool forceCreate, GrContext* context);
+        void clear();
+
+        inline EGLSyncKHR& eglFence() { return mEglFence; }
+
+        inline sk_sp<SkImage> getImage() { return mImage; }
+
+    private:
         // mImage is the SkImage created from mGraphicBuffer.
         sk_sp<SkImage> mImage;
 
@@ -82,8 +100,11 @@
          */
         EGLSyncKHR mEglFence;
 
-        void createIfNeeded(sp<GraphicBuffer> graphicBuffer, android_dataspace dataspace,
-                            bool forceCreate);
+        GrBackendTexture mBackendTexture;
+
+        GrAHardwareBufferUtils::DeleteImageProc mDeleteProc;
+
+        GrAHardwareBufferUtils::DeleteImageCtx mDeleteCtx;
     };
 
     /**
diff --git a/libs/hwui/surfacetexture/SurfaceTexture.cpp b/libs/hwui/surfacetexture/SurfaceTexture.cpp
index da09444..a27db65 100644
--- a/libs/hwui/surfacetexture/SurfaceTexture.cpp
+++ b/libs/hwui/surfacetexture/SurfaceTexture.cpp
@@ -23,6 +23,7 @@
 
 #include "Matrix.h"
 #include "SurfaceTexture.h"
+#include "ImageConsumer.h"
 
 namespace android {
 
@@ -150,7 +151,7 @@
     // buffer has reallocated the original buffer slot after this buffer
     // was acquired.
     status_t err = ConsumerBase::releaseBufferLocked(buf, graphicBuffer, display, eglFence);
-    // We could be releasing an EGL buffer, even if not currently attached to a GL context.
+    // We could be releasing an EGL/Vulkan buffer, even if not currently attached to a GL context.
     mImageConsumer.onReleaseBufferLocked(buf);
     mEGLConsumer.onReleaseBufferLocked(buf);
     return err;
@@ -235,6 +236,10 @@
 
     if (mOpMode == OpMode::attachedToView) {
         mOpMode = OpMode::detached;
+        // Free all EglImage and VkImage before the context is destroyed.
+        for (int i=0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; i++) {
+            mImageConsumer.onFreeBufferLocked(i);
+        }
     } else {
         SFT_LOGE("detachFromView: not attached to View");
     }
diff --git a/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml b/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml
index b063e13..814246f 100644
--- a/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml
+++ b/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml
@@ -66,7 +66,7 @@
             android:id="@+id/bar_chart_details"
             style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
             android:layout_width="wrap_content"
-            android:layout_height="48dp"
+            android:layout_height="wrap_content"
             android:gravity="center"/>
     </LinearLayout>
 
diff --git a/packages/SettingsLib/BarChartPreference/res/values/styles.xml b/packages/SettingsLib/BarChartPreference/res/values/styles.xml
index 4876cb6..5587928 100644
--- a/packages/SettingsLib/BarChartPreference/res/values/styles.xml
+++ b/packages/SettingsLib/BarChartPreference/res/values/styles.xml
@@ -18,7 +18,7 @@
 <resources>
     <style name="BarViewStyle">
         <item name="android:layout_width">0dp</item>
-        <item name="android:layout_height">226dp</item>
+        <item name="android:layout_height">250dp</item>
         <item name="android:layout_weight">1</item>
         <item name="android:layout_marginStart">8dp</item>
         <item name="android:layout_marginEnd">8dp</item>
diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java
index 1003c97..20e0a3b 100644
--- a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java
+++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java
@@ -158,6 +158,11 @@
         holder.setDividerAllowedAbove(true);
         holder.setDividerAllowedBelow(true);
 
+        // We bind title and details early so that we can preserve the correct height for chart
+        // view.
+        bindChartTitleView(holder);
+        bindChartDetailsView(holder);
+
         // If the state is loading, we just show a blank view.
         if (mIsLoading) {
             holder.itemView.setVisibility(View.INVISIBLE);
@@ -165,9 +170,6 @@
         }
         holder.itemView.setVisibility(View.VISIBLE);
 
-        // We must show title of bar chart.
-        bindChartTitleView(holder);
-
         final BarViewInfo[] barViewInfos = mBarChartInfo.getBarViewInfos();
         // If there is no any bar view, we just show an empty text.
         if (barViewInfos == null || barViewInfos.length == 0) {
@@ -175,8 +177,6 @@
             return;
         }
         setEmptyViewVisible(holder, false /* visible */);
-
-        bindChartDetailsView(holder);
         updateBarChart(holder);
     }
 
diff --git a/packages/SettingsLib/LayoutPreference/res/values/styles.xml b/packages/SettingsLib/LayoutPreference/res/values/styles.xml
index 805744b..6a2b729 100644
--- a/packages/SettingsLib/LayoutPreference/res/values/styles.xml
+++ b/packages/SettingsLib/LayoutPreference/res/values/styles.xml
@@ -31,12 +31,10 @@
     </style>
 
     <style name="TextAppearance.EntityHeaderSummary"
-           parent="@android:style/TextAppearance.Material.Body1">
+           parent="@*android:style/TextAppearance.DeviceDefault.Body1">
         <item name="android:textAlignment">viewStart</item>
         <item name="android:textColor">?android:attr/textColorSecondary</item>
-        <item name="android:gravity">start</item>
         <item name="android:singleLine">true</item>
         <item name="android:ellipsize">marquee</item>
-        <item name="android:textSize">14sp</item>
     </style>
 </resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/circle_blue_40dp.xml b/packages/SystemUI/res/drawable/circle_blue_40dp.xml
new file mode 100644
index 0000000..00d2c52
--- /dev/null
+++ b/packages/SystemUI/res/drawable/circle_blue_40dp.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="oval">
+    <size android:height="40dp"
+          android:width="40dp" />
+    <solid android:color="#4285f4" />
+    <stroke android:color="#f1f3f4" android:width="1dp" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/circle_white_40dp.xml b/packages/SystemUI/res/drawable/circle_white_40dp.xml
new file mode 100644
index 0000000..bcb1640
--- /dev/null
+++ b/packages/SystemUI/res/drawable/circle_white_40dp.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="oval">
+    <size android:height="40dp"
+          android:width="40dp" />
+    <solid android:color="#ffffff" />
+    <stroke android:color="#f1f3f4" android:width="1dp" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 7e0f3ae..725ace4 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -220,48 +220,142 @@
                     android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
                     style="@style/TextAppearance.NotificationInfo.Button"/>
             </LinearLayout>
-
-
         </RelativeLayout>
         <LinearLayout
             android:id="@+id/interruptiveness_settings"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginTop="@dimen/notification_guts_button_spacing"
-            android:layout_marginStart="@dimen/notification_guts_button_side_margin"
-            android:layout_marginEnd="@dimen/notification_guts_button_side_margin"
-            android:gravity="center"
-            android:orientation="horizontal"
+            android:orientation="vertical"
             android:visibility="gone">
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="2dp"
+                android:layout_marginStart="@dimen/notification_guts_button_side_margin"
+                android:layout_marginEnd="@dimen/notification_guts_button_side_margin"
+                android:gravity="center"
+                android:orientation="horizontal">
+                <LinearLayout
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:gravity="center_horizontal"
+                    android:orientation="vertical">
+                    <FrameLayout
+                        android:id="@+id/int_block_wrapper"
+                        android:padding="4dp"
+                        android:layout_width="48dp"
+                        android:layout_height="48dp"
+                        android:gravity="center">
+                        <ImageButton
+                            android:id="@+id/int_block"
+                            android:background="@drawable/circle_white_40dp"
+                            android:src="@drawable/ic_notification_block"
+                            android:layout_gravity="center"
+                            android:layout_width="40dp"
+                            android:layout_height="40dp"
+                            android:clickable="false"
+                            android:tint="@color/GM2_grey_400"
+                            style="@style/TextAppearance.NotificationInfo.Button"/>
+                    </FrameLayout>
+                    <TextView
+                        android:id="@+id/int_block_label"
+                        android:text="@string/inline_block_button"
+                        android:layout_gravity="center_horizontal"
+                        android:gravity="center"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:ellipsize="end"
+                        android:maxLines="1"
+                        style="@style/TextAppearance.NotificationInfo.ButtonLabel"/>
+                </LinearLayout>
+                <LinearLayout
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:gravity="center_horizontal"
+                    android:orientation="vertical">
+                    <FrameLayout
+                        android:id="@+id/int_silent_wrapper"
+                        android:padding="4dp"
+                        android:layout_width="48dp"
+                        android:layout_height="48dp"
+                        android:gravity="center">
+                        <ImageButton
+                            android:id="@+id/int_silent"
+                            android:background="@drawable/circle_white_40dp"
+                            android:src="@drawable/ic_notifications_silence"
+                            android:layout_gravity="center"
+                            android:layout_width="40dp"
+                            android:layout_height="40dp"
+                            android:clickable="false"
+                            android:tint="@color/GM2_grey_400"
+                            style="@style/TextAppearance.NotificationInfo.Button"/>
+                    </FrameLayout>
+                    <TextView
+                        android:id="@+id/int_silent_label"
+                        android:text="@string/inline_silent_button_silent"
+                        android:layout_gravity="center_horizontal"
+                        android:gravity="center"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:ellipsize="end"
+                        android:maxLines="1"
+                        style="@style/TextAppearance.NotificationInfo.ButtonLabel"/>
+                </LinearLayout>
+                <LinearLayout
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:gravity="center_horizontal"
+                    android:orientation="vertical">
+                    <FrameLayout
+                        android:id="@+id/int_alert_wrapper"
+                        android:padding="4dp"
+                        android:layout_width="48dp"
+                        android:layout_height="48dp"
+                        android:gravity="center">
+                        <ImageButton
+                            android:id="@+id/int_alert"
+                            android:background="@drawable/circle_white_40dp"
+                            android:src="@drawable/ic_notifications_alert"
+                            android:layout_gravity="center"
+                            android:layout_width="40dp"
+                            android:layout_height="40dp"
+                            android:clickable="false"
+                            android:tint="@color/GM2_grey_400"
+                            style="@style/TextAppearance.NotificationInfo.Button"/>
+                    </FrameLayout>
+                    <TextView
+                        android:id="@+id/int_alert_label"
+                        android:text="@string/inline_silent_button_alert"
+                        android:layout_gravity="center_horizontal"
+                        android:gravity="center"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:ellipsize="end"
+                        android:maxLines="1"
+                        style="@style/TextAppearance.NotificationInfo.ButtonLabel"/>
+                </LinearLayout>
+            </LinearLayout>
             <TextView
-                android:id="@+id/int_block"
-                android:text="@string/inline_block_button"
-                android:layout_width="0dp"
-                android:layout_height="match_parent"
-                android:drawableTop="@drawable/ic_notification_block"
-                android:drawableTint="?android:attr/colorAccent"
-                android:layout_weight="1"
-                style="@style/TextAppearance.NotificationInfo.Button"/>
+                android:id="@+id/hint_text"
+                android:layout_marginStart="@*android:dimen/notification_content_margin_start"
+                android:layout_marginEnd="@*android:dimen/notification_content_margin_start"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                style="@style/TextAppearance.NotificationInfo.HintText" />
             <TextView
-                android:id="@+id/int_silent"
-                android:text="@string/inline_minimize_button"
-                android:layout_width="0dp"
-                android:layout_height="match_parent"
-                android:drawableTop="@drawable/ic_notifications_silence"
-                android:drawableTint="?android:attr/colorAccent"
-                android:layout_weight="1"
-                style="@style/TextAppearance.NotificationInfo.Button"/>
-            <TextView
-                android:id="@+id/int_alert"
-                android:text="@string/inline_keep_button"
-                android:layout_width="0dp"
-                android:layout_height="match_parent"
-                android:drawableTop="@drawable/ic_notifications_alert"
-                android:drawableTint="?android:attr/colorAccent"
-                android:layout_weight="1"
-                style="@style/TextAppearance.NotificationInfo.Button"/>
+                android:id="@+id/done_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="right"
+                android:paddingRight="24dp"
+                android:text="@string/inline_done_button"
+                style="@style/TextAppearance.NotificationInfo.Button" />
         </LinearLayout>
     </LinearLayout>
+
     <com.android.systemui.statusbar.notification.row.NotificationUndoLayout
         android:id="@+id/confirmation"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 9e9aada..16222f7 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1608,7 +1608,7 @@
     <string name="inline_silent_button_stay_silent">Stay silent</string>
 
     <!-- Notification inline controls: button to make notifications alert the user [CHAR_LIMIT=35] -->
-    <string name="inline_silent_button_alert">Alert me</string>
+    <string name="inline_silent_button_alert">Alert</string>
 
     <!-- Notification inline controls: button to continue alerting the user when notifications arrive [CHAR_LIMIT=35] -->
     <string name="inline_silent_button_keep_alerting">Keep alerting</string>
@@ -1616,6 +1616,15 @@
     <!-- Notification Inline controls: continue receiving notifications prompt, app level -->
     <string name="inline_keep_showing_app">Keep showing notifications from this app?</string>
 
+    <!-- Hint text for block button in the interruptiveness settings [CHAR_LIMIT=NONE]-->
+    <string name="hint_text_block">Blocked notifications do not appear anywhere or play a sound. You can unblock notifications in settings.</string>
+
+    <!-- Hint text for silent button in the interruptiveness settings [CHAR_LIMIT=NONE]-->
+    <string name="hint_text_silent">Silent notifications appear in the shade, but do not appear on the lock screen, present a banner, or play a sound.</string>
+
+    <!-- Hint text for alert button in the interruptiveness settings [CHAR_LIMIT=NONE]-->
+    <string name="hint_text_alert">Alerted notifications appear in the shade, on the lock screen, present a banner, and play a sound.</string>
+
     <!-- Notification: Control panel: Label that displays when the app's notifications cannot be blocked. -->
     <string name="notification_unblockable_desc">These notifications can\'t be turned off</string>
 
@@ -2322,9 +2331,6 @@
     <!-- Content description for ongoing privacy chip. Use with multiple apps [CHAR LIMIT=NONE]-->
     <string name="ongoing_privacy_chip_content_multiple_apps">Applications are using your <xliff:g id="types_list" example="camera, location">%s</xliff:g>.</string>
 
-    <!-- Ongoing Privacy "Chip" in use text [CHAR LIMIT=10]-->
-    <string name="ongoing_privacy_chip_in_use">In use:</string>
-
     <!-- Content description for ongoing privacy chip. Use with multiple apps using same app op[CHAR LIMIT=NONE]-->
     <plurals name="ongoing_privacy_chip_content_multiple_apps_single_op">
         <item quantity="one"><xliff:g id="num_apps" example="1">%1$d</xliff:g> application is using your <xliff:g id="type" example="camera">%2$s</xliff:g>.</item>
@@ -2359,12 +2365,6 @@
     <!-- Text for microphone app op [CHAR LIMIT=20]-->
     <string name="privacy_type_microphone">microphone</string>
 
-    <!-- Text for indicating extra apps using app ops [CHAR LIMIT=NONE] -->
-    <plurals name="ongoing_privacy_dialog_overflow_text">
-        <item quantity="one"><xliff:g id="num_apps" example="1">%d</xliff:g> other app</item>
-        <item quantity="other"><xliff:g id="num_apps" example="3">%d</xliff:g> other apps</item>
-    </plurals>
-
     <!-- Text for the quick setting tile for sensor privacy [CHAR LIMIT=30] -->
     <string name="sensor_privacy_mode">Sensors off</string>
 
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 4adece9..0f5df45 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -444,6 +444,19 @@
         <item name="android:alpha">0.54</item>
     </style>
 
+    <style name="TextAppearance.NotificationInfo.ButtonLabel">
+        <item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
+        <item name="android:textSize">14sp</item>
+        <item name="android:alpha">0.54</item>
+        <item name="android:paddingTop">4dp</item>
+        <item name="android:paddingBottom">16dp</item>
+    </style>
+
+    <style name="TextAppearance.NotificationInfo.HintText">
+        <item name="android:textSize">12sp</item>
+        <item name="android:alpha">0.54</item>
+    </style>
+
     <style name="TextAppearance.NotificationInfo.Secondary.Warning">
         <item name="android:textColor">?android:attr/colorError</item>
     </style>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 39a5842..62b0542 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -24,6 +24,8 @@
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import android.animation.ArgbEvaluator;
+import android.animation.LayoutTransition;
+import android.animation.ObjectAnimator;
 import android.annotation.IntDef;
 import android.app.ActivityManager;
 import android.content.Context;
@@ -141,6 +143,8 @@
         addOnAttachStateChangeListener(
                 new DisableStateTracker(DISABLE_NONE, DISABLE2_SYSTEM_ICONS));
 
+        setupLayoutTransition();
+
         mSlotBattery = context.getString(
                 com.android.internal.R.string.status_bar_battery);
         mBatteryIconView = new ImageView(context);
@@ -178,6 +182,21 @@
         setLayerType(LAYER_TYPE_SOFTWARE, null);
     }
 
+    private void setupLayoutTransition() {
+        LayoutTransition transition = new LayoutTransition();
+        transition.setDuration(200);
+
+        ObjectAnimator appearAnimator = ObjectAnimator.ofFloat(null, "alpha", 0f, 1f);
+        transition.setAnimator(LayoutTransition.APPEARING, appearAnimator);
+        transition.setInterpolator(LayoutTransition.APPEARING, Interpolators.ALPHA_IN);
+
+        ObjectAnimator disappearAnimator = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f);
+        transition.setInterpolator(LayoutTransition.DISAPPEARING, Interpolators.ALPHA_OUT);
+        transition.setAnimator(LayoutTransition.DISAPPEARING, disappearAnimator);
+
+        setLayoutTransition(transition);
+    }
+
     public void setForceShowPercent(boolean show) {
         setPercentShowMode(show ? MODE_ON : MODE_DEFAULT);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
index 84a3446..cf17018 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
@@ -24,6 +24,7 @@
 import android.os.UserHandle
 import android.provider.Settings
 import android.util.IconDrawableFactory
+import android.util.StatsLog
 import android.view.Gravity
 import android.view.LayoutInflater
 import android.view.View
@@ -55,7 +56,13 @@
 
     fun createDialog(): Dialog {
         val builder = AlertDialog.Builder(context).apply {
-            setPositiveButton(R.string.ongoing_privacy_dialog_ok, null)
+            setPositiveButton(R.string.ongoing_privacy_dialog_ok,
+                    object : DialogInterface.OnClickListener {
+                override fun onClick(dialog: DialogInterface?, which: Int) {
+                    StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED,
+                            StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__DIALOG_DISMISS)
+                }
+            })
             setNeutralButton(R.string.ongoing_privacy_dialog_open_settings,
                     object : DialogInterface.OnClickListener {
                         val intent = Intent(Settings.ACTION_PRIVACY_SETTINGS).putExtra(
@@ -63,6 +70,8 @@
 
                         @Suppress("DEPRECATION")
                         override fun onClick(dialog: DialogInterface?, which: Int) {
+                            StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED, StatsLog
+                                    .PRIVACY_INDICATORS_INTERACTED__TYPE__DIALOG_PRIVACY_SETTINGS)
                             Dependency.get(ActivityStarter::class.java)
                                     .postStartActivityDismissingKeyguard(intent, 0)
                         }
@@ -136,6 +145,9 @@
                         .putExtra(Intent.EXTRA_PACKAGE_NAME, app.packageName)
                         .putExtra(Intent.EXTRA_USER, UserHandle.getUserHandleForUid(app.uid))
                 override fun onClick(v: View?) {
+                    StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED,
+                            StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__DIALOG_LINE_ITEM,
+                            app.packageName)
                     Dependency.get(ActivityStarter::class.java)
                             .postStartActivityDismissingKeyguard(intent, 0)
                     dismissDialog?.invoke()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index b502a9524..4862b9e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -41,6 +41,7 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Pair;
+import android.util.StatsLog;
 import android.view.DisplayCutout;
 import android.view.View;
 import android.view.WindowInsets;
@@ -156,6 +157,7 @@
         }
     };
     private boolean mHasTopCutout = false;
+    private boolean mPrivacyChipLogged = false;
 
     /**
      * Runnable for automatically fading out the long press tooltip (as if it were animating away).
@@ -210,6 +212,7 @@
         mPrivacyChip.setOnClickListener(this);
         mCarrierGroup = findViewById(R.id.carrier_group);
 
+
         updateResources();
 
         Rect tintArea = new Rect(0, 0, 0, 0);
@@ -265,6 +268,13 @@
     private void setChipVisibility(boolean chipVisible) {
         if (chipVisible) {
             mPrivacyChip.setVisibility(View.VISIBLE);
+            // Makes sure that the chip is logged as viewed at most once each time QS is opened
+            // mListening makes sure that the callback didn't return after the user closed QS
+            if (!mPrivacyChipLogged && mListening) {
+                mPrivacyChipLogged = true;
+                StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED,
+                        StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__CHIP_VIEWED);
+            }
         } else {
             mPrivacyChip.setVisibility(View.GONE);
         }
@@ -534,6 +544,7 @@
             mAlarmController.removeCallback(this);
             mPrivacyItemController.removeCallback(mPICCallback);
             mContext.unregisterReceiver(mRingerReceiver);
+            mPrivacyChipLogged = false;
         }
     }
 
@@ -547,6 +558,8 @@
             PrivacyDialogBuilder builder = mPrivacyChip.getBuilder();
             if (builder.getAppsAndTypes().size() == 0) return;
             Handler mUiHandler = new Handler(Looper.getMainLooper());
+            StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED,
+                    StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__CHIP_CLICKED);
             mUiHandler.post(() -> {
                 Dialog mDialog = new OngoingPrivacyDialog(mContext, builder).createDialog();
                 SystemUIDialog.setShowForAllUsers(mDialog, false);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 0b1e9c3..bdebf79 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -88,7 +88,9 @@
 
     @Override
     public BooleanState newTileState() {
-        return new BooleanState();
+        BooleanState state = new BooleanState();
+        state.handlesLongClick = false;
+        return state;
     }
 
     @Override
@@ -116,20 +118,25 @@
     }
 
     @Override
+    protected void handleLongClick() {
+        handleClick();
+    }
+
+    @Override
     protected void handleClick() {
         if (getState().state == Tile.STATE_UNAVAILABLE) {
             return;
         }
-        if (mKeyguard.isSecure() && !mKeyguard.canSkipBouncer()) {
-            mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
-                showDetail(true);
-            });
-            return;
-        }
 
         CastDevice activeProjection = getActiveDeviceMediaProjection();
         if (activeProjection == null) {
-            showDetail(true);
+            if (mKeyguard.isSecure() && !mKeyguard.canSkipBouncer()) {
+                mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
+                    showDetail(true);
+                });
+            } else {
+                showDetail(true);
+            }
         } else {
             mController.stopCasting(activeProjection);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index 3723731..2e4325b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.notification.row;
 
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_MIN;
 import static android.app.NotificationManager.IMPORTANCE_NONE;
@@ -38,6 +37,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.metrics.LogMaker;
 import android.os.Handler;
@@ -81,10 +81,11 @@
     }
 
     public static final int ACTION_NONE = 0;
-    public static final int ACTION_UNDO = 1;
-    public static final int ACTION_TOGGLE_SILENT = 2;
-    public static final int ACTION_BLOCK = 3;
-    public static final int ACTION_DELIVER_SILENTLY = 4;
+    static final int ACTION_UNDO = 1;
+    static final int ACTION_TOGGLE_SILENT = 2;
+    static final int ACTION_BLOCK = 3;
+    static final int ACTION_DELIVER_SILENTLY = 4;
+    private static final int ACTION_ALERT = 5;
 
     private INotificationManager mINotificationManager;
     private PackageManager mPm;
@@ -98,6 +99,7 @@
     private NotificationChannel mSingleNotificationChannel;
     private int mStartingChannelImportance;
     private boolean mWasShownHighPriority;
+    private int mNotificationBlockState = ACTION_NONE;
     /**
      * The last importance level chosen by the user.  Null if the user has not chosen an importance
      * level; non-null once the user takes an action which indicates an explicit preference.
@@ -117,7 +119,6 @@
 
     /** Whether this view is being shown as part of the blocking helper. */
     private boolean mIsForBlockingHelper;
-    private boolean mNegativeUserSentiment;
 
     /**
      * String that describes how the user exit or quit out of this view, also used as a counter tag.
@@ -126,8 +127,8 @@
 
     private OnClickListener mOnKeepShowing = v -> {
         mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
-        closeControls(v);
         if (mIsForBlockingHelper) {
+            closeControls(v);
             mMetricsLogger.write(getLogMaker().setCategory(
                     MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
                     .setType(MetricsEvent.TYPE_ACTION)
@@ -135,23 +136,36 @@
         }
     };
 
-    private OnClickListener mOnToggleSilent = v -> {
-        handleSaveImportance(ACTION_TOGGLE_SILENT, MetricsEvent.BLOCKING_HELPER_CLICK_ALERT_ME);
+    private OnClickListener mOnAlert = v -> {
+        mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
+        mChosenImportance = IMPORTANCE_DEFAULT;
+        updateButtonsAndHelpText(ACTION_ALERT);
+    };
+
+    private OnClickListener mOnDismissSettings = v -> {
+        closeControls(v);
     };
 
     private OnClickListener mOnDeliverSilently = v -> {
         handleSaveImportance(
                 ACTION_DELIVER_SILENTLY, MetricsEvent.BLOCKING_HELPER_CLICK_STAY_SILENT);
+        if (!mIsForBlockingHelper) {
+            updateButtonsAndHelpText(ACTION_DELIVER_SILENTLY);
+        }
     };
 
     private OnClickListener mOnStopOrMinimizeNotifications = v -> {
         handleSaveImportance(ACTION_BLOCK, MetricsEvent.BLOCKING_HELPER_CLICK_BLOCKED);
+        if (!mIsForBlockingHelper) {
+            updateButtonsAndHelpText(ACTION_BLOCK);
+        }
     };
 
     private void handleSaveImportance(int action, int metricsSubtype) {
         Runnable saveImportance = () -> {
-            swapContent(action, true /* animate */);
+            saveImportanceAndExitReason(action);
             if (mIsForBlockingHelper) {
+                swapContent(action, true /* animate */);
                 mMetricsLogger.write(getLogMaker()
                         .setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
                         .setType(MetricsEvent.TYPE_ACTION)
@@ -177,6 +191,7 @@
         } else {
             mMetricsLogger.write(importanceChangeLogMaker().setType(MetricsEvent.TYPE_DISMISS));
         }
+        saveImportanceAndExitReason(ACTION_UNDO);
         swapContent(ACTION_UNDO, true /* animate */);
     };
 
@@ -252,7 +267,6 @@
         mSingleNotificationChannel = notificationChannel;
         mStartingChannelImportance = mSingleNotificationChannel.getImportance();
         mWasShownHighPriority = wasShownHighPriority;
-        mNegativeUserSentiment = isUserSentimentNegative;
         mIsNonblockable = isNonblockable;
         mIsForeground =
                 (mSbn.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
@@ -329,14 +343,6 @@
         bindGroup();
         if (mIsNonblockable) {
             blockPrompt.setText(R.string.notification_unblockable_desc);
-        } else {
-            if (mNegativeUserSentiment) {
-                blockPrompt.setText(R.string.inline_blocking_helper);
-            }  else if (mIsSingleDefaultChannel || mNumUniqueChannelsInRow > 1) {
-                blockPrompt.setText(R.string.inline_keep_showing_app);
-            } else {
-                blockPrompt.setText(R.string.inline_keep_showing);
-            }
         }
     }
 
@@ -403,6 +409,7 @@
         }
     }
 
+
     @VisibleForTesting
     void logBlockingHelperCounter(String counterTag) {
         if (mIsForBlockingHelper) {
@@ -454,21 +461,20 @@
         if (showInterruptivenessSettings) {
             findViewById(R.id.block_or_minimize).setVisibility(GONE);
             findViewById(R.id.interruptiveness_settings).setVisibility(VISIBLE);
-            View block = findViewById(R.id.int_block);
-            TextView silent = findViewById(R.id.int_silent);
-            TextView alert = findViewById(R.id.int_alert);
-
+            View done = findViewById(R.id.done_button);
+            done.setOnClickListener(mOnDismissSettings);
+            View block = findViewById(R.id.int_block_wrapper);
+            View silent = findViewById(R.id.int_silent_wrapper);
+            View alert = findViewById(R.id.int_alert_wrapper);
             block.setOnClickListener(mOnStopOrMinimizeNotifications);
-            if (mWasShownHighPriority) {
-                silent.setOnClickListener(mOnToggleSilent);
-                silent.setText(R.string.inline_silent_button_silent);
-                alert.setOnClickListener(mOnKeepShowing);
-                alert.setText(R.string.inline_silent_button_keep_alerting);
+            silent.setOnClickListener(mOnDeliverSilently);
+            alert.setOnClickListener(mOnAlert);
+            if (mNotificationBlockState != ACTION_NONE) {
+                updateButtonsAndHelpText(mNotificationBlockState);
+            } else if (mWasShownHighPriority) {
+                updateButtonsAndHelpText(ACTION_ALERT);
             } else {
-                silent.setOnClickListener(mOnKeepShowing);
-                silent.setText(R.string.inline_silent_button_stay_silent);
-                alert.setOnClickListener(mOnToggleSilent);
-                alert.setText(R.string.inline_silent_button_alert);
+                updateButtonsAndHelpText(ACTION_DELIVER_SILENTLY);
             }
         } else {
             findViewById(R.id.block_or_minimize).setVisibility(VISIBLE);
@@ -515,6 +521,73 @@
         }
     }
 
+    private void updateButtonsAndHelpText(int blockState) {
+        mNotificationBlockState = blockState;
+        ImageView block = findViewById(R.id.int_block);
+        ImageView silent = findViewById(R.id.int_silent);
+        ImageView alert = findViewById(R.id.int_alert);
+        TextView hintText = findViewById(R.id.hint_text);
+        switch (blockState) {
+            case ACTION_BLOCK:
+                block.setBackgroundResource(R.drawable.circle_blue_40dp);
+                block.setColorFilter(Color.WHITE);
+                silent.setBackgroundResource(R.drawable.circle_white_40dp);
+                silent.setColorFilter(getResources().getColor(R.color.GM2_grey_400));
+                alert.setBackgroundResource(R.drawable.circle_white_40dp);
+                alert.setColorFilter(getResources().getColor(R.color.GM2_grey_400));
+                hintText.setText(R.string.hint_text_block);
+                break;
+            case ACTION_DELIVER_SILENTLY:
+                silent.setBackgroundResource(R.drawable.circle_blue_40dp);
+                silent.setColorFilter(Color.WHITE);
+                block.setBackgroundResource(R.drawable.circle_white_40dp);
+                block.setColorFilter(getResources().getColor(R.color.GM2_grey_400));
+                alert.setBackgroundResource(R.drawable.circle_white_40dp);
+                alert.setColorFilter(getResources().getColor(R.color.GM2_grey_400));
+                hintText.setText(R.string.hint_text_silent);
+                break;
+            case ACTION_ALERT:
+                alert.setBackgroundResource(R.drawable.circle_blue_40dp);
+                alert.setColorFilter(Color.WHITE);
+                block.setBackgroundResource(R.drawable.circle_white_40dp);
+                block.setColorFilter(getResources().getColor(R.color.GM2_grey_400));
+                silent.setBackgroundResource(R.drawable.circle_white_40dp);
+                silent.setColorFilter(getResources().getColor(R.color.GM2_grey_400));
+                hintText.setText(R.string.hint_text_alert);
+                break;
+        }
+    }
+
+    private void saveImportanceAndExitReason(@NotificationInfoAction int action) {
+        switch (action) {
+            case ACTION_UNDO:
+                mChosenImportance = mStartingChannelImportance;
+                break;
+            case ACTION_DELIVER_SILENTLY:
+                mExitReason = NotificationCounters.BLOCKING_HELPER_DELIVER_SILENTLY;
+                mChosenImportance = IMPORTANCE_LOW;
+                break;
+            case ACTION_TOGGLE_SILENT:
+                mExitReason = NotificationCounters.BLOCKING_HELPER_TOGGLE_SILENT;
+                if (mWasShownHighPriority) {
+                    mChosenImportance = IMPORTANCE_LOW;
+                } else {
+                    mChosenImportance = IMPORTANCE_DEFAULT;
+                }
+                break;
+            case ACTION_BLOCK:
+                mExitReason = NotificationCounters.BLOCKING_HELPER_STOP_NOTIFICATIONS;
+                if (mIsForeground) {
+                    mChosenImportance = IMPORTANCE_MIN;
+                } else {
+                    mChosenImportance = IMPORTANCE_NONE;
+                }
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+    }
+
     private void swapContent(@NotificationInfoAction int action, boolean animate) {
         if (mExpandAnimation != null) {
             mExpandAnimation.cancel();
@@ -525,32 +598,25 @@
         TextView confirmationText = findViewById(R.id.confirmation_text);
         View header = findViewById(R.id.header);
 
+        saveImportanceAndExitReason(action);
+
         switch (action) {
             case ACTION_UNDO:
-                mChosenImportance = mStartingChannelImportance;
                 break;
             case ACTION_DELIVER_SILENTLY:
-                mExitReason = NotificationCounters.BLOCKING_HELPER_DELIVER_SILENTLY;
-                mChosenImportance = IMPORTANCE_LOW;
                 confirmationText.setText(R.string.notification_channel_silenced);
                 break;
             case ACTION_TOGGLE_SILENT:
-                mExitReason = NotificationCounters.BLOCKING_HELPER_TOGGLE_SILENT;
                 if (mWasShownHighPriority) {
-                    mChosenImportance = IMPORTANCE_LOW;
                     confirmationText.setText(R.string.notification_channel_silenced);
                 } else {
-                    mChosenImportance = IMPORTANCE_DEFAULT;
                     confirmationText.setText(R.string.notification_channel_unsilenced);
                 }
                 break;
             case ACTION_BLOCK:
-                mExitReason = NotificationCounters.BLOCKING_HELPER_STOP_NOTIFICATIONS;
                 if (mIsForeground) {
-                    mChosenImportance = IMPORTANCE_MIN;
                     confirmationText.setText(R.string.notification_channel_minimized);
                 } else {
-                    mChosenImportance = IMPORTANCE_NONE;
                     confirmationText.setText(R.string.notification_channel_disabled);
                 }
                 break;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index 19a73f6..fb4fd31 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -341,79 +341,62 @@
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
                 IMPORTANCE_DEFAULT, true);
-        final TextView silent = mNotificationInfo.findViewById(R.id.int_silent);
+        final TextView silent = mNotificationInfo.findViewById(R.id.int_silent_label);
         assertEquals(VISIBLE, silent.getVisibility());
         assertEquals(
                 mContext.getString(R.string.inline_silent_button_silent), silent.getText());
     }
 
     @Test
-    public void testBindNotification_SilenceButton_CurrentlySilent() throws Exception {
+    public void testBindNotification_verifyButtonTexts() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
                 IMPORTANCE_LOW, false);
-        final TextView silent = mNotificationInfo.findViewById(R.id.int_silent);
+        final TextView block = mNotificationInfo.findViewById(R.id.int_block_label);
+        final TextView alert = mNotificationInfo.findViewById(R.id.int_alert_label);
+        final TextView silent = mNotificationInfo.findViewById(R.id.int_silent_label);
         assertEquals(VISIBLE, silent.getVisibility());
+        assertEquals(VISIBLE, block.getVisibility());
+        assertEquals(VISIBLE, alert.getVisibility());
         assertEquals(
-                mContext.getString(R.string.inline_silent_button_stay_silent),
+                mContext.getString(R.string.inline_silent_button_silent),
                 silent.getText());
+        assertEquals(
+                mContext.getString(R.string.inline_silent_button_alert), alert.getText());
+        assertEquals(
+                mContext.getString(R.string.inline_block_button), block.getText());
     }
 
     @Test
-    public void testBindNotification_AlertButton_CurrentlySilent() throws Exception {
+    public void testBindNotification_verifyHintTextForSilent() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
                 IMPORTANCE_LOW, false);
-        final TextView alert = mNotificationInfo.findViewById(R.id.int_alert);
-        assertEquals(VISIBLE, alert.getVisibility());
-        assertEquals(
-                mContext.getString(R.string.inline_silent_button_alert), alert.getText());
+        TextView hintText = mNotificationInfo.findViewById(R.id.hint_text);
+        assertEquals(mContext.getString(R.string.hint_text_silent), hintText.getText());
     }
 
     @Test
-    public void testBindNotification_UnSilenceButton_currentlyAlerting() throws Exception {
-        mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
-                IMPORTANCE_DEFAULT, true);
-        final TextView alert = mNotificationInfo.findViewById(R.id.int_alert);
-        assertEquals(VISIBLE, alert.getVisibility());
-        assertEquals(
-                mContext.getString(R.string.inline_silent_button_keep_alerting), alert.getText());
-    }
-
-    @Test
-    public void testBindNotification_ChannelImportanceUnspecified_NotifAlerting() throws Exception {
-        mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
-                IMPORTANCE_DEFAULT, true);
-        final TextView silent = mNotificationInfo.findViewById(R.id.int_silent);
-        final TextView alert = mNotificationInfo.findViewById(R.id.int_alert);
-        assertEquals(VISIBLE, silent.getVisibility());
-        assertEquals(VISIBLE, alert.getVisibility());
-        assertEquals(
-                mContext.getString(R.string.inline_silent_button_silent), silent.getText());
-        assertEquals(
-                mContext.getString(R.string.inline_silent_button_keep_alerting), alert.getText());
-    }
-
-    @Test
-    public void testBindNotification_ChannelImportanceUnspecified_NotifSilent() throws Exception {
-        mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
+    public void testBindNotification_verifyHintTextForBlock() throws Exception {
+        mNotificationChannel.setImportance(IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
                 IMPORTANCE_LOW, false);
-        final TextView silent = mNotificationInfo.findViewById(R.id.int_silent);
-        final TextView alert = mNotificationInfo.findViewById(R.id.int_alert);
-        assertEquals(VISIBLE, silent.getVisibility());
-        assertEquals(VISIBLE, alert.getVisibility());
-        assertEquals(
-                mContext.getString(R.string.inline_silent_button_stay_silent), silent.getText());
-        assertEquals(
-                mContext.getString(R.string.inline_silent_button_alert), alert.getText());
+        View blockWrapper = mNotificationInfo.findViewById(R.id.int_block_wrapper);
+        blockWrapper.performClick();
+        TextView hintText = mNotificationInfo.findViewById(R.id.hint_text);
+        assertEquals(mContext.getString(R.string.hint_text_block), hintText.getText());
+    }
+
+    @Test
+    public void testBindNotification_verifyHintTextForAlert() throws Exception {
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+                IMPORTANCE_DEFAULT, true);
+        TextView hintText = mNotificationInfo.findViewById(R.id.hint_text);
+        assertEquals(mContext.getString(R.string.hint_text_alert), hintText.getText());
     }
 
     @Test
@@ -560,16 +543,6 @@
     }
 
     @Test
-    public void testbindNotification_BlockingHelper() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false, false,
-                true, true, IMPORTANCE_DEFAULT, true);
-        final TextView view = mNotificationInfo.findViewById(R.id.block_prompt);
-        assertEquals(View.VISIBLE, view.getVisibility());
-        assertEquals(mContext.getString(R.string.inline_blocking_helper), view.getText());
-    }
-
-    @Test
     public void testbindNotification_UnblockableTextVisibleWhenAppUnblockable() throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
@@ -687,8 +660,8 @@
                 true, false /* isNonblockable */, IMPORTANCE_DEFAULT, false
         );
 
-        mNotificationInfo.findViewById(R.id.int_block).performClick();
-        waitForUndoButton();
+        mNotificationInfo.findViewById(R.id.int_block_wrapper).performClick();
+        mNotificationInfo.findViewById(R.id.done_button).performClick();
         mNotificationInfo.handleCloseControls(true, false);
 
         mTestableLooper.processAllMessages();
@@ -709,8 +682,8 @@
                 true, false /* isNonblockable */, IMPORTANCE_DEFAULT, false
         );
 
-        mNotificationInfo.findViewById(R.id.int_block).performClick();
-        waitForUndoButton();
+        mNotificationInfo.findViewById(R.id.int_block_wrapper).performClick();
+        mNotificationInfo.findViewById(R.id.done_button).performClick();
         mNotificationInfo.handleCloseControls(true, false);
 
         mTestableLooper.processAllMessages();
@@ -842,7 +815,7 @@
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
-                IMPORTANCE_DEFAULT, false);
+                true, false, IMPORTANCE_DEFAULT, false);
         mNotificationInfo.findViewById(R.id.block).performClick();
         waitForUndoButton();
 
@@ -861,8 +834,8 @@
                 true, false,
                 IMPORTANCE_DEFAULT, false);
 
-        mNotificationInfo.findViewById(R.id.int_block).performClick();
-        waitForUndoButton();
+        mNotificationInfo.findViewById(R.id.int_block_wrapper).performClick();
+        mNotificationInfo.findViewById(R.id.done_button).performClick();
         mNotificationInfo.handleCloseControls(true, false);
 
         ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
@@ -929,7 +902,7 @@
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
-                IMPORTANCE_DEFAULT, false);
+                true, false, IMPORTANCE_DEFAULT, false);
         mNotificationInfo.findViewById(R.id.minimize).performClick();
         waitForUndoButton();
 
@@ -944,7 +917,7 @@
         mSbn.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE;
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
-                IMPORTANCE_DEFAULT, false);
+                true, false, IMPORTANCE_DEFAULT, false);
 
         mNotificationInfo.findViewById(R.id.minimize).performClick();
         waitForUndoButton();
@@ -1014,63 +987,14 @@
     }
 
     @Test
-    public void testBlockUndoDoesNotBlockNotificationChannel_notBlockingHelper() throws Exception {
-        mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
-                null, null, null,
-                true, false,
-                IMPORTANCE_DEFAULT, false);
-
-        mNotificationInfo.findViewById(R.id.int_block).performClick();
-        waitForUndoButton();
-        mNotificationInfo.findViewById(R.id.undo).performClick();
-        waitForStopButton();
-        // mNotificationInfo.handleCloseControls doesn't get called by this interaction.
-
-        ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
-        verify(mMetricsLogger, times(2)).write(logMakerCaptor.capture());
-        assertEquals(MetricsEvent.ACTION_SAVE_IMPORTANCE,
-                logMakerCaptor.getValue().getCategory());
-        assertEquals(MetricsEvent.TYPE_DISMISS,
-                logMakerCaptor.getValue().getType());
-        assertEquals(IMPORTANCE_NONE - IMPORTANCE_LOW,
-                logMakerCaptor.getValue().getSubtype());
-
-
-        mTestableLooper.processAllMessages();
-        verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
-                anyString(), eq(TEST_UID), any());
-    }
-
-    @Test
-    public void testMinUndoDoesNotMinNotificationChannel_notBlockingHelper() throws Exception {
-        mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
-                null, null, null, true,
-                true, IMPORTANCE_DEFAULT, false);
-
-        mNotificationInfo.findViewById(R.id.minimize).performClick();
-        waitForUndoButton();
-        mNotificationInfo.findViewById(R.id.undo).performClick();
-        waitForStopButton();
-        // mNotificationInfo.handleCloseControls doesn't get called by this code path
-
-        mTestableLooper.processAllMessages();
-        verify(mMockINotificationManager, times(0)).updateNotificationChannelForPackage(
-                anyString(), eq(TEST_UID), any());
-    }
-
-    @Test
     public void testSilenceCallsUpdateNotificationChannel() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
                 IMPORTANCE_DEFAULT, true);
 
-        mNotificationInfo.findViewById(R.id.int_silent).performClick();
-        waitForUndoButton();
+        mNotificationInfo.findViewById(R.id.int_silent_wrapper).performClick();
+        mNotificationInfo.findViewById(R.id.done_button).performClick();
         mNotificationInfo.handleCloseControls(true, false);
 
         mTestableLooper.processAllMessages();
@@ -1090,8 +1014,8 @@
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
                 IMPORTANCE_DEFAULT, false);
 
-        mNotificationInfo.findViewById(R.id.int_alert).performClick();
-        waitForUndoButton();
+        mNotificationInfo.findViewById(R.id.int_alert_wrapper).performClick();
+        mNotificationInfo.findViewById(R.id.done_button).performClick();
         mNotificationInfo.handleCloseControls(true, false);
 
         mTestableLooper.processAllMessages();
@@ -1112,8 +1036,8 @@
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
                 IMPORTANCE_DEFAULT, true);
 
-        mNotificationInfo.findViewById(R.id.int_silent).performClick();
-        waitForUndoButton();
+        mNotificationInfo.findViewById(R.id.int_silent_wrapper).performClick();
+        mNotificationInfo.findViewById(R.id.done_button).performClick();
         mNotificationInfo.handleCloseControls(true, false);
 
         mTestableLooper.processAllMessages();
@@ -1134,8 +1058,8 @@
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
                 IMPORTANCE_LOW, false);
 
-        mNotificationInfo.findViewById(R.id.int_alert).performClick();
-        waitForUndoButton();
+        mNotificationInfo.findViewById(R.id.int_alert_wrapper).performClick();
+        mNotificationInfo.findViewById(R.id.done_button).performClick();
         mNotificationInfo.handleCloseControls(true, false);
 
         mTestableLooper.processAllMessages();
@@ -1153,7 +1077,7 @@
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
-                IMPORTANCE_DEFAULT, false);
+                true, false, IMPORTANCE_DEFAULT, false);
 
         mNotificationInfo.findViewById(R.id.minimize).performClick();
         waitForUndoButton();
@@ -1171,8 +1095,8 @@
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
                 IMPORTANCE_DEFAULT, false);
 
-        mNotificationInfo.findViewById(R.id.int_block).performClick();
-        waitForUndoButton();
+        mNotificationInfo.findViewById(R.id.int_block_wrapper).performClick();
+        mNotificationInfo.findViewById(R.id.done_button).performClick();
         mNotificationInfo.handleCloseControls(false, false);
 
         mTestableLooper.processAllMessages();
@@ -1188,9 +1112,8 @@
                 (Runnable saveImportance, StatusBarNotification sbn) -> {
                 }, null, null, true, true, IMPORTANCE_DEFAULT, false);
 
-        mNotificationInfo.findViewById(R.id.int_block).performClick();
+        mNotificationInfo.findViewById(R.id.int_block_wrapper).performClick();
         mTestableLooper.processAllMessages();
-        ensureNoUndoButton();
         mNotificationInfo.handleCloseControls(true, false);
 
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -1207,12 +1130,12 @@
                 }, null, null, true, false, IMPORTANCE_DEFAULT, false
         );
 
-        mNotificationInfo.findViewById(R.id.int_block).performClick();
+        mNotificationInfo.findViewById(R.id.int_block_wrapper).performClick();
+        mNotificationInfo.findViewById(R.id.done_button).performClick();
         mTestableLooper.processAllMessages();
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
                 eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel));
 
-        waitForUndoButton();
         mNotificationInfo.handleCloseControls(true, false);
 
         mTestableLooper.processAllMessages();
@@ -1231,78 +1154,11 @@
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
-                IMPORTANCE_DEFAULT, false);
+                true, false, IMPORTANCE_DEFAULT, false);
 
         mNotificationInfo.findViewById(R.id.minimize).performClick();
         waitForUndoButton();
         TextView confirmationText = mNotificationInfo.findViewById(R.id.confirmation_text);
         assertTrue(confirmationText.getText().toString().contains("minimized"));
     }
-
-    @Test
-    public void testUndoText_block() throws Exception {
-        mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
-                IMPORTANCE_DEFAULT, false);
-
-        mNotificationInfo.findViewById(R.id.int_block).performClick();
-        waitForUndoButton();
-        TextView confirmationText = mNotificationInfo.findViewById(R.id.confirmation_text);
-        assertTrue(confirmationText.getText().toString().contains("won't see"));
-    }
-
-    @Test
-    public void testUndoText_silence() throws Exception {
-        mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
-                IMPORTANCE_DEFAULT, true);
-
-        mNotificationInfo.findViewById(R.id.int_silent).performClick();
-        waitForUndoButton();
-        TextView confirmationText = mNotificationInfo.findViewById(R.id.confirmation_text);
-        assertEquals(mContext.getString(R.string.notification_channel_silenced),
-                confirmationText.getText());
-    }
-
-    @Test
-    public void testUndoText_unsilence() throws Exception {
-        mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
-                IMPORTANCE_DEFAULT, false);
-
-        mNotificationInfo.findViewById(R.id.int_alert).performClick();
-        waitForUndoButton();
-        TextView confirmationText = mNotificationInfo.findViewById(R.id.confirmation_text);
-        assertEquals(mContext.getString(R.string.notification_channel_unsilenced),
-                confirmationText.getText());
-    }
-
-    @Test
-    public void testNoHeaderOnConfirmation() throws Exception {
-        mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
-                IMPORTANCE_DEFAULT, false);
-
-        mNotificationInfo.findViewById(R.id.int_block).performClick();
-        waitForUndoButton();
-        assertEquals(GONE, mNotificationInfo.findViewById(R.id.header).getVisibility());
-    }
-
-    @Test
-    public void testHeaderOnUndo() throws Exception {
-        mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
-                IMPORTANCE_DEFAULT, false);
-
-        mNotificationInfo.findViewById(R.id.int_block).performClick();
-        waitForUndoButton();
-        mNotificationInfo.findViewById(R.id.undo).performClick();
-        waitForStopButton();
-        assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
-    }
 }
diff --git a/services/core/java/com/android/server/BluetoothService.java b/services/core/java/com/android/server/BluetoothService.java
index 1bf4e3a..6018f00 100644
--- a/services/core/java/com/android/server/BluetoothService.java
+++ b/services/core/java/com/android/server/BluetoothService.java
@@ -18,15 +18,26 @@
 
 import android.bluetooth.BluetoothAdapter;
 import android.content.Context;
+import android.os.SystemProperties;
 
 class BluetoothService extends SystemService {
+    private static final String HEADLESS_SYSTEM_USER = "android.car.systemuser.headless";
+
     private BluetoothManagerService mBluetoothManagerService;
+    private boolean mInitialized = false;
 
     public BluetoothService(Context context) {
         super(context);
         mBluetoothManagerService = new BluetoothManagerService(context);
     }
 
+    private void initialize() {
+        if (!mInitialized) {
+            mBluetoothManagerService.handleOnBootPhase();
+            mInitialized = true;
+        }
+    }
+
     @Override
     public void onStart() {
     }
@@ -36,13 +47,15 @@
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
             publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE,
                     mBluetoothManagerService);
-        } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
-            mBluetoothManagerService.handleOnBootPhase();
+        } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY &&
+                !SystemProperties.getBoolean(HEADLESS_SYSTEM_USER, false)) {
+            initialize();
         }
     }
 
     @Override
     public void onSwitchUser(int userHandle) {
+        initialize();
         mBluetoothManagerService.handleOnSwitchUser(userHandle);
     }
 
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index abc1066a..0387774 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -519,10 +519,10 @@
 
     public void setProcess(ProcessRecord _proc) {
         app = _proc;
-        if (pendingConnectionGroup > 0) {
-            app.connectionService = this;
-            app.connectionGroup = pendingConnectionGroup;
-            app.connectionImportance = pendingConnectionImportance;
+        if (pendingConnectionGroup > 0 && _proc != null) {
+            _proc.connectionService = this;
+            _proc.connectionGroup = pendingConnectionGroup;
+            _proc.connectionImportance = pendingConnectionImportance;
             pendingConnectionGroup = pendingConnectionImportance = 0;
         }
         if (ActivityManagerService.TRACK_PROCSTATS_ASSOCIATIONS) {
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 871f9f8..952399b 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -684,7 +684,8 @@
      * @param status the RollbackManager.STATUS_* code with the failure.
      * @param message the failure message.
      */
-    private void sendFailure(IntentSender statusReceiver, int status, String message) {
+    private void sendFailure(IntentSender statusReceiver, @RollbackManager.Status int status,
+            String message) {
         Log.e(TAG, message);
         try {
             final Intent fillIn = new Intent();
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 3d2c30e..3999edd 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -18,7 +18,7 @@
 
 import static android.Manifest.permission.BIND_DEVICE_ADMIN;
 import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
-import static android.Manifest.permission.REQUEST_SCREEN_LOCK_COMPLEXITY;
+import static android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY;
 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
 import static android.app.admin.DeviceAdminReceiver.EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE;
 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER;
@@ -4795,8 +4795,8 @@
         final int callingUserId = mInjector.userHandleGetCallingUserId();
         enforceUserUnlocked(callingUserId);
         mContext.enforceCallingOrSelfPermission(
-                REQUEST_SCREEN_LOCK_COMPLEXITY,
-                "Must have " + REQUEST_SCREEN_LOCK_COMPLEXITY + " permission.");
+                REQUEST_PASSWORD_COMPLEXITY,
+                "Must have " + REQUEST_PASSWORD_COMPLEXITY + " permission.");
 
         synchronized (getLockObject()) {
             int targetUserId = getCredentialOwner(callingUserId, /* parent= */ false);
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 039a4b7..28a815e 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -5201,7 +5201,7 @@
     public void testGetPasswordComplexity_currentUserNoPassword() {
         when(getServices().userManager.isUserUnlocked(DpmMockContext.CALLER_USER_HANDLE))
                 .thenReturn(true);
-        mServiceContext.permissions.add(permission.REQUEST_SCREEN_LOCK_COMPLEXITY);
+        mServiceContext.permissions.add(permission.REQUEST_PASSWORD_COMPLEXITY);
         when(getServices().userManager.getCredentialOwnerProfile(DpmMockContext.CALLER_USER_HANDLE))
                 .thenReturn(DpmMockContext.CALLER_USER_HANDLE);
 
@@ -5211,7 +5211,7 @@
     public void testGetPasswordComplexity_currentUserHasPassword() {
         when(getServices().userManager.isUserUnlocked(DpmMockContext.CALLER_USER_HANDLE))
                 .thenReturn(true);
-        mServiceContext.permissions.add(permission.REQUEST_SCREEN_LOCK_COMPLEXITY);
+        mServiceContext.permissions.add(permission.REQUEST_PASSWORD_COMPLEXITY);
         when(getServices().userManager.getCredentialOwnerProfile(DpmMockContext.CALLER_USER_HANDLE))
                 .thenReturn(DpmMockContext.CALLER_USER_HANDLE);
         dpms.mUserPasswordMetrics.put(
@@ -5224,7 +5224,7 @@
     public void testGetPasswordComplexity_unifiedChallengeReturnsParentUserPassword() {
         when(getServices().userManager.isUserUnlocked(DpmMockContext.CALLER_USER_HANDLE))
                 .thenReturn(true);
-        mServiceContext.permissions.add(permission.REQUEST_SCREEN_LOCK_COMPLEXITY);
+        mServiceContext.permissions.add(permission.REQUEST_PASSWORD_COMPLEXITY);
 
         UserInfo parentUser = new UserInfo();
         parentUser.id = DpmMockContext.CALLER_USER_HANDLE + 10;
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
index c072d4e..83c0af9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
@@ -59,7 +59,7 @@
     public void setUpOnDisplay(DisplayContent dc) {
         mStack = createTaskStackOnDisplay(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, dc);
         mTask = createTaskInStack(mStack, 0 /* userId */);
-        mToken = WindowTestUtils.createTestAppWindowToken(dc, false /* skipOnParentChanged */);
+        mToken = WindowTestUtils.createTestAppWindowToken(dc);
 
         mTask.addChild(mToken, 0);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
index a98a604..db04f11 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
@@ -60,7 +60,7 @@
         MockitoAnnotations.initMocks(this);
 
         mToken = createTestAppWindowToken(mDisplayContent, WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, false /* skipOnParentChanged */);
+                ACTIVITY_TYPE_STANDARD);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index 68b40b9..70c8c93 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -81,8 +81,7 @@
     public void setUp() throws Exception {
         mStack = createTaskStackOnDisplay(mDisplayContent);
         mTask = createTaskInStack(mStack, 0 /* userId */);
-        mToken = WindowTestUtils.createTestAppWindowToken(mDisplayContent,
-                false /* skipOnParentChanged */);
+        mToken = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
 
         mTask.addChild(mToken, 0);
     }
@@ -219,9 +218,6 @@
 
     @Test
     public void testSizeCompatBounds() {
-        // The real surface transaction is unnecessary.
-        mToken.setSkipPrepareSurfaces(true);
-
         final Rect fixedBounds = mToken.getRequestedOverrideConfiguration().windowConfiguration
                 .getBounds();
         fixedBounds.set(0, 0, 1200, 1600);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
index 0dec8ee..a7a785d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
@@ -56,24 +56,15 @@
 
     static TestAppWindowToken createTestAppWindowToken(DisplayContent dc) {
         synchronized (dc.mWmService.mGlobalLock) {
-            return new TestAppWindowToken(dc, true /* skipOnParentChanged */);
-        }
-    }
-
-    static TestAppWindowToken createTestAppWindowToken(DisplayContent dc,
-            boolean skipOnParentChanged) {
-        synchronized (dc.mWmService.mGlobalLock) {
-            return new TestAppWindowToken(dc, skipOnParentChanged);
+            return new TestAppWindowToken(dc);
         }
     }
 
     /** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */
     static class TestAppWindowToken extends AppWindowToken {
         boolean mOnTop = false;
-        private boolean mSkipPrepareSurfaces;
-        boolean mSkipOnParentChanged = true;
 
-        private TestAppWindowToken(DisplayContent dc, boolean skipOnParentChanged) {
+        private TestAppWindowToken(DisplayContent dc) {
             super(dc.mWmService, new IApplicationToken.Stub() {
                 @Override
                 public String getName() {
@@ -81,7 +72,6 @@
                 }
             }, new ComponentName("", ""), false, dc, true /* fillsParent */);
             mTargetSdk = Build.VERSION_CODES.CUR_DEVELOPMENT;
-            mSkipOnParentChanged = skipOnParentChanged;
             mActivityRecord = mock(ActivityRecord.class);
             mActivityRecord.app = mock(WindowProcessController.class);
         }
@@ -103,44 +93,10 @@
         }
 
         @Override
-        void onParentChanged() {
-            if (!mSkipOnParentChanged) {
-                super.onParentChanged();
-            } else {
-                updateConfigurationFromParent(this);
-            }
-        }
-
-        @Override
         boolean isOnTop() {
             return mOnTop;
         }
 
-        @Override
-        void prepareSurfaces() {
-            if (!mSkipPrepareSurfaces) {
-                super.prepareSurfaces();
-            }
-        }
-
-        void setSkipPrepareSurfaces(boolean ignore) {
-            mSkipPrepareSurfaces = ignore;
-        }
-    }
-
-    /**
-     * Used when we don't want to perform surface related operation in
-     * {@link WindowContainer#onParentChanged} or the overridden method, but the configuration
-     * still needs to propagate from parent.
-     *
-     * @see ConfigurationContainer#onParentChanged
-     */
-    static void updateConfigurationFromParent(WindowContainer container) {
-        final WindowContainer parent = container.getParent();
-        if (parent != null) {
-            container.onConfigurationChanged(parent.getConfiguration());
-            container.onMergedOverrideConfigurationChanged();
-        }
     }
 
     static TestWindowToken createTestWindowToken(int type, DisplayContent dc) {
@@ -246,10 +202,5 @@
 
             mHasSurface = hadSurface;
         }
-
-        @Override
-        void onParentChanged() {
-            updateConfigurationFromParent(this);
-        }
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 032eba1..fb698d9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -269,16 +269,10 @@
 
     WindowTestUtils.TestAppWindowToken createTestAppWindowToken(DisplayContent dc, int
             windowingMode, int activityType) {
-        return createTestAppWindowToken(dc, windowingMode, activityType,
-                false /*skipOnParentChanged */);
-    }
-
-    WindowTestUtils.TestAppWindowToken createTestAppWindowToken(DisplayContent dc, int
-            windowingMode, int activityType, boolean skipOnParentChanged) {
         final TaskStack stack = createTaskStackOnDisplay(windowingMode, activityType, dc);
         final Task task = createTaskInStack(stack, 0 /* userId */);
         final WindowTestUtils.TestAppWindowToken appWindowToken =
-                WindowTestUtils.createTestAppWindowToken(dc, skipOnParentChanged);
+                WindowTestUtils.createTestAppWindowToken(dc);
         task.addChild(appWindowToken, 0);
         return appWindowToken;
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
index 2fc6efa..7d7c398 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
@@ -43,7 +43,6 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.After;
@@ -212,7 +211,6 @@
         return createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, name);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeWithNoTarget() {
         mDisplayContent.mInputMethodTarget = null;
@@ -230,7 +228,6 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeWithAppTarget() {
         final WindowState imeAppTarget = createWindow("imeAppTarget");
@@ -250,7 +247,6 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeWithAppTargetWithChildWindows() {
         final WindowState imeAppTarget = createWindow("imeAppTarget");
@@ -277,7 +273,6 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeWithAppTargetAndAppAbove() {
         final WindowState appBelowImeTarget = createWindow("appBelowImeTarget");
@@ -301,7 +296,6 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeNonAppImeTarget() {
         final WindowState imeSystemOverlayTarget = createWindow(null, TYPE_SYSTEM_OVERLAY,
@@ -329,7 +323,6 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForStatusBarImeTarget() {
         mDisplayContent.mInputMethodTarget = mStatusBarWindow;
@@ -344,7 +337,6 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testStackLayers() {
         final WindowState anyWindow1 = createWindow("anyWindow");
@@ -432,7 +424,6 @@
         }
     }
 
-    @FlakyTest(bugId = 124088319)
     @Test
     public void testDockedDividerPosition() {
         final WindowState pinnedStackWindow = createWindowOnStack(null, WINDOWING_MODE_PINNED,
diff --git a/tests/RollbackTest/Android.bp b/tests/RollbackTest/Android.bp
index 8be721a..dfc3b6e 100644
--- a/tests/RollbackTest/Android.bp
+++ b/tests/RollbackTest/Android.bp
@@ -118,7 +118,7 @@
         ":com.android.tests.rollback.testapex.RollbackTestApexV2",
     ],
     test_config: "RollbackTest.xml",
-    sdk_version: "system_current",
+    sdk_version: "test_current",
 }
 
 java_test_host {