Merge "Controls UI - Update strings to match latest guidance" into rvc-dev
diff --git a/Android.bp b/Android.bp
index ce2729d..e7fcb34 100644
--- a/Android.bp
+++ b/Android.bp
@@ -239,6 +239,7 @@
         ":framework-sax-sources",
         ":framework-telecomm-sources",
         ":framework-telephony-common-sources",
+        ":framework-telephony-sources",
         ":framework-wifi-annotations",
         ":framework-wifi-non-updatable-sources",
         ":PacProcessor-aidl-sources",
@@ -285,7 +286,6 @@
         ":framework-permission-sources",
         ":framework-sdkextensions-sources",
         ":framework-statsd-sources",
-        ":framework-telephony-sources",
         ":framework-tethering-srcs",
         ":framework-wifi-updatable-sources",
         ":updatable-media-srcs",
@@ -300,7 +300,6 @@
         "framework-permission-stubs-module_libs_api",
         "framework-sdkextensions-stubs-module_libs_api",
         "framework-statsd-stubs-module_libs_api",
-        "framework-telephony-stubs", // TODO: Update to module_libs_api when there is one.
         "framework-tethering-stubs-module_libs_api",
         "framework-wifi-stubs-module_libs_api",
     ],
@@ -523,9 +522,8 @@
     defaults: ["framework-aidl-export-defaults"],
     installable: false, // this lib is a build-only library
     static_libs: [
+        "app-compat-annotations",
         "framework-minus-apex",
-        // TODO (b/147688669) should be removed
-        "framework-telephony",
         "framework-updatable-stubs-module_libs_api",
     ],
     sdk_version: "core_platform",
@@ -1327,8 +1325,8 @@
 java_library {
     name: "framework-telephony",
     srcs: [
-        ":framework-telephony-sources",
-        ":framework-telephony-shared-srcs",
+        //":framework-telephony-sources",
+        //":framework-telephony-shared-srcs",
     ],
     // TODO: change to framework-system-stub to build against system APIs.
     libs: [
diff --git a/api/current.txt b/api/current.txt
index 0c3281c..9407549 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -278,6 +278,7 @@
     field public static final int activityCloseExitAnimation = 16842939; // 0x10100bb
     field public static final int activityOpenEnterAnimation = 16842936; // 0x10100b8
     field public static final int activityOpenExitAnimation = 16842937; // 0x10100b9
+    field public static final int actor = 16844313; // 0x1010619
     field public static final int addPrintersActivity = 16843750; // 0x10103e6
     field public static final int addStatesFromChildren = 16842992; // 0x10100f0
     field public static final int adjustViewBounds = 16843038; // 0x101011e
@@ -11970,7 +11971,6 @@
     method @CheckResult public abstract int checkSignatures(@NonNull String, @NonNull String);
     method @CheckResult public abstract int checkSignatures(int, int);
     method public abstract void clearInstantAppCookie();
-    method public void clearMimeGroup(@NonNull String);
     method @Deprecated public abstract void clearPackagePreferredActivities(@NonNull String);
     method public abstract String[] currentToCanonicalPackageNames(@NonNull String[]);
     method public abstract void extendVerificationTimeout(int, int, long);
@@ -12006,7 +12006,7 @@
     method @NonNull public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method @Nullable public abstract android.content.Intent getLaunchIntentForPackage(@NonNull String);
     method @Nullable public abstract android.content.Intent getLeanbackLaunchIntentForPackage(@NonNull String);
-    method @Nullable public java.util.Set<java.lang.String> getMimeGroup(@NonNull String);
+    method @NonNull public java.util.Set<java.lang.String> getMimeGroup(@NonNull String);
     method @NonNull public android.content.pm.ModuleInfo getModuleInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method @Nullable public abstract String getNameForUid(int);
     method @Nullable public android.content.pm.PackageInfo getPackageArchiveInfo(@NonNull String, int);
@@ -24655,7 +24655,6 @@
     field public static final int ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR = 2; // 0x2
     field public static final int ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER = 1; // 0x1
     field public static final int ENCAPSULATION_MODE_ELEMENTARY_STREAM = 1; // 0x1
-    field public static final int ENCAPSULATION_MODE_HANDLE = 2; // 0x2
     field public static final int ENCAPSULATION_MODE_NONE = 0; // 0x0
     field public static final int ERROR = -1; // 0xffffffff
     field public static final int ERROR_BAD_VALUE = -2; // 0xfffffffe
@@ -24688,7 +24687,6 @@
     method @NonNull public android.media.AudioTrack.Builder setPerformanceMode(int);
     method @NonNull public android.media.AudioTrack.Builder setSessionId(@IntRange(from=1) int) throws java.lang.IllegalArgumentException;
     method @NonNull public android.media.AudioTrack.Builder setTransferMode(int) throws java.lang.IllegalArgumentException;
-    method @NonNull public android.media.AudioTrack.Builder setTunerConfiguration(@NonNull android.media.AudioTrack.TunerConfiguration);
   }
 
   public static final class AudioTrack.MetricsConstants {
@@ -24720,18 +24718,6 @@
     method public void onTearDown(@NonNull android.media.AudioTrack);
   }
 
-  public static class AudioTrack.TunerConfiguration {
-    method public int getContentId();
-    method public int getSyncId();
-  }
-
-  public static class AudioTrack.TunerConfiguration.Builder {
-    ctor public AudioTrack.TunerConfiguration.Builder();
-    method @NonNull public android.media.AudioTrack.TunerConfiguration build();
-    method @NonNull public android.media.AudioTrack.TunerConfiguration.Builder setContentId(@IntRange(from=1) int);
-    method @NonNull public android.media.AudioTrack.TunerConfiguration.Builder setSyncId(@IntRange(from=1) int);
-  }
-
   public class CamcorderProfile {
     method public static android.media.CamcorderProfile get(int);
     method public static android.media.CamcorderProfile get(int, int);
@@ -26884,9 +26870,11 @@
     field public static final int CONNECTION_STATE_CONNECTING = 1; // 0x1
     field public static final int CONNECTION_STATE_DISCONNECTED = 0; // 0x0
     field @NonNull public static final android.os.Parcelable.Creator<android.media.MediaRoute2Info> CREATOR;
-    field public static final String FEATURE_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO";
-    field public static final String FEATURE_LIVE_VIDEO = "android.media.intent.category.LIVE_VIDEO";
-    field public static final String FEATURE_REMOTE_PLAYBACK = "android.media.intent.category.REMOTE_PLAYBACK";
+    field public static final String FEATURE_LIVE_AUDIO = "android.media.route.feature.LIVE_AUDIO";
+    field public static final String FEATURE_LIVE_VIDEO = "android.media.route.feature.LIVE_VIDEO";
+    field public static final String FEATURE_REMOTE_AUDIO_PLAYBACK = "android.media.route.feature.REMOTE_AUDIO_PLAYBACK";
+    field public static final String FEATURE_REMOTE_PLAYBACK = "android.media.route.feature.REMOTE_PLAYBACK";
+    field public static final String FEATURE_REMOTE_VIDEO_PLAYBACK = "android.media.route.feature.REMOTE_VIDEO_PLAYBACK";
     field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
     field public static final int PLAYBACK_VOLUME_VARIABLE = 1; // 0x1
   }
@@ -47802,7 +47790,7 @@
     method @Deprecated public void sendMultimediaMessage(android.content.Context, android.net.Uri, String, android.os.Bundle, android.app.PendingIntent);
     method public void sendMultipartTextMessage(String, String, java.util.ArrayList<java.lang.String>, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
     method public void sendMultipartTextMessage(@NonNull String, @Nullable String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, long);
-    method public void sendMultipartTextMessage(@NonNull String, @Nullable String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
+    method public void sendMultipartTextMessage(@NonNull String, @Nullable String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String, @Nullable String);
     method public void sendTextMessage(String, String, String, android.app.PendingIntent, android.app.PendingIntent);
     method public void sendTextMessage(@NonNull String, @Nullable String, @NonNull String, @Nullable android.app.PendingIntent, @Nullable android.app.PendingIntent, long);
     method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.SEND_SMS}) public void sendTextMessageWithoutPersisting(String, String, String, android.app.PendingIntent, android.app.PendingIntent);
@@ -48093,6 +48081,7 @@
     method public android.telephony.SubscriptionPlan build();
     method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime);
     method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period);
+    method @NonNull public android.telephony.SubscriptionPlan.Builder resetNetworkTypes();
     method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
     method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
     method @NonNull public android.telephony.SubscriptionPlan.Builder setNetworkTypes(@NonNull int[]);
diff --git a/api/system-current.txt b/api/system-current.txt
index ee93225..5788ac9 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -341,12 +341,10 @@
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidImportance(int);
     method @RequiresPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) public void killProcessesWhenImperceptible(@NonNull int[], @NonNull String);
     method @RequiresPermission(android.Manifest.permission.KILL_UID) public void killUid(int, String);
-    method public void registerHomeVisibilityObserver(@NonNull android.app.HomeVisibilityObserver);
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
     method public void setDeviceLocales(@NonNull android.os.LocaleList);
     method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public static void setPersistentVrThread(int);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean switchUser(@NonNull android.os.UserHandle);
-    method public void unregisterHomeVisibilityObserver(@NonNull android.app.HomeVisibilityObserver);
   }
 
   public static interface ActivityManager.OnUidImportanceListener {
@@ -599,11 +597,6 @@
     field public static final String ACTION_DOWNLOAD_COMPLETED = "android.intent.action.DOWNLOAD_COMPLETED";
   }
 
-  public abstract class HomeVisibilityObserver {
-    ctor public HomeVisibilityObserver();
-    method public abstract void onHomeVisibilityChanged(boolean);
-  }
-
   public abstract class InstantAppResolverService extends android.app.Service {
     ctor public InstantAppResolverService();
     method public final void attachBaseContext(android.content.Context);
@@ -1771,6 +1764,7 @@
   }
 
   public abstract class ContentResolver {
+    method public int checkUriPermission(@NonNull android.net.Uri, int, int);
     method @NonNull public static android.net.Uri decodeFromFile(@NonNull java.io.File);
     method @NonNull public static java.io.File encodeToFile(@NonNull android.net.Uri);
     method @Nullable @RequiresPermission("android.permission.CACHE_CONTENT") public android.os.Bundle getCache(@NonNull android.net.Uri);
@@ -4341,6 +4335,26 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getClientUid();
   }
 
+  public class AudioTrack implements android.media.AudioRouting android.media.VolumeAutomation {
+    field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int ENCAPSULATION_MODE_HANDLE = 2; // 0x2
+  }
+
+  public static class AudioTrack.Builder {
+    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioTrack.Builder setTunerConfiguration(@NonNull android.media.AudioTrack.TunerConfiguration);
+  }
+
+  public static class AudioTrack.TunerConfiguration {
+    method @IntRange(from=1) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getContentId();
+    method @IntRange(from=1) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getSyncId();
+  }
+
+  public static class AudioTrack.TunerConfiguration.Builder {
+    ctor public AudioTrack.TunerConfiguration.Builder();
+    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioTrack.TunerConfiguration build();
+    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioTrack.TunerConfiguration.Builder setContentId(@IntRange(from=1) int);
+    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioTrack.TunerConfiguration.Builder setSyncId(@IntRange(from=1) int);
+  }
+
   public class HwAudioSource {
     method public boolean isPlaying();
     method public void start();
@@ -8170,7 +8184,7 @@
     field public static final String ACTION_UPDATE_CARRIER_PROVISIONING_URLS = "android.intent.action.UPDATE_CARRIER_PROVISIONING_URLS";
     field public static final String ACTION_UPDATE_CONVERSATION_ACTIONS = "android.intent.action.UPDATE_CONVERSATION_ACTIONS";
     field public static final String ACTION_UPDATE_CT_LOGS = "android.intent.action.UPDATE_CT_LOGS";
-    field @RequiresPermission("android.permission.UPDATE_CONFIG") public static final String ACTION_UPDATE_EMERGENCY_NUMBER_DB = "android.os.action.UPDATE_EMERGENCY_NUMBER_DB";
+    field public static final String ACTION_UPDATE_EMERGENCY_NUMBER_DB = "android.os.action.UPDATE_EMERGENCY_NUMBER_DB";
     field public static final String ACTION_UPDATE_INTENT_FIREWALL = "android.intent.action.UPDATE_INTENT_FIREWALL";
     field public static final String ACTION_UPDATE_LANG_ID = "android.intent.action.UPDATE_LANG_ID";
     field public static final String ACTION_UPDATE_NETWORK_WATCHLIST = "android.intent.action.UPDATE_NETWORK_WATCHLIST";
@@ -9648,6 +9662,7 @@
     method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
     method @Nullable public android.os.Bundle onGetInlineSuggestionsRendererInfo();
     method @Nullable public android.view.View onRenderSuggestion(@NonNull android.service.autofill.InlinePresentation, int, int);
+    method public final void startIntentSender(@NonNull android.content.IntentSender);
     field public static final String SERVICE_INTERFACE = "android.service.autofill.InlineSuggestionRenderService";
   }
 
@@ -10162,6 +10177,7 @@
     method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
     method public abstract void onEndSession(@NonNull String) throws java.io.IOException;
     method public abstract void onStartSession(@NonNull String, int, @NonNull android.os.ParcelFileDescriptor, @NonNull java.io.File, @NonNull java.io.File) throws java.io.IOException;
+    method public abstract void onVolumeStateChanged(@NonNull android.os.storage.StorageVolume) throws java.io.IOException;
     field public static final int FLAG_SESSION_ATTRIBUTE_INDEXABLE = 2; // 0x2
     field public static final int FLAG_SESSION_TYPE_FUSE = 1; // 0x1
     field public static final String SERVICE_INTERFACE = "android.service.storage.ExternalStorageService";
@@ -10564,9 +10580,6 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isInEmergencyCall();
     method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUserSelectedOutgoingPhoneAccount(@Nullable android.telecom.PhoneAccountHandle);
-    field public static final int CALL_SOURCE_EMERGENCY_DIALPAD = 1; // 0x1
-    field public static final int CALL_SOURCE_EMERGENCY_SHORTCUT = 2; // 0x2
-    field public static final int CALL_SOURCE_UNSPECIFIED = 0; // 0x0
     field public static final String EXTRA_CALL_BACK_INTENT = "android.telecom.extra.CALL_BACK_INTENT";
     field public static final String EXTRA_CLEAR_MISSED_CALLS_INTENT = "android.telecom.extra.CLEAR_MISSED_CALLS_INTENT";
     field public static final String EXTRA_CONNECTION_SERVICE = "android.telecom.extra.CONNECTION_SERVICE";
@@ -11414,6 +11427,7 @@
     method public boolean isDataConnectivityPossible();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean isIccLockEnabled();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isInEmergencySmsMode();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isLteCdmaEvdoGsmWcdmaEnabled();
@@ -11431,7 +11445,6 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean);
     method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
-    method public void requestModemActivityInfo(@NonNull android.os.ResultReceiver);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetAllCarrierActions();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption();
@@ -11494,29 +11507,18 @@
     field @Deprecated public static final String EXTRA_APN_TYPE = "apnType";
     field public static final String EXTRA_APN_TYPE_INT = "apnTypeInt";
     field public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable";
-    field public static final String EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE = "android.telephony.extra.DEFAULT_SUBSCRIPTION_SELECT_TYPE";
-    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL = 4; // 0x4
-    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA = 1; // 0x1
-    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE = 0; // 0x0
-    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_SMS = 3; // 0x3
-    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_VOICE = 2; // 0x2
     field public static final String EXTRA_ERROR_CODE = "errorCode";
     field public static final String EXTRA_PCO_ID = "pcoId";
     field public static final String EXTRA_PCO_VALUE = "pcoValue";
     field public static final String EXTRA_PHONE_IN_ECM_STATE = "android.telephony.extra.PHONE_IN_ECM_STATE";
     field public static final String EXTRA_PHONE_IN_EMERGENCY_CALL = "android.telephony.extra.PHONE_IN_EMERGENCY_CALL";
     field public static final String EXTRA_REDIRECTION_URL = "redirectionUrl";
-    field public static final String EXTRA_SIM_COMBINATION_NAMES = "android.telephony.extra.SIM_COMBINATION_NAMES";
-    field public static final String EXTRA_SIM_COMBINATION_WARNING_TYPE = "android.telephony.extra.SIM_COMBINATION_WARNING_TYPE";
-    field public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA = 1; // 0x1
-    field public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE = 0; // 0x0
     field public static final String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
     field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
     field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
     field public static final int INVALID_EMERGENCY_NUMBER_DB_VERSION = -1; // 0xffffffff
     field public static final int KEY_TYPE_EPDG = 1; // 0x1
     field public static final int KEY_TYPE_WLAN = 2; // 0x2
-    field public static final String MODEM_ACTIVITY_RESULT_KEY = "controller_activity";
     field public static final long NETWORK_TYPE_BITMASK_1xRTT = 64L; // 0x40L
     field public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L
     field public static final long NETWORK_TYPE_BITMASK_EDGE = 2L; // 0x2L
diff --git a/api/test-current.txt b/api/test-current.txt
index c50438a..3586fec 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3193,6 +3193,7 @@
     method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
     method @Nullable public android.os.Bundle onGetInlineSuggestionsRendererInfo();
     method @Nullable public android.view.View onRenderSuggestion(@NonNull android.service.autofill.InlinePresentation, int, int);
+    method public final void startIntentSender(@NonNull android.content.IntentSender);
     field public static final String SERVICE_INTERFACE = "android.service.autofill.InlineSuggestionRenderService";
   }
 
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index 3d02ffb..77a3eb3 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -357,30 +357,7 @@
                     protoOutput->write(FIELD_TYPE_FLOAT | fieldNum, dim.mValue.float_value);
                     break;
                 case STRING: {
-                    bool isBytesField = false;
-                    // Bytes field is logged via string format in log_msg format. So here we check
-                    // if this string field is a byte field.
-                    std::map<int, std::vector<int>>::const_iterator itr;
-                    if (depth == 0 && (itr = AtomsInfo::kBytesFieldAtoms.find(tagId)) !=
-                                              AtomsInfo::kBytesFieldAtoms.end()) {
-                        const std::vector<int>& bytesFields = itr->second;
-                        for (int bytesField : bytesFields) {
-                            if (bytesField == fieldNum) {
-                                // This is a bytes field
-                                isBytesField = true;
-                                break;
-                            }
-                        }
-                    }
-                    if (isBytesField) {
-                        if (dim.mValue.str_value.length() > 0) {
-                            protoOutput->write(FIELD_TYPE_MESSAGE | fieldNum,
-                                               (const char*)dim.mValue.str_value.c_str(),
-                                               dim.mValue.str_value.length());
-                        }
-                    } else {
-                        protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
-                    }
+                    protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
                     break;
                 }
                 case STORAGE:
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index b00f542..1b81704 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -4821,9 +4821,9 @@
 
     /**
      * Register with {@link HomeVisibilityObserver} with ActivityManager.
+     * TODO: b/144351078 expose as SystemApi
      * @hide
      */
-    @SystemApi
     public void registerHomeVisibilityObserver(@NonNull HomeVisibilityObserver observer) {
         Preconditions.checkNotNull(observer);
         try {
@@ -4838,9 +4838,9 @@
 
     /**
      * Unregister with {@link HomeVisibilityObserver} with ActivityManager.
+     * TODO: b/144351078 expose as SystemApi
      * @hide
      */
-    @SystemApi
     public void unregisterHomeVisibilityObserver(@NonNull HomeVisibilityObserver observer) {
         Preconditions.checkNotNull(observer);
         try {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 0b0a803..a1ec27b 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -3358,31 +3358,20 @@
         }
     }
 
+    @Override
     public void setMimeGroup(String mimeGroup, Set<String> mimeTypes) {
         try {
-            mPM.setMimeGroup(mContext.getPackageName(), mimeGroup,
-                    new ArrayList<String>(mimeTypes));
+            mPM.setMimeGroup(mContext.getPackageName(), mimeGroup, new ArrayList<>(mimeTypes));
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
     }
 
-    @Override
-    public void clearMimeGroup(String mimeGroup) {
-        try {
-            mPM.clearMimeGroup(mContext.getPackageName(), mimeGroup);
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        }
-    }
-
+    @NonNull
     @Override
     public Set<String> getMimeGroup(String group) {
         try {
             List<String> mimeGroup = mPM.getMimeGroup(mContext.getPackageName(), group);
-            if (mimeGroup == null) {
-                return null;
-            }
             return new ArraySet<>(mimeGroup);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
diff --git a/core/java/android/app/HomeVisibilityObserver.java b/core/java/android/app/HomeVisibilityObserver.java
index f3465f8..8422c6f 100644
--- a/core/java/android/app/HomeVisibilityObserver.java
+++ b/core/java/android/app/HomeVisibilityObserver.java
@@ -16,7 +16,6 @@
 
 package android.app;
 
-import android.annotation.SystemApi;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -28,9 +27,9 @@
  * An observer / callback to create and register by
  * {@link ActivityManager#registerHomeVisibilityObserver} so that it's triggered when
  * visibility of home page changes.
+ * TODO: b/144351078 expose as SystemApi
  * @hide
  */
-@SystemApi
 public abstract class HomeVisibilityObserver {
     private Context mContext;
     private ActivityManager mActivityManager;
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index f6ab9af4..31fc2d0 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -7583,7 +7583,10 @@
                 isOneToOne = !isGroupConversation();
             }
             boolean isConversationLayout = mConversationType != CONVERSATION_TYPE_LEGACY;
-            Icon largeIcon = isConversationLayout ? mShortcutIcon : mBuilder.mN.mLargeIcon;
+            boolean isImportantConversation = mConversationType == CONVERSATION_TYPE_IMPORTANT;
+            Icon largeIcon = isConversationLayout && mShortcutIcon != null
+                    ? mShortcutIcon
+                    : mBuilder.mN.mLargeIcon;
             TemplateBindResult bindResult = new TemplateBindResult();
             StandardTemplateParams p = mBuilder.mParams.reset()
                     .hasProgress(false)
@@ -7625,6 +7628,10 @@
                     isOneToOne);
             contentView.setCharSequence(R.id.status_bar_latest_event_content,
                     "setConversationTitle", conversationTitle);
+            if (isConversationLayout) {
+                contentView.setBoolean(R.id.status_bar_latest_event_content,
+                        "setIsImportantConversation", isImportantConversation);
+            }
             contentView.setIcon(R.id.status_bar_latest_event_content, "setLargeIcon",
                     largeIcon);
             contentView.setBundle(R.id.status_bar_latest_event_content, "setData",
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 4c4afb0..99b730e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -9388,9 +9388,9 @@
     }
 
     /**
-     * Called by device owner or profile owner of secondary users  that is affiliated with the
-     * device to disable the status bar. Disabling the status bar blocks notifications, quick
-     * settings and other screen overlays that allow escaping from a single use device.
+     * Called by device owner or profile owner of secondary users that is affiliated with the
+     * device to disable the status bar. Disabling the status bar blocks notifications and quick
+     * settings.
      * <p>
      * <strong>Note:</strong> This method has no effect for LockTask mode. The behavior of the
      * status bar in LockTask mode can be configured with
diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java
index 38498bc..5891072 100644
--- a/core/java/android/bluetooth/BluetoothHearingAid.java
+++ b/core/java/android/bluetooth/BluetoothHearingAid.java
@@ -496,17 +496,20 @@
     }
 
     /**
-     * Get the CustomerId of the device.
+     * Get the HiSyncId (unique hearing aid device identifier) of the device.
+     *
+     * <a href=https://source.android.com/devices/bluetooth/asha#hisyncid>HiSyncId documentation
+     * can be found here</a>
      *
      * @param device Bluetooth device
-     * @return the CustomerId of the device
+     * @return the HiSyncId of the device
      * @hide
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public long getHiSyncId(@Nullable BluetoothDevice device) {
         if (VDBG) {
-            log("getCustomerId(" + device + ")");
+            log("getHiSyncId(" + device + ")");
         }
         final IBluetoothHearingAid service = getService();
         try {
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index d8e8b27..65eb642 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -1585,6 +1585,10 @@
      * This method is typically used when the provider implements more dynamic
      * access controls that cannot be expressed with {@code <path-permission>}
      * style static rules.
+     * <p>
+     * Because validation of these dynamic access controls has significant
+     * system health impact, this feature is only available to providers that
+     * are built into the system.
      *
      * @param uri the {@link Uri} to perform an access check on.
      * @param uid the UID to check the permission for.
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index b134c37..7510ce7 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1357,8 +1357,28 @@
         }
     }
 
-    /** {@hide} */
+    /**
+     * Perform a detailed internal check on a {@link Uri} to determine if a UID
+     * is able to access it with specific mode flags.
+     * <p>
+     * This method is typically used when the provider implements more dynamic
+     * access controls that cannot be expressed with {@code <path-permission>}
+     * style static rules.
+     * <p>
+     * Because validation of these dynamic access controls has significant
+     * system health impact, this feature is only available to providers that
+     * are built into the system.
+     *
+     * @param uri the {@link Uri} to perform an access check on.
+     * @param uid the UID to check the permission for.
+     * @param modeFlags the access flags to use for the access check, such as
+     *            {@link Intent#FLAG_GRANT_READ_URI_PERMISSION}.
+     * @return {@link PackageManager#PERMISSION_GRANTED} if access is allowed,
+     *         otherwise {@link PackageManager#PERMISSION_DENIED}.
+     * @hide
+     */
     @Override
+    @SystemApi
     public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) {
         Objects.requireNonNull(uri, "uri");
 
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index b52034f..5bad055 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -743,8 +743,6 @@
 
     void setMimeGroup(String packageName, String group, in List<String> mimeTypes);
 
-    void clearMimeGroup(String packageName, String group);
-
     List<String> getMimeGroup(String packageName, String group);
 
     boolean isAutoRevokeWhitelisted(String packageName);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 2c79022..03b99ed 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -7894,10 +7894,14 @@
     }
 
     /**
-     * Sets MIME group's MIME types
+     * Sets MIME group's MIME types.
      *
-     * @param mimeGroup MIME group to modify
-     * @param mimeTypes new MIME types contained by MIME group
+     * Libraries should use a reverse-DNS prefix followed by a ':' character and library-specific
+     * group name to avoid namespace collisions, e.g. "com.example:myFeature".
+     *
+     * @param mimeGroup MIME group to modify.
+     * @param mimeTypes new MIME types contained by MIME group.
+     * @throws IllegalArgumentException if the MIME group was not declared in the manifest.
      */
     public void setMimeGroup(@NonNull String mimeGroup, @NonNull Set<String> mimeTypes) {
         throw new UnsupportedOperationException(
@@ -7905,22 +7909,16 @@
     }
 
     /**
-     * Clears MIME group by removing all MIME types from it
+     * Gets all MIME types contained by MIME group.
      *
-     * @param mimeGroup MIME group to clear
-     */
-    public void clearMimeGroup(@NonNull String mimeGroup) {
-        throw new UnsupportedOperationException(
-                "clearMimeGroup not implemented in subclass");
-    }
-
-    /**
-     * Gets all MIME types that MIME group contains
+     * Libraries should use a reverse-DNS prefix followed by a ':' character and library-specific
+     * group name to avoid namespace collisions, e.g. "com.example:myFeature".
      *
-     * @return MIME types contained by the MIME group,
-     *         or null if the MIME group was not declared in the manifest.
+     * @param mimeGroup MIME group to retrieve.
+     * @return MIME types contained by the MIME group.
+     * @throws IllegalArgumentException if the MIME group was not declared in the manifest.
      */
-    @Nullable
+    @NonNull
     public Set<String> getMimeGroup(@NonNull String mimeGroup) {
         throw new UnsupportedOperationException(
                 "getMimeGroup not implemented in subclass");
diff --git a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
index 1aeb76a3..0593545 100644
--- a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
+++ b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
@@ -43,7 +43,6 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * Enrollment information about the different available keyphrases.
@@ -120,11 +119,6 @@
     private final KeyphraseMetadata[] mKeyphrases;
 
     /**
-     * Set of UIDs associated with the detected enrollment applications.
-     */
-    private final Set<Integer> mEnrollmentApplicationUids;
-
-    /**
      * Map between KeyphraseMetadata and the package name of the enrollment app that provides it.
      */
     final private Map<KeyphraseMetadata, String> mKeyphrasePackageMap;
@@ -142,13 +136,11 @@
             mParseError = "No enrollment applications found";
             mKeyphrasePackageMap = Collections.<KeyphraseMetadata, String>emptyMap();
             mKeyphrases = null;
-            mEnrollmentApplicationUids = Collections.emptySet();
             return;
         }
 
         List<String> parseErrors = new LinkedList<String>();
         mKeyphrasePackageMap = new HashMap<KeyphraseMetadata, String>();
-        mEnrollmentApplicationUids = new ArraySet<>();
         for (ResolveInfo ri : ris) {
             try {
                 ApplicationInfo ai = pm.getApplicationInfo(
@@ -170,7 +162,6 @@
                         getKeyphraseMetadataFromApplicationInfo(pm, ai, parseErrors);
                 if (metadata != null) {
                     mKeyphrasePackageMap.put(metadata, ai.packageName);
-                    mEnrollmentApplicationUids.add(ai.uid);
                 }
             } catch (PackageManager.NameNotFoundException e) {
                 String error = "error parsing voice enrollment meta-data for "
@@ -373,21 +364,9 @@
         return null;
     }
 
-    /**
-     * Tests if the input UID matches a supported enrollment application.
-     *
-     * @param uid UID of the caller to test against.
-     * @return Returns true if input uid matches the uid of a supported enrollment application.
-     *         False if not.
-     */
-    public boolean isUidSupportedEnrollmentApplication(int uid) {
-        return mEnrollmentApplicationUids.contains(uid);
-    }
-
     @Override
     public String toString() {
         return "KeyphraseEnrollmentInfo [KeyphrasePackageMap=" + mKeyphrasePackageMap.toString()
-                + ", enrollmentApplicationUids=" + mEnrollmentApplicationUids.toString()
                 + ", ParseError=" + mParseError + "]";
     }
 }
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 2cafcdb..c2ee21d 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -2284,7 +2284,9 @@
             // When insets API is enabled, it is responsible for client and server side
             // visibility of IME window.
             if (isVisibilityAppliedUsingInsetsConsumer()) {
-                mInputView.dispatchWindowVisibilityChanged(View.GONE);
+                if (mInputView != null) {
+                    mInputView.dispatchWindowVisibilityChanged(View.GONE);
+                }
             } else {
                 mWindow.hide();
             }
diff --git a/core/java/android/os/ConfigUpdate.java b/core/java/android/os/ConfigUpdate.java
index a28f5fb..4908919 100644
--- a/core/java/android/os/ConfigUpdate.java
+++ b/core/java/android/os/ConfigUpdate.java
@@ -16,7 +16,6 @@
 
 package android.os;
 
-import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
@@ -119,14 +118,14 @@
     /**
     * Update the emergency number database into the devices.
     * <p>Extra: {@link #EXTRA_VERSION} the numeric version of the database.
-    * <p>Extra: {@link #EXTRA_REQUIRED_HASH} the hash of the database.
+    * <p>Extra: {@link #EXTRA_REQUIRED_HASH} hash of the database, which is encoded by base-16
+     * SHA512.
     * <p>Input: {@link android.content.Intent#getData} the URI to download emergency number
     * database.
     *
     * @hide
     */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.UPDATE_CONFIG)
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_UPDATE_EMERGENCY_NUMBER_DB =
             "android.os.action.UPDATE_EMERGENCY_NUMBER_DB";
@@ -141,7 +140,7 @@
     public static final String EXTRA_VERSION = "android.os.extra.VERSION";
 
     /**
-     * A string to indicate the hash of the data.
+     * Hash of the database, which is encoded by base-16 SHA512.
      *
      * @hide
      */
diff --git a/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl b/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl
index 1bcc76b..bed4302 100644
--- a/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl
+++ b/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl
@@ -16,6 +16,7 @@
 
 package android.service.autofill;
 
+import android.content.IntentSender;
 import android.os.IBinder;
 import android.view.SurfaceControlViewHost;
 
@@ -30,4 +31,5 @@
     void onContent(in SurfaceControlViewHost.SurfacePackage surface);
     void onError();
     void onTransferTouchFocusToImeWindow(in IBinder sourceInputToken, int displayId);
+    void onStartIntentSender(in IntentSender intentSender);
 }
diff --git a/core/java/android/service/autofill/InlineSuggestionRenderService.java b/core/java/android/service/autofill/InlineSuggestionRenderService.java
index 7fbc309..0d4be58 100644
--- a/core/java/android/service/autofill/InlineSuggestionRenderService.java
+++ b/core/java/android/service/autofill/InlineSuggestionRenderService.java
@@ -24,6 +24,7 @@
 import android.app.Service;
 import android.app.slice.Slice;
 import android.content.Intent;
+import android.content.IntentSender;
 import android.graphics.PixelFormat;
 import android.os.Bundle;
 import android.os.Handler;
@@ -60,6 +61,8 @@
 
     private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);
 
+    private IInlineSuggestionUiCallback mCallback;
+
     private void handleRenderSuggestion(IInlineSuggestionUiCallback callback,
             InlinePresentation presentation, int width, int height, IBinder hostInputToken,
             int displayId) {
@@ -84,6 +87,7 @@
                 }
                 return;
             }
+            mCallback = callback;
 
             final InlineSuggestionRoot suggestionRoot = new InlineSuggestionRoot(this, callback);
             suggestionRoot.addView(suggestionView);
@@ -155,6 +159,20 @@
     }
 
     /**
+     * Starts the {@link IntentSender} from the client app.
+     *
+     * @param intentSender the {@link IntentSender} to start the attribution UI from the client app.
+     */
+    public final void startIntentSender(@NonNull IntentSender intentSender) {
+        if (mCallback == null) return;
+        try {
+            mCallback.onStartIntentSender(intentSender);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      *  Returns the metadata about the renderer. Returns {@code null} if no metadata is provided.
      */
     @Nullable
diff --git a/core/java/android/service/storage/ExternalStorageService.java b/core/java/android/service/storage/ExternalStorageService.java
index fe797eb..3b4d84a 100644
--- a/core/java/android/service/storage/ExternalStorageService.java
+++ b/core/java/android/service/storage/ExternalStorageService.java
@@ -25,11 +25,13 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.ParcelFileDescriptor;
 import android.os.ParcelableException;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
+import android.os.storage.StorageVolume;
+
+import com.android.internal.os.BackgroundThread;
 
 import java.io.File;
 import java.io.IOException;
@@ -97,7 +99,7 @@
     public @interface SessionFlag {}
 
     private final ExternalStorageServiceWrapper mWrapper = new ExternalStorageServiceWrapper();
-    private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);
+    private final Handler mHandler = BackgroundThread.getHandler();
 
     /**
      * Called when the system starts a session associated with {@code deviceFd}
@@ -131,6 +133,20 @@
      */
     public abstract void onEndSession(@NonNull String sessionId) throws IOException;
 
+    /**
+     * Called when any volume's state changes.
+     *
+     * <p> This is required to communicate volume state changes with the Storage Service before
+     * broadcasting to other apps. The Storage Service needs to process any change in the volume
+     * state (before other apps receive a broadcast for the same) to update the database so that
+     * other apps have the correct view of the volume.
+     *
+     * <p> Blocks until the Storage Service processes/scans the volume or fails in doing so.
+     *
+     * @param vol name of the volume that was changed
+     */
+    public abstract void onVolumeStateChanged(@NonNull StorageVolume vol) throws IOException;
+
     @Override
     @NonNull
     public final IBinder onBind(@NonNull Intent intent) {
@@ -154,6 +170,19 @@
         }
 
         @Override
+        public void notifyVolumeStateChanged(String sessionId, StorageVolume vol,
+                RemoteCallback callback) {
+            mHandler.post(() -> {
+                try {
+                    onVolumeStateChanged(vol);
+                    sendResult(sessionId, null /* throwable */, callback);
+                } catch (Throwable t) {
+                    sendResult(sessionId, t, callback);
+                }
+            });
+        }
+
+        @Override
         public void endSession(String sessionId, RemoteCallback callback) throws RemoteException {
             mHandler.post(() -> {
                 try {
diff --git a/core/java/android/service/storage/IExternalStorageService.aidl b/core/java/android/service/storage/IExternalStorageService.aidl
index ae46f1f..30fefd3 100644
--- a/core/java/android/service/storage/IExternalStorageService.aidl
+++ b/core/java/android/service/storage/IExternalStorageService.aidl
@@ -18,6 +18,7 @@
 
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteCallback;
+import android.os.storage.StorageVolume;
 
 /**
  * @hide
@@ -27,4 +28,6 @@
     void startSession(@utf8InCpp String sessionId, int type, in ParcelFileDescriptor deviceFd,
          @utf8InCpp String upperPath, @utf8InCpp String lowerPath, in RemoteCallback callback);
     void endSession(@utf8InCpp String sessionId, in RemoteCallback callback);
+    void notifyVolumeStateChanged(@utf8InCpp String sessionId, in StorageVolume vol,
+        in RemoteCallback callback);
 }
\ No newline at end of file
diff --git a/core/java/android/telephony/SubscriptionPlan.java b/core/java/android/telephony/SubscriptionPlan.java
index 901957f..d5ac436 100644
--- a/core/java/android/telephony/SubscriptionPlan.java
+++ b/core/java/android/telephony/SubscriptionPlan.java
@@ -372,5 +372,15 @@
             plan.networkTypes = Arrays.copyOf(networkTypes, networkTypes.length);
             return this;
         }
+
+        /**
+         * Reset any network types that were set with {@link #setNetworkTypes(int[])}.
+         * This will make the SubscriptionPlan apply to all network types.
+         */
+        public @NonNull Builder resetNetworkTypes() {
+            plan.networkTypes = Arrays.copyOf(TelephonyManager.getAllNetworkTypes(),
+                    TelephonyManager.getAllNetworkTypes().length);
+            return this;
+        }
     }
 }
diff --git a/core/java/android/view/InsetsSource.java b/core/java/android/view/InsetsSource.java
index 719f649..294faaf 100644
--- a/core/java/android/view/InsetsSource.java
+++ b/core/java/android/view/InsetsSource.java
@@ -18,6 +18,7 @@
 
 import static android.view.InsetsState.ITYPE_IME;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.Insets;
 import android.graphics.Rect;
@@ -114,7 +115,7 @@
         if (!ignoreVisibility && !mVisible) {
             return Insets.NONE;
         }
-        if (!mTmpFrame.setIntersect(frame, relativeFrame)) {
+        if (!getIntersection(frame, relativeFrame, mTmpFrame)) {
             return Insets.NONE;
         }
 
@@ -144,12 +145,33 @@
         }
     }
 
+    /**
+     * Outputs the intersection of two rectangles. The shared edges will also be counted in the
+     * intersection.
+     *
+     * @param a The first rectangle being intersected with.
+     * @param b The second rectangle being intersected with.
+     * @param out The rectangle which represents the intersection.
+     * @return {@code true} if there is any intersection.
+     */
+    private static boolean getIntersection(@NonNull Rect a, @NonNull Rect b, @NonNull Rect out) {
+        if (a.left <= b.right && b.left <= a.right && a.top <= b.bottom && b.top <= a.bottom) {
+            out.left = Math.max(a.left, b.left);
+            out.top = Math.max(a.top, b.top);
+            out.right = Math.min(a.right, b.right);
+            out.bottom = Math.min(a.bottom, b.bottom);
+            return true;
+        }
+        out.setEmpty();
+        return false;
+    }
+
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix);
         pw.print("InsetsSource type="); pw.print(InsetsState.typeToString(mType));
         pw.print(" frame="); pw.print(mFrame.toShortString());
         if (mVisibleFrame != null) {
-            pw.print(" visibleFrmae="); pw.print(mVisibleFrame.toShortString());
+            pw.print(" visibleFrame="); pw.print(mVisibleFrame.toShortString());
         }
         pw.print(" visible="); pw.print(mVisible);
         pw.println();
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 67e5927..4e7ae8a 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -16,6 +16,9 @@
 
 package com.android.internal.widget;
 
+import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_EXTERNAL;
+import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_INLINE;
+
 import android.annotation.AttrRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -35,6 +38,7 @@
 import android.os.Parcelable;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.view.Gravity;
@@ -46,6 +50,7 @@
 import android.view.animation.PathInterpolator;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.RemoteViews;
 import android.widget.TextView;
 
@@ -109,13 +114,14 @@
     private View mExpandButtonContainer;
     private ViewGroup mExpandButtonAndContentContainer;
     private NotificationExpandButton mExpandButton;
+    private MessagingLinearLayout mImageMessageContainer;
     private int mExpandButtonExpandedTopMargin;
     private int mBadgedSideMargins;
     private int mIconSizeBadged;
     private int mIconSizeCentered;
     private CachingIconView mIcon;
+    private View mImportanceRingView;
     private int mExpandedGroupTopMargin;
-    private int mExpandButtonExpandedSize;
     private View mConversationFacePile;
     private int mNotificationBackgroundColor;
     private CharSequence mFallbackChatName;
@@ -126,6 +132,8 @@
     private View mContentContainer;
     private boolean mExpandable = true;
     private int mContentMarginEnd;
+    private Rect mMessagingClipRect;
+    private TextView mAppName;
 
     public ConversationLayout(@NonNull Context context) {
         super(context);
@@ -150,18 +158,20 @@
         super.onFinishInflate();
         mMessagingLinearLayout = findViewById(R.id.notification_messaging);
         mMessagingLinearLayout.setMessagingLayout(this);
+        mImageMessageContainer = findViewById(R.id.conversation_image_message_container);
         // We still want to clip, but only on the top, since views can temporarily out of bounds
         // during transitions.
         DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
         int size = Math.max(displayMetrics.widthPixels, displayMetrics.heightPixels);
-        Rect rect = new Rect(0, 0, size, size);
-        mMessagingLinearLayout.setClipBounds(rect);
+        mMessagingClipRect = new Rect(0, 0, size, size);
+        setMessagingClippingDisabled(false);
         mTitleView = findViewById(R.id.title);
         mAvatarSize = getResources().getDimensionPixelSize(R.dimen.messaging_avatar_size);
         mTextPaint.setTextAlign(Paint.Align.CENTER);
         mTextPaint.setAntiAlias(true);
         mConversationIcon = findViewById(R.id.conversation_icon);
         mIcon = findViewById(R.id.icon);
+        mImportanceRingView = findViewById(R.id.conversation_icon_badge_ring);
         mConversationIconBadge = findViewById(R.id.conversation_icon_badge);
         mIcon.setOnVisibilityChangedListener((visibility) -> {
             // Always keep the badge visibility in sync with the icon. This is necessary in cases
@@ -176,8 +186,6 @@
         mExpandButton = findViewById(R.id.expand_button);
         mExpandButtonExpandedTopMargin = getResources().getDimensionPixelSize(
                 R.dimen.conversation_expand_button_top_margin_expanded);
-        mExpandButtonExpandedSize = getResources().getDimensionPixelSize(
-                R.dimen.conversation_expand_button_expanded_size);
         mNotificationHeaderExpandedPadding = getResources().getDimensionPixelSize(
                 R.dimen.conversation_header_expanded_padding_end);
         mContentMarginEnd = getResources().getDimensionPixelSize(
@@ -195,6 +203,7 @@
                 R.string.conversation_title_fallback_one_to_one);
         mFallbackGroupChatName = getResources().getString(
                 R.string.conversation_title_fallback_group_chat);
+        mAppName = findViewById(R.id.app_name_text);
     }
 
     @RemotableViewMethod
@@ -208,6 +217,14 @@
     }
 
     /**
+     * Sets this conversation as "important", adding some additional UI treatment.
+     */
+    @RemotableViewMethod
+    public void setIsImportantConversation(boolean isImportantConversation) {
+        mImportanceRingView.setVisibility(isImportantConversation ? VISIBLE : GONE);
+    }
+
+    /**
      * Set this layout to show the collapsed representation.
      *
      * @param isCollapsed is it collapsed
@@ -304,14 +321,12 @@
         updateTitleAndNamesDisplay();
 
         updateConversationLayout();
-
     }
 
     /**
      * Update the layout according to the data provided (i.e mIsOneToOne, expanded etc);
      */
     private void updateConversationLayout() {
-        // TODO: resolve this from shortcuts
         // Set avatar and name
         CharSequence conversationText = mConversationTitle;
         // TODO: display the secondary text somewhere
@@ -370,6 +385,42 @@
             messagingGroup.setCanHideSenderIfFirst(canHide);
         }
         updateIconPositionAndSize();
+        updateImageMessages();
+        updateAppName();
+    }
+
+    private void updateImageMessages() {
+        boolean displayExternalImage = false;
+        ArraySet<View> newMessages = new ArraySet<>();
+        if (mIsCollapsed) {
+
+            // When collapsed, we're displaying all image messages in a dedicated container
+            // on the right of the layout instead of inline. Let's add all isolated images there
+            int imageIndex = 0;
+            for (int i = 0; i < mGroups.size(); i++) {
+                MessagingGroup messagingGroup = mGroups.get(i);
+                MessagingImageMessage isolatedMessage = messagingGroup.getIsolatedMessage();
+                if (isolatedMessage != null) {
+                    newMessages.add(isolatedMessage.getView());
+                    displayExternalImage = true;
+                    if (imageIndex
+                            != mImageMessageContainer.indexOfChild(isolatedMessage.getView())) {
+                        mImageMessageContainer.removeView(isolatedMessage.getView());
+                        mImageMessageContainer.addView(isolatedMessage.getView(), imageIndex);
+                    }
+                    imageIndex++;
+                }
+            }
+        }
+        // Remove all messages that don't belong into the image layout
+        for (int i = 0; i < mImageMessageContainer.getChildCount(); i++) {
+            View child = mImageMessageContainer.getChildAt(i);
+            if (!newMessages.contains(child)) {
+                mImageMessageContainer.removeView(child);
+                i--;
+            }
+        }
+        mImageMessageContainer.setVisibility(displayExternalImage ? VISIBLE : GONE);
     }
 
     private void bindFacePile() {
@@ -414,6 +465,14 @@
         topView.setImageIcon(secondLastIcon);
     }
 
+    private void updateAppName() {
+        mAppName.setVisibility(mIsCollapsed ? GONE : VISIBLE);
+    }
+
+    public boolean shouldHideAppName() {
+        return mIsCollapsed;
+    }
+
     /**
      * update the icon position and sizing
      */
@@ -423,7 +482,7 @@
         int marginTop;
         int iconSize;
         if (mIsOneToOne || mIsCollapsed) {
-            // Baded format
+            // Badged format
             gravity = Gravity.LEFT;
             marginStart = mBadgedSideMargins;
             marginTop = mBadgedSideMargins;
@@ -439,11 +498,9 @@
         layoutParams.gravity = gravity;
         layoutParams.topMargin = marginTop;
         layoutParams.setMarginStart(marginStart);
+        layoutParams.width = iconSize;
+        layoutParams.height = iconSize;
         mConversationIconBadge.setLayoutParams(layoutParams);
-        ViewGroup.LayoutParams iconParams = mIcon.getLayoutParams();
-        iconParams.width = iconSize;
-        iconParams.height = iconSize;
-        mIcon.setLayoutParams(iconParams);
     }
 
     @RemotableViewMethod
@@ -662,7 +719,9 @@
                 newGroup = MessagingGroup.createGroup(mMessagingLinearLayout);
                 mAddedGroups.add(newGroup);
             }
-            newGroup.setDisplayImagesAtEnd(mIsCollapsed);
+            newGroup.setImageDisplayLocation(mIsCollapsed
+                    ? IMAGE_DISPLAY_LOCATION_EXTERNAL
+                    : IMAGE_DISPLAY_LOCATION_INLINE);
             newGroup.setIsInConversation(true);
             newGroup.setLayoutColor(mLayoutColor);
             newGroup.setTextColors(mSenderTextColor, mMessageTextColor);
@@ -817,6 +876,10 @@
         return mMessagingLinearLayout;
     }
 
+    public @NonNull ViewGroup getImageMessageContainer() {
+        return mImageMessageContainer;
+    }
+
     public ArrayList<MessagingGroup> getMessagingGroups() {
         return mGroups;
     }
@@ -827,20 +890,17 @@
         int gravity;
         int topMargin = 0;
         ViewGroup newContainer;
-        int newContainerHeight;
         if (mIsCollapsed) {
             drawableId = R.drawable.ic_expand_notification;
             contentDescriptionId = R.string.expand_button_content_description_collapsed;
             gravity = Gravity.CENTER;
             newContainer = mExpandButtonAndContentContainer;
-            newContainerHeight = LayoutParams.MATCH_PARENT;
         } else {
             drawableId = R.drawable.ic_collapse_notification;
             contentDescriptionId = R.string.expand_button_content_description_expanded;
             gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
             topMargin = mExpandButtonExpandedTopMargin;
             newContainer = this;
-            newContainerHeight = mExpandButtonExpandedSize;
         }
         mExpandButton.setImageDrawable(getContext().getDrawable(drawableId));
         mExpandButton.setColorFilter(mExpandButton.getOriginalNotificationColor());
@@ -850,14 +910,11 @@
         if (newContainer != mExpandButtonContainer.getParent()) {
             ((ViewGroup) mExpandButtonContainer.getParent()).removeView(mExpandButtonContainer);
             newContainer.addView(mExpandButtonContainer);
-            MarginLayoutParams layoutParams =
-                    (MarginLayoutParams) mExpandButtonContainer.getLayoutParams();
-            layoutParams.height = newContainerHeight;
-            mExpandButtonContainer.setLayoutParams(layoutParams);
         }
 
         // update if the expand button is centered
-        FrameLayout.LayoutParams layoutParams = (LayoutParams) mExpandButton.getLayoutParams();
+        LinearLayout.LayoutParams layoutParams =
+                (LinearLayout.LayoutParams) mExpandButton.getLayoutParams();
         layoutParams.gravity = gravity;
         layoutParams.topMargin = topMargin;
         mExpandButton.setLayoutParams(layoutParams);
@@ -905,4 +962,9 @@
         }
         updateContentPaddings();
     }
+
+    @Override
+    public void setMessagingClippingDisabled(boolean clippingDisabled) {
+        mMessagingLinearLayout.setClipBounds(clippingDisabled ? null : mMessagingClipRect);
+    }
 }
diff --git a/core/java/com/android/internal/widget/IMessagingLayout.java b/core/java/com/android/internal/widget/IMessagingLayout.java
index 149d056..b72c081 100644
--- a/core/java/com/android/internal/widget/IMessagingLayout.java
+++ b/core/java/com/android/internal/widget/IMessagingLayout.java
@@ -39,4 +39,9 @@
      * @return the list of messaging groups
      */
     ArrayList<MessagingGroup> getMessagingGroups();
+
+    /**
+     * Disable the clipping of the messaging container.
+     */
+    void setMessagingClippingDisabled(boolean clippingDisabled);
 }
diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java
index c68da97..53272f7 100644
--- a/core/java/com/android/internal/widget/MessagingGroup.java
+++ b/core/java/com/android/internal/widget/MessagingGroup.java
@@ -17,6 +17,7 @@
 package com.android.internal.widget;
 
 import android.annotation.AttrRes;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StyleRes;
@@ -44,6 +45,8 @@
 
 import com.android.internal.R;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -54,6 +57,23 @@
 public class MessagingGroup extends LinearLayout implements MessagingLinearLayout.MessagingChild {
     private static Pools.SimplePool<MessagingGroup> sInstancePool
             = new Pools.SynchronizedPool<>(10);
+
+    /**
+     * Images are displayed inline.
+     */
+    public static final int IMAGE_DISPLAY_LOCATION_INLINE = 0;
+
+    /**
+     * Images are displayed at the end of the group.
+     */
+    public static final int IMAGE_DISPLAY_LOCATION_AT_END = 1;
+
+    /**
+     *     Images are displayed externally.
+     */
+    public static final int IMAGE_DISPLAY_LOCATION_EXTERNAL = 2;
+
+
     private MessagingLinearLayout mMessageContainer;
     ImageFloatingTextView mSenderView;
     private ImageView mAvatarView;
@@ -70,7 +90,7 @@
     private boolean mIsHidingAnimated;
     private boolean mNeedsGeneratedAvatar;
     private Person mSender;
-    private boolean mImagesAtEnd;
+    private @ImageDisplayLocation int mImageDisplayLocation;
     private ViewGroup mImageContainer;
     private MessagingImageMessage mIsolatedMessage;
     private boolean mClippingDisabled;
@@ -476,7 +496,7 @@
                 mAddedMessages.add(message);
             }
             boolean isImage = message instanceof MessagingImageMessage;
-            if (mImagesAtEnd && isImage) {
+            if (mImageDisplayLocation != IMAGE_DISPLAY_LOCATION_INLINE && isImage) {
                 isolatedMessage = (MessagingImageMessage) message;
             } else {
                 if (removeFromParentIfDifferent(message, mMessageContainer)) {
@@ -500,9 +520,12 @@
             }
         }
         if (isolatedMessage != null) {
-            if (removeFromParentIfDifferent(isolatedMessage, mImageContainer)) {
+            if (mImageDisplayLocation == IMAGE_DISPLAY_LOCATION_AT_END
+                    && removeFromParentIfDifferent(isolatedMessage, mImageContainer)) {
                 mImageContainer.removeAllViews();
                 mImageContainer.addView(isolatedMessage.getView());
+            } else if (mImageDisplayLocation == IMAGE_DISPLAY_LOCATION_EXTERNAL) {
+                mImageContainer.removeAllViews();
             }
             isolatedMessage.setIsolated(true);
         } else if (mIsolatedMessage != null) {
@@ -515,7 +538,8 @@
     }
 
     private void updateImageContainerVisibility() {
-        mImageContainer.setVisibility(mIsolatedMessage != null && mImagesAtEnd
+        mImageContainer.setVisibility(mIsolatedMessage != null
+                && mImageDisplayLocation == IMAGE_DISPLAY_LOCATION_AT_END
                 ? View.VISIBLE : View.GONE);
     }
 
@@ -620,9 +644,9 @@
         mClippingDisabled = disabled;
     }
 
-    public void setDisplayImagesAtEnd(boolean atEnd) {
-        if (mImagesAtEnd != atEnd) {
-            mImagesAtEnd = atEnd;
+    public void setImageDisplayLocation(@ImageDisplayLocation int displayLocation) {
+        if (mImageDisplayLocation != displayLocation) {
+            mImageDisplayLocation = displayLocation;
             updateImageContainerVisibility();
         }
     }
@@ -670,4 +694,13 @@
             mMessagingIconContainer.setLayoutParams(layoutParams);
         }
     }
+
+    @IntDef(prefix = {"IMAGE_DISPLAY_LOCATION_"}, value = {
+            IMAGE_DISPLAY_LOCATION_INLINE,
+            IMAGE_DISPLAY_LOCATION_AT_END,
+            IMAGE_DISPLAY_LOCATION_EXTERNAL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    private @interface ImageDisplayLocation {
+    }
 }
diff --git a/core/java/com/android/internal/widget/MessagingImageMessage.java b/core/java/com/android/internal/widget/MessagingImageMessage.java
index c243f3b..27689d4 100644
--- a/core/java/com/android/internal/widget/MessagingImageMessage.java
+++ b/core/java/com/android/internal/widget/MessagingImageMessage.java
@@ -149,10 +149,16 @@
     protected void onDraw(Canvas canvas) {
         canvas.save();
         canvas.clipPath(getRoundedRectPath());
-        int width = (int) Math.max(getActualWidth(), getActualHeight() * mAspectRatio);
-        int height = (int) (width / mAspectRatio);
+        // Calculate the right sizing ensuring that the image is nicely centered in the layout
+        // during transitions
+        int width = (int) Math.max((Math.min(getHeight(), getActualHeight()) * mAspectRatio),
+                getActualWidth());
+        int height = (int) Math.max((Math.min(getWidth(), getActualWidth()) / mAspectRatio),
+                getActualHeight());
+        height = (int) Math.max(height, width / mAspectRatio);
         int left = (int) ((getActualWidth() - width) / 2.0f);
-        mDrawable.setBounds(left, 0, left + width, height);
+        int top = (int) ((getActualHeight() - height) / 2.0f);
+        mDrawable.setBounds(left, top, left + width, top + height);
         mDrawable.draw(canvas);
         canvas.restore();
     }
@@ -222,8 +228,17 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         if (mIsIsolated) {
+            // When isolated we have a fixed size, let's use that sizing.
             setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
                     MeasureSpec.getSize(heightMeasureSpec));
+        } else {
+            // If we are displaying inline, we never want to go wider than actual size of the
+            // image, otherwise it will look quite blurry.
+            int width = Math.min(MeasureSpec.getSize(widthMeasureSpec),
+                    mDrawable.getIntrinsicWidth());
+            int height = (int) Math.min(MeasureSpec.getSize(heightMeasureSpec), width
+                    / mAspectRatio);
+            setMeasuredDimension(width, height);
         }
     }
 
@@ -231,7 +246,7 @@
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
         // TODO: ensure that this isn't called when transforming
-        setActualWidth(getStaticWidth());
+        setActualWidth(getWidth());
         setActualHeight(getHeight());
     }
 
@@ -258,13 +273,6 @@
         return mActualHeight;
     }
 
-    public int getStaticWidth() {
-        if (mIsIsolated) {
-            return getWidth();
-        }
-        return (int) (getHeight() * mAspectRatio);
-    }
-
     public void setIsolated(boolean isolated) {
         if (mIsIsolated != isolated) {
             mIsIsolated = isolated;
diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java
index 3fb5d43..a162e4e 100644
--- a/core/java/com/android/internal/widget/MessagingLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLayout.java
@@ -16,6 +16,9 @@
 
 package com.android.internal.widget;
 
+import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_AT_END;
+import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_INLINE;
+
 import android.annotation.AttrRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -447,7 +450,9 @@
                 newGroup = MessagingGroup.createGroup(mMessagingLinearLayout);
                 mAddedGroups.add(newGroup);
             }
-            newGroup.setDisplayImagesAtEnd(mDisplayImagesAtEnd);
+            newGroup.setImageDisplayLocation(mDisplayImagesAtEnd
+                    ? IMAGE_DISPLAY_LOCATION_AT_END
+                    : IMAGE_DISPLAY_LOCATION_INLINE);
             newGroup.setIsInConversation(false);
             newGroup.setLayoutColor(mLayoutColor);
             newGroup.setTextColors(mSenderTextColor, mMessageTextColor);
@@ -599,4 +604,9 @@
     public ArrayList<MessagingGroup> getMessagingGroups() {
         return mGroups;
     }
+
+    @Override
+    public void setMessagingClippingDisabled(boolean clippingDisabled) {
+        // Don't do anything, this is only used for the ConversationLayout
+    }
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 68c51b9..84d9ce2 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3447,12 +3447,25 @@
     <permission android:name="android.permission.BIND_AUGMENTED_AUTOFILL_SERVICE"
                 android:protectionLevel="signature" />
 
-    <!-- Must be required by hotword enrollment application,
-         to ensure that only the system can interact with it.
-         @hide <p>Not for use by third-party applications.</p> -->
+    <!-- Must be required by a {@link android.service.voice.VoiceInteractionService} implementation
+         to enroll its own sound models. This is a more restrictive permission than the higher-level
+         permission KEYPHRASE_ENROLLMENT_APPLICATION. For the caller to enroll sound models with
+         this permission, it must hold the permission and be the active VoiceInteractionService in
+         the system.
+         {@see Settings.Secure.VOICE_INTERACTION_SERVICE}
+         @hide -->
     <permission android:name="android.permission.MANAGE_VOICE_KEYPHRASES"
         android:protectionLevel="signature|privileged" />
 
+    <!-- Must be required by a keyphrase enrollment application, to enroll sound models. This is
+         treated as a higher-level permission to MANAGE_VOICE_KEYPHRASES as a caller can enroll
+         sound models at any time. This permission should be reserved for system enrollment
+         applications detected by {@link android.hardware.soundtrigger.KeyphraseEnrollmentInfo}
+         only.
+         @hide <p>Not for use by third-party applications.</p> -->
+    <permission android:name="android.permission.KEYPHRASE_ENROLLMENT_APPLICATION"
+        android:protectionLevel="signature|privileged" />
+
     <!-- Must be required by a {@link com.android.media.remotedisplay.RemoteDisplayProvider},
          to ensure that only the system can bind to it.
          @hide -->
diff --git a/core/res/res/drawable/conversation_badge_ring.xml b/core/res/res/drawable/conversation_badge_ring.xml
new file mode 100644
index 0000000..11ba8ad
--- /dev/null
+++ b/core/res/res/drawable/conversation_badge_ring.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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">
+
+    <solid
+        android:color="@color/transparent"/>
+
+    <stroke
+        android:color="@color/conversation_important_highlight"
+        android:width="2dp"/>
+
+    <size
+        android:width="26dp"
+        android:height="26dp"/>
+</shape>
+
diff --git a/core/res/res/layout/notification_template_material_conversation.xml b/core/res/res/layout/notification_template_material_conversation.xml
index 2348dee..7bf13ec 100644
--- a/core/res/res/layout/notification_template_material_conversation.xml
+++ b/core/res/res/layout/notification_template_material_conversation.xml
@@ -31,6 +31,7 @@
         android:clipChildren="false"
         android:clipToPadding="false"
         android:paddingTop="12dp"
+        android:paddingBottom="12dp"
     >
 
         <FrameLayout
@@ -57,18 +58,31 @@
 
             <FrameLayout
                 android:id="@+id/conversation_icon_badge"
-                android:layout_width="20dp"
-                android:layout_height="20dp"
+                android:layout_width="@dimen/conversation_icon_size_badged"
+                android:layout_height="@dimen/conversation_icon_size_badged"
                 android:layout_marginLeft="@dimen/conversation_badge_side_margin"
                 android:layout_marginTop="@dimen/conversation_badge_side_margin"
-                android:background="@drawable/conversation_badge_background" >
-                <!-- Badge: 20x20, 48dp padding left + top -->
+            >
+                <ImageView
+                    android:id="@+id/conversation_icon_badge_bg"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:src="@drawable/conversation_badge_background"
+                />
                 <com.android.internal.widget.CachingIconView
                     android:id="@+id/icon"
-                    android:layout_width="@dimen/conversation_icon_size_badged"
-                    android:layout_height="@dimen/conversation_icon_size_badged"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:layout_margin="4dp"
                     android:layout_gravity="center"
                 />
+                <ImageView
+                    android:id="@+id/conversation_icon_badge_ring"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:src="@drawable/conversation_badge_ring"
+                    android:visibility="gone"
+                />
             </FrameLayout>
         </FrameLayout>
     </FrameLayout>
@@ -107,6 +121,7 @@
                     android:layout_height="wrap_content"
                     android:orientation="horizontal"
                     android:paddingTop="16dp"
+                    android:layout_marginBottom="2dp"
                     android:paddingStart="@dimen/conversation_content_start"
                 >
                     <TextView
@@ -159,12 +174,22 @@
                     />
                 </LinearLayout>
 
+                <!-- App Name -->
+                <TextView
+                    android:id="@+id/app_name_text"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginStart="@dimen/conversation_content_start"
+                    android:textSize="12sp"
+                    android:layout_marginBottom="16dp"
+                    android:textAppearance="@style/TextAppearance.DeviceDefault.Notification"
+                />
+
                 <!-- Messages -->
                 <com.android.internal.widget.MessagingLinearLayout
                     android:id="@+id/notification_messaging"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_marginTop="2dp"
                     android:spacing="@dimen/notification_messaging_spacing"
                     android:clipToPadding="false"
                     android:clipChildren="false"
@@ -186,13 +211,29 @@
     </com.android.internal.widget.RemeasuringLinearLayout>
 
     <!--This is dynamically placed between here and at the end of the layout-->
-    <FrameLayout
+    <LinearLayout
         android:id="@+id/expand_button_container"
         android:layout_width="wrap_content"
-        android:layout_height="@dimen/conversation_expand_button_expanded_size"
+        android:layout_height="@dimen/conversation_expand_button_size"
         android:layout_gravity="end|top"
         android:paddingStart="16dp"
-        android:paddingEnd="@dimen/notification_content_margin_end">
+        android:orientation="horizontal"
+        android:paddingEnd="@dimen/notification_content_margin_end"
+        android:clipToPadding="false"
+        android:clipChildren="false"
+        >
+        <!-- Images -->
+        <com.android.internal.widget.MessagingLinearLayout
+            android:id="@+id/conversation_image_message_container"
+            android:forceHasOverlappingRendering="false"
+            android:layout_width="40dp"
+            android:layout_height="40dp"
+            android:layout_marginEnd="11dp"
+            android:spacing="0dp"
+            android:layout_gravity="center"
+            android:clipToPadding="false"
+            android:clipChildren="false"
+            />
         <com.android.internal.widget.NotificationExpandButton
             android:id="@+id/expand_button"
             android:layout_width="@dimen/notification_header_expand_icon_size"
@@ -202,5 +243,5 @@
             android:clickable="false"
             android:importantForAccessibility="no"
             />
-    </FrameLayout>
+    </LinearLayout>
 </com.android.internal.widget.ConversationLayout>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index fe08f9c..d6e200a 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2121,6 +2121,35 @@
     <declare-styleable name="AndroidManifestQueriesProvider" parent="AndroidManifestQueries" >
         <attr name="authorities" />
     </declare-styleable>
+    <!--
+        Matches an overlayable, its overlays, its actor, and/or its containing target.
+        A target or actor must always be specified, but can be combined for more specificity.
+        Valid combinations and what they match are:
+
+        targetPackage:
+         - All overlays targeting any overlayables inside 'targetPackage'
+
+        targetPackage + targetName:
+         - All overlays targeting the overlayable 'targetName' inside 'targetPackage'
+
+        targetPackage + targetName + actor:
+         - All overlays targeting the overlayable 'targetName' inside 'targetPackage' if the
+           overlayable specifies 'actor'
+
+        targetPackage + actor:
+         - All overlays targeting overlayables inside 'targetPackage' that specify `actor`
+         - The actor itself if the above matches
+
+        actor:
+         - All overlays targeting overlayables that specify `actor`
+         - All targets that contain an overlayable that specifies `actor`
+         - The actor itself
+    -->
+    <declare-styleable name="AndroidManifestQueriesOverlayable">
+        <attr name="targetPackage" />
+        <attr name="targetName"/>
+        <attr name="actor" format="string" />
+    </declare-styleable>
 
 
     <!-- The <code>static-library</code> tag declares that this apk is providing itself
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 91248f1..831da6f 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -226,4 +226,6 @@
     <color name="resolver_text_color_secondary_dark">#ffC4C6C6</color>
     <color name="resolver_empty_state_text">#FF202124</color>
     <color name="resolver_empty_state_icon">#FF5F6368</color>
+
+    <color name="conversation_important_highlight">#F9AB00</color>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 4dedc63..f2e2599 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -686,18 +686,18 @@
     <dimen name="conversation_avatar_size">52dp</dimen>
     <!-- Start of the content in the conversation template -->
     <dimen name="conversation_content_start">80dp</dimen>
-    <!-- Size of the expand button when expanded -->
-    <dimen name="conversation_expand_button_expanded_size">80dp</dimen>
+    <!-- Size of the expand button in the conversation layout -->
+    <dimen name="conversation_expand_button_size">80dp</dimen>
     <!-- Top margin of the expand button for conversations when expanded -->
     <dimen name="conversation_expand_button_top_margin_expanded">18dp</dimen>
     <!-- Side margins of the conversation badge in relation to the conversation icon -->
     <dimen name="conversation_badge_side_margin">36dp</dimen>
-    <!-- size of the notification icon when badged in a conversation -->
-    <dimen name="conversation_icon_size_badged">15dp</dimen>
-    <!-- size of the notification icon when centered in a conversation -->
-    <dimen name="conversation_icon_size_centered">20dp</dimen>
+    <!-- size of the notification badge when applied to the conversation icon -->
+    <dimen name="conversation_icon_size_badged">20dp</dimen>
+    <!-- size of the notification badge when centered in a conversation -->
+    <dimen name="conversation_icon_size_centered">26dp</dimen>
     <!-- margin on the top when the icon is centered for group conversations -->
-    <dimen name="conversation_icon_margin_top_centered">5dp</dimen>
+    <dimen name="conversation_icon_margin_top_centered">12dp</dimen>
 
     <!-- The padding of the conversation header when expanded. This is calculated from the expand button size + notification_content_margin_end -->
     <dimen name="conversation_header_expanded_padding_end">38dp</dimen>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 9f4b344..f02d54f 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3019,6 +3019,7 @@
       <public name="preserveLegacyExternalStorage" />
       <public name="mimeGroup" />
       <public name="gwpAsanMode" />
+      <public name="actor" />
     </public-group>
 
     <public-group type="drawable" first-id="0x010800b5">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5ea48ed..55e23c3 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -533,26 +533,28 @@
     <!-- Title of the Global Actions Dialog -->
     <string name="global_actions" product="default">Phone options</string>
 
-    <!-- label for item that locks the phone in the phone options dialog -->
+    <!-- label for item that locks the phone in the phone options dialog [CHAR LIMIT=24]-->
     <string name="global_action_lock">Screen lock</string>
 
-    <!-- label for item that turns off power in phone options dialog -->
+    <!-- label for item that turns off power in phone options dialog [CHAR LIMIT=24] -->
     <string name="global_action_power_off">Power off</string>
 
-    <!-- label for item that restarts phone in phone options dialog -->
-    <!-- TODO: promote to separate string-->
-    <string name="global_action_restart" translatable="false">@string/sim_restart_button</string>
+    <!-- label for item that shows options to power off and restart the phone [CHAR LIMIT=24]-->
+    <string name="global_action_power_options">Power</string>
 
-    <!-- label for item that starts emergency call -->
+    <!-- label for item that restarts phone in phone options dialog [CHAR LIMIT=24]-->
+    <string name="global_action_restart">Restart</string>
+
+    <!-- label for item that opens emergency features in the phone options dialog [CHAR LIMIT=24]-->
     <string name="global_action_emergency">Emergency</string>
 
-    <!-- label for item that generates a bug report in the phone options dialog -->
+    <!-- label for item that generates a bug report in the phone options dialog [CHAR LIMIT=24] -->
     <string name="global_action_bug_report">Bug report</string>
 
-    <!-- label for item that logouts the current user -->
+    <!-- label for item that logouts the current user [CHAR LIMIT=24]-->
     <string name="global_action_logout">End session</string>
 
-    <!-- label for screenshot item in power menu -->
+    <!-- label for screenshot item in power menu [CHAR LIMIT=24]-->
     <string name="global_action_screenshot">Screenshot</string>
 
     <!-- Take bug report menu title [CHAR LIMIT=30] -->
@@ -617,7 +619,7 @@
     <!-- label for item that launches voice assist in phone options dialog [CHAR LIMIT=15]-->
     <string name="global_action_voice_assist">Voice Assist</string>
 
-    <!-- label for item that locks the phone and enforces that it can't be unlocked without strong authentication. [CHAR LIMIT=15] -->
+    <!-- label for item that locks the phone and enforces that it can't be unlocked without strong authentication. [CHAR LIMIT=24] -->
     <string name="global_action_lockdown">Lockdown</string>
 
     <!-- Text to use when the number in a notification info is too large
@@ -1164,7 +1166,7 @@
     <!-- 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_systemCamera">Allow an application or service access to system cameras to take pictures and videos</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_systemCamera">This privileged | system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well</string>
+    <string name="permdesc_systemCamera">This privileged or system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well</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_cameraOpenCloseListener">Allow an application or service to receive callbacks about camera devices being opened or closed.</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 20d943d..e0e6074 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3860,6 +3860,8 @@
   <java-symbol type="string" name="conversation_title_fallback_group_chat" />
   <java-symbol type="id" name="conversation_icon" />
   <java-symbol type="id" name="conversation_icon_badge" />
+  <java-symbol type="id" name="conversation_icon_badge_ring" />
+  <java-symbol type="id" name="conversation_icon_badge_bg" />
   <java-symbol type="id" name="expand_button_container" />
   <java-symbol type="id" name="messaging_group_content_container" />
   <java-symbol type="id" name="expand_button_and_content_container" />
@@ -3870,8 +3872,8 @@
   <java-symbol type="id" name="conversation_face_pile" />
   <java-symbol type="id" name="conversation_text" />
   <java-symbol type="id" name="message_icon_container" />
+  <java-symbol type="id" name="conversation_image_message_container" />
   <java-symbol type="dimen" name="conversation_expand_button_top_margin_expanded" />
-  <java-symbol type="dimen" name="conversation_expand_button_expanded_size" />
   <java-symbol type="dimen" name="messaging_group_singleline_sender_padding_end" />
   <java-symbol type="dimen" name="conversation_badge_side_margin" />
   <java-symbol type="dimen" name="conversation_icon_size_badged" />
diff --git a/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestService.java b/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestService.java
index a027f9e..79b803a 100644
--- a/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestService.java
+++ b/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestService.java
@@ -15,19 +15,24 @@
  */
 package com.android.coretests.apps.bstatstestapp;
 
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
 import android.R;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.Service;
+import android.content.Context;
 import android.content.Intent;
 import android.graphics.Color;
+import android.hardware.display.DisplayManager;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Process;
 import android.os.RemoteException;
 import android.util.Log;
 import android.util.Size;
+import android.view.Display;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -46,11 +51,17 @@
 
     private static final int TIMEOUT_OVERLAY_SEC = 2;
 
+    private Context mOverlayContext;
     private View mOverlay;
 
     @Override
     public void onCreate() {
         Log.d(TAG, "onCreate called. myUid=" + Process.myUid());
+
+        final DisplayManager dm = getSystemService(DisplayManager.class);
+        final Display defaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
+        final Context defaultDisplayContext = createDisplayContext(defaultDisplay);
+        mOverlayContext = defaultDisplayContext.createWindowContext(TYPE_APPLICATION_OVERLAY, null);
     }
 
     @Override
@@ -93,7 +104,7 @@
 
     private void removeOverlays() {
         if (mOverlay != null) {
-            final WindowManager wm = TestService.this.getSystemService(WindowManager.class);
+            final WindowManager wm = mOverlayContext.getSystemService(WindowManager.class);
             wm.removeView(mOverlay);
             mOverlay = null;
         }
@@ -107,11 +118,11 @@
 
         @Override
         public void showApplicationOverlay() throws RemoteException {
-            final WindowManager wm = TestService.this.getSystemService(WindowManager.class);
+            final WindowManager wm = mOverlayContext.getSystemService(WindowManager.class);
             final Size size = wm.getCurrentWindowMetrics().getSize();
 
             final WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(
-                    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
+                    TYPE_APPLICATION_OVERLAY,
                     WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                             | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                             | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
@@ -124,7 +135,7 @@
                     ViewGroup.LayoutParams.MATCH_PARENT,
                     ViewGroup.LayoutParams.MATCH_PARENT);
 
-            mOverlay = new View(TestService.this);
+            mOverlay = new View(mOverlayContext);
             mOverlay.setBackgroundColor(Color.GREEN);
             mOverlay.setLayoutParams(vglp);
 
diff --git a/core/tests/coretests/src/android/view/InsetsSourceTest.java b/core/tests/coretests/src/android/view/InsetsSourceTest.java
index 756d63d..b3f6fe9 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceTest.java
@@ -127,6 +127,48 @@
     }
 
     @Test
+    public void testCalculateInsets_noIntersection_vertical() {
+        mSource.setFrame(new Rect(0, 0, 500, 100));
+        Insets insets = mSource.calculateInsets(new Rect(0, 100, 500, 500), false);
+        assertEquals(Insets.NONE, insets);
+    }
+
+    @Test
+    public void testCalculateInsets_zeroWidthIntersection_vertical_start() {
+        mSource.setFrame(new Rect(0, 0, 500, 100));
+        Insets insets = mSource.calculateInsets(new Rect(0, 0, 0, 500), false);
+        assertEquals(Insets.of(0, 100, 0, 0), insets);
+    }
+
+    @Test
+    public void testCalculateInsets_zeroWidthIntersection_vertical_end() {
+        mSource.setFrame(new Rect(0, 0, 500, 100));
+        Insets insets = mSource.calculateInsets(new Rect(500, 0, 500, 500), false);
+        assertEquals(Insets.of(0, 100, 0, 0), insets);
+    }
+
+    @Test
+    public void testCalculateInsets_noIntersection_horizontal() {
+        mSource.setFrame(new Rect(0, 0, 100, 500));
+        Insets insets = mSource.calculateInsets(new Rect(100, 0, 500, 500), false);
+        assertEquals(Insets.NONE, insets);
+    }
+
+    @Test
+    public void testCalculateInsets_zeroWidthIntersection_horizontal_start() {
+        mSource.setFrame(new Rect(0, 0, 100, 500));
+        Insets insets = mSource.calculateInsets(new Rect(0, 0, 500, 0), false);
+        assertEquals(Insets.of(100, 0, 0, 0), insets);
+    }
+
+    @Test
+    public void testCalculateInsets_zeroWidthIntersection_horizontal_end() {
+        mSource.setFrame(new Rect(0, 0, 100, 500));
+        Insets insets = mSource.calculateInsets(new Rect(0, 500, 500, 500), false);
+        assertEquals(Insets.of(100, 0, 0, 0), insets);
+    }
+
+    @Test
     public void testCalculateVisibleInsets_override() {
         mSource.setFrame(new Rect(0, 0, 500, 100));
         mSource.setVisibleFrame(new Rect(0, 0, 500, 200));
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 6e63d17..9950f05 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -425,9 +425,9 @@
     /**
      * Returns an array of supported encapsulation modes for the device.
      *
-     * The array can include any of
-     * {@link AudioTrack#ENCAPSULATION_MODE_ELEMENTARY_STREAM},
-     * {@link AudioTrack#ENCAPSULATION_MODE_HANDLE}.
+     * The array can include any of the {@code AudioTrack} encapsulation modes,
+     * e.g. {@link AudioTrack#ENCAPSULATION_MODE_NONE},
+     * or {@link AudioTrack#ENCAPSULATION_MODE_ELEMENTARY_STREAM}.
      *
      * @return An array of supported encapsulation modes for the device.  This
      *     may be an empty array if no encapsulation modes are supported.
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 94d4fcc..d17e429 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -22,6 +22,8 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Binder;
@@ -229,7 +231,7 @@
     @IntDef({
         ENCAPSULATION_MODE_NONE,
         ENCAPSULATION_MODE_ELEMENTARY_STREAM,
-        ENCAPSULATION_MODE_HANDLE,
+        // ENCAPSULATION_MODE_HANDLE, @SystemApi
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface EncapsulationMode {}
@@ -244,16 +246,17 @@
     /**
      * This mode indicates metadata encapsulation with an elementary stream payload.
      * Both compressed and PCM format is allowed.
-     *
-     * TODO(b/147778408) Link: See the Android developers guide for more information.
      */
     public static final int ENCAPSULATION_MODE_ELEMENTARY_STREAM = 1;
     /**
-     * This mode indicates metadata encapsulation with a handle payload.
-     * The handle is a 64 bit long, provided by the Tuner API.
-     *
-     * TODO(b/147778408) Link: Fill in Tuner API to obtain the handle.
+     * This mode indicates metadata encapsulation with a handle payload
+     * and is set through {@link Builder#setEncapsulationMode(int)}.
+     * The handle is a 64 bit long, provided by the Tuner API
+     * in {@link android.os.Build.VERSION_CODES#R}.
+     * @hide
      */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     public static final int ENCAPSULATION_MODE_HANDLE = 2;
 
     /* Enumeration of metadata types permitted for use by
@@ -908,7 +911,9 @@
      *
      * Use the Builder to construct the TunerConfiguration object,
      * which is then used by the {@link AudioTrack.Builder} to create an AudioTrack.
+     * @hide
      */
+    @SystemApi
     public static class TunerConfiguration {
         private final int mContentId;
         private final int mSyncId;
@@ -921,15 +926,17 @@
         /**
          * Returns the contentId.
          */
-        public int getContentId() {
-            return mContentId;
+        @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+        public @IntRange(from = 1) int getContentId() {
+            return mContentId; // The Builder ensures this is > 0.
         }
 
         /**
          * Returns the syncId.
          */
-        public int getSyncId() {
-            return mSyncId;
+        @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+        public @IntRange(from = 1) int getSyncId() {
+            return mSyncId;  // The Builder ensures this is > 0.
         }
 
         /**
@@ -943,11 +950,13 @@
              * Sets the contentId from the Tuner filter.
              *
              * @param contentId selects the audio stream to use.
-             *     See android.media.tv.tuner.filter.Filter#getId().
+             *     The contentId may be obtained from
+             *     {@link android.media.tv.tuner.filter.Filter#getId()}.
              *     This is always a positive number.
-             *     TODO(b/147778408) Link to tuner filter doc when unhidden.
+             *
              * @return the same Builder instance.
              */
+            @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
             public @NonNull Builder setContentId(@IntRange(from = 1) int contentId) {
                 if (contentId < 1) {
                     throw new IllegalArgumentException(
@@ -962,11 +971,13 @@
              *
              * @param syncId selects the clock to use for synchronization
              *     of audio with other streams such as video.
-             *     See android.media.tv.tuner.Tuner#getAvSyncHwId().
+             *     The syncId may be obtained from
+             *     {@link android.media.tv.tuner.Tuner#getAvSyncHwId()}.
              *     This is always a positive number.
-             *     TODO(b/147778408) Link to tuner filter doc when unhidden.
+             *
              * @return the same Builder instance.
              */
+            @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
             public @NonNull Builder setSyncId(@IntRange(from = 1) int syncId) {
                 if (syncId < 1) {
                     throw new IllegalArgumentException("syncId " + syncId + " must be positive");
@@ -983,11 +994,12 @@
              * @throws UnsupportedOperationException if the parameters set on the
              *     {@code Builder} are incompatible.
              */
+            @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
             public @NonNull TunerConfiguration build() {
                 if (mContentId < 1 || mSyncId < 1) {
                     throw new UnsupportedOperationException(
-                            "contentId " + mContentId
-                            + " syncId " + mSyncId
+                            "mContentId " + mContentId
+                            + " mSyncId " + mSyncId
                             + " must be set");
                 }
                 return new TunerConfiguration(mContentId, mSyncId);
@@ -1113,15 +1125,14 @@
          *
          * Encapsulation mode allows metadata to be sent together with
          * the audio data payload in a {@code ByteBuffer}.
-         * The data format is specified in the Android developers site.
-         *
-         * TODO(b/147778408) Link to doc page.
+         * This requires a compatible hardware audio codec.
          *
          * @param encapsulationMode one of {@link AudioTrack#ENCAPSULATION_MODE_NONE},
-         *        {@link AudioTrack#ENCAPSULATION_MODE_ELEMENTARY_STREAM},
-         *        {@link AudioTrack#ENCAPSULATION_MODE_HANDLE}.
+         *        or {@link AudioTrack#ENCAPSULATION_MODE_ELEMENTARY_STREAM}.
          * @return the same Builder instance.
          */
+        // Note: with the correct permission {@code AudioTrack#ENCAPSULATION_MODE_HANDLE}
+        // may be used as well.
         public @NonNull Builder setEncapsulationMode(@EncapsulationMode int encapsulationMode) {
             switch (encapsulationMode) {
                 case ENCAPSULATION_MODE_NONE:
@@ -1225,7 +1236,10 @@
          *
          * @param tunerConfiguration obtained by {@link AudioTrack.TunerConfiguration.Builder}.
          * @return the same Builder instance.
+         * @hide
          */
+        @SystemApi
+        @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
         public @NonNull Builder setTunerConfiguration(
                 @NonNull TunerConfiguration tunerConfiguration) {
             if (tunerConfiguration == null) {
@@ -1475,7 +1489,7 @@
      *
      * For AudioTracks incorporating a secondary Audio Description stream
      * (where such contents may be sent through an Encapsulation Mode
-     * {@link #ENCAPSULATION_MODE_ELEMENTARY_STREAM} or {@link #ENCAPSULATION_MODE_HANDLE}
+     * other than {@link #ENCAPSULATION_MODE_NONE}).
      * or internally by a HW channel),
      * the level of mixing of the Audio Description to the Main Audio stream
      * is controlled by this method.
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index a8f7185..cbf2364 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -316,7 +316,7 @@
      * A key describing the hardware AV sync id.
      * The associated value is an integer
      *
-     * @see android.media.tv.tuner.Tuner#getAvSyncHwId
+     * See android.media.tv.tuner.Tuner#getAvSyncHwId.
      */
     public static final String KEY_HARDWARE_AV_SYNC_ID = "hw-av-sync-id";
 
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index 36ccf00..9985613 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -238,7 +238,7 @@
      * Refer to the class documentation for details about live audio routes.
      * </p>
      */
-    public static final String FEATURE_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO";
+    public static final String FEATURE_LIVE_AUDIO = "android.media.route.feature.LIVE_AUDIO";
 
     /**
      * Media feature: Live video.
@@ -259,13 +259,15 @@
      *
      * @see android.app.Presentation
      */
-    public static final String FEATURE_LIVE_VIDEO = "android.media.intent.category.LIVE_VIDEO";
+    public static final String FEATURE_LIVE_VIDEO = "android.media.route.feature.LIVE_VIDEO";
 
     /**
      * Media feature: Remote playback.
      * <p>
      * A route that supports remote playback routing will allow an application to send
      * requests to play content remotely to supported destinations.
+     * A route may only support {@link #FEATURE_REMOTE_AUDIO_PLAYBACK audio playback} or
+     * {@link #FEATURE_REMOTE_VIDEO_PLAYBACK video playback}.
      * </p><p>
      * Remote playback routes destinations operate independently of the local device.
      * When a remote playback route is selected, the application can control the content
@@ -274,9 +276,35 @@
      * </p><p>
      * Refer to the class documentation for details about remote playback routes.
      * </p>
+     * @see #FEATURE_REMOTE_AUDIO_PLAYBACK
+     * @see #FEATURE_REMOTE_VIDEO_PLAYBACK
      */
     public static final String FEATURE_REMOTE_PLAYBACK =
-            "android.media.intent.category.REMOTE_PLAYBACK";
+            "android.media.route.feature.REMOTE_PLAYBACK";
+
+    /**
+     * Media feature: Remote audio playback.
+     * <p>
+     * A route that supports remote audio playback routing will allow an application to send
+     * requests to play audio content remotely to supported destinations.
+     *
+     * @see #FEATURE_REMOTE_PLAYBACK
+     * @see #FEATURE_REMOTE_VIDEO_PLAYBACK
+     */
+    public static final String FEATURE_REMOTE_AUDIO_PLAYBACK =
+            "android.media.route.feature.REMOTE_AUDIO_PLAYBACK";
+
+    /**
+     * Media feature: Remote video playback.
+     * <p>
+     * A route that supports remote video playback routing will allow an application to send
+     * requests to play video content remotely to supported destinations.
+     *
+     * @see #FEATURE_REMOTE_PLAYBACK
+     * @see #FEATURE_REMOTE_AUDIO_PLAYBACK
+     */
+    public static final String FEATURE_REMOTE_VIDEO_PLAYBACK =
+            "android.media.route.feature.REMOTE_VIDEO_PLAYBACK";
 
     final String mId;
     final CharSequence mName;
diff --git a/media/jni/soundpool/StreamManager.cpp b/media/jni/soundpool/StreamManager.cpp
index 79e4d8a..c612218 100644
--- a/media/jni/soundpool/StreamManager.cpp
+++ b/media/jni/soundpool/StreamManager.cpp
@@ -340,8 +340,10 @@
     int64_t waitTimeNs = kWaitTimeBeforeCloseNs;
     std::unique_lock lock(mStreamManagerLock);
     while (!mQuit) {
-        mStreamManagerCondition.wait_for(
-                lock, std::chrono::duration<int64_t, std::nano>(waitTimeNs));
+        if (mRestartStreams.empty()) { // on thread start, mRestartStreams can be non-empty.
+            mStreamManagerCondition.wait_for(
+                    lock, std::chrono::duration<int64_t, std::nano>(waitTimeNs));
+        }
         ALOGV("%s(%d) awake", __func__, id);
 
         sanityCheckQueue_l();
diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml
index 2392c96..87f89ce 100644
--- a/packages/PackageInstaller/res/values-ar/strings.xml
+++ b/packages/PackageInstaller/res/values-ar/strings.xml
@@ -24,8 +24,8 @@
     <string name="installing_app" msgid="1165095864863849422">"جارٍ تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="install_done" msgid="5987363587661783896">"تم تثبيت التطبيق."</string>
     <string name="install_confirm_question" msgid="8176284075816604590">"هل تريد تثبيت هذا التطبيق؟"</string>
-    <string name="install_confirm_question_update" msgid="7942235418781274635">"هل تريد تثبيت إعادة تحميل لهذا التطبيق الحالي؟ لن تفقد بياناتك الحالية."</string>
-    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"هل تريد تثبيت إعادة تحميل لهذا التطبيق المضمَّن؟ لن تفقد بياناتك الحالية."</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"هل تريد تثبيت تحديث لهذا التطبيق الحالي؟ لن تفقد بياناتك الحالية."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"هل تريد تثبيت تحديث لهذا التطبيق المضمَّن؟ لن تفقد بياناتك الحالية."</string>
     <string name="install_failed" msgid="5777824004474125469">"التطبيق ليس مثبتًا."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"تم حظر تثبيت الحزمة."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"لم يتم تثبيت التطبيق لأن حزمة التثبيت تتعارض مع حزمة حالية."</string>
diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml
index 2011013..65e75cd 100644
--- a/packages/PackageInstaller/res/values-eu/strings.xml
+++ b/packages/PackageInstaller/res/values-eu/strings.xml
@@ -83,9 +83,9 @@
     <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak tableta honetan."</string>
     <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telebista honetan."</string>
     <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telefono honetan."</string>
-    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefonoak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zu zarela hura erabiltzeagatik telefonoak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zu zarela hura erabiltzeagatik tabletak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zu zarela hura erabiltzeagatik telebistak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefonoak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telefonoak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik tabletak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telebistak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
     <string name="anonymous_source_continue" msgid="4375745439457209366">"Egin aurrera"</string>
     <string name="external_sources_settings" msgid="4046964413071713807">"Ezarpenak"</string>
     <string name="wear_app_channel" msgid="1960809674709107850">"Wear aplikazioak instalatzea/desinstalatzea"</string>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 2d351c7..d93c015 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -1313,7 +1313,8 @@
             }
 
             // isValuePreservedInRestore shouldn't change back to false if it has been set to true.
-            boolean isPreserved = shouldPreserveSetting(overrideableByRestore, resetToDefault);
+            boolean isPreserved = shouldPreserveSetting(overrideableByRestore, resetToDefault,
+                    packageName, value);
 
             // Is something gonna change?
             if (Objects.equals(value, this.value)
@@ -1339,11 +1340,16 @@
         }
 
         private boolean shouldPreserveSetting(boolean overrideableByRestore,
-                boolean resetToDefault) {
+                boolean resetToDefault, String packageName, String value) {
             if (resetToDefault) {
                 // By default settings are not marked as preserved.
                 return false;
             }
+            if (value != null && value.equals(this.value)
+                    && SYSTEM_PACKAGE_NAME.equals(packageName)) {
+                // Do not mark preserved if it's the system reinitializing to the same value.
+                return false;
+            }
 
             // isValuePreservedInRestore shouldn't change back to false if it has been set to true.
             return this.isValuePreservedInRestore || !overrideableByRestore;
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
index 6a3c661..9f448af 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
@@ -47,6 +47,7 @@
             "日本語";
 
     private static final String TEST_PACKAGE = "package";
+    private static final String SYSTEM_PACKAGE = "android";
     private static final String SETTING_NAME = "test_setting";
 
     private final Object mLock = new Object();
@@ -253,6 +254,26 @@
 
     }
 
+    public void testModifySettingBySystemPackage_sameValue_preserveFlagNotSet() {
+        SettingsState settingsState = getSettingStateObject();
+        // Initialize the setting.
+        settingsState.insertSettingLocked(SETTING_NAME, "1", null, false, SYSTEM_PACKAGE);
+        // Update the setting.
+        settingsState.insertSettingLocked(SETTING_NAME, "1", null, false, SYSTEM_PACKAGE);
+
+        assertFalse(settingsState.getSettingLocked(SETTING_NAME).isValuePreservedInRestore());
+    }
+
+    public void testModifySettingBySystemPackage_newValue_preserveFlagSet() {
+        SettingsState settingsState = getSettingStateObject();
+        // Initialize the setting.
+        settingsState.insertSettingLocked(SETTING_NAME, "1", null, false, SYSTEM_PACKAGE);
+        // Update the setting.
+        settingsState.insertSettingLocked(SETTING_NAME, "2", null, false, SYSTEM_PACKAGE);
+
+        assertTrue(settingsState.getSettingLocked(SETTING_NAME).isValuePreservedInRestore());
+    }
+
     private SettingsState getSettingStateObject() {
         SettingsState settingsState = new SettingsState(getContext(), mLock, mSettingsFile, 1,
                 SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
diff --git a/packages/SystemUI/res/layout/notification_conversation_info.xml b/packages/SystemUI/res/layout/notification_conversation_info.xml
index 6a7f9e2..87cb5c7f 100644
--- a/packages/SystemUI/res/layout/notification_conversation_info.xml
+++ b/packages/SystemUI/res/layout/notification_conversation_info.xml
@@ -53,8 +53,7 @@
             android:layout_centerVertical="true"
             android:gravity="center_vertical"
             android:layout_alignEnd="@id/conversation_icon"
-            android:layout_toEndOf="@id/conversation_icon"
-            android:layout_alignStart="@id/mute">
+            android:layout_toEndOf="@id/conversation_icon">
             <LinearLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
@@ -127,96 +126,230 @@
 
         <!-- end aligned fields -->
         <ImageButton
-            android:id="@+id/mute"
+            android:id="@+id/info"
             android:layout_width="@dimen/notification_importance_toggle_size"
             android:layout_height="@dimen/notification_importance_toggle_size"
             android:layout_centerVertical="true"
             android:background="@drawable/ripple_drawable"
-            android:layout_toStartOf="@id/fave"
-            android:tint="@color/notification_guts_link_icon_tint"/>
-        <ImageButton
-            android:id="@+id/fave"
-            android:layout_width="@dimen/notification_importance_toggle_size"
-            android:layout_height="@dimen/notification_importance_toggle_size"
-            android:layout_centerVertical="true"
-            android:background="@drawable/ripple_drawable"
+            android:contentDescription="@string/notification_more_settings"
+            android:src="@drawable/ic_settings"
             android:layout_alignParentEnd="true"
             android:tint="@color/notification_guts_link_icon_tint"/>
 
     </LinearLayout>
 
     <LinearLayout
-        android:id="@+id/actions"
+        android:id="@+id/inline_controls"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginEnd="@*android:dimen/notification_content_margin_end"
+        android:paddingEnd="@*android:dimen/notification_content_margin_end"
+        android:layout_marginTop="@dimen/notification_guts_option_vertical_padding"
         android:clipChildren="false"
         android:clipToPadding="false"
         android:orientation="vertical">
 
-        <View
+        <!-- Non configurable app/channel text. appears instead of @+id/interruptiveness_settings-->
+        <TextView
+            android:id="@+id/non_configurable_text"
+            android:text="@string/notification_unblockable_desc"
+            android:visibility="gone"
             android:layout_width="match_parent"
-            android:layout_height="0.5dp"
-            android:background="@color/GM2_grey_300" />
+            android:layout_height="wrap_content"
+            style="@*android:style/TextAppearance.DeviceDefault.Notification" />
 
-        <Button
-            android:id="@+id/snooze"
-            android:layout_height="@dimen/notification_guts_conversation_action_height"
+        <!-- Non configurable multichannel text. appears instead of @+id/interruptiveness_settings-->
+        <TextView
+            android:id="@+id/non_configurable_multichannel_text"
+            android:text="@string/notification_multichannel_desc"
+            android:visibility="gone"
             android:layout_width="match_parent"
-            style="?android:attr/borderlessButtonStyle"
-            android:text="@string/notification_menu_snooze_action"
-            android:gravity="left|center_vertical"
-            android:drawableStart="@drawable/ic_snooze"
-            android:drawablePadding="@dimen/notification_guts_conversation_action_text_padding_start"
-            android:drawableTint="@color/notification_guts_link_icon_tint"/>
+            android:layout_height="wrap_content"
+            style="@*android:style/TextAppearance.DeviceDefault.Notification" />
 
-        <View
+        <LinearLayout
+            android:id="@+id/interruptiveness_settings"
             android:layout_width="match_parent"
-            android:layout_height="0.5dp"
-            android:background="@color/GM2_grey_300" />
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:orientation="vertical">
 
-        <Button
-            android:id="@+id/bubble"
-            android:layout_height="@dimen/notification_guts_conversation_action_height"
-            android:layout_width="match_parent"
-            style="?android:attr/borderlessButtonStyle"
-            android:text="@string/notification_conversation_favorite"
-            android:gravity="left|center_vertical"
-            android:drawableStart="@drawable/ic_create_bubble"
-            android:drawablePadding="@dimen/notification_guts_conversation_action_text_padding_start"
-            android:drawableTint="@color/notification_guts_link_icon_tint"/>
+            <com.android.systemui.statusbar.notification.row.ButtonLinearLayout
+                android:id="@+id/priority"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="@dimen/notification_importance_button_padding"
+                android:clickable="true"
+                android:focusable="true"
+                android:background="@drawable/notification_guts_priority_button_bg"
+                android:orientation="vertical">
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:gravity="center"
+                >
+                    <ImageView
+                        android:id="@+id/priority_icon"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:src="@drawable/ic_important_outline"
+                        android:background="@android:color/transparent"
+                        android:tint="@color/notification_guts_priority_contents"
+                        android:clickable="false"
+                        android:focusable="false"/>
+                    <TextView
+                        android:id="@+id/priority_label"
+                        android:layout_width="0dp"
+                        android:layout_height="wrap_content"
+                        android:layout_marginStart="@dimen/notification_importance_drawable_padding"
+                        android:layout_weight="1"
+                        android:ellipsize="end"
+                        android:maxLines="1"
+                        android:clickable="false"
+                        android:focusable="false"
+                        android:textAppearance="@style/TextAppearance.NotificationImportanceButton"
+                        android:text="@string/notification_priority_title"/>
+                </LinearLayout>
+                <TextView
+                    android:id="@+id/priority_summary"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="@dimen/notification_importance_button_description_top_margin"
+                    android:visibility="gone"
+                    android:text="@string/notification_channel_summary_priority"
+                    android:clickable="false"
+                    android:focusable="false"
+                    android:ellipsize="end"
+                    android:maxLines="2"
+                    android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"/>
+            </com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
 
-        <View
-            android:layout_width="match_parent"
-            android:layout_height="0.5dp"
-            android:background="@color/GM2_grey_300" />
-        <Button
-            android:id="@+id/home"
-            android:layout_height="@dimen/notification_guts_conversation_action_height"
-            android:layout_width="match_parent"
-            style="?android:attr/borderlessButtonStyle"
-            android:text="@string/notification_conversation_home_screen"
-            android:gravity="left|center_vertical"
-            android:drawableStart="@drawable/ic_add_to_home"
-            android:drawablePadding="@dimen/notification_guts_conversation_action_text_padding_start"
-            android:drawableTint="@color/notification_guts_link_icon_tint"/>
+            <com.android.systemui.statusbar.notification.row.ButtonLinearLayout
+                android:id="@+id/default_behavior"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/notification_importance_button_separation"
+                android:padding="@dimen/notification_importance_button_padding"
+                android:clickable="true"
+                android:focusable="true"
+                android:background="@drawable/notification_guts_priority_button_bg"
+                android:orientation="vertical">
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:gravity="center"
+                >
+                    <ImageView
+                        android:id="@+id/default_icon"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:src="@drawable/ic_notifications_alert"
+                        android:background="@android:color/transparent"
+                        android:tint="@color/notification_guts_priority_contents"
+                        android:clickable="false"
+                        android:focusable="false"/>
+                    <TextView
+                        android:id="@+id/default_label"
+                        android:layout_width="0dp"
+                        android:layout_height="wrap_content"
+                        android:layout_marginStart="@dimen/notification_importance_drawable_padding"
+                        android:layout_weight="1"
+                        android:ellipsize="end"
+                        android:maxLines="1"
+                        android:clickable="false"
+                        android:focusable="false"
+                        android:textAppearance="@style/TextAppearance.NotificationImportanceButton"
+                        android:text="@string/notification_alert_title"/>
+                </LinearLayout>
+                <TextView
+                    android:id="@+id/default_summary"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="@dimen/notification_importance_button_description_top_margin"
+                    android:visibility="gone"
+                    android:text="@string/notification_channel_summary_default"
+                    android:clickable="false"
+                    android:focusable="false"
+                    android:ellipsize="end"
+                    android:maxLines="2"
+                    android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"/>
+            </com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
 
-        <View
-            android:layout_width="match_parent"
-            android:layout_height="0.5dp"
-            android:background="@color/GM2_grey_300" />
-
-        <Button
-            android:id="@+id/info"
-            android:layout_height="@dimen/notification_guts_conversation_action_height"
-            android:layout_width="match_parent"
-            style="?android:attr/borderlessButtonStyle"
-            android:drawableStart="@drawable/ic_settings"
-            android:text="@string/notification_menu_settings_action"
-            android:gravity="left|center_vertical"
-            android:drawablePadding="@dimen/notification_guts_conversation_action_text_padding_start"
-            android:drawableTint="@color/notification_guts_link_icon_tint"/>
+            <com.android.systemui.statusbar.notification.row.ButtonLinearLayout
+                android:id="@+id/silence"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/notification_importance_button_separation"
+                android:padding="@dimen/notification_importance_button_padding"
+                android:clickable="true"
+                android:focusable="true"
+                android:background="@drawable/notification_guts_priority_button_bg"
+                android:orientation="vertical">
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:gravity="center"
+                >
+                    <ImageView
+                        android:id="@+id/silence_icon"
+                        android:src="@drawable/ic_notifications_silence"
+                        android:background="@android:color/transparent"
+                        android:tint="@color/notification_guts_priority_contents"
+                        android:layout_gravity="center"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:clickable="false"
+                        android:focusable="false"/>
+                    <TextView
+                        android:id="@+id/silence_label"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:ellipsize="end"
+                        android:maxLines="1"
+                        android:clickable="false"
+                        android:focusable="false"
+                        android:layout_toEndOf="@id/silence_icon"
+                        android:layout_marginStart="@dimen/notification_importance_drawable_padding"
+                        android:textAppearance="@style/TextAppearance.NotificationImportanceButton"
+                        android:text="@string/notification_silence_title"/>
+                </LinearLayout>
+                <TextView
+                    android:id="@+id/silence_summary"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="@dimen/notification_importance_button_description_top_margin"
+                    android:visibility="gone"
+                    android:text="@string/notification_channel_summary_low"
+                    android:clickable="false"
+                    android:focusable="false"
+                    android:ellipsize="end"
+                    android:maxLines="2"
+                    android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"/>
+            </com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
 
         </LinearLayout>
 
+        <RelativeLayout
+            android:id="@+id/bottom_buttons"
+            android:layout_width="match_parent"
+            android:layout_height="60dp"
+            android:gravity="center_vertical"
+            android:paddingStart="4dp"
+            android:paddingEnd="4dp"
+        >
+            <TextView
+                android:id="@+id/done"
+                android:text="@string/inline_ok_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentEnd="true"
+                android:gravity="end|center_vertical"
+                android:minWidth="@dimen/notification_importance_toggle_size"
+                android:minHeight="@dimen/notification_importance_toggle_size"
+                style="@style/TextAppearance.NotificationInfo.Button"/>
+        </RelativeLayout>
+    </LinearLayout>
+
 </com.android.systemui.statusbar.notification.row.NotificationConversationInfo>
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 6ab573b..73b711d 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -52,8 +52,7 @@
             android:layout_centerVertical="true"
             android:gravity="center_vertical"
             android:layout_alignEnd="@id/pkg_icon"
-            android:layout_toEndOf="@id/pkg_icon"
-            android:layout_alignStart="@id/mute">
+            android:layout_toEndOf="@id/pkg_icon">
             <TextView
                 android:id="@+id/channel_name"
                 android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 52074e2d..f71c0b3 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1819,6 +1819,18 @@
     <!-- [CHAR LIMIT=150] Notification Importance title: bubble level summary -->
     <string name="notification_channel_summary_bubble">Keeps your attention with a floating shortcut to this content.</string>
 
+    <!-- [CHAR LIMIT=150] Notification Importance title: important conversation level summary -->
+    <string name="notification_channel_summary_priority">Shows at top of conversation section and appears as a bubble.</string>
+
+    <!--[CHAR LIMIT=150] Conversation inline controls footer shown when all conversations from the app are allowed to show as bubbles -->
+    <string name="notification_conversation_channel_all_bubble">All conversations from <xliff:g id="app_name" example="YouTube">%1$s</xliff:g> bubble by default. Manage in <xliff:g id="app_name" example="Settings">%2$s</xliff:g>.</string>
+
+    <!--[CHAR LIMIT=30] Linkable text to Settings app -->
+    <string name="notification_conversation_channel_settings">Settings</string>
+
+    <!-- [CHAR LIMIT=150] Notification Importance title: important conversation level -->
+    <string name="notification_priority_title">Priority</string>
+
     <!-- [CHAR LIMIT=NONE] Empty overflow title -->
     <string name="bubble_overflow_empty_title">No recent bubbles</string>
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
index 164215b..b57b22f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
@@ -50,7 +50,9 @@
                         if (endRunnable != null) {
                             endRunnable.run();
                         }
-                        view.setVisibility(View.INVISIBLE);
+                        if (view.getVisibility() != View.GONE) {
+                            view.setVisibility(View.INVISIBLE);
+                        }
                     }
                 });
         if (view.hasOverlappingRendering()) {
@@ -75,7 +77,7 @@
      */
     public static void fadeOut(View view, float fadeOutAmount, boolean remap) {
         view.animate().cancel();
-        if (fadeOutAmount == 1.0f) {
+        if (fadeOutAmount == 1.0f && view.getVisibility() != View.GONE) {
             view.setVisibility(View.INVISIBLE);
         } else if (view.getVisibility() == View.INVISIBLE) {
             view.setVisibility(View.VISIBLE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
index 4759d56..ba3db09 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
@@ -28,6 +28,7 @@
 import android.widget.TextView;
 
 import com.android.internal.util.ContrastColorUtil;
+import com.android.internal.widget.ConversationLayout;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationContentView;
 
@@ -42,6 +43,7 @@
 
     private static final TextViewComparator sTextViewComparator = new TextViewComparator();
     private static final VisibilityApplicator sVisibilityApplicator = new VisibilityApplicator();
+    private static final VisibilityApplicator sAppNameApplicator = new AppNameApplicator();
     private static  final DataExtractor sIconExtractor = new DataExtractor() {
         @Override
         public Object extractData(ExpandableNotificationRow row) {
@@ -64,7 +66,7 @@
     };
     private final static ResultApplicator mGreyApplicator = new ResultApplicator() {
         @Override
-        public void apply(View view, boolean apply) {
+        public void apply(View parent, View view, boolean apply, boolean reset) {
             NotificationHeaderView header = (NotificationHeaderView) view;
             ImageView icon = (ImageView) view.findViewById(
                     com.android.internal.R.id.icon);
@@ -132,8 +134,12 @@
                     }
                 },
                 sVisibilityApplicator));
-        mComparators.add(HeaderProcessor.forTextView(mRow,
-                com.android.internal.R.id.app_name_text));
+        mComparators.add(new HeaderProcessor(
+                mRow,
+                com.android.internal.R.id.app_name_text,
+                null,
+                sTextViewComparator,
+                sAppNameApplicator));
         mComparators.add(HeaderProcessor.forTextView(mRow,
                 com.android.internal.R.id.header_text));
         mDividers.add(com.android.internal.R.id.header_text_divider);
@@ -299,19 +305,19 @@
         public void apply(ExpandableNotificationRow row, boolean reset) {
             boolean apply = mApply && !reset;
             if (row.isSummaryWithChildren()) {
-                applyToView(apply, row.getNotificationHeader());
+                applyToView(apply, reset, row.getNotificationHeader());
                 return;
             }
-            applyToView(apply, row.getPrivateLayout().getContractedChild());
-            applyToView(apply, row.getPrivateLayout().getHeadsUpChild());
-            applyToView(apply, row.getPrivateLayout().getExpandedChild());
+            applyToView(apply, reset, row.getPrivateLayout().getContractedChild());
+            applyToView(apply, reset, row.getPrivateLayout().getHeadsUpChild());
+            applyToView(apply, reset, row.getPrivateLayout().getExpandedChild());
         }
 
-        private void applyToView(boolean apply, View parent) {
+        private void applyToView(boolean apply, boolean reset, View parent) {
             if (parent != null) {
                 View view = parent.findViewById(mId);
                 if (view != null && !mComparator.isEmpty(view)) {
-                    mApplicator.apply(view, apply);
+                    mApplicator.apply(parent, view, apply, reset);
                 }
             }
         }
@@ -375,14 +381,26 @@
     }
 
     private interface ResultApplicator {
-        void apply(View view, boolean apply);
+        void apply(View parent, View view, boolean apply, boolean reset);
     }
 
     private static class VisibilityApplicator implements ResultApplicator {
 
         @Override
-        public void apply(View view, boolean apply) {
+        public void apply(View parent, View view, boolean apply, boolean reset) {
             view.setVisibility(apply ? View.GONE : View.VISIBLE);
         }
     }
+
+    private static class AppNameApplicator extends VisibilityApplicator {
+
+        @Override
+        public void apply(View parent, View view, boolean apply, boolean reset) {
+            if (reset && parent instanceof ConversationLayout) {
+                ConversationLayout layout = (ConversationLayout) parent;
+                apply = layout.shouldHideAppName();
+            }
+            super.apply(parent, view, apply, reset);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java
index 2a45bc2..83e51cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java
@@ -49,6 +49,14 @@
         mTransformedViews.put(key, transformedView);
     }
 
+    public void addTransformedView(View transformedView) {
+        int key = transformedView.getId();
+        if (key == View.NO_ID) {
+            throw new IllegalArgumentException("View argument does not have a valid id");
+        }
+        addTransformedView(key, transformedView);
+    }
+
     /**
      * Add a view that transforms to a similar sibling, meaning that we should consider any mapping
      * found treated as the same viewType. This is useful for imageViews, where it's hard to compare
@@ -62,6 +70,14 @@
         mKeysTransformingToSimilar.add(key);
     }
 
+    public void addViewTransformingToSimilar(View transformedView) {
+        int key = transformedView.getId();
+        if (key == View.NO_ID) {
+            throw new IllegalArgumentException("View argument does not have a valid id");
+        }
+        addViewTransformingToSimilar(key, transformedView);
+    }
+
     public void reset() {
         mTransformedViews.clear();
         mKeysTransformingToSimilar.clear();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java
index a3fb225..2ee2153 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java
@@ -82,7 +82,7 @@
             float startActualWidth = getStartActualWidth();
             mImageMessage.setActualWidth(
                     (int) NotificationUtils.interpolate(startActualWidth,
-                            mImageMessage.getStaticWidth(),
+                            mImageMessage.getWidth(),
                             interpolatedValue));
             float startActualHeight = getStartActualHeight();
             mImageMessage.setActualHeight(
@@ -121,7 +121,7 @@
     @Override
     protected void resetTransformedView() {
         super.resetTransformedView();
-        mImageMessage.setActualWidth(mImageMessage.getStaticWidth());
+        mImageMessage.setActualWidth(mImageMessage.getWidth());
         mImageMessage.setActualHeight(mImageMessage.getHeight());
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java
index 9383f53..5ee4693 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java
@@ -102,11 +102,11 @@
             MessagingGroup matchingGroup = pairs.get(ownGroup);
             if (!isGone(ownGroup)) {
                 if (matchingGroup != null) {
-                    transformGroups(ownGroup, matchingGroup, transformationAmount, to);
+                    int totalTranslation = transformGroups(ownGroup, matchingGroup,
+                            transformationAmount, to);
                     if (lastPairedGroup == null) {
                         lastPairedGroup = ownGroup;
                         if (to){
-                            float totalTranslation = ownGroup.getTop() - matchingGroup.getTop();
                             currentTranslation = matchingGroup.getAvatar().getTranslationY()
                                     - totalTranslation;
                         } else {
@@ -229,14 +229,19 @@
         return result;
     }
 
-    private void transformGroups(MessagingGroup ownGroup, MessagingGroup otherGroup,
+    /**
+     * Transform two groups towards each other.
+     *
+     * @return the total transformation distance that the group goes through
+     */
+    private int transformGroups(MessagingGroup ownGroup, MessagingGroup otherGroup,
             float transformationAmount, boolean to) {
         boolean useLinearTransformation =
                 otherGroup.getIsolatedMessage() == null && !mTransformInfo.isAnimating();
         transformView(transformationAmount, to, ownGroup.getSenderView(), otherGroup.getSenderView(),
                 true /* sameAsAny */, useLinearTransformation);
-        transformView(transformationAmount, to, ownGroup.getAvatar(), otherGroup.getAvatar(),
-                true /* sameAsAny */, useLinearTransformation);
+        int totalAvatarTranslation = transformView(transformationAmount, to, ownGroup.getAvatar(),
+                otherGroup.getAvatar(), true /* sameAsAny */, useLinearTransformation);
         List<MessagingMessage> ownMessages = ownGroup.getMessages();
         List<MessagingMessage> otherMessages = otherGroup.getMessages();
         float previousTranslation = 0;
@@ -245,6 +250,7 @@
             if (isGone(child)) {
                 continue;
             }
+            float messageAmount = transformationAmount;
             int otherIndex = otherMessages.size() - 1 - i;
             View otherChild = null;
             if (otherIndex >= 0) {
@@ -257,18 +263,19 @@
                 // Let's fade out as we approach the top of the screen. We can only do this if
                 // we're actually moving up
                 float distanceToTop = child.getTop() + child.getHeight() + previousTranslation;
-                transformationAmount = distanceToTop / child.getHeight();
-                transformationAmount = Math.max(0.0f, Math.min(1.0f, transformationAmount));
+                messageAmount = distanceToTop / child.getHeight();
+                messageAmount = Math.max(0.0f, Math.min(1.0f, messageAmount));
                 if (to) {
-                    transformationAmount = 1.0f - transformationAmount;
+                    messageAmount = 1.0f - messageAmount;
                 }
             }
-            transformView(transformationAmount, to, child, otherChild, false, /* sameAsAny */
-                    useLinearTransformation);
+            int totalTranslation = transformView(messageAmount, to, child, otherChild,
+                    false /* sameAsAny */, useLinearTransformation);
             boolean otherIsIsolated = otherGroup.getIsolatedMessage() == otherChild;
-            if (transformationAmount == 0.0f
+            if (messageAmount == 0.0f
                     && (otherIsIsolated || otherGroup.isSingleLine())) {
                 ownGroup.setClippingDisabled(true);
+                mMessagingLayout.setMessagingClippingDisabled(true);
             }
             if (otherChild == null) {
                 child.setTranslationY(previousTranslation);
@@ -276,23 +283,28 @@
             } else if (ownGroup.getIsolatedMessage() == child || otherIsIsolated) {
                 // We don't want to add any translation for the image that is transforming
             } else if (to) {
-                float totalTranslation = child.getTop() + ownGroup.getTop()
-                        - otherChild.getTop() - otherChild.getTop();
                 previousTranslation = otherChild.getTranslationY() - totalTranslation;
             } else {
                 previousTranslation = child.getTranslationY();
             }
         }
         ownGroup.updateClipRect();
+        return totalAvatarTranslation;
     }
 
-    private void transformView(float transformationAmount, boolean to, View ownView,
+    /**
+     * Transform a view to another view.
+     *
+     * @return the total translationY this view goes through
+     */
+    private int transformView(float transformationAmount, boolean to, View ownView,
             View otherView, boolean sameAsAny, boolean useLinearTransformation) {
         TransformState ownState = TransformState.createFrom(ownView, mTransformInfo);
         if (useLinearTransformation) {
             ownState.setDefaultInterpolator(Interpolators.LINEAR);
         }
         ownState.setIsSameAsAnyView(sameAsAny && !isGone(otherView));
+        int totalTranslationDistance = 0;
         if (to) {
             if (otherView != null) {
                 TransformState otherState = TransformState.createFrom(otherView, mTransformInfo);
@@ -306,6 +318,8 @@
                     // since avatars serve as anchors for the rest of the layout transition
                     ownState.transformViewVerticalTo(otherState, transformationAmount);
                 }
+                totalTranslationDistance = ownState.getLaidOutLocationOnScreen()[1]
+                        - otherState.getLaidOutLocationOnScreen()[1];
                 otherState.recycle();
             } else {
                 ownState.disappear(transformationAmount, null);
@@ -323,12 +337,15 @@
                     // since avatars serve as anchors for the rest of the layout transition
                     ownState.transformViewVerticalFrom(otherState, transformationAmount);
                 }
+                totalTranslationDistance = ownState.getLaidOutLocationOnScreen()[1]
+                        - otherState.getLaidOutLocationOnScreen()[1];
                 otherState.recycle();
             } else {
                 ownState.appear(transformationAmount, null);
             }
         }
         ownState.recycle();
+        return totalTranslationDistance;
     }
 
     private HashMap<MessagingGroup, MessagingGroup> findPairs(ArrayList<MessagingGroup> ownGroups,
@@ -362,6 +379,9 @@
         if (view.getVisibility() == View.GONE) {
             return true;
         }
+        if (view.getParent() == null) {
+            return true;
+        }
         final ViewGroup.LayoutParams lp = view.getLayoutParams();
         if (lp instanceof MessagingLinearLayout.LayoutParams
                 && ((MessagingLinearLayout.LayoutParams) lp).hide) {
@@ -433,6 +453,7 @@
             ownGroup.setClippingDisabled(false);
             ownGroup.updateClipRect();
         }
+        mMessagingLayout.setMessagingClippingDisabled(false);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
index 337f312..82fb491 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
@@ -100,7 +100,7 @@
         transformViewFullyFrom(otherState, transformationAmount);
     }
 
-    protected void ensureVisible() {
+    public void ensureVisible() {
         if (mTransformedView.getVisibility() == View.INVISIBLE
                 || mTransformedView.getAlpha() != 1.0f) {
             // We have the same content, lets show ourselves
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
index 8674047..1d5c289 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
@@ -78,12 +78,6 @@
         val aPersonType = a.getPeopleNotificationType()
         val bPersonType = b.getPeopleNotificationType()
 
-        val aIsPeople = aPersonType == TYPE_PERSON
-        val bIsPeople = bPersonType == TYPE_PERSON
-
-        val aIsImportantPeople = aPersonType == TYPE_IMPORTANT_PERSON
-        val bIsImportantPeople = bPersonType == TYPE_IMPORTANT_PERSON
-
         val aMedia = isImportantMedia(a)
         val bMedia = isImportantMedia(b)
 
@@ -100,9 +94,14 @@
             aHeadsUp != bHeadsUp -> if (aHeadsUp) -1 else 1
             // Provide consistent ranking with headsUpManager
             aHeadsUp -> headsUpManager.compare(a, b)
-            usePeopleFiltering && aIsPeople != bIsPeople -> if (aIsPeople) -1 else 1
-            usePeopleFiltering && aIsImportantPeople != bIsImportantPeople ->
-                if (aIsImportantPeople) -1 else 1
+            usePeopleFiltering && aPersonType != bPersonType -> when (aPersonType) {
+                TYPE_IMPORTANT_PERSON -> -1
+                TYPE_PERSON -> when (bPersonType) {
+                    TYPE_IMPORTANT_PERSON -> 1
+                    else -> -1
+                }
+                else -> 1
+            }
             // Upsort current media notification.
             aMedia != bMedia -> if (aMedia) -1 else 1
             // Upsort PRIORITY_MAX system notifications
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index 1088cdc3..8e2bfb8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -20,11 +20,10 @@
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
-import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_CACHED;
-import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC;
-import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED;
 import static android.provider.Settings.Secure.BUBBLE_IMPORTANT_CONVERSATIONS;
 
+import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN;
+
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import android.annotation.IntDef;
@@ -36,7 +35,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager;
@@ -49,6 +47,10 @@
 import android.provider.Settings;
 import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
+import android.transition.ChangeBounds;
+import android.transition.Fade;
+import android.transition.TransitionManager;
+import android.transition.TransitionSet;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Slog;
@@ -65,13 +67,10 @@
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.phone.ShadeController;
 
 import java.lang.annotation.Retention;
-import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -83,11 +82,9 @@
 
 
     private INotificationManager mINotificationManager;
-    private LauncherApps mLauncherApps;
     ShortcutManager mShortcutManager;
     private PackageManager mPm;
     private VisualStabilityManager mVisualStabilityManager;
-    private ShadeController mShadeController;
     private ConversationIconFactory mIconFactory;
 
     private String mPackageName;
@@ -97,44 +94,34 @@
     private NotificationChannel mNotificationChannel;
     private ShortcutInfo mShortcutInfo;
     private String mConversationId;
-    private NotificationEntry mEntry;
     private StatusBarNotification mSbn;
     private boolean mIsDeviceProvisioned;
-    private boolean mStartedAsBubble;
-    private boolean mIsBubbleable;
 
+    private TextView mPriorityDescriptionView;
+    private TextView mDefaultDescriptionView;
+    private TextView mSilentDescriptionView;
     private @Action int mSelectedAction = -1;
 
     private OnSnoozeClickListener mOnSnoozeClickListener;
     private OnSettingsClickListener mOnSettingsClickListener;
     private NotificationGuts mGutsContainer;
-    private BubbleController mBubbleController;
 
     @VisibleForTesting
     boolean mSkipPost = false;
 
     @Retention(SOURCE)
-    @IntDef({ACTION_BUBBLE, ACTION_HOME, ACTION_FAVORITE, ACTION_SNOOZE, ACTION_MUTE,
-            ACTION_UNBUBBLE, ACTION_SETTINGS})
+    @IntDef({ACTION_DEFAULT, ACTION_HOME, ACTION_FAVORITE, ACTION_SNOOZE, ACTION_MUTE,
+            ACTION_SETTINGS})
     private @interface Action {}
-    static final int ACTION_BUBBLE = 0;
+    static final int ACTION_DEFAULT = 0;
     static final int ACTION_HOME = 1;
     static final int ACTION_FAVORITE = 2;
     static final int ACTION_SNOOZE = 3;
     static final int ACTION_MUTE = 4;
     static final int ACTION_SETTINGS = 5;
-    static final int ACTION_UNBUBBLE = 6;
 
-    private OnClickListener mOnBubbleClick = v -> {
-        mSelectedAction = mStartedAsBubble ? ACTION_UNBUBBLE : ACTION_BUBBLE;
-        if (mStartedAsBubble) {
-            mBubbleController.onUserDemotedBubbleFromNotification(mEntry);
-        } else {
-            mBubbleController.onUserCreatedBubbleFromNotification(mEntry);
-        }
-        closeControls(v, true);
-    };
-
+    // TODO: b/152050825
+    /*
     private OnClickListener mOnHomeClick = v -> {
         mSelectedAction = ACTION_HOME;
         mShortcutManager.requestPinShortcut(mShortcutInfo, null);
@@ -142,21 +129,30 @@
         closeControls(v, true);
     };
 
-    private OnClickListener mOnFavoriteClick = v -> {
-        mSelectedAction = ACTION_FAVORITE;
-        updateChannel();
-
-    };
-
     private OnClickListener mOnSnoozeClick = v -> {
         mSelectedAction = ACTION_SNOOZE;
         mOnSnoozeClickListener.onClick(v, 1);
         closeControls(v, true);
     };
+    */
+
+    private OnClickListener mOnFavoriteClick = v -> {
+        mSelectedAction = ACTION_FAVORITE;
+        updateToggleActions(mSelectedAction, true);
+    };
+
+    private OnClickListener mOnDefaultClick = v -> {
+        mSelectedAction = ACTION_DEFAULT;
+        updateToggleActions(mSelectedAction, true);
+    };
 
     private OnClickListener mOnMuteClick = v -> {
         mSelectedAction = ACTION_MUTE;
-        updateChannel();
+        updateToggleActions(mSelectedAction, true);
+    };
+
+    private OnClickListener mOnDone = v -> {
+        closeControls(v, true);
     };
 
     public NotificationConversationInfo(Context context, AttributeSet attrs) {
@@ -177,7 +173,6 @@
 
     public void bindNotification(
             ShortcutManager shortcutManager,
-            LauncherApps launcherApps,
             PackageManager pm,
             INotificationManager iNotificationManager,
             VisualStabilityManager visualStabilityManager,
@@ -185,16 +180,13 @@
             NotificationChannel notificationChannel,
             NotificationEntry entry,
             OnSettingsClickListener onSettingsClick,
-            OnAppSettingsClickListener onAppSettingsClick,
             OnSnoozeClickListener onSnoozeClickListener,
             ConversationIconFactory conversationIconFactory,
             boolean isDeviceProvisioned) {
         mSelectedAction = -1;
         mINotificationManager = iNotificationManager;
         mVisualStabilityManager = visualStabilityManager;
-        mBubbleController = Dependency.get(BubbleController.class);
         mPackageName = pkg;
-        mEntry = entry;
         mSbn = entry.getSbn();
         mPm = pm;
         mAppName = mPackageName;
@@ -204,11 +196,9 @@
         mDelegatePkg = mSbn.getOpPkg();
         mIsDeviceProvisioned = isDeviceProvisioned;
         mOnSnoozeClickListener = onSnoozeClickListener;
-        mShadeController = Dependency.get(ShadeController.class);
         mIconFactory = conversationIconFactory;
 
         mShortcutManager = shortcutManager;
-        mLauncherApps = launcherApps;
         mConversationId = mNotificationChannel.getConversationId();
         if (TextUtils.isEmpty(mNotificationChannel.getConversationId())) {
             mConversationId = mSbn.getShortcutId(mContext);
@@ -218,16 +208,13 @@
         }
         mShortcutInfo = entry.getRanking().getShortcutInfo();
 
-        mIsBubbleable = mEntry.getBubbleMetadata() != null
-            && Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.NOTIFICATION_BUBBLES, 0) == 1;
-        mStartedAsBubble = mEntry.isBubble();
-
         createConversationChannelIfNeeded();
 
         bindHeader();
         bindActions();
 
+        View done = findViewById(R.id.done);
+        done.setOnClickListener(mOnDone);
     }
 
     void createConversationChannelIfNeeded() {
@@ -252,37 +239,28 @@
     }
 
     private void bindActions() {
-        // TODO: figure out what should happen for non-configurable channels
 
-        Button bubble = findViewById(R.id.bubble);
-        bubble.setVisibility(mIsBubbleable ? VISIBLE : GONE);
-        bubble.setOnClickListener(mOnBubbleClick);
-        if (mStartedAsBubble) {
-            bubble.setText(R.string.notification_conversation_unbubble);
-        } else {
-            bubble.setText(R.string.notification_conversation_bubble);
-        }
-
+        // TODO: b/152050825
+        /*
         Button home = findViewById(R.id.home);
         home.setOnClickListener(mOnHomeClick);
         home.setVisibility(mShortcutInfo != null
                 && mShortcutManager.isRequestPinShortcutSupported()
                 ? VISIBLE : GONE);
 
-        View favorite = findViewById(R.id.fave);
-        favorite.setOnClickListener(mOnFavoriteClick);
-
         Button snooze = findViewById(R.id.snooze);
         snooze.setOnClickListener(mOnSnoozeClick);
+        */
 
-        View mute = findViewById(R.id.mute);
-        mute.setOnClickListener(mOnMuteClick);
+        findViewById(R.id.priority).setOnClickListener(mOnFavoriteClick);
+        findViewById(R.id.default_behavior).setOnClickListener(mOnDefaultClick);
+        findViewById(R.id.silence).setOnClickListener(mOnMuteClick);
 
         final View settingsButton = findViewById(R.id.info);
         settingsButton.setOnClickListener(getSettingsOnClickListener());
         settingsButton.setVisibility(settingsButton.hasOnClickListeners() ? VISIBLE : GONE);
 
-        updateToggleActions();
+        updateToggleActions(getSelectedAction(), false);
     }
 
     private void bindHeader() {
@@ -310,16 +288,16 @@
         // TODO: bring back when channel name does not include name
         // bindName();
         bindPackage();
-        bindIcon();
+        bindIcon(mNotificationChannel.isImportantConversation());
 
     }
 
-    private void bindIcon() {
+    private void bindIcon(boolean important) {
         ImageView image = findViewById(R.id.conversation_icon);
         if (mShortcutInfo != null) {
             image.setImageDrawable(mIconFactory.getConversationDrawable(
                     mShortcutInfo, mPackageName, mAppUid,
-                    mNotificationChannel.isImportantConversation()));
+                    important));
         } else {
             if (mSbn.getNotification().extras.getBoolean(EXTRA_IS_GROUP_CONVERSATION, false)) {
                 // TODO: maybe use a generic group icon, or a composite of recent senders
@@ -378,11 +356,6 @@
         ((TextView) findViewById(R.id.pkg_name)).setText(mAppName);
     }
 
-    private boolean bubbleImportantConversations() {
-        return Settings.Secure.getInt(mContext.getContentResolver(),
-                BUBBLE_IMPORTANT_CONVERSATIONS, 1) == 1;
-    }
-
     private void bindDelegate() {
         TextView delegateView = findViewById(R.id.delegate_name);
 
@@ -431,6 +404,15 @@
     }
 
     @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        mPriorityDescriptionView = findViewById(R.id.priority_summary);
+        mDefaultDescriptionView = findViewById(R.id.default_summary);
+        mSilentDescriptionView = findViewById(R.id.silence_summary);
+    }
+
+    @Override
     public void onFinishedClosing() {
         // TODO: do we need to do anything here?
     }
@@ -450,32 +432,84 @@
         }
     }
 
-    private void updateToggleActions() {
-        ImageButton favorite = findViewById(R.id.fave);
-        if (mNotificationChannel.isImportantConversation()) {
-            favorite.setContentDescription(
-                    mContext.getString(R.string.notification_conversation_favorite));
-            favorite.setImageResource(R.drawable.ic_important);
-        } else {
-            favorite.setContentDescription(
-                    mContext.getString(R.string.notification_conversation_unfavorite));
-            favorite.setImageResource(R.drawable.ic_important_outline);
+    private void updateToggleActions(int selectedAction, boolean userTriggered) {
+        if (userTriggered) {
+            TransitionSet transition = new TransitionSet();
+            transition.setOrdering(TransitionSet.ORDERING_TOGETHER);
+            transition.addTransition(new Fade(Fade.OUT))
+                    .addTransition(new ChangeBounds())
+                    .addTransition(
+                            new Fade(Fade.IN)
+                                    .setStartDelay(150)
+                                    .setDuration(200)
+                                    .setInterpolator(FAST_OUT_SLOW_IN));
+            transition.setDuration(350);
+            transition.setInterpolator(FAST_OUT_SLOW_IN);
+            TransitionManager.beginDelayedTransition(this, transition);
         }
 
-        ImageButton mute = findViewById(R.id.mute);
-        if (mNotificationChannel.getImportance() >= IMPORTANCE_DEFAULT
-                || mNotificationChannel.getImportance() == IMPORTANCE_UNSPECIFIED) {
-            mute.setContentDescription(
-                    mContext.getString(R.string.notification_conversation_unmute));
-            mute.setImageResource(R.drawable.ic_notifications_alert);
-        } else {
-            mute.setContentDescription(
-                    mContext.getString(R.string.notification_conversation_mute));
-            mute.setImageResource(R.drawable.ic_notifications_silence);
+        View priority = findViewById(R.id.priority);
+        View defaultBehavior = findViewById(R.id.default_behavior);
+        View silence = findViewById(R.id.silence);
+
+        switch (selectedAction) {
+            case ACTION_FAVORITE:
+                mPriorityDescriptionView.setVisibility(VISIBLE);
+                mDefaultDescriptionView.setVisibility(GONE);
+                mSilentDescriptionView.setVisibility(GONE);
+                post(() -> {
+                    priority.setSelected(true);
+                    defaultBehavior.setSelected(false);
+                    silence.setSelected(false);
+                });
+                break;
+
+            case ACTION_MUTE:
+                mSilentDescriptionView.setVisibility(VISIBLE);
+                mDefaultDescriptionView.setVisibility(GONE);
+                mPriorityDescriptionView.setVisibility(GONE);
+                post(() -> {
+                    priority.setSelected(false);
+                    defaultBehavior.setSelected(false);
+                    silence.setSelected(true);
+                });
+                break;
+
+            case ACTION_DEFAULT:
+                mDefaultDescriptionView.setVisibility(VISIBLE);
+                mSilentDescriptionView.setVisibility(GONE);
+                mPriorityDescriptionView.setVisibility(GONE);
+                post(() -> {
+                    priority.setSelected(false);
+                    defaultBehavior.setSelected(true);
+                    silence.setSelected(false);
+                });
+                break;
+
+            default:
+                throw new IllegalArgumentException("Unrecognized behavior: " + mSelectedAction);
         }
 
+        boolean isAChange = getSelectedAction() != selectedAction;
+        TextView done = findViewById(R.id.done);
+        done.setText(isAChange
+                ? R.string.inline_ok_button
+                : R.string.inline_done_button);
+
         // update icon in case importance has changed
-        bindIcon();
+        bindIcon(selectedAction == ACTION_FAVORITE);
+    }
+
+    int getSelectedAction() {
+        if (mNotificationChannel.getImportance() <= IMPORTANCE_LOW
+                && mNotificationChannel.getImportance() > IMPORTANCE_UNSPECIFIED) {
+            return ACTION_MUTE;
+        } else {
+            if (mNotificationChannel.isImportantConversation()) {
+                return ACTION_FAVORITE;
+            }
+        }
+        return ACTION_DEFAULT;
     }
 
     private void updateChannel() {
@@ -517,11 +551,7 @@
 
     @Override
     public boolean shouldBeSaved() {
-        // Toggle actions are already saved by the time the guts are closed; save for any other
-        // taps
-        return mSelectedAction > -1
-                && mSelectedAction != ACTION_FAVORITE
-                && mSelectedAction != ACTION_MUTE;
+        return mSelectedAction == ACTION_FAVORITE || mSelectedAction == ACTION_MUTE;
     }
 
     @Override
@@ -568,45 +598,41 @@
         @Override
         public void run() {
             try {
-                boolean channelSettingChanged = mAction != ACTION_HOME && mAction != ACTION_SNOOZE;
                 switch (mAction) {
-                    case ACTION_BUBBLE:
-                    case ACTION_UNBUBBLE:
-                        boolean canBubble = mAction == ACTION_BUBBLE;
-                        if (mChannelToUpdate.canBubble() != canBubble) {
-                            channelSettingChanged = true;
-                            mChannelToUpdate.setAllowBubbles(canBubble);
-                        } else {
-                            channelSettingChanged = false;
-                        }
-                        break;
                     case ACTION_FAVORITE:
                         mChannelToUpdate.setImportantConversation(
                                 !mChannelToUpdate.isImportantConversation());
-                        if (mChannelToUpdate.isImportantConversation()
-                                && bubbleImportantConversations()) {
+                        if (mChannelToUpdate.isImportantConversation()) {
                             mChannelToUpdate.setAllowBubbles(true);
                         }
+                        mChannelToUpdate.setImportance(Math.max(
+                                mChannelToUpdate.getOriginalImportance(), IMPORTANCE_DEFAULT));
+                        break;
+                    case ACTION_DEFAULT:
+                        mChannelToUpdate.setImportance(Math.max(
+                                mChannelToUpdate.getOriginalImportance(), IMPORTANCE_DEFAULT));
+                        if (mChannelToUpdate.isImportantConversation()) {
+                            mChannelToUpdate.setImportantConversation(false);
+                            mChannelToUpdate.setAllowBubbles(false);
+                        }
                         break;
                     case ACTION_MUTE:
                         if (mChannelToUpdate.getImportance() == IMPORTANCE_UNSPECIFIED
                                 || mChannelToUpdate.getImportance() >= IMPORTANCE_DEFAULT) {
                             mChannelToUpdate.setImportance(IMPORTANCE_LOW);
-                        } else {
-                            mChannelToUpdate.setImportance(Math.max(
-                                    mChannelToUpdate.getOriginalImportance(), IMPORTANCE_DEFAULT));
+                        }
+                        if (mChannelToUpdate.isImportantConversation()) {
+                            mChannelToUpdate.setImportantConversation(false);
+                            mChannelToUpdate.setAllowBubbles(false);
                         }
                         break;
                 }
 
-                if (channelSettingChanged) {
-                    mINotificationManager.updateNotificationChannelForPackage(
+                mINotificationManager.updateNotificationChannelForPackage(
                             mAppPkg, mAppUid, mChannelToUpdate);
-                }
             } catch (RemoteException e) {
                 Log.e(TAG, "Unable to update notification channel", e);
             }
-            ThreadUtils.postOnMainThread(() -> updateToggleActions());
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 1d7d611..2487d1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -394,7 +394,6 @@
 
         notificationInfoView.bindNotification(
                 mShortcutManager,
-                mLauncherApps,
                 pmUser,
                 mNotificationManager,
                 mVisualStabilityManager,
@@ -402,7 +401,6 @@
                 row.getEntry().getChannel(),
                 row.getEntry(),
                 onSettingsClick,
-                onAppSettingsClick,
                 onSnoozeClickListener,
                 iconFactoryLoader,
                 mDeviceProvisionedController.isDeviceProvisioned());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
index 162786c..91a2e7c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
@@ -18,47 +18,56 @@
 
 import android.content.Context
 import android.view.View
-
+import android.view.ViewGroup
 import com.android.internal.widget.ConversationLayout
 import com.android.internal.widget.MessagingLinearLayout
 import com.android.systemui.R
+import com.android.systemui.statusbar.TransformableView
+import com.android.systemui.statusbar.ViewTransformationHelper
 import com.android.systemui.statusbar.notification.NotificationUtils
+import com.android.systemui.statusbar.notification.TransformState
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.row.HybridNotificationView
 
 /**
- * Wraps a notification containing a converation template
+ * Wraps a notification containing a conversation template
  */
 class NotificationConversationTemplateViewWrapper constructor(
     ctx: Context,
     view: View,
     row: ExpandableNotificationRow
-)
-    : NotificationTemplateViewWrapper(ctx, view, row) {
+) : NotificationTemplateViewWrapper(ctx, view, row) {
 
-    private val minHeightWithActions: Int
-    private val conversationLayout: ConversationLayout
-    private var conversationIcon: View? = null
-    private var conversationBadge: View? = null
-    private var expandButton: View? = null
+    private val minHeightWithActions: Int = NotificationUtils.getFontScaledHeight(
+            ctx,
+            R.dimen.notification_messaging_actions_min_height
+    )
+    private val conversationLayout: ConversationLayout = view as ConversationLayout
+
+    private lateinit var conversationIcon: View
+    private lateinit var conversationBadgeBg: View
+    private lateinit var expandButton: View
     private lateinit var expandButtonContainer: View
-    private var messagingLinearLayout: MessagingLinearLayout? = null
-
-    init {
-        conversationLayout = view as ConversationLayout
-        minHeightWithActions = NotificationUtils.getFontScaledHeight(ctx,
-                R.dimen.notification_messaging_actions_min_height)
-    }
+    private lateinit var imageMessageContainer: ViewGroup
+    private lateinit var messagingLinearLayout: MessagingLinearLayout
+    private lateinit var conversationTitle: View
+    private lateinit var importanceRing: View
+    private lateinit var appName: View
 
     private fun resolveViews() {
         messagingLinearLayout = conversationLayout.messagingLinearLayout
-        conversationIcon = conversationLayout.requireViewById(
-                com.android.internal.R.id.conversation_icon)
-        conversationBadge = conversationLayout.requireViewById(
-                com.android.internal.R.id.conversation_icon_badge)
-        expandButton = conversationLayout.requireViewById(
-                com.android.internal.R.id.expand_button)
-        expandButtonContainer = conversationLayout.requireViewById(
-                com.android.internal.R.id.expand_button_container)
+        imageMessageContainer = conversationLayout.imageMessageContainer
+        with(conversationLayout) {
+            conversationIcon = requireViewById(com.android.internal.R.id.conversation_icon)
+            conversationBadgeBg =
+                    requireViewById(com.android.internal.R.id.conversation_icon_badge_bg)
+            expandButton = requireViewById(com.android.internal.R.id.expand_button)
+            expandButtonContainer =
+                    requireViewById(com.android.internal.R.id.expand_button_container)
+            importanceRing = requireViewById(com.android.internal.R.id.conversation_icon_badge_ring)
+            appName = requireViewById(com.android.internal.R.id.app_name_text)
+            conversationTitle = requireViewById(com.android.internal.R.id.conversation_text)
+        }
     }
 
     override fun onContentUpdated(row: ExpandableNotificationRow) {
@@ -71,41 +80,69 @@
     override fun updateTransformedTypes() {
         // This also clears the existing types
         super.updateTransformedTypes()
-        messagingLinearLayout?.let {
-            mTransformationHelper.addTransformedView(it.id, it)
-        }
-        conversationIcon?.let {
-            mTransformationHelper.addViewTransformingToSimilar(it.id, it)
-        }
-        conversationBadge?.let {
-            mTransformationHelper.addViewTransformingToSimilar(it.id, it)
-        }
-        expandButton?.let {
-            mTransformationHelper.addViewTransformingToSimilar(it.id, it)
-        }
+
+        addTransformedViews(
+                messagingLinearLayout,
+                appName,
+                conversationTitle)
+
+        // Let's ignore the image message container since that is transforming as part of the
+        // messages already
+        mTransformationHelper.setCustomTransformation(
+                object : ViewTransformationHelper.CustomTransformation() {
+                    override fun transformTo(
+                        ownState: TransformState,
+                        otherView: TransformableView,
+                        transformationAmount: Float
+                    ): Boolean {
+                        if (otherView is HybridNotificationView) {
+                            return false
+                        }
+                        // we're hidden by default by the transformState
+                        ownState.ensureVisible()
+                        // Let's do nothing otherwise, this is already handled by the messages
+                        return true
+                    }
+
+                    override fun transformFrom(
+                        ownState: TransformState,
+                        otherView: TransformableView,
+                        transformationAmount: Float
+                    ): Boolean =
+                            transformTo(ownState, otherView, transformationAmount)
+                },
+                imageMessageContainer.id
+        )
+
+        addViewsTransformingToSimilar(
+                conversationIcon,
+                conversationBadgeBg,
+                expandButton,
+                importanceRing
+        )
     }
 
-    override fun setRemoteInputVisible(visible: Boolean) {
-        conversationLayout.showHistoricMessages(visible)
-    }
+    override fun setRemoteInputVisible(visible: Boolean) =
+            conversationLayout.showHistoricMessages(visible)
 
-    override fun updateExpandability(expandable: Boolean, onClickListener: View.OnClickListener?) {
-        conversationLayout.updateExpandability(expandable, onClickListener)
-    }
+    override fun updateExpandability(expandable: Boolean, onClickListener: View.OnClickListener?) =
+            conversationLayout.updateExpandability(expandable, onClickListener)
 
     override fun disallowSingleClick(x: Float, y: Float): Boolean {
-        if (expandButtonContainer.visibility == View.VISIBLE
-                && isOnView(expandButtonContainer, x, y)) {
-            return true
-        }
-        return super.disallowSingleClick(x, y)
+        val isOnExpandButton = expandButtonContainer.visibility == View.VISIBLE &&
+                isOnView(expandButtonContainer, x, y)
+        return isOnExpandButton || super.disallowSingleClick(x, y)
     }
 
-    override fun getMinLayoutHeight(): Int {
-        if (mActionsContainer != null && mActionsContainer.visibility != View.GONE) {
-            return minHeightWithActions
-        } else {
-            return super.getMinLayoutHeight()
-        }
-    }
+    override fun getMinLayoutHeight(): Int =
+            if (mActionsContainer != null && mActionsContainer.visibility != View.GONE)
+                minHeightWithActions
+            else
+                super.getMinLayoutHeight()
+
+    private fun addTransformedViews(vararg vs: View) =
+            vs.forEach(mTransformationHelper::addTransformedView)
+
+    private fun addViewsTransformingToSimilar(vararg vs: View) =
+            vs.forEach(mTransformationHelper::addViewTransformingToSimilar)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index 1d06198..a44ad3d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -132,11 +132,6 @@
         updateCropToPaddingForImageViews();
         Notification notification = row.getEntry().getSbn().getNotification();
         mIcon.setTag(ImageTransformState.ICON_TAG, notification.getSmallIcon());
-        if (mWorkProfileImage != null) {
-            // The work profile image is always the same lets just set the icon tag for it not to
-            // animate
-            mWorkProfileImage.setTag(ImageTransformState.ICON_TAG, notification.getSmallIcon());
-        }
 
         // We need to reset all views that are no longer transforming in case a view was previously
         // transformed, but now we decided to transform its container instead.
@@ -183,6 +178,7 @@
         mTransformationHelper.reset();
         mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_ICON,
                 mIcon);
+        mTransformationHelper.addViewTransformingToSimilar(mWorkProfileImage);
         if (mIsLowPriority && mHeaderText != null) {
             mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TITLE,
                     mHeaderText);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
index cdf0f2d..a2599ec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
@@ -42,7 +42,6 @@
 import dagger.Lazy
 import junit.framework.Assert.assertEquals
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mockito.mock
@@ -194,7 +193,6 @@
         assertEquals(listOf(b, a), rankingManager.updateRanking(null, listOf(a, b), "test"))
     }
 
-    @Ignore // TODO: (b/149046729) fix test and re-enable
     @Test
     fun testSort_importantPeople() {
         whenever(sectionsManager.isFilteringEnabled()).thenReturn(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index 2e3a57a..6998edd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -26,6 +26,8 @@
 import static android.view.View.GONE;
 import static android.view.View.VISIBLE;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
@@ -223,7 +225,6 @@
     public void testBindNotification_SetsShortcutIcon() {
         mNotificationInfo.bindNotification(
                 mShortcutManager,
-                mLauncherApps,
                 mMockPackageManager,
                 mMockINotificationManager,
                 mVisualStabilityManager,
@@ -232,7 +233,6 @@
                 mEntry,
                 null,
                 null,
-                null,
                 mIconFactory,
                 true);
         final ImageView view = mNotificationInfo.findViewById(R.id.conversation_icon);
@@ -244,7 +244,6 @@
         when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
         mNotificationInfo.bindNotification(
                 mShortcutManager,
-                mLauncherApps,
                 mMockPackageManager,
                 mMockINotificationManager,
                 mVisualStabilityManager,
@@ -253,7 +252,6 @@
                 mEntry,
                 null,
                 null,
-                null,
                 mIconFactory,
                 true);
         final TextView textView = mNotificationInfo.findViewById(R.id.pkg_name);
@@ -291,7 +289,6 @@
 
         mNotificationInfo.bindNotification(
                 mShortcutManager,
-                mLauncherApps,
                 mMockPackageManager,
                 mMockINotificationManager,
                 mVisualStabilityManager,
@@ -300,7 +297,6 @@
                 mEntry,
                 null,
                 null,
-                null,
                 mIconFactory,
                 true);
         final TextView textView = mNotificationInfo.findViewById(R.id.group_name);
@@ -314,7 +310,6 @@
     public void testBindNotification_GroupNameHiddenIfNoGroup() {
         mNotificationInfo.bindNotification(
                 mShortcutManager,
-                mLauncherApps,
                 mMockPackageManager,
                 mMockINotificationManager,
                 mVisualStabilityManager,
@@ -323,7 +318,6 @@
                 mEntry,
                 null,
                 null,
-                null,
                 mIconFactory,
                 true);
         final TextView textView = mNotificationInfo.findViewById(R.id.group_name);
@@ -336,7 +330,6 @@
     public void testBindNotification_noDelegate() {
         mNotificationInfo.bindNotification(
                 mShortcutManager,
-                mLauncherApps,
                 mMockPackageManager,
                 mMockINotificationManager,
                 mVisualStabilityManager,
@@ -345,7 +338,6 @@
                 mEntry,
                 null,
                 null,
-                null,
                 mIconFactory,
                 true);
         final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
@@ -365,7 +357,6 @@
         NotificationEntry entry = new NotificationEntryBuilder().setSbn(mSbn).build();
         mNotificationInfo.bindNotification(
                 mShortcutManager,
-                mLauncherApps,
                 mMockPackageManager,
                 mMockINotificationManager,
                 mVisualStabilityManager,
@@ -374,7 +365,6 @@
                 entry,
                 null,
                 null,
-                null,
                 mIconFactory,
                 true);
         final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
@@ -387,7 +377,6 @@
         final CountDownLatch latch = new CountDownLatch(1);
         mNotificationInfo.bindNotification(
                 mShortcutManager,
-                mLauncherApps,
                 mMockPackageManager,
                 mMockINotificationManager,
                 mVisualStabilityManager,
@@ -399,7 +388,6 @@
                     latch.countDown();
                 },
                 null,
-                null,
                 mIconFactory,
                 true);
 
@@ -413,7 +401,6 @@
     public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() {
         mNotificationInfo.bindNotification(
                 mShortcutManager,
-                mLauncherApps,
                 mMockPackageManager,
                 mMockINotificationManager,
                 mVisualStabilityManager,
@@ -422,7 +409,6 @@
                 mEntry,
                 null,
                 null,
-                null,
                 mIconFactory,
                 true);
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
@@ -434,7 +420,6 @@
         final CountDownLatch latch = new CountDownLatch(1);
         mNotificationInfo.bindNotification(
                 mShortcutManager,
-                mLauncherApps,
                 mMockPackageManager,
                 mMockINotificationManager,
                 mVisualStabilityManager,
@@ -446,7 +431,6 @@
                     latch.countDown();
                 },
                 null,
-                null,
                 mIconFactory,
                 false);
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
@@ -454,380 +438,11 @@
     }
 
     @Test
-    public void testBindNotification_bubbleActionVisibleWhenCanBubble()  {
-        Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mLauncherApps,
-                mMockPackageManager,
-                mMockINotificationManager,
-                mVisualStabilityManager,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mBubbleEntry,
-                null,
-                null,
-                null,
-                mIconFactory,
-                true);
-
-        View bubbleView = mNotificationInfo.findViewById(R.id.bubble);
-        assertEquals(View.VISIBLE, bubbleView.getVisibility());
-    }
-
-    @Test
-    public void testBindNotification_bubbleAction_noBubbleMetadata()  {
-        Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mLauncherApps,
-                mMockPackageManager,
-                mMockINotificationManager,
-                mVisualStabilityManager,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                null,
-                mIconFactory,
-                true);
-
-        View bubbleView = mNotificationInfo.findViewById(R.id.bubble);
-        assertEquals(View.GONE, bubbleView.getVisibility());
-    }
-
-    @Test
-    public void testBindNotification_bubbleActionGloballyOff()  {
-        Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 0);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mLauncherApps,
-                mMockPackageManager,
-                mMockINotificationManager,
-                mVisualStabilityManager,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mBubbleEntry,
-                null,
-                null,
-                null,
-                mIconFactory,
-                true);
-
-        View bubbleView = mNotificationInfo.findViewById(R.id.bubble);
-        assertEquals(View.GONE, bubbleView.getVisibility());
-    }
-
-    @Test
-    public void testAddToHome() throws Exception {
-        when(mShortcutManager.isRequestPinShortcutSupported()).thenReturn(true);
-
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mLauncherApps,
-                mMockPackageManager,
-                mMockINotificationManager,
-                mVisualStabilityManager,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mBubbleEntry,
-                null,
-                null,
-                null,
-                mIconFactory,
-                true);
-
-        // Promote it
-        mNotificationInfo.findViewById(R.id.home).performClick();
-        mTestableLooper.processAllMessages();
-
-        verify(mShortcutManager, times(1)).requestPinShortcut(mShortcutInfo, null);
-        verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
-                anyString(), anyInt(), any());
-        verify(mShadeController).animateCollapsePanels();
-    }
-
-    @Test
-    public void testSnooze() throws Exception {
-        final CountDownLatch latch = new CountDownLatch(1);
-
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mLauncherApps,
-                mMockPackageManager,
-                mMockINotificationManager,
-                mVisualStabilityManager,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mBubbleEntry,
-                null,
-                null,
-                (View v, int hours) -> {
-                    latch.countDown();
-                },
-                mIconFactory,
-                true);
-
-        // Promote it
-        mNotificationInfo.findViewById(R.id.snooze).performClick();
-        mTestableLooper.processAllMessages();
-
-        assertEquals(0, latch.getCount());
-        verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
-                anyString(), anyInt(), any());
-    }
-
-    @Test
-    public void testBubble_promotesBubble() throws Exception {
-        Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
-        mNotificationChannel.setAllowBubbles(false);
-        mConversationChannel.setAllowBubbles(false);
-
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mLauncherApps,
-                mMockPackageManager,
-                mMockINotificationManager,
-                mVisualStabilityManager,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mBubbleEntry,
-                null,
-                null,
-                null,
-                mIconFactory,
-                true);
-
-        assertFalse(mBubbleEntry.isBubble());
-
-        // Promote it
-        mNotificationInfo.findViewById(R.id.bubble).performClick();
-        mTestableLooper.processAllMessages();
-
-        verify(mBubbleController, times(1)).onUserCreatedBubbleFromNotification(mBubbleEntry);
-        ArgumentCaptor<NotificationChannel> captor =
-                ArgumentCaptor.forClass(NotificationChannel.class);
-        verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
-                anyString(), anyInt(), captor.capture());
-        assertTrue(captor.getValue().canBubble());
-    }
-
-    @Test
-    public void testBubble_demotesBubble() throws Exception {
-        Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
-        mBubbleEntry.getSbn().getNotification().flags |= FLAG_BUBBLE;
-
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mLauncherApps,
-                mMockPackageManager,
-                mMockINotificationManager,
-                mVisualStabilityManager,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mBubbleEntry,
-                null,
-                null,
-                null,
-                mIconFactory,
-                true);
-
-        assertTrue(mBubbleEntry.isBubble());
-
-        // Demote it
-        mNotificationInfo.findViewById(R.id.bubble).performClick();
-        mTestableLooper.processAllMessages();
-
-        verify(mBubbleController, times(1)).onUserDemotedBubbleFromNotification(mBubbleEntry);
-        ArgumentCaptor<NotificationChannel> captor =
-                ArgumentCaptor.forClass(NotificationChannel.class);
-        verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
-                anyString(), anyInt(), captor.capture());
-        assertFalse(captor.getValue().canBubble());
-    }
-
-    @Test
-    public void testBubble_noChannelChange() throws Exception {
-        Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mLauncherApps,
-                mMockPackageManager,
-                mMockINotificationManager,
-                mVisualStabilityManager,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mBubbleEntry,
-                null,
-                null,
-                null,
-                mIconFactory,
-                true);
-
-        assertFalse(mBubbleEntry.isBubble());
-        assertTrue(mNotificationChannel.canBubble());
-
-        // Promote it
-        mNotificationInfo.findViewById(R.id.bubble).performClick();
-        mTestableLooper.processAllMessages();
-
-        verify(mBubbleController, times(1)).onUserCreatedBubbleFromNotification(mBubbleEntry);
-        verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
-                anyString(), anyInt(), any());
-    }
-
-    @Test
-    public void testFavorite_favorite_noBubble() throws Exception {
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                BUBBLE_IMPORTANT_CONVERSATIONS, 0);
-        mNotificationChannel.setAllowBubbles(false);
-        mConversationChannel.setAllowBubbles(false);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mLauncherApps,
-                mMockPackageManager,
-                mMockINotificationManager,
-                mVisualStabilityManager,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                null,
-                mIconFactory,
-                true);
-
-        ImageButton fave = mNotificationInfo.findViewById(R.id.fave);
-        assertEquals(mContext.getString(R.string.notification_conversation_unfavorite),
-                fave.getContentDescription().toString());
-
-        fave.performClick();
-        mTestableLooper.processAllMessages();
-
-        ArgumentCaptor<NotificationChannel> captor =
-                ArgumentCaptor.forClass(NotificationChannel.class);
-        verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
-                anyString(), anyInt(), captor.capture());
-        assertTrue(captor.getValue().isImportantConversation());
-        assertFalse(captor.getValue().canBubble());
-        verify(mBubbleController, never()).onUserCreatedBubbleFromNotification(mEntry);
-    }
-
-    @Test
-    public void testFavorite_favorite_bubble() throws Exception {
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                BUBBLE_IMPORTANT_CONVERSATIONS, 1);
-        mNotificationChannel.setAllowBubbles(false);
-        mConversationChannel.setAllowBubbles(false);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mLauncherApps,
-                mMockPackageManager,
-                mMockINotificationManager,
-                mVisualStabilityManager,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                null,
-                mIconFactory,
-                true);
-
-        ImageButton fave = mNotificationInfo.findViewById(R.id.fave);
-        assertEquals(mContext.getString(R.string.notification_conversation_unfavorite),
-                fave.getContentDescription().toString());
-
-        fave.performClick();
-        mTestableLooper.processAllMessages();
-
-        ArgumentCaptor<NotificationChannel> captor =
-                ArgumentCaptor.forClass(NotificationChannel.class);
-        verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
-                anyString(), anyInt(), captor.capture());
-        assertTrue(captor.getValue().isImportantConversation());
-        assertTrue(captor.getValue().canBubble());
-    }
-
-    @Test
-    public void testFavorite_unfavorite() throws Exception {
-        mNotificationChannel.setImportantConversation(true);
-        mConversationChannel.setImportantConversation(true);
-
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mLauncherApps,
-                mMockPackageManager,
-                mMockINotificationManager,
-                mVisualStabilityManager,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                null,
-                mIconFactory,
-                true);
-
-        ImageButton fave = mNotificationInfo.findViewById(R.id.fave);
-        assertEquals(mContext.getString(R.string.notification_conversation_favorite),
-                fave.getContentDescription().toString());
-
-        fave.performClick();
-        mTestableLooper.processAllMessages();
-
-        ArgumentCaptor<NotificationChannel> captor =
-                ArgumentCaptor.forClass(NotificationChannel.class);
-        verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
-                anyString(), anyInt(), captor.capture());
-        assertFalse(captor.getValue().isImportantConversation());
-    }
-
-    @Test
-    public void testMute_mute() throws Exception {
-        mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mConversationChannel.setImportance(IMPORTANCE_DEFAULT);
-
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mLauncherApps,
-                mMockPackageManager,
-                mMockINotificationManager,
-                mVisualStabilityManager,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                null,
-                mIconFactory,
-                true);
-
-        ImageButton mute = mNotificationInfo.findViewById(R.id.mute);
-        assertEquals(mContext.getString(R.string.notification_conversation_unmute),
-                mute.getContentDescription().toString());
-
-        mute.performClick();
-        mTestableLooper.processAllMessages();
-
-        ArgumentCaptor<NotificationChannel> captor =
-                ArgumentCaptor.forClass(NotificationChannel.class);
-        verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
-                anyString(), anyInt(), captor.capture());
-        assertEquals(IMPORTANCE_LOW, captor.getValue().getImportance());
-    }
-
-    @Test
-    public void testMute_unmute() throws Exception {
-        mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationChannel.setOriginalImportance(IMPORTANCE_HIGH);
+    public void testBindNotification_silentSelected_isFave_isSilent() {
         mConversationChannel.setImportance(IMPORTANCE_LOW);
-        mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
-
+        mConversationChannel.setImportantConversation(true);
         mNotificationInfo.bindNotification(
                 mShortcutManager,
-                mLauncherApps,
                 mMockPackageManager,
                 mMockINotificationManager,
                 mVisualStabilityManager,
@@ -836,15 +451,200 @@
                 mEntry,
                 null,
                 null,
+                mIconFactory,
+                true);
+        View view = mNotificationInfo.findViewById(R.id.silence);
+        assertThat(view.isSelected()).isTrue();
+    }
+
+    @Test
+    public void testBindNotification_defaultSelected_notFave_notSilent() {
+        mConversationChannel.setImportance(IMPORTANCE_HIGH);
+        mConversationChannel.setImportantConversation(false);
+        mConversationChannel.setAllowBubbles(true);
+        mNotificationInfo.bindNotification(
+                mShortcutManager,
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mEntry,
+                null,
+                null,
+                mIconFactory,
+                true);
+        View view = mNotificationInfo.findViewById(R.id.default_behavior);
+        assertThat(view.isSelected()).isTrue();
+    }
+
+    @Test
+    public void testFavorite() throws Exception {
+        mConversationChannel.setAllowBubbles(false);
+        mConversationChannel.setImportance(IMPORTANCE_LOW);
+        mConversationChannel.setImportantConversation(false);
+
+        mNotificationInfo.bindNotification(
+                mShortcutManager,
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mEntry,
+                null,
                 null,
                 mIconFactory,
                 true);
 
-        ImageButton mute = mNotificationInfo.findViewById(R.id.mute);
-        assertEquals(mContext.getString(R.string.notification_conversation_mute),
-                mute.getContentDescription().toString());
+        View fave = mNotificationInfo.findViewById(R.id.priority);
+        fave.performClick();
+        mTestableLooper.processAllMessages();
 
-        mute.performClick();
+        // silence subtext visible, others not
+        assertThat(mNotificationInfo.findViewById(R.id.priority_summary).getVisibility())
+                .isEqualTo(VISIBLE);
+        assertThat(mNotificationInfo.findViewById(R.id.default_summary).getVisibility())
+                .isEqualTo(GONE);
+        assertThat(mNotificationInfo.findViewById(R.id.silence_summary).getVisibility())
+                .isEqualTo(GONE);
+
+        // no changes until hit done
+        verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+                anyString(), anyInt(), any());
+        assertFalse(mConversationChannel.isImportantConversation());
+        assertFalse(mConversationChannel.canBubble());
+        assertEquals(IMPORTANCE_LOW, mConversationChannel.getImportance());
+    }
+
+    @Test
+    public void testDefault() throws Exception {
+        mConversationChannel.setAllowBubbles(false);
+        mConversationChannel.setImportance(IMPORTANCE_LOW);
+        mConversationChannel.setImportantConversation(false);
+        mNotificationInfo.bindNotification(
+                mShortcutManager,
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mEntry,
+                null,
+                null,
+                mIconFactory,
+                true);
+
+        mNotificationInfo.findViewById(R.id.default_behavior).performClick();
+        mTestableLooper.processAllMessages();
+
+        // silence subtext visible, others not
+        assertThat(mNotificationInfo.findViewById(R.id.priority_summary).getVisibility())
+                .isEqualTo(GONE);
+        assertThat(mNotificationInfo.findViewById(R.id.default_summary).getVisibility())
+                .isEqualTo(VISIBLE);
+        assertThat(mNotificationInfo.findViewById(R.id.silence_summary).getVisibility())
+                .isEqualTo(GONE);
+
+        // no changes until hit done
+        verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+                anyString(), anyInt(), any());
+        assertFalse(mConversationChannel.isImportantConversation());
+        assertFalse(mConversationChannel.canBubble());
+        assertEquals(IMPORTANCE_LOW, mConversationChannel.getImportance());
+    }
+
+    @Test
+    public void testSilence() throws Exception {
+        mConversationChannel.setImportance(IMPORTANCE_DEFAULT);
+        mConversationChannel.setImportantConversation(false);
+
+        mNotificationInfo.bindNotification(
+                mShortcutManager,
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mEntry,
+                null,
+                null,
+                mIconFactory,
+                true);
+
+        View silence = mNotificationInfo.findViewById(R.id.silence);
+
+        silence.performClick();
+        mTestableLooper.processAllMessages();
+
+        // silence subtext visible, others not
+        assertThat(mNotificationInfo.findViewById(R.id.priority_summary).getVisibility())
+                .isEqualTo(GONE);
+        assertThat(mNotificationInfo.findViewById(R.id.default_summary).getVisibility())
+                .isEqualTo(GONE);
+        assertThat(mNotificationInfo.findViewById(R.id.silence_summary).getVisibility())
+                .isEqualTo(VISIBLE);
+
+        // no changes until save
+        verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+                anyString(), anyInt(), any());
+        assertEquals(IMPORTANCE_DEFAULT, mConversationChannel.getImportance());
+    }
+
+    @Test
+    public void testFavorite_andSave() throws Exception {
+        mConversationChannel.setAllowBubbles(false);
+        mConversationChannel.setImportance(IMPORTANCE_LOW);
+        mConversationChannel.setImportantConversation(false);
+
+        mNotificationInfo.bindNotification(
+                mShortcutManager,
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mEntry,
+                null,
+                null,
+                mIconFactory,
+                true);
+
+        View fave = mNotificationInfo.findViewById(R.id.priority);
+        fave.performClick();
+        mNotificationInfo.findViewById(R.id.done).performClick();
+        mTestableLooper.processAllMessages();
+
+        ArgumentCaptor<NotificationChannel> captor =
+                ArgumentCaptor.forClass(NotificationChannel.class);
+        verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+                anyString(), anyInt(), captor.capture());
+        assertTrue(captor.getValue().isImportantConversation());
+        assertTrue(captor.getValue().canBubble());
+        assertEquals(IMPORTANCE_DEFAULT, captor.getValue().getImportance());
+    }
+
+    @Test
+    public void testFavorite_andSave_doesNotLowerImportance() throws Exception {
+        mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
+        mConversationChannel.setImportance(9);
+
+        mNotificationInfo.bindNotification(
+                mShortcutManager,
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mEntry,
+                null,
+                null,
+                mIconFactory,
+                true);
+
+        View fave = mNotificationInfo.findViewById(R.id.priority);
+        fave.performClick();
+        mNotificationInfo.findViewById(R.id.done).performClick();
         mTestableLooper.processAllMessages();
 
         ArgumentCaptor<NotificationChannel> captor =
@@ -855,10 +655,12 @@
     }
 
     @Test
-    public void testBindNotification_createsNewChannel() throws Exception {
+    public void testDefault_andSave() throws Exception {
+        mConversationChannel.setAllowBubbles(true);
+        mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
+        mConversationChannel.setImportantConversation(true);
         mNotificationInfo.bindNotification(
                 mShortcutManager,
-                mLauncherApps,
                 mMockPackageManager,
                 mMockINotificationManager,
                 mVisualStabilityManager,
@@ -867,6 +669,126 @@
                 mEntry,
                 null,
                 null,
+                mIconFactory,
+                true);
+
+        mNotificationInfo.findViewById(R.id.default_behavior).performClick();
+        mNotificationInfo.findViewById(R.id.done).performClick();
+        mTestableLooper.processAllMessages();
+
+        ArgumentCaptor<NotificationChannel> captor =
+                ArgumentCaptor.forClass(NotificationChannel.class);
+        verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+                anyString(), anyInt(), captor.capture());
+        assertFalse(captor.getValue().isImportantConversation());
+        assertFalse(captor.getValue().canBubble());
+        assertEquals(IMPORTANCE_HIGH, captor.getValue().getImportance());
+    }
+
+    @Test
+    public void testDefault_andSave_doesNotChangeNonImportantBubbling() throws Exception {
+        mConversationChannel.setAllowBubbles(true);
+        mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
+        mConversationChannel.setImportantConversation(false);
+        mNotificationInfo.bindNotification(
+                mShortcutManager,
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mEntry,
+                null,
+                null,
+                mIconFactory,
+                true);
+
+        mNotificationInfo.findViewById(R.id.default_behavior).performClick();
+        mNotificationInfo.findViewById(R.id.done).performClick();
+        mTestableLooper.processAllMessages();
+
+        ArgumentCaptor<NotificationChannel> captor =
+                ArgumentCaptor.forClass(NotificationChannel.class);
+        verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+                anyString(), anyInt(), captor.capture());
+        assertFalse(captor.getValue().isImportantConversation());
+        assertTrue(captor.getValue().canBubble());
+        assertEquals(IMPORTANCE_HIGH, captor.getValue().getImportance());
+    }
+
+    @Test
+    public void testDefault_andSave_doesNotDemoteImportance() throws Exception {
+        mConversationChannel.setImportance(9);
+        mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
+
+        mNotificationInfo.bindNotification(
+                mShortcutManager,
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mEntry,
+                null,
+                null,
+                mIconFactory,
+                true);
+
+        mNotificationInfo.findViewById(R.id.default_behavior).performClick();
+        mNotificationInfo.findViewById(R.id.done).performClick();
+        mTestableLooper.processAllMessages();
+
+        ArgumentCaptor<NotificationChannel> captor =
+                ArgumentCaptor.forClass(NotificationChannel.class);
+        verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+                anyString(), anyInt(), captor.capture());
+        assertEquals(IMPORTANCE_HIGH, captor.getValue().getImportance());
+    }
+
+    @Test
+    public void testSilence_andSave() throws Exception {
+        mConversationChannel.setImportance(IMPORTANCE_DEFAULT);
+        mConversationChannel.setImportantConversation(true);
+        mConversationChannel.setAllowBubbles(true);
+
+        mNotificationInfo.bindNotification(
+                mShortcutManager,
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mEntry,
+                null,
+                null,
+                mIconFactory,
+                true);
+
+        View silence = mNotificationInfo.findViewById(R.id.silence);
+        silence.performClick();
+        mNotificationInfo.findViewById(R.id.done).performClick();
+        mTestableLooper.processAllMessages();
+
+        ArgumentCaptor<NotificationChannel> captor =
+                ArgumentCaptor.forClass(NotificationChannel.class);
+        verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+                anyString(), anyInt(), captor.capture());
+        assertFalse(captor.getValue().isImportantConversation());
+        assertFalse(captor.getValue().canBubble());
+        assertEquals(IMPORTANCE_LOW, captor.getValue().getImportance());
+    }
+
+    @Test
+    public void testBindNotification_createsNewChannel() throws Exception {
+        mNotificationInfo.bindNotification(
+                mShortcutManager,
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mEntry,
+                null,
                 null,
                 mIconFactory,
                 true);
@@ -880,7 +802,6 @@
         mNotificationChannel.setConversationId("", CONVERSATION_ID);
         mNotificationInfo.bindNotification(
                 mShortcutManager,
-                mLauncherApps,
                 mMockPackageManager,
                 mMockINotificationManager,
                 mVisualStabilityManager,
@@ -889,7 +810,6 @@
                 mEntry,
                 null,
                 null,
-                null,
                 mIconFactory,
                 true);
 
@@ -903,7 +823,6 @@
         mConversationChannel.setImportance(IMPORTANCE_DEFAULT);
         mNotificationInfo.bindNotification(
                 mShortcutManager,
-                mLauncherApps,
                 mMockPackageManager,
                 mMockINotificationManager,
                 mVisualStabilityManager,
@@ -912,11 +831,13 @@
                 mEntry,
                 null,
                 null,
-                null,
                 mIconFactory,
                 true);
 
-        mNotificationInfo.findViewById(R.id.mute).performClick();
+        mNotificationInfo.findViewById(R.id.silence).performClick();
+        mNotificationInfo.findViewById(R.id.done).performClick();
+
+        mTestableLooper.processAllMessages();
 
         verify(mVisualStabilityManager).temporarilyAllowReordering();
     }
diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
index b4b0641..8b50b01 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
@@ -28,6 +28,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentSender;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.os.Bundle;
@@ -250,23 +251,31 @@
         final InlineSuggestionsResponse inlineSuggestionsResponse =
                 InlineSuggestionFactory.createAugmentedInlineSuggestionsResponse(
                         request, inlineSuggestionsData, focusedId,
-                        dataset -> {
-                            mCallbacks.logAugmentedAutofillSelected(sessionId,
-                                    dataset.getId());
-                            try {
-                                final ArrayList<AutofillId> fieldIds = dataset.getFieldIds();
-                                final int size = fieldIds.size();
-                                final boolean hideHighlight = size == 1
-                                        && fieldIds.get(0).equals(focusedId);
-                                if (dataset.getAuthentication() != null) {
-                                    client.startIntentSender(dataset.getAuthentication(),
-                                            new Intent());
-                                } else {
+                        new InlineSuggestionFactory.InlineSuggestionUiCallback() {
+                            @Override
+                            public void autofill(Dataset dataset) {
+                                mCallbacks.logAugmentedAutofillSelected(sessionId,
+                                        dataset.getId());
+                                try {
+                                    final ArrayList<AutofillId> fieldIds = dataset.getFieldIds();
+                                    final int size = fieldIds.size();
+                                    final boolean hideHighlight = size == 1
+                                            && fieldIds.get(0).equals(focusedId);
                                     client.autofill(sessionId, fieldIds, dataset.getFieldValues(),
                                             hideHighlight);
+                                } catch (RemoteException e) {
+                                    Slog.w(TAG, "Encounter exception autofilling the values");
                                 }
-                            } catch (RemoteException e) {
-                                Slog.w(TAG, "Encounter exception autofilling the values");
+                            }
+
+                            @Override
+                            public void startIntentSender(IntentSender intentSender,
+                                    Intent intent) {
+                                try {
+                                    client.startIntentSender(intentSender, intent);
+                                } catch (RemoteException e) {
+                                    Slog.w(TAG, "RemoteException starting intent sender");
+                                }
                             }
                         }, onErrorCallback, remoteRenderService);
 
diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
index c26d7ee..e98ac75 100644
--- a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
+++ b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
@@ -21,6 +21,8 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.Intent;
+import android.content.IntentSender;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.service.autofill.Dataset;
@@ -49,6 +51,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.BiConsumer;
+import java.util.function.Consumer;
 import java.util.regex.Pattern;
 
 public final class InlineSuggestionFactory {
@@ -62,6 +65,11 @@
          * Callback to autofill a dataset to the client app.
          */
         void autofill(@NonNull Dataset dataset);
+
+        /**
+         * Callback to start Intent in client app.
+         */
+        void startIntentSender(@NonNull IntentSender intentSender, @NonNull Intent intent);
     }
 
     /**
@@ -94,7 +102,8 @@
                 response.getAuthentication() == null ? null : response.getInlinePresentation();
         return createInlineSuggestionsResponseInternal(/* isAugmented= */ false, request,
                 response.getDatasets(), filterText, inlineAuthentication, autofillId,
-                onErrorCallback, onClickFactory, remoteRenderService);
+                onErrorCallback, onClickFactory, (intentSender) ->
+                        client.startIntentSender(intentSender, new Intent()), remoteRenderService);
     }
 
     /**
@@ -111,8 +120,12 @@
         if (sDebug) Slog.d(TAG, "createAugmentedInlineSuggestionsResponse called");
         return createInlineSuggestionsResponseInternal(/* isAugmented= */ true, request,
                 datasets, /* filterText= */ null, /* inlineAuthentication= */ null,
-                autofillId, onErrorCallback, (dataset, datasetIndex) ->
-                        inlineSuggestionUiCallback.autofill(dataset), remoteRenderService);
+                autofillId, onErrorCallback,
+                (dataset, datasetIndex) ->
+                        inlineSuggestionUiCallback.autofill(dataset),
+                (intentSender) ->
+                        inlineSuggestionUiCallback.startIntentSender(intentSender, new Intent()),
+                remoteRenderService);
     }
 
     @Nullable
@@ -121,12 +134,13 @@
             @Nullable List<Dataset> datasets, @Nullable String filterText,
             @Nullable InlinePresentation inlineAuthentication, @NonNull AutofillId autofillId,
             @NonNull Runnable onErrorCallback, @NonNull BiConsumer<Dataset, Integer> onClickFactory,
+            @NonNull Consumer<IntentSender> intentSenderConsumer,
             @Nullable RemoteInlineSuggestionRenderService remoteRenderService) {
 
         final ArrayList<InlineSuggestion> inlineSuggestions = new ArrayList<>();
         if (inlineAuthentication != null) {
             InlineSuggestion inlineAuthSuggestion = createInlineAuthSuggestion(inlineAuthentication,
-                    remoteRenderService, onClickFactory, onErrorCallback,
+                    remoteRenderService, onClickFactory, onErrorCallback, intentSenderConsumer,
                     request.getHostInputToken(), request.getHostDisplayId());
             inlineSuggestions.add(inlineAuthSuggestion);
 
@@ -157,7 +171,7 @@
             InlineSuggestion inlineSuggestion = createInlineSuggestion(isAugmented, dataset,
                     datasetIndex,
                     mergedInlinePresentation(request, datasetIndex, inlinePresentation),
-                    onClickFactory, remoteRenderService, onErrorCallback,
+                    onClickFactory, remoteRenderService, onErrorCallback, intentSenderConsumer,
                     request.getHostInputToken(), request.getHostDisplayId());
 
             inlineSuggestions.add(inlineSuggestion);
@@ -201,7 +215,8 @@
             @NonNull InlinePresentation inlinePresentation,
             @NonNull BiConsumer<Dataset, Integer> onClickFactory,
             @NonNull RemoteInlineSuggestionRenderService remoteRenderService,
-            @NonNull Runnable onErrorCallback, @Nullable IBinder hostInputToken,
+            @NonNull Runnable onErrorCallback, @NonNull Consumer<IntentSender> intentSenderConsumer,
+            @Nullable IBinder hostInputToken,
             int displayId) {
         final String suggestionSource = isAugmented ? InlineSuggestionInfo.SOURCE_PLATFORM
                 : InlineSuggestionInfo.SOURCE_AUTOFILL;
@@ -216,7 +231,7 @@
         final InlineSuggestion inlineSuggestion = new InlineSuggestion(inlineSuggestionInfo,
                 createInlineContentProvider(inlinePresentation,
                         () -> onClickFactory.accept(dataset, datasetIndex), onErrorCallback,
-                        remoteRenderService, hostInputToken, displayId));
+                        intentSenderConsumer, remoteRenderService, hostInputToken, displayId));
 
         return inlineSuggestion;
     }
@@ -225,6 +240,7 @@
             @NonNull InlinePresentation inlinePresentation,
             @NonNull RemoteInlineSuggestionRenderService remoteRenderService,
             @NonNull BiConsumer<Dataset, Integer> onClickFactory, @NonNull Runnable onErrorCallback,
+            @NonNull Consumer<IntentSender> intentSenderConsumer,
             @Nullable IBinder hostInputToken, int displayId) {
         final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
                 inlinePresentation.getInlinePresentationSpec(),
@@ -235,7 +251,8 @@
                 createInlineContentProvider(inlinePresentation,
                         () -> onClickFactory.accept(null,
                                 AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED),
-                        onErrorCallback, remoteRenderService, hostInputToken, displayId));
+                        onErrorCallback, intentSenderConsumer, remoteRenderService, hostInputToken,
+                        displayId));
     }
 
     /**
@@ -261,6 +278,7 @@
     private static IInlineContentProvider.Stub createInlineContentProvider(
             @NonNull InlinePresentation inlinePresentation, @Nullable Runnable onClickAction,
             @NonNull Runnable onErrorCallback,
+            @NonNull Consumer<IntentSender> intentSenderConsumer,
             @Nullable RemoteInlineSuggestionRenderService remoteRenderService,
             @Nullable IBinder hostInputToken,
             int displayId) {
@@ -269,7 +287,7 @@
             public void provideContent(int width, int height, IInlineContentCallback callback) {
                 UiThread.getHandler().post(() -> {
                     final IInlineSuggestionUiCallback uiCallback = createInlineSuggestionUiCallback(
-                            callback, onClickAction, onErrorCallback);
+                            callback, onClickAction, onErrorCallback, intentSenderConsumer);
 
                     if (remoteRenderService == null) {
                         Slog.e(TAG, "RemoteInlineSuggestionRenderService is null");
@@ -285,7 +303,8 @@
 
     private static IInlineSuggestionUiCallback.Stub createInlineSuggestionUiCallback(
             @NonNull IInlineContentCallback callback, @NonNull Runnable onAutofillCallback,
-            @NonNull Runnable onErrorCallback) {
+            @NonNull Runnable onErrorCallback,
+            @NonNull Consumer<IntentSender> intentSenderConsumer) {
         return new IInlineSuggestionUiCallback.Stub() {
             @Override
             public void onClick() throws RemoteException {
@@ -320,6 +339,11 @@
                     onErrorCallback.run();
                 }
             }
+
+            @Override
+            public void onStartIntentSender(IntentSender intentSender) {
+                intentSenderConsumer.accept(intentSender);
+            }
         };
     }
 
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index a767347..0bf81e0 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -682,6 +682,7 @@
     private static final int H_ABORT_IDLE_MAINT = 12;
     private static final int H_BOOT_COMPLETED = 13;
     private static final int H_COMPLETE_UNLOCK_USER = 14;
+    private static final int H_VOLUME_STATE_CHANGED = 15;
 
     class StorageManagerServiceHandler extends Handler {
         public StorageManagerServiceHandler(Looper looper) {
@@ -805,6 +806,11 @@
                     completeUnlockUser((int) msg.obj);
                     break;
                 }
+                case H_VOLUME_STATE_CHANGED: {
+                    final SomeArgs args = (SomeArgs) msg.obj;
+                    onVolumeStateChangedInternal((VolumeInfo) args.arg1, (int) args.arg2,
+                            (int) args.arg3);
+                }
             }
         }
     }
@@ -1323,7 +1329,11 @@
                     final int oldState = vol.state;
                     final int newState = state;
                     vol.state = newState;
-                    onVolumeStateChangedLocked(vol, oldState, newState);
+                    final SomeArgs args = SomeArgs.obtain();
+                    args.arg1 = vol;
+                    args.arg2 = oldState;
+                    args.arg3 = newState;
+                    mHandler.obtainMessage(H_VOLUME_STATE_CHANGED, args).sendToTarget();
                 }
             }
         }
@@ -1496,78 +1506,89 @@
         return true;
     }
 
-    @GuardedBy("mLock")
-    private void onVolumeStateChangedLocked(VolumeInfo vol, int oldState, int newState) {
-        if (vol.type == VolumeInfo.TYPE_EMULATED && newState != VolumeInfo.STATE_MOUNTED) {
-            mFuseMountedUser.remove(vol.getMountUserId());
-        }
-        // Remember that we saw this volume so we're ready to accept user
-        // metadata, or so we can annoy them when a private volume is ejected
-        if (!TextUtils.isEmpty(vol.fsUuid)) {
-            VolumeRecord rec = mRecords.get(vol.fsUuid);
-            if (rec == null) {
-                rec = new VolumeRecord(vol.type, vol.fsUuid);
-                rec.partGuid = vol.partGuid;
-                rec.createdMillis = System.currentTimeMillis();
-                if (vol.type == VolumeInfo.TYPE_PRIVATE) {
-                    rec.nickname = vol.disk.getDescription();
-                }
-                mRecords.put(rec.fsUuid, rec);
-            } else {
-                // Handle upgrade case where we didn't store partition GUID
-                if (TextUtils.isEmpty(rec.partGuid)) {
+    private void onVolumeStateChangedInternal(VolumeInfo vol, int oldState, int newState) {
+        synchronized (mLock) {
+            if (vol.type == VolumeInfo.TYPE_EMULATED && newState != VolumeInfo.STATE_MOUNTED) {
+                mFuseMountedUser.remove(vol.getMountUserId());
+            }
+            // Remember that we saw this volume so we're ready to accept user
+            // metadata, or so we can annoy them when a private volume is ejected
+            if (!TextUtils.isEmpty(vol.fsUuid)) {
+                VolumeRecord rec = mRecords.get(vol.fsUuid);
+                if (rec == null) {
+                    rec = new VolumeRecord(vol.type, vol.fsUuid);
                     rec.partGuid = vol.partGuid;
+                    rec.createdMillis = System.currentTimeMillis();
+                    if (vol.type == VolumeInfo.TYPE_PRIVATE) {
+                        rec.nickname = vol.disk.getDescription();
+                    }
+                    mRecords.put(rec.fsUuid, rec);
+                } else {
+                    // Handle upgrade case where we didn't store partition GUID
+                    if (TextUtils.isEmpty(rec.partGuid)) {
+                        rec.partGuid = vol.partGuid;
+                    }
+                }
+
+                rec.lastSeenMillis = System.currentTimeMillis();
+                writeSettingsLocked();
+            }
+        }
+        // This is a blocking call to Storage Service which needs to process volume state changed
+        // before notifying other listeners.
+        // Intentionally called without the mLock to avoid deadlocking from the Storage Service.
+        try {
+            mStorageSessionController.notifyVolumeStateChanged(vol);
+        } catch (ExternalStorageServiceException e) {
+            Log.e(TAG, "Failed to notify volume state changed to the Storage Service", e);
+        }
+        synchronized (mLock) {
+            mCallbacks.notifyVolumeStateChanged(vol, oldState, newState);
+
+            // Do not broadcast before boot has completed to avoid launching the
+            // processes that receive the intent unnecessarily.
+            if (mBootCompleted && isBroadcastWorthy(vol)) {
+                final Intent intent = new Intent(VolumeInfo.ACTION_VOLUME_STATE_CHANGED);
+                intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.id);
+                intent.putExtra(VolumeInfo.EXTRA_VOLUME_STATE, newState);
+                intent.putExtra(VolumeRecord.EXTRA_FS_UUID, vol.fsUuid);
+                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+                        | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+                mHandler.obtainMessage(H_INTERNAL_BROADCAST, intent).sendToTarget();
+            }
+
+            final String oldStateEnv = VolumeInfo.getEnvironmentForState(oldState);
+            final String newStateEnv = VolumeInfo.getEnvironmentForState(newState);
+
+            if (!Objects.equals(oldStateEnv, newStateEnv)) {
+                // Kick state changed event towards all started users. Any users
+                // started after this point will trigger additional
+                // user-specific broadcasts.
+                for (int userId : mSystemUnlockedUsers) {
+                    if (vol.isVisibleForRead(userId)) {
+                        final StorageVolume userVol = vol.buildStorageVolume(mContext, userId,
+                                false);
+                        mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget();
+
+                        mCallbacks.notifyStorageStateChanged(userVol.getPath(), oldStateEnv,
+                                newStateEnv);
+                    }
                 }
             }
 
-            rec.lastSeenMillis = System.currentTimeMillis();
-            writeSettingsLocked();
-        }
-
-        mCallbacks.notifyVolumeStateChanged(vol, oldState, newState);
-
-        // Do not broadcast before boot has completed to avoid launching the
-        // processes that receive the intent unnecessarily.
-        if (mBootCompleted && isBroadcastWorthy(vol)) {
-            final Intent intent = new Intent(VolumeInfo.ACTION_VOLUME_STATE_CHANGED);
-            intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.id);
-            intent.putExtra(VolumeInfo.EXTRA_VOLUME_STATE, newState);
-            intent.putExtra(VolumeRecord.EXTRA_FS_UUID, vol.fsUuid);
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
-                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
-            mHandler.obtainMessage(H_INTERNAL_BROADCAST, intent).sendToTarget();
-        }
-
-        final String oldStateEnv = VolumeInfo.getEnvironmentForState(oldState);
-        final String newStateEnv = VolumeInfo.getEnvironmentForState(newState);
-
-        if (!Objects.equals(oldStateEnv, newStateEnv)) {
-            // Kick state changed event towards all started users. Any users
-            // started after this point will trigger additional
-            // user-specific broadcasts.
-            for (int userId : mSystemUnlockedUsers) {
-                if (vol.isVisibleForRead(userId)) {
-                    final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, false);
-                    mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget();
-
-                    mCallbacks.notifyStorageStateChanged(userVol.getPath(), oldStateEnv,
-                            newStateEnv);
-                }
-            }
-        }
-
-        if ((vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_STUB)
+            if ((vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_STUB)
                     && vol.state == VolumeInfo.STATE_EJECTING) {
-            // TODO: this should eventually be handled by new ObbVolume state changes
-            /*
-             * Some OBBs might have been unmounted when this volume was
-             * unmounted, so send a message to the handler to let it know to
-             * remove those from the list of mounted OBBS.
-             */
-            mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(
-                    OBB_FLUSH_MOUNT_STATE, vol.path));
+                // TODO: this should eventually be handled by new ObbVolume state changes
+                /*
+                 * Some OBBs might have been unmounted when this volume was
+                 * unmounted, so send a message to the handler to let it know to
+                 * remove those from the list of mounted OBBS.
+                 */
+                mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(
+                        OBB_FLUSH_MOUNT_STATE, vol.path));
+            }
+            maybeLogMediaMount(vol, newState);
         }
-        maybeLogMediaMount(vol, newState);
     }
 
     private void maybeLogMediaMount(VolumeInfo vol, int newState) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 89e245c..b79f75a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -24660,15 +24660,6 @@
     }
 
     @Override
-    public void clearMimeGroup(String packageName, String mimeGroup) {
-        boolean changed = mSettings.mPackages.get(packageName).clearMimeGroup(mimeGroup);
-
-        if (changed) {
-            applyMimeGroupChanges(packageName, mimeGroup);
-        }
-    }
-
-    @Override
     public List<String> getMimeGroup(String packageName, String mimeGroup) {
         return mSettings.mPackages.get(packageName).getMimeGroup(mimeGroup);
     }
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index a83a847..9a8692d 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -241,7 +241,8 @@
     public boolean setMimeGroup(String mimeGroup, List<String> mimeTypes) {
         ArraySet<String> oldMimeTypes = getMimeGroupInternal(mimeGroup);
         if (oldMimeTypes == null) {
-            return false;
+            throw new IllegalArgumentException("Unknown MIME group " + mimeGroup
+                    + " for package " + name);
         }
 
         ArraySet<String> newMimeTypes = new ArraySet<>(mimeTypes);
@@ -250,21 +251,11 @@
         return hasChanges;
     }
 
-    public boolean clearMimeGroup(String mimeGroup) {
-        ArraySet<String> mimeTypes = getMimeGroupInternal(mimeGroup);
-
-        if (mimeTypes == null || mimeTypes.isEmpty()) {
-            return false;
-        }
-
-        mimeTypes.clear();
-        return true;
-    }
-
     public List<String> getMimeGroup(String mimeGroup) {
         ArraySet<String> mimeTypes = getMimeGroupInternal(mimeGroup);
         if (mimeTypes == null) {
-            return null;
+            throw new IllegalArgumentException("Unknown MIME group " + mimeGroup
+                    + " for package " + name);
         }
         return new ArrayList<>(mimeTypes);
     }
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index e3abcda..a726d39 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -125,7 +125,6 @@
 
 
     static {
-        PHONE_PERMISSIONS.add(Manifest.permission.READ_PHONE_STATE);
         PHONE_PERMISSIONS.add(Manifest.permission.CALL_PHONE);
         PHONE_PERMISSIONS.add(Manifest.permission.READ_CALL_LOG);
         PHONE_PERMISSIONS.add(Manifest.permission.WRITE_CALL_LOG);
diff --git a/services/core/java/com/android/server/storage/StorageSessionController.java b/services/core/java/com/android/server/storage/StorageSessionController.java
index baef5d6..0fd77b9c 100644
--- a/services/core/java/com/android/server/storage/StorageSessionController.java
+++ b/services/core/java/com/android/server/storage/StorageSessionController.java
@@ -106,6 +106,38 @@
     }
 
     /**
+     * Notifies the Storage Service that volume state for {@code vol} is changed.
+     * A session may already be created for this volume if it is mounted before or the volume state
+     * has changed to mounted.
+     *
+     * Does nothing if {@link #shouldHandle} is {@code false}
+     *
+     * Blocks until the Storage Service processes/scans the volume or fails in doing so.
+     *
+     * @throws ExternalStorageServiceException if it fails to connect to ExternalStorageService
+     */
+    public void notifyVolumeStateChanged(VolumeInfo vol) throws ExternalStorageServiceException {
+        if (!shouldHandle(vol)) {
+            return;
+        }
+        String sessionId = vol.getId();
+        int userId = vol.getMountUserId();
+
+        StorageUserConnection connection = null;
+        synchronized (mLock) {
+            connection = mConnections.get(userId);
+            if (connection != null) {
+                Slog.i(TAG, "Notifying volume state changed for session with id: " + sessionId);
+                connection.notifyVolumeStateChanged(sessionId,
+                        vol.buildStorageVolume(mContext, userId, false));
+            } else {
+                Slog.w(TAG, "No available storage user connection for userId : " + userId);
+            }
+        }
+    }
+
+
+    /**
      * Removes and returns the {@link StorageUserConnection} for {@code vol}.
      *
      * Does nothing if {@link #shouldHandle} is {@code false}
diff --git a/services/core/java/com/android/server/storage/StorageUserConnection.java b/services/core/java/com/android/server/storage/StorageUserConnection.java
index dd18f4e..c207a7b 100644
--- a/services/core/java/com/android/server/storage/StorageUserConnection.java
+++ b/services/core/java/com/android/server/storage/StorageUserConnection.java
@@ -35,6 +35,7 @@
 import android.os.RemoteCallback;
 import android.os.UserHandle;
 import android.os.storage.StorageManagerInternal;
+import android.os.storage.StorageVolume;
 import android.service.storage.ExternalStorageService;
 import android.service.storage.IExternalStorageService;
 import android.text.TextUtils;
@@ -100,6 +101,23 @@
     }
 
     /**
+     * Notifies Storage Service about volume state changed.
+     *
+     * @throws ExternalStorageServiceException if failed to notify the Storage Service that
+     * {@code StorageVolume} is changed
+     */
+    public void notifyVolumeStateChanged(String sessionId, StorageVolume vol)
+            throws ExternalStorageServiceException {
+        Objects.requireNonNull(sessionId);
+        Objects.requireNonNull(vol);
+
+        prepareRemote();
+        synchronized (mLock) {
+            mActiveConnection.notifyVolumeStateChangedLocked(sessionId, vol);
+        }
+    }
+
+    /**
      * Removes a session without ending it or waiting for exit.
      *
      * This should only be used if the session has certainly been ended because the volume was
@@ -287,6 +305,20 @@
             }
         }
 
+        public void notifyVolumeStateChangedLocked(String sessionId, StorageVolume vol) throws
+                ExternalStorageServiceException {
+            CountDownLatch latch = new CountDownLatch(1);
+            try {
+                mRemote.notifyVolumeStateChanged(sessionId, vol, new RemoteCallback(
+                        result -> setResultLocked(latch, result)));
+                waitForLatch(latch, "notify_volume_state_changed " + vol);
+                maybeThrowExceptionLocked();
+            } catch (Exception e) {
+                throw new ExternalStorageServiceException("Failed to notify volume state changed "
+                        + "for vol : " + vol, e);
+            }
+        }
+
         private void setResultLocked(CountDownLatch latch, Bundle result) {
             mLastException = result.getParcelable(EXTRA_ERROR);
             latch.countDown();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 3c0db09..fb079f3 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1918,7 +1918,6 @@
         super.onConfigurationChanged(newParentConfig);
         if (wasInMultiWindowMode != inMultiWindowMode()) {
             mStackSupervisor.scheduleUpdateMultiWindowMode(this);
-            updateShadowsRadius(isFocused(), getPendingTransaction());
         }
 
         final int newWinMode = getWindowingMode();
@@ -3325,6 +3324,7 @@
         }
 
         updateSurfaceCrop();
+        updateShadowsRadius(isFocused(), getPendingTransaction());
 
         if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) {
             scheduleAnimation();
@@ -4149,26 +4149,40 @@
     }
 
     /**
+     * @return true if the task is visible and has at least one visible child.
+     */
+    private boolean hasVisibleChildren() {
+        if (!isAttached() || isForceHidden()) {
+            return false;
+        }
+
+        return getActivity(ActivityRecord::isVisible) != null;
+    }
+
+    /**
      * @return the desired shadow radius in pixels for the current task.
      */
     private float getShadowRadius(boolean taskIsFocused) {
-        if (mDisplayContent == null) {
+        int elevation = 0;
+
+        // Get elevation for a specific windowing mode.
+        if (inPinnedWindowingMode()) {
+            elevation = PINNED_WINDOWING_MODE_ELEVATION_IN_DIP;
+        } else if (ENABLE_FREEFORM_COMPOSITOR_SHADOWS && inFreeformWindowingMode()) {
+            // TODO(b/149585281) remove when root task has the correct bounds for freeform
+            elevation = taskIsFocused
+                    ? DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP : DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
+        } else {
+            // For all other windowing modes, do not draw a shadow.
             return 0;
         }
 
-        if (inPinnedWindowingMode()) {
-            return dipToPixel(PINNED_WINDOWING_MODE_ELEVATION_IN_DIP,
-                    mDisplayContent.getDisplayMetrics());
-        }
-        // TODO(b/149585281) remove when root task has the correct bounds for freeform
-        if (ENABLE_FREEFORM_COMPOSITOR_SHADOWS && inFreeformWindowingMode()) {
-            final int elevation = taskIsFocused
-                    ? DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP : DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
-            return dipToPixel(elevation, mDisplayContent.getDisplayMetrics());
+        // If the task has no visible children, do not draw a shadow.
+        if (!hasVisibleChildren()) {
+            return 0;
         }
 
-        // For all other windowing modes, do not draw a shadow.
-        return 0;
+        return dipToPixel(elevation, getDisplayContent().getDisplayMetrics());
     }
 
     /**
diff --git a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
index 5f0c8fe3..725036c 100644
--- a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
+++ b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
@@ -51,7 +51,8 @@
 using FileIdx = int16_t;
 using BlockIdx = int32_t;
 using NumBlocks = int32_t;
-using CompressionType = int16_t;
+using BlockType = int8_t;
+using CompressionType = int8_t;
 using RequestType = int16_t;
 using MagicType = uint32_t;
 
@@ -59,7 +60,7 @@
 static constexpr int BLOCKS_COUNT = BUFFER_SIZE / INCFS_DATA_FILE_BLOCK_SIZE;
 
 static constexpr int COMMAND_SIZE = 4 + 2 + 2 + 4; // bytes
-static constexpr int HEADER_SIZE = 2 + 2 + 4 + 2;  // bytes
+static constexpr int HEADER_SIZE = 2 + 1 + 1 + 4 + 2; // bytes
 static constexpr std::string_view OKAY = "OKAY"sv;
 static constexpr MagicType INCR = 0x52434e49; // BE INCR
 
@@ -110,6 +111,7 @@
 
 struct BlockHeader {
     FileIdx fileIdx = -1;
+    BlockType blockType = -1;
     CompressionType compressionType = -1;
     BlockIdx blockIdx = -1;
     BlockSize blockSize = -1;
@@ -649,8 +651,8 @@
             auto remainingData = std::span(data);
             while (!remainingData.empty()) {
                 auto header = readHeader(remainingData);
-                if (header.fileIdx == -1 && header.compressionType == 0 && header.blockIdx == 0 &&
-                    header.blockSize == 0) {
+                if (header.fileIdx == -1 && header.blockType == 0 && header.compressionType == 0 &&
+                    header.blockIdx == 0 && header.blockSize == 0) {
                     ALOGI("Stop signal received. Sending exit command (remaining bytes: %d).",
                           int(remainingData.size()));
 
@@ -658,8 +660,8 @@
                     mStopReceiving = true;
                     break;
                 }
-                if (header.fileIdx < 0 || header.blockSize <= 0 || header.compressionType < 0 ||
-                    header.blockIdx < 0) {
+                if (header.fileIdx < 0 || header.blockSize <= 0 || header.blockType < 0 ||
+                    header.compressionType < 0 || header.blockIdx < 0) {
                     ALOGE("invalid header received. Abort.");
                     mStopReceiving = true;
                     break;
@@ -687,7 +689,7 @@
                         .fileFd = writeFd,
                         .pageIndex = static_cast<IncFsBlockIndex>(header.blockIdx),
                         .compression = static_cast<IncFsCompressionKind>(header.compressionType),
-                        .kind = INCFS_BLOCK_KIND_DATA,
+                        .kind = static_cast<IncFsBlockKind>(header.blockType),
                         .dataSize = static_cast<uint16_t>(header.blockSize),
                         .data = (const char*)remainingData.data(),
                 };
@@ -761,8 +763,8 @@
     }
 
     header.fileIdx = static_cast<FileIdx>(be16toh(*reinterpret_cast<const uint16_t*>(&data[0])));
-    header.compressionType =
-            static_cast<CompressionType>(be16toh(*reinterpret_cast<const uint16_t*>(&data[2])));
+    header.blockType = static_cast<BlockType>(data[2]);
+    header.compressionType = static_cast<CompressionType>(data[3]);
     header.blockIdx = static_cast<BlockIdx>(be32toh(*reinterpret_cast<const uint32_t*>(&data[4])));
     header.blockSize =
             static_cast<BlockSize>(be16toh(*reinterpret_cast<const uint16_t*>(&data[8])));
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 1a4ce8a..891acc1 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -158,6 +158,7 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        FakeSettingsProvider.clearSettingsProvider();
 
         mPowerSaveState = new PowerSaveState.Builder()
                 .setBatterySaverEnabled(BATTERY_SAVER_ENABLED)
@@ -263,6 +264,7 @@
         LocalServices.removeServiceForTest(DisplayManagerInternal.class);
         LocalServices.removeServiceForTest(BatteryManagerInternal.class);
         LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+        FakeSettingsProvider.clearSettingsProvider();
     }
 
     /**
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 0eba07b..18d5819 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -41,7 +41,6 @@
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.hardware.soundtrigger.IRecognitionStatusCallback;
-import android.hardware.soundtrigger.KeyphraseEnrollmentInfo;
 import android.hardware.soundtrigger.KeyphraseMetadata;
 import android.hardware.soundtrigger.ModelParams;
 import android.hardware.soundtrigger.SoundTrigger;
@@ -100,7 +99,7 @@
  * SystemService that publishes an IVoiceInteractionManagerService.
  */
 public class VoiceInteractionManagerService extends SystemService {
-    static final String TAG = "VoiceInteractionManagerService";
+    static final String TAG = "VoiceInteractionManager";
     static final boolean DEBUG = false;
 
     final Context mContext;
@@ -172,17 +171,17 @@
     }
 
     @Override
-    public void onStartUser(@NonNull UserInfo userInfo) {
-        if (DEBUG_USER) Slog.d(TAG, "onStartUser(" + userInfo + ")");
+    public void onUserStarting(@NonNull TargetUser user) {
+        if (DEBUG_USER) Slog.d(TAG, "onUserStarting(" + user + ")");
 
-        mServiceStub.initForUser(userInfo.id);
+        mServiceStub.initForUser(user.getUserIdentifier());
     }
 
     @Override
-    public void onUnlockUser(@NonNull UserInfo userInfo) {
-        if (DEBUG_USER) Slog.d(TAG, "onUnlockUser(" + userInfo + ")");
+    public void onUserUnlocking(@NonNull TargetUser user) {
+        if (DEBUG_USER) Slog.d(TAG, "onUserUnlocking(" + user + ")");
 
-        mServiceStub.initForUser(userInfo.id);
+        mServiceStub.initForUser(user.getUserIdentifier());
         mServiceStub.switchImplementationIfNeeded(false);
     }
 
@@ -224,7 +223,6 @@
     class VoiceInteractionManagerServiceStub extends IVoiceInteractionManagerService.Stub {
 
         VoiceInteractionManagerServiceImpl mImpl;
-        KeyphraseEnrollmentInfo mEnrollmentApplicationInfo;
 
         private boolean mSafeMode;
         private int mCurUser;
@@ -449,15 +447,6 @@
             }
         }
 
-        private void getOrCreateEnrollmentApplicationInfo() {
-            synchronized (this) {
-                if (mEnrollmentApplicationInfo == null) {
-                    mEnrollmentApplicationInfo = new KeyphraseEnrollmentInfo(
-                            mContext.getPackageManager());
-                }
-            }
-        }
-
         private void setCurrentUserLocked(@UserIdInt int userHandle) {
             mCurUser = userHandle;
             final UserInfo userInfo = mUserManagerInternal.getUserInfo(mCurUser);
@@ -1391,11 +1380,6 @@
                 pw.println("  mCurUserUnlocked: " + mCurUserUnlocked);
                 pw.println("  mCurUserSupported: " + mCurUserSupported);
                 dumpSupportedUsers(pw, "  ");
-                if (mEnrollmentApplicationInfo == null) {
-                    pw.println("  (No enrollment application info)");
-                } else {
-                    pw.println("  " + mEnrollmentApplicationInfo.toString());
-                }
                 mDbHelper.dump(pw);
                 if (mImpl == null) {
                     pw.println("  (No active implementation)");
@@ -1425,9 +1409,13 @@
             }
         }
 
+        private boolean isCallerHoldingPermission(String permission) {
+            return mContext.checkCallingOrSelfPermission(permission)
+                    == PackageManager.PERMISSION_GRANTED;
+        }
+
         private void enforceCallingPermission(String permission) {
-            if (mContext.checkCallingOrSelfPermission(permission)
-                    != PackageManager.PERMISSION_GRANTED) {
+            if (!isCallerHoldingPermission(permission)) {
                 throw new SecurityException("Caller does not hold the permission " + permission);
             }
         }
@@ -1440,12 +1428,12 @@
         }
 
         private void enforceCallerAllowedToEnrollVoiceModel() {
-            enforceCallingPermission(Manifest.permission.MANAGE_VOICE_KEYPHRASES);
-            if (!isCallerCurrentVoiceInteractionService()
-                    && !isCallerTrustedEnrollmentApplication()) {
-                throw new SecurityException("Caller is required to be the current voice interaction"
-                        + " service or a system enrollment application to enroll voice models");
+            if (isCallerHoldingPermission(Manifest.permission.KEYPHRASE_ENROLLMENT_APPLICATION)) {
+                return;
             }
+
+            enforceCallingPermission(Manifest.permission.MANAGE_VOICE_KEYPHRASES);
+            enforceIsCurrentVoiceInteractionService();
         }
 
         private boolean isCallerCurrentVoiceInteractionService() {
@@ -1453,12 +1441,6 @@
                     && mImpl.mInfo.getServiceInfo().applicationInfo.uid == Binder.getCallingUid();
         }
 
-        private boolean isCallerTrustedEnrollmentApplication() {
-            getOrCreateEnrollmentApplicationInfo();
-            return mEnrollmentApplicationInfo.isUidSupportedEnrollmentApplication(
-                            Binder.getCallingUid());
-        }
-
         private void setImplLocked(VoiceInteractionManagerServiceImpl impl) {
             mImpl = impl;
             mAtmInternal.notifyActiveVoiceInteractionServiceChanged(
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 1792256..e3baa0a 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -848,7 +848,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int CALL_SOURCE_EMERGENCY_SHORTCUT = 2;
 
     /**
@@ -856,7 +855,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int CALL_SOURCE_EMERGENCY_DIALPAD = 1;
 
     /**
@@ -864,7 +862,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int CALL_SOURCE_UNSPECIFIED = 0;
 
     /**
diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt
index 9d1fa37..228029d 100644
--- a/telephony/api/system-current.txt
+++ b/telephony/api/system-current.txt
@@ -806,6 +806,7 @@
     method public boolean isDataConnectivityPossible();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean isIccLockEnabled();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isInEmergencySmsMode();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isLteCdmaEvdoGsmWcdmaEnabled();
@@ -823,7 +824,6 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean);
     method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
-    method public void requestModemActivityInfo(@NonNull android.os.ResultReceiver);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetAllCarrierActions();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption();
@@ -886,29 +886,18 @@
     field @Deprecated public static final String EXTRA_APN_TYPE = "apnType";
     field public static final String EXTRA_APN_TYPE_INT = "apnTypeInt";
     field public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable";
-    field public static final String EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE = "android.telephony.extra.DEFAULT_SUBSCRIPTION_SELECT_TYPE";
-    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL = 4; // 0x4
-    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA = 1; // 0x1
-    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE = 0; // 0x0
-    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_SMS = 3; // 0x3
-    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_VOICE = 2; // 0x2
     field public static final String EXTRA_ERROR_CODE = "errorCode";
     field public static final String EXTRA_PCO_ID = "pcoId";
     field public static final String EXTRA_PCO_VALUE = "pcoValue";
     field public static final String EXTRA_PHONE_IN_ECM_STATE = "android.telephony.extra.PHONE_IN_ECM_STATE";
     field public static final String EXTRA_PHONE_IN_EMERGENCY_CALL = "android.telephony.extra.PHONE_IN_EMERGENCY_CALL";
     field public static final String EXTRA_REDIRECTION_URL = "redirectionUrl";
-    field public static final String EXTRA_SIM_COMBINATION_NAMES = "android.telephony.extra.SIM_COMBINATION_NAMES";
-    field public static final String EXTRA_SIM_COMBINATION_WARNING_TYPE = "android.telephony.extra.SIM_COMBINATION_WARNING_TYPE";
-    field public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA = 1; // 0x1
-    field public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE = 0; // 0x0
     field public static final String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
     field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
     field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
     field public static final int INVALID_EMERGENCY_NUMBER_DB_VERSION = -1; // 0xffffffff
     field public static final int KEY_TYPE_EPDG = 1; // 0x1
     field public static final int KEY_TYPE_WLAN = 2; // 0x2
-    field public static final String MODEM_ACTIVITY_RESULT_KEY = "controller_activity";
     field public static final long NETWORK_TYPE_BITMASK_1xRTT = 64L; // 0x40L
     field public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L
     field public static final long NETWORK_TYPE_BITMASK_EDGE = 2L; // 0x2L
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 4940cb2..93fbb00 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -690,7 +690,7 @@
      */
     public void updateNrState() {
         mNrState = NR_STATE_NONE;
-        if (mDataSpecificInfo.isEnDcAvailable) {
+        if (mDataSpecificInfo != null && mDataSpecificInfo.isEnDcAvailable) {
             if (!mDataSpecificInfo.isDcNrRestricted && mDataSpecificInfo.isNrAvailable) {
                 mNrState = NR_STATE_NOT_RESTRICTED;
             } else {
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index f6552ee..c144746 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -424,7 +424,7 @@
             String destinationAddress, String scAddress, String text,
             PendingIntent sentIntent, PendingIntent deliveryIntent) {
         sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
-                true /* persistMessage*/, null, 0L /* messageId */);
+                true /* persistMessage*/, null, null, 0L /* messageId */);
     }
 
 
@@ -443,7 +443,7 @@
             @Nullable PendingIntent sentIntent, @Nullable PendingIntent deliveryIntent,
             long messageId) {
         sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
-                true /* persistMessage*/, null, messageId);
+                true /* persistMessage*/, null, null, messageId);
     }
 
     /**
@@ -561,7 +561,7 @@
 
     private void sendTextMessageInternal(String destinationAddress, String scAddress,
             String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
-            boolean persistMessage, String packageName, long messageId) {
+            boolean persistMessage, String packageName, String attributionTag, long messageId) {
         if (TextUtils.isEmpty(destinationAddress)) {
             throw new IllegalArgumentException("Invalid destinationAddress");
         }
@@ -586,7 +586,7 @@
                 public void onSuccess(int subId) {
                     ISms iSms = getISmsServiceOrThrow();
                     try {
-                        iSms.sendTextForSubscriber(subId, packageName,
+                        iSms.sendTextForSubscriber(subId, packageName, attributionTag,
                                 destinationAddress, scAddress, text, sentIntent, deliveryIntent,
                                 persistMessage, messageId);
                     } catch (RemoteException e) {
@@ -606,7 +606,7 @@
             // visible to the user.
             ISms iSms = getISmsServiceOrThrow();
             try {
-                iSms.sendTextForSubscriber(getSubscriptionId(), packageName,
+                iSms.sendTextForSubscriber(getSubscriptionId(), packageName, attributionTag,
                         destinationAddress, scAddress, text, sentIntent, deliveryIntent,
                         persistMessage, messageId);
             } catch (RemoteException e) {
@@ -653,7 +653,7 @@
             String destinationAddress, String scAddress, String text,
             PendingIntent sentIntent, PendingIntent deliveryIntent) {
         sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
-                false /* persistMessage */, null,
+                false /* persistMessage */, null, null,
                 0L /* messageId */);
     }
 
@@ -937,7 +937,7 @@
             String destinationAddress, String scAddress, ArrayList<String> parts,
             ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
-                deliveryIntents, true /* persistMessage*/, null,
+                deliveryIntents, true /* persistMessage*/, null, null,
                 0L /* messageId */);
     }
 
@@ -955,7 +955,7 @@
             @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
             @Nullable List<PendingIntent> deliveryIntents, long messageId) {
         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
-                deliveryIntents, true /* persistMessage*/, null,
+                deliveryIntents, true /* persistMessage*/, null, null,
                 messageId);
     }
 
@@ -979,15 +979,18 @@
     public void sendMultipartTextMessage(
             @NonNull String destinationAddress, @Nullable String scAddress,
             @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
-            @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName) {
+            @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName,
+            @Nullable String attributionTag) {
         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
-                deliveryIntents, true /* persistMessage*/, packageName, 0L /* messageId */);
+                deliveryIntents, true /* persistMessage*/, packageName, attributionTag,
+                0L /* messageId */);
     }
 
     private void sendMultipartTextMessageInternal(
             String destinationAddress, String scAddress, List<String> parts,
             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
-            boolean persistMessage, String packageName, long messageId) {
+            boolean persistMessage, String packageName, @Nullable String attributionTag,
+            long messageId) {
         if (TextUtils.isEmpty(destinationAddress)) {
             throw new IllegalArgumentException("Invalid destinationAddress");
         }
@@ -1012,7 +1015,7 @@
                     public void onSuccess(int subId) {
                         try {
                             ISms iSms = getISmsServiceOrThrow();
-                            iSms.sendMultipartTextForSubscriber(subId, packageName,
+                            iSms.sendMultipartTextForSubscriber(subId, packageName, attributionTag,
                                     destinationAddress, scAddress, parts, sentIntents,
                                     deliveryIntents, persistMessage, messageId);
                         } catch (RemoteException e) {
@@ -1034,8 +1037,8 @@
                     ISms iSms = getISmsServiceOrThrow();
                     if (iSms != null) {
                         iSms.sendMultipartTextForSubscriber(getSubscriptionId(), packageName,
-                                destinationAddress, scAddress, parts, sentIntents, deliveryIntents,
-                                persistMessage, messageId);
+                                attributionTag, destinationAddress, scAddress, parts, sentIntents,
+                                deliveryIntents, persistMessage, messageId);
                     }
                 } catch (RemoteException e) {
                     Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - "
@@ -1053,7 +1056,7 @@
                 deliveryIntent = deliveryIntents.get(0);
             }
             sendTextMessageInternal(destinationAddress, scAddress, parts.get(0),
-                    sentIntent, deliveryIntent, true, packageName, messageId);
+                    sentIntent, deliveryIntent, true, packageName, attributionTag, messageId);
         }
     }
 
@@ -1083,7 +1086,7 @@
             String destinationAddress, String scAddress, List<String> parts,
             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
-                deliveryIntents, false /* persistMessage*/, null,
+                deliveryIntents, false /* persistMessage*/, null, null,
                 0L /* messageId */);
     }
 
@@ -1246,7 +1249,7 @@
                             ISms iSms = getISmsServiceOrThrow();
                             if (iSms != null) {
                                 iSms.sendMultipartTextForSubscriberWithOptions(subId,
-                                        null, destinationAddress,
+                                        null, null, destinationAddress,
                                         scAddress, parts, sentIntents, deliveryIntents,
                                         persistMessage, finalPriority, expectMore, finalValidity);
                             }
@@ -1268,7 +1271,7 @@
                     ISms iSms = getISmsServiceOrThrow();
                     if (iSms != null) {
                         iSms.sendMultipartTextForSubscriberWithOptions(getSubscriptionId(),
-                                null, destinationAddress,
+                                null, null, destinationAddress,
                                 scAddress, parts, sentIntents, deliveryIntents,
                                 persistMessage, finalPriority, expectMore, finalValidity);
                     }
@@ -1399,9 +1402,8 @@
             public void onSuccess(int subId) {
                 try {
                     ISms iSms = getISmsServiceOrThrow();
-                    iSms.sendDataForSubscriber(subId, null,
-                            destinationAddress, scAddress, destinationPort & 0xFFFF, data,
-                            sentIntent, deliveryIntent);
+                    iSms.sendDataForSubscriber(subId, null, null, destinationAddress, scAddress,
+                            destinationPort & 0xFFFF, data, sentIntent, deliveryIntent);
                 } catch (RemoteException e) {
                     Log.e(TAG, "sendDataMessage: Couldn't send SMS - Exception: " + e.getMessage());
                     notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
@@ -1553,7 +1555,7 @@
             // it here because we do not have access to the activity context that is performing this
             // operation.
             // Requires that the calling process has the SEND_SMS permission.
-            getITelephony().enqueueSmsPickResult(null,
+            getITelephony().enqueueSmsPickResult(null, null,
                     new IIntegerConsumer.Stub() {
                         @Override
                         public void accept(int subId) {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 441a8ee..0eaeda0 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -165,7 +165,6 @@
      * into the ResultReceiver Bundle.
      * @hide
      */
-    @SystemApi
     public static final String MODEM_ACTIVITY_RESULT_KEY = "controller_activity";
 
     /**
@@ -1438,7 +1437,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE =
             "android.telephony.extra.DEFAULT_SUBSCRIPTION_SELECT_TYPE";
 
@@ -1458,7 +1456,6 @@
      * to indicate there's no need to re-select any default subscription.
      * @hide
      */
-    @SystemApi
     public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE = 0;
 
     /**
@@ -1466,7 +1463,6 @@
      * to indicate there's a need to select default data subscription.
      * @hide
      */
-    @SystemApi
     public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA = 1;
 
     /**
@@ -1474,7 +1470,6 @@
      * to indicate there's a need to select default voice call subscription.
      * @hide
      */
-    @SystemApi
     public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_VOICE = 2;
 
     /**
@@ -1482,7 +1477,6 @@
      * to indicate there's a need to select default sms subscription.
      * @hide
      */
-    @SystemApi
     public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_SMS = 3;
 
     /**
@@ -1492,7 +1486,6 @@
      * which subscription should be the default subscription.
      * @hide
      */
-    @SystemApi
     public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL = 4;
 
     /**
@@ -1502,7 +1495,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String EXTRA_SIM_COMBINATION_WARNING_TYPE =
             "android.telephony.extra.SIM_COMBINATION_WARNING_TYPE";
 
@@ -1519,7 +1511,6 @@
      * to indicate there's no SIM combination warning.
      * @hide
      */
-    @SystemApi
     public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE = 0;
 
     /**
@@ -1527,7 +1518,6 @@
      * to indicate two active SIMs are both CDMA hence there might be functional limitation.
      * @hide
      */
-    @SystemApi
     public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA = 1;
 
     /**
@@ -1538,7 +1528,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String EXTRA_SIM_COMBINATION_NAMES =
             "android.telephony.extra.SIM_COMBINATION_NAMES";
 
@@ -10278,7 +10267,6 @@
      * {@link #MODEM_ACTIVITY_RESULT_KEY}.
      * @hide
      */
-    @SystemApi
     public void requestModemActivityInfo(@NonNull ResultReceiver result) {
         try {
             ITelephony service = getITelephony();
@@ -13003,6 +12991,7 @@
      */
     @WorkerThread
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SystemApi
     public boolean isIccLockEnabled() {
         try {
             ITelephony telephony = getITelephony();
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index fed969d..89f811e 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -86,9 +86,9 @@
      *  raw pdu of the status report is in the extended data ("pdu").
      * @param subId the subId id.
      */
-    void sendDataForSubscriber(int subId, String callingPkg, in String destAddr,
-            in String scAddr, in int destPort, in byte[] data, in PendingIntent sentIntent,
-            in PendingIntent deliveryIntent);
+    void sendDataForSubscriber(int subId, String callingPkg, String callingattributionTag,
+            in String destAddr, in String scAddr, in int destPort,in byte[] data,
+            in PendingIntent sentIntent, in PendingIntent deliveryIntent);
 
     /**
      * Send an SMS.
@@ -120,8 +120,8 @@
      * @param messageId An id that uniquely identifies the message requested to be sent.
      *   Used for logging and diagnostics purposes. The id may be 0.
      */
-    void sendTextForSubscriber(in int subId, String callingPkg, in String destAddr,
-            in String scAddr, in String text, in PendingIntent sentIntent,
+    void sendTextForSubscriber(in int subId, String callingPkg, String callingAttributionTag,
+            in String destAddr, in String scAddr, in String text, in PendingIntent sentIntent,
             in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp,
             in long messageId);
 
@@ -222,7 +222,7 @@
      *   Used for logging and diagnostics purposes. The id may be 0.
      */
     void sendMultipartTextForSubscriber(in int subId, String callingPkg,
-            in String destinationAddress, in String scAddress,
+            String callingAttributionTag, in String destinationAddress, in String scAddress,
             in List<String> parts, in List<PendingIntent> sentIntents,
             in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp,
             in long messageId);
@@ -272,10 +272,10 @@
      *  Any Other values included Negative considered as Invalid Validity Period of the message.
      */
     void sendMultipartTextForSubscriberWithOptions(in int subId, String callingPkg,
-            in String destinationAddress, in String scAddress, in List<String> parts,
-            in List<PendingIntent> sentIntents, in List<PendingIntent> deliveryIntents,
-            in boolean persistMessageForNonDefaultSmsApp, in int priority, in boolean expectMore,
-            in int validityPeriod);
+            String callingAttributionTag, in String destinationAddress, in String scAddress,
+            in List<String> parts, in List<PendingIntent> sentIntents,
+            in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp,
+            in int priority, in boolean expectMore, in int validityPeriod);
 
     /**
      * Enable reception of cell broadcast (SMS-CB) messages with the given
@@ -433,6 +433,7 @@
      *
      * @param subId the SIM id.
      * @param callingPkg the package name of the calling app
+     * @param callingAttributionTag the attribution tag of calling context
      * @param messageUri the URI of the stored message
      * @param scAddress is the service center address or null to use the current default SMSC
      * @param sentIntent if not NULL this <code>PendingIntent</code> is
@@ -452,8 +453,9 @@
      *  broadcast when the message is delivered to the recipient.  The
      *  raw pdu of the status report is in the extended data ("pdu").
      */
-    void sendStoredText(int subId, String callingPkg, in Uri messageUri, String scAddress,
-            in PendingIntent sentIntent, in PendingIntent deliveryIntent);
+    void sendStoredText(int subId, String callingPkg, String callingAttributionTag,
+            in Uri messageUri, String scAddress, in PendingIntent sentIntent,
+            in PendingIntent deliveryIntent);
 
     /**
      * Send a system stored multi-part text message.
@@ -465,6 +467,7 @@
      *
      * @param subId the SIM id.
      * @param callingPkg the package name of the calling app
+     * @param callingAttributeTag the attribute tag of the calling context
      * @param messageUri the URI of the stored message
      * @param scAddress is the service center address or null to use
      *   the current default SMSC
@@ -488,8 +491,8 @@
      *   to the recipient.  The raw pdu of the status report is in the
      *   extended data ("pdu").
      */
-    void sendStoredMultipartText(int subId, String callingPkg, in Uri messageUri,
-                String scAddress, in List<PendingIntent> sentIntents,
+    void sendStoredMultipartText(int subId, String callingPkg, String callingAttributeTag,
+                in Uri messageUri, String scAddress, in List<PendingIntent> sentIntents,
                 in List<PendingIntent> deliveryIntents);
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index 67ad23a..f1182f7 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -45,15 +45,15 @@
     }
 
     @Override
-    public void sendDataForSubscriber(int subId, String callingPkg, String destAddr,
-            String scAddr, int destPort, byte[] data, PendingIntent sentIntent,
+    public void sendDataForSubscriber(int subId, String callingPkg, String callingAttributionTag,
+            String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent,
             PendingIntent deliveryIntent) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public void sendTextForSubscriber(int subId, String callingPkg, String destAddr,
-            String scAddr, String text, PendingIntent sentIntent,
+    public void sendTextForSubscriber(int subId, String callingPkg, String callingAttributionTag,
+            String destAddr, String scAddr, String text, PendingIntent sentIntent,
             PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp,
             long messageId) {
         throw new UnsupportedOperationException();
@@ -76,7 +76,7 @@
 
     @Override
     public void sendMultipartTextForSubscriber(int subId, String callingPkg,
-            String destinationAddress, String scAddress,
+            String callingAttributionTag, String destinationAddress, String scAddress,
             List<String> parts, List<PendingIntent> sentIntents,
             List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp,
             long messageId) {
@@ -85,7 +85,7 @@
 
     @Override
     public void sendMultipartTextForSubscriberWithOptions(int subId, String callingPkg,
-            String destinationAddress, String scAddress,
+            String callingAttributionTag, String destinationAddress, String scAddress,
             List<String> parts, List<PendingIntent> sentIntents,
             List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp,
             int priority, boolean expectMore, int validityPeriod) {
@@ -162,14 +162,15 @@
     }
 
     @Override
-    public void sendStoredText(int subId, String callingPkg, Uri messageUri, String scAddress,
-            PendingIntent sentIntent, PendingIntent deliveryIntent) {
+    public void sendStoredText(int subId, String callingPkg, String callingAttributionTag,
+            Uri messageUri, String scAddress, PendingIntent sentIntent,
+            PendingIntent deliveryIntent) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public void sendStoredMultipartText(int subId, String callingPkg, Uri messageUri,
-            String scAddress, List<PendingIntent> sentIntents,
+    public void sendStoredMultipartText(int subId, String callingPkg, String callingAttributionTag,
+            Uri messageUri, String scAddress, List<PendingIntent> sentIntents,
             List<PendingIntent> deliveryIntents) {
         throw new UnsupportedOperationException();
     }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 81c0895..43aeb19 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2204,7 +2204,8 @@
      * Enqueue a pending sms Consumer, which will answer with the user specified selection for an
      * outgoing SmsManager operation.
      */
-    oneway void enqueueSmsPickResult(String callingPackage, IIntegerConsumer subIdResult);
+    oneway void enqueueSmsPickResult(String callingPackage, String callingAttributeTag,
+        IIntegerConsumer subIdResult);
 
     /**
      * Returns the MMS user agent.
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index f31a2af..47eb63e 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -55,8 +55,7 @@
         resetState(that.resetState),
         nested(that.nested),
         uidField(that.uidField),
-        whitelisted(that.whitelisted),
-        binaryFields(that.binaryFields) {}
+        whitelisted(that.whitelisted) {}
 
 AtomDecl::AtomDecl(int c, const string& n, const string& m)
     :code(c),
@@ -422,10 +421,6 @@
             continue;
         }
     }
-    // Binary field validity is already checked above.
-    if (isBinaryField) {
-        atomDecl->binaryFields.push_back(it->first);
-    }
   }
 
   return errorCount;
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
index d99b931..c6dad1d 100644
--- a/tools/stats_log_api_gen/Collation.h
+++ b/tools/stats_log_api_gen/Collation.h
@@ -147,8 +147,6 @@
 
     bool whitelisted = false;
 
-    vector<int> binaryFields;
-
     AtomDecl();
     AtomDecl(const AtomDecl& that);
     AtomDecl(int code, const string& name, const string& message);
diff --git a/tools/stats_log_api_gen/atoms_info_writer.cpp b/tools/stats_log_api_gen/atoms_info_writer.cpp
index 58f13a4..4f66f68 100644
--- a/tools/stats_log_api_gen/atoms_info_writer.cpp
+++ b/tools/stats_log_api_gen/atoms_info_writer.cpp
@@ -48,9 +48,6 @@
             "  const static std::map<int, StateAtomFieldOptions> "
             "kStateAtomsFieldOptions;\n");
     fprintf(out,
-            "  const static std::map<int, std::vector<int>> "
-            "kBytesFieldAtoms;\n");
-    fprintf(out,
             "  const static std::set<int> kWhitelistedAtoms;\n");
     fprintf(out, "};\n");
     fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n", atoms.maxPushedAtomId);
@@ -175,35 +172,6 @@
             "const std::map<int, StateAtomFieldOptions> "
             "AtomsInfo::kStateAtomsFieldOptions = "
             "getStateAtomFieldOptions();\n");
-
-    fprintf(out,
-            "static std::map<int, std::vector<int>> "
-            "getBinaryFieldAtoms() {\n");
-    fprintf(out, "    std::map<int, std::vector<int>> options;\n");
-    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
-         atom != atoms.decls.end(); atom++) {
-        if (atom->binaryFields.size() == 0) {
-            continue;
-        }
-        fprintf(out,
-                "\n    // Adding binary fields for atom "
-                "(%d)%s\n",
-                atom->code, atom->name.c_str());
-
-        for (const auto& field : atom->binaryFields) {
-            fprintf(out, "    options[%d /* %s */].push_back(%d);\n",
-                    atom->code, make_constant_name(atom->name).c_str(), field);
-        }
-    }
-
-    fprintf(out, "    return options;\n");
-    fprintf(out, "}\n");
-
-    fprintf(out,
-            "const std::map<int, std::vector<int>> "
-            "AtomsInfo::kBytesFieldAtoms = "
-            "getBinaryFieldAtoms();\n");
-
 }
 
 int write_atoms_info_header(FILE* out, const Atoms &atoms, const string& namespaceStr) {
diff --git a/wifi/java/android/net/wifi/WifiMigration.java b/wifi/java/android/net/wifi/WifiMigration.java
index 666d72d..87afdc5 100755
--- a/wifi/java/android/net/wifi/WifiMigration.java
+++ b/wifi/java/android/net/wifi/WifiMigration.java
@@ -138,7 +138,10 @@
 
     /**
      * Load data from legacy shared wifi config store file.
-     * TODO(b/149418926): Add XSD for the AOSP file format for each file from R.
+     * <p>
+     * Expected AOSP format is available in the sample files under {@code /frameworks/base/wifi/
+     * java/android/net/wifi/migration_samples}.
+     * </p>
      * <p>
      * Note:
      * <li>OEMs need to change the implementation of
@@ -214,7 +217,10 @@
 
     /**
      * Load data from legacy user wifi config store file.
-     * TODO(b/149418926): Add XSD for the AOSP file format for each file from R.
+     * <p>
+     * Expected AOSP format is available in the sample files under {@code /frameworks/base/wifi/
+     * java/android/net/wifi/migration_samples}.
+     * </p>
      * <p>
      * Note:
      * <li>OEMs need to change the implementation of
diff --git a/wifi/java/android/net/wifi/migration_samples/README.txt b/wifi/java/android/net/wifi/migration_samples/README.txt
new file mode 100644
index 0000000..264deba
--- /dev/null
+++ b/wifi/java/android/net/wifi/migration_samples/README.txt
@@ -0,0 +1,35 @@
+This folder contains sample files for each of the 4 XML Wi-Fi config store files in Android 11 AOSP.
+OEMs can use these files as reference for converting their previous customized
+formats into the AOSP format. The conversion logic needs to be written in
+WifiMigration.java class, i.e each OEM needs to modify
+WifiMigration.convertAndRetrieveSharedConfigStoreFile() and the
+WifiMigration.convertAndRetrieveUserConfigStoreFile() methods.
+
+The 4 files are:
+
+Shared files
+============
+1) WifiConfigStore.xml - General storage for shared configurations. Includes
+user's saved Wi-Fi networks.
+AOSP Path in Android 10: /data/misc/wifi/WifiConfigStore.xml
+AOSP Path in Android 11: /data/misc/apexdata/com.android/wifi/WifiConfigStore.xml
+Sample File (in this folder): Shared_WifiConfigStore.xml
+
+2) WifiConfigStoreSoftAp.xml - Storage for user's softap/tethering configuration.
+AOSP Path in Android 10: /data/misc/wifi/softap.conf.
+Note: Was key/value format in Android 10. Conversion to XML done in SoftApConfToXmlMigrationUtil.java.
+AOSP Path in Android 11: /data/misc/apexdata/com.android/wifi/WifiConfigStore.xml
+Sample File (in this folder): Shared_WifiConfigStoreSoftAp.xml
+
+User specific files
+==================
+3) WifiConfigStore.xml - General storage for user specific configurations. Includes
+user's saved passpoint networks, Wi-Fi network request approvals, etc.
+AOSP Path in Android 10: /data/misc_ce/<userId>/wifi/WifiConfigStore.xml
+AOSP Path in Android 11: /data/misc_ce/<userId>/apexdata/com.android/wifi/WifiConfigStore.xml
+Sample File (in this folder): User_WifiConfigStore.xml
+
+4) WifiConfigStoreNetworkSuggestions.xml - Storage for app installed network suggestions.
+AOSP Path in Android 10: /data/misc_ce/<userId>/wifi/WifiConfigStoreNetworkSuggestions.xml
+AOSP Path in Android 11: /data/misc_ce/<userId>/apexdata/com.android/wifi/WifiConfigStoreNetworkSuggestions.xml
+Sample File (in this folder): User_WifiConfigStoreNetworkSuggestions.xml
diff --git a/wifi/java/android/net/wifi/migration_samples/Shared_WifiConfigStore.xml b/wifi/java/android/net/wifi/migration_samples/Shared_WifiConfigStore.xml
new file mode 100644
index 0000000..3063276
--- /dev/null
+++ b/wifi/java/android/net/wifi/migration_samples/Shared_WifiConfigStore.xml
@@ -0,0 +1,200 @@
+<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+<WifiConfigStoreData>
+<int name="Version" value="3" />
+<NetworkList>
+<Network>
+<WifiConfiguration>
+<string name="ConfigKey">&quot;OPEN_SSID&quot;NONE</string>
+<string name="SSID">&quot;OPEN_SSID&quot;</string>
+<null name="PreSharedKey" />
+<null name="WEPKeys" />
+<int name="WEPTxKeyIndex" value="0" />
+<boolean name="HiddenSSID" value="false" />
+<boolean name="RequirePMF" value="false" />
+<byte-array name="AllowedKeyMgmt" num="1">01</byte-array>
+<byte-array name="AllowedProtocols" num="1">03</byte-array>
+<byte-array name="AllowedAuthAlgos" num="0"></byte-array>
+<byte-array name="AllowedGroupCiphers" num="1">2f</byte-array>
+<byte-array name="AllowedPairwiseCiphers" num="1">0e</byte-array>
+<byte-array name="AllowedGroupMgmtCiphers" num="1">04</byte-array>
+<byte-array name="AllowedSuiteBCiphers" num="0"></byte-array>
+<boolean name="Shared" value="true" />
+<boolean name="AutoJoinEnabled" value="true" />
+<boolean name="Trusted" value="true" />
+<null name="BSSID" />
+<int name="Status" value="2" />
+<null name="FQDN" />
+<null name="ProviderFriendlyName" />
+<null name="LinkedNetworksList" />
+<null name="DefaultGwMacAddress" />
+<boolean name="ValidatedInternetAccess" value="true" />
+<boolean name="NoInternetAccessExpected" value="false" />
+<boolean name="MeteredHint" value="false" />
+<int name="MeteredOverride" value="0" />
+<boolean name="UseExternalScores" value="false" />
+<int name="NumAssociation" value="3" />
+<int name="CreatorUid" value="1000" />
+<string name="CreatorName">android.uid.system:1000</string>
+<int name="LastUpdateUid" value="1000" />
+<string name="LastUpdateName">android.uid.system:1000</string>
+<int name="LastConnectUid" value="1000" />
+<boolean name="IsLegacyPasspointConfig" value="false" />
+<long-array name="RoamingConsortiumOIs" num="0" />
+<string name="RandomizedMacAddress">ce:b1:36:bb:71:ac</string>
+<int name="MacRandomizationSetting" value="1" />
+<int name="CarrierId" value="-1" />
+</WifiConfiguration>
+<NetworkStatus>
+<string name="SelectionStatus">NETWORK_SELECTION_ENABLED</string>
+<string name="DisableReason">NETWORK_SELECTION_ENABLE</string>
+<string name="ConnectChoice">&quot;ENTERPRISE_SSID&quot;WPA_EAP</string>
+<boolean name="HasEverConnected" value="true" />
+</NetworkStatus>
+<IpConfiguration>
+<string name="IpAssignment">DHCP</string>
+<string name="ProxySettings">NONE</string>
+</IpConfiguration>
+</Network>
+<Network>
+<WifiConfiguration>
+<string name="ConfigKey">&quot;ENTERPRISE_SSID&quot;WPA_EAP</string>
+<string name="SSID">&quot;ENTERPRISE_SSID&quot;</string>
+<null name="PreSharedKey" />
+<null name="WEPKeys" />
+<int name="WEPTxKeyIndex" value="0" />
+<boolean name="HiddenSSID" value="false" />
+<boolean name="RequirePMF" value="false" />
+<byte-array name="AllowedKeyMgmt" num="1">0c</byte-array>
+<byte-array name="AllowedProtocols" num="1">03</byte-array>
+<byte-array name="AllowedAuthAlgos" num="0"></byte-array>
+<byte-array name="AllowedGroupCiphers" num="1">2f</byte-array>
+<byte-array name="AllowedPairwiseCiphers" num="1">0e</byte-array>
+<byte-array name="AllowedGroupMgmtCiphers" num="1">04</byte-array>
+<byte-array name="AllowedSuiteBCiphers" num="0"></byte-array>
+<boolean name="Shared" value="true" />
+<boolean name="AutoJoinEnabled" value="true" />
+<boolean name="Trusted" value="true" />
+<null name="BSSID" />
+<int name="Status" value="2" />
+<null name="FQDN" />
+<null name="ProviderFriendlyName" />
+<null name="LinkedNetworksList" />
+<null name="DefaultGwMacAddress" />
+<boolean name="ValidatedInternetAccess" value="false" />
+<boolean name="NoInternetAccessExpected" value="false" />
+<boolean name="MeteredHint" value="false" />
+<int name="MeteredOverride" value="0" />
+<boolean name="UseExternalScores" value="false" />
+<int name="NumAssociation" value="0" />
+<int name="CreatorUid" value="1000" />
+<string name="CreatorName">android.uid.system:1000</string>
+<int name="LastUpdateUid" value="1000" />
+<string name="LastUpdateName">android.uid.system:1000</string>
+<int name="LastConnectUid" value="1000" />
+<boolean name="IsLegacyPasspointConfig" value="false" />
+<long-array name="RoamingConsortiumOIs" num="0" />
+<string name="RandomizedMacAddress">f6:b3:94:44:40:87</string>
+<int name="MacRandomizationSetting" value="1" />
+<int name="CarrierId" value="-1" />
+</WifiConfiguration>
+<NetworkStatus>
+<string name="SelectionStatus">NETWORK_SELECTION_TEMPORARY_DISABLED</string>
+<string name="DisableReason">NETWORK_SELECTION_DISABLED_AUTHENTICATION_FAILURE</string>
+<null name="ConnectChoice" />
+<boolean name="HasEverConnected" value="false" />
+</NetworkStatus>
+<IpConfiguration>
+<string name="IpAssignment">DHCP</string>
+<string name="ProxySettings">NONE</string>
+</IpConfiguration>
+<WifiEnterpriseConfiguration>
+<string name="Identity">adadadasdaddsa</string>
+<string name="AnonIdentity">asdadaddadasd</string>
+<string name="Password">adasdadadad</string>
+<string name="ClientCert"></string>
+<string name="CaCert"></string>
+<string name="SubjectMatch"></string>
+<string name="Engine">0</string>
+<string name="EngineId"></string>
+<string name="PrivateKeyId"></string>
+<string name="AltSubjectMatch"></string>
+<string name="DomSuffixMatch">adsad</string>
+<string name="CaPath">/system/etc/security/cacerts</string>
+<int name="EapMethod" value="0" />
+<int name="Phase2Method" value="3" />
+<string name="PLMN"></string>
+<string name="Realm"></string>
+<int name="Ocsp" value="0" />
+<string name="WapiCertSuite"></string>
+</WifiEnterpriseConfiguration>
+</Network>
+<Network>
+<WifiConfiguration>
+<string name="ConfigKey">&quot;WPA3_SSID&quot;SAE</string>
+<string name="SSID">&quot;WPA3_SSID&quot;</string>
+<string name="PreSharedKey">&quot;sfsdfsfdsfsdf&quot;</string>
+<null name="WEPKeys" />
+<int name="WEPTxKeyIndex" value="0" />
+<boolean name="HiddenSSID" value="false" />
+<boolean name="RequirePMF" value="true" />
+<byte-array name="AllowedKeyMgmt" num="2">0001</byte-array>
+<byte-array name="AllowedProtocols" num="1">02</byte-array>
+<byte-array name="AllowedAuthAlgos" num="0"></byte-array>
+<byte-array name="AllowedGroupCiphers" num="1">28</byte-array>
+<byte-array name="AllowedPairwiseCiphers" num="1">0c</byte-array>
+<byte-array name="AllowedGroupMgmtCiphers" num="1">04</byte-array>
+<byte-array name="AllowedSuiteBCiphers" num="0"></byte-array>
+<boolean name="Shared" value="true" />
+<boolean name="AutoJoinEnabled" value="true" />
+<boolean name="Trusted" value="true" />
+<null name="BSSID" />
+<int name="Status" value="1" />
+<null name="FQDN" />
+<null name="ProviderFriendlyName" />
+<null name="LinkedNetworksList" />
+<null name="DefaultGwMacAddress" />
+<boolean name="ValidatedInternetAccess" value="false" />
+<boolean name="NoInternetAccessExpected" value="false" />
+<boolean name="MeteredHint" value="false" />
+<int name="MeteredOverride" value="0" />
+<boolean name="UseExternalScores" value="false" />
+<int name="NumAssociation" value="0" />
+<int name="CreatorUid" value="1000" />
+<string name="CreatorName">android.uid.system:1000</string>
+<int name="LastUpdateUid" value="1000" />
+<string name="LastUpdateName">android.uid.system:1000</string>
+<int name="LastConnectUid" value="1000" />
+<boolean name="IsLegacyPasspointConfig" value="false" />
+<long-array name="RoamingConsortiumOIs" num="0" />
+<string name="RandomizedMacAddress">a6:3d:b0:13:ed:41</string>
+<int name="MacRandomizationSetting" value="1" />
+<int name="CarrierId" value="-1" />
+</WifiConfiguration>
+<NetworkStatus>
+<string name="SelectionStatus">NETWORK_SELECTION_PERMANENTLY_DISABLED</string>
+<string name="DisableReason">NETWORK_SELECTION_DISABLED_BY_WRONG_PASSWORD</string>
+<null name="ConnectChoice" />
+<boolean name="HasEverConnected" value="false" />
+</NetworkStatus>
+<IpConfiguration>
+<string name="IpAssignment">DHCP</string>
+<string name="ProxySettings">NONE</string>
+</IpConfiguration>
+</Network>
+</NetworkList>
+<MacAddressMap>
+<map name="MacMapEntry" />
+</MacAddressMap>
+<Settings>
+<map name="Values">
+<boolean name="wifi_p2p_pending_factory_reset" value="false" />
+<boolean name="wifi_scan_throttle_enabled" value="true" />
+<null name="wifi_p2p_device_name" />
+<boolean name="wifi_scan_always_enabled" value="false" />
+<boolean name="wifi_verbose_logging_enabled" value="true" />
+</map>
+</Settings>
+<PasspointConfigData>
+<long name="ProviderIndex" value="0" />
+</PasspointConfigData>
+</WifiConfigStoreData>
diff --git a/wifi/java/android/net/wifi/migration_samples/Shared_WifiConfigStoreSoftAp.xml b/wifi/java/android/net/wifi/migration_samples/Shared_WifiConfigStoreSoftAp.xml
new file mode 100644
index 0000000..fd99dd3
--- /dev/null
+++ b/wifi/java/android/net/wifi/migration_samples/Shared_WifiConfigStoreSoftAp.xml
@@ -0,0 +1,22 @@
+<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+<WifiConfigStoreData>
+<int name="Version" value="3" />
+<SoftAp>
+<string name="SSID">HOTSPOT_SSID</string>
+<int name="ApBand" value="1" />
+<int name="Channel" value="0" />
+<boolean name="HiddenSSID" value="false" />
+<int name="SecurityType" value="1" />
+<string name="Passphrase">blahblahblah</string>
+<int name="MaxNumberOfClients" value="0" />
+<boolean name="ClientControlByUser" value="false" />
+<boolean name="AutoShutdownEnabled" value="true" />
+<long name="ShutdownTimeoutMillis" value="0" />
+<BlockedClientList>
+<string name="ClientMacAddress">00:11:22:33:44:55</string>
+</BlockedClientList>
+<AllowedClientList>
+<string name="ClientMacAddress">aa:bb:cc:dd:ee:ff</string>
+</AllowedClientList>
+</SoftAp>
+</WifiConfigStoreData>
diff --git a/wifi/java/android/net/wifi/migration_samples/User_WifiConfigStore.xml b/wifi/java/android/net/wifi/migration_samples/User_WifiConfigStore.xml
new file mode 100644
index 0000000..67d5aab
--- /dev/null
+++ b/wifi/java/android/net/wifi/migration_samples/User_WifiConfigStore.xml
@@ -0,0 +1,81 @@
+<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+<WifiConfigStoreData>
+<int name="Version" value="3" />
+<NetworkList />
+<PasspointConfigData>
+<ProviderList>
+<Provider>
+<long name="ProviderID" value="0" />
+<int name="CreatorUID" value="10085" />
+<string name="PackageName">com.android.certinstaller</string>
+<list name="CaCertificateAliases">
+<string>HS2_0_0</string>
+</list>
+<null name="ClientPrivateKeyAlias" />
+<boolean name="HasEverConnected" value="false" />
+<boolean name="IsFromSuggestion" value="false" />
+<boolean name="IsTrusted" value="true" />
+<Configuration>
+<int name="UpdateIdentifier" value="-2147483648" />
+<int name="CredentialPriority" value="-2147483648" />
+<null name="TrustRootCertList" />
+<long name="SubscriptionCreationTime" value="-9223372036854775808" />
+<long name="SubscriptionExpirationTime" value="-9223372036854775808" />
+<null name="SubscriptionType" />
+<long name="UsageLimitTimePeriod" value="-9223372036854775808" />
+<long name="UsageLimitStartTime" value="-9223372036854775808" />
+<long name="UsageLimitDataLimit" value="-9223372036854775808" />
+<long name="UsageLimitTimeLimit" value="-9223372036854775808" />
+<HomeSP>
+<string name="FQDN">Passpoint.net</string>
+<string name="FriendlyName">Passpoint Friendly Name</string>
+<null name="IconURL" />
+<null name="HomeNetworkIDs" />
+<null name="MatchAllOIs" />
+<null name="MatchAnyOIs" />
+<null name="OtherHomePartners" />
+<null name="RoamingConsortiumOIs" />
+</HomeSP>
+<Credential>
+<long name="CreationTime" value="-9223372036854775808" />
+<long name="ExpirationTime" value="-9223372036854775808" />
+<string name="Realm">passpoint.com</string>
+<boolean name="CheckAAAServerCertStatus" value="false" />
+<UserCredential>
+<string name="Username">blahblahblah</string>
+<string name="Password">doubleblahlah</string>
+<boolean name="MachineManaged" value="true" />
+<null name="SoftTokenApp" />
+<boolean name="AbleToShare" value="false" />
+<int name="EAPType" value="21" />
+<string name="NonEAPInnerMethod">PAP</string>
+</UserCredential>
+</Credential>
+<int name="CarrierId" value="-1" />
+<boolean name="AutoJoinEnabled" value="true" />
+<boolean name="IsMacRandomizationEnabled" value="true" />
+<int name="MeteredOverride" value="0" />
+</Configuration>
+<null name="RemediationCaCertificateAlias" />
+</Provider>
+</ProviderList>
+</PasspointConfigData>
+<OpenNetworkNotifierBlacklistConfigData />
+<NetworkRequestMap>
+<ApprovedAccessPointsPerApp>
+<string name="RequestorPackageName">com.android.cts.verifier</string>
+<AccessPoint>
+<string name="SSID">OPEN_SSID</string>
+<string name="BSSID">00:11:22:33:44:55</string>
+<int name="NetworkType" value="0" />
+</AccessPoint>
+</ApprovedAccessPointsPerApp>
+</NetworkRequestMap>
+<WakeupConfigStoreData>
+<FeatureState>
+<boolean name="IsActive" value="false" />
+<boolean name="IsOnboarded" value="false" />
+<int name="NotificationsShown" value="1" />
+</FeatureState>
+</WakeupConfigStoreData>
+</WifiConfigStoreData>
diff --git a/wifi/java/android/net/wifi/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml b/wifi/java/android/net/wifi/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml
new file mode 100644
index 0000000..4ecdd29
--- /dev/null
+++ b/wifi/java/android/net/wifi/migration_samples/User_WifiConfigStoreNetworkSuggestions.xml
@@ -0,0 +1,155 @@
+<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+<WifiConfigStoreData>
+<int name="Version" value="3" />
+<NetworkSuggestionMap>
+<NetworkSuggestionPerApp>
+<string name="SuggestorPackageName">com.android.cts.verifier</string>
+<null name="SuggestorFeatureId" />
+<boolean name="SuggestorHasUserApproved" value="true" />
+<int name="SuggestorMaxSize" value="1" />
+<int name="SuggestorUid" value="10228" />
+<int name="SuggestorCarrierId" value="-1" />
+<NetworkSuggestion>
+<WifiConfiguration>
+<string name="ConfigKey">&quot;OPEN_SSID&quot;NONE</string>
+<string name="SSID">&quot;OPEN_SSID&quot;</string>
+<null name="PreSharedKey" />
+<null name="WEPKeys" />
+<int name="WEPTxKeyIndex" value="0" />
+<boolean name="HiddenSSID" value="false" />
+<boolean name="RequirePMF" value="false" />
+<byte-array name="AllowedKeyMgmt" num="1">01</byte-array>
+<byte-array name="AllowedProtocols" num="0"></byte-array>
+<byte-array name="AllowedAuthAlgos" num="0"></byte-array>
+<byte-array name="AllowedGroupCiphers" num="0"></byte-array>
+<byte-array name="AllowedPairwiseCiphers" num="0"></byte-array>
+<byte-array name="AllowedGroupMgmtCiphers" num="0"></byte-array>
+<byte-array name="AllowedSuiteBCiphers" num="0"></byte-array>
+<boolean name="Shared" value="true" />
+<boolean name="AutoJoinEnabled" value="true" />
+<boolean name="Trusted" value="true" />
+<null name="BSSID" />
+<int name="Status" value="0" />
+<null name="FQDN" />
+<null name="ProviderFriendlyName" />
+<null name="LinkedNetworksList" />
+<null name="DefaultGwMacAddress" />
+<boolean name="ValidatedInternetAccess" value="false" />
+<boolean name="NoInternetAccessExpected" value="false" />
+<boolean name="MeteredHint" value="false" />
+<int name="MeteredOverride" value="1" />
+<boolean name="UseExternalScores" value="false" />
+<int name="NumAssociation" value="0" />
+<int name="CreatorUid" value="10228" />
+<string name="CreatorName">com.android.cts.verifier</string>
+<int name="LastUpdateUid" value="-1" />
+<null name="LastUpdateName" />
+<int name="LastConnectUid" value="0" />
+<boolean name="IsLegacyPasspointConfig" value="false" />
+<long-array name="RoamingConsortiumOIs" num="0" />
+<string name="RandomizedMacAddress">02:00:00:00:00:00</string>
+<int name="MacRandomizationSetting" value="1" />
+<int name="CarrierId" value="-1" />
+</WifiConfiguration>
+<boolean name="IsAppInteractionRequired" value="false" />
+<boolean name="IsUserInteractionRequired" value="false" />
+<boolean name="IsUserAllowedToManuallyConnect" value="false" />
+<boolean name="InitializedAutoJoinEnabled" value="true" />
+<boolean name="AutoJoinEnabled" value="true" />
+</NetworkSuggestion>
+<NetworkSuggestion>
+<WifiConfiguration>
+<string name="ConfigKey">passpoint.net</string>
+<null name="SSID" />
+<null name="PreSharedKey" />
+<null name="WEPKeys" />
+<int name="WEPTxKeyIndex" value="0" />
+<boolean name="HiddenSSID" value="false" />
+<boolean name="RequirePMF" value="false" />
+<byte-array name="AllowedKeyMgmt" num="0"></byte-array>
+<byte-array name="AllowedProtocols" num="0"></byte-array>
+<byte-array name="AllowedAuthAlgos" num="0"></byte-array>
+<byte-array name="AllowedGroupCiphers" num="0"></byte-array>
+<byte-array name="AllowedPairwiseCiphers" num="0"></byte-array>
+<byte-array name="AllowedGroupMgmtCiphers" num="0"></byte-array>
+<byte-array name="AllowedSuiteBCiphers" num="0"></byte-array>
+<boolean name="Shared" value="true" />
+<boolean name="AutoJoinEnabled" value="true" />
+<boolean name="Trusted" value="true" />
+<null name="BSSID" />
+<int name="Status" value="0" />
+<string name="FQDN">passpoint.net</string>
+<null name="ProviderFriendlyName" />
+<null name="LinkedNetworksList" />
+<null name="DefaultGwMacAddress" />
+<boolean name="ValidatedInternetAccess" value="false" />
+<boolean name="NoInternetAccessExpected" value="false" />
+<boolean name="MeteredHint" value="false" />
+<int name="MeteredOverride" value="0" />
+<boolean name="UseExternalScores" value="false" />
+<int name="NumAssociation" value="0" />
+<int name="CreatorUid" value="1000" />
+<string name="CreatorName">com.android.cts.verifier</string>
+<int name="LastUpdateUid" value="-1" />
+<null name="LastUpdateName" />
+<int name="LastConnectUid" value="0" />
+<boolean name="IsLegacyPasspointConfig" value="false" />
+<long-array name="RoamingConsortiumOIs" num="0" />
+<string name="RandomizedMacAddress">02:00:00:00:00:00</string>
+<int name="MacRandomizationSetting" value="1" />
+<int name="CarrierId" value="-1" />
+<boolean name="IsMostRecentlyConnected" value="false" />
+</WifiConfiguration>
+<PasspointConfiguration>
+<int name="UpdateIdentifier" value="-2147483648" />
+<int name="CredentialPriority" value="-2147483648" />
+<null name="TrustRootCertList" />
+<long name="SubscriptionCreationTime" value="-9223372036854775808" />
+<long name="SubscriptionExpirationTime" value="-9223372036854775808" />
+<null name="SubscriptionType" />
+<long name="UsageLimitTimePeriod" value="-9223372036854775808" />
+<long name="UsageLimitStartTime" value="-9223372036854775808" />
+<long name="UsageLimitDataLimit" value="-9223372036854775808" />
+<long name="UsageLimitTimeLimit" value="-9223372036854775808" />
+<HomeSP>
+<string name="FQDN">passpoint.net</string>
+<string name="FriendlyName">Passpoint Friendly Name</string>
+<null name="IconURL" />
+<null name="HomeNetworkIDs" />
+<null name="MatchAllOIs" />
+<null name="MatchAnyOIs" />
+<null name="OtherHomePartners" />
+<null name="RoamingConsortiumOIs" />
+</HomeSP>
+<Credential>
+<long name="CreationTime" value="-9223372036854775808" />
+<long name="ExpirationTime" value="-9223372036854775808" />
+<string name="Realm">passpoint.com</string>
+<boolean name="CheckAAAServerCertStatus" value="false" />
+<UserCredential>
+<string name="Username">blahblahblah</string>
+<string name="Password">doubleblahblah</string>
+<boolean name="MachineManaged" value="false" />
+<null name="SoftTokenApp" />
+<boolean name="AbleToShare" value="false" />
+<int name="EAPType" value="21" />
+<string name="NonEAPInnerMethod">PAP</string>
+</UserCredential>
+</Credential>
+<int name="CarrierId" value="-1" />
+<boolean name="AutoJoinEnabled" value="true" />
+<boolean name="IsMacRandomizationEnabled" value="true" />
+<int name="MeteredOverride" value="0" />
+</PasspointConfiguration>
+<boolean name="IsAppInteractionRequired" value="false" />
+<boolean name="IsUserInteractionRequired" value="false" />
+<boolean name="IsUserAllowedToManuallyConnect" value="true" />
+<boolean name="InitializedAutoJoinEnabled" value="true" />
+<boolean name="AutoJoinEnabled" value="true" />
+</NetworkSuggestion>
+</NetworkSuggestionPerApp>
+</NetworkSuggestionMap>
+<ImsiPrivacyProtectionExemptionMap>
+<map name="CarrierExemptionMap" />
+</ImsiPrivacyProtectionExemptionMap>
+</WifiConfigStoreData>