Merge "Revert "Fix issue in attached layouting"" into qt-dev
diff --git a/Android.bp b/Android.bp
index 6a85f62..c3025e8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -480,10 +480,7 @@
         "media/java/android/media/IMediaHTTPConnection.aidl",
         "media/java/android/media/IMediaHTTPService.aidl",
         "media/java/android/media/IMediaResourceMonitor.aidl",
-        "media/java/android/media/IMediaRoute2Callback.aidl",
-        "media/java/android/media/IMediaRoute2Provider.aidl",
         "media/java/android/media/IMediaRouterClient.aidl",
-        "media/java/android/media/IMediaRouter2ManagerClient.aidl",
         "media/java/android/media/IMediaRouterService.aidl",
         "media/java/android/media/IMediaScannerListener.aidl",
         "media/java/android/media/IMediaScannerService.aidl",
@@ -1836,4 +1833,4 @@
     name: "framework-aidl-mappings",
     srcs: [":framework-defaults"],
     output: "framework-aidl-mappings.txt"
-}
+}
\ No newline at end of file
diff --git a/api/current.txt b/api/current.txt
index ccfc0f5..34ba3fc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -734,6 +734,7 @@
     field public static final int iconTintMode = 16844127; // 0x101055f
     field public static final int iconifiedByDefault = 16843514; // 0x10102fa
     field public static final int id = 16842960; // 0x10100d0
+    field public static final int identifier = 16844204; // 0x10105ac
     field public static final int ignoreGravity = 16843263; // 0x10101ff
     field public static final int imageButtonStyle = 16842866; // 0x1010072
     field public static final int imageWellStyle = 16842867; // 0x1010073
@@ -9000,7 +9001,7 @@
     method @Nullable public byte[] getManufacturerSpecificData(int);
     method public java.util.Map<android.os.ParcelUuid,byte[]> getServiceData();
     method @Nullable public byte[] getServiceData(android.os.ParcelUuid);
-    method @Nullable public java.util.List<android.os.ParcelUuid> getServiceSolicitationUuids();
+    method @NonNull public java.util.List<android.os.ParcelUuid> getServiceSolicitationUuids();
     method public java.util.List<android.os.ParcelUuid> getServiceUuids();
     method public int getTxPowerLevel();
   }
@@ -10085,6 +10086,7 @@
     method public int getFlags();
     method @Nullable public float[] getFloatArrayExtra(String);
     method public float getFloatExtra(String, float);
+    method @Nullable public String getIdentifier();
     method @Nullable public int[] getIntArrayExtra(String);
     method public int getIntExtra(String, int);
     method @Nullable public java.util.ArrayList<java.lang.Integer> getIntegerArrayListExtra(String);
@@ -10168,6 +10170,7 @@
     method @NonNull public android.content.Intent setDataAndTypeAndNormalize(@NonNull android.net.Uri, @Nullable String);
     method public void setExtrasClassLoader(@Nullable ClassLoader);
     method @NonNull public android.content.Intent setFlags(int);
+    method @NonNull public android.content.Intent setIdentifier(@Nullable String);
     method @NonNull public android.content.Intent setPackage(@Nullable String);
     method public void setSelector(@Nullable android.content.Intent);
     method public void setSourceBounds(@Nullable android.graphics.Rect);
@@ -10428,6 +10431,7 @@
     field public static final int FILL_IN_CLIP_DATA = 128; // 0x80
     field public static final int FILL_IN_COMPONENT = 8; // 0x8
     field public static final int FILL_IN_DATA = 2; // 0x2
+    field public static final int FILL_IN_IDENTIFIER = 256; // 0x100
     field public static final int FILL_IN_PACKAGE = 16; // 0x10
     field public static final int FILL_IN_SELECTOR = 64; // 0x40
     field public static final int FILL_IN_SOURCE_BOUNDS = 32; // 0x20
@@ -23041,6 +23045,7 @@
   public final class AudioAttributes implements android.os.Parcelable {
     method public boolean areHapticChannelsMuted();
     method public int describeContents();
+    method public int getAllowedCapturePolicy();
     method public int getContentType();
     method public int getFlags();
     method public int getUsage();
@@ -23246,6 +23251,7 @@
     method public int generateAudioSessionId();
     method @NonNull public java.util.List<android.media.AudioPlaybackConfiguration> getActivePlaybackConfigurations();
     method @NonNull public java.util.List<android.media.AudioRecordingConfiguration> getActiveRecordingConfigurations();
+    method public int getAllowedCapturePolicy();
     method public android.media.AudioDeviceInfo[] getDevices(int);
     method public java.util.List<android.media.MicrophoneInfo> getMicrophones() throws java.io.IOException;
     method public int getMode();
@@ -23418,6 +23424,10 @@
   }
 
   public final class AudioPlaybackCaptureConfiguration {
+    method @NonNull public int[] getExcludeUids();
+    method @NonNull public int[] getExcludeUsages();
+    method @NonNull public int[] getMatchingUids();
+    method @NonNull public int[] getMatchingUsages();
     method @NonNull public android.media.projection.MediaProjection getMediaProjection();
   }
 
@@ -23776,27 +23786,6 @@
     field public static final int QUALITY_MEDIUM = 1; // 0x1
   }
 
-  public class DataSourceDesc {
-    method public long getEndPosition();
-    method @Nullable public String getMediaId();
-    method public long getStartPosition();
-    field public static final long LONG_MAX_TIME_MS = 576460752303423L; // 0x20c49ba5e353fL
-    field public static final long POSITION_UNKNOWN = 576460752303423L; // 0x20c49ba5e353fL
-  }
-
-  public static final class DataSourceDesc.Builder {
-    ctor public DataSourceDesc.Builder();
-    ctor public DataSourceDesc.Builder(@Nullable android.media.DataSourceDesc);
-    method @NonNull public android.media.DataSourceDesc build();
-    method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.net.Uri);
-    method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.net.Uri, @Nullable java.util.Map<java.lang.String,java.lang.String>, @Nullable java.util.List<java.net.HttpCookie>);
-    method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor);
-    method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor, long, long);
-    method @NonNull public android.media.DataSourceDesc.Builder setEndPosition(long);
-    method @NonNull public android.media.DataSourceDesc.Builder setMediaId(@Nullable String);
-    method @NonNull public android.media.DataSourceDesc.Builder setStartPosition(long);
-  }
-
   public final class DeniedByServerException extends android.media.MediaDrmException {
     ctor public DeniedByServerException(String);
   }
@@ -24663,8 +24652,6 @@
   }
 
   public class MediaController2 implements java.lang.AutoCloseable {
-    ctor public MediaController2(@NonNull android.content.Context, @NonNull android.media.Session2Token);
-    ctor public MediaController2(@NonNull android.content.Context, @NonNull android.media.Session2Token, @NonNull java.util.concurrent.Executor, @NonNull android.media.MediaController2.ControllerCallback);
     method public void cancelSessionCommand(@NonNull Object);
     method public void close();
     method @Nullable public android.media.Session2Token getConnectedSessionToken();
@@ -24672,6 +24659,13 @@
     method @NonNull public Object sendSessionCommand(@NonNull android.media.Session2Command, @Nullable android.os.Bundle);
   }
 
+  public static final class MediaController2.Builder {
+    ctor public MediaController2.Builder(@NonNull android.content.Context, @NonNull android.media.Session2Token);
+    method @NonNull public android.media.MediaController2 build();
+    method @NonNull public android.media.MediaController2.Builder setConnectionHints(@NonNull android.os.Bundle);
+    method @NonNull public android.media.MediaController2.Builder setControllerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaController2.ControllerCallback);
+  }
+
   public abstract static class MediaController2.ControllerCallback {
     ctor public MediaController2.ControllerCallback();
     method public void onCommandResult(@NonNull android.media.MediaController2, @NonNull Object, @NonNull android.media.Session2Command, @NonNull android.media.Session2Command.Result);
@@ -25555,225 +25549,6 @@
     field public static final int MEDIA_TRACK_TYPE_VIDEO = 1; // 0x1
   }
 
-  public class MediaPlayer2 implements android.media.AudioRouting java.lang.AutoCloseable {
-    ctor public MediaPlayer2(@NonNull android.content.Context);
-    method public void addOnRoutingChangedListener(@NonNull android.media.AudioRouting.OnRoutingChangedListener, @Nullable android.os.Handler);
-    method @NonNull public Object attachAuxEffect(int);
-    method public boolean cancelCommand(@NonNull Object);
-    method public void clearDrmEventCallback();
-    method @NonNull public Object clearNextDataSources();
-    method public void clearPendingCommands();
-    method public void close();
-    method @NonNull public Object deselectTrack(@NonNull android.media.MediaPlayer2.TrackInfo);
-    method @NonNull public Object deselectTrack(@NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.TrackInfo);
-    method @NonNull public android.media.AudioAttributes getAudioAttributes();
-    method public int getAudioSessionId();
-    method public long getBufferedPosition();
-    method public long getBufferedPosition(@NonNull android.media.DataSourceDesc);
-    method @Nullable public android.media.DataSourceDesc getCurrentDataSource();
-    method public long getCurrentPosition();
-    method public long getDuration();
-    method public long getDuration(@NonNull android.media.DataSourceDesc);
-    method public float getMaxPlayerVolume();
-    method @Nullable public android.os.PersistableBundle getMetrics();
-    method @NonNull public android.media.PlaybackParams getPlaybackParams();
-    method public float getPlayerVolume();
-    method @Nullable public android.media.AudioDeviceInfo getPreferredDevice();
-    method @Nullable public android.media.AudioDeviceInfo getRoutedDevice();
-    method @Nullable public android.media.MediaPlayer2.TrackInfo getSelectedTrack(int);
-    method @Nullable public android.media.MediaPlayer2.TrackInfo getSelectedTrack(@NonNull android.media.DataSourceDesc, int);
-    method public int getState();
-    method @NonNull public android.media.SyncParams getSyncParams();
-    method @Nullable public android.media.MediaTimestamp getTimestamp();
-    method @NonNull public java.util.List<android.media.MediaPlayer2.TrackInfo> getTrackInfo();
-    method @NonNull public java.util.List<android.media.MediaPlayer2.TrackInfo> getTrackInfo(@NonNull android.media.DataSourceDesc);
-    method @NonNull public android.util.Size getVideoSize();
-    method public boolean isLooping();
-    method @NonNull public Object loopCurrent(boolean);
-    method @NonNull public Object notifyWhenCommandLabelReached(@NonNull Object);
-    method @NonNull public Object pause();
-    method @NonNull public Object play();
-    method @NonNull public Object prepare();
-    method public void registerEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaPlayer2.EventCallback);
-    method public void removeOnRoutingChangedListener(@NonNull android.media.AudioRouting.OnRoutingChangedListener);
-    method public void reset();
-    method @NonNull public Object seekTo(long);
-    method @NonNull public Object seekTo(long, int);
-    method @NonNull public Object selectTrack(@NonNull android.media.MediaPlayer2.TrackInfo);
-    method @NonNull public Object selectTrack(@NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.TrackInfo);
-    method @NonNull public Object setAudioAttributes(@NonNull android.media.AudioAttributes);
-    method @NonNull public Object setAudioSessionId(int);
-    method @NonNull public Object setAuxEffectSendLevel(float);
-    method @NonNull public Object setDataSource(@NonNull android.media.DataSourceDesc);
-    method @NonNull public Object setDisplay(@Nullable android.view.SurfaceHolder);
-    method public void setDrmEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaPlayer2.DrmEventCallback);
-    method @NonNull public Object setNextDataSource(@NonNull android.media.DataSourceDesc);
-    method @NonNull public Object setNextDataSources(@NonNull java.util.List<android.media.DataSourceDesc>);
-    method @NonNull public Object setPlaybackParams(@NonNull android.media.PlaybackParams);
-    method @NonNull public Object setPlayerVolume(float);
-    method public boolean setPreferredDevice(@Nullable android.media.AudioDeviceInfo);
-    method @NonNull public Object setScreenOnWhilePlaying(boolean);
-    method @NonNull public Object setSurface(@Nullable android.view.Surface);
-    method @NonNull public Object setSyncParams(@NonNull android.media.SyncParams);
-    method @NonNull public Object setWakeLock(@NonNull android.os.PowerManager.WakeLock);
-    method @NonNull public Object skipToNext();
-    method public void unregisterEventCallback(@NonNull android.media.MediaPlayer2.EventCallback);
-    field public static final int CALL_COMPLETED_ATTACH_AUX_EFFECT = 1; // 0x1
-    field public static final int CALL_COMPLETED_CLEAR_NEXT_DATA_SOURCES = 30; // 0x1e
-    field public static final int CALL_COMPLETED_DESELECT_TRACK = 2; // 0x2
-    field public static final int CALL_COMPLETED_LOOP_CURRENT = 3; // 0x3
-    field public static final int CALL_COMPLETED_PAUSE = 4; // 0x4
-    field public static final int CALL_COMPLETED_PLAY = 5; // 0x5
-    field public static final int CALL_COMPLETED_PREPARE = 6; // 0x6
-    field public static final int CALL_COMPLETED_SEEK_TO = 14; // 0xe
-    field public static final int CALL_COMPLETED_SELECT_TRACK = 15; // 0xf
-    field public static final int CALL_COMPLETED_SET_AUDIO_ATTRIBUTES = 16; // 0x10
-    field public static final int CALL_COMPLETED_SET_AUDIO_SESSION_ID = 17; // 0x11
-    field public static final int CALL_COMPLETED_SET_AUX_EFFECT_SEND_LEVEL = 18; // 0x12
-    field public static final int CALL_COMPLETED_SET_DATA_SOURCE = 19; // 0x13
-    field public static final int CALL_COMPLETED_SET_DISPLAY = 33; // 0x21
-    field public static final int CALL_COMPLETED_SET_NEXT_DATA_SOURCE = 22; // 0x16
-    field public static final int CALL_COMPLETED_SET_NEXT_DATA_SOURCES = 23; // 0x17
-    field public static final int CALL_COMPLETED_SET_PLAYBACK_PARAMS = 24; // 0x18
-    field public static final int CALL_COMPLETED_SET_PLAYER_VOLUME = 26; // 0x1a
-    field public static final int CALL_COMPLETED_SET_SCREEN_ON_WHILE_PLAYING = 35; // 0x23
-    field public static final int CALL_COMPLETED_SET_SURFACE = 27; // 0x1b
-    field public static final int CALL_COMPLETED_SET_SYNC_PARAMS = 28; // 0x1c
-    field public static final int CALL_COMPLETED_SET_WAKE_LOCK = 34; // 0x22
-    field public static final int CALL_COMPLETED_SKIP_TO_NEXT = 29; // 0x1d
-    field public static final int CALL_STATUS_BAD_VALUE = 2; // 0x2
-    field public static final int CALL_STATUS_ERROR_IO = 4; // 0x4
-    field public static final int CALL_STATUS_ERROR_UNKNOWN = -2147483648; // 0x80000000
-    field public static final int CALL_STATUS_INVALID_OPERATION = 1; // 0x1
-    field public static final int CALL_STATUS_NO_DRM_SCHEME = 6; // 0x6
-    field public static final int CALL_STATUS_NO_ERROR = 0; // 0x0
-    field public static final int CALL_STATUS_PERMISSION_DENIED = 3; // 0x3
-    field public static final int CALL_STATUS_SKIPPED = 5; // 0x5
-    field public static final int MEDIA_ERROR_IO = -1004; // 0xfffffc14
-    field public static final int MEDIA_ERROR_MALFORMED = -1007; // 0xfffffc11
-    field public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200; // 0xc8
-    field public static final int MEDIA_ERROR_TIMED_OUT = -110; // 0xffffff92
-    field public static final int MEDIA_ERROR_UNKNOWN = 1; // 0x1
-    field public static final int MEDIA_ERROR_UNSUPPORTED = -1010; // 0xfffffc0e
-    field public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804; // 0x324
-    field public static final int MEDIA_INFO_AUDIO_RENDERING_START = 4; // 0x4
-    field public static final int MEDIA_INFO_BAD_INTERLEAVING = 800; // 0x320
-    field public static final int MEDIA_INFO_BUFFERING_END = 702; // 0x2be
-    field public static final int MEDIA_INFO_BUFFERING_START = 701; // 0x2bd
-    field public static final int MEDIA_INFO_BUFFERING_UPDATE = 704; // 0x2c0
-    field public static final int MEDIA_INFO_DATA_SOURCE_END = 5; // 0x5
-    field public static final int MEDIA_INFO_DATA_SOURCE_LIST_END = 6; // 0x6
-    field public static final int MEDIA_INFO_DATA_SOURCE_REPEAT = 7; // 0x7
-    field public static final int MEDIA_INFO_DATA_SOURCE_START = 2; // 0x2
-    field public static final int MEDIA_INFO_METADATA_UPDATE = 802; // 0x322
-    field public static final int MEDIA_INFO_NOT_SEEKABLE = 801; // 0x321
-    field public static final int MEDIA_INFO_PREPARED = 100; // 0x64
-    field public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; // 0x386
-    field public static final int MEDIA_INFO_UNKNOWN = 1; // 0x1
-    field public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; // 0x385
-    field public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805; // 0x325
-    field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
-    field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
-    field public static final int PLAYER_STATE_ERROR = 1005; // 0x3ed
-    field public static final int PLAYER_STATE_IDLE = 1001; // 0x3e9
-    field public static final int PLAYER_STATE_PAUSED = 1003; // 0x3eb
-    field public static final int PLAYER_STATE_PLAYING = 1004; // 0x3ec
-    field public static final int PLAYER_STATE_PREPARED = 1002; // 0x3ea
-    field public static final int PREPARE_DRM_STATUS_KEY_EXCHANGE_ERROR = 7; // 0x7
-    field public static final int PREPARE_DRM_STATUS_PREPARATION_ERROR = 3; // 0x3
-    field public static final int PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR = 1; // 0x1
-    field public static final int PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR = 2; // 0x2
-    field public static final int PREPARE_DRM_STATUS_RESOURCE_BUSY = 5; // 0x5
-    field public static final int PREPARE_DRM_STATUS_RESTORE_ERROR = 6; // 0x6
-    field public static final int PREPARE_DRM_STATUS_SUCCESS = 0; // 0x0
-    field public static final int PREPARE_DRM_STATUS_UNSUPPORTED_SCHEME = 4; // 0x4
-    field public static final int SEEK_CLOSEST = 3; // 0x3
-    field public static final int SEEK_CLOSEST_SYNC = 2; // 0x2
-    field public static final int SEEK_NEXT_SYNC = 1; // 0x1
-    field public static final int SEEK_PREVIOUS_SYNC = 0; // 0x0
-  }
-
-  public abstract static class MediaPlayer2.DrmEventCallback {
-    ctor public MediaPlayer2.DrmEventCallback();
-    method public void onDrmConfig(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm);
-    method @Nullable public abstract android.media.MediaPlayer2.DrmPreparationInfo onDrmInfo(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.DrmInfo);
-    method @NonNull public abstract byte[] onDrmKeyRequest(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm.KeyRequest);
-    method public void onDrmPrepared(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, @Nullable byte[]);
-  }
-
-  public static final class MediaPlayer2.DrmInfo {
-    method @NonNull public java.util.Map<java.util.UUID,byte[]> getPssh();
-    method @NonNull public java.util.List<java.util.UUID> getSupportedSchemes();
-  }
-
-  public static final class MediaPlayer2.DrmPreparationInfo {
-    method @Nullable public byte[] getInitData();
-    method @Nullable public byte[] getKeySetId();
-    method public int getKeyType();
-    method @Nullable public String getMimeType();
-    method @Nullable public java.util.Map<java.lang.String,java.lang.String> getOptionalParameters();
-    method @NonNull public java.util.UUID getUuid();
-  }
-
-  public static final class MediaPlayer2.DrmPreparationInfo.Builder {
-    ctor public MediaPlayer2.DrmPreparationInfo.Builder(@NonNull java.util.UUID);
-    method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo build();
-    method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setInitData(@Nullable byte[]);
-    method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setKeySetId(@Nullable byte[]);
-    method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setKeyType(int);
-    method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setMimeType(@Nullable String);
-    method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setOptionalParameters(@Nullable java.util.Map<java.lang.String,java.lang.String>);
-  }
-
-  public static class MediaPlayer2.EventCallback {
-    ctor public MediaPlayer2.EventCallback();
-    method public void onCallCompleted(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, int);
-    method public void onCommandLabelReached(@NonNull android.media.MediaPlayer2, @NonNull Object);
-    method public void onError(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, int);
-    method public void onInfo(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, int);
-    method public void onMediaTimeDiscontinuity(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaTimestamp);
-    method public void onSubtitleData(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.SubtitleData);
-    method public void onTimedMetaDataAvailable(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.TimedMetaData);
-    method public void onVideoSizeChanged(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.util.Size);
-  }
-
-  public static final class MediaPlayer2.MetricsConstants {
-    field public static final String CODEC_AUDIO = "android.media.mediaplayer.audio.codec";
-    field public static final String CODEC_VIDEO = "android.media.mediaplayer.video.codec";
-    field public static final String DURATION = "android.media.mediaplayer.durationMs";
-    field public static final String ERRORS = "android.media.mediaplayer.err";
-    field public static final String ERROR_CODE = "android.media.mediaplayer.errcode";
-    field public static final String FRAMES = "android.media.mediaplayer.frames";
-    field public static final String FRAMES_DROPPED = "android.media.mediaplayer.dropped";
-    field public static final String HEIGHT = "android.media.mediaplayer.height";
-    field public static final String MIME_TYPE_AUDIO = "android.media.mediaplayer.audio.mime";
-    field public static final String MIME_TYPE_VIDEO = "android.media.mediaplayer.video.mime";
-    field public static final String PLAYING = "android.media.mediaplayer.playingMs";
-    field public static final String WIDTH = "android.media.mediaplayer.width";
-  }
-
-  public static final class MediaPlayer2.NoDrmSchemeException extends android.media.MediaDrmException {
-    ctor public MediaPlayer2.NoDrmSchemeException(@Nullable String);
-  }
-
-  public static final class MediaPlayer2.SubtitleData {
-    method @NonNull public byte[] getData();
-    method public long getDurationUs();
-    method public long getStartTimeUs();
-    method @NonNull public android.media.MediaPlayer2.TrackInfo getTrackInfo();
-  }
-
-  public static class MediaPlayer2.TrackInfo {
-    method @Nullable public android.media.MediaFormat getFormat();
-    method @NonNull public String getLanguage();
-    method public int getTrackType();
-    field public static final int MEDIA_TRACK_TYPE_AUDIO = 2; // 0x2
-    field public static final int MEDIA_TRACK_TYPE_METADATA = 5; // 0x5
-    field public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4; // 0x4
-    field public static final int MEDIA_TRACK_TYPE_UNKNOWN = 0; // 0x0
-    field public static final int MEDIA_TRACK_TYPE_VIDEO = 1; // 0x1
-  }
-
   public class MediaRecorder implements android.media.AudioRecordingMonitor android.media.AudioRouting android.media.MicrophoneDirection {
     ctor public MediaRecorder();
     method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
@@ -26080,6 +25855,7 @@
   }
 
   public static final class MediaSession2.ControllerInfo {
+    method @NonNull public android.os.Bundle getConnectionHints();
     method @NonNull public String getPackageName();
     method @NonNull public android.media.session.MediaSessionManager.RemoteUserInfo getRemoteUserInfo();
     method public int getUid();
@@ -26099,7 +25875,7 @@
     method public final void addSession(@NonNull android.media.MediaSession2);
     method @NonNull public final java.util.List<android.media.MediaSession2> getSessions();
     method @CallSuper @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent);
-    method @NonNull public abstract android.media.MediaSession2 onGetPrimarySession();
+    method @Nullable public abstract android.media.MediaSession2 onGetSession(@NonNull android.media.MediaSession2.ControllerInfo);
     method @Nullable public abstract android.media.MediaSession2Service.MediaNotification onUpdateNotification(@NonNull android.media.MediaSession2);
     method public final void removeSession(@NonNull android.media.MediaSession2);
     field public static final String SERVICE_INTERFACE = "android.media.MediaSession2Service";
@@ -28756,10 +28532,13 @@
 
   public final class DnsResolver {
     method @NonNull public static android.net.DnsResolver getInstance();
-    method public <T> void query(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback<T>);
-    method public <T> void query(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback<T>);
-    method public void query(@Nullable android.net.Network, @NonNull String, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.InetAddressAnswerCallback);
+    method public void query(@Nullable android.net.Network, @NonNull String, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super java.util.List<java.net.InetAddress>>);
+    method public void query(@Nullable android.net.Network, @NonNull String, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super java.util.List<java.net.InetAddress>>);
+    method public void rawQuery(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super byte[]>);
+    method public void rawQuery(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super byte[]>);
     field public static final int CLASS_IN = 1; // 0x1
+    field public static final int ERROR_PARSE = 0; // 0x0
+    field public static final int ERROR_SYSTEM = 1; // 0x1
     field public static final int FLAG_EMPTY = 0; // 0x0
     field public static final int FLAG_NO_CACHE_LOOKUP = 4; // 0x4
     field public static final int FLAG_NO_CACHE_STORE = 2; // 0x2
@@ -28768,23 +28547,13 @@
     field public static final int TYPE_AAAA = 28; // 0x1c
   }
 
-  public abstract static class DnsResolver.AnswerCallback<T> {
-    ctor public DnsResolver.AnswerCallback(@NonNull android.net.DnsResolver.AnswerParser<T>);
-    method public abstract void onAnswer(@NonNull T);
-    method public abstract void onParseException(@NonNull android.net.ParseException);
-    method public abstract void onQueryException(@NonNull android.system.ErrnoException);
+  public static interface DnsResolver.Callback<T> {
+    method public void onAnswer(@NonNull T, int);
+    method public void onError(@NonNull android.net.DnsResolver.DnsException);
   }
 
-  public static interface DnsResolver.AnswerParser<T> {
-    method @NonNull public T parse(@NonNull byte[]) throws android.net.ParseException;
-  }
-
-  public abstract static class DnsResolver.InetAddressAnswerCallback extends android.net.DnsResolver.AnswerCallback<java.util.List<java.net.InetAddress>> {
-    ctor public DnsResolver.InetAddressAnswerCallback();
-  }
-
-  public abstract static class DnsResolver.RawAnswerCallback extends android.net.DnsResolver.AnswerCallback<byte[]> {
-    ctor public DnsResolver.RawAnswerCallback();
+  public static class DnsResolver.DnsException extends java.lang.Exception {
+    field public final int code;
   }
 
   public class InetAddresses {
@@ -29110,8 +28879,6 @@
   }
 
   public class ParseException extends java.lang.RuntimeException {
-    ctor public ParseException(@NonNull String);
-    ctor public ParseException(@NonNull String, @NonNull Throwable);
     field public String response;
   }
 
@@ -38591,7 +38358,6 @@
     field public static final String ARTIST_KEY = "artist_key";
     field public static final String BOOKMARK = "bookmark";
     field public static final String COMPOSER = "composer";
-    field public static final String DURATION = "duration";
     field public static final String IS_ALARM = "is_alarm";
     field public static final String IS_AUDIOBOOK = "is_audiobook";
     field public static final String IS_MUSIC = "is_music";
@@ -38674,7 +38440,6 @@
   }
 
   public static interface MediaStore.DownloadColumns extends android.provider.MediaStore.MediaColumns {
-    field public static final String DESCRIPTION = "description";
     field public static final String DOWNLOAD_URI = "download_uri";
     field public static final String REFERER_URI = "referer_uri";
   }
@@ -38709,16 +38474,11 @@
   }
 
   public static interface MediaStore.Images.ImageColumns extends android.provider.MediaStore.MediaColumns {
-    field public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
-    field public static final String BUCKET_ID = "bucket_id";
-    field public static final String DATE_TAKEN = "datetaken";
     field public static final String DESCRIPTION = "description";
-    field public static final String GROUP_ID = "group_id";
     field public static final String IS_PRIVATE = "isprivate";
     field @Deprecated public static final String LATITUDE = "latitude";
     field @Deprecated public static final String LONGITUDE = "longitude";
     field @Deprecated public static final String MINI_THUMB_MAGIC = "mini_thumb_magic";
-    field public static final String ORIENTATION = "orientation";
     field @Deprecated public static final String PICASA_ID = "picasa_id";
   }
 
@@ -38762,16 +38522,22 @@
   }
 
   public static interface MediaStore.MediaColumns extends android.provider.BaseColumns {
+    field public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
+    field public static final String BUCKET_ID = "bucket_id";
     field @Deprecated public static final String DATA = "_data";
     field public static final String DATE_ADDED = "date_added";
     field public static final String DATE_EXPIRES = "date_expires";
     field public static final String DATE_MODIFIED = "date_modified";
+    field public static final String DATE_TAKEN = "datetaken";
     field public static final String DISPLAY_NAME = "_display_name";
     field public static final String DOCUMENT_ID = "document_id";
+    field public static final String DURATION = "duration";
+    field public static final String GROUP_ID = "group_id";
     field public static final String HEIGHT = "height";
     field public static final String INSTANCE_ID = "instance_id";
     field public static final String IS_PENDING = "is_pending";
     field public static final String MIME_TYPE = "mime_type";
+    field public static final String ORIENTATION = "orientation";
     field public static final String ORIGINAL_DOCUMENT_ID = "original_document_id";
     field public static final String OWNER_PACKAGE_NAME = "owner_package_name";
     field public static final String RELATIVE_PATH = "relative_path";
@@ -38820,13 +38586,8 @@
     field public static final String ALBUM = "album";
     field public static final String ARTIST = "artist";
     field public static final String BOOKMARK = "bookmark";
-    field public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
-    field public static final String BUCKET_ID = "bucket_id";
     field public static final String CATEGORY = "category";
-    field public static final String DATE_TAKEN = "datetaken";
     field public static final String DESCRIPTION = "description";
-    field public static final String DURATION = "duration";
-    field public static final String GROUP_ID = "group_id";
     field public static final String IS_PRIVATE = "isprivate";
     field public static final String LANGUAGE = "language";
     field @Deprecated public static final String LATITUDE = "latitude";
@@ -39335,7 +39096,7 @@
     field @Deprecated public static final String BEARER = "bearer";
     field public static final String CARRIER_ENABLED = "carrier_enabled";
     field public static final String CARRIER_ID = "carrier_id";
-    field public static final android.net.Uri CONTENT_URI;
+    field @NonNull public static final android.net.Uri CONTENT_URI;
     field public static final String CURRENT = "current";
     field public static final String DEFAULT_SORT_ORDER = "name ASC";
     field @Deprecated public static final String MCC = "mcc";
@@ -39354,7 +39115,7 @@
     field public static final String PROXY = "proxy";
     field public static final String ROAMING_PROTOCOL = "roaming_protocol";
     field public static final String SERVER = "server";
-    field public static final android.net.Uri SIM_APN_URI;
+    field @NonNull public static final android.net.Uri SIM_APN_URI;
     field public static final String SUBSCRIPTION_ID = "sub_id";
     field public static final String TYPE = "type";
     field public static final String USER = "user";
@@ -48577,7 +48338,6 @@
     method public static boolean logEvent(int);
     method public static boolean logStart(int);
     method public static boolean logStop(int);
-    method public static void write(int, @NonNull java.lang.Object...);
   }
 
   public class StringBuilderPrinter implements android.util.Printer {
@@ -54023,7 +53783,7 @@
     method public int getEnd();
     method @NonNull public String getEntity(int);
     method public int getEntityCount();
-    method public android.os.Bundle getExtras();
+    method @NonNull public android.os.Bundle getExtras();
     method public int getStart();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.view.textclassifier.TextLinks.TextLink> CREATOR;
diff --git a/api/removed.txt b/api/removed.txt
index 70ff50e..8836326 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -522,6 +522,22 @@
     method @Deprecated public static void untrash(@NonNull android.content.Context, @NonNull android.net.Uri);
   }
 
+  public static interface MediaStore.Audio.AudioColumns extends android.provider.MediaStore.MediaColumns {
+    field public static final String DURATION = "duration";
+  }
+
+  public static interface MediaStore.DownloadColumns extends android.provider.MediaStore.MediaColumns {
+    field @Deprecated public static final String DESCRIPTION = "description";
+  }
+
+  public static interface MediaStore.Images.ImageColumns extends android.provider.MediaStore.MediaColumns {
+    field public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
+    field public static final String BUCKET_ID = "bucket_id";
+    field public static final String DATE_TAKEN = "datetaken";
+    field public static final String GROUP_ID = "group_id";
+    field public static final String ORIENTATION = "orientation";
+  }
+
   public static interface MediaStore.MediaColumns extends android.provider.BaseColumns {
     field @Deprecated public static final String HASH = "_hash";
     field @Deprecated public static final String IS_TRASHED = "is_trashed";
@@ -546,6 +562,14 @@
     method @NonNull public android.net.Uri publish();
   }
 
+  public static interface MediaStore.Video.VideoColumns extends android.provider.MediaStore.MediaColumns {
+    field public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
+    field public static final String BUCKET_ID = "bucket_id";
+    field public static final String DATE_TAKEN = "datetaken";
+    field public static final String DURATION = "duration";
+    field public static final String GROUP_ID = "group_id";
+  }
+
   public static final class Settings.Global extends android.provider.Settings.NameValueTable {
     field @Deprecated public static final String CONTACT_METADATA_SYNC = "contact_metadata_sync";
   }
diff --git a/api/system-current.txt b/api/system-current.txt
index 026ce09..ae27daf 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -254,8 +254,6 @@
     field public static final int config_defaultAssistant = 17039393; // 0x1040021
     field public static final int config_defaultBrowser = 17039394; // 0x1040022
     field public static final int config_defaultDialer = 17039395; // 0x1040023
-    field public static final int config_defaultGallery = 17039398; // 0x1040026
-    field public static final int config_defaultMusic = 17039397; // 0x1040025
     field public static final int config_defaultSms = 17039396; // 0x1040024
     field public static final int config_feedbackIntentExtraKey = 17039391; // 0x104001f
     field public static final int config_feedbackIntentNameKey = 17039392; // 0x1040020
@@ -564,6 +562,7 @@
     method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean addConfiguration(long, byte[]);
     method @Deprecated @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getData(long);
     method @Deprecated @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getMetadata();
+    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] getRegisteredExperimentIds() throws android.app.StatsManager.StatsUnavailableException;
     method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getReports(long) throws android.app.StatsManager.StatsUnavailableException;
     method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getStatsMetadata() throws android.app.StatsManager.StatsUnavailableException;
     method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void removeConfig(long) throws android.app.StatsManager.StatsUnavailableException;
@@ -1217,7 +1216,6 @@
     method public int getUsageSource();
     method @RequiresPermission(allOf={android.Manifest.permission.SUSPEND_APPS, android.Manifest.permission.OBSERVE_APP_USAGE}) public void registerAppUsageLimitObserver(int, @NonNull String[], @NonNull java.time.Duration, @NonNull java.time.Duration, @Nullable android.app.PendingIntent);
     method @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerAppUsageObserver(int, @NonNull String[], long, @NonNull java.util.concurrent.TimeUnit, @NonNull android.app.PendingIntent);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerUsageSessionObserver(int, @NonNull String[], long, @NonNull java.util.concurrent.TimeUnit, long, @NonNull java.util.concurrent.TimeUnit, @NonNull android.app.PendingIntent, @Nullable android.app.PendingIntent);
     method @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerUsageSessionObserver(int, @NonNull String[], @NonNull java.time.Duration, @NonNull java.time.Duration, @NonNull android.app.PendingIntent, @Nullable android.app.PendingIntent);
     method public void reportUsageStart(@NonNull android.app.Activity, @NonNull String);
     method public void reportUsageStart(@NonNull android.app.Activity, @NonNull String, long);
@@ -2004,15 +2002,15 @@
   public final class HdmiControlManager {
     method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void addHotplugEventListener(android.hardware.hdmi.HdmiControlManager.HotplugEventListener);
     method @Nullable public android.hardware.hdmi.HdmiClient getClient(int);
-    method @Nullable public java.util.List<android.hardware.hdmi.HdmiDeviceInfo> getConnectedDevicesList();
+    method @NonNull public java.util.List<android.hardware.hdmi.HdmiDeviceInfo> getConnectedDevices();
     method public int getPhysicalAddress();
     method @Nullable public android.hardware.hdmi.HdmiPlaybackClient getPlaybackClient();
     method @Nullable public android.hardware.hdmi.HdmiSwitchClient getSwitchClient();
     method @Nullable public android.hardware.hdmi.HdmiTvClient getTvClient();
-    method public boolean isRemoteDeviceConnected(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
-    method public void powerOffRemoteDevice(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
+    method public boolean isDeviceConnected(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
+    method public void powerOffDevice(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
     method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void removeHotplugEventListener(android.hardware.hdmi.HdmiControlManager.HotplugEventListener);
-    method public void requestRemoteDeviceToBecomeActiveSource(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
+    method public void setActiveSource(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
     method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setStandbyMode(boolean);
     field public static final String ACTION_OSD_MESSAGE = "android.hardware.hdmi.action.OSD_MESSAGE";
     field public static final int AVR_VOLUME_MUTED = 101; // 0x65
@@ -3498,8 +3496,8 @@
     method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes);
     method public void clearAudioServerStateCallback();
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
-    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.audiopolicy.AudioProductStrategies getAudioProductStrategies();
-    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.audiopolicy.AudioVolumeGroups getAudioVolumeGroups();
+    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies();
+    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioVolumeGroup> getAudioVolumeGroups();
     method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
     method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
     method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
@@ -3674,31 +3672,13 @@
     method public void setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener);
     method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setAudioPolicyVolumeCallback(@NonNull android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback);
     method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setIsAudioFocusPolicy(boolean);
-    method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setIsTestFocusPolicy(boolean);
     method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setLooper(@NonNull android.os.Looper) throws java.lang.IllegalArgumentException;
   }
 
-  public final class AudioProductStrategies implements java.lang.Iterable<android.media.audiopolicy.AudioProductStrategy> android.os.Parcelable {
-    ctor public AudioProductStrategies();
-    method public int describeContents();
-    method @NonNull public android.media.AudioAttributes getAudioAttributesForLegacyStreamType(int);
-    method @NonNull public android.media.AudioAttributes getAudioAttributesForProductStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
-    method @Nullable public android.media.audiopolicy.AudioProductStrategy getById(int);
-    method public int getLegacyStreamTypeForAudioAttributes(@NonNull android.media.AudioAttributes);
-    method @Nullable public android.media.audiopolicy.AudioProductStrategy getProductStrategyForAudioAttributes(@NonNull android.media.AudioAttributes);
-    method public int getVolumeGroupIdForAttributes(@NonNull android.media.AudioAttributes);
-    method public int getVolumeGroupIdForLegacyStreamType(int);
-    method @NonNull public java.util.Iterator<android.media.audiopolicy.AudioProductStrategy> iterator();
-    method public int size();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioProductStrategies> CREATOR;
-  }
-
   public final class AudioProductStrategy implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public android.media.AudioAttributes getAudioAttributes();
     method public int getId();
-    method @NonNull public String name();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioProductStrategy> CREATOR;
   }
@@ -3711,16 +3691,6 @@
     method @NonNull public String name();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioVolumeGroup> CREATOR;
-  }
-
-  public final class AudioVolumeGroups implements java.lang.Iterable<android.media.audiopolicy.AudioVolumeGroup> android.os.Parcelable {
-    ctor public AudioVolumeGroups();
-    method public int describeContents();
-    method @Nullable public android.media.audiopolicy.AudioVolumeGroup getById(int);
-    method @NonNull public java.util.Iterator<android.media.audiopolicy.AudioVolumeGroup> iterator();
-    method public int size();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioVolumeGroups> CREATOR;
     field public static final int DEFAULT_VOLUME_GROUP = -1; // 0xffffffff
   }
 
@@ -6816,7 +6786,7 @@
 
   public abstract class TextClassifierService extends android.app.Service {
     ctor public TextClassifierService();
-    method public static android.view.textclassifier.TextClassifier getDefaultTextClassifierImplementation(@NonNull android.content.Context);
+    method @NonNull public static android.view.textclassifier.TextClassifier getDefaultTextClassifierImplementation(@NonNull android.content.Context);
     method @Deprecated public final android.view.textclassifier.TextClassifier getLocalTextClassifier();
     method @Nullable public final android.os.IBinder onBind(android.content.Intent);
     method @MainThread public abstract void onClassifyText(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextClassification.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.TextClassification>);
@@ -7234,6 +7204,7 @@
   }
 
   public static final class CarrierRestrictionRules.Builder {
+    ctor public CarrierRestrictionRules.Builder();
     method @NonNull public android.telephony.CarrierRestrictionRules build();
     method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllCarriersAllowed();
     method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllowedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
@@ -9488,22 +9459,6 @@
     method public static void writeRaw(@NonNull byte[], int);
   }
 
-  public class StatsLogAtoms {
-    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED = 170; // 0xaa
-    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED = 8; // 0x8
-    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED = 5; // 0x5
-    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED = 1; // 0x1
-    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED = 3; // 0x3
-    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_RESTRICTED_PERMISSION = 9; // 0x9
-    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED = 2; // 0x2
-    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED = 6; // 0x6
-    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE = 7; // 0x7
-    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED = 4; // 0x4
-  }
-
-  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef(prefix="PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__", value={android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED}) public static @interface StatsLogAtoms.PermissionGrantRequestResultReported_Result {
-  }
-
 }
 
 package android.view {
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 162f212..5d74e17 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -60,6 +60,18 @@
 
 }
 
+package android.hardware.hdmi {
+
+  public final class HdmiControlManager {
+    method @Deprecated public java.util.List<android.hardware.hdmi.HdmiDeviceInfo> getConnectedDevicesList();
+    method @Deprecated public boolean isRemoteDeviceConnected(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
+    method @Deprecated public void powerOffRemoteDevice(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
+    method @Deprecated public void powerOnRemoteDevice(android.hardware.hdmi.HdmiDeviceInfo);
+    method @Deprecated public void requestRemoteDeviceToBecomeActiveSource(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
+  }
+
+}
+
 package android.location {
 
   public class LocationManager {
diff --git a/api/test-current.txt b/api/test-current.txt
index ac44dca..d37b45e 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1074,6 +1074,19 @@
 
 package android.media {
 
+  public final class AudioFocusInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.media.AudioAttributes getAttributes();
+    method @NonNull public String getClientId();
+    method public int getClientUid();
+    method public int getFlags();
+    method public int getGainRequest();
+    method public int getLossReceived();
+    method @NonNull public String getPackageName();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.media.AudioFocusInfo> CREATOR;
+  }
+
   public final class AudioFocusRequest {
     method @Nullable public android.media.AudioManager.OnAudioFocusChangeListener getOnAudioFocusChangeListener();
   }
@@ -1085,6 +1098,14 @@
     method public static boolean isEncodingLinearPcm(int);
   }
 
+  public class AudioManager {
+    method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
+    method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
+    method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
+    method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public void unregisterAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
+    method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public void unregisterAudioPolicyAsync(@NonNull android.media.audiopolicy.AudioPolicy);
+  }
+
   public static final class AudioRecord.MetricsConstants {
     field public static final String ATTRIBUTES = "android.media.audiorecord.attributes";
     field public static final String CHANNEL_MASK = "android.media.audiorecord.channelMask";
@@ -1124,13 +1145,6 @@
     method public android.media.BufferingParams.Builder setResumePlaybackMarkMs(int);
   }
 
-  public class FileDataSourceDesc extends android.media.DataSourceDesc {
-    method public long getLength();
-    method public long getOffset();
-    method @NonNull public android.os.ParcelFileDescriptor getParcelFileDescriptor();
-    field public static final long FD_LENGTH_UNKNOWN = 576460752303423487L; // 0x7ffffffffffffffL
-  }
-
   public static final class MediaCodecInfo.VideoCapabilities.PerformancePoint {
     ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(int, int, int, int, @NonNull android.util.Size);
     ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(@NonNull android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint, @NonNull android.util.Size);
@@ -1139,28 +1153,11 @@
     method public int getMaxMacroBlocks();
   }
 
-  public class MediaPlayer2 implements android.media.AudioRouting java.lang.AutoCloseable {
-    method public android.media.MediaPlayer2.DrmInfo getDrmInfo(@NonNull android.media.DataSourceDesc);
-    method public android.media.MediaDrm.KeyRequest getDrmKeyRequest(@NonNull android.media.DataSourceDesc, @Nullable byte[], @Nullable byte[], @Nullable String, int, @Nullable java.util.Map<java.lang.String,java.lang.String>) throws android.media.MediaPlayer2.NoDrmSchemeException;
-    method public String getDrmPropertyString(@NonNull android.media.DataSourceDesc, @NonNull String) throws android.media.MediaPlayer2.NoDrmSchemeException;
-    method @NonNull public Object prepareDrm(@NonNull android.media.DataSourceDesc, @NonNull java.util.UUID);
-    method public byte[] provideDrmKeyResponse(@NonNull android.media.DataSourceDesc, @Nullable byte[], @NonNull byte[]) throws android.media.DeniedByServerException, android.media.MediaPlayer2.NoDrmSchemeException;
-    method public void releaseDrm(@NonNull android.media.DataSourceDesc) throws android.media.MediaPlayer2.NoDrmSchemeException;
-    method public void restoreDrmKeys(@NonNull android.media.DataSourceDesc, @NonNull byte[]) throws android.media.MediaPlayer2.NoDrmSchemeException;
-    method public void setDrmPropertyString(@NonNull android.media.DataSourceDesc, @NonNull String, @NonNull String) throws android.media.MediaPlayer2.NoDrmSchemeException;
-  }
-
   public final class PlaybackParams implements android.os.Parcelable {
     method public int getAudioStretchMode();
     method public android.media.PlaybackParams setAudioStretchMode(int);
   }
 
-  public class UriDataSourceDesc extends android.media.DataSourceDesc {
-    method @Nullable public java.util.List<java.net.HttpCookie> getCookies();
-    method @Nullable public java.util.Map<java.lang.String,java.lang.String> getHeaders();
-    method @NonNull public android.net.Uri getUri();
-  }
-
   public static final class VolumeShaper.Configuration.Builder {
     method @NonNull public android.media.VolumeShaper.Configuration.Builder setOptionFlags(int);
   }
@@ -1202,6 +1199,91 @@
 
 }
 
+package android.media.audiopolicy {
+
+  public class AudioMix {
+    method public int getMixState();
+    field public static final int MIX_STATE_DISABLED = -1; // 0xffffffff
+    field public static final int MIX_STATE_IDLE = 0; // 0x0
+    field public static final int MIX_STATE_MIXING = 1; // 0x1
+    field public static final int ROUTE_FLAG_LOOP_BACK = 2; // 0x2
+    field public static final int ROUTE_FLAG_RENDER = 1; // 0x1
+  }
+
+  public static class AudioMix.Builder {
+    ctor public AudioMix.Builder(android.media.audiopolicy.AudioMixingRule) throws java.lang.IllegalArgumentException;
+    method public android.media.audiopolicy.AudioMix build() throws java.lang.IllegalArgumentException;
+    method public android.media.audiopolicy.AudioMix.Builder setDevice(@NonNull android.media.AudioDeviceInfo) throws java.lang.IllegalArgumentException;
+    method public android.media.audiopolicy.AudioMix.Builder setFormat(android.media.AudioFormat) throws java.lang.IllegalArgumentException;
+    method public android.media.audiopolicy.AudioMix.Builder setRouteFlags(int) throws java.lang.IllegalArgumentException;
+  }
+
+  public class AudioMixingRule {
+    field public static final int RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET = 2; // 0x2
+    field public static final int RULE_MATCH_ATTRIBUTE_USAGE = 1; // 0x1
+    field public static final int RULE_MATCH_UID = 4; // 0x4
+  }
+
+  public static class AudioMixingRule.Builder {
+    ctor public AudioMixingRule.Builder();
+    method public android.media.audiopolicy.AudioMixingRule.Builder addMixRule(int, Object) throws java.lang.IllegalArgumentException;
+    method public android.media.audiopolicy.AudioMixingRule.Builder addRule(android.media.AudioAttributes, int) throws java.lang.IllegalArgumentException;
+    method @NonNull public android.media.audiopolicy.AudioMixingRule.Builder allowPrivilegedPlaybackCapture(boolean);
+    method public android.media.audiopolicy.AudioMixingRule build();
+    method public android.media.audiopolicy.AudioMixingRule.Builder excludeMixRule(int, Object) throws java.lang.IllegalArgumentException;
+    method public android.media.audiopolicy.AudioMixingRule.Builder excludeRule(android.media.AudioAttributes, int) throws java.lang.IllegalArgumentException;
+  }
+
+  public class AudioPolicy {
+    method public int attachMixes(@NonNull java.util.List<android.media.audiopolicy.AudioMix>);
+    method public android.media.AudioRecord createAudioRecordSink(android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException;
+    method public android.media.AudioTrack createAudioTrackSource(android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException;
+    method public int detachMixes(@NonNull java.util.List<android.media.audiopolicy.AudioMix>);
+    method public int getFocusDuckingBehavior();
+    method public int getStatus();
+    method public int setFocusDuckingBehavior(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void setRegistration(String);
+    method public String toLogFriendlyString();
+    field public static final int FOCUS_POLICY_DUCKING_DEFAULT = 0; // 0x0
+    field public static final int FOCUS_POLICY_DUCKING_IN_APP = 0; // 0x0
+    field public static final int FOCUS_POLICY_DUCKING_IN_POLICY = 1; // 0x1
+    field public static final int POLICY_STATUS_REGISTERED = 2; // 0x2
+    field public static final int POLICY_STATUS_UNREGISTERED = 1; // 0x1
+  }
+
+  public abstract static class AudioPolicy.AudioPolicyFocusListener {
+    ctor public AudioPolicy.AudioPolicyFocusListener();
+    method public void onAudioFocusAbandon(android.media.AudioFocusInfo);
+    method public void onAudioFocusGrant(android.media.AudioFocusInfo, int);
+    method public void onAudioFocusLoss(android.media.AudioFocusInfo, boolean);
+    method public void onAudioFocusRequest(android.media.AudioFocusInfo, int);
+  }
+
+  public abstract static class AudioPolicy.AudioPolicyStatusListener {
+    ctor public AudioPolicy.AudioPolicyStatusListener();
+    method public void onMixStateUpdate(android.media.audiopolicy.AudioMix);
+    method public void onStatusChange();
+  }
+
+  public abstract static class AudioPolicy.AudioPolicyVolumeCallback {
+    ctor public AudioPolicy.AudioPolicyVolumeCallback();
+    method public void onVolumeAdjustment(int);
+  }
+
+  public static class AudioPolicy.Builder {
+    ctor public AudioPolicy.Builder(android.content.Context);
+    method @NonNull public android.media.audiopolicy.AudioPolicy.Builder addMix(@NonNull android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException;
+    method @NonNull public android.media.audiopolicy.AudioPolicy build();
+    method public void setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener);
+    method public void setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener);
+    method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setAudioPolicyVolumeCallback(@NonNull android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback);
+    method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setIsAudioFocusPolicy(boolean);
+    method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setIsTestFocusPolicy(boolean);
+    method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setLooper(@NonNull android.os.Looper) throws java.lang.IllegalArgumentException;
+  }
+
+}
+
 package android.metrics {
 
   public class LogMaker {
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index e577b6d..55d3fba 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -257,7 +257,8 @@
         BluetoothSmpPairingEventReported bluetooth_smp_pairing_event_reported = 167;
         ScreenTimeoutExtensionReported screen_timeout_extension_reported = 168;
         ProcessStartTime process_start_time = 169;
-        PermissionGrantRequestResultReported permission_grant_request_result_reported = 170;
+        PermissionGrantRequestResultReported permission_grant_request_result_reported =
+            170 [(log_from_module) = "permissioncontroller"];
         BluetoothSocketConnectionStateChanged bluetooth_socket_connection_state_changed = 171;
         DeviceIdentifierAccessDenied device_identifier_access_denied = 172;
         BubbleDeveloperErrorReported bubble_developer_error_reported = 173;
@@ -278,7 +279,7 @@
     }
 
     // Pulled events will start at field 10000.
-    // Next: 10058
+    // Next: 10059
     oneof pulled {
         WifiBytesTransfer wifi_bytes_transfer = 10000;
         WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001;
@@ -338,6 +339,7 @@
         GpuStatsAppInfo gpu_stats_app_info = 10055;
         SystemIonHeapSize system_ion_heap_size = 10056;
         AppsOnExternalStorageInfo apps_on_external_storage_info = 10057;
+        FaceSettings face_settings = 10058;
     }
 
     // DO NOT USE field numbers above 100,000 in AOSP.
@@ -5583,6 +5585,7 @@
         SWIPE_LEFT = 13;
         SWIPE_RIGHT = 14;
         STACK_EXPANDED = 15;
+        FLYOUT = 16;
     }
     optional Action action = 6;
 
@@ -5924,3 +5927,23 @@
     // The name of the package that is installed on the external storage.
     optional string package_name = 2;
 }
+
+/**
+ * Logs the settings related to Face.
+ * Logged from:
+ *   frameworks/base/services/core/java/com/android/server/stats
+ */
+message FaceSettings {
+    // Whether or not face unlock is allowed on Keyguard.
+    optional bool unlock_keyguard_enabled = 1;
+    // Whether or not face unlock dismisses the Keyguard.
+    optional bool unlock_dismisses_keyguard = 2;
+    // Whether or not face unlock requires attention.
+    optional bool unlock_attention_required = 3;
+    // Whether or not face unlock is allowed for apps (through BiometricPrompt).
+    optional bool unlock_app_enabled = 4;
+    // Whether or not face unlock always requires user confirmation.
+    optional bool unlock_always_require_confirmation = 5;
+    // Whether or not a diverse set of poses are required during enrollment.
+    optional bool unlock_diversity_required = 6;
+}
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index d6411a7..51839c4 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -254,6 +254,9 @@
         // AppsOnExternalStorageInfo
         {android::util::APPS_ON_EXTERNAL_STORAGE_INFO,
          {.puller = new StatsCompanionServicePuller(android::util::APPS_ON_EXTERNAL_STORAGE_INFO)}},
+        // Face Settings
+        {android::util::FACE_SETTINGS,
+         {.puller = new StatsCompanionServicePuller(android::util::FACE_SETTINGS)}},
 };
 
 StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 4f388a4..cf4ef20 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1838,17 +1838,17 @@
         private final float mScale;
         private final int mSystemUiVisibility;
         private final boolean mIsTranslucent;
-
-        // TODO(b/116112787) TaskSnapshot must also book keep the color space from hardware bitmap
-        // when created.
-        private final ColorSpace mColorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
+        // Must be one of the named color spaces, otherwise, always use SRGB color space.
+        private final ColorSpace mColorSpace;
 
         public TaskSnapshot(@NonNull ComponentName topActivityComponent, GraphicBuffer snapshot,
-                int orientation, Rect contentInsets, boolean reducedResolution, float scale,
-                boolean isRealSnapshot, int windowingMode, int systemUiVisibility,
-                boolean isTranslucent) {
+                @NonNull ColorSpace colorSpace, int orientation, Rect contentInsets,
+                boolean reducedResolution, float scale, boolean isRealSnapshot, int windowingMode,
+                int systemUiVisibility, boolean isTranslucent) {
             mTopActivityComponent = topActivityComponent;
             mSnapshot = snapshot;
+            mColorSpace = colorSpace.getId() < 0
+                    ? ColorSpace.get(ColorSpace.Named.SRGB) : colorSpace;
             mOrientation = orientation;
             mContentInsets = new Rect(contentInsets);
             mReducedResolution = reducedResolution;
@@ -1862,6 +1862,10 @@
         private TaskSnapshot(Parcel source) {
             mTopActivityComponent = ComponentName.readFromParcel(source);
             mSnapshot = source.readParcelable(null /* classLoader */);
+            int colorSpaceId = source.readInt();
+            mColorSpace = colorSpaceId >= 0
+                    ? ColorSpace.get(ColorSpace.Named.values()[colorSpaceId])
+                    : ColorSpace.get(ColorSpace.Named.SRGB);
             mOrientation = source.readInt();
             mContentInsets = source.readParcelable(null /* classLoader */);
             mReducedResolution = source.readBoolean();
@@ -1968,6 +1972,7 @@
         public void writeToParcel(Parcel dest, int flags) {
             ComponentName.writeToParcel(mTopActivityComponent, dest);
             dest.writeParcelable(mSnapshot, 0);
+            dest.writeInt(mColorSpace.getId());
             dest.writeInt(mOrientation);
             dest.writeParcelable(mContentInsets, 0);
             dest.writeBoolean(mReducedResolution);
@@ -1985,6 +1990,7 @@
             return "TaskSnapshot{"
                     + " mTopActivityComponent=" + mTopActivityComponent.flattenToShortString()
                     + " mSnapshot=" + mSnapshot + " (" + width + "x" + height + ")"
+                    + " mColorSpace=" + mColorSpace.toString()
                     + " mOrientation=" + mOrientation
                     + " mContentInsets=" + mContentInsets.toShortString()
                     + " mReducedResolution=" + mReducedResolution + " mScale=" + mScale
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b6e5754..143361f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -224,6 +224,12 @@
     private static final boolean DEBUG_PROVIDER = false;
     public static final boolean DEBUG_ORDER = false;
     private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
+    /**
+     * The delay to release the provider when it has no more references. It reduces the number of
+     * transactions for acquiring and releasing provider if the client accesses the provider
+     * frequently in a short time.
+     */
+    private static final long CONTENT_PROVIDER_RETAIN_TIME = 1000;
     private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
 
     /** Type for IActivityManager.serviceDoneExecuting: anonymous operation */
@@ -6498,16 +6504,13 @@
                 if (!prc.removePending) {
                     // Schedule the actual remove asynchronously, since we don't know the context
                     // this will be called in.
-                    // TODO: it would be nice to post a delayed message, so
-                    // if we come back and need the same provider quickly
-                    // we will still have it available.
                     if (DEBUG_PROVIDER) {
                         Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
                                 + prc.holder.info.name);
                     }
                     prc.removePending = true;
                     Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
-                    mH.sendMessage(msg);
+                    mH.sendMessageDelayed(msg, CONTENT_PROVIDER_RETAIN_TIME);
                 } else {
                     Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
                 }
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 15982a7..6f92244 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -38,7 +38,6 @@
 import android.os.Process;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
-import android.os.SystemProperties;
 import android.os.UserManager;
 import android.util.ArrayMap;
 import android.util.LongSparseArray;
@@ -5209,7 +5208,6 @@
      * @hide
      */
     public int noteProxyOpNoThrow(int op, String proxiedPackageName, int proxiedUid) {
-        logOperationIfNeeded(op, mContext.getOpPackageName(), proxiedPackageName);
         try {
             return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(),
                     proxiedUid, proxiedPackageName);
@@ -5238,7 +5236,6 @@
      */
     @UnsupportedAppUsage
     public int noteOpNoThrow(int op, int uid, String packageName) {
-        logOperationIfNeeded(op, packageName, null);
         try {
             return mService.noteOperation(op, uid, packageName);
         } catch (RemoteException e) {
@@ -5346,7 +5343,6 @@
      * @hide
      */
     public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
-        logOperationIfNeeded(op, packageName, null);
         try {
             return mService.startOperation(getToken(mService), op, uid, packageName,
                     startIfModeDefault);
@@ -5363,7 +5359,6 @@
      * @hide
      */
     public void finishOp(int op, int uid, String packageName) {
-        logOperationIfNeeded(op, packageName, null);
         try {
             mService.finishOperation(getToken(mService), op, uid, packageName);
         } catch (RemoteException e) {
@@ -5703,45 +5698,4 @@
 
         return AppOpsManager.MODE_DEFAULT;
     }
-
-    private static void logOperationIfNeeded(int op, String callingPackage, String proxiedPackage) {
-        // Check if debug logging propety is enabled.
-        if (!SystemProperties.getBoolean(DEBUG_LOGGING_ENABLE_PROP, false)) {
-            return;
-        }
-        // Check if this package should be logged.
-        String packages = SystemProperties.get(DEBUG_LOGGING_PACKAGES_PROP, "");
-        if (!"".equals(packages) && callingPackage != null) {
-            boolean found = false;
-            for (String pkg : packages.split(",")) {
-                if (callingPackage.equals(pkg)) {
-                    found = true;
-                    break;
-                }
-            }
-            if (!found) {
-                return;
-            }
-        }
-        String opStr = opToName(op);
-        // Check if this app op should be logged
-        String logOps = SystemProperties.get(DEBUG_LOGGING_OPS_PROP, "");
-        if (!"".equals(logOps)) {
-            boolean found = false;
-            for (String logOp : logOps.split(",")) {
-                if (opStr.equals(logOp)) {
-                    found = true;
-                    break;
-                }
-            }
-            if (!found) {
-                return;
-            }
-        }
-
-        // Log a stack trace
-        Exception here = new Exception("HERE!");
-        android.util.Log.i(DEBUG_LOGGING_TAG, "Note operation package= " + callingPackage
-                + " proxied= " + proxiedPackage + " op= " + opStr, here);
-    }
 }
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 1785d2a..48ca716 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -223,7 +223,7 @@
     void enterSafeMode();
     void noteWakeupAlarm(in IIntentSender sender, in WorkSource workSource, int sourceUid,
             in String sourcePkg, in String tag);
-    void removeContentProvider(in IBinder connection, boolean stable);
+    oneway void removeContentProvider(in IBinder connection, boolean stable);
     @UnsupportedAppUsage
     void setRequestedOrientation(in IBinder token, int requestedOrientation);
     void unbindFinished(in IBinder token, in Intent service, boolean doRebind);
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index 2e14d03..e6682d6 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -414,7 +414,6 @@
      * Returns the experiments IDs registered with statsd, or an empty array if there aren't any.
      *
      * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
-     * @hide
      */
     @RequiresPermission(allOf = {DUMP, PACKAGE_USAGE_STATS})
     public long[] getRegisteredExperimentIds()
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index eb1ea90..f8dc20e 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -678,29 +678,6 @@
         }
     }
 
-
-    /**
-     * @deprecated use {@link #registerUsageSessionObserver(int, String[], Duration, Duration,
-     *                                                      PendingIntent, PendingIntent)}.
-     *
-     * @hide
-     */
-    @Deprecated
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE)
-    // STOPSHIP b/128455269: remove this method
-    public void registerUsageSessionObserver(int sessionObserverId,
-            @NonNull String[] observedEntities, long timeLimit, @NonNull TimeUnit timeUnit,
-            long sessionThresholdTime,  @NonNull TimeUnit sessionThresholdTimeUnit,
-            @NonNull PendingIntent limitReachedCallbackIntent,
-            @Nullable PendingIntent sessionEndCallbackIntent) {
-        final Duration timeLimitDuration = Duration.ofMillis(timeUnit.toMillis(timeLimit));
-        final Duration sessionThresholdDuration =
-                Duration.ofMillis(sessionThresholdTimeUnit.toMillis(sessionThresholdTime));
-        registerUsageSessionObserver(sessionObserverId, observedEntities, timeLimitDuration,
-                sessionThresholdDuration, limitReachedCallbackIntent, sessionEndCallbackIntent);
-    }
-
     /**
      * Register a usage session observer that receives a callback on the provided {@code
      * limitReachedCallbackIntent} when the sum of usages of apps and tokens in the {@code
diff --git a/core/java/android/bluetooth/le/ScanRecord.java b/core/java/android/bluetooth/le/ScanRecord.java
index 2174255..30868bf 100644
--- a/core/java/android/bluetooth/le/ScanRecord.java
+++ b/core/java/android/bluetooth/le/ScanRecord.java
@@ -16,6 +16,7 @@
 
 package android.bluetooth.le;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.bluetooth.BluetoothUuid;
@@ -97,7 +98,7 @@
      * Returns a list of service solicitation UUIDs within the advertisement that are used to
      * identify the Bluetooth GATT services.
      */
-    @Nullable
+    @NonNull
     public List<ParcelUuid> getServiceSolicitationUuids() {
         return mServiceSolicitationUuids;
     }
@@ -297,9 +298,6 @@
             if (serviceUuids.isEmpty()) {
                 serviceUuids = null;
             }
-            if (serviceSolicitationUuids.isEmpty()) {
-                serviceSolicitationUuids = null;
-            }
             return new ScanRecord(serviceUuids, serviceSolicitationUuids, manufacturerData,
                     serviceData, advertiseFlag, txPowerLevel, localName, scanRecord);
         } catch (Exception e) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 8628d32..e66cd31 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -643,6 +643,7 @@
     private static final String ATTR_CATEGORY = "category";
     private static final String TAG_EXTRA = "extra";
     private static final String ATTR_TYPE = "type";
+    private static final String ATTR_IDENTIFIER = "ident";
     private static final String ATTR_COMPONENT = "component";
     private static final String ATTR_DATA = "data";
     private static final String ATTR_FLAGS = "flags";
@@ -6314,6 +6315,7 @@
     private String mAction;
     private Uri mData;
     private String mType;
+    private String mIdentifier;
     private String mPackage;
     private ComponentName mComponent;
     private int mFlags;
@@ -6359,6 +6361,7 @@
         this.mAction = o.mAction;
         this.mData = o.mData;
         this.mType = o.mType;
+        this.mIdentifier = o.mIdentifier;
         this.mPackage = o.mPackage;
         this.mComponent = o.mComponent;
 
@@ -6678,6 +6681,11 @@
                     intent.mType = value;
                 }
 
+                // identifier
+                else if (uri.startsWith("identifier=", i)) {
+                    intent.mIdentifier = value;
+                }
+
                 // launch flags
                 else if (uri.startsWith("launchFlags=", i)) {
                     intent.mFlags = Integer.decode(value).intValue();
@@ -7017,6 +7025,12 @@
                         hasIntentInfo = true;
                     }
                     break;
+                case "-i":
+                    intent.setIdentifier(cmd.getNextArgRequired());
+                    if (intent == baseIntent) {
+                        hasIntentInfo = true;
+                    }
+                    break;
                 case "-c":
                     intent.addCategory(cmd.getNextArgRequired());
                     if (intent == baseIntent) {
@@ -7375,7 +7389,7 @@
     public static void printIntentArgsHelp(PrintWriter pw, String prefix) {
         final String[] lines = new String[] {
                 "<INTENT> specifications include these flags and arguments:",
-                "    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]",
+                "    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>] [-i <IDENTIFIER>]",
                 "    [-c <CATEGORY> [-c <CATEGORY>] ...]",
                 "    [-n <COMPONENT_NAME>]",
                 "    [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]",
@@ -7557,6 +7571,18 @@
     }
 
     /**
+     * Retrieve the identifier for this Intent.  If non-null, this is an arbitrary identity
+     * of the Intent to distinguish it from other Intents.
+     *
+     * @return The identifier of this intent or null if none is specified.
+     *
+     * @see #setIdentifier
+     */
+    public @Nullable String getIdentifier() {
+        return mIdentifier;
+    }
+
+    /**
      * Check if a category exists in the intent.
      *
      * @param category The category to check.
@@ -8576,6 +8602,28 @@
     }
 
     /**
+     * Set an identifier for this Intent.  If set, this provides a unique identity for this Intent,
+     * allowing it to be unique from other Intents that would otherwise look the same.  In
+     * particular, this will be used by {@link #filterEquals(Intent)} to determine if two
+     * Intents are the same as with other fields like {@link #setAction}.  However, unlike those
+     * fields, the identifier is <em>never</em> used for matching against an {@link IntentFilter};
+     * it is as if the identifier has not been set on the Intent.
+     *
+     * @param identifier The identifier for this Intent.  The contents of the string have no
+     *                   meaning to the system, except whether they are exactly the same as
+     *                   another identifier.
+     *
+     * @return Returns the same Intent object, for chaining multiple calls
+     * into a single statement.
+     *
+     * @see #getIdentifier
+     */
+    public @NonNull Intent setIdentifier(@Nullable String identifier) {
+        mIdentifier = identifier;
+        return this;
+    }
+
+    /**
      * Add a new category to the intent.  Categories provide additional detail
      * about the action the intent performs.  When resolving an intent, only
      * activities that provide <em>all</em> of the requested categories will be
@@ -9693,6 +9741,12 @@
     public static final int FILL_IN_CLIP_DATA = 1<<7;
 
     /**
+     * Use with {@link #fillIn} to allow the current identifier value to be
+     * overwritten, even if it is already set.
+     */
+    public static final int FILL_IN_IDENTIFIER = 1<<8;
+
+    /**
      * Copy the contents of <var>other</var> in to this object, but only
      * where fields are not defined by this object.  For purposes of a field
      * being defined, the following pieces of data in the Intent are
@@ -9702,6 +9756,7 @@
      * <li> action, as set by {@link #setAction}.
      * <li> data Uri and MIME type, as set by {@link #setData(Uri)},
      * {@link #setType(String)}, or {@link #setDataAndType(Uri, String)}.
+     * <li> identifier, as set by {@link #setIdentifier}.
      * <li> categories, as set by {@link #addCategory}.
      * <li> package, as set by {@link #setPackage}.
      * <li> component, as set by {@link #setComponent(ComponentName)} or
@@ -9713,8 +9768,8 @@
      * </ul>
      *
      * <p>In addition, you can use the {@link #FILL_IN_ACTION},
-     * {@link #FILL_IN_DATA}, {@link #FILL_IN_CATEGORIES}, {@link #FILL_IN_PACKAGE},
-     * {@link #FILL_IN_COMPONENT}, {@link #FILL_IN_SOURCE_BOUNDS},
+     * {@link #FILL_IN_DATA}, {@link #FILL_IN_IDENTIFIER}, {@link #FILL_IN_CATEGORIES},
+     * {@link #FILL_IN_PACKAGE}, {@link #FILL_IN_COMPONENT}, {@link #FILL_IN_SOURCE_BOUNDS},
      * {@link #FILL_IN_SELECTOR}, and {@link #FILL_IN_CLIP_DATA} to override
      * the restriction where the corresponding field will not be replaced if
      * it is already set.
@@ -9758,6 +9813,11 @@
             changes |= FILL_IN_DATA;
             mayHaveCopiedUris = true;
         }
+        if (other.mIdentifier != null
+                && (mIdentifier == null || (flags&FILL_IN_IDENTIFIER) != 0)) {
+            mIdentifier = other.mIdentifier;
+            changes |= FILL_IN_IDENTIFIER;
+        }
         if (other.mCategories != null
                 && (mCategories == null || (flags&FILL_IN_CATEGORIES) != 0)) {
             if (other.mCategories != null) {
@@ -9871,9 +9931,11 @@
 
     /**
      * Determine if two intents are the same for the purposes of intent
-     * resolution (filtering). That is, if their action, data, type,
+     * resolution (filtering). That is, if their action, data, type, identity,
      * class, and categories are the same.  This does <em>not</em> compare
-     * any extra data included in the intents.
+     * any extra data included in the intents.  Note that technically when actually
+     * matching against an {@link IntentFilter} the identifier is ignored, while here
+     * it is directly compared for equality like the other fields.
      *
      * @param other The other Intent to compare against.
      *
@@ -9887,6 +9949,7 @@
         if (!Objects.equals(this.mAction, other.mAction)) return false;
         if (!Objects.equals(this.mData, other.mData)) return false;
         if (!Objects.equals(this.mType, other.mType)) return false;
+        if (!Objects.equals(this.mIdentifier, other.mIdentifier)) return false;
         if (!Objects.equals(this.mPackage, other.mPackage)) return false;
         if (!Objects.equals(this.mComponent, other.mComponent)) return false;
         if (!Objects.equals(this.mCategories, other.mCategories)) return false;
@@ -9913,6 +9976,9 @@
         if (mType != null) {
             code += mType.hashCode();
         }
+        if (mIdentifier != null) {
+            code += mIdentifier.hashCode();
+        }
         if (mPackage != null) {
             code += mPackage.hashCode();
         }
@@ -10005,6 +10071,13 @@
             first = false;
             b.append("typ=").append(mType);
         }
+        if (mIdentifier != null) {
+            if (!first) {
+                b.append(' ');
+            }
+            first = false;
+            b.append("id=").append(mIdentifier);
+        }
         if (mFlags != 0) {
             if (!first) {
                 b.append(' ');
@@ -10276,6 +10349,9 @@
         if (mType != null) {
             uri.append("type=").append(Uri.encode(mType, "/")).append(';');
         }
+        if (mIdentifier != null) {
+            uri.append("identifier=").append(Uri.encode(mIdentifier, "/")).append(';');
+        }
         if (mFlags != 0) {
             uri.append("launchFlags=0x").append(Integer.toHexString(mFlags)).append(';');
         }
@@ -10326,6 +10402,7 @@
         out.writeString(mAction);
         Uri.writeToParcel(out, mData);
         out.writeString(mType);
+        out.writeString(mIdentifier);
         out.writeInt(mFlags);
         out.writeString(mPackage);
         ComponentName.writeToParcel(mComponent, out);
@@ -10383,6 +10460,7 @@
         setAction(in.readString());
         mData = Uri.CREATOR.createFromParcel(in);
         mType = in.readString();
+        mIdentifier = in.readString();
         mFlags = in.readInt();
         mPackage = in.readString();
         mComponent = ComponentName.readFromParcel(in);
@@ -10445,6 +10523,8 @@
         String mimeType = sa.getString(com.android.internal.R.styleable.Intent_mimeType);
         intent.setDataAndType(data != null ? Uri.parse(data) : null, mimeType);
 
+        intent.setIdentifier(sa.getString(com.android.internal.R.styleable.Intent_identifier));
+
         String packageName = sa.getString(com.android.internal.R.styleable.Intent_targetPackage);
         String className = sa.getString(com.android.internal.R.styleable.Intent_targetClass);
         if (packageName != null && className != null) {
@@ -10499,6 +10579,9 @@
         if (mType != null) {
             out.attribute(null, ATTR_TYPE, mType);
         }
+        if (mIdentifier != null) {
+            out.attribute(null, ATTR_IDENTIFIER, mIdentifier);
+        }
         if (mComponent != null) {
             out.attribute(null, ATTR_COMPONENT, mComponent.flattenToShortString());
         }
@@ -10529,6 +10612,8 @@
                 intent.setData(Uri.parse(attrValue));
             } else if (ATTR_TYPE.equals(attrName)) {
                 intent.setType(attrValue);
+            } else if (ATTR_IDENTIFIER.equals(attrName)) {
+                intent.setIdentifier(attrValue);
             } else if (ATTR_COMPONENT.equals(attrName)) {
                 intent.setComponent(ComponentName.unflattenFromString(attrValue));
             } else if (ATTR_FLAGS.equals(attrName)) {
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 6c72a9a..6ce6828 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -841,13 +841,12 @@
      * installation (for example, the same split name), the APK in this session
      * will replace the existing APK.
      * <p>
-     * In such a case that multiple packages need to be commited simultaneously,
+     * In such a case that multiple packages need to be committed simultaneously,
      * multiple sessions can be referenced by a single multi-package session.
      * This session is created with no package name and calling
-     * {@link SessionParams#setMultiPackage()} with {@code true}. The
-     * individual session IDs can be added with {@link #addChildSessionId(int)}
-     * and commit of the multi-package session will result in all child sessions
-     * being committed atomically.
+     * {@link SessionParams#setMultiPackage()}. The individual session IDs can be
+     * added with {@link #addChildSessionId(int)} and commit of the multi-package
+     * session will result in all child sessions being committed atomically.
      */
     public static class Session implements Closeable {
         /** {@hide} */
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 9e0ee58..d3575c0 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -1252,6 +1252,7 @@
      * fire the flash for flash power metering during precapture, and then fire the flash
      * for the final capture, if a flash is available on the device and the AE mode is set to
      * enable the flash.</p>
+     * <p>Devices that initially shipped with Android version {@link android.os.Build.VERSION_CODES#Q Q} or newer will not include any LEGACY-level devices.</p>
      *
      * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 6035f40..7349f0c 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -93,8 +93,8 @@
         }
 
         @Override // binder call
-        public void onAuthenticationSucceeded(long deviceId, Face face) {
-            mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, face).sendToTarget();
+        public void onAuthenticationSucceeded(long deviceId, Face face, int userId) {
+            mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, userId, 0, face).sendToTarget();
         }
 
         @Override // binder call
@@ -168,6 +168,44 @@
     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
     public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
             int flags, @NonNull AuthenticationCallback callback, @Nullable Handler handler) {
+        authenticate(crypto, cancel, flags, callback, handler, mContext.getUserId());
+    }
+
+    /**
+     * Use the provided handler thread for events.
+     */
+    private void useHandler(Handler handler) {
+        if (handler != null) {
+            mHandler = new MyHandler(handler.getLooper());
+        } else if (mHandler.getLooper() != mContext.getMainLooper()) {
+            mHandler = new MyHandler(mContext.getMainLooper());
+        }
+    }
+
+    /**
+     * Request authentication of a crypto object. This call operates the face recognition hardware
+     * and starts capturing images. It terminates when
+     * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
+     * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)} is called, at
+     * which point the object is no longer valid. The operation can be canceled by using the
+     * provided cancel object.
+     *
+     * @param crypto   object associated with the call or null if none required.
+     * @param cancel   an object that can be used to cancel authentication
+     * @param flags    optional flags; should be 0
+     * @param callback an object to receive authentication events
+     * @param handler  an optional handler to handle callback events
+     * @param userId   userId to authenticate for
+     * @throws IllegalArgumentException if the crypto operation is not supported or is not backed
+     *                                  by
+     *                                  <a href="{@docRoot}training/articles/keystore.html">Android
+     *                                  Keystore facility</a>.
+     * @throws IllegalStateException    if the crypto primitive is not initialized.
+     * @hide
+     */
+    public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
+            int flags, @NonNull AuthenticationCallback callback, @Nullable Handler handler,
+            int userId) {
         if (callback == null) {
             throw new IllegalArgumentException("Must supply an authentication callback");
         }
@@ -187,7 +225,7 @@
                 mAuthenticationCallback = callback;
                 mCryptoObject = crypto;
                 long sessionId = crypto != null ? crypto.getOpId() : 0;
-                mService.authenticate(mToken, sessionId, mContext.getUserId(), mServiceReceiver,
+                mService.authenticate(mToken, sessionId, userId, mServiceReceiver,
                         flags, mContext.getOpPackageName());
             } catch (RemoteException e) {
                 Log.w(TAG, "Remote exception while authenticating: ", e);
@@ -196,24 +234,13 @@
                     // try again later.
                     callback.onAuthenticationError(FACE_ERROR_HW_UNAVAILABLE,
                             getErrorString(mContext, FACE_ERROR_HW_UNAVAILABLE,
-                                0 /* vendorCode */));
+                                    0 /* vendorCode */));
                 }
             }
         }
     }
 
     /**
-     * Use the provided handler thread for events.
-     */
-    private void useHandler(Handler handler) {
-        if (handler != null) {
-            mHandler = new MyHandler(handler.getLooper());
-        } else if (mHandler.getLooper() != mContext.getMainLooper()) {
-            mHandler = new MyHandler(mContext.getMainLooper());
-        }
-    }
-
-    /**
      * Request face authentication enrollment. This call operates the face authentication hardware
      * and starts capturing images. Progress will be indicated by callbacks to the
      * {@link EnrollmentCallback} object. It terminates when
diff --git a/core/java/android/hardware/face/IFaceServiceReceiver.aidl b/core/java/android/hardware/face/IFaceServiceReceiver.aidl
index 2176902..10f9c43 100644
--- a/core/java/android/hardware/face/IFaceServiceReceiver.aidl
+++ b/core/java/android/hardware/face/IFaceServiceReceiver.aidl
@@ -24,7 +24,7 @@
 oneway interface IFaceServiceReceiver {
     void onEnrollResult(long deviceId, int faceId, int remaining);
     void onAcquired(long deviceId, int acquiredInfo, int vendorCode);
-    void onAuthenticationSucceeded(long deviceId, in Face face);
+    void onAuthenticationSucceeded(long deviceId, in Face face, int userId);
     void onAuthenticationFailed(long deviceId);
     void onError(long deviceId, int error, int vendorCode);
     void onRemoved(long deviceId, int faceId, int remaining);
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index aff385d..d05ba79 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -428,17 +428,33 @@
     }
 
     /**
-     * Get a snapshot of the real-time status of the remote devices.
+     * Get a snapshot of the real-time status of the devices on the CEC bus.
      *
-     * <p>This only applies to devices with multiple HDMI inputs.
+     * <p>This only applies to devices with switch functionality, which are devices with one
+     * or more than one HDMI inputs.
      *
-     * @return a list of {@link HdmiDeviceInfo} of the connected CEC devices. An empty
-     * list will be returned if there is none.
+     * @return a list of {@link HdmiDeviceInfo} of the connected CEC devices on the CEC bus. An
+     * empty list will be returned if there is none.
      *
      * @hide
      */
+    @NonNull
     @SystemApi
-    @Nullable
+    public List<HdmiDeviceInfo> getConnectedDevices() {
+        try {
+            return mService.getDeviceList();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @removed
+     * @hide
+     * @deprecated Please use {@link #getConnectedDevices()} instead.
+     */
+    @Deprecated
+    @SystemApi
     public List<HdmiDeviceInfo> getConnectedDevicesList() {
         try {
             return mService.getDeviceList();
@@ -448,7 +464,8 @@
     }
 
     /**
-     * Power off the target device by sending CEC commands.
+     * Power off the target device by sending CEC commands. Note that this device can't be the
+     * current device itself.
      *
      * <p>The target device info can be obtained by calling {@link #getConnectedDevicesList()}.
      *
@@ -457,6 +474,23 @@
      * @hide
      */
     @SystemApi
+    public void powerOffDevice(@NonNull HdmiDeviceInfo deviceInfo) {
+        Preconditions.checkNotNull(deviceInfo);
+        try {
+            mService.powerOffRemoteDevice(
+                    deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @removed
+     * @hide
+     * @deprecated Please use {@link #powerOffDevice(deviceInfo)} instead.
+     */
+    @Deprecated
+    @SystemApi
     public void powerOffRemoteDevice(@NonNull HdmiDeviceInfo deviceInfo) {
         Preconditions.checkNotNull(deviceInfo);
         try {
@@ -468,7 +502,8 @@
     }
 
     /**
-     * Power on the target device by sending CEC commands.
+     * Power on the target device by sending CEC commands. Note that this device can't be the
+     * current device itself.
      *
      * <p>The target device info can be obtained by calling {@link #getConnectedDevicesList()}.
      *
@@ -476,6 +511,23 @@
      *
      * @hide
      */
+    public void powerOnDevice(HdmiDeviceInfo deviceInfo) {
+        Preconditions.checkNotNull(deviceInfo);
+        try {
+            mService.powerOnRemoteDevice(
+                    deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @removed
+     * @hide
+     * @deprecated Please use {@link #powerOnDevice(deviceInfo)} instead.
+     */
+    @Deprecated
+    @SystemApi
     public void powerOnRemoteDevice(HdmiDeviceInfo deviceInfo) {
         Preconditions.checkNotNull(deviceInfo);
         try {
@@ -487,15 +539,35 @@
     }
 
     /**
-     * Request the target device to be the new Active Source by sending CEC commands.
+     * Request the target device to be the new Active Source by sending CEC commands. Note that
+     * this device can't be the current device itself.
      *
      * <p>The target device info can be obtained by calling {@link #getConnectedDevicesList()}.
      *
+     * <p>If the target device responds to the command, the users should see the target device
+     * streaming on their TVs.
+     *
      * @param deviceInfo HdmiDeviceInfo of the target device
      *
      * @hide
      */
     @SystemApi
+    public void setActiveSource(@NonNull HdmiDeviceInfo deviceInfo) {
+        Preconditions.checkNotNull(deviceInfo);
+        try {
+            mService.askRemoteDeviceToBecomeActiveSource(deviceInfo.getPhysicalAddress());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @removed
+     * @hide
+     * @deprecated Please use {@link #setActiveSource(deviceInfo)} instead.
+     */
+    @Deprecated
+    @SystemApi
     public void requestRemoteDeviceToBecomeActiveSource(@NonNull HdmiDeviceInfo deviceInfo) {
         Preconditions.checkNotNull(deviceInfo);
         try {
@@ -556,7 +628,7 @@
     }
 
     /**
-     * Check if the target remote device is connected to the current device.
+     * Check if the target device is connected to the current device.
      *
      * <p>The API also returns true if the current device is the target.
      *
@@ -567,6 +639,27 @@
      * @hide
      */
     @SystemApi
+    public boolean isDeviceConnected(@NonNull HdmiDeviceInfo targetDevice) {
+        Preconditions.checkNotNull(targetDevice);
+        mPhysicalAddress = getPhysicalAddress();
+        if (mPhysicalAddress == INVALID_PHYSICAL_ADDRESS) {
+            return false;
+        }
+        int targetPhysicalAddress = targetDevice.getPhysicalAddress();
+        if (targetPhysicalAddress == INVALID_PHYSICAL_ADDRESS) {
+            return false;
+        }
+        return HdmiUtils.getLocalPortFromPhysicalAddress(targetPhysicalAddress, mPhysicalAddress)
+            != HdmiUtils.TARGET_NOT_UNDER_LOCAL_DEVICE;
+    }
+
+    /**
+     * @removed
+     * @hide
+     * @deprecated Please use {@link #isDeviceConnected(targetDevice)} instead.
+     */
+    @Deprecated
+    @SystemApi
     public boolean isRemoteDeviceConnected(@NonNull HdmiDeviceInfo targetDevice) {
         Preconditions.checkNotNull(targetDevice);
         mPhysicalAddress = getPhysicalAddress();
diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java
index 06c32c6..b6c4fe2 100644
--- a/core/java/android/net/DnsResolver.java
+++ b/core/java/android/net/DnsResolver.java
@@ -93,6 +93,23 @@
     public static final int FLAG_NO_CACHE_STORE = 1 << 1;
     public static final int FLAG_NO_CACHE_LOOKUP = 1 << 2;
 
+    @IntDef(prefix = { "ERROR_" }, value = {
+            ERROR_PARSE,
+            ERROR_SYSTEM
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface DnsError {}
+    /**
+     * Indicates that there was an error parsing the response the query.
+     * The cause of this error is available via getCause() and is a ParseException.
+     */
+    public static final int ERROR_PARSE = 0;
+    /**
+     * Indicates that there was an error sending the query.
+     * The cause of this error is available via getCause() and is an ErrnoException.
+     */
+    public static final int ERROR_SYSTEM = 1;
+
     private static final int NETID_UNSET = 0;
 
     private static final DnsResolver sInstance = new DnsResolver();
@@ -107,97 +124,57 @@
     private DnsResolver() {}
 
     /**
-     * Answer parser for parsing raw answers
+     * Base interface for answer callbacks
      *
-     * @param <T> The type of the parsed answer
+     * @param <T> The type of the answer
      */
-    public interface AnswerParser<T> {
-        /**
-         * Creates a <T> answer by parsing the given raw answer.
-         *
-         * @param rawAnswer the raw answer to be parsed
-         * @return a parsed <T> answer
-         * @throws ParseException if parsing failed
-         */
-        @NonNull T parse(@NonNull byte[] rawAnswer) throws ParseException;
-    }
-
-    /**
-     * Base class for answer callbacks
-     *
-     * @param <T> The type of the parsed answer
-     */
-    public abstract static class AnswerCallback<T> {
-        /** @hide */
-        public final AnswerParser<T> parser;
-
-        public AnswerCallback(@NonNull AnswerParser<T> parser) {
-            this.parser = parser;
-        };
-
+    public interface Callback<T> {
         /**
          * Success response to
-         * {@link android.net.DnsResolver#query query()}.
+         * {@link android.net.DnsResolver#query query()} or
+         * {@link android.net.DnsResolver#rawQuery rawQuery()}.
          *
          * Invoked when the answer to a query was successfully parsed.
          *
-         * @param answer parsed answer to the query.
+         * @param answer <T> answer to the query.
+         * @param rcode The response code in the DNS response.
          *
          * {@see android.net.DnsResolver#query query()}
          */
-        public abstract void onAnswer(@NonNull T answer);
-
+        void onAnswer(@NonNull T answer, int rcode);
         /**
          * Error response to
-         * {@link android.net.DnsResolver#query query()}.
+         * {@link android.net.DnsResolver#query query()} or
+         * {@link android.net.DnsResolver#rawQuery rawQuery()}.
          *
          * Invoked when there is no valid answer to
          * {@link android.net.DnsResolver#query query()}
+         * {@link android.net.DnsResolver#rawQuery rawQuery()}.
          *
-         * @param exception a {@link ParseException} object with additional
+         * @param error a {@link DnsException} object with additional
          *    detail regarding the failure
          */
-        public abstract void onParseException(@NonNull ParseException exception);
-
-        /**
-         * Error response to
-         * {@link android.net.DnsResolver#query query()}.
-         *
-         * Invoked if an error happens when
-         * issuing the DNS query or receiving the result.
-         * {@link android.net.DnsResolver#query query()}
-         *
-         * @param exception an {@link ErrnoException} object with additional detail
-         *    regarding the failure
-         */
-        public abstract void onQueryException(@NonNull ErrnoException exception);
+        void onError(@NonNull DnsException error);
     }
 
     /**
-     * Callback for receiving raw answers
+     * Class to represent DNS error
      */
-    public abstract static class RawAnswerCallback extends AnswerCallback<byte[]> {
-        public RawAnswerCallback() {
-            super(rawAnswer -> rawAnswer);
-        }
-    }
+    public static class DnsException extends Exception {
+       /**
+        * DNS error code as one of the ERROR_* constants
+        */
+        @DnsError public final int code;
 
-    /**
-     * Callback for receiving parsed {@link InetAddress} answers
-     *
-     * Note that if the answer does not contain any IP addresses,
-     * onAnswer will be called with an empty list.
-     */
-    public abstract static class InetAddressAnswerCallback
-            extends AnswerCallback<List<InetAddress>> {
-        public InetAddressAnswerCallback() {
-            super(rawAnswer -> new DnsAddressAnswer(rawAnswer).getAddresses());
+        DnsException(@DnsError int code, @Nullable Throwable cause) {
+            super(cause);
+            this.code = code;
         }
     }
 
     /**
      * Send a raw DNS query.
-     * The answer will be provided asynchronously through the provided {@link AnswerCallback}.
+     * The answer will be provided asynchronously through the provided {@link Callback}.
      *
      * @param network {@link Network} specifying which network to query on.
      *         {@code null} for query on default network.
@@ -206,13 +183,13 @@
      * @param executor The {@link Executor} that the callback should be executed on.
      * @param cancellationSignal used by the caller to signal if the query should be
      *    cancelled. May be {@code null}.
-     * @param callback an {@link AnswerCallback} which will be called to notify the caller
+     * @param callback a {@link Callback} which will be called to notify the caller
      *    of the result of dns query.
      */
-    public <T> void query(@Nullable Network network, @NonNull byte[] query, @QueryFlag int flags,
+    public void rawQuery(@Nullable Network network, @NonNull byte[] query, @QueryFlag int flags,
             @NonNull @CallbackExecutor Executor executor,
             @Nullable CancellationSignal cancellationSignal,
-            @NonNull AnswerCallback<T> callback) {
+            @NonNull Callback<? super byte[]> callback) {
         if (cancellationSignal != null && cancellationSignal.isCanceled()) {
             return;
         }
@@ -222,9 +199,7 @@
             queryfd = resNetworkSend((network != null
                 ? network.netId : NETID_UNSET), query, query.length, flags);
         } catch (ErrnoException e) {
-            executor.execute(() -> {
-                callback.onQueryException(e);
-            });
+            executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
             return;
         }
 
@@ -237,7 +212,7 @@
 
     /**
      * Send a DNS query with the specified name, class and query type.
-     * The answer will be provided asynchronously through the provided {@link AnswerCallback}.
+     * The answer will be provided asynchronously through the provided {@link Callback}.
      *
      * @param network {@link Network} specifying which network to query on.
      *         {@code null} for query on default network.
@@ -248,14 +223,14 @@
      * @param executor The {@link Executor} that the callback should be executed on.
      * @param cancellationSignal used by the caller to signal if the query should be
      *    cancelled. May be {@code null}.
-     * @param callback an {@link AnswerCallback} which will be called to notify the caller
+     * @param callback a {@link Callback} which will be called to notify the caller
      *    of the result of dns query.
      */
-    public <T> void query(@Nullable Network network, @NonNull String domain,
+    public void rawQuery(@Nullable Network network, @NonNull String domain,
             @QueryClass int nsClass, @QueryType int nsType, @QueryFlag int flags,
             @NonNull @CallbackExecutor Executor executor,
             @Nullable CancellationSignal cancellationSignal,
-            @NonNull AnswerCallback<T> callback) {
+            @NonNull Callback<? super byte[]> callback) {
         if (cancellationSignal != null && cancellationSignal.isCanceled()) {
             return;
         }
@@ -265,9 +240,7 @@
             queryfd = resNetworkQuery((network != null
                     ? network.netId : NETID_UNSET), domain, nsClass, nsType, flags);
         } catch (ErrnoException e) {
-            executor.execute(() -> {
-                callback.onQueryException(e);
-            });
+            executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
             return;
         }
         synchronized (lock)  {
@@ -277,27 +250,28 @@
         }
     }
 
-    private class InetAddressAnswerAccumulator extends InetAddressAnswerCallback {
+    private class InetAddressAnswerAccumulator implements Callback<byte[]> {
         private final List<InetAddress> mAllAnswers;
-        private ParseException mParseException;
-        private ErrnoException mErrnoException;
-        private final InetAddressAnswerCallback mUserCallback;
+        private int mRcode;
+        private DnsException mDnsException;
+        private final Callback<? super List<InetAddress>> mUserCallback;
         private final int mTargetAnswerCount;
         private int mReceivedAnswerCount = 0;
 
-        InetAddressAnswerAccumulator(int size, @NonNull InetAddressAnswerCallback callback) {
+        InetAddressAnswerAccumulator(int size,
+                @NonNull Callback<? super List<InetAddress>> callback) {
             mTargetAnswerCount = size;
             mAllAnswers = new ArrayList<>();
             mUserCallback = callback;
         }
 
-        private boolean maybeReportException() {
-            if (mErrnoException != null) {
-                mUserCallback.onQueryException(mErrnoException);
+        private boolean maybeReportError() {
+            if (mRcode != 0) {
+                mUserCallback.onAnswer(mAllAnswers, mRcode);
                 return true;
             }
-            if (mParseException != null) {
-                mUserCallback.onParseException(mParseException);
+            if (mDnsException != null) {
+                mUserCallback.onError(mDnsException);
                 return true;
             }
             return false;
@@ -305,34 +279,43 @@
 
         private void maybeReportAnswer() {
             if (++mReceivedAnswerCount != mTargetAnswerCount) return;
-            if (mAllAnswers.isEmpty() && maybeReportException()) return;
+            if (mAllAnswers.isEmpty() && maybeReportError()) return;
             // TODO: Do RFC6724 sort.
-            mUserCallback.onAnswer(mAllAnswers);
+            mUserCallback.onAnswer(mAllAnswers, mRcode);
         }
 
         @Override
-        public void onAnswer(@NonNull List<InetAddress> answer) {
-            mAllAnswers.addAll(answer);
+        public void onAnswer(@NonNull byte[] answer, int rcode) {
+            // If at least one query succeeded, return an rcode of 0.
+            // Otherwise, arbitrarily return the first rcode received.
+            if (mReceivedAnswerCount == 0 || rcode == 0) {
+                mRcode = rcode;
+            }
+            try {
+                mAllAnswers.addAll(new DnsAddressAnswer(answer).getAddresses());
+            } catch (ParseException e) {
+                mDnsException = new DnsException(ERROR_PARSE, e);
+            }
             maybeReportAnswer();
         }
 
         @Override
-        public void onParseException(@NonNull ParseException e) {
-            mParseException = e;
-            maybeReportAnswer();
-        }
-
-        @Override
-        public void onQueryException(@NonNull ErrnoException e) {
-            mErrnoException = e;
+        public void onError(@NonNull DnsException error) {
+            mDnsException = error;
             maybeReportAnswer();
         }
     }
 
     /**
-     * Send a DNS query with the specified name, get back a set of InetAddresses asynchronously.
-     * The answer will be provided asynchronously through the provided
-     * {@link InetAddressAnswerCallback}.
+     * Send a DNS query with the specified name on a network with both IPv4 and IPv6,
+     * get back a set of InetAddresses asynchronously.
+     *
+     * This method will examine the connection ability on given network, and query IPv4
+     * and IPv6 if connection is available.
+     *
+     * If at least one query succeeded with valid answer, rcode will be 0
+     *
+     * The answer will be provided asynchronously through the provided {@link Callback}.
      *
      * @param network {@link Network} specifying which network to query on.
      *         {@code null} for query on default network.
@@ -341,13 +324,13 @@
      * @param executor The {@link Executor} that the callback should be executed on.
      * @param cancellationSignal used by the caller to signal if the query should be
      *    cancelled. May be {@code null}.
-     * @param callback an {@link InetAddressAnswerCallback} which will be called to notify the
+     * @param callback a {@link Callback} which will be called to notify the
      *    caller of the result of dns query.
      */
     public void query(@Nullable Network network, @NonNull String domain, @QueryFlag int flags,
             @NonNull @CallbackExecutor Executor executor,
             @Nullable CancellationSignal cancellationSignal,
-            @NonNull InetAddressAnswerCallback callback) {
+            @NonNull Callback<? super List<InetAddress>> callback) {
         if (cancellationSignal != null && cancellationSignal.isCanceled()) {
             return;
         }
@@ -365,9 +348,7 @@
                 v6fd = resNetworkQuery((network != null
                         ? network.netId : NETID_UNSET), domain, CLASS_IN, TYPE_AAAA, flags);
             } catch (ErrnoException e) {
-                executor.execute(() -> {
-                    callback.onQueryException(e);
-                });
+                executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
                 return;
             }
             queryCount++;
@@ -377,7 +358,9 @@
         // Avoiding gateways drop packets if queries are sent too close together
         try {
             Thread.sleep(SLEEP_TIME_MS);
-        } catch (InterruptedException ex) { }
+        } catch (InterruptedException ex) {
+            Thread.currentThread().interrupt();
+        }
 
         if (queryIpv4) {
             try {
@@ -385,9 +368,7 @@
                         ? network.netId : NETID_UNSET), domain, CLASS_IN, TYPE_A, flags);
             } catch (ErrnoException e) {
                 if (queryIpv6) resNetworkCancel(v6fd);  // Closes fd, marks it invalid.
-                executor.execute(() -> {
-                    callback.onQueryException(e);
-                });
+                executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
                 return;
             }
             queryCount++;
@@ -413,34 +394,89 @@
         }
     }
 
-    private <T> void registerFDListener(@NonNull Executor executor,
-            @NonNull FileDescriptor queryfd, @NonNull AnswerCallback<T> answerCallback,
+    /**
+     * Send a DNS query with the specified name and query type, get back a set of
+     * InetAddresses asynchronously.
+     *
+     * The answer will be provided asynchronously through the provided {@link Callback}.
+     *
+     * @param network {@link Network} specifying which network to query on.
+     *         {@code null} for query on default network.
+     * @param domain domain name to query
+     * @param nsType dns resource record (RR) type as one of the TYPE_* constants
+     * @param flags flags as a combination of the FLAGS_* constants
+     * @param executor The {@link Executor} that the callback should be executed on.
+     * @param cancellationSignal used by the caller to signal if the query should be
+     *    cancelled. May be {@code null}.
+     * @param callback a {@link Callback} which will be called to notify the caller
+     *    of the result of dns query.
+     */
+    public void query(@Nullable Network network, @NonNull String domain,
+            @QueryType int nsType, @QueryFlag int flags,
+            @NonNull @CallbackExecutor Executor executor,
+            @Nullable CancellationSignal cancellationSignal,
+            @NonNull Callback<? super List<InetAddress>> callback) {
+        if (cancellationSignal != null && cancellationSignal.isCanceled()) {
+            return;
+        }
+        final Object lock = new Object();
+        final FileDescriptor queryfd;
+        try {
+            queryfd = resNetworkQuery((network != null
+                    ? network.netId : NETID_UNSET), domain, CLASS_IN, nsType, flags);
+        } catch (ErrnoException e) {
+            executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
+            return;
+        }
+        final InetAddressAnswerAccumulator accumulator =
+                new InetAddressAnswerAccumulator(1, callback);
+        synchronized (lock)  {
+            registerFDListener(executor, queryfd, accumulator, cancellationSignal, lock);
+            if (cancellationSignal == null) return;
+            addCancellationSignal(cancellationSignal, queryfd, lock);
+        }
+    }
+
+    /**
+     * Class to retrieve DNS response
+     *
+     * @hide
+     */
+    public static final class DnsResponse {
+        public final @NonNull byte[] answerbuf;
+        public final int rcode;
+        public DnsResponse(@NonNull byte[] answerbuf, int rcode) {
+            this.answerbuf = answerbuf;
+            this.rcode = rcode;
+        }
+    }
+
+    private void registerFDListener(@NonNull Executor executor,
+            @NonNull FileDescriptor queryfd, @NonNull Callback<? super byte[]> answerCallback,
             @Nullable CancellationSignal cancellationSignal, @NonNull Object lock) {
         Looper.getMainLooper().getQueue().addOnFileDescriptorEventListener(
                 queryfd,
                 FD_EVENTS,
                 (fd, events) -> {
                     executor.execute(() -> {
+                        DnsResponse resp = null;
+                        ErrnoException exception = null;
                         synchronized (lock) {
                             if (cancellationSignal != null && cancellationSignal.isCanceled()) {
                                 return;
                             }
-                            byte[] answerbuf = null;
                             try {
-                                answerbuf = resNetworkResult(fd);  // Closes fd, marks it invalid.
+                                resp = resNetworkResult(fd);  // Closes fd, marks it invalid.
                             } catch (ErrnoException e) {
                                 Log.e(TAG, "resNetworkResult:" + e.toString());
-                                answerCallback.onQueryException(e);
-                                return;
-                            }
-
-                            try {
-                                answerCallback.onAnswer(
-                                        answerCallback.parser.parse(answerbuf));
-                            } catch (ParseException e) {
-                                answerCallback.onParseException(e);
+                                exception = e;
                             }
                         }
+                        if (exception != null) {
+                            answerCallback.onError(new DnsException(ERROR_SYSTEM, exception));
+                            return;
+                        }
+                        answerCallback.onAnswer(resp.answerbuf, resp.rcode);
                     });
                     // Unregister this fd listener
                     return 0;
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index db87c97..c06a132 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -145,9 +145,10 @@
     /**
      * DNS resolver series jni method.
      * Read a result for the query associated with the {@code fd}.
-     * @return a byte array containing blob answer
+     * @return DnsResponse containing blob answer and rcode
      */
-    public static native byte[] resNetworkResult(FileDescriptor fd) throws ErrnoException;
+    public static native DnsResolver.DnsResponse resNetworkResult(FileDescriptor fd)
+            throws ErrnoException;
 
     /**
      * DNS resolver series jni method.
diff --git a/core/java/android/net/ParseException.java b/core/java/android/net/ParseException.java
index 9d4727a..bcfdd7e 100644
--- a/core/java/android/net/ParseException.java
+++ b/core/java/android/net/ParseException.java
@@ -25,12 +25,12 @@
 public class ParseException extends RuntimeException {
     public String response;
 
-    public ParseException(@NonNull String response) {
+    ParseException(@NonNull String response) {
         super(response);
         this.response = response;
     }
 
-    public ParseException(@NonNull String response, @NonNull Throwable cause) {
+    ParseException(@NonNull String response, @NonNull Throwable cause) {
         super(response, cause);
         this.response = response;
     }
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index 847b8e4..02f9925 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -16,6 +16,7 @@
 
 package android.preference;
 
+import android.annotation.NonNull;
 import android.annotation.UnsupportedAppUsage;
 import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
@@ -27,8 +28,8 @@
 import android.media.AudioManager;
 import android.media.Ringtone;
 import android.media.RingtoneManager;
-import android.media.audiopolicy.AudioProductStrategies;
-import android.media.audiopolicy.AudioVolumeGroups;
+import android.media.audiopolicy.AudioProductStrategy;
+import android.media.audiopolicy.AudioVolumeGroup;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -67,7 +68,6 @@
 
     private static final int MSG_GROUP_VOLUME_CHANGED = 1;
     private final Handler mVolumeHandler = new VolumeHandler();
-    private final AudioProductStrategies mAudioProductStrategies;
     private AudioAttributes mAttributes;
     private int mVolumeGroupId;
 
@@ -161,11 +161,9 @@
         }
         mZenMode = mNotificationManager.getZenMode();
 
-        mAudioProductStrategies = mAudioManager.getAudioProductStrategies();
-        if (mAudioProductStrategies.size() > 0) {
-            mVolumeGroupId = mAudioProductStrategies.getVolumeGroupIdForLegacyStreamType(
-                    mStreamType);
-            mAttributes = mAudioProductStrategies.getAudioAttributesForLegacyStreamType(
+        if (hasAudioProductStrategies()) {
+            mVolumeGroupId = getVolumeGroupIdForLegacyStreamType(mStreamType);
+            mAttributes = getAudioAttributesForLegacyStreamType(
                     mStreamType);
         }
 
@@ -190,6 +188,40 @@
         mDefaultUri = defaultUri;
     }
 
+    private boolean hasAudioProductStrategies() {
+        return AudioManager.getAudioProductStrategies().size() > 0;
+    }
+
+    private int getVolumeGroupIdForLegacyStreamType(int streamType) {
+        for (final AudioProductStrategy productStrategy :
+                AudioManager.getAudioProductStrategies()) {
+            int volumeGroupId = productStrategy.getVolumeGroupIdForLegacyStreamType(streamType);
+            if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
+                return volumeGroupId;
+            }
+        }
+
+        return AudioManager.getAudioProductStrategies().stream()
+                .map(strategy -> strategy.getVolumeGroupIdForAudioAttributes(
+                        AudioProductStrategy.sDefaultAttributes))
+                .filter(volumeGroupId -> volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP)
+                .findFirst()
+                .orElse(AudioVolumeGroup.DEFAULT_VOLUME_GROUP);
+    }
+
+    private @NonNull AudioAttributes getAudioAttributesForLegacyStreamType(int streamType) {
+        for (final AudioProductStrategy productStrategy :
+                AudioManager.getAudioProductStrategies()) {
+            AudioAttributes aa = productStrategy.getAudioAttributesForLegacyStreamType(streamType);
+            if (aa != null) {
+                return aa;
+            }
+        }
+        return new AudioAttributes.Builder()
+                .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
+                .setUsage(AudioAttributes.USAGE_UNKNOWN).build();
+    }
+
     private static boolean isNotificationOrRing(int stream) {
         return stream == AudioManager.STREAM_RING || stream == AudioManager.STREAM_NOTIFICATION;
     }
@@ -329,7 +361,7 @@
         postStopSample();
         mContext.getContentResolver().unregisterContentObserver(mVolumeObserver);
         mReceiver.setListening(false);
-        if (mAudioProductStrategies.size() > 0) {
+        if (hasAudioProductStrategies()) {
             unregisterVolumeGroupCb();
         }
         mSeekBar.setOnSeekBarChangeListener(null);
@@ -349,7 +381,7 @@
                 System.getUriFor(System.VOLUME_SETTINGS_INT[mStreamType]),
                 false, mVolumeObserver);
         mReceiver.setListening(true);
-        if (mAudioProductStrategies.size() > 0) {
+        if (hasAudioProductStrategies()) {
             registerVolumeGroupCb();
         }
     }
@@ -507,7 +539,7 @@
             if (AudioManager.VOLUME_CHANGED_ACTION.equals(action)) {
                 int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
                 int streamValue = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
-                if (mAudioProductStrategies.size() == 0) {
+                if (hasAudioProductStrategies()) {
                     updateVolumeSlider(streamType, streamValue);
                 }
             } else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
@@ -519,13 +551,12 @@
                 }
             } else if (AudioManager.STREAM_DEVICES_CHANGED_ACTION.equals(action)) {
                 int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
-                if (mAudioProductStrategies.size() == 0) {
+                if (hasAudioProductStrategies()) {
                     int streamVolume = mAudioManager.getStreamVolume(streamType);
                     updateVolumeSlider(streamType, streamVolume);
                 } else {
-                    int volumeGroup = mAudioProductStrategies.getVolumeGroupIdForLegacyStreamType(
-                            streamType);
-                    if (volumeGroup != AudioVolumeGroups.DEFAULT_VOLUME_GROUP
+                    int volumeGroup = getVolumeGroupIdForLegacyStreamType(streamType);
+                    if (volumeGroup != AudioVolumeGroup.DEFAULT_VOLUME_GROUP
                             && volumeGroup == mVolumeGroupId) {
                         int streamVolume = mAudioManager.getStreamVolume(streamType);
                         updateVolumeSlider(streamType, streamVolume);
@@ -558,14 +589,14 @@
     }
 
     private void registerVolumeGroupCb() {
-        if (mVolumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
+        if (mVolumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
             mAudioManager.registerVolumeGroupCallback(Runnable::run, mVolumeGroupCallback);
             mLastProgress = mAudioManager.getVolumeIndexForAttributes(mAttributes);
         }
     }
 
     private void unregisterVolumeGroupCb() {
-        if (mVolumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
+        if (mVolumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
             mAudioManager.unregisterVolumeGroupCallback(mVolumeGroupCallback);
         }
     }
@@ -578,7 +609,7 @@
                 case MSG_GROUP_VOLUME_CHANGED:
                     int group = (int) args.arg1;
                     if (mVolumeGroupId != group
-                            || mVolumeGroupId == AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
+                            || mVolumeGroupId == AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
                         return;
                     }
                     updateSlider();
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index da19d59..bff8328 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -31,7 +31,6 @@
 import android.app.Activity;
 import android.app.AppGlobals;
 import android.content.ClipData;
-import android.content.ContentInterface;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.ContentUris;
@@ -968,6 +967,13 @@
         public static final String DATE_MODIFIED = "date_modified";
 
         /**
+         * The time the media item was taken.
+         */
+        @CurrentTimeMillisLong
+        @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+        public static final String DATE_TAKEN = "datetaken";
+
+        /**
          * The MIME type of the media item.
          * <p>
          * This is typically defined based on the file extension of the media
@@ -1117,6 +1123,38 @@
         public static final String SECONDARY_DIRECTORY = "secondary_directory";
 
         /**
+         * The primary bucket ID of this media item. This can be useful to
+         * present the user a first-level clustering of related media items.
+         * This is a read-only column that is automatically computed.
+         */
+        @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+        public static final String BUCKET_ID = "bucket_id";
+
+        /**
+         * The primary bucket display name of this media item. This can be
+         * useful to present the user a first-level clustering of related
+         * media items. This is a read-only column that is automatically
+         * computed.
+         */
+        @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+        public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
+
+        /**
+         * The group ID of this media item. This can be useful to present
+         * the user a grouping of related media items, such a burst of
+         * images, or a {@code JPG} and {@code DNG} version of the same
+         * image.
+         * <p>
+         * This is a read-only column that is automatically computed based
+         * on the first portion of the filename. For example,
+         * {@code IMG1024.BURST001.JPG} and {@code IMG1024.BURST002.JPG}
+         * will have the same {@link #GROUP_ID} because the first portion of
+         * their filenames is identical.
+         */
+        @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+        public static final String GROUP_ID = "group_id";
+
+        /**
          * The "document ID" GUID as defined by the <em>XMP Media
          * Management</em> standard, extracted from any XMP metadata contained
          * within this media item. The value is {@code null} when no metadata
@@ -1152,6 +1190,20 @@
          */
         @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
         public static final String ORIGINAL_DOCUMENT_ID = "original_document_id";
+
+        /**
+         * The duration of the media item.
+         */
+        @DurationMillisLong
+        @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+        public static final String DURATION = "duration";
+
+        /**
+         * The orientation for the media item, expressed in degrees. For
+         * example, 0, 90, 180, or 270 degrees.
+         */
+        @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+        public static final String ORIENTATION = "orientation";
     }
 
     /**
@@ -1357,7 +1409,10 @@
 
         /**
          * The description of the download.
+         *
+         * @removed
          */
+        @Deprecated
         @Column(Cursor.FIELD_TYPE_STRING)
         String DESCRIPTION = "description";
     }
@@ -1573,18 +1628,9 @@
             @Column(value = Cursor.FIELD_TYPE_FLOAT, readOnly = true)
             public static final String LONGITUDE = "longitude";
 
-            /**
-             * The time the media item was taken.
-             */
-            @CurrentTimeMillisLong
-            @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+            /** @removed promoted to parent interface */
             public static final String DATE_TAKEN = "datetaken";
-
-            /**
-             * The orientation for the image expressed as degrees.
-             * Only degrees 0, 90, 180, 270 will work.
-             */
-            @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+            /** @removed promoted to parent interface */
             public static final String ORIENTATION = "orientation";
 
             /**
@@ -1598,36 +1644,11 @@
             @Column(Cursor.FIELD_TYPE_INTEGER)
             public static final String MINI_THUMB_MAGIC = "mini_thumb_magic";
 
-            /**
-             * The primary bucket ID of this media item. This can be useful to
-             * present the user a first-level clustering of related media items.
-             * This is a read-only column that is automatically computed.
-             */
-            @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+            /** @removed promoted to parent interface */
             public static final String BUCKET_ID = "bucket_id";
-
-            /**
-             * The primary bucket display name of this media item. This can be
-             * useful to present the user a first-level clustering of related
-             * media items. This is a read-only column that is automatically
-             * computed.
-             */
-            @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+            /** @removed promoted to parent interface */
             public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
-
-            /**
-             * The group ID of this media item. This can be useful to present
-             * the user a grouping of related media items, such a burst of
-             * images, or a {@code JPG} and {@code DNG} version of the same
-             * image.
-             * <p>
-             * This is a read-only column that is automatically computed based
-             * on the first portion of the filename. For example,
-             * {@code IMG1024.BURST001.JPG} and {@code IMG1024.BURST002.JPG}
-             * will have the same {@link #GROUP_ID} because the first portion of
-             * their filenames is identical.
-             */
-            @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+            /** @removed promoted to parent interface */
             public static final String GROUP_ID = "group_id";
         }
 
@@ -2048,11 +2069,7 @@
             @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
             public static final String TITLE_KEY = "title_key";
 
-            /**
-             * The duration of the audio item.
-             */
-            @DurationMillisLong
-            @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+            /** @removed promoted to parent interface */
             public static final String DURATION = "duration";
 
             /**
@@ -2885,12 +2902,7 @@
          * Video metadata columns.
          */
         public interface VideoColumns extends MediaColumns {
-
-            /**
-             * The duration of the video item.
-             */
-            @DurationMillisLong
-            @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+            /** @removed promoted to parent interface */
             public static final String DURATION = "duration";
 
             /**
@@ -2965,11 +2977,7 @@
             @Column(value = Cursor.FIELD_TYPE_FLOAT, readOnly = true)
             public static final String LONGITUDE = "longitude";
 
-            /**
-             * The time the media item was taken.
-             */
-            @CurrentTimeMillisLong
-            @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+            /** @removed promoted to parent interface */
             public static final String DATE_TAKEN = "datetaken";
 
             /**
@@ -2983,36 +2991,11 @@
             @Column(Cursor.FIELD_TYPE_INTEGER)
             public static final String MINI_THUMB_MAGIC = "mini_thumb_magic";
 
-            /**
-             * The primary bucket ID of this media item. This can be useful to
-             * present the user a first-level clustering of related media items.
-             * This is a read-only column that is automatically computed.
-             */
-            @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+            /** @removed promoted to parent interface */
             public static final String BUCKET_ID = "bucket_id";
-
-            /**
-             * The primary bucket display name of this media item. This can be
-             * useful to present the user a first-level clustering of related
-             * media items. This is a read-only column that is automatically
-             * computed.
-             */
-            @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+            /** @removed promoted to parent interface */
             public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
-
-            /**
-             * The group ID of this media item. This can be useful to present
-             * the user a grouping of related media items, such a burst of
-             * images, or a {@code JPG} and {@code DNG} version of the same
-             * image.
-             * <p>
-             * This is a read-only column that is automatically computed based
-             * on the first portion of the filename. For example,
-             * {@code IMG1024.BURST001.JPG} and {@code IMG1024.BURST002.JPG}
-             * will have the same {@link #GROUP_ID} because the first portion of
-             * their filenames is identical.
-             */
-            @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+            /** @removed promoted to parent interface */
             public static final String GROUP_ID = "group_id";
 
             /**
diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java
index 4088ce8..30c4e90 100644
--- a/core/java/android/service/textclassifier/TextClassifierService.java
+++ b/core/java/android/service/textclassifier/TextClassifierService.java
@@ -358,6 +358,7 @@
     /**
      * Returns the platform's default TextClassifier implementation.
      */
+    @NonNull
     public static TextClassifier getDefaultTextClassifierImplementation(@NonNull Context context) {
         final TextClassificationManager tcm =
                 context.getSystemService(TextClassificationManager.class);
diff --git a/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java
index 9da29c0..cfc092c 100644
--- a/core/java/android/util/StatsLog.java
+++ b/core/java/android/util/StatsLog.java
@@ -187,21 +187,6 @@
     }
 
     /**
-     * Add a log to the stats log.
-     *
-     * @param id     The id of the atom
-     * @param params The parameters of the atom's message.
-     */
-    public static void write(int id, @NonNull Object... params) {
-        switch (id) {
-            case PERMISSION_GRANT_REQUEST_RESULT_REPORTED:
-                write(id, (long) params[0], (int) params[1], (String) params[2], (String) params[3],
-                        (boolean) params[4], (int) params[5]);
-                break;
-        }
-    }
-
-    /**
      * Write an event to stats log using the raw format.
      *
      * @param buffer    The encoded buffer of data to write..
diff --git a/core/java/android/util/StatsLogAtoms.java b/core/java/android/util/StatsLogAtoms.java
deleted file mode 100644
index 4780cb5..0000000
--- a/core/java/android/util/StatsLogAtoms.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-
-import java.lang.annotation.Retention;
-
-/**
- * Exposed stats logs atom ids.
- *
- * @hide
- */
-@SystemApi
-public class StatsLogAtoms {
-    private StatsLogAtoms() {
-    }
-
-    /**
-     * Information about a permission grant request
-     *
-     * Usage: {@code StatsLog.write(PERMISSION_GRANT_REQUEST_RESULT_REPORTED, long request_id,
-     * int requesting_uid, String requesting_package_name, String permission_name,
-     * boolean is_implicit, @PermissionGrantRequestResultReported_Result int result)}
-     */
-    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED =
-            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED;
-
-    @Retention(SOURCE)
-    @IntDef(prefix = "PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__",
-            value = {PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED,
-                    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED,
-                    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED,
-                    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED,
-                    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED,
-                    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED,
-                    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE,
-                    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED})
-    public @interface PermissionGrantRequestResultReported_Result {}
-
-    /**
-     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
-     * permission request was ignored
-     */
-    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED =
-            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED;
-
-    /**
-     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
-     * permission request was ignored because it was user fixed
-     */
-    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED =
-            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED;
-
-    /**
-     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
-     * permission request was ignored because it was policy fixed
-     */
-    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED =
-            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED;
-
-    /**
-     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
-     * permission request was ignored because it was restricted
-     */
-    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_RESTRICTED_PERMISSION =
-            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_RESTRICTED_PERMISSION;
-
-    /**
-     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
-     * permission was granted by user action
-     */
-    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED =
-            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED;
-
-    /**
-     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
-     * permission was automatically granted
-     */
-    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED =
-            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED;
-
-    /**
-     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
-     * permission was denied by user action
-     */
-    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED =
-            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED;
-
-    /**
-     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
-     * permission was denied with prejudice by the user
-     */
-    public static final int
-            PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE =
-            StatsLogInternal
-                    .PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE;
-
-    /**
-     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
-     * permission was automatically denied
-     */
-    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED =
-            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED;
-}
diff --git a/core/java/android/view/InputMonitor.java b/core/java/android/view/InputMonitor.java
index 693f287..bbd27dc 100644
--- a/core/java/android/view/InputMonitor.java
+++ b/core/java/android/view/InputMonitor.java
@@ -22,6 +22,13 @@
 import android.os.RemoteException;
 
 /**
+ * An {@code InputMonitor} allows privileged applications and components to monitor streams of
+ * {@link InputEvent}s without having to be the designated recipient for the event.
+ *
+ * For example, focus dispatched events would normally only go to the focused window on the
+ * targeted display, but an {@code InputMonitor} will also receive a copy of that event if they're
+ * registered to monitor that type of event on the targeted display.
+ *
  * @hide
  */
 public final class InputMonitor implements Parcelable {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index b5ad908..d67c884 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -90,8 +90,8 @@
     private static native ScreenshotGraphicBuffer nativeScreenshot(IBinder displayToken,
             Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation,
             boolean captureSecureLayers);
-    private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
-            Rect sourceCrop, float frameScale, IBinder[] excludeLayers);
+    private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder displayToken,
+            IBinder layerHandleToken, Rect sourceCrop, float frameScale, IBinder[] excludeLayers);
 
     private static native long nativeCreateTransaction();
     private static native long nativeGetNativeTransactionFinalizer();
@@ -1998,7 +1998,8 @@
      */
     public static ScreenshotGraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
             float frameScale) {
-        return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale, null);
+        final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
+        return nativeCaptureLayers(displayToken, layerHandleToken, sourceCrop, frameScale, null);
     }
 
     /**
@@ -2007,7 +2008,8 @@
      */
     public static ScreenshotGraphicBuffer captureLayersExcluding(IBinder layerHandleToken,
             Rect sourceCrop, float frameScale, IBinder[] exclude) {
-        return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale, exclude);
+        final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
+        return nativeCaptureLayers(displayToken, layerHandleToken, sourceCrop, frameScale, exclude);
     }
 
     /**
diff --git a/core/java/android/view/textclassifier/TextLinks.java b/core/java/android/view/textclassifier/TextLinks.java
index 66a72f9..f3e0dc1 100644
--- a/core/java/android/view/textclassifier/TextLinks.java
+++ b/core/java/android/view/textclassifier/TextLinks.java
@@ -281,6 +281,7 @@
         /**
          * Returns a bundle containing custom data related to this TextLink.
          */
+        @NonNull
         public Bundle getExtras() {
             return mExtras;
         }
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 37bed65..4c32f03 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -21,6 +21,7 @@
 import android.annotation.NonNull;
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
+import android.content.res.ResourceId;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.os.Build;
@@ -1991,7 +1992,7 @@
                 // dependencies for a specific set of rules
                 for (int j = 0; j < rulesCount; j++) {
                     final int rule = rules[rulesFilter[j]];
-                    if (rule > 0) {
+                    if (ResourceId.isValid(rule)) {
                         // The node this node depends on
                         final Node dependency = keyNodes.get(rule);
                         // Skip unknowns and self dependencies
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index b51f808..4d4fe03 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -101,9 +101,7 @@
 import android.widget.AbsListView;
 import android.widget.BaseAdapter;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
 import android.widget.ListView;
-import android.widget.Space;
 import android.widget.TextView;
 import android.widget.Toast;
 
@@ -1429,11 +1427,9 @@
     }
 
     private void updateAlphabeticalList() {
-        if (getDisplayList().size() > MAX_RANKED_TARGETS) {
-            mSortedList.clear();
-            mSortedList.addAll(getDisplayList());
-            Collections.sort(mSortedList, new AzInfoComparator(ChooserActivity.this));
-        }
+        mSortedList.clear();
+        mSortedList.addAll(getDisplayList());
+        Collections.sort(mSortedList, new AzInfoComparator(ChooserActivity.this));
     }
 
     /**
@@ -1604,7 +1600,7 @@
         private final Intent mFillInIntent;
         private final int mFillInFlags;
         private final float mModifiedScore;
-        private boolean mIsSuspended;
+        private boolean mIsSuspended = false;
 
         SelectableTargetInfo(DisplayResolveInfo sourceInfo, ChooserTarget chooserTarget,
                 float modifiedScore) {
@@ -1619,6 +1615,8 @@
                         final PackageManager pm = getPackageManager();
                         mBadgeIcon = pm.getApplicationIcon(ai.applicationInfo);
                         mBadgeContentDescription = pm.getApplicationLabel(ai.applicationInfo);
+                        mIsSuspended =
+                                (ai.applicationInfo.flags & ApplicationInfo.FLAG_SUSPENDED) != 0;
                     }
                 }
             }
@@ -1633,8 +1631,6 @@
 
             mFillInIntent = null;
             mFillInFlags = 0;
-            ApplicationInfo ai = sourceInfo.getResolveInfo().activityInfo.applicationInfo;
-            mIsSuspended = (ai.flags & ApplicationInfo.FLAG_SUSPENDED) != 0;
         }
 
         private SelectableTargetInfo(SelectableTargetInfo other, Intent fillInIntent, int flags) {
@@ -1836,7 +1832,7 @@
             return;
         }
 
-        if (mChooserRowAdapter.calculateMaxTargetsPerRow(right - left)
+        if (mChooserRowAdapter.calculateChooserTargetWidth(right - left)
                 || mAdapterView.getAdapter() == null) {
             mAdapterView.setAdapter(mChooserRowAdapter);
 
@@ -2049,12 +2045,13 @@
         @Override
         public int getUnfilteredCount() {
             int appTargets = super.getUnfilteredCount();
-            if (appTargets > MAX_RANKED_TARGETS) {
-                appTargets = appTargets + MAX_RANKED_TARGETS;
+            if (appTargets > getMaxRankedTargets()) {
+                appTargets = appTargets + getMaxRankedTargets();
             }
             return appTargets + getSelectableServiceTargetCount() + getCallerTargetCount();
         }
 
+
         public int getCallerTargetCount() {
             return Math.min(mCallerTargets.size(), MAX_SUGGESTED_APP_TARGETS);
         }
@@ -2082,14 +2079,17 @@
 
         int getAlphaTargetCount() {
             int standardCount = super.getCount();
-            return standardCount > MAX_RANKED_TARGETS ? standardCount : 0;
+            return standardCount > getMaxRankedTargets() ? standardCount : 0;
         }
 
         int getRankedTargetCount() {
-            int spacesAvailable = MAX_RANKED_TARGETS - getCallerTargetCount();
+            int spacesAvailable = getMaxRankedTargets() - getCallerTargetCount();
             return Math.min(spacesAvailable, super.getCount());
         }
 
+        private int getMaxRankedTargets() {
+            return mChooserRowAdapter == null ? 4 : mChooserRowAdapter.getMaxTargetsPerRow();
+        }
 
         public int getPositionTargetType(int position) {
             int offset = 0;
@@ -2325,9 +2325,9 @@
     class ChooserRowAdapter extends BaseAdapter {
         private ChooserListAdapter mChooserListAdapter;
         private final LayoutInflater mLayoutInflater;
-        private int mCalculatedMaxTargetsPerRow = MAX_TARGETS_PER_ROW_LANDSCAPE;
 
         private DirectShareViewHolder mDirectShareViewHolder;
+        private int mChooserTargetWidth = 0;
 
         private static final int VIEW_TYPE_DIRECT_SHARE = 0;
         private static final int VIEW_TYPE_NORMAL = 1;
@@ -2356,25 +2356,23 @@
         }
 
         /**
-         * Determine how many targets can comfortably fit in a single row.
+         * Calculate the chooser target width to maximize space per item
          *
          * @param width The new row width to use for recalculation
-         * @return true if the numbers of targets per row has changed
+         * @return true if the view width has changed
          */
-        public boolean calculateMaxTargetsPerRow(int width) {
-            int targetWidth = getResources().getDimensionPixelSize(
+        public boolean calculateChooserTargetWidth(int width) {
+            int targetMinWidth = getResources().getDimensionPixelSize(
                     R.dimen.chooser_target_width);
 
-            if (targetWidth == 0 || width == 0) {
+            if (width == 0) {
                 return false;
             }
 
-            int margin = getResources().getDimensionPixelSize(
-                    R.dimen.chooser_edge_margin_normal);
-
-            int newCount =  (width - margin * 2) / targetWidth;
-            if (newCount != mCalculatedMaxTargetsPerRow) {
-                mCalculatedMaxTargetsPerRow = newCount;
+            int targetWidth =  width / getMaxTargetsPerRow();
+            int newWidth = Math.max(targetWidth, targetMinWidth);
+            if (newWidth != mChooserTargetWidth) {
+                mChooserTargetWidth = newWidth;
                 return true;
             }
 
@@ -2388,7 +2386,7 @@
                 maxTargets = MAX_TARGETS_PER_ROW_LANDSCAPE;
             }
 
-            return Math.min(maxTargets, mCalculatedMaxTargetsPerRow);
+            return maxTargets;
         }
 
         @Override
@@ -2498,6 +2496,8 @@
 
         private RowViewHolder loadViewsIntoRow(RowViewHolder holder) {
             final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+            final int exactSpec = MeasureSpec.makeMeasureSpec(mChooserTargetWidth,
+                    MeasureSpec.EXACTLY);
             int columnCount = holder.getColumnCount();
 
             final boolean isDirectShare = holder instanceof DirectShareViewHolder;
@@ -2533,20 +2533,20 @@
                 }
 
                 // Force height to be a given so we don't have visual disruption during scaling.
-                v.measure(spec, spec);
-                setViewHeight(v, v.getMeasuredHeight());
+                v.measure(exactSpec, spec);
+                setViewBounds(v, v.getMeasuredWidth(), v.getMeasuredHeight());
             }
 
             final ViewGroup viewGroup = holder.getViewGroup();
 
             // Pre-measure and fix height so we can scale later.
             holder.measure();
-            setViewHeight(viewGroup, holder.getMeasuredRowHeight());
+            setViewBounds(viewGroup, LayoutParams.MATCH_PARENT, holder.getMeasuredRowHeight());
 
             if (isDirectShare) {
                 DirectShareViewHolder dsvh = (DirectShareViewHolder) holder;
-                setViewHeight(dsvh.getRow(0), dsvh.getMinRowHeight());
-                setViewHeight(dsvh.getRow(1), dsvh.getMinRowHeight());
+                setViewBounds(dsvh.getRow(0), LayoutParams.MATCH_PARENT, dsvh.getMinRowHeight());
+                setViewBounds(dsvh.getRow(1), LayoutParams.MATCH_PARENT, dsvh.getMinRowHeight());
             }
 
             viewGroup.setTag(holder);
@@ -2554,13 +2554,14 @@
             return holder;
         }
 
-        private void setViewHeight(View view, int heightPx) {
+        private void setViewBounds(View view, int widthPx, int heightPx) {
             LayoutParams lp = view.getLayoutParams();
             if (lp == null) {
-                lp = new LayoutParams(LayoutParams.MATCH_PARENT, heightPx);
+                lp = new LayoutParams(widthPx, heightPx);
                 view.setLayoutParams(lp);
             } else {
                 lp.height = heightPx;
+                lp.width = widthPx;
             }
         }
 
@@ -2712,11 +2713,6 @@
             return mMeasuredRowHeight;
         }
 
-        protected void addSpacer(ViewGroup row) {
-            row.addView(new Space(ChooserActivity.this),
-                    new LinearLayout.LayoutParams(0, 0, 1));
-        }
-
         public void setItemIndex(int itemIndex, int listIndex) {
             mItemIndices[itemIndex] = listIndex;
         }
@@ -2756,10 +2752,6 @@
             mRow.addView(v);
             mCells[index] = v;
 
-            if (index != (mCells.length - 1)) {
-                addSpacer(mRow);
-            }
-
             return mRow;
         }
 
@@ -2794,10 +2786,6 @@
             row.addView(v);
             mCells[index] = v;
 
-            if (index % mCellCountPerRow != (mCellCountPerRow - 1)) {
-                addSpacer(row);
-            }
-
             return row;
         }
 
diff --git a/core/java/com/android/internal/app/SimpleIconFactory.java b/core/java/com/android/internal/app/SimpleIconFactory.java
index a85485d..2484109 100644
--- a/core/java/com/android/internal/app/SimpleIconFactory.java
+++ b/core/java/com/android/internal/app/SimpleIconFactory.java
@@ -34,6 +34,8 @@
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.PaintFlagsDrawFilter;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.drawable.AdaptiveIconDrawable;
@@ -56,7 +58,7 @@
 /**
  * @deprecated Use the Launcher3 Iconloaderlib at packages/apps/Launcher3/iconloaderlib. This class
  * is a temporary fork of Iconloader. It combines all necessary methods to render app icons that are
- * possibly badged. It is intended to be used only by Sharesheet for the Q release.
+ * possibly badged. It is intended to be used only by Sharesheet for the Q release with custom code.
  */
 @Deprecated
 public class SimpleIconFactory {
@@ -202,6 +204,7 @@
     /**
      * Creates bitmap using the source drawable and flattened pre-rendered app icon.
      * The bitmap is visually normalized with other icons and has enough spacing to add shadow.
+     * This is custom functionality added to Iconloaderlib that will need to be ported.
      *
      * @param icon                      source of the icon associated with a user that has no badge
      * @param renderedAppIcon           pre-rendered app icon to use as a badge, likely the output
@@ -212,34 +215,70 @@
      */
     @Deprecated
     Bitmap createAppBadgedIconBitmap(@Nullable Drawable icon, Bitmap renderedAppIcon) {
-        // Flatten the passed in icon
-        float [] scale = new float[1];
-
         // If no icon is provided use the system default
         if (icon == null) {
             icon = getFullResDefaultActivityIcon(mFillResIconDpi);
         }
-        icon = normalizeAndWrapToAdaptiveIcon(icon, null, scale);
-        Bitmap bitmap = createIconBitmap(icon, scale[0]);
-        if (icon instanceof AdaptiveIconDrawable) {
-            mCanvas.setBitmap(bitmap);
-            recreateIcon(Bitmap.createBitmap(bitmap), mCanvas);
-            mCanvas.setBitmap(null);
+
+        // Direct share icons cannot be adaptive, most will arrive as bitmaps. To get reliable
+        // presentation, force all DS icons to be circular. Scale DS image so it completely fills.
+        int w = icon.getIntrinsicWidth();
+        int h = icon.getIntrinsicHeight();
+        float scale = 1;
+        if (h > w && w > 0) {
+            scale = (float) h / w;
+        } else if (w > h && h > 0) {
+            scale = (float) w / h;
+        }
+        Bitmap bitmap = createIconBitmap(icon, scale);
+        bitmap = maskBitmapToCircle(bitmap);
+        icon = new BitmapDrawable(mContext.getResources(), bitmap);
+
+        // We now have a circular masked and scaled icon, inset and apply shadow
+        scale = getScale(icon, null);
+        bitmap = createIconBitmap(icon, scale);
+
+        mCanvas.setBitmap(bitmap);
+        recreateIcon(Bitmap.createBitmap(bitmap), mCanvas);
+
+        if (renderedAppIcon != null) {
+            // Now scale down and apply the badge to the bottom right corner of the flattened icon
+            renderedAppIcon = Bitmap.createScaledBitmap(renderedAppIcon, mBadgeBitmapSize,
+                    mBadgeBitmapSize, false);
+
+            // Paint the provided badge on top of the flattened icon
+            mCanvas.drawBitmap(renderedAppIcon, mIconBitmapSize - mBadgeBitmapSize,
+                    mIconBitmapSize - mBadgeBitmapSize, null);
         }
 
-        // Now scale down and apply the badge to the bottom right corner of the flattened icon
-        renderedAppIcon = Bitmap.createScaledBitmap(renderedAppIcon, mBadgeBitmapSize,
-                mBadgeBitmapSize, false);
-
-        // Paint the provided badge on top of the flattened icon
-        mCanvas.setBitmap(bitmap);
-        mCanvas.drawBitmap(renderedAppIcon, mIconBitmapSize - mBadgeBitmapSize,
-                mIconBitmapSize - mBadgeBitmapSize, null);
         mCanvas.setBitmap(null);
 
         return bitmap;
     }
 
+    private Bitmap maskBitmapToCircle(Bitmap bitmap) {
+        final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
+                bitmap.getHeight(), Bitmap.Config.ARGB_8888);
+        final Canvas canvas = new Canvas(output);
+        final Paint paint = new Paint();
+        paint.setAntiAlias(true);
+
+        // Draw mask
+        paint.setColor(0xffffffff);
+        canvas.drawARGB(0, 0, 0, 0);
+        canvas.drawCircle(bitmap.getWidth() / 2f,
+                bitmap.getHeight() / 2f,
+                bitmap.getWidth() / 2f - 1 /* -1 to avoid circles with flat sides */,
+                paint);
+
+        // Draw masked bitmap
+        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
+        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
+        canvas.drawBitmap(bitmap, rect, rect, paint);
+
+        return output;
+    }
+
     private static Drawable getFullResDefaultActivityIcon(int iconDpi) {
         return Resources.getSystem().getDrawableForDensity(android.R.mipmap.sym_def_app_icon,
                 iconDpi);
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index 18c4b46..a7244a7 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -332,33 +332,11 @@
     }
 
     private void moveInMediaStore(@Nullable File oldVisibleFile, @Nullable File newVisibleFile) {
-        // visibleFolders are null if we're moving a document in external thumb drive or SD card.
-        //
-        // They should be all null or not null at the same time. File#renameTo() doesn't work across
-        // volumes so an exception will be thrown before calling this method.
-        if (oldVisibleFile != null && newVisibleFile != null) {
-            final long token = Binder.clearCallingIdentity();
-
-            try {
-                final ContentResolver resolver = getContext().getContentResolver();
-                final Uri externalUri = newVisibleFile.isDirectory()
-                        ? MediaStore.Files.getDirectoryUri("external")
-                        : MediaStore.Files.getContentUri("external");
-
-                ContentValues values = new ContentValues();
-                values.put(MediaStore.Files.FileColumns.DATA, newVisibleFile.getAbsolutePath());
-
-                // Logic borrowed from MtpDatabase.
-                // note - we are relying on a special case in MediaProvider.update() to update
-                // the paths for all children in the case where this is a directory.
-                final String path = oldVisibleFile.getAbsolutePath();
-                resolver.update(externalUri,
-                        values,
-                        "_data LIKE ? AND lower(_data)=lower(?)",
-                        new String[]{path, path});
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
+        if (oldVisibleFile != null) {
+            MediaStore.scanFile(getContext(), oldVisibleFile);
+        }
+        if (newVisibleFile != null) {
+            MediaStore.scanFile(getContext(), newVisibleFile);
         }
     }
 
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index afdeb1b..a295bd2 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -566,7 +566,18 @@
             System.exit(-1);
         } finally {
             IoUtils.closeQuietly(sessionSocket);
-            IoUtils.closeQuietly(usapPoolSocket);
+
+            try {
+                // This socket is closed using Os.close due to an issue with the implementation of
+                // LocalSocketImp.close.  Because the raw FD is created by init and then loaded from
+                // an environment variable (as opposed to being created by the LocalSocketImpl
+                // itself) the current implementation will not actually close the underlying FD.
+                //
+                // See b/130309968 for discussion of this issue.
+                Os.close(usapPoolSocket.getFileDescriptor());
+            } catch (ErrnoException ex) {
+                Log.e("USAP", "Failed to close USAP pool socket: " + ex.getMessage());
+            }
         }
 
         try {
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index d945e13..32fce8f 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -630,7 +630,7 @@
                 drawingBounds.bottom -= framePadding.bottom - frameOffsets.bottom;
             }
 
-            Drawable bg = getBackground();
+            Drawable bg = super.getBackground();
             if (bg != null) {
                 bg.setBounds(drawingBounds);
             }
@@ -1238,6 +1238,11 @@
         mLastOriginalBackgroundDrawable = mOriginalBackgroundDrawable;
     }
 
+    @Override
+    public Drawable getBackground() {
+        return mOriginalBackgroundDrawable;
+    }
+
     private int calculateStatusBarColor() {
         return calculateBarColor(mWindow.getAttributes().flags, FLAG_TRANSLUCENT_STATUS,
                 mSemiTransparentBarColor, mWindow.mStatusBarColor,
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index b6ee0fe..f266502 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -678,6 +678,7 @@
     char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:")-1 + PROPERTY_VALUE_MAX];
     char nativeBridgeLibrary[sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX];
     char cpuAbiListBuf[sizeof("--cpu-abilist=") + PROPERTY_VALUE_MAX];
+    char corePlatformApiPolicyBuf[sizeof("-Xcore-platform-api-policy:") + PROPERTY_VALUE_MAX];
     char methodTraceFileBuf[sizeof("-Xmethod-trace-file:") + PROPERTY_VALUE_MAX];
     char methodTraceFileSizeBuf[sizeof("-Xmethod-trace-file-size:") + PROPERTY_VALUE_MAX];
     std::string fingerprintBuf;
@@ -1024,6 +1025,16 @@
         addOption("--generate-mini-debug-info");
     }
 
+    // If set, the property below can be used to enable core platform API violation reporting.
+    property_get("persist.debug.dalvik.vm.core_platform_api_policy", propBuf, "");
+    if (propBuf[0] != '\0') {
+      snprintf(corePlatformApiPolicyBuf,
+               sizeof(corePlatformApiPolicyBuf),
+               "-Xcore-platform-api-policy:%s",
+               propBuf);
+      addOption(corePlatformApiPolicyBuf);
+    }
+
     /*
      * Retrieve the build fingerprint and provide it to the runtime. That way, ANR dumps will
      * contain the fingerprint and can be parsed.
diff --git a/core/jni/android_media_AudioProductStrategies.cpp b/core/jni/android_media_AudioProductStrategies.cpp
index 822b74a..17a02b2 100644
--- a/core/jni/android_media_AudioProductStrategies.cpp
+++ b/core/jni/android_media_AudioProductStrategies.cpp
@@ -39,7 +39,7 @@
 using namespace android;
 
 // ----------------------------------------------------------------------------
-static const char* const kClassPathName = "android/media/audiopolicy/AudioProductStrategies";
+static const char* const kClassPathName = "android/media/audiopolicy/AudioProductStrategy";
 static const char* const kAudioProductStrategyClassPathName =
         "android/media/audiopolicy/AudioProductStrategy";
 
@@ -194,34 +194,12 @@
     return jStatus;
 }
 
-static jint
-android_media_AudioSystem_getProductStrategyFromAudioAttributes(JNIEnv *env, jobject clazz,
-                                                                jobject jAudioAttributes)
-{
-    JNIAudioAttributeHelper::UniqueAaPtr attributes = JNIAudioAttributeHelper::makeUnique();
-    jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env,
-                                                           jAudioAttributes,
-                                                           attributes.get());
-    if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
-        return jStatus;
-    }
-    product_strategy_t psId;
-    status_t status = AudioSystem::getProductStrategyFromAudioAttributes(
-                AudioAttributes(*attributes.get()), psId);
-    if (status != NO_ERROR) {
-        return nativeToJavaStatus(status);
-    }
-    return psId;
-}
-
 /*
  * JNI registration.
  */
 static const JNINativeMethod gMethods[] = {
     {"native_list_audio_product_strategies", "(Ljava/util/ArrayList;)I",
                         (void *)android_media_AudioSystem_listAudioProductStrategies},
-    {"native_get_product_strategies_from_audio_attributes", "(Landroid/media/AudioAttributes;)I",
-                        (void *)android_media_AudioSystem_getProductStrategyFromAudioAttributes},
 };
 
 int register_android_media_AudioProductStrategies(JNIEnv *env)
diff --git a/core/jni/android_media_AudioVolumeGroups.cpp b/core/jni/android_media_AudioVolumeGroups.cpp
index 64f0c1e..7098451 100644
--- a/core/jni/android_media_AudioVolumeGroups.cpp
+++ b/core/jni/android_media_AudioVolumeGroups.cpp
@@ -39,7 +39,7 @@
 using namespace android;
 
 // ----------------------------------------------------------------------------
-static const char* const kClassPathName = "android/media/audiopolicy/AudioVolumeGroups";
+static const char* const kClassPathName = "android/media/audiopolicy/AudioVolumeGroup";
 static const char* const kAudioVolumeGroupClassPathName =
         "android/media/audiopolicy/AudioVolumeGroup";
 
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index dd754f3..28c59db 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -270,7 +270,7 @@
     return jniCreateFileDescriptor(env, fd);
 }
 
-static jbyteArray android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz, jobject javaFd) {
+static jobject android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz, jobject javaFd) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     int rcode;
     std::vector<uint8_t> buf(MAXPACKETSIZE, 0);
@@ -291,7 +291,10 @@
                 reinterpret_cast<jbyte*>(buf.data()));
     }
 
-    return answer;
+    jclass class_DnsResponse = env->FindClass("android/net/DnsResolver$DnsResponse");
+    jmethodID ctor = env->GetMethodID(class_DnsResponse, "<init>", "([BI)V");
+
+    return env->NewObject(class_DnsResponse, ctor, answer, rcode);
 }
 
 static void android_net_utils_resNetworkCancel(JNIEnv *env, jobject thiz, jobject javaFd) {
@@ -354,7 +357,7 @@
     { "setupRaSocket", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_setupRaSocket },
     { "resNetworkSend", "(I[BII)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkSend },
     { "resNetworkQuery", "(ILjava/lang/String;III)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkQuery },
-    { "resNetworkResult", "(Ljava/io/FileDescriptor;)[B", (void*) android_net_utils_resNetworkResult },
+    { "resNetworkResult", "(Ljava/io/FileDescriptor;)Landroid/net/DnsResolver$DnsResponse;", (void*) android_net_utils_resNetworkResult },
     { "resNetworkCancel", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_resNetworkCancel },
 };
 
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 3135c62..c0b31e4 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -271,8 +271,9 @@
             capturedSecureLayers);
 }
 
-static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
-        jobject sourceCropObj, jfloat frameScale, jobjectArray excludeArray) {
+static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTokenObj,
+        jobject layerHandleToken, jobject sourceCropObj, jfloat frameScale,
+        jobjectArray excludeArray) {
 
     sp<IBinder> layerHandle = ibinderForJavaObject(env, layerHandleToken);
     if (layerHandle == NULL) {
@@ -301,7 +302,12 @@
     }
 
     sp<GraphicBuffer> buffer;
-    const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
+    ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
+    sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
+    if (displayToken != nullptr) {
+        const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
+        dataspace = pickDataspaceFromColorMode(colorMode);
+    }
     status_t res = ScreenshotClient::captureChildLayers(layerHandle, dataspace,
                                                         ui::PixelFormat::RGBA_8888, sourceCrop,
                                                         excludeHandles, frameScale, &buffer);
@@ -1373,7 +1379,8 @@
             "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
             (void*)nativeScreenshot },
     {"nativeCaptureLayers",
-            "(Landroid/os/IBinder;Landroid/graphics/Rect;F[Landroid/os/IBinder;)"
+            "(Landroid/os/IBinder;Landroid/os/IBinder;Landroid/graphics/Rect;"
+            "F[Landroid/os/IBinder;)"
             "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
             (void*)nativeCaptureLayers },
     {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
diff --git a/core/proto/android/stats/devicepolicy/device_policy_enums.proto b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
index 589a6a7..0db7424 100644
--- a/core/proto/android/stats/devicepolicy/device_policy_enums.proto
+++ b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
@@ -145,4 +145,8 @@
   ESTABLISH_VPN = 118;
   SET_NETWORK_LOGGING_ENABLED = 119;
   RETRIEVE_NETWORK_LOGS = 120;
+  PROVISIONING_PREPARE_TOTAL_TIME_MS = 121;
+  PROVISIONING_PREPARE_STARTED = 122;
+  PROVISIONING_PREPARE_COMPLETED = 123;
+  PROVISIONING_FLOW_TYPE = 124;
 }
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
index 1f80417..68c62a6 100644
--- a/core/res/res/layout/chooser_grid.xml
+++ b/core/res/res/layout/chooser_grid.xml
@@ -32,11 +32,11 @@
 
         <ImageView
             android:id="@+id/drag"
-            android:layout_width="32dp"
+            android:layout_width="24dp"
             android:layout_height="4dp"
             android:src="@drawable/ic_drag_handle"
             android:clickable="true"
-            android:layout_marginTop="@dimen/chooser_view_spacing"
+            android:layout_marginTop="@dimen/chooser_edge_margin_thin"
             android:tint="@color/lighter_gray"
             android:layout_centerHorizontal="true"
             android:layout_alignParentTop="true" />
@@ -61,8 +61,9 @@
                   android:layout_width="wrap_content"
                   android:textAppearance="?attr/textAppearanceMedium"
                   android:textSize="20sp"
+                  android:textColor="?attr/textColorPrimary"
                   android:gravity="center"
-                  android:paddingTop="@dimen/chooser_view_spacing"
+                  android:paddingTop="@dimen/chooser_edge_margin_thin"
                   android:paddingBottom="@dimen/chooser_view_spacing"
                   android:paddingLeft="24dp"
                   android:paddingRight="24dp"
diff --git a/core/res/res/layout/chooser_grid_preview_text.xml b/core/res/res/layout/chooser_grid_preview_text.xml
index 6abf57a..3c9ffdb 100644
--- a/core/res/res/layout/chooser_grid_preview_text.xml
+++ b/core/res/res/layout/chooser_grid_preview_text.xml
@@ -43,16 +43,18 @@
         android:layout_gravity="center_vertical"
         android:ellipsize="end"
         android:gravity="start|top"
-        android:paddingRight="24dp"
+        android:paddingRight="@dimen/chooser_view_spacing"
         android:maxLines="2"/>
-    <Button
+    <ImageButton
         android:id="@+id/copy_button"
-        android:layout_width="24dp"
-        android:layout_height="24dp"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:padding="12dp"
         android:gravity="center"
         android:layout_gravity="center_vertical"
-        android:foreground="@drawable/ic_content_copy_gm2"
+        android:src="@drawable/ic_content_copy_gm2"
         android:clickable="true"
+        android:contentDescription="@string/copy"
         android:background="?attr/selectableItemBackgroundBorderless"/>
   </LinearLayout>
 
@@ -63,8 +65,8 @@
       android:layout_height="wrap_content"
       android:layout_gravity="center"
       android:orientation="horizontal"
-      android:layout_marginLeft="@dimen/chooser_edge_margin_thin"
-      android:layout_marginRight="@dimen/chooser_edge_margin_thin"
+      android:layout_marginLeft="@dimen/chooser_edge_margin_normal"
+      android:layout_marginRight="@dimen/chooser_edge_margin_normal"
       android:minHeight="80dp"
       android:background="@drawable/chooser_content_preview_rounded"
       android:id="@+id/content_preview_title_layout">
@@ -87,7 +89,7 @@
         android:layout_gravity="center_vertical"
         android:ellipsize="end"
         android:maxLines="2"
-        android:textAppearance="?attr/textAppearanceMedium"/>
+        android:textSize="20sp"/>
   </LinearLayout>
 </LinearLayout>
 
diff --git a/core/res/res/layout/chooser_row.xml b/core/res/res/layout/chooser_row.xml
index 742d7eed..f5814c3 100644
--- a/core/res/res/layout/chooser_row.xml
+++ b/core/res/res/layout/chooser_row.xml
@@ -20,9 +20,7 @@
               android:orientation="horizontal"
               android:layout_width="match_parent"
               android:layout_height="100dp"
-              android:gravity="start|top"
-              android:paddingStart="@dimen/chooser_edge_margin_normal"
-              android:paddingEnd="@dimen/chooser_edge_margin_normal">
+              android:gravity="start|top">
   <TextView
       android:id="@+id/chooser_row_text_option"
       android:layout_width="match_parent"
diff --git a/core/res/res/layout/resolve_grid_item.xml b/core/res/res/layout/resolve_grid_item.xml
index 7065149..256d94e 100644
--- a/core/res/res/layout/resolve_grid_item.xml
+++ b/core/res/res/layout/resolve_grid_item.xml
@@ -24,8 +24,8 @@
               android:gravity="center"
               android:paddingTop="24dp"
               android:paddingBottom="8dp"
-              android:paddingLeft="2dp"
-              android:paddingRight="2dp"
+              android:paddingLeft="12dp"
+              android:paddingRight="12dp"
               android:focusable="true"
               android:background="?attr/selectableItemBackgroundBorderless">
 
@@ -45,7 +45,6 @@
               android:textAppearance="?attr/textAppearanceSmall"
               android:textColor="?attr/textColorPrimary"
               android:textSize="14sp"
-              android:fontFamily="sans-serif-condensed"
               android:gravity="top|center_horizontal"
               android:lines="1"
               android:ellipsize="end" />
@@ -54,6 +53,7 @@
     <TextView android:id="@android:id/text2"
               android:textAppearance="?android:attr/textAppearanceSmall"
               android:textSize="12sp"
+              android:textColor="?attr/textColorSecondary"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:lines="1"
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 47c243c..bfa57e4 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1684,18 +1684,27 @@
              This flag is turned on by default. <em>This attribute is usable only by system apps.
              </em> -->
         <attr name="allowClearUserDataOnFailedRestore"/>
-        <!-- If {@code true} the app's non sensitive audio can be capture by other apps with
-             {@code AudioPlaybackCaptureConfiguration} and a {@code MediaProjection}.
+        <!-- If {@code true} the app's non sensitive audio can be captured by other apps with
+             {@link android.media.AudioPlaybackCaptureConfiguration} and a
+             {@link android.media.projection.MediaProjection}.
+
+             If {@code false} the audio played by the application will never be captured by non
+             system apps. It is equivalent to limiting
+             {@link android.media.AudioManager#setAllowedCapturePolicy(int)} to
+             {@link android.media.AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM}.
 
              <p>
              Non sensitive audio is defined as audio whose {@code AttributeUsage} is
              {@code USAGE_UNKNOWN}), {@code USAGE_MEDIA}) or {@code USAGE_GAME}).
-             All other usages (eg. {@code USAGE_VOICE_COMMUNICATION}) will not be captured.
+             All other usages like {@code USAGE_VOICE_COMMUNICATION} will not be captured.
 
              <p>
              The default value is:
                  - {@code true} for apps with targetSdkVersion >= 29 (Q).
                  - {@code false} for apps with targetSdkVersion < 29.
+
+             <p>
+             See {@link android.media.AudioPlaybackCaptureConfiguration} for more detail.
              -->
         <attr name="allowAudioPlaybackCapture" format="boolean" />
         <!-- If {@code true} this app allows shared/external storage media to be
@@ -2814,6 +2823,9 @@
             case-sensitive, unlike formal RFC MIME types.  As a result,
             MIME types here should always use lower case letters.</em></p> -->
         <attr name="mimeType" />
+        <!-- The identifier to assign to the intent, as per
+            {@link android.content.Intent#setIdentifier Intent.setIdentifier()}. -->
+        <attr name="identifier" format="string" />
         <!-- The package part of the ComponentName to assign to the Intent, as per
             {@link android.content.Intent#setComponent Intent.setComponent()}. -->
         <attr name="targetPackage" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f27f34a..edcc057 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -745,6 +745,10 @@
 
     <!-- XXXXXX END OF RESOURCES USING WRONG NAMING CONVENTION -->
 
+    <!-- If this is true, notification effects will be played by the notification server.
+         When false, car notification effects will be handled elsewhere. -->
+    <bool name="config_enableServerNotificationEffectsForAutomotive">false</bool>
+
     <!-- If this is true, the screen will come on when you unplug usb/power/whatever. -->
     <bool name="config_unplugTurnsOnScreen">false</bool>
 
@@ -1971,10 +1975,6 @@
     <bool name="config_showDefaultEmergency">false</bool>
     <!-- Whether the default home settings should be shown. -->
     <bool name="config_showDefaultHome">true</bool>
-    <!-- The name of the package that will hold the music role by default. -->
-    <string name="config_defaultMusic" translatable="false">com.android.music</string>
-    <!-- The name of the package that will hold the gallery role by default. -->
-    <string name="config_defaultGallery" translatable="false">com.android.gallery3d</string>
 
     <!-- Enable/disable default bluetooth profiles:
         HSP_AG, ObexObjectPush, Audio, NAP -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 02cbc2e..b81db15 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -728,6 +728,6 @@
     <dimen name="chooser_preview_width">-1px</dimen>
     <dimen name="resolver_icon_size">42dp</dimen>
     <dimen name="resolver_badge_size">18dp</dimen>
-    <dimen name="chooser_target_width">76dp</dimen>
+    <dimen name="chooser_target_width">90dp</dimen>
     <dimen name="chooser_max_collapsed_height">288dp</dimen>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 626518c..9a8c754 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2945,6 +2945,7 @@
         <public name="allowExternalStorageSandbox"/>
         <public name="ensuringStatusBarContrastWhenTransparent" />
         <public name="ensuringNavigationBarContrastWhenTransparent" />
+        <public name="identifier" />
     </public-group>
 
     <public-group type="drawable" first-id="0x010800b4">
@@ -2987,10 +2988,6 @@
       <public name="config_defaultDialer" />
       <!-- @hide @SystemApi -->
       <public name="config_defaultSms" />
-      <!-- @hide @SystemApi -->
-      <public name="config_defaultMusic" />
-      <!-- @hide @SystemApi -->
-      <public name="config_defaultGallery" />
     </public-group>
 
     <public-group type="bool" first-id="0x01110000">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f8a2ac9..4bd2cc75 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1521,10 +1521,10 @@
     <string name="face_acquired_too_high">Move phone higher.</string>
     <!-- Message shown during face acquisition when the user is too low relatively to sensor [CHAR LIMIT=50] -->
     <string name="face_acquired_too_low">Move phone lower.</string>
-    <!-- Message shown during face acquisition when the user is too right relatively to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_right">Move phone to the right.</string>
-    <!-- Message shown during face acquisition when the user is too left relatively to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_left">Move phone to the left.</string>
+    <!-- Message shown during face acquisition when only the right part of the user's face was detected [CHAR LIMIT=50] -->
+    <string name="face_acquired_too_right">Move phone to the left.</string>
+    <!-- Message shown during face acquisition when only the left part of the user's face was detected [CHAR LIMIT=50] -->
+    <string name="face_acquired_too_left">Move phone to the right.</string>
     <!-- Message shown during face acquisition when the user is not front facing the sensor [CHAR LIMIT=50] -->
     <string name="face_acquired_poor_gaze">Look at the screen with your eyes open.</string>
     <!-- Message shown during face acquisition when the user is not detected [CHAR LIMIT=50] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e9ce6ac..da2f890 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1910,6 +1910,7 @@
   <java-symbol type="array" name="config_testLocationProviders" />
   <java-symbol type="array" name="config_defaultNotificationVibePattern" />
   <java-symbol type="array" name="config_notificationFallbackVibePattern" />
+  <java-symbol type="bool" name="config_enableServerNotificationEffectsForAutomotive" />
   <java-symbol type="bool" name="config_useAttentionLight" />
   <java-symbol type="bool" name="config_adaptive_sleep_available" />
   <java-symbol type="bool" name="config_animateScreenLights" />
@@ -3751,4 +3752,9 @@
   <!-- For DropBox -->
   <java-symbol type="integer" name="config_dropboxLowPriorityBroadcastRateLimitPeriod" />
   <java-symbol type="array" name="config_dropboxLowPriorityTags" />
+
+  <!-- For Privacy Type -->
+  <java-symbol type="drawable" name="perm_group_camera" />
+  <java-symbol type="drawable" name="perm_group_location" />
+  <java-symbol type="drawable" name="perm_group_microphone" />
 </resources>
diff --git a/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java b/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
index 99b6421..267cb36 100644
--- a/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
+++ b/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
@@ -163,6 +163,20 @@
         assertTrue(overlayManagerContainsPackage(APP_OVERLAY_PACKAGE_NAME));
     }
 
+    @Test
+    public void changesPersistedWhenUninstallingDisabledOverlay() throws Exception {
+        getDevice().enableAdbRoot();
+        assertFalse(getDevice().executeShellCommand("cat /data/system/overlays.xml")
+                .contains(APP_OVERLAY_PACKAGE_NAME));
+        installPackage("OverlayHostTests_AppOverlayV1.apk");
+        assertTrue(getDevice().executeShellCommand("cat /data/system/overlays.xml")
+                .contains(APP_OVERLAY_PACKAGE_NAME));
+        uninstallPackage(APP_OVERLAY_PACKAGE_NAME);
+        delay();
+        assertFalse(getDevice().executeShellCommand("cat /data/system/overlays.xml")
+                .contains(APP_OVERLAY_PACKAGE_NAME));
+    }
+
     private void delay() {
         try {
             Thread.sleep(1000);
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 9b1f259..9998854 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -17,8 +17,8 @@
 #include "Properties.h"
 #include "Debug.h"
 #include "DeviceInfo.h"
-#include "SkTraceEventCommon.h"
 #include "HWUIProperties.sysprop.h"
+#include "SkTraceEventCommon.h"
 
 #include <algorithm>
 #include <cstdlib>
@@ -67,7 +67,7 @@
 bool Properties::isolatedProcess = false;
 
 int Properties::contextPriority = 0;
-int Properties::defaultRenderAhead = 0;
+uint32_t Properties::defaultRenderAhead = 0;
 
 static int property_get_int(const char* key, int defaultValue) {
     char buf[PROPERTY_VALUE_MAX] = {
@@ -130,12 +130,9 @@
 
     enableForceDarkSupport = property_get_bool(PROPERTY_ENABLE_FORCE_DARK, true);
 
-    defaultRenderAhead = std::max(0, std::min(2, property_get_int(PROPERTY_RENDERAHEAD,
-            render_ahead().value_or(0))));
-
-    if (defaultRenderAhead && sRenderPipelineType == RenderPipelineType::SkiaVulkan) {
-        ALOGW("hwui.render_ahead of %d ignored because pipeline is skiavk", defaultRenderAhead);
-    }
+    defaultRenderAhead =
+            std::max(0u, std::min(2u, static_cast<uint32_t>(property_get_int(
+                                              PROPERTY_RENDERAHEAD, render_ahead().value_or(0)))));
 
     return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw);
 }
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 3e91c63..3105e58 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -253,7 +253,7 @@
 
     ANDROID_API static int contextPriority;
 
-    static int defaultRenderAhead;
+    static uint32_t defaultRenderAhead;
 
 private:
     static ProfileType sProfileType;
diff --git a/libs/hwui/pipeline/skia/ShaderCache.cpp b/libs/hwui/pipeline/skia/ShaderCache.cpp
index 8508274..66aa8c2 100644
--- a/libs/hwui/pipeline/skia/ShaderCache.cpp
+++ b/libs/hwui/pipeline/skia/ShaderCache.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "ShaderCache.h"
+#include <GrContext.h>
 #include <log/log.h>
 #include <openssl/sha.h>
 #include <algorithm>
@@ -23,7 +24,6 @@
 #include "FileBlobCache.h"
 #include "Properties.h"
 #include "utils/TraceUtils.h"
-#include <GrContext.h>
 
 namespace android {
 namespace uirenderer {
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index 570e895..9248ead 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -101,7 +101,7 @@
 
     SkiaPipeline::updateLighting(lightGeometry, lightInfo);
     renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface,
-            SkMatrix::I());
+                SkMatrix::I());
     layerUpdateQueue->clear();
 
     // Draw visual debugging features
@@ -156,8 +156,23 @@
     }
 }
 
+static void setBufferCount(ANativeWindow* window, uint32_t extraBuffers) {
+    int query_value;
+    int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
+    if (err != 0 || query_value < 0) {
+        ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, query_value);
+        return;
+    }
+    auto min_undequeued_buffers = static_cast<uint32_t>(query_value);
+
+    int bufferCount = min_undequeued_buffers + 2 + extraBuffers;
+    ALOGD("Setting buffer count to %d, min_undequeued %u, extraBuffers %u",
+            bufferCount, min_undequeued_buffers, extraBuffers);
+    native_window_set_buffer_count(window, bufferCount);
+}
+
 bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior,
-                                    ColorMode colorMode) {
+                                    ColorMode colorMode, uint32_t extraBuffers) {
     if (mEglSurface != EGL_NO_SURFACE) {
         mEglManager.destroySurface(mEglSurface);
         mEglSurface = EGL_NO_SURFACE;
@@ -177,6 +192,7 @@
     if (mEglSurface != EGL_NO_SURFACE) {
         const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer);
         mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer);
+        setBufferCount(surface, extraBuffers);
         return true;
     }
 
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
index 6692922..3fe0f92 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
@@ -44,7 +44,7 @@
                      FrameInfo* currentFrameInfo, bool* requireSwap) override;
     DeferredLayerUpdater* createTextureLayer() override;
     bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior,
-                    renderthread::ColorMode colorMode) override;
+                    renderthread::ColorMode colorMode, uint32_t extraBuffers) override;
     void onStop() override;
     bool isSurfaceReady() override;
     bool isContextReady() override;
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 721a115..ccc1701 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -250,8 +250,9 @@
         }
         if (mCaptureSequence > 0 || mPictureCapturedCallback) {
             mRecorder.reset(new SkPictureRecorder());
-            SkCanvas* pictureCanvas = mRecorder->beginRecording(surface->width(), surface->height(), nullptr,
-                                                                SkPictureRecorder::kPlaybackDrawPicture_RecordFlag);
+            SkCanvas* pictureCanvas =
+                    mRecorder->beginRecording(surface->width(), surface->height(), nullptr,
+                                              SkPictureRecorder::kPlaybackDrawPicture_RecordFlag);
             mNwayCanvas = std::make_unique<SkNWayCanvas>(surface->width(), surface->height());
             mNwayCanvas->addCanvas(surface->getCanvas());
             mNwayCanvas->addCanvas(pictureCanvas);
@@ -276,8 +277,7 @@
                 if (1 == mCaptureSequence) {
                     savePictureAsync(data, mCapturedFile);
                 } else {
-                    savePictureAsync(data,
-                            mCapturedFile + "_" + std::to_string(mCaptureSequence));
+                    savePictureAsync(data, mCapturedFile + "_" + std::to_string(mCaptureSequence));
                 }
                 mCaptureSequence--;
             }
@@ -327,7 +327,7 @@
     auto& props = node.properties();
     return Rect(props.getLeft(), props.getTop(), props.getRight(), props.getBottom());
 }
-}
+}  // namespace
 
 void SkiaPipeline::renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip,
                                    const std::vector<sp<RenderNode>>& nodes, bool opaque,
@@ -464,10 +464,20 @@
 // (3) Requires RGBA colors (instead of BGRA).
 static const uint32_t kOverdrawColors[2][6] = {
         {
-                0x00000000, 0x00000000, 0x2f2f0000, 0x2f002f00, 0x3f00003f, 0x7f00007f,
+                0x00000000,
+                0x00000000,
+                0x2f2f0000,
+                0x2f002f00,
+                0x3f00003f,
+                0x7f00007f,
         },
         {
-                0x00000000, 0x00000000, 0x2f2f0000, 0x4f004f4f, 0x5f50335f, 0x7f00007f,
+                0x00000000,
+                0x00000000,
+                0x2f2f0000,
+                0x4f004f4f,
+                0x5f50335f,
+                0x7f00007f,
         },
 };
 
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index d945635..5a47a29 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -142,8 +142,7 @@
 void SkiaRecordingCanvas::drawWebViewFunctor(int functor) {
     FunctorDrawable* functorDrawable;
     if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
-        functorDrawable =
-                mDisplayList->allocateDrawable<VkFunctorDrawable>(functor, asSkCanvas());
+        functorDrawable = mDisplayList->allocateDrawable<VkFunctorDrawable>(functor, asSkCanvas());
     } else {
         functorDrawable = mDisplayList->allocateDrawable<GLFunctorDrawable>(functor, asSkCanvas());
     }
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index edde6d3..e8cb219 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -18,12 +18,12 @@
 
 #include "DeferredLayerUpdater.h"
 #include "Readback.h"
+#include "ShaderCache.h"
 #include "SkiaPipeline.h"
 #include "SkiaProfileRenderer.h"
 #include "VkInteropFunctorDrawable.h"
 #include "renderstate/RenderState.h"
 #include "renderthread/Frame.h"
-#include "ShaderCache.h"
 
 #include <SkSurface.h>
 #include <SkTypes.h>
@@ -70,8 +70,8 @@
         return false;
     }
     SkiaPipeline::updateLighting(lightGeometry, lightInfo);
-    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
-            backBuffer, mVkSurface->getCurrentPreTransform());
+    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer,
+                mVkSurface->getCurrentPreTransform());
     ShaderCache::get().onVkFrameFlushed(mRenderThread.getGrContext());
     layerUpdateQueue->clear();
 
@@ -116,7 +116,7 @@
 void SkiaVulkanPipeline::onStop() {}
 
 bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior,
-                                    ColorMode colorMode) {
+                                    ColorMode colorMode, uint32_t extraBuffers) {
     if (mVkSurface) {
         mVkManager.destroySurface(mVkSurface);
         mVkSurface = nullptr;
@@ -125,8 +125,9 @@
     setSurfaceColorProperties(colorMode);
     if (surface) {
         mRenderThread.requireVkContext();
-        mVkSurface = mVkManager.createSurface(surface, colorMode, mSurfaceColorSpace,
-                                              mSurfaceColorType, mRenderThread.getGrContext());
+        mVkSurface =
+                mVkManager.createSurface(surface, colorMode, mSurfaceColorSpace, mSurfaceColorType,
+                                         mRenderThread.getGrContext(), extraBuffers);
     }
 
     return mVkSurface != nullptr;
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index 77a7ab1..3173478 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -43,7 +43,7 @@
                      FrameInfo* currentFrameInfo, bool* requireSwap) override;
     DeferredLayerUpdater* createTextureLayer() override;
     bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior,
-                    renderthread::ColorMode colorMode) override;
+                    renderthread::ColorMode colorMode, uint32_t extraBuffers) override;
     void onStop() override;
     bool isSurfaceReady() override;
     bool isContextReady() override;
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
index 1b9e53b..1127926 100644
--- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
@@ -17,16 +17,16 @@
 #include "VkFunctorDrawable.h"
 #include <private/hwui/DrawVkInfo.h>
 
-#include "renderthread/VulkanManager.h"
-#include "renderthread/RenderThread.h"
-#include <SkAndroidFrameworkUtils.h>
 #include <GrBackendDrawableInfo.h>
+#include <SkAndroidFrameworkUtils.h>
 #include <SkImage.h>
 #include <utils/Color.h>
 #include <utils/Trace.h>
 #include <utils/TraceUtils.h>
 #include <vk/GrVkTypes.h>
 #include <thread>
+#include "renderthread/RenderThread.h"
+#include "renderthread/VulkanManager.h"
 #include "thread/ThreadBase.h"
 #include "utils/TimeUtils.h"
 
@@ -64,13 +64,13 @@
 
     SkMatrix44 mat4(mMatrix);
     VkFunctorDrawParams params{
-      .width = mImageInfo.width(),
-      .height = mImageInfo.height(),
-      .color_space_ptr = mImageInfo.colorSpace(),
-      .clip_left = mClip.fLeft,
-      .clip_top = mClip.fTop,
-      .clip_right = mClip.fRight,
-      .clip_bottom = mClip.fBottom,
+            .width = mImageInfo.width(),
+            .height = mImageInfo.height(),
+            .color_space_ptr = mImageInfo.colorSpace(),
+            .clip_left = mClip.fLeft,
+            .clip_top = mClip.fTop,
+            .clip_right = mClip.fRight,
+            .clip_bottom = mClip.fBottom,
     };
     mat4.asColMajorf(&params.transform[0]);
     params.secondary_command_buffer = vulkan_info.fSecondaryCommandBuffer;
@@ -87,8 +87,7 @@
     vulkan_info.fDrawBounds->extent.height = mClip.fBottom - mClip.fTop;
 }
 
-VkFunctorDrawable::~VkFunctorDrawable() {
-}
+VkFunctorDrawable::~VkFunctorDrawable() {}
 
 void VkFunctorDrawable::onDraw(SkCanvas* canvas) {
     // "canvas" is either SkNWayCanvas created by SkiaPipeline::tryCapture (SKP capture use case) or
@@ -106,9 +105,8 @@
         SkCanvas* gpuCanvas = SkAndroidFrameworkUtils::getBaseWrappedCanvas(canvas);
         // Enforce "canvas" must be an AlphaFilterCanvas. For GPU canvas, the call should come from
         // onSnapGpuDrawHandler.
-        LOG_ALWAYS_FATAL_IF(
-                gpuCanvas == canvas,
-                "VkFunctorDrawable::onDraw() should not be called with a GPU canvas!");
+        LOG_ALWAYS_FATAL_IF(gpuCanvas == canvas,
+                            "VkFunctorDrawable::onDraw() should not be called with a GPU canvas!");
 
         // This will invoke onSnapGpuDrawHandler and regular draw flow.
         gpuCanvas->drawDrawable(this);
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index 8b02c11..a31081c 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -21,17 +21,16 @@
 #include "RenderThread.h"
 #include "pipeline/skia/ShaderCache.h"
 #include "pipeline/skia/SkiaMemoryTracer.h"
-#include "Properties.h"
 #include "renderstate/RenderState.h"
 #include "thread/CommonPool.h"
 
 #include <GrContextOptions.h>
 #include <SkExecutor.h>
 #include <SkGraphics.h>
+#include <SkMathPriv.h>
 #include <gui/Surface.h>
 #include <math.h>
 #include <set>
-#include <SkMathPriv.h>
 
 namespace android {
 namespace uirenderer {
@@ -79,14 +78,13 @@
 
 class CommonPoolExecutor : public SkExecutor {
 public:
-    virtual void add(std::function<void(void)> func) override {
-        CommonPool::post(std::move(func));
-    }
+    virtual void add(std::function<void(void)> func) override { CommonPool::post(std::move(func)); }
 };
 
 static CommonPoolExecutor sDefaultExecutor;
 
-void CacheManager::configureContext(GrContextOptions* contextOptions, const void* identity, ssize_t size) {
+void CacheManager::configureContext(GrContextOptions* contextOptions, const void* identity,
+                                    ssize_t size) {
     contextOptions->fAllowPathMaskCaching = true;
 
     // This sets the maximum size for a single texture atlas in the GPU font cache.  If necessary,
@@ -180,7 +178,8 @@
         }
 
         const char* layerType = Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL
-                ? "GlLayer" : "VkLayer";
+                                        ? "GlLayer"
+                                        : "VkLayer";
         size_t layerMemoryTotal = 0;
         for (std::set<Layer*>::iterator it = renderState->mActiveLayers.begin();
              it != renderState->mActiveLayers.end(); it++) {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 4808d68..1b3bd30 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -17,6 +17,7 @@
 #include "CanvasContext.h"
 #include <GpuMemoryTracker.h>
 
+#include "../Properties.h"
 #include "AnimationContext.h"
 #include "EglManager.h"
 #include "Frame.h"
@@ -31,7 +32,6 @@
 #include "utils/GLUtils.h"
 #include "utils/TimeUtils.h"
 #include "utils/TraceUtils.h"
-#include "../Properties.h"
 
 #include <cutils/properties.h>
 #include <private/hwui/DrawGlInfo.h>
@@ -153,7 +153,8 @@
     }
 
     ColorMode colorMode = mWideColorGamut ? ColorMode::WideColorGamut : ColorMode::SRGB;
-    bool hasSurface = mRenderPipeline->setSurface(mNativeSurface.get(), mSwapBehavior, colorMode);
+    bool hasSurface = mRenderPipeline->setSurface(mNativeSurface.get(), mSwapBehavior, colorMode,
+                                                  mRenderAheadDepth);
 
     mFrameNumber = -1;
 
@@ -298,7 +299,7 @@
 
     mAnimationContext->startFrame(info.mode);
     mRenderPipeline->onPrepareTree();
-    for (const sp<RenderNode> &node : mRenderNodes) {
+    for (const sp<RenderNode>& node : mRenderNodes) {
         // Only the primary target node will be drawn full - all other nodes would get drawn in
         // real time mode. In case of a window, the primary node is the window content and the other
         // node(s) are non client / filler nodes.
@@ -322,7 +323,7 @@
 
     if (CC_LIKELY(mSwapHistory.size() && !Properties::forceDrawFrame)) {
         nsecs_t latestVsync = mRenderThread.timeLord().latestVsync();
-        SwapHistory &lastSwap = mSwapHistory.back();
+        SwapHistory& lastSwap = mSwapHistory.back();
         nsecs_t vsyncDelta = std::abs(lastSwap.vsyncTime - latestVsync);
         // The slight fudge-factor is to deal with cases where
         // the vsync was estimated due to being slow handling the signal.
@@ -405,8 +406,7 @@
     SkRect dirty;
     mDamageAccumulator.finish(&dirty);
 
-    if (dirty.isEmpty() && Properties::skipEmptyFrames
-            && !surfaceRequiresRedraw()) {
+    if (dirty.isEmpty() && Properties::skipEmptyFrames && !surfaceRequiresRedraw()) {
         mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
         return;
     }
@@ -416,21 +416,21 @@
     Frame frame = mRenderPipeline->getFrame();
 
     SkRect windowDirty = computeDirtyRect(frame, &dirty);
+    if (mRenderAheadDepth) {
+        auto presentTime =
+                mCurrentFrameInfo->get(FrameInfoIndex::Vsync) +
+                (mRenderThread.timeLord().frameIntervalNanos() * (mRenderAheadDepth + 1));
+        native_window_set_buffers_timestamp(mNativeSurface.get(), presentTime);
+    }
 
     bool drew = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry, &mLayerUpdateQueue,
-                                      mContentDrawBounds, mOpaque, mLightInfo,
-                                      mRenderNodes, &(profiler()));
+                                      mContentDrawBounds, mOpaque, mLightInfo, mRenderNodes,
+                                      &(profiler()));
 
     int64_t frameCompleteNr = mFrameCompleteCallbacks.size() ? getFrameNumber() : -1;
 
     waitOnFences();
 
-    if (mRenderAheadDepth) {
-        auto presentTime = mCurrentFrameInfo->get(FrameInfoIndex::Vsync) +
-                (mRenderThread.timeLord().frameIntervalNanos() * (mRenderAheadDepth + 1));
-        native_window_set_buffers_timestamp(mNativeSurface.get(), presentTime);
-    }
-
     bool requireSwap = false;
     bool didSwap =
             mRenderPipeline->swapBuffers(frame, drew, windowDirty, mCurrentFrameInfo, &requireSwap);
@@ -645,21 +645,13 @@
 }
 
 void CanvasContext::applyRenderAheadSettings() {
-    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
-        // TODO: Fix SkiaVulkan's assumptions on buffer counts. And SIGBUS crashes.
-        mRenderAheadDepth = 0;
-        return;
-    }
-    if (mNativeSurface) {
-        native_window_set_buffer_count(mNativeSurface.get(), 3 + mRenderAheadDepth);
-        if (!mRenderAheadDepth) {
-            native_window_set_buffers_timestamp(mNativeSurface.get(), NATIVE_WINDOW_TIMESTAMP_AUTO);
-        }
+    if (mNativeSurface && !mRenderAheadDepth) {
+        native_window_set_buffers_timestamp(mNativeSurface.get(), NATIVE_WINDOW_TIMESTAMP_AUTO);
     }
 }
 
-void CanvasContext::setRenderAheadDepth(int renderAhead) {
-    if (renderAhead < 0 || renderAhead > 2 || renderAhead == mRenderAheadDepth) {
+void CanvasContext::setRenderAheadDepth(uint32_t renderAhead) {
+    if (renderAhead > 2 || renderAhead == mRenderAheadDepth || mNativeSurface) {
         return;
     }
     mRenderAheadDepth = renderAhead;
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 4a3119a..0bd080d 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -17,15 +17,15 @@
 #pragma once
 
 #include "DamageAccumulator.h"
-#include "Lighting.h"
 #include "FrameInfo.h"
 #include "FrameInfoVisualizer.h"
 #include "FrameMetricsReporter.h"
 #include "IContextFactory.h"
 #include "IRenderPipeline.h"
 #include "LayerUpdateQueue.h"
-#include "RenderNode.h"
+#include "Lighting.h"
 #include "ReliableSurface.h"
+#include "RenderNode.h"
 #include "renderthread/RenderTask.h"
 #include "renderthread/RenderThread.h"
 
@@ -37,10 +37,10 @@
 #include <utils/Functor.h>
 
 #include <functional>
+#include <future>
 #include <set>
 #include <string>
 #include <vector>
-#include <future>
 
 namespace android {
 namespace uirenderer {
@@ -187,9 +187,7 @@
         mRenderPipeline->setPictureCapturedCallback(callback);
     }
 
-    void setForceDark(bool enable) {
-        mUseForceDark = enable;
-    }
+    void setForceDark(bool enable) { mUseForceDark = enable; }
 
     bool useForceDark() {
         // The force-dark override has the highest priority, followed by the disable setting
@@ -204,7 +202,8 @@
         return mUseForceDark;
     }
 
-    void setRenderAheadDepth(int renderAhead);
+    // Must be called before setSurface
+    void setRenderAheadDepth(uint32_t renderAhead);
 
 private:
     CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
@@ -238,7 +237,7 @@
     // painted onto its surface.
     bool mIsDirty = false;
     SwapBehavior mSwapBehavior = SwapBehavior::kSwap_default;
-    int mRenderAheadDepth = 0;
+    uint32_t mRenderAheadDepth = 0;
     struct SwapHistory {
         SkRect damage;
         nsecs_t vsyncTime;
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 51eeab7..91dc3bc 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -109,9 +109,8 @@
 
     // Even if we aren't drawing this vsync pulse the next frame number will still be accurate
     if (CC_UNLIKELY(callback)) {
-        context->enqueueFrameWork([callback, frameNr = context->getFrameNumber()]() {
-            callback(frameNr);
-        });
+        context->enqueueFrameWork(
+                [callback, frameNr = context->getFrameNumber()]() { callback(frameNr); });
     }
 
     if (CC_LIKELY(canDrawThisFrame)) {
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 2cc3f36..1d55334 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -29,10 +29,10 @@
 #include <EGL/eglext.h>
 #include <GLES/gl.h>
 
+#include <gui/Surface.h>
+#include <system/window.h>
 #include <string>
 #include <vector>
-#include <system/window.h>
-#include <gui/Surface.h>
 
 #define GLES_VERSION 2
 
@@ -171,8 +171,7 @@
                         EGL_NONE};
     EGLConfig config = EGL_NO_CONFIG_KHR;
     EGLint numConfigs = 1;
-    if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) ||
-        numConfigs != 1) {
+    if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) || numConfigs != 1) {
         return EGL_NO_CONFIG_KHR;
     }
     return config;
@@ -203,8 +202,7 @@
                         EGL_NONE};
     EGLConfig config = EGL_NO_CONFIG_KHR;
     EGLint numConfigs = 1;
-    if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) ||
-        numConfigs != 1) {
+    if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) || numConfigs != 1) {
         return EGL_NO_CONFIG_KHR;
     }
     return config;
@@ -262,7 +260,7 @@
         mEglConfigWideGamut = loadFP16Config(mEglDisplay, mSwapBehavior);
         if (mEglConfigWideGamut == EGL_NO_CONFIG_KHR) {
             ALOGE("Device claims wide gamut support, cannot find matching config, error = %s",
-                    eglErrorString());
+                  eglErrorString());
             EglExtensions.pixelFormatFloat = false;
         }
     } else if (wideColorType == SkColorType::kN32_SkColorType) {
@@ -350,7 +348,7 @@
     EGLSurface surface = eglCreateWindowSurface(
             mEglDisplay, wideColorGamut ? mEglConfigWideGamut : mEglConfig, window, attribs);
     if (surface == EGL_NO_SURFACE) {
-        return Error<EGLint> { eglGetError() };
+        return Error<EGLint>{eglGetError()};
     }
 
     if (mSwapBehavior != SwapBehavior::Preserved) {
@@ -525,12 +523,8 @@
             ALOGE("EglManager::fenceWait: error dup'ing fence fd: %d", errno);
             return -errno;
         }
-        EGLint attribs[] = {
-            EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd,
-            EGL_NONE
-        };
-        EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay,
-                EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
+        EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, EGL_NONE};
+        EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
         if (sync == EGL_NO_SYNC_KHR) {
             close(fenceFd);
             ALOGE("EglManager::fenceWait: error creating EGL fence: %#x", eglGetError());
@@ -559,18 +553,16 @@
 }
 
 status_t EglManager::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence,
-        sp<Fence>& nativeFence) {
+                                        sp<Fence>& nativeFence) {
     if (!hasEglContext()) {
         ALOGE("EglManager::createReleaseFence: EGLDisplay not initialized");
         return INVALID_OPERATION;
     }
 
     if (SyncFeatures::getInstance().useNativeFenceSync()) {
-        EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay,
-                EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
+        EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
         if (sync == EGL_NO_SYNC_KHR) {
-            ALOGE("EglManager::createReleaseFence: error creating EGL fence: %#x",
-                    eglGetError());
+            ALOGE("EglManager::createReleaseFence: error creating EGL fence: %#x", eglGetError());
             return UNKNOWN_ERROR;
         }
         glFlush();
@@ -578,7 +570,8 @@
         eglDestroySyncKHR(mEglDisplay, sync);
         if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
             ALOGE("EglManager::createReleaseFence: error dup'ing native fence "
-                    "fd: %#x", eglGetError());
+                  "fd: %#x",
+                  eglGetError());
             return UNKNOWN_ERROR;
         }
         nativeFence = new Fence(fenceFd);
@@ -592,7 +585,7 @@
             EGLint result = eglClientWaitSyncKHR(mEglDisplay, *eglFence, 0, 1000000000);
             if (result == EGL_FALSE) {
                 ALOGE("EglManager::createReleaseFence: error waiting for previous fence: %#x",
-                        eglGetError());
+                      eglGetError());
                 return UNKNOWN_ERROR;
             } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
                 ALOGE("EglManager::createReleaseFence: timeout waiting for previous fence");
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index 0502eb8..3b81014 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -66,8 +66,8 @@
     virtual bool swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty,
                              FrameInfo* currentFrameInfo, bool* requireSwap) = 0;
     virtual DeferredLayerUpdater* createTextureLayer() = 0;
-    virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior,
-                            ColorMode colorMode) = 0;
+    virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior, ColorMode colorMode,
+                            uint32_t extraBuffers) = 0;
     virtual void onStop() = 0;
     virtual bool isSurfaceReady() = 0;
     virtual bool isContextReady() = 0;
diff --git a/libs/hwui/renderthread/ReliableSurface.cpp b/libs/hwui/renderthread/ReliableSurface.cpp
index 6f2b9df..b9410c2 100644
--- a/libs/hwui/renderthread/ReliableSurface.cpp
+++ b/libs/hwui/renderthread/ReliableSurface.cpp
@@ -34,13 +34,13 @@
     // Make warnings happy
     SurfaceExposer() = delete;
 
-    using Surface::setBufferCount;
-    using Surface::setSwapInterval;
-    using Surface::dequeueBuffer;
-    using Surface::queueBuffer;
     using Surface::cancelBuffer;
+    using Surface::dequeueBuffer;
     using Surface::lockBuffer_DEPRECATED;
     using Surface::perform;
+    using Surface::queueBuffer;
+    using Surface::setBufferCount;
+    using Surface::setSwapInterval;
 };
 
 #define callProtected(surface, func, ...) ((*surface).*&SurfaceExposer::func)(__VA_ARGS__)
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index b58bab1..1a1b9da 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -84,7 +84,7 @@
 
 void RenderProxy::setSurface(const sp<Surface>& surface) {
     mRenderThread.queue().post(
-            [ this, surf = surface ]() mutable { mContext->setSurface(std::move(surf)); });
+            [this, surf = surface]() mutable { mContext->setSurface(std::move(surf)); });
 }
 
 void RenderProxy::allocateBuffers() {
@@ -251,7 +251,7 @@
 
 void RenderProxy::setProcessStatsBuffer(int fd) {
     auto& rt = RenderThread::getInstance();
-    rt.queue().post([&rt, fd = dup(fd) ]() {
+    rt.queue().post([&rt, fd = dup(fd)]() {
         rt.globalProfileData().switchStorageToAshmem(fd);
         close(fd);
     });
@@ -285,7 +285,7 @@
 void RenderProxy::setPictureCapturedCallback(
         const std::function<void(sk_sp<SkPicture>&&)>& callback) {
     mRenderThread.queue().post(
-            [ this, cb = callback ]() { mContext->setPictureCapturedCallback(cb); });
+            [this, cb = callback]() { mContext->setPictureCapturedCallback(cb); });
 }
 
 void RenderProxy::setFrameCallback(std::function<void(int64_t)>&& callback) {
@@ -297,13 +297,13 @@
 }
 
 void RenderProxy::addFrameMetricsObserver(FrameMetricsObserver* observerPtr) {
-    mRenderThread.queue().post([ this, observer = sp{observerPtr} ]() {
+    mRenderThread.queue().post([this, observer = sp{observerPtr}]() {
         mContext->addFrameMetricsObserver(observer.get());
     });
 }
 
 void RenderProxy::removeFrameMetricsObserver(FrameMetricsObserver* observerPtr) {
-    mRenderThread.queue().post([ this, observer = sp{observerPtr} ]() {
+    mRenderThread.queue().post([this, observer = sp{observerPtr}]() {
         mContext->removeFrameMetricsObserver(observer.get());
     });
 }
@@ -313,9 +313,8 @@
 }
 
 void RenderProxy::setRenderAheadDepth(int renderAhead) {
-    mRenderThread.queue().post([ context = mContext, renderAhead ] {
-        context->setRenderAheadDepth(renderAhead);
-    });
+    mRenderThread.queue().post(
+            [context = mContext, renderAhead] { context->setRenderAheadDepth(renderAhead); });
 }
 
 int RenderProxy::copySurfaceInto(sp<Surface>& surface, int left, int top, int right, int bottom,
@@ -393,9 +392,7 @@
 void RenderProxy::preload() {
     // Create RenderThread object and start the thread. Then preload Vulkan/EGL driver.
     auto& thread = RenderThread::getInstance();
-    thread.queue().post([&thread]() {
-        thread.preload();
-    });
+    thread.queue().post([&thread]() { thread.preload(); });
 }
 
 } /* namespace renderthread */
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index b76e49c..eca7d88 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -16,6 +16,7 @@
 
 #include "RenderThread.h"
 
+#include "../HardwareBitmapUploader.h"
 #include "CanvasContext.h"
 #include "DeviceInfo.h"
 #include "EglManager.h"
@@ -29,7 +30,6 @@
 #include "utils/FatVector.h"
 #include "utils/TimeUtils.h"
 #include "utils/TraceUtils.h"
-#include "../HardwareBitmapUploader.h"
 
 #ifdef HWUI_GLES_WRAP_ENABLED
 #include "debug/GlesDriver.h"
@@ -410,9 +410,7 @@
 void RenderThread::preload() {
     // EGL driver is always preloaded only if HWUI renders with GL.
     if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
-        std::thread eglInitThread([]() {
-            eglGetDisplay(EGL_DEFAULT_DISPLAY);
-        });
+        std::thread eglInitThread([]() { eglGetDisplay(EGL_DEFAULT_DISPLAY); });
         eglInitThread.detach();
     } else {
         requireVkContext();
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 5f43b48..6bb26fd 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -22,8 +22,8 @@
 #include "../JankTracker.h"
 #include "CacheManager.h"
 #include "TimeLord.h"
-#include "thread/ThreadBase.h"
 #include "WebViewFunctorManager.h"
+#include "thread/ThreadBase.h"
 #include "utils/TimeUtils.h"
 
 #include <GrContext.h>
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 4011329..5edf330 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -29,7 +29,6 @@
 #include <GrBackendSurface.h>
 #include <GrContext.h>
 #include <GrTypes.h>
-#include <GrTypes.h>
 #include <vk/GrVkExtensions.h>
 #include <vk/GrVkTypes.h>
 
@@ -43,7 +42,7 @@
     // so we can get access to the pNext for the next struct.
     struct CommonVulkanHeader {
         VkStructureType sType;
-        void*           pNext;
+        void* pNext;
     };
 
     void* pNext = features.pNext;
@@ -94,13 +93,13 @@
     VkResult err;
 
     constexpr VkApplicationInfo app_info = {
-        VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType
-        nullptr,                            // pNext
-        "android framework",                // pApplicationName
-        0,                                  // applicationVersion
-        "android framework",                // pEngineName
-        0,                                  // engineVerison
-        mAPIVersion,                        // apiVersion
+            VK_STRUCTURE_TYPE_APPLICATION_INFO,  // sType
+            nullptr,                             // pNext
+            "android framework",                 // pApplicationName
+            0,                                   // applicationVersion
+            "android framework",                 // pEngineName
+            0,                                   // engineVerison
+            mAPIVersion,                         // apiVersion
     };
 
     {
@@ -128,14 +127,14 @@
     }
 
     const VkInstanceCreateInfo instance_create = {
-        VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,    // sType
-        nullptr,                                   // pNext
-        0,                                         // flags
-        &app_info,                                 // pApplicationInfo
-        0,                                         // enabledLayerNameCount
-        nullptr,                                   // ppEnabledLayerNames
-        (uint32_t) mInstanceExtensions.size(),     // enabledExtensionNameCount
-        mInstanceExtensions.data(),                // ppEnabledExtensionNames
+            VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,  // sType
+            nullptr,                                 // pNext
+            0,                                       // flags
+            &app_info,                               // pApplicationInfo
+            0,                                       // enabledLayerNameCount
+            nullptr,                                 // ppEnabledLayerNames
+            (uint32_t)mInstanceExtensions.size(),    // enabledExtensionNameCount
+            mInstanceExtensions.data(),              // ppEnabledExtensionNames
     };
 
     GET_PROC(CreateInstance);
@@ -200,11 +199,11 @@
     {
         uint32_t extensionCount = 0;
         err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount,
-                nullptr);
+                                                  nullptr);
         LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err);
         mDeviceExtensionsOwner.resize(extensionCount);
         err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount,
-                mDeviceExtensionsOwner.data());
+                                                  mDeviceExtensionsOwner.data());
         LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err);
         bool hasKHRSwapchainExtension = false;
         for (const VkExtensionProperties& extension : mDeviceExtensionsOwner) {
@@ -216,7 +215,7 @@
         LOG_ALWAYS_FATAL_IF(!hasKHRSwapchainExtension);
     }
 
-    auto getProc = [] (const char* proc_name, VkInstance instance, VkDevice device) {
+    auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) {
         if (device != VK_NULL_HANDLE) {
             return vkGetDeviceProcAddr(device, proc_name);
         }
@@ -224,7 +223,8 @@
     };
 
     grExtensions.init(getProc, mInstance, mPhysicalDevice, mInstanceExtensions.size(),
-            mInstanceExtensions.data(), mDeviceExtensions.size(), mDeviceExtensions.data());
+                      mInstanceExtensions.data(), mDeviceExtensions.size(),
+                      mDeviceExtensions.data());
 
     LOG_ALWAYS_FATAL_IF(!grExtensions.hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1));
 
@@ -237,7 +237,7 @@
 
     if (grExtensions.hasExtension(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, 2)) {
         VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT* blend;
-        blend = (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT*) malloc(
+        blend = (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT*)malloc(
                 sizeof(VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT));
         LOG_ALWAYS_FATAL_IF(!blend);
         blend->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT;
@@ -247,7 +247,7 @@
     }
 
     VkPhysicalDeviceSamplerYcbcrConversionFeatures* ycbcrFeature;
-    ycbcrFeature = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*) malloc(
+    ycbcrFeature = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*)malloc(
             sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures));
     LOG_ALWAYS_FATAL_IF(!ycbcrFeature);
     ycbcrFeature->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
@@ -261,17 +261,17 @@
     // and we can't depend on it on all platforms
     features.features.robustBufferAccess = VK_FALSE;
 
-    float queuePriorities[1] = { 0.0 };
+    float queuePriorities[1] = {0.0};
 
     void* queueNextPtr = nullptr;
 
     VkDeviceQueueGlobalPriorityCreateInfoEXT queuePriorityCreateInfo;
 
-    if (Properties::contextPriority != 0
-            && grExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) {
+    if (Properties::contextPriority != 0 &&
+        grExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) {
         memset(&queuePriorityCreateInfo, 0, sizeof(VkDeviceQueueGlobalPriorityCreateInfoEXT));
         queuePriorityCreateInfo.sType =
-            VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT;
+                VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT;
         queuePriorityCreateInfo.pNext = nullptr;
         switch (Properties::contextPriority) {
             case EGL_CONTEXT_PRIORITY_LOW_IMG:
@@ -285,41 +285,40 @@
                 break;
             default:
                 LOG_ALWAYS_FATAL("Unsupported context priority");
-         }
-         queueNextPtr = &queuePriorityCreateInfo;
+        }
+        queueNextPtr = &queuePriorityCreateInfo;
     }
 
     const VkDeviceQueueCreateInfo queueInfo[2] = {
-        {
-            VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
-            queueNextPtr,                               // pNext
-            0,                                          // VkDeviceQueueCreateFlags
-            mGraphicsQueueIndex,                        // queueFamilyIndex
-            1,                                          // queueCount
-            queuePriorities,                            // pQueuePriorities
-        },
-        {
-            VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
-            queueNextPtr,                               // pNext
-            0,                                          // VkDeviceQueueCreateFlags
-            mPresentQueueIndex,                         // queueFamilyIndex
-            1,                                          // queueCount
-            queuePriorities,                            // pQueuePriorities
-        }
-    };
+            {
+                    VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,  // sType
+                    queueNextPtr,                                // pNext
+                    0,                                           // VkDeviceQueueCreateFlags
+                    mGraphicsQueueIndex,                         // queueFamilyIndex
+                    1,                                           // queueCount
+                    queuePriorities,                             // pQueuePriorities
+            },
+            {
+                    VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,  // sType
+                    queueNextPtr,                                // pNext
+                    0,                                           // VkDeviceQueueCreateFlags
+                    mPresentQueueIndex,                          // queueFamilyIndex
+                    1,                                           // queueCount
+                    queuePriorities,                             // pQueuePriorities
+            }};
     uint32_t queueInfoCount = (mPresentQueueIndex != mGraphicsQueueIndex) ? 2 : 1;
 
     const VkDeviceCreateInfo deviceInfo = {
-        VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,    // sType
-        &features,                               // pNext
-        0,                                       // VkDeviceCreateFlags
-        queueInfoCount,                          // queueCreateInfoCount
-        queueInfo,                               // pQueueCreateInfos
-        0,                                       // layerCount
-        nullptr,                                 // ppEnabledLayerNames
-        (uint32_t) mDeviceExtensions.size(),     // extensionCount
-        mDeviceExtensions.data(),                // ppEnabledExtensionNames
-        nullptr,                                 // ppEnabledFeatures
+            VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,  // sType
+            &features,                             // pNext
+            0,                                     // VkDeviceCreateFlags
+            queueInfoCount,                        // queueCreateInfoCount
+            queueInfo,                             // pQueueCreateInfos
+            0,                                     // layerCount
+            nullptr,                               // ppEnabledLayerNames
+            (uint32_t)mDeviceExtensions.size(),    // extensionCount
+            mDeviceExtensions.data(),              // ppEnabledExtensionNames
+            nullptr,                               // ppEnabledFeatures
     };
 
     LOG_ALWAYS_FATAL_IF(mCreateDevice(mPhysicalDevice, &deviceInfo, nullptr, &mDevice));
@@ -371,8 +370,8 @@
         // this needs to be on the render queue
         commandPoolInfo.queueFamilyIndex = mGraphicsQueueIndex;
         commandPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-        SkDEBUGCODE(VkResult res =) mCreateCommandPool(mDevice, &commandPoolInfo, nullptr,
-                &mCommandPool);
+        SkDEBUGCODE(VkResult res =)
+                mCreateCommandPool(mDevice, &commandPoolInfo, nullptr, &mCommandPool);
         SkASSERT(VK_SUCCESS == res);
     }
     LOG_ALWAYS_FATAL_IF(mCommandPool == VK_NULL_HANDLE);
@@ -391,7 +390,7 @@
 }
 
 sk_sp<GrContext> VulkanManager::createContext(const GrContextOptions& options) {
-    auto getProc = [] (const char* proc_name, VkInstance instance, VkDevice device) {
+    auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) {
         if (device != VK_NULL_HANDLE) {
             return vkGetDeviceProcAddr(device, proc_name);
         }
@@ -431,7 +430,6 @@
 }
 
 Frame VulkanManager::dequeueNextBuffer(VulkanSurface* surface) {
-
     VulkanSurface::NativeBufferInfo* bufferInfo = surface->dequeueNativeBuffer();
 
     if (bufferInfo == nullptr) {
@@ -480,7 +478,7 @@
                 bufferInfo->skSurface->wait(1, &backendSemaphore);
                 // The following flush blocks the GPU immediately instead of waiting for other
                 // drawing ops. It seems dequeue_fence is not respected otherwise.
-                //TODO: remove the flush after finding why backendSemaphore is not working.
+                // TODO: remove the flush after finding why backendSemaphore is not working.
                 bufferInfo->skSurface->flush();
             }
         }
@@ -557,15 +555,15 @@
 
 VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode colorMode,
                                             sk_sp<SkColorSpace> surfaceColorSpace,
-                                            SkColorType surfaceColorType,
-                                            GrContext* grContext) {
+                                            SkColorType surfaceColorType, GrContext* grContext,
+                                            uint32_t extraBuffers) {
     LOG_ALWAYS_FATAL_IF(!hasVkContext(), "Not initialized");
     if (!window) {
         return nullptr;
     }
 
     return VulkanSurface::Create(window, colorMode, surfaceColorType, surfaceColorSpace, grContext,
-                                  *this);
+                                 *this, extraBuffers);
 }
 
 bool VulkanManager::setupDummyCommandBuffer() {
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index a7a43cc..1a3a0e4 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -18,16 +18,16 @@
 #define VULKANMANAGER_H
 
 #if !defined(VK_USE_PLATFORM_ANDROID_KHR)
-#  define VK_USE_PLATFORM_ANDROID_KHR
+#define VK_USE_PLATFORM_ANDROID_KHR
 #endif
 #include <vulkan/vulkan.h>
 
 #include <GrContextOptions.h>
-#include <vk/GrVkExtensions.h>
 #include <SkSurface.h>
 #include <ui/Fence.h>
 #include <utils/StrongPointer.h>
 #include <vk/GrVkBackendContext.h>
+#include <vk/GrVkExtensions.h>
 #include "Frame.h"
 #include "IRenderPipeline.h"
 #include "VulkanSurface.h"
@@ -59,8 +59,8 @@
     // Create and destroy functions for wrapping an ANativeWindow in a VulkanSurface
     VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode,
                                  sk_sp<SkColorSpace> surfaceColorSpace,
-                                 SkColorType surfaceColorType,
-                                 GrContext* grContext);
+                                 SkColorType surfaceColorType, GrContext* grContext,
+                                 uint32_t extraBuffers);
     void destroySurface(VulkanSurface* surface);
 
     Frame dequeueNextBuffer(VulkanSurface* surface);
diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp
index be78b69..32815fe 100644
--- a/libs/hwui/renderthread/VulkanSurface.cpp
+++ b/libs/hwui/renderthread/VulkanSurface.cpp
@@ -16,12 +16,12 @@
 
 #include "VulkanSurface.h"
 
-#include <algorithm>
 #include <SkSurface.h>
+#include <algorithm>
 
 #include "VulkanManager.h"
-#include "utils/TraceUtils.h"
 #include "utils/Color.h"
+#include "utils/TraceUtils.h"
 
 namespace android {
 namespace uirenderer {
@@ -31,10 +31,9 @@
     // For now, only support pure rotations, not flip or flip-and-rotate, until we have
     // more time to test them and build sample code. As far as I know we never actually
     // use anything besides pure rotations anyway.
-    return transform == 0
-        || transform == NATIVE_WINDOW_TRANSFORM_ROT_90
-        || transform == NATIVE_WINDOW_TRANSFORM_ROT_180
-        || transform == NATIVE_WINDOW_TRANSFORM_ROT_270;
+    return transform == 0 || transform == NATIVE_WINDOW_TRANSFORM_ROT_90 ||
+           transform == NATIVE_WINDOW_TRANSFORM_ROT_180 ||
+           transform == NATIVE_WINDOW_TRANSFORM_ROT_270;
 }
 
 static int InvertTransform(int transform) {
@@ -85,16 +84,16 @@
 }
 
 void VulkanSurface::ComputeWindowSizeAndTransform(WindowInfo* windowInfo, const SkISize& minSize,
-                                                   const SkISize& maxSize) {
+                                                  const SkISize& maxSize) {
     SkISize& windowSize = windowInfo->size;
 
     // clamp width & height to handle currentExtent of -1 and  protect us from broken hints
-    if (windowSize.width() < minSize.width() || windowSize.width() > maxSize.width()
-        || windowSize.height() < minSize.height() || windowSize.height() > maxSize.height()) {
+    if (windowSize.width() < minSize.width() || windowSize.width() > maxSize.width() ||
+        windowSize.height() < minSize.height() || windowSize.height() > maxSize.height()) {
         int width = std::min(maxSize.width(), std::max(minSize.width(), windowSize.width()));
         int height = std::min(maxSize.height(), std::max(minSize.height(), windowSize.height()));
-        ALOGE("Invalid Window Dimensions [%d, %d]; clamping to [%d, %d]",
-              windowSize.width(), windowSize.height(), width, height);
+        ALOGE("Invalid Window Dimensions [%d, %d]; clamping to [%d, %d]", windowSize.width(),
+              windowSize.height(), width, height);
         windowSize.set(width, height);
     }
 
@@ -145,12 +144,8 @@
 public:
     VkSurfaceAutoDeleter(VkInstance instance, VkSurfaceKHR surface,
                          PFN_vkDestroySurfaceKHR destroySurfaceKHR)
-            : mInstance(instance)
-            , mSurface(surface)
-            , mDestroySurfaceKHR(destroySurfaceKHR) {}
-    ~VkSurfaceAutoDeleter() {
-        destroy();
-    }
+            : mInstance(instance), mSurface(surface), mDestroySurfaceKHR(destroySurfaceKHR) {}
+    ~VkSurfaceAutoDeleter() { destroy(); }
 
     void destroy() {
         if (mSurface != VK_NULL_HANDLE) {
@@ -166,9 +161,9 @@
 };
 
 VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode,
-                                       SkColorType colorType, sk_sp<SkColorSpace> colorSpace,
-                                       GrContext* grContext, const VulkanManager& vkManager) {
-
+                                     SkColorType colorType, sk_sp<SkColorSpace> colorSpace,
+                                     GrContext* grContext, const VulkanManager& vkManager,
+                                     uint32_t extraBuffers) {
     VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo;
     memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR));
     surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
@@ -188,10 +183,11 @@
                                           vkManager.mDestroySurfaceKHR);
 
     SkDEBUGCODE(VkBool32 supported; res = vkManager.mGetPhysicalDeviceSurfaceSupportKHR(
-            vkManager.mPhysicalDevice, vkManager.mPresentQueueIndex, vkSurface, &supported);
-    // All physical devices and queue families on Android must be capable of
-    // presentation with any native window.
-    SkASSERT(VK_SUCCESS == res && supported););
+                                            vkManager.mPhysicalDevice, vkManager.mPresentQueueIndex,
+                                            vkSurface, &supported);
+                // All physical devices and queue families on Android must be capable of
+                // presentation with any native window.
+                SkASSERT(VK_SUCCESS == res && supported););
 
     // check for capabilities
     VkSurfaceCapabilitiesKHR caps;
@@ -225,14 +221,13 @@
     int query_value;
     int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
     if (err != 0 || query_value < 0) {
-        ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err,
-              query_value);
+        ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, query_value);
         return nullptr;
     }
     auto min_undequeued_buffers = static_cast<uint32_t>(query_value);
 
-    windowInfo.bufferCount = min_undequeued_buffers
-            + std::max(VulkanSurface::sTargetBufferCount, caps.minImageCount);
+    windowInfo.bufferCount = min_undequeued_buffers +
+                             std::max(sTargetBufferCount + extraBuffers, caps.minImageCount);
     if (caps.maxImageCount > 0 && windowInfo.bufferCount > caps.maxImageCount) {
         // Application must settle for fewer images than desired:
         windowInfo.bufferCount = caps.maxImageCount;
@@ -241,8 +236,7 @@
     // Currently Skia requires the images to be color attachments and support all transfer
     // operations.
     VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
-                                   VK_IMAGE_USAGE_SAMPLED_BIT |
-                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+                                   VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
                                    VK_IMAGE_USAGE_TRANSFER_DST_BIT;
     LOG_ALWAYS_FATAL_IF((caps.supportedUsageFlags & usageFlags) != usageFlags);
 
@@ -336,7 +330,8 @@
     err = native_window_set_buffers_data_space(window, windowInfo.dataspace);
     if (err != 0) {
         ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_data_space(%d) "
-              "failed: %s (%d)", windowInfo.dataspace, strerror(-err), err);
+              "failed: %s (%d)",
+              windowInfo.dataspace, strerror(-err), err);
         return false;
     }
 
@@ -344,7 +339,8 @@
     err = native_window_set_buffers_dimensions(window, size.width(), size.height());
     if (err != 0) {
         ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_dimensions(%d,%d) "
-              "failed: %s (%d)", size.width(), size.height(), strerror(-err), err);
+              "failed: %s (%d)",
+              size.width(), size.height(), strerror(-err), err);
         return false;
     }
 
@@ -357,7 +353,8 @@
     err = native_window_set_buffers_transform(window, InvertTransform(windowInfo.transform));
     if (err != 0) {
         ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_transform(%d) "
-              "failed: %s (%d)", windowInfo.transform, strerror(-err), err);
+              "failed: %s (%d)",
+              windowInfo.transform, strerror(-err), err);
         return false;
     }
 
@@ -366,7 +363,8 @@
     err = native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_FREEZE);
     if (err != 0) {
         ALOGE("VulkanSurface::UpdateWindow() native_window_set_scaling_mode(SCALE_TO_WINDOW) "
-              "failed: %s (%d)", strerror(-err), err);
+              "failed: %s (%d)",
+              strerror(-err), err);
         return false;
     }
 
@@ -388,12 +386,12 @@
 }
 
 VulkanSurface::VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo,
-                               SkISize minWindowSize, SkISize maxWindowSize, GrContext* grContext)
+                             SkISize minWindowSize, SkISize maxWindowSize, GrContext* grContext)
         : mNativeWindow(window)
         , mWindowInfo(windowInfo)
         , mGrContext(grContext)
         , mMinWindowSize(minWindowSize)
-        , mMaxWindowSize(maxWindowSize) { }
+        , mMaxWindowSize(maxWindowSize) {}
 
 VulkanSurface::~VulkanSurface() {
     releaseBuffers();
@@ -436,8 +434,7 @@
     // value at the end of the function if everything dequeued correctly.
     mCurrentBufferInfo = nullptr;
 
-
-    //check if the native window has been resized or rotated and update accordingly
+    // check if the native window has been resized or rotated and update accordingly
     SkISize newSize = SkISize::MakeEmpty();
     int transformHint = 0;
     mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_WIDTH, &newSize.fWidth);
@@ -457,8 +454,8 @@
                                                        newWindowInfo.actualSize.height());
             if (err != 0) {
                 ALOGE("native_window_set_buffers_dimensions(%d,%d) failed: %s (%d)",
-                      newWindowInfo.actualSize.width(),
-                      newWindowInfo.actualSize.height(), strerror(-err), err);
+                      newWindowInfo.actualSize.width(), newWindowInfo.actualSize.height(),
+                      strerror(-err), err);
                 return nullptr;
             }
             // reset the NativeBufferInfo (including SkSurface) associated with the old buffers. The
@@ -469,7 +466,7 @@
 
         if (newWindowInfo.transform != mWindowInfo.transform) {
             err = native_window_set_buffers_transform(mNativeWindow.get(),
-                    InvertTransform(newWindowInfo.transform));
+                                                      InvertTransform(newWindowInfo.transform));
             if (err != 0) {
                 ALOGE("native_window_set_buffers_transform(%d) failed: %s (%d)",
                       newWindowInfo.transform, strerror(-err), err);
@@ -512,11 +509,9 @@
     VulkanSurface::NativeBufferInfo* bufferInfo = &mNativeBuffers[idx];
 
     if (bufferInfo->skSurface.get() == nullptr) {
-        bufferInfo->skSurface =
-                SkSurface::MakeFromAHardwareBuffer(mGrContext,
-                        ANativeWindowBuffer_getHardwareBuffer(bufferInfo->buffer.get()),
-                        kTopLeft_GrSurfaceOrigin, DataSpaceToColorSpace(mWindowInfo.dataspace),
-                        nullptr);
+        bufferInfo->skSurface = SkSurface::MakeFromAHardwareBuffer(
+                mGrContext, ANativeWindowBuffer_getHardwareBuffer(bufferInfo->buffer.get()),
+                kTopLeft_GrSurfaceOrigin, DataSpaceToColorSpace(mWindowInfo.dataspace), nullptr);
         if (bufferInfo->skSurface.get() == nullptr) {
             ALOGE("SkSurface::MakeFromAHardwareBuffer failed");
             mNativeWindow->cancelBuffer(mNativeWindow.get(), buffer, fence_fd);
diff --git a/libs/hwui/renderthread/VulkanSurface.h b/libs/hwui/renderthread/VulkanSurface.h
index 305483f..b7af596 100644
--- a/libs/hwui/renderthread/VulkanSurface.h
+++ b/libs/hwui/renderthread/VulkanSurface.h
@@ -19,8 +19,8 @@
 #include <system/window.h>
 #include <vulkan/vulkan.h>
 
-#include <SkSize.h>
 #include <SkRefCnt.h>
+#include <SkSize.h>
 
 #include "IRenderPipeline.h"
 
@@ -34,12 +34,9 @@
 
 class VulkanSurface {
 public:
-    static VulkanSurface* Create(ANativeWindow* window,
-                                  ColorMode colorMode,
-                                  SkColorType colorType,
-                                  sk_sp<SkColorSpace> colorSpace,
-                                  GrContext* grContext,
-                                  const VulkanManager& vkManager);
+    static VulkanSurface* Create(ANativeWindow* window, ColorMode colorMode, SkColorType colorType,
+                                 sk_sp<SkColorSpace> colorSpace, GrContext* grContext,
+                                 const VulkanManager& vkManager, uint32_t extraBuffers);
     ~VulkanSurface();
 
     sk_sp<SkSurface> getCurrentSkSurface() {
@@ -104,15 +101,10 @@
         SkMatrix preTransform;
     };
 
-    VulkanSurface(ANativeWindow* window,
-                  const WindowInfo& windowInfo,
-                  SkISize minWindowSize,
-                  SkISize maxWindowSize,
-                  GrContext* grContext);
-    static bool UpdateWindow(ANativeWindow* window,
-                             const WindowInfo& windowInfo);
-    static void ComputeWindowSizeAndTransform(WindowInfo* windowInfo,
-                                              const SkISize& minSize,
+    VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo, SkISize minWindowSize,
+                  SkISize maxWindowSize, GrContext* grContext);
+    static bool UpdateWindow(ANativeWindow* window, const WindowInfo& windowInfo);
+    static void ComputeWindowSizeAndTransform(WindowInfo* windowInfo, const SkISize& minSize,
                                               const SkISize& maxSize);
     void releaseBuffers();
 
diff --git a/libs/hwui/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
index e86cf42..a671bda 100644
--- a/libs/hwui/tests/unit/SkiaPipelineTests.cpp
+++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
@@ -31,6 +31,9 @@
 #include "renderthread/CanvasContext.h"
 #include "tests/common/TestUtils.h"
 
+#include <gui/BufferItemConsumer.h>
+#include <gui/Surface.h>
+
 using namespace android;
 using namespace android::uirenderer;
 using namespace android::uirenderer::renderthread;
@@ -421,10 +424,20 @@
     EXPECT_EQ(1, surface->canvas()->mDrawCounter);
 }
 
+static sp<Surface> createDummySurface() {
+    sp<IGraphicBufferProducer> producer;
+    sp<IGraphicBufferConsumer> consumer;
+    BufferQueue::createBufferQueue(&producer, &consumer);
+    producer->setMaxDequeuedBufferCount(1);
+    producer->setAsyncMode(true);
+    return new Surface(producer);
+}
+
 RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, context_lost) {
+    auto surface = createDummySurface();
     auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
     EXPECT_FALSE(pipeline->isSurfaceReady());
-    EXPECT_TRUE(pipeline->setSurface((Surface*)0x01, SwapBehavior::kSwap_default, ColorMode::SRGB));
+    EXPECT_TRUE(pipeline->setSurface(surface.get(), SwapBehavior::kSwap_default, ColorMode::SRGB, 0));
     EXPECT_TRUE(pipeline->isSurfaceReady());
     renderThread.destroyRenderingContext();
     EXPECT_FALSE(pipeline->isSurfaceReady());
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index ce464b7..211a0cb 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -17,6 +17,7 @@
 package android.location;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -44,6 +45,8 @@
     public static final int CONSTELLATION_GALILEO = 6;
     /** Constellation type constant for IRNSS. */
     public static final int CONSTELLATION_IRNSS = 7;
+    /** @hide */
+    public static final int CONSTELLATION_COUNT = 8;
 
     /** @hide */
     public static final int GNSS_SV_FLAGS_NONE = 0;
@@ -251,4 +254,36 @@
     public float getCarrierFrequencyHz(int satIndex) {
         return mCarrierFrequencies[satIndex];
     }
+
+    /**
+     * Returns the string representation of a constellation type. For example,
+     * {@link #CONSTELLATION_GPS} is represented by the string GPS.
+     *
+     * @param constellationType the constellation type.
+     * @return the string representation.
+     * @hide
+     */
+    @NonNull
+    public static String constellationTypeToString(@ConstellationType int constellationType) {
+        switch (constellationType) {
+            case CONSTELLATION_UNKNOWN:
+                return "UNKNOWN";
+            case CONSTELLATION_GPS:
+                return "GPS";
+            case CONSTELLATION_SBAS:
+                return "SBAS";
+            case CONSTELLATION_GLONASS:
+                return "GLONASS";
+            case CONSTELLATION_QZSS:
+                return "QZSS";
+            case CONSTELLATION_BEIDOU:
+                return "BEIDOU";
+            case CONSTELLATION_GALILEO:
+                return "GALILEO";
+            case CONSTELLATION_IRNSS:
+                return "IRNSS";
+            default:
+                return Integer.toString(constellationType);
+        }
+    }
 }
diff --git a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
index 057a4ae..7823971 100644
--- a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
+++ b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
@@ -16,26 +16,26 @@
 
 package com.android.internal.location.gnssmetrics;
 
+import android.location.GnssStatus;
 import android.os.SystemClock;
-import android.os.connectivity.GpsBatteryStats;
 import android.os.SystemProperties;
-
+import android.os.connectivity.GpsBatteryStats;
 import android.server.location.ServerLocationProtoEnums;
-
 import android.text.format.DateUtils;
 import android.util.Base64;
 import android.util.Log;
 import android.util.StatsLog;
 import android.util.TimeUtils;
 
-import java.util.Arrays;
-
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.location.nano.GnssLogsProto.GnssLog;
 import com.android.internal.location.nano.GnssLogsProto.PowerMetrics;
 
+import java.util.Arrays;
+
 /**
  * GnssMetrics: Is used for logging GNSS metrics
+ *
  * @hide
  */
 public class GnssMetrics {
@@ -66,6 +66,11 @@
   /* GNSS power metrics */
   private GnssPowerMetrics mGnssPowerMetrics;
 
+    /**
+     * A boolean array indicating whether the constellation types have been used in fix.
+     */
+    private boolean[] mConstellationTypes;
+
   /** Constructor */
   public GnssMetrics(IBatteryStats stats) {
     mGnssPowerMetrics = new GnssPowerMetrics(stats);
@@ -156,6 +161,18 @@
     return;
   }
 
+
+    /**
+     * Logs that a constellation type has been observed.
+     */
+    public void logConstellationType(int constellationType) {
+        if (constellationType >= mConstellationTypes.length) {
+            Log.e(TAG, "Constellation type " + constellationType + " is not valid.");
+            return;
+        }
+        mConstellationTypes[constellationType] = true;
+    }
+
   /**
    * Dumps GNSS metrics as a proto string
    * @return
@@ -232,6 +249,13 @@
       s.append("  Top 4 Avg CN0 standard deviation (dB-Hz): ").append(
           topFourAverageCn0Statistics.getStandardDeviation()).append("\n");
     }
+        s.append("  Used-in-fix constellation types: ");
+        for (int i = 0; i < mConstellationTypes.length; i++) {
+            if (mConstellationTypes[i]) {
+                s.append(GnssStatus.constellationTypeToString(i)).append(" ");
+            }
+        }
+        s.append("\n");
     s.append("GNSS_KPI_END").append("\n");
     GpsBatteryStats stats = mGnssPowerMetrics.getGpsBatteryStats();
     if (stats != null) {
@@ -320,9 +344,15 @@
     timeToFirstFixSecStatistics.reset();
     positionAccuracyMeterStatistics.reset();
     topFourAverageCn0Statistics.reset();
+        resetConstellationTypes();
     return;
   }
 
+    /** Resets {@link #mConstellationTypes} as an all-false boolean array. */
+    public void resetConstellationTypes() {
+        mConstellationTypes = new boolean[GnssStatus.CONSTELLATION_COUNT];
+    }
+
   /* Class for handling GNSS power related metrics */
   private class GnssPowerMetrics {
 
diff --git a/media/apex/java/android/media/DataSourceDesc.java b/media/apex/java/android/media/DataSourceDesc.java
index d00ff2a..9a9c74a 100644
--- a/media/apex/java/android/media/DataSourceDesc.java
+++ b/media/apex/java/android/media/DataSourceDesc.java
@@ -34,6 +34,8 @@
  *
  * Used by {@link MediaPlayer2#setDataSource}, {@link MediaPlayer2#setNextDataSource} and
  * {@link MediaPlayer2#setNextDataSources} to set data source for playback.
+ *
+ * @hide
  */
 public class DataSourceDesc {
     // intentionally less than long.MAX_VALUE
diff --git a/media/apex/java/android/media/FileDataSourceDesc.java b/media/apex/java/android/media/FileDataSourceDesc.java
index feb67e1..2aa2cb7 100644
--- a/media/apex/java/android/media/FileDataSourceDesc.java
+++ b/media/apex/java/android/media/FileDataSourceDesc.java
@@ -17,7 +17,6 @@
 package android.media;
 
 import android.annotation.NonNull;
-import android.annotation.TestApi;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
@@ -32,7 +31,6 @@
  * <p>Users should use {@link Builder} to create {@link FileDataSourceDesc}.
  * @hide
  */
-@TestApi
 public class FileDataSourceDesc extends DataSourceDesc {
     private static final String TAG = "FileDataSourceDesc";
 
diff --git a/media/apex/java/android/media/MediaConstants.java b/media/apex/java/android/media/MediaConstants.java
index 776c1ba..ce10889 100644
--- a/media/apex/java/android/media/MediaConstants.java
+++ b/media/apex/java/android/media/MediaConstants.java
@@ -28,6 +28,7 @@
     static final String KEY_ALLOWED_COMMANDS = "android.media.key.ALLOWED_COMMANDS";
     static final String KEY_PLAYBACK_ACTIVE = "android.media.key.PLAYBACK_ACTIVE";
     static final String KEY_TOKEN_EXTRAS = "android.media.key.TOKEN_EXTRAS";
+    static final String KEY_CONNECTION_HINTS = "android.media.key.CONNECTION_HINTS";
 
     private MediaConstants() {
     }
diff --git a/media/apex/java/android/media/MediaController2.java b/media/apex/java/android/media/MediaController2.java
index 1e8438e..fb4e6ac 100644
--- a/media/apex/java/android/media/MediaController2.java
+++ b/media/apex/java/android/media/MediaController2.java
@@ -17,6 +17,7 @@
 package android.media;
 
 import static android.media.MediaConstants.KEY_ALLOWED_COMMANDS;
+import static android.media.MediaConstants.KEY_CONNECTION_HINTS;
 import static android.media.MediaConstants.KEY_PACKAGE_NAME;
 import static android.media.MediaConstants.KEY_PID;
 import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE;
@@ -91,24 +92,16 @@
      * Create a {@link MediaController2} from the {@link Session2Token}.
      * This connects to the session and may wake up the service if it's not available.
      *
-     * @param context Context
+     * @param context context
      * @param token token to connect to
-     */
-    public MediaController2(@NonNull Context context, @NonNull Session2Token token) {
-        this(context, token, context.getMainExecutor(), new ControllerCallback() {});
-    }
-
-    /**
-     * Create a {@link MediaController2} from the {@link Session2Token}.
-     * This connects to the session and may wake up the service if it's not available.
-     *
-     * @param context Context
-     * @param token token to connect to
+     * @param connectionHints a session-specific argument to send to the session when connecting.
+     *                        The contents of this bundle may affect the connection result.
      * @param executor executor to run callbacks on.
      * @param callback controller callback to receive changes in.
      */
-    public MediaController2(@NonNull Context context, @NonNull Session2Token token,
-            @NonNull Executor executor, @NonNull ControllerCallback callback) {
+    MediaController2(@NonNull Context context, @NonNull Session2Token token,
+            @Nullable Bundle connectionHints, @NonNull Executor executor,
+            @NonNull ControllerCallback callback) {
         if (context == null) {
             throw new IllegalArgumentException("context shouldn't be null");
         }
@@ -130,9 +123,9 @@
         boolean connectRequested;
         if (token.getType() == TYPE_SESSION) {
             mServiceConnection = null;
-            connectRequested = requestConnectToSession();
+            connectRequested = requestConnectToSession(connectionHints);
         } else {
-            mServiceConnection = new SessionServiceConnection();
+            mServiceConnection = new SessionServiceConnection(connectionHints);
             connectRequested = requestConnectToService();
         }
         if (!connectRequested) {
@@ -350,16 +343,17 @@
         }
     }
 
-    private Bundle createConnectionRequest() {
+    private Bundle createConnectionRequest(@Nullable Bundle connectionHints) {
         Bundle connectionRequest = new Bundle();
         connectionRequest.putString(KEY_PACKAGE_NAME, mContext.getPackageName());
         connectionRequest.putInt(KEY_PID, Process.myPid());
+        connectionRequest.putBundle(KEY_CONNECTION_HINTS, connectionHints);
         return connectionRequest;
     }
 
-    private boolean requestConnectToSession() {
+    private boolean requestConnectToSession(@Nullable Bundle connectionHints) {
         Session2Link sessionBinder = mSessionToken.getSessionLink();
-        Bundle connectionRequest = createConnectionRequest();
+        Bundle connectionRequest = createConnectionRequest(connectionHints);
         try {
             sessionBinder.connect(mControllerStub, getNextSeqNumber(), connectionRequest);
         } catch (RuntimeException e) {
@@ -402,6 +396,93 @@
     }
 
     /**
+     * Builder for {@link MediaController2}.
+     * <p>
+     * Any incoming event from the {@link MediaSession2} will be handled on the callback
+     * executor. If it's not set, {@link Context#getMainExecutor()} will be used by default.
+     */
+    public static final class Builder {
+        private Context mContext;
+        private Session2Token mToken;
+        private Bundle mConnectionHints;
+        private Executor mCallbackExecutor;
+        private ControllerCallback mCallback;
+
+        /**
+         * Creates a builder for {@link MediaController2}.
+         *
+         * @param context context
+         * @param token token of the session to connect to
+         */
+        public Builder(@NonNull Context context, @NonNull Session2Token token) {
+            if (context == null) {
+                throw new IllegalArgumentException("context shouldn't be null");
+            }
+            if (token == null) {
+                throw new IllegalArgumentException("token shouldn't be null");
+            }
+            mContext = context;
+            mToken = token;
+        }
+
+        /**
+         * Set the connection hints for the controller.
+         * <p>
+         * {@code connectionHints} is a session-specific argument to send to the session when
+         * connecting. The contents of this bundle may affect the connection result.
+         *
+         * @param connectionHints a bundle which contains the connection hints
+         * @return The Builder to allow chaining
+         */
+        @NonNull
+        public Builder setConnectionHints(@NonNull Bundle connectionHints) {
+            if (connectionHints == null) {
+                throw new IllegalArgumentException("connectionHints shouldn't be null");
+            }
+            mConnectionHints = new Bundle(connectionHints);
+            return this;
+        }
+
+        /**
+         * Set callback for the controller and its executor.
+         *
+         * @param executor callback executor
+         * @param callback session callback.
+         * @return The Builder to allow chaining
+         */
+        @NonNull
+        public Builder setControllerCallback(@NonNull Executor executor,
+                @NonNull ControllerCallback callback) {
+            if (executor == null) {
+                throw new IllegalArgumentException("executor shouldn't be null");
+            }
+            if (callback == null) {
+                throw new IllegalArgumentException("callback shouldn't be null");
+            }
+            mCallbackExecutor = executor;
+            mCallback = callback;
+            return this;
+        }
+
+        /**
+         * Build {@link MediaController2}.
+         *
+         * @return a new controller
+         */
+        @NonNull
+        public MediaController2 build() {
+            if (mCallbackExecutor == null) {
+                mCallbackExecutor = mContext.getMainExecutor();
+            }
+            if (mCallback == null) {
+                mCallback = new ControllerCallback() {};
+            }
+            return new MediaController2(
+                    mContext, mToken, mConnectionHints, mCallbackExecutor, mCallback);
+        }
+    }
+
+    /**
      * Interface for listening to change in activeness of the {@link MediaSession2}.
      * <p>
      * This API is not generally intended for third party application developers.
@@ -469,7 +550,10 @@
 
     // This will be called on the main thread.
     private class SessionServiceConnection implements ServiceConnection {
-        SessionServiceConnection() {
+        private final Bundle mConnectionHints;
+
+        SessionServiceConnection(@Nullable Bundle connectionHints) {
+            mConnectionHints = connectionHints;
         }
 
         @Override
@@ -491,7 +575,7 @@
                     Log.wtf(TAG, "Service interface is missing.");
                     return;
                 }
-                Bundle connectionRequest = createConnectionRequest();
+                Bundle connectionRequest = createConnectionRequest(mConnectionHints);
                 iService.connect(mControllerStub, getNextSeqNumber(), connectionRequest);
                 connectRequested = true;
             } catch (RemoteException e) {
diff --git a/media/apex/java/android/media/MediaPlayer2.java b/media/apex/java/android/media/MediaPlayer2.java
index 72c18f6..614d737 100644
--- a/media/apex/java/android/media/MediaPlayer2.java
+++ b/media/apex/java/android/media/MediaPlayer2.java
@@ -273,6 +273,8 @@
  * Then check the <code>status</code> parameter. The value {@link #CALL_STATUS_NO_ERROR} indicates a
  * successful transition. Any other value will be an error. Call {@link #getState()} to
  * determine the current state. </p>
+ *
+ * @hide
  */
 public class MediaPlayer2 implements AutoCloseable, AudioRouting {
     static {
diff --git a/media/apex/java/android/media/MediaSession2.java b/media/apex/java/android/media/MediaSession2.java
index a900d87..6b56ae0 100644
--- a/media/apex/java/android/media/MediaSession2.java
+++ b/media/apex/java/android/media/MediaSession2.java
@@ -17,6 +17,7 @@
 package android.media;
 
 import static android.media.MediaConstants.KEY_ALLOWED_COMMANDS;
+import static android.media.MediaConstants.KEY_CONNECTION_HINTS;
 import static android.media.MediaConstants.KEY_PACKAGE_NAME;
 import static android.media.MediaConstants.KEY_PID;
 import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE;
@@ -308,8 +309,11 @@
         String callingPkg = connectionRequest.getString(KEY_PACKAGE_NAME);
 
         RemoteUserInfo remoteUserInfo = new RemoteUserInfo(callingPkg, callingPid, callingUid);
-        final ControllerInfo controllerInfo = new ControllerInfo(remoteUserInfo,
-                mSessionManager.isTrustedForMediaControl(remoteUserInfo), controller);
+        final ControllerInfo controllerInfo = new ControllerInfo(
+                remoteUserInfo,
+                mSessionManager.isTrustedForMediaControl(remoteUserInfo),
+                controller,
+                connectionRequest.getBundle(KEY_CONNECTION_HINTS));
         mCallbackExecutor.execute(() -> {
             boolean connected = false;
             try {
@@ -568,6 +572,7 @@
         private final RemoteUserInfo mRemoteUserInfo;
         private final boolean mIsTrusted;
         private final Controller2Link mControllerBinder;
+        private final Bundle mConnectionHints;
         private final Object mLock = new Object();
         //@GuardedBy("mLock")
         private int mNextSeqNumber;
@@ -583,12 +588,16 @@
          * @param remoteUserInfo remote user info
          * @param trusted {@code true} if trusted, {@code false} otherwise
          * @param controllerBinder Controller2Link for the connected controller.
+         * @param connectionHints a session-specific argument sent from the controller for the
+         *                        connection. The contents of this bundle may affect the
+         *                        connection result.
          */
         ControllerInfo(@NonNull RemoteUserInfo remoteUserInfo, boolean trusted,
-                @Nullable Controller2Link controllerBinder) {
+                @Nullable Controller2Link controllerBinder, @Nullable Bundle connectionHints) {
             mRemoteUserInfo = remoteUserInfo;
             mIsTrusted = trusted;
             mControllerBinder = controllerBinder;
+            mConnectionHints = connectionHints;
             mPendingCommands = new ArrayMap<>();
             mRequestedCommandSeqNumbers = new ArraySet<>();
         }
@@ -617,6 +626,14 @@
         }
 
         /**
+         * @return connection hints sent from controller, or {@link Bundle#EMPTY} if none.
+         */
+        @NonNull
+        public Bundle getConnectionHints() {
+            return mConnectionHints == null ? Bundle.EMPTY : new Bundle(mConnectionHints);
+        }
+
+        /**
          * Return if the controller has granted {@code android.permission.MEDIA_CONTENT_CONTROL} or
          * has a enabled notification listener so can be trusted to accept connection and incoming
          * command request.
diff --git a/media/apex/java/android/media/MediaSession2Service.java b/media/apex/java/android/media/MediaSession2Service.java
index 5bb746a..28ead99 100644
--- a/media/apex/java/android/media/MediaSession2Service.java
+++ b/media/apex/java/android/media/MediaSession2Service.java
@@ -16,6 +16,10 @@
 
 package android.media;
 
+import static android.media.MediaConstants.KEY_CONNECTION_HINTS;
+import static android.media.MediaConstants.KEY_PACKAGE_NAME;
+import static android.media.MediaConstants.KEY_PID;
+
 import android.annotation.CallSuper;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -24,6 +28,9 @@
 import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
+import android.media.MediaSession2.ControllerInfo;
+import android.media.session.MediaSessionManager;
+import android.media.session.MediaSessionManager.RemoteUserInfo;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -70,6 +77,8 @@
     //@GuardedBy("mLock")
     private NotificationManager mNotificationManager;
     //@GuardedBy("mLock")
+    private MediaSessionManager mMediaSessionManager;
+    //@GuardedBy("mLock")
     private Intent mStartSelfIntent;
     //@GuardedBy("mLock")
     private Map<String, MediaSession2> mSessions = new ArrayMap<>();
@@ -93,6 +102,8 @@
             mStartSelfIntent = new Intent(this, this.getClass());
             mNotificationManager =
                     (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+            mMediaSessionManager =
+                    (MediaSessionManager) getSystemService(Context.MEDIA_SESSION_SERVICE);
         }
     }
 
@@ -132,34 +143,22 @@
 
     /**
      * Called when a {@link MediaController2} is created with the this service's
-     * {@link Session2Token}. Return the primary session for telling the controller which session to
-     * connect.
-     * <p>
-     * Primary session is the highest priority session that this service manages. Here are some
-     * recommendations of the primary session.
-     * <ol>
-     * <li>When there's no {@link MediaSession2}, create and return a new session. Resume the
-     * playback that the app has the lastly played with the new session. The behavior is what
-     * framework expects when the framework sends key events to the service.</li>
-     * <li>When there's multiple {@link MediaSession2}s, pick the session that has the lastly
-     * started the playback. This is the same way as the framework prioritize sessions to receive
-     * media key events.</li>
-     * </ol>
+     * {@link Session2Token}. Return the session for telling the controller which session to
+     * connect. Return {@code null} to reject the connection from this controller.
      * <p>
      * Session returned here will be added to this service automatically. You don't need to call
      * {@link #addSession(MediaSession2)} for that.
      * <p>
-     * Session service will accept or reject the connection with the
-     * {@link MediaSession2.SessionCallback} in the session returned here.
-     * <p>
      * This method is always called on the main thread.
      *
-     * @return a new session
+     * @param controllerInfo information of the controller which is trying to connect.
+     * @return a {@link MediaSession2} instance for the controller to connect to, or {@code null}
+     *         to reject connection
      * @see MediaSession2.Builder
      * @see #getSessions()
      */
-    @NonNull
-    public abstract MediaSession2 onGetPrimarySession();
+    @Nullable
+    public abstract MediaSession2 onGetSession(@NonNull ControllerInfo controllerInfo);
 
     /**
      * Called when notification UI needs update. Override this method to show or cancel your own
@@ -251,6 +250,16 @@
     }
 
     /**
+     * Returns the {@link MediaSessionManager}.
+     */
+    @NonNull
+    MediaSessionManager getMediaSessionManager() {
+        synchronized (mLock) {
+            return mMediaSessionManager;
+        }
+    }
+
+    /**
      * Called by registered {@link MediaSession2.ForegroundServiceEventCallback}
      *
      * @param session session with change
@@ -365,8 +374,33 @@
                             Log.d(TAG, "Handling incoming connection request from the"
                                     + " controller, controller=" + caller + ", uid=" + uid);
                         }
+
+                        String callingPkg = connectionRequest.getString(KEY_PACKAGE_NAME);
+                        // The Binder.getCallingPid() can be 0 for an oneway call from the
+                        // remote process. If it's the case, use PID from the connectionRequest.
+                        RemoteUserInfo remoteUserInfo = new RemoteUserInfo(
+                                callingPkg,
+                                pid == 0 ? connectionRequest.getInt(KEY_PID) : pid,
+                                uid);
+                        final ControllerInfo controllerInfo = new ControllerInfo(
+                                remoteUserInfo,
+                                service.getMediaSessionManager()
+                                        .isTrustedForMediaControl(remoteUserInfo),
+                                caller,
+                                connectionRequest.getBundle(KEY_CONNECTION_HINTS));
+
                         final MediaSession2 session;
-                        session = service.onGetPrimarySession();
+                        session = service.onGetSession(controllerInfo);
+
+                        if (session == null) {
+                            if (DEBUG) {
+                                Log.d(TAG, "Rejecting incoming connection request from the"
+                                        + " controller, controller=" + caller + ", uid=" + uid);
+                            }
+                            // Note: Trusted controllers also can be rejected according to the
+                            // service implementation.
+                            return;
+                        }
                         service.addSession(session);
                         shouldNotifyDisconnected = false;
                         session.onConnect(caller, pid, uid, seq, connectionRequest);
@@ -377,8 +411,7 @@
                         // Trick to call onDisconnected() in one place.
                         if (shouldNotifyDisconnected) {
                             if (DEBUG) {
-                                Log.d(TAG, "Service has destroyed prematurely."
-                                        + " Rejecting connection");
+                                Log.d(TAG, "Notifying the controller of its disconnection");
                             }
                             try {
                                 caller.notifyDisconnected(0);
diff --git a/media/apex/java/android/media/UriDataSourceDesc.java b/media/apex/java/android/media/UriDataSourceDesc.java
index eaedf1e..adf7a7d 100644
--- a/media/apex/java/android/media/UriDataSourceDesc.java
+++ b/media/apex/java/android/media/UriDataSourceDesc.java
@@ -18,7 +18,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.TestApi;
 import android.net.Uri;
 
 import java.net.HttpCookie;
@@ -36,7 +35,6 @@
  * <p>Users should use {@link Builder} to change {@link UriDataSourceDesc}.
  * @hide
  */
-@TestApi
 public class UriDataSourceDesc extends DataSourceDesc {
     private Uri mUri;
     private Map<String, String> mHeader;
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 9d4bce7..e655460 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -20,7 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
-import android.media.audiopolicy.AudioProductStrategies;
+import android.media.audiopolicy.AudioProductStrategy;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -535,6 +535,23 @@
     }
 
     /**
+     * Return the capture policy.
+     * @return the capture policy set by {@link Builder#setAllowedCapturePolicy(int)} or
+     *         the default if it was not called.
+     */
+    @CapturePolicy
+    public int getAllowedCapturePolicy() {
+        if ((mFlags & FLAG_NO_SYSTEM_CAPTURE) == FLAG_NO_SYSTEM_CAPTURE) {
+            return ALLOW_CAPTURE_BY_NONE;
+        }
+        if ((mFlags & FLAG_NO_MEDIA_PROJECTION) == FLAG_NO_MEDIA_PROJECTION) {
+            return ALLOW_CAPTURE_BY_SYSTEM;
+        }
+        return ALLOW_CAPTURE_BY_ALL;
+    }
+
+
+    /**
      * Builder class for {@link AudioAttributes} objects.
      * <p> Here is an example where <code>Builder</code> is used to define the
      * {@link AudioAttributes} to be used by a new <code>AudioTrack</code> instance:
@@ -696,12 +713,19 @@
         }
 
         /**
-         * Specifying if audio may or may not be captured by other apps or the system.
+         * Specifies weather the audio may or may not be captured by other apps or the system.
          *
          * The default is {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}.
          *
-         * Note that an application can also set its global policy, in which case the most
-         * restrictive policy is always applied.
+         * There are multiple ways to set this policy:
+         *  - for each tracks independently, with this method
+         *  - application wide at runtime, with {@link AudioManager#setAllowedCapturePolicy(int)}
+         *  - application wide at build time, see {@code allowAudioPlaybackCapture} in the
+         *    application manifest.
+         * The most restrictive policy is always applied.
+         *
+         * See {@link AudioPlaybackCaptureConfiguration} for more details on the restrictions
+         * which audio signals can be captured.
          *
          * @param capturePolicy one of
          *     {@link #ALLOW_CAPTURE_BY_ALL},
@@ -783,9 +807,10 @@
          */
         @UnsupportedAppUsage
         public Builder setInternalLegacyStreamType(int streamType) {
-            final AudioProductStrategies ps = new AudioProductStrategies();
-            if (ps.size() > 0) {
-                AudioAttributes attributes = ps.getAudioAttributesForLegacyStreamType(streamType);
+            if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
+                AudioAttributes attributes =
+                        AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
+                                streamType);
                 if (attributes != null) {
                     return new Builder(attributes);
                 }
@@ -1165,9 +1190,8 @@
                     AudioSystem.STREAM_MUSIC : AudioSystem.STREAM_TTS;
         }
 
-        final AudioProductStrategies ps = new AudioProductStrategies();
-        if (ps.size() > 0) {
-            return ps.getLegacyStreamTypeForAudioAttributes(aa);
+        if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
+            return AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes(aa);
         }
         // usage to stream type mapping
         switch (aa.getUsage()) {
diff --git a/media/java/android/media/AudioFocusInfo.java b/media/java/android/media/AudioFocusInfo.java
index 3aaa7df..ee89509 100644
--- a/media/java/android/media/AudioFocusInfo.java
+++ b/media/java/android/media/AudioFocusInfo.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -27,6 +28,7 @@
  * @hide
  * A class to encapsulate information about an audio focus owner or request.
  */
+@TestApi
 @SystemApi
 public final class AudioFocusInfo implements Parcelable {
 
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index a5a4092..8831265 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -26,6 +26,7 @@
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -37,9 +38,9 @@
 import android.content.Intent;
 import android.media.audiopolicy.AudioPolicy;
 import android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener;
-import android.media.audiopolicy.AudioProductStrategies;
+import android.media.audiopolicy.AudioProductStrategy;
+import android.media.audiopolicy.AudioVolumeGroup;
 import android.media.audiopolicy.AudioVolumeGroupChangeHandler;
-import android.media.audiopolicy.AudioVolumeGroups;
 import android.media.projection.MediaProjection;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
@@ -1483,12 +1484,21 @@
      }
 
     /**
-     * Specifying if this audio may or may not be captured by other apps or the system.
+     * Specifies wheather the audio played by this app may or may not be captured by other apps or
+     * the system.
      *
      * The default is {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}.
      *
-     * Note that each audio track can also set its policy, in which case the most
-     * restrictive policy is always applied.
+     * There are multiple ways to set this policy:
+     *  - for each tracks independently, see
+     *    {@link AudioAttributes.Builder#setAllowedCapturePolicy(int)}
+     *  - application wide at runtime, with this method
+     *  - application wide at build time, see {@code allowAudioPlaybackCapture} in the application
+     *  manifest.
+     * The most restrictive policy is always applied.
+     *
+     * See {@link AudioPlaybackCaptureConfiguration} for more details on the restrictions
+     * which audio signals can be captured.
      *
      * @param capturePolicy one of
      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
@@ -1503,7 +1513,22 @@
         int result = AudioSystem.setAllowedCapturePolicy(Process.myUid(), flags);
         if (result != AudioSystem.AUDIO_STATUS_OK) {
             Log.e(TAG, "Could not setAllowedCapturePolicy: " + result);
+            return;
         }
+        mCapturePolicy = capturePolicy;
+    }
+
+    @AudioAttributes.CapturePolicy
+    private int mCapturePolicy = AudioAttributes.ALLOW_CAPTURE_BY_ALL;
+
+    /**
+     * Return the capture policy.
+     * @return the capture policy set by {@link #setAllowedCapturePolicy(int)} or
+     *         the default if it was not called.
+     */
+    @AudioAttributes.CapturePolicy
+    public int getAllowedCapturePolicy() {
+        return mCapturePolicy;
     }
 
     //====================================================================
@@ -3026,6 +3051,7 @@
      * @param requestResult the result to the focus request to be passed to the requester
      * @param ap a valid registered {@link AudioPolicy} configured as a focus policy.
      */
+    @TestApi
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     public void setFocusRequestResult(@NonNull AudioFocusInfo afi,
@@ -3065,6 +3091,7 @@
      *     if there was an error sending the request.
      * @throws NullPointerException if the {@link AudioFocusInfo} or {@link AudioPolicy} are null.
      */
+    @TestApi
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     public int dispatchAudioFocusChange(@NonNull AudioFocusInfo afi, int focusChange,
@@ -3327,6 +3354,7 @@
      *    {@link android.Manifest.permission#MODIFY_AUDIO_ROUTING} permission,
      *    {@link #SUCCESS} otherwise.
      */
+    @TestApi
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     public int registerAudioPolicy(@NonNull AudioPolicy policy) {
@@ -3361,6 +3389,7 @@
      * Unregisters an {@link AudioPolicy} asynchronously.
      * @param policy the non-null {@link AudioPolicy} to unregister.
      */
+    @TestApi
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     public void unregisterAudioPolicyAsync(@NonNull AudioPolicy policy) {
@@ -3387,6 +3416,7 @@
      * associated with mixes of this policy.
      * @param policy the non-null {@link AudioPolicy} to unregister.
      */
+    @TestApi
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     public void unregisterAudioPolicy(@NonNull AudioPolicy policy) {
@@ -5406,8 +5436,9 @@
      *         {@see android.media.audiopolicy.AudioProductStrategy} objects.
      */
     @SystemApi
+    @NonNull
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
-    public @NonNull AudioProductStrategies getAudioProductStrategies() {
+    public static List<AudioProductStrategy> getAudioProductStrategies() {
         final IAudioService service = getService();
         try {
             return service.getAudioProductStrategies();
@@ -5421,15 +5452,16 @@
      * Introspection API to retrieve audio volume groups.
      * When implementing {Car|Oem}AudioManager, use this method  to retrieve the collection of
      * audio volume groups.
-     * @return a (possibly zero-length) array of
-     *         {@see android.media.audiopolicy.AudioVolumeGroups} objects.
+     * @return a (possibly zero-length) List of
+     *         {@see android.media.audiopolicy.AudioVolumeGroup} objects.
      */
     @SystemApi
+    @NonNull
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
-    public @NonNull AudioVolumeGroups getAudioVolumeGroups() {
+    public static List<AudioVolumeGroup> getAudioVolumeGroups() {
         final IAudioService service = getService();
         try {
-            return service.listAudioVolumeGroups();
+            return service.getAudioVolumeGroups();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/media/java/android/media/AudioPlaybackCaptureConfiguration.java b/media/java/android/media/AudioPlaybackCaptureConfiguration.java
index bcaef03..fe5005a 100644
--- a/media/java/android/media/AudioPlaybackCaptureConfiguration.java
+++ b/media/java/android/media/AudioPlaybackCaptureConfiguration.java
@@ -20,26 +20,35 @@
 import android.media.AudioAttributes.AttributeUsage;
 import android.media.audiopolicy.AudioMix;
 import android.media.audiopolicy.AudioMixingRule;
+import android.media.audiopolicy.AudioMixingRule.AudioMixMatchCriterion;
 import android.media.projection.MediaProjection;
 import android.os.RemoteException;
 
 import com.android.internal.util.Preconditions;
 
+import java.util.function.ToIntFunction;
+
 /**
  * Configuration for capturing audio played by other apps.
  *
- * Only the following audio can be captured:
- *  - usage MUST be {@link AudioAttributes#USAGE_UNKNOWN} or {@link AudioAttributes#USAGE_GAME}
+ *  When capturing audio signals played by other apps (and yours),
+ *  you will only capture a mix of the audio signals played by players
+ *  (such as AudioTrack or MediaPlayer) which present the following characteristics:
+ *  - the usage value MUST be {@link AudioAttributes#USAGE_UNKNOWN} or
+ *    {@link AudioAttributes#USAGE_GAME}
  *    or {@link AudioAttributes#USAGE_MEDIA}. All other usages CAN NOT be captured.
- *  - audio attributes MUST have its ${@link AudioAttributes.Builder#setAllowedCapturePolicy}
- *    to {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}.
- *  - played by apps that MUST be in the same user profile as the capturing app
- *    (eg work profile can not capture user profile apps and vice-versa).
- *  - played by apps for which the attribute allowAudioPlaybackCapture in their manifest
+ *  - AND the capture policy set by their app (with ${@link AudioManager#setAllowedCapturePolicy})
+ *    or on each player (with ${@link AudioAttributes.Builder#setAllowedCapturePolicy}) is
+ *    {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}, whichever is the most strict.
+ *  - AND their app attribute allowAudioPlaybackCapture in their manifest
  *    MUST either be:
  *      * set to "true"
- *      * not set, and their targetSdkVersion MUST be equal or higher to
+ *      * not set, and their {@code targetSdkVersion} MUST be equal or higher to
  *        {@link android.os.Build.VERSION_CODES#Q}.
+ *        Ie. Apps that do not target at least Android Q must explicitly opt-in to be captured by a
+ *            MediaProjection.
+ *  - AND their apps MUST be in the same user profile as your app
+ *    (eg work profile can not capture user profile apps and vice-versa).
  *
  * <p>An example for creating a capture configuration for capturing all media playback:
  *
@@ -77,6 +86,39 @@
         return mProjection;
     }
 
+    /** @return the usages passed to {@link Builder#addMatchingUsage(int)}. */
+    @AttributeUsage
+    public @NonNull int[] getMatchingUsages() {
+        return getIntPredicates(AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE,
+                                criterion -> criterion.getAudioAttributes().getUsage());
+    }
+
+    /** @return the UIDs passed to {@link Builder#addMatchingUid(int)}. */
+    public @NonNull int[] getMatchingUids() {
+        return getIntPredicates(AudioMixingRule.RULE_MATCH_UID,
+                                criterion -> criterion.getIntProp());
+    }
+
+    /** @return the usages passed to {@link Builder#excludeUsage(int)}. */
+    @AttributeUsage
+    public @NonNull int[] getExcludeUsages() {
+        return getIntPredicates(AudioMixingRule.RULE_EXCLUDE_ATTRIBUTE_USAGE,
+                                criterion -> criterion.getAudioAttributes().getUsage());
+    }
+
+    /** @return the UIDs passed to {@link Builder#excludeUid(int)}.  */
+    public @NonNull int[] getExcludeUids() {
+        return getIntPredicates(AudioMixingRule.RULE_EXCLUDE_UID,
+                                criterion -> criterion.getIntProp());
+    }
+
+    private int[] getIntPredicates(int rule,
+                                   ToIntFunction<AudioMixMatchCriterion> getPredicate) {
+        return mAudioMixingRule.getCriteria().stream()
+            .filter(criterion -> criterion.getRule() == rule)
+            .mapToInt(getPredicate)
+            .toArray();
+    }
 
     /**
      * Returns a mix that routes audio back into the app while still playing it from the speakers.
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 980cb04..eddbee4 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -33,8 +33,8 @@
 import android.media.PlayerBase;
 import android.media.VolumePolicy;
 import android.media.audiopolicy.AudioPolicyConfig;
-import android.media.audiopolicy.AudioProductStrategies;
-import android.media.audiopolicy.AudioVolumeGroups;
+import android.media.audiopolicy.AudioProductStrategy;
+import android.media.audiopolicy.AudioVolumeGroup;
 import android.media.audiopolicy.IAudioPolicyCallback;
 import android.media.projection.IMediaProjection;
 import android.net.Uri;
@@ -86,7 +86,7 @@
     @UnsupportedAppUsage
     int getStreamMaxVolume(int streamType);
 
-    AudioVolumeGroups listAudioVolumeGroups();
+    List<AudioVolumeGroup> getAudioVolumeGroups();
 
     void setVolumeIndexForAttributes(in AudioAttributes aa, int index, int flags, String callingPackage);
 
@@ -98,7 +98,7 @@
 
     int getLastAudibleStreamVolume(int streamType);
 
-    AudioProductStrategies getAudioProductStrategies();
+    List<AudioProductStrategy> getAudioProductStrategies();
 
     void setMicrophoneMute(boolean on, String callingPackage, int userId);
 
diff --git a/media/java/android/media/IMediaRoute2Callback.aidl b/media/java/android/media/IMediaRoute2Callback.aidl
deleted file mode 100644
index f03c8ab..0000000
--- a/media/java/android/media/IMediaRoute2Callback.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-/**
- * @hide
- */
-oneway interface IMediaRoute2Callback {
-    void onRouteSelected(int uid, String routeId);
-}
diff --git a/media/java/android/media/IMediaRoute2Provider.aidl b/media/java/android/media/IMediaRoute2Provider.aidl
deleted file mode 100644
index b97dcc5..0000000
--- a/media/java/android/media/IMediaRoute2Provider.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.media.IMediaRoute2Callback;
-
-/**
- * {@hide}
- */
-oneway interface IMediaRoute2Provider {
-    void setCallback(IMediaRoute2Callback callback);
-    void selectRoute(int uid, String id);
-}
diff --git a/media/java/android/media/IMediaRouter2ManagerClient.aidl b/media/java/android/media/IMediaRouter2ManagerClient.aidl
deleted file mode 100644
index 234551b..0000000
--- a/media/java/android/media/IMediaRouter2ManagerClient.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-/**
- * {@hide}
- */
-oneway interface IMediaRouter2ManagerClient {
-    void onRouteSelected(int uid, String routeId);
-    void onControlCategoriesChanged(int uid, in List<String> categories);
-}
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index 59f1d0d..3308fc9 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -17,7 +17,6 @@
 package android.media;
 
 import android.media.IMediaRouterClient;
-import android.media.IMediaRouter2ManagerClient;
 import android.media.MediaRouterClientState;
 
 /**
@@ -30,15 +29,8 @@
     MediaRouterClientState getState(IMediaRouterClient client);
     boolean isPlaybackActive(IMediaRouterClient client);
 
-    void setControlCategories(IMediaRouterClient client, in List<String> categories);
     void setDiscoveryRequest(IMediaRouterClient client, int routeTypes, boolean activeScan);
     void setSelectedRoute(IMediaRouterClient client, String routeId, boolean explicit);
     void requestSetVolume(IMediaRouterClient client, String routeId, int volume);
     void requestUpdateVolume(IMediaRouterClient client, String routeId, int direction);
-
-    void registerManagerAsUser(IMediaRouter2ManagerClient callback,
-            String packageName, int userId);
-    void unregisterManager(IMediaRouter2ManagerClient callback);
-    void setRemoteRoute(IMediaRouter2ManagerClient callback,
-            int uid, String routeId, boolean explicit);
 }
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
deleted file mode 100644
index 04ddc30..0000000
--- a/media/java/android/media/MediaRoute2ProviderService.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * @hide
- */
-public abstract class MediaRoute2ProviderService extends Service {
-    private static final String TAG = "MediaRouteProviderSrv";
-
-    public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService";
-
-    private final Handler mHandler;
-    private ProviderStub mStub;
-    private IMediaRoute2Callback mCallback;
-
-    public MediaRoute2ProviderService() {
-        mHandler = new Handler(Looper.getMainLooper());
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        if (SERVICE_INTERFACE.equals(intent.getAction())) {
-            if (mStub == null) {
-                mStub = new ProviderStub();
-            }
-            return mStub;
-        }
-        return null;
-    }
-
-    /**
-     * Called when selectRoute is called on a route of the provider.
-     *
-     * @param uid The target application uid
-     * @param routeId The id of the target route
-     */
-    public abstract void onSelect(int uid, String routeId);
-
-    /**
-     * Updates provider info from selected route and appliation.
-     *
-     * TODO: When provider descriptor is defined, this should update the descriptor correctly.
-     *
-     * @param uid
-     * @param routeId
-     */
-    public void updateProvider(int uid, String routeId) {
-        if (mCallback != null) {
-            try {
-                //TODO: After publishState() is fully implemented, delete this.
-                mCallback.onRouteSelected(uid, routeId);
-            } catch (RemoteException ex) {
-                Log.d(TAG, "Failed to update provider");
-            }
-        }
-        publishState();
-    }
-
-    void setCallback(IMediaRoute2Callback callback) {
-        mCallback = callback;
-        publishState();
-    }
-
-    void publishState() {
-        //TODO: Send provider descriptor to the MediaRouterService
-    }
-
-    final class ProviderStub extends IMediaRoute2Provider.Stub {
-        ProviderStub() { }
-
-        @Override
-        public void setCallback(IMediaRoute2Callback callback) {
-            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::setCallback,
-                    MediaRoute2ProviderService.this, callback));
-        }
-
-        @Override
-        public void selectRoute(int uid, String id) {
-            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelect,
-                    MediaRoute2ProviderService.this, uid, id));
-        }
-    }
-}
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 5a89d8c..3444e92 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -347,17 +347,6 @@
             return mDisplayService.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
         }
 
-        void setControlCategories(List<String> categories) {
-            if (mClient != null) {
-                try {
-                    mMediaRouterService.setControlCategories(mClient,
-                            categories);
-                } catch (RemoteException ex) {
-                    Log.e(TAG, "Unable to set control categories.", ex);
-                }
-            }
-        }
-
         private void updatePresentationDisplays(int changedDisplayId) {
             final int count = mRoutes.size();
             for (int i = 0; i < count; i++) {
@@ -930,25 +919,6 @@
         return -1;
     }
 
-    //TODO: Remove @hide when it is ready.
-    //TODO: Provide pre-defined categories for app developers.
-    /**
-     * Sets control categories of the client application.
-     * Control categories can be used to filter out media routes
-     * that don't correspond with the client application.
-     * The only routes that match any of the categories will be shown on other applications.
-     *
-     * @hide
-     * @param categories Categories to set
-     */
-    public void setControlCategories(@NonNull List<String> categories) {
-        if (categories == null) {
-            throw new IllegalArgumentException("Categories must not be null");
-        }
-        sStatic.setControlCategories(categories);
-    }
-
-
     /**
      * Select the specified route to use for output of the given media types.
      * <p class="note">
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
deleted file mode 100644
index ac5958e..0000000
--- a/media/java/android/media/MediaRouter2Manager.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.content.Context;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * @hide
- */
-public class MediaRouter2Manager {
-    private static final String TAG = "MediaRouter2Manager";
-    private static final Object sLock = new Object();
-
-    @GuardedBy("sLock")
-    private static MediaRouter2Manager sInstance;
-
-    final String mPackageName;
-
-    private Context mContext;
-    private Client mClient;
-    private final IMediaRouterService mMediaRouterService;
-    final Handler mHandler;
-
-    @GuardedBy("sLock")
-    final ArrayList<CallbackRecord> mCallbacks = new ArrayList<>();
-
-    /**
-     * Gets an instance of media router manager that controls media route of other apps.
-     * @param context
-     * @return
-     */
-    public static MediaRouter2Manager getInstance(@NonNull Context context) {
-        if (context == null) {
-            throw new IllegalArgumentException("context must not be null");
-        }
-        synchronized (sLock) {
-            if (sInstance == null) {
-                sInstance = new MediaRouter2Manager(context);
-            }
-            return sInstance;
-        }
-    }
-
-    private MediaRouter2Manager(Context context) {
-        mContext = context.getApplicationContext();
-        mMediaRouterService = IMediaRouterService.Stub.asInterface(
-                ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
-        mPackageName = mContext.getPackageName();
-        mHandler = new Handler(context.getMainLooper());
-    }
-
-    /**
-     * Registers a callback to listen route info.
-     *
-     * @param executor The executor that runs the callback.
-     * @param callback The callback to add.
-     */
-    public void addCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull Callback callback) {
-
-        if (executor == null) {
-            throw new IllegalArgumentException("executor must not be null");
-        }
-        if (callback == null) {
-            throw new IllegalArgumentException("callback must not be null");
-        }
-
-        synchronized (sLock) {
-            final int index = findCallbackRecord(callback);
-            if (index >= 0) {
-                Log.w(TAG, "Ignore adding the same callback twice.");
-                return;
-            }
-            if (mCallbacks.size() == 0) {
-                Client client = new Client();
-                try {
-                    mMediaRouterService.registerManagerAsUser(client, mPackageName,
-                            UserHandle.myUserId());
-                    mClient = client;
-                } catch (RemoteException ex) {
-                    Log.e(TAG, "Unable to register media router manager.", ex);
-                }
-            }
-            mCallbacks.add(new CallbackRecord(executor, callback));
-        }
-    }
-
-    /**
-     * Removes the specified callback.
-     *
-     * @param callback The callback to remove.
-     */
-    public void removeCallback(@NonNull Callback callback) {
-        if (callback == null) {
-            throw new IllegalArgumentException("callback must not be null");
-        }
-
-        synchronized (sLock) {
-            final int index = findCallbackRecord(callback);
-            if (index < 0) {
-                Log.w(TAG, "Ignore removing unknown callback. " + callback);
-                return;
-            }
-            mCallbacks.remove(index);
-            if (mCallbacks.size() == 0 && mClient != null) {
-                try {
-                    mMediaRouterService.unregisterManager(mClient);
-                } catch (RemoteException ex) {
-                    Log.e(TAG, "Unable to unregister media router manager", ex);
-                }
-                mClient = null;
-            }
-        }
-    }
-
-    private int findCallbackRecord(Callback callback) {
-        final int count = mCallbacks.size();
-        for (int i = 0; i < count; i++) {
-            if (mCallbacks.get(i).mCallback == callback) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Selects media route for the specified application uid.
-     *
-     * @param uid The uid of the application that should change it's media route.
-     * @param routeId The id of the route to select
-     */
-    public void selectRoute(int uid, String routeId) {
-        if (mClient != null) {
-            try {
-                mMediaRouterService.setRemoteRoute(mClient, uid, routeId, /* explicit= */true);
-            } catch (RemoteException ex) {
-                Log.e(TAG, "Unable to select media route", ex);
-            }
-        }
-    }
-
-    /**
-     * Unselects media route for the specified application uid.
-     *
-     * @param uid The uid of the application that should stop routing.
-     */
-    public void unselectRoute(int uid) {
-        if (mClient != null) {
-            try {
-                mMediaRouterService.setRemoteRoute(mClient, uid, null, /* explicit= */ true);
-            } catch (RemoteException ex) {
-                Log.e(TAG, "Unable to select media route", ex);
-            }
-        }
-    }
-
-    void notifyRouteSelected(int uid, String routeId) {
-        for (CallbackRecord record : mCallbacks) {
-            record.mExecutor.execute(() -> record.mCallback.onRouteSelected(uid, routeId));
-        }
-    }
-
-    void notifyControlCategoriesChanged(int uid, List<String> categories) {
-        for (CallbackRecord record : mCallbacks) {
-            record.mExecutor.execute(
-                    () -> record.mCallback.onControlCategoriesChanged(uid, categories));
-        }
-    }
-
-    /**
-     * Interface for receiving events about media routing changes.
-     */
-    public abstract static class Callback {
-        /**
-         * Called when a route is selected for some application uid.
-         * @param uid
-         * @param routeId
-         */
-        public abstract void onRouteSelected(int uid, String routeId);
-
-        /**
-         * Called when the control categories of an application is changed.
-         * @param uid the uid of the app that changed control categories
-         * @param categories the changed categories
-         */
-        public abstract void onControlCategoriesChanged(int uid, List<String> categories);
-    }
-
-    final class CallbackRecord {
-        public final Executor mExecutor;
-        public final Callback mCallback;
-
-        CallbackRecord(Executor executor, Callback callback) {
-            mExecutor = executor;
-            mCallback = callback;
-        }
-    }
-
-    class Client extends IMediaRouter2ManagerClient.Stub {
-        @Override
-        public void onRouteSelected(int uid, String routeId) {
-            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyRouteSelected,
-                    MediaRouter2Manager.this, uid, routeId));
-        }
-
-        @Override
-        public void onControlCategoriesChanged(int uid, List<String> categories) {
-            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyControlCategoriesChanged,
-                    MediaRouter2Manager.this, uid, categories));
-        }
-    }
-}
diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java
index 09f17c0..2f03d26 100644
--- a/media/java/android/media/audiopolicy/AudioMix.java
+++ b/media/java/android/media/audiopolicy/AudioMix.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.media.AudioDeviceInfo;
 import android.media.AudioFormat;
@@ -31,6 +32,7 @@
 /**
  * @hide
  */
+@TestApi
 @SystemApi
 public class AudioMix {
 
diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java
index 947b06c..ed2fdae 100644
--- a/media/java/android/media/audiopolicy/AudioMixingRule.java
+++ b/media/java/android/media/audiopolicy/AudioMixingRule.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.media.AudioAttributes;
 import android.os.Parcel;
@@ -41,6 +42,7 @@
  *         .build();
  * </pre>
  */
+@TestApi
 @SystemApi
 public class AudioMixingRule {
 
@@ -92,7 +94,8 @@
     public static final int RULE_EXCLUDE_UID =
             RULE_EXCLUSION_MASK | RULE_MATCH_UID;
 
-    static final class AudioMixMatchCriterion {
+    /** @hide */
+    public static final class AudioMixMatchCriterion {
         @UnsupportedAppUsage
         final AudioAttributes mAttr;
         @UnsupportedAppUsage
@@ -137,6 +140,10 @@
                 dest.writeInt(-1);
             }
         }
+
+        public AudioAttributes getAudioAttributes() { return mAttr; }
+        public int getIntProp() { return mIntProp; }
+        public int getRule() { return mRule; }
     }
 
     boolean isAffectingUsage(int usage) {
@@ -163,7 +170,8 @@
     int getTargetMixType() { return mTargetMixType; }
     @UnsupportedAppUsage
     private final ArrayList<AudioMixMatchCriterion> mCriteria;
-    ArrayList<AudioMixMatchCriterion> getCriteria() { return mCriteria; }
+    /** @hide */
+    public ArrayList<AudioMixMatchCriterion> getCriteria() { return mCriteria; }
     @UnsupportedAppUsage
     private boolean mAllowPrivilegedPlaybackCapture = false;
 
diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java
index 00f6013..1cd60f7 100644
--- a/media/java/android/media/audiopolicy/AudioPolicy.java
+++ b/media/java/android/media/audiopolicy/AudioPolicy.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.app.ActivityManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -55,6 +56,7 @@
  * @hide
  * AudioPolicy provides access to the management of audio routing and audio focus.
  */
+@TestApi
 @SystemApi
 public class AudioPolicy {
 
@@ -237,6 +239,7 @@
         }
 
         /**
+         * @hide
          * Test method to declare whether this audio focus policy is for test purposes only.
          * Having a test policy registered will disable the current focus policy and replace it
          * with this test policy. When unregistered, the previous focus policy will be restored.
@@ -245,6 +248,7 @@
          * @param isTestFocusPolicy true if the focus policy to register is for testing purposes.
          * @return the same Builder instance
          */
+        @TestApi
         @NonNull
         public Builder setIsTestFocusPolicy(boolean isTestFocusPolicy) {
             mIsTestFocusPolicy = isTestFocusPolicy;
diff --git a/media/java/android/media/audiopolicy/AudioProductStrategies.aidl b/media/java/android/media/audiopolicy/AudioProductStrategies.aidl
deleted file mode 100644
index bec11bc..0000000
--- a/media/java/android/media/audiopolicy/AudioProductStrategies.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 2018, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.media.audiopolicy;
-
-parcelable AudioProductStrategies;
diff --git a/media/java/android/media/audiopolicy/AudioProductStrategies.java b/media/java/android/media/audiopolicy/AudioProductStrategies.java
deleted file mode 100644
index c305b68..0000000
--- a/media/java/android/media/audiopolicy/AudioProductStrategies.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.audiopolicy;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.media.AudioAttributes;
-import android.media.AudioSystem;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * @hide
- * A class to encapsulate a collection of {@link AudioProductStrategy}.
- * Provides helper functions to easily retrieve the {@link AudioAttributes} for a given product
- * strategy or legacy stream type.
- */
-@SystemApi
-public final class AudioProductStrategies implements Iterable<AudioProductStrategy>, Parcelable {
-
-    private final ArrayList<AudioProductStrategy> mAudioProductStrategyList;
-
-    private static final String TAG = "AudioProductStrategies";
-
-    public AudioProductStrategies() {
-        ArrayList<AudioProductStrategy> apsList = new ArrayList<AudioProductStrategy>();
-        int status = native_list_audio_product_strategies(apsList);
-        if (status != AudioSystem.SUCCESS) {
-            Log.w(TAG, ": createAudioProductStrategies failed");
-        }
-        mAudioProductStrategyList = apsList;
-    }
-
-    private AudioProductStrategies(ArrayList<AudioProductStrategy> audioProductStrategy) {
-        mAudioProductStrategyList = audioProductStrategy;
-    }
-
-    /**
-     * @hide
-     * @return number of {@link AudioProductStrategy} objects
-     */
-    @SystemApi
-    public int size() {
-        return mAudioProductStrategyList.size();
-    }
-
-    /**
-     * @hide
-     * @return the matching {@link AudioProductStrategy} objects with the given id,
-     *         null object if not found.
-     */
-    @SystemApi
-    public @Nullable AudioProductStrategy getById(int productStrategyId) {
-        for (final AudioProductStrategy avg : this) {
-            if (avg.getId() == productStrategyId) {
-                return avg;
-            }
-        }
-        Log.e(TAG, ": invalid product strategy id: " + productStrategyId + " requested");
-        return null;
-    }
-
-    /**
-     * Returns an {@link Iterator}
-     */
-    @Override
-    public @NonNull Iterator<AudioProductStrategy> iterator() {
-        return mAudioProductStrategyList.iterator();
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        AudioProductStrategies that = (AudioProductStrategies) o;
-
-        return mAudioProductStrategyList.equals(that.mAudioProductStrategyList);
-    }
-
-    /**
-     * @hide
-     * @param aps {@link AudioProductStrategy} (which is the generalisation of Car Audio Usage /
-     *                        legacy routing_strategy linked to {@link AudioAttributes#getUsage()} )
-     * @return the {@link AudioAttributes} relevant for the given product strategy.
-     *         If none is found, it builds the default attributes.
-     *         TODO: shall the helper collection be able to identify the platform default?
-     */
-    @SystemApi
-    @NonNull
-    public AudioAttributes getAudioAttributesForProductStrategy(@NonNull AudioProductStrategy aps) {
-        Preconditions.checkNotNull(aps, "AudioProductStrategy must not be null");
-        for (final AudioProductStrategy audioProductStrategy : this) {
-            if (audioProductStrategy.equals(aps)) {
-                return audioProductStrategy.getAudioAttributes();
-            }
-        }
-        return new AudioAttributes.Builder()
-                                  .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
-                                  .setUsage(AudioAttributes.USAGE_UNKNOWN).build();
-    }
-
-    /**
-     * @hide
-     * @param streamType legacy stream type used for volume operation only
-     * @return the {@link AudioAttributes} relevant for the given streamType.
-     *         If none is found, it builds the default attributes.
-     */
-    @SystemApi
-    public @NonNull AudioAttributes getAudioAttributesForLegacyStreamType(int streamType) {
-        for (final AudioProductStrategy productStrategy : this) {
-            AudioAttributes aa = productStrategy.getAudioAttributesForLegacyStreamType(streamType);
-            if (aa != null) {
-                return aa;
-            }
-        }
-        return new AudioAttributes.Builder()
-                                  .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
-                                  .setUsage(AudioAttributes.USAGE_UNKNOWN).build();
-    }
-
-    /**
-     * @hide
-     * @param aa the {@link AudioAttributes} for which stream type is requested
-     * @return the legacy stream type relevant for the given {@link AudioAttributes}.
-     *         If the product strategy is not associated to any stream, it returns
-     *         {@link AudioSystem#STREAM_MUSIC}.
-     *         If no product strategy supports the stream type, it returns
-     *         {@link AudioSystem#STREAM_MUSIC}.
-     */
-    @SystemApi
-    public int getLegacyStreamTypeForAudioAttributes(@NonNull AudioAttributes aa) {
-        Preconditions.checkNotNull(aa, "AudioAttributes must not be null");
-        for (final AudioProductStrategy productStrategy : this) {
-            if (productStrategy.supportsAudioAttributes(aa)) {
-                int streamType = productStrategy.getLegacyStreamTypeForAudioAttributes(aa);
-                if (streamType == AudioSystem.STREAM_DEFAULT) {
-                    Log.w(TAG, "Attributes " + aa.toString() + " ported by strategy "
-                            + productStrategy.name() + " has no stream type associated, "
-                            + "DO NOT USE STREAM TO CONTROL THE VOLUME");
-                    return AudioSystem.STREAM_MUSIC;
-                }
-                return streamType;
-            }
-        }
-        return AudioSystem.STREAM_MUSIC;
-    }
-
-    /**
-     * @hide
-     * @param aa the {@link AudioAttributes} to be considered
-     * @return {@link AudioProductStrategy} supporting the given {@link AudioAttributes}.
-     *         null is returned if no match with given attributes.
-     */
-    @SystemApi
-    @Nullable
-    public AudioProductStrategy getProductStrategyForAudioAttributes(@NonNull AudioAttributes aa) {
-        Preconditions.checkNotNull(aa, "attributes must not be null");
-        int productStrategyId =  native_get_product_strategies_from_audio_attributes(aa);
-        if (productStrategyId < 0) {
-            Log.w(TAG, "no strategy found for Attributes " + aa.toString());
-            return null;
-        }
-        return getById(productStrategyId);
-    }
-
-   /**
-    * @hide
-    * @param attributes the {@link AudioAttributes} to be considered
-    * @return volume group associated to the given {@link AudioAttributes}.
-    *         If no group supports the given {@link AudioAttributes}, it returns the volume group
-    *         for the default attributes.
-    *         If no group supports the default attributes, it returns {@link #DEFAULT_VOLUME_GROUP}
-    */
-    @SystemApi
-    public int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) {
-        Preconditions.checkNotNull(attributes, "attributes must not be null");
-        int volumeGroupId = getVolumeGroupIdForAttributesInt(attributes);
-        if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
-            return volumeGroupId;
-        }
-        // The default volume group is the one hosted by default product strategy, i.e.
-        // supporting Default Attributes
-        return getVolumeGroupIdForAttributesInt(AudioProductStrategy.sDefaultAttributes);
-    }
-
-   /**
-    * @hide
-    * @param streamType to be considered
-    * @return volume group associated to the given stream type.
-    */
-    @SystemApi
-    public int getVolumeGroupIdForLegacyStreamType(int streamType) {
-        for (final AudioProductStrategy productStrategy : this) {
-            int volumeGroupId = productStrategy.getVolumeGroupIdForLegacyStreamType(streamType);
-            if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
-                return volumeGroupId;
-            }
-        }
-        // The default volume group is the one hosted by default product strategy, i.e.
-        // supporting Default Attributes
-        return getVolumeGroupIdForAttributesInt(AudioProductStrategy.sDefaultAttributes);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(size());
-        for (final AudioProductStrategy productStrategy : this) {
-            productStrategy.writeToParcel(dest, flags);
-        }
-    }
-
-    /**
-     * @param attributes to be considered
-     * @return volume group associated to the given {@link AudioAttributes}.
-     */
-    private int getVolumeGroupIdForAttributesInt(@NonNull AudioAttributes attributes) {
-        Preconditions.checkNotNull(attributes, "attributes must not be null");
-        for (final AudioProductStrategy productStrategy : this) {
-            int volumeGroupId = productStrategy.getVolumeGroupIdForAudioAttributes(attributes);
-            if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
-                return volumeGroupId;
-            }
-        }
-        return AudioVolumeGroups.DEFAULT_VOLUME_GROUP;
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<AudioProductStrategies> CREATOR =
-            new Parcelable.Creator<AudioProductStrategies>() {
-                @Override
-                public AudioProductStrategies createFromParcel(@NonNull Parcel in) {
-                    ArrayList<AudioProductStrategy> apsList = new ArrayList<AudioProductStrategy>();
-                    int size = in.readInt();
-                    for (int index = 0; index < size; index++) {
-                        apsList.add(AudioProductStrategy.CREATOR.createFromParcel(in));
-                    }
-                    return new AudioProductStrategies(apsList);
-                }
-
-                @Override
-                public @NonNull AudioProductStrategies[] newArray(int size) {
-                    return new AudioProductStrategies[size];
-                }
-            };
-
-    private static native int native_list_audio_product_strategies(
-            ArrayList<AudioProductStrategy> strategies);
-
-    private static native int native_get_product_strategies_from_audio_attributes(
-            AudioAttributes attributes);
-}
diff --git a/media/java/android/media/audiopolicy/AudioProductStrategy.java b/media/java/android/media/audiopolicy/AudioProductStrategy.java
index c1c255f..9ac9411 100644
--- a/media/java/android/media/audiopolicy/AudioProductStrategy.java
+++ b/media/java/android/media/audiopolicy/AudioProductStrategy.java
@@ -25,9 +25,14 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
+import android.util.Log;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * @hide
  * A class to encapsulate a collection of attributes associated to a given product strategy
@@ -41,6 +46,9 @@
      */
     public static final int DEFAULT_GROUP = -1;
 
+
+    private static final String TAG = "AudioProductStrategy";
+
     private final AudioAttributesGroup[] mAudioAttributesGroups;
     private final String mName;
     /**
@@ -51,6 +59,86 @@
      */
     private int mId;
 
+    private static final Object sLock = new Object();
+
+    @GuardedBy("sLock")
+    private static List<AudioProductStrategy> sAudioProductStrategies;
+
+    /**
+     * @hide
+     * @return the list of AudioProductStrategy discovered from platform configuration file.
+     */
+    @NonNull
+    public static List<AudioProductStrategy> getAudioProductStrategies() {
+        if (sAudioProductStrategies == null) {
+            synchronized (sLock) {
+                if (sAudioProductStrategies == null) {
+                    sAudioProductStrategies = initializeAudioProductStrategies();
+                }
+            }
+        }
+        return sAudioProductStrategies;
+    }
+
+    /**
+     * @hide
+     * @param streamType to match against AudioProductStrategy
+     * @return the AudioAttributes for the first strategy found with the associated stream type
+     *          If no match is found, returns AudioAttributes with unknown content_type and usage
+     */
+    @NonNull
+    public static AudioAttributes getAudioAttributesForStrategyWithLegacyStreamType(
+            int streamType) {
+        for (final AudioProductStrategy productStrategy :
+                AudioProductStrategy.getAudioProductStrategies()) {
+            AudioAttributes aa = productStrategy.getAudioAttributesForLegacyStreamType(streamType);
+            if (aa != null) {
+                return aa;
+            }
+        }
+        return new AudioAttributes.Builder()
+            .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
+            .setUsage(AudioAttributes.USAGE_UNKNOWN).build();
+    }
+
+    /**
+     * @hide
+     * @param audioAttributes to identify AudioProductStrategy with
+     * @return legacy stream type associated with matched AudioProductStrategy
+     *              Defaults to STREAM_MUSIC if no match is found, or if matches is STREAM_DEFAULT
+     */
+    public static int getLegacyStreamTypeForStrategyWithAudioAttributes(
+            @NonNull AudioAttributes audioAttributes) {
+        Preconditions.checkNotNull(audioAttributes, "AudioAttributes must not be null");
+        for (final AudioProductStrategy productStrategy :
+                AudioProductStrategy.getAudioProductStrategies()) {
+            if (productStrategy.supportsAudioAttributes(audioAttributes)) {
+                int streamType = productStrategy.getLegacyStreamTypeForAudioAttributes(
+                        audioAttributes);
+                if (streamType == AudioSystem.STREAM_DEFAULT) {
+                    Log.w(TAG, "Attributes " + audioAttributes.toString() + " ported by strategy "
+                            + productStrategy.getId() + " has no stream type associated, "
+                            + "DO NOT USE STREAM TO CONTROL THE VOLUME");
+                    return AudioSystem.STREAM_MUSIC;
+                }
+                return streamType;
+            }
+        }
+        return AudioSystem.STREAM_MUSIC;
+    }
+
+    private static List<AudioProductStrategy> initializeAudioProductStrategies() {
+        ArrayList<AudioProductStrategy> apsList = new ArrayList<AudioProductStrategy>();
+        int status = native_list_audio_product_strategies(apsList);
+        if (status != AudioSystem.SUCCESS) {
+            Log.w(TAG, ": initializeAudioProductStrategies failed");
+        }
+        return apsList;
+    }
+
+    private static native int native_list_audio_product_strategies(
+            ArrayList<AudioProductStrategy> strategies);
+
     @Override
     public boolean equals(@Nullable Object o) {
         if (this == o) return true;
@@ -65,8 +153,7 @@
     /**
      * @param name of the product strategy
      * @param id of the product strategy
-     * @param audioAttributes {@link AudioAttributes} associated to the given product strategy
-     * @param legacyStreamTypes associated to the given product strategy.
+     * @param aag {@link AudioAttributesGroup} associated to the given product strategy
      */
     private AudioProductStrategy(@NonNull String name, int id,
             @NonNull AudioAttributesGroup[] aag) {
@@ -79,15 +166,6 @@
 
     /**
      * @hide
-     * @return human-readable name of this product strategy, which is similar to a usage
-     */
-    @SystemApi
-    public @NonNull String name() {
-        return mName;
-    }
-
-    /**
-     * @hide
      * @return the product strategy ID (which is the generalisation of Car Audio Usage / legacy
      *         routing_strategy linked to {@link AudioAttributes#getUsage()}).
      */
@@ -158,7 +236,7 @@
      * @hide
      * @param streamType legacy stream type used for volume operation only
      * @return the volume group id relevant for the given streamType.
-     *         If none is found, {@link AudioVolumeGroups#DEFAULT_VOLUME_GROUP} is returned.
+     *         If none is found, {@link AudioVolumeGroup#DEFAULT_VOLUME_GROUP} is returned.
      */
     public int getVolumeGroupIdForLegacyStreamType(int streamType) {
         for (final AudioAttributesGroup aag : mAudioAttributesGroups) {
@@ -166,14 +244,14 @@
                 return aag.getVolumeGroupId();
             }
         }
-        return AudioVolumeGroups.DEFAULT_VOLUME_GROUP;
+        return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
     }
 
     /**
      * @hide
      * @param aa the {@link AudioAttributes} to be considered
      * @return the volume group id associated with the given audio attributes if found,
-     *         {@link AudioVolumeGroups#DEFAULT_VOLUME_GROUP} otherwise.
+     *         {@link AudioVolumeGroup#DEFAULT_VOLUME_GROUP} otherwise.
      */
     public int getVolumeGroupIdForAudioAttributes(@NonNull AudioAttributes aa) {
         Preconditions.checkNotNull(aa, "AudioAttributes must not be null");
@@ -182,7 +260,7 @@
                 return aag.getVolumeGroupId();
             }
         }
-        return AudioVolumeGroups.DEFAULT_VOLUME_GROUP;
+        return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
     }
 
     @Override
@@ -200,7 +278,8 @@
         }
     }
 
-    public static final @android.annotation.NonNull Parcelable.Creator<AudioProductStrategy> CREATOR =
+    @NonNull
+    public static final Parcelable.Creator<AudioProductStrategy> CREATOR =
             new Parcelable.Creator<AudioProductStrategy>() {
                 @Override
                 public AudioProductStrategy createFromParcel(@NonNull Parcel in) {
diff --git a/media/java/android/media/audiopolicy/AudioVolumeGroup.java b/media/java/android/media/audiopolicy/AudioVolumeGroup.java
index b60947f..79be922 100644
--- a/media/java/android/media/audiopolicy/AudioVolumeGroup.java
+++ b/media/java/android/media/audiopolicy/AudioVolumeGroup.java
@@ -19,11 +19,15 @@
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.media.AudioAttributes;
+import android.media.AudioSystem;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.Log;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -34,6 +38,12 @@
  */
 @SystemApi
 public final class AudioVolumeGroup implements Parcelable {
+    private static final String TAG = "AudioVolumeGroup";
+    /**
+     * Volume group value to use when introspection API fails.
+     */
+    public static final int DEFAULT_VOLUME_GROUP = -1;
+
     /**
      * Unique identifier of a volume group.
      */
@@ -46,10 +56,43 @@
     private final AudioAttributes[] mAudioAttributes;
     private int[] mLegacyStreamTypes;
 
+    private static final Object sLock = new Object();
+
+    @GuardedBy("sLock")
+    private static List<AudioVolumeGroup> sAudioVolumeGroups;
+
+    /**
+     * @hide
+     * @return the List of AudioVolumeGroup discovered from platform configuration file.
+     */
+    @NonNull
+    public static List<AudioVolumeGroup> getAudioVolumeGroups() {
+        if (sAudioVolumeGroups == null) {
+            synchronized (sLock) {
+                if (sAudioVolumeGroups == null) {
+                    sAudioVolumeGroups = initializeAudioVolumeGroups();
+                }
+            }
+        }
+        return sAudioVolumeGroups;
+    }
+
+    private static List<AudioVolumeGroup> initializeAudioVolumeGroups() {
+        ArrayList<AudioVolumeGroup> avgList = new ArrayList<>();
+        int status = native_list_audio_volume_groups(avgList);
+        if (status != AudioSystem.SUCCESS) {
+            Log.w(TAG, ": listAudioVolumeGroups failed");
+        }
+        return avgList;
+    }
+
+    private static native int native_list_audio_volume_groups(
+            ArrayList<AudioVolumeGroup> groups);
+
     /**
      * @param name of the volume group
      * @param id of the volume group
-     * @param followers {@link AudioProductStrategies} strategy following this volume group
+     * @param legacyStreamTypes of volume group
      */
     AudioVolumeGroup(@NonNull String name, int id,
                      @NonNull AudioAttributes[] audioAttributes,
diff --git a/media/java/android/media/audiopolicy/AudioVolumeGroups.aidl b/media/java/android/media/audiopolicy/AudioVolumeGroups.aidl
deleted file mode 100644
index 918cac3..0000000
--- a/media/java/android/media/audiopolicy/AudioVolumeGroups.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 2018, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.media.audiopolicy;
-
-parcelable AudioVolumeGroups;
diff --git a/media/java/android/media/audiopolicy/AudioVolumeGroups.java b/media/java/android/media/audiopolicy/AudioVolumeGroups.java
deleted file mode 100644
index 2e56f84..0000000
--- a/media/java/android/media/audiopolicy/AudioVolumeGroups.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.audiopolicy;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.media.AudioSystem;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * @hide
- * A class to encapsulate a collection of {@link AudioVolumeGroup}.
- */
-@SystemApi
-public final class AudioVolumeGroups implements Iterable<AudioVolumeGroup>, Parcelable {
-
-    private final ArrayList<AudioVolumeGroup> mAudioVolumeGroupList;
-
-    private static final String TAG = "AudioVolumeGroups";
-
-    /**
-     * Volume group value to use when introspection API fails.
-     */
-    public static final int DEFAULT_VOLUME_GROUP = -1;
-
-    public AudioVolumeGroups() {
-        ArrayList<AudioVolumeGroup> avgList = new ArrayList<AudioVolumeGroup>();
-        int status = native_list_audio_volume_groups(avgList);
-        if (status != AudioSystem.SUCCESS) {
-            Log.w(TAG, ": listAudioVolumeGroups failed");
-        }
-        mAudioVolumeGroupList = avgList;
-    }
-
-    private AudioVolumeGroups(@NonNull ArrayList<AudioVolumeGroup> audioVolumeGroupList) {
-        Preconditions.checkNotNull(audioVolumeGroupList, "audioVolumeGroupList must not be null");
-        mAudioVolumeGroupList = audioVolumeGroupList;
-    }
-
-    /**
-     * @return number of {@link AudioProductStrategy} objects
-     */
-    public int size() {
-        return mAudioVolumeGroupList.size();
-    }
-
-    /**
-     * Returns an {@link Iterator}
-     */
-    @Override
-    public @NonNull Iterator<AudioVolumeGroup> iterator() {
-        return mAudioVolumeGroupList.iterator();
-    }
-
-    @Override
-    public boolean equals(@NonNull Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        AudioVolumeGroups that = (AudioVolumeGroups) o;
-
-        return mAudioVolumeGroupList.equals(that.mAudioVolumeGroupList);
-    }
-
-    /**
-     * @return the matching {@link AudioVolumeGroup} objects with the given id,
-     *         null object if not found.
-     */
-    public @Nullable AudioVolumeGroup getById(int volumeGroupId) {
-        for (final AudioVolumeGroup avg : this) {
-            if (avg.getId() == volumeGroupId) {
-                return avg;
-            }
-        }
-        Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested");
-        return null;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(size());
-        for (final AudioVolumeGroup volumeGroup : this) {
-            volumeGroup.writeToParcel(dest, flags);
-        }
-    }
-
-    private static native int native_list_audio_volume_groups(
-            ArrayList<AudioVolumeGroup> groups);
-
-    public static final Parcelable.Creator<AudioVolumeGroups> CREATOR =
-            new Parcelable.Creator<AudioVolumeGroups>() {
-                @Override
-                public @NonNull AudioVolumeGroups createFromParcel(@NonNull Parcel in) {
-                    Preconditions.checkNotNull(in, "in Parcel must not be null");
-                    ArrayList<AudioVolumeGroup> avgList = new ArrayList<AudioVolumeGroup>();
-                    int size = in.readInt();
-                    for (int index = 0; index < size; index++) {
-                        avgList.add(AudioVolumeGroup.CREATOR.createFromParcel(in));
-                    }
-                    return new AudioVolumeGroups(avgList);
-                }
-
-                @Override
-                public @NonNull AudioVolumeGroups[] newArray(int size) {
-                    return new AudioVolumeGroups[size];
-                }
-            };
-}
diff --git a/media/tests/MediaRouteProvider/Android.bp b/media/tests/MediaRouteProvider/Android.bp
deleted file mode 100644
index da42824..0000000
--- a/media/tests/MediaRouteProvider/Android.bp
+++ /dev/null
@@ -1,18 +0,0 @@
-android_test {
-    name: "mediarouteprovider",
-
-    srcs: ["**/*.java"],
-
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-    ],
-
-    static_libs: [
-        "android-support-test",
-        "mockito-target-minus-junit4",
-    ],
-
-    platform_apis: true,
-    certificate: "platform",
-}
\ No newline at end of file
diff --git a/media/tests/MediaRouteProvider/AndroidManifest.xml b/media/tests/MediaRouteProvider/AndroidManifest.xml
deleted file mode 100644
index 489a621..0000000
--- a/media/tests/MediaRouteProvider/AndroidManifest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2019 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.mediarouteprovider.example">
-
-    <application android:label="@string/app_name">
-        <uses-library android:name="android.test.runner" />
-        <service android:name=".SampleMediaRoute2ProviderService"
-            android:label="@string/app_name"
-            android:exported="true">
-            <intent-filter>
-                <action android:name="android.media.MediaRoute2ProviderService" />
-            </intent-filter>
-       </service>
-    </application>
-</manifest>
diff --git a/media/tests/MediaRouteProvider/res/values/strings.xml b/media/tests/MediaRouteProvider/res/values/strings.xml
deleted file mode 100644
index bb97064..0000000
--- a/media/tests/MediaRouteProvider/res/values/strings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <!-- name of the app [CHAR LIMIT=25]-->
-    <string name="app_name">SampleMediaRouteProvider</string>
-</resources>
\ No newline at end of file
diff --git a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
deleted file mode 100644
index 22fbd85..0000000
--- a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mediarouteprovider.example;
-
-import android.content.Intent;
-import android.media.MediaRoute2ProviderService;
-import android.os.IBinder;
-
-public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService {
-    @Override
-    public IBinder onBind(Intent intent) {
-        return super.onBind(intent);
-    }
-
-    @Override
-    public void onSelect(int uid, String routeId) {
-        updateProvider(uid, routeId);
-    }
-}
diff --git a/media/tests/MediaRouter/Android.bp b/media/tests/MediaRouter/Android.bp
deleted file mode 100644
index 611b25a..0000000
--- a/media/tests/MediaRouter/Android.bp
+++ /dev/null
@@ -1,18 +0,0 @@
-android_test {
-    name: "mediaroutertest",
-
-    srcs: ["**/*.java"],
-
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-    ],
-
-    static_libs: [
-        "android-support-test",
-        "mockito-target-minus-junit4",
-    ],
-
-    platform_apis: true,
-    certificate: "platform",
-}
\ No newline at end of file
diff --git a/media/tests/MediaRouter/AndroidManifest.xml b/media/tests/MediaRouter/AndroidManifest.xml
deleted file mode 100644
index a34a264..0000000
--- a/media/tests/MediaRouter/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2019 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.mediaroutertest">
-
-    <uses-permission android:name="android.permission.CONTROL_MEDIA_ROUTE" />
-
-    <application android:label="@string/app_name">
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.mediaroutertest"
-                     android:label="MediaRouter Tests"/>
-</manifest>
diff --git a/media/tests/MediaRouter/AndroidTest.xml b/media/tests/MediaRouter/AndroidTest.xml
deleted file mode 100644
index 1301062..0000000
--- a/media/tests/MediaRouter/AndroidTest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<configuration description="Runs sample instrumentation test.">
-    <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
-    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
-        <option name="test-file-name" value="mediaroutertest.apk"/>
-    </target_preparer>
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
-    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
-    <option name="test-suite-tag" value="apct"/>
-    <option name="test-tag" value="MediaRouterTest"/>
-
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest">
-        <option name="package" value="com.android.mediaroutertest"/>
-        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
-        <option name="hidden-api-checks" value="false"/>
-    </test>
-</configuration>
diff --git a/media/tests/MediaRouter/res/values/strings.xml b/media/tests/MediaRouter/res/values/strings.xml
deleted file mode 100644
index 0737020..0000000
--- a/media/tests/MediaRouter/res/values/strings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <!-- name of the app [CHAR LIMIT=25]-->
-    <string name="app_name">mediaRouterTest</string>
-</resources>
\ No newline at end of file
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
deleted file mode 100644
index a4bde65..0000000
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mediaroutertest;
-
-import static org.mockito.Mockito.after;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.media.MediaRouter;
-import android.media.MediaRouter2Manager;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class MediaRouterManagerTest {
-    private static final String TAG = "MediaRouterManagerTest";
-
-    private static final int TARGET_UID = 109992;
-    private static final String ROUTE_1 = "MediaRoute1";
-
-    private static final int AWAIT_MS = 1000;
-    private static final int TIMEOUT_MS = 1000;
-
-    private Context mContext;
-    private MediaRouter2Manager mManager;
-    private MediaRouter mRouter;
-    private Executor mExecutor;
-
-    private static final List<String> TEST_CONTROL_CATEGORIES = new ArrayList();
-    private static final String CONTROL_CATEGORY_1 = "android.media.mediarouter.MEDIA1";
-    private static final String CONTROL_CATEGORY_2 = "android.media.mediarouter.MEDIA2";
-    static {
-        TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_1);
-        TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_2);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getTargetContext();
-        mManager = MediaRouter2Manager.getInstance(mContext);
-        mRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
-        mExecutor = new ThreadPoolExecutor(
-            1, 20, 3, TimeUnit.SECONDS,
-            new SynchronousQueue<Runnable>());
-    }
-
-    @Test
-    public void transferTest() throws Exception {
-        MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
-
-        mManager.addCallback(mExecutor, mockCallback);
-
-        verify(mockCallback, after(AWAIT_MS).never())
-            .onRouteSelected(eq(TARGET_UID), any(String.class));
-
-        mManager.selectRoute(TARGET_UID, ROUTE_1);
-        verify(mockCallback, timeout(TIMEOUT_MS)).onRouteSelected(TARGET_UID, ROUTE_1);
-
-        mManager.removeCallback(mockCallback);
-    }
-
-    @Test
-    public void controlCategoryTest() throws Exception {
-        final int uid = android.os.Process.myUid();
-
-        MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
-        mManager.addCallback(mExecutor, mockCallback);
-
-        verify(mockCallback, after(AWAIT_MS).never()).onControlCategoriesChanged(eq(uid),
-                any(List.class));
-
-        mRouter.setControlCategories(TEST_CONTROL_CATEGORIES);
-        verify(mockCallback, timeout(TIMEOUT_MS).atLeastOnce())
-            .onControlCategoriesChanged(uid, TEST_CONTROL_CATEGORIES);
-
-        mManager.removeCallback(mockCallback);
-    }
-
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 44e8874..efebfc2 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.car;
 
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.car.drivingstate.CarDrivingStateEvent;
@@ -39,6 +40,7 @@
 import com.android.car.notification.NotificationClickHandlerFactory;
 import com.android.car.notification.NotificationViewController;
 import com.android.car.notification.PreprocessingManager;
+import com.android.internal.statusbar.RegisterStatusBarResult;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.CarSystemUIFactory;
@@ -259,8 +261,8 @@
 
 
     @Override
-    protected void makeStatusBarView() {
-        super.makeStatusBarView();
+    protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
+        super.makeStatusBarView(result);
         mHvacController = new HvacController(mContext);
 
         CarSystemUIFactory factory = SystemUIFactory.getInstance();
@@ -432,7 +434,7 @@
     }
 
     @Override
-    protected void createNavigationBar() {
+    protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
         mShowBottom = mContext.getResources().getBoolean(R.bool.config_enableBottomNavigationBar);
         mShowLeft = mContext.getResources().getBoolean(R.bool.config_enableLeftNavigationBar);
         mShowRight = mContext.getResources().getBoolean(R.bool.config_enableRightNavigationBar);
@@ -443,7 +445,7 @@
 
         // There has been a car customized nav bar on the default display, so just create nav bars
         // on external displays.
-        mNavigationBarController.createNavigationBars(false /* includeDefaultDisplay */);
+        mNavigationBarController.createNavigationBars(false /* includeDefaultDisplay */, result);
     }
 
     private void buildNavBarContent() {
diff --git a/packages/PackageInstaller/TEST_MAPPING b/packages/PackageInstaller/TEST_MAPPING
new file mode 100644
index 0000000..42aa47c
--- /dev/null
+++ b/packages/PackageInstaller/TEST_MAPPING
@@ -0,0 +1,24 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsPackageInstallTestCases",
+      "options": [
+        {
+          "exclude-annotation": "android.platform.test.annotations.AppModeInstant"
+        }
+      ]
+    },
+    {
+      "name": "CtsNoPermissionTestCases"
+    },
+    {
+      "name": "CtsNoPermissionTestCases25"
+    },
+    {
+      "name": "CtsPackageInstallerTapjackingTestCases"
+    },
+    {
+      "name": "CtsPackageUninstallTestCases"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
index cee4666..93f24f7 100755
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
@@ -83,28 +83,6 @@
         ApplicationInfo appInfo = getIntent()
                 .getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
         mPackageURI = getIntent().getData();
-        final File sourceFile = new File(mPackageURI.getPath());
-        PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(this, appInfo, sourceFile);
-
-        mAlert.setIcon(as.icon);
-        mAlert.setTitle(as.label);
-        mAlert.setView(R.layout.install_content_view);
-        mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.cancel),
-                (ignored, ignored2) -> {
-                    if (mInstallingTask != null) {
-                        mInstallingTask.cancel(true);
-                    }
-
-                    if (mSessionId > 0) {
-                        getPackageManager().getPackageInstaller().abandonSession(mSessionId);
-                        mSessionId = 0;
-                    }
-
-                    setResult(RESULT_CANCELED);
-                    finish();
-                }, null);
-        setupAlert();
-        requireViewById(R.id.installing).setVisibility(View.VISIBLE);
 
         if ("package".equals(mPackageURI.getScheme())) {
             try {
@@ -114,6 +92,29 @@
                 launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null);
             }
         } else {
+            final File sourceFile = new File(mPackageURI.getPath());
+            PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(this, appInfo, sourceFile);
+
+            mAlert.setIcon(as.icon);
+            mAlert.setTitle(as.label);
+            mAlert.setView(R.layout.install_content_view);
+            mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.cancel),
+                    (ignored, ignored2) -> {
+                        if (mInstallingTask != null) {
+                            mInstallingTask.cancel(true);
+                        }
+
+                        if (mSessionId > 0) {
+                            getPackageManager().getPackageInstaller().abandonSession(mSessionId);
+                            mSessionId = 0;
+                        }
+
+                        setResult(RESULT_CANCELED);
+                        finish();
+                    }, null);
+            setupAlert();
+            requireViewById(R.id.installing).setVisibility(View.VISIBLE);
+
             if (savedInstanceState != null) {
                 mSessionId = savedInstanceState.getInt(SESSION_ID);
                 mInstallId = savedInstanceState.getInt(INSTALL_ID);
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index f2de9ec..881f4b1 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -109,8 +109,8 @@
         } else {
             Uri packageUri = intent.getData();
 
-            if (packageUri != null && (packageUri.getScheme().equals(ContentResolver.SCHEME_FILE)
-                    || packageUri.getScheme().equals(ContentResolver.SCHEME_CONTENT))) {
+            if (packageUri != null && packageUri.getScheme().equals(
+                    ContentResolver.SCHEME_CONTENT)) {
                 // [IMPORTANT] This path is deprecated, but should still work. Only necessary
                 // features should be added.
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
index 239b1d4..eff02d2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
@@ -173,6 +173,7 @@
     }
 
     override fun draw(c: Canvas) {
+        c.saveLayer(null, null)
         unifiedPath.reset()
         levelPath.reset()
         levelRect.set(fillRect)
@@ -243,6 +244,7 @@
             // And draw the plus sign on top of the fill
             c.drawPath(scaledPlus, errorPaint)
         }
+        c.restore()
     }
 
     private fun batteryColorForLevel(level: Int): Int {
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
deleted file mode 100644
index 4c45a75..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.settingslib.users;
-
-import android.app.ActivityManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.UserInfo;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
-
-import com.android.internal.util.UserIcons;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Helper class for managing users, providing methods for removing, adding and switching users.
- *
- * @deprecated - Do not use
- */
-@Deprecated
-public final class UserManagerHelper {
-    private static final String TAG = "UserManagerHelper";
-    private static final String HEADLESS_SYSTEM_USER = "android.car.systemuser.headless";
-    private final Context mContext;
-    private final UserManager mUserManager;
-    private final ActivityManager mActivityManager;
-    private OnUsersUpdateListener mUpdateListener;
-    private final BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            mUpdateListener.onUsersUpdate();
-        }
-    };
-
-    public UserManagerHelper(Context context) {
-        mContext = context;
-        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
-    }
-
-    /**
-     * Registers a listener for updates to all users - removing, adding users or changing user info.
-     *
-     * @param listener Instance of {@link OnUsersUpdateListener}.
-     */
-    public void registerOnUsersUpdateListener(OnUsersUpdateListener listener) {
-        mUpdateListener = listener;
-        registerReceiver();
-    }
-
-    /**
-     * Unregisters listener by unregistering {@code BroadcastReceiver}.
-     */
-    public void unregisterOnUsersUpdateListener() {
-        unregisterReceiver();
-    }
-
-    /**
-     * Returns {@code true} if the system is in the headless user 0 model.
-     *
-     * @return {@boolean true} if headless system user.
-     */
-    public boolean isHeadlessSystemUser() {
-        return SystemProperties.getBoolean(HEADLESS_SYSTEM_USER, false);
-    }
-
-    /**
-     * Gets UserInfo for the foreground user.
-     *
-     * Concept of foreground user is relevant for the multi-user deployment. Foreground user
-     * corresponds to the currently "logged in" user.
-     *
-     * @return {@link UserInfo} for the foreground user.
-     */
-    public UserInfo getForegroundUserInfo() {
-        return mUserManager.getUserInfo(getForegroundUserId());
-    }
-
-    /**
-     * @return Id of the foreground user.
-     */
-    public int getForegroundUserId() {
-        return mActivityManager.getCurrentUser();
-    }
-
-    /**
-     * Gets UserInfo for the user running the caller process.
-     *
-     * Differentiation between foreground user and current process user is relevant for multi-user
-     * deployments.
-     *
-     * Some multi-user aware components (like SystemUI) might run as a singleton - one component
-     * for all users. Current process user is then always the same for that component, even when
-     * the foreground user changes.
-     *
-     * @return {@link UserInfo} for the user running the current process.
-     */
-    public UserInfo getCurrentProcessUserInfo() {
-        return mUserManager.getUserInfo(getCurrentProcessUserId());
-    }
-
-    /**
-     * @return Id for the user running the current process.
-     */
-    public int getCurrentProcessUserId() {
-        return UserHandle.myUserId();
-    }
-
-    /**
-     * Gets all the other users on the system that are not the user running the current process.
-     *
-     * @return List of {@code UserInfo} for each user that is not the user running the process.
-     */
-    public List<UserInfo> getAllUsersExcludesCurrentProcessUser() {
-        return getAllUsersExceptUser(getCurrentProcessUserId());
-    }
-
-    /**
-     * Gets all the existing users on the system that are not the currently running as the
-     * foreground user.
-     *
-     * @return List of {@code UserInfo} for each user that is not the foreground user.
-     */
-    public List<UserInfo> getAllUsersExcludesForegroundUser() {
-        return getAllUsersExceptUser(getForegroundUserId());
-    }
-
-    /**
-     * Gets all the other users on the system that are not the system user.
-     *
-     * @return List of {@code UserInfo} for each user that is not the system user.
-     */
-    public List<UserInfo> getAllUsersExcludesSystemUser() {
-        return getAllUsersExceptUser(UserHandle.USER_SYSTEM);
-    }
-
-    /**
-     * Get all the users except the one with userId passed in.
-     *
-     * @param userId of the user not to be returned.
-     * @return All users other than user with userId.
-     */
-    public List<UserInfo> getAllUsersExceptUser(int userId) {
-        List<UserInfo> others = mUserManager.getUsers(/* excludeDying= */true);
-
-        for (Iterator<UserInfo> iterator = others.iterator(); iterator.hasNext(); ) {
-            UserInfo userInfo = iterator.next();
-            if (userInfo.id == userId) {
-                // Remove user with userId from the list.
-                iterator.remove();
-            }
-        }
-        return others;
-    }
-
-    /**
-     * Gets all the users on the system that are not currently being removed.
-     */
-    public List<UserInfo> getAllUsers() {
-        if (isHeadlessSystemUser()) {
-            return getAllUsersExcludesSystemUser();
-        }
-        return mUserManager.getUsers(/* excludeDying= */true);
-    }
-
-    // User information accessors
-
-    /**
-     * Checks whether the user is system user (admin).
-     *
-     * @param userInfo User to check against system user.
-     * @return {@code true} if system user, {@code false} otherwise.
-     */
-    public boolean userIsSystemUser(UserInfo userInfo) {
-        return userInfo.id == UserHandle.USER_SYSTEM;
-    }
-
-    /**
-     * Returns whether this user can be removed from the system.
-     *
-     * @param userInfo User to be removed
-     * @return {@code true} if they can be removed, {@code false} otherwise.
-     */
-    public boolean userCanBeRemoved(UserInfo userInfo) {
-        return !userIsSystemUser(userInfo);
-    }
-
-    /**
-     * Checks whether passed in user is the foreground user.
-     *
-     * @param userInfo User to check.
-     * @return {@code true} if foreground user, {@code false} otherwise.
-     */
-    public boolean userIsForegroundUser(UserInfo userInfo) {
-        return getForegroundUserId() == userInfo.id;
-    }
-
-    /**
-     * Checks whether passed in user is the user that's running the current process.
-     *
-     * @param userInfo User to check.
-     * @return {@code true} if user running the process, {@code false} otherwise.
-     */
-    public boolean userIsRunningCurrentProcess(UserInfo userInfo) {
-        return getCurrentProcessUserId() == userInfo.id;
-    }
-
-    // Foreground user information accessors.
-
-    /**
-     * Checks if the foreground user is a guest user.
-     */
-    public boolean foregroundUserIsGuestUser() {
-      return getForegroundUserInfo().isGuest();
-    }
-
-    /**
-     * Return whether the foreground user has a restriction.
-     *
-     * @param restriction Restriction to check. Should be a UserManager.* restriction.
-     * @return Whether that restriction exists for the foreground user.
-     */
-    public boolean foregroundUserHasUserRestriction(String restriction) {
-        return mUserManager.hasUserRestriction(restriction, getForegroundUserInfo().getUserHandle());
-    }
-
-    /**
-     * Checks if the foreground user can add new users.
-     */
-    public boolean foregroundUserCanAddUsers() {
-        return !foregroundUserHasUserRestriction(UserManager.DISALLOW_ADD_USER);
-    }
-
-    // Current process user information accessors
-
-    /**
-     * Checks if the calling app is running in a demo user.
-     */
-    public boolean currentProcessRunningAsDemoUser() {
-        return mUserManager.isDemoUser();
-    }
-
-    /**
-     * Checks if the calling app is running as a guest user.
-     */
-    public boolean currentProcessRunningAsGuestUser() {
-        return mUserManager.isGuestUser();
-    }
-
-    /**
-     * Checks whether this process is running under the system user.
-     */
-    public boolean currentProcessRunningAsSystemUser() {
-        return mUserManager.isSystemUser();
-    }
-
-    // Current process user restriction accessors
-
-    /**
-     * Return whether the user running the current process has a restriction.
-     *
-     * @param restriction Restriction to check. Should be a UserManager.* restriction.
-     * @return Whether that restriction exists for the user running the process.
-     */
-    public boolean currentProcessHasUserRestriction(String restriction) {
-        return mUserManager.hasUserRestriction(restriction);
-    }
-
-    /**
-     * Checks if the user running the current process can add new users.
-     */
-    public boolean currentProcessCanAddUsers() {
-        return !currentProcessHasUserRestriction(UserManager.DISALLOW_ADD_USER);
-    }
-
-    /**
-     * Checks if the user running the current process can remove users.
-     */
-    public boolean currentProcessCanRemoveUsers() {
-        return !currentProcessHasUserRestriction(UserManager.DISALLOW_REMOVE_USER);
-    }
-
-    /**
-     * Checks if the user running the current process is allowed to switch to another user.
-     */
-    public boolean currentProcessCanSwitchUsers() {
-        return !currentProcessHasUserRestriction(UserManager.DISALLOW_USER_SWITCH);
-    }
-
-    /**
-     * Checks if the current process user can modify accounts. Demo and Guest users cannot modify
-     * accounts even if the DISALLOW_MODIFY_ACCOUNTS restriction is not applied.
-     */
-    public boolean currentProcessCanModifyAccounts() {
-        return !currentProcessHasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)
-                && !currentProcessRunningAsDemoUser()
-                && !currentProcessRunningAsGuestUser();
-    }
-
-    // User actions
-
-    /**
-     * Creates a new user on the system.
-     *
-     * @param userName Name to give to the newly created user.
-     * @return Newly created user.
-     */
-    public UserInfo createNewUser(String userName) {
-        UserInfo user = mUserManager.createUser(userName, 0 /* flags */);
-        if (user == null) {
-            // Couldn't create user, most likely because there are too many, but we haven't
-            // been able to reload the list yet.
-            Log.w(TAG, "can't create user.");
-            return null;
-        }
-        assignDefaultIcon(user);
-        return user;
-    }
-
-    /**
-     * Tries to remove the user that's passed in. System user cannot be removed.
-     * If the user to be removed is user currently running the process,
-     * it switches to the system user first, and then removes the user.
-     *
-     * @param userInfo User to be removed
-     * @return {@code true} if user is successfully removed, {@code false} otherwise.
-     */
-    public boolean removeUser(UserInfo userInfo) {
-        if (userIsSystemUser(userInfo)) {
-            Log.w(TAG, "User " + userInfo.id + " is system user, could not be removed.");
-            return false;
-        }
-
-        if (userInfo.id == getCurrentProcessUserId()) {
-            switchToUserId(UserHandle.USER_SYSTEM);
-        }
-
-        return mUserManager.removeUser(userInfo.id);
-    }
-
-    /**
-     * Switches (logs in) to another user.
-     *
-     * @param userInfo User to switch to.
-     */
-    public void switchToUser(UserInfo userInfo) {
-        if (userInfo.id == getForegroundUserId()) {
-            return;
-        }
-
-        switchToUserId(userInfo.id);
-    }
-
-    /**
-     * Creates a new guest session and switches into the guest session.
-     *
-     * @param guestName Username for the guest user.
-     */
-    public void startNewGuestSession(String guestName) {
-        UserInfo guest = mUserManager.createGuest(mContext, guestName);
-        if (guest == null) {
-            // Couldn't create user, most likely because there are too many, but we haven't
-            // been able to reload the list yet.
-            Log.w(TAG, "can't create user.");
-            return;
-        }
-        assignDefaultIcon(guest);
-        switchToUserId(guest.id);
-    }
-
-    /**
-     * Gets an icon for the user.
-     *
-     * @param userInfo User for which we want to get the icon.
-     * @return a Bitmap for the icon
-     */
-    public Bitmap getUserIcon(UserInfo userInfo) {
-        Bitmap picture = mUserManager.getUserIcon(userInfo.id);
-
-        if (picture == null) {
-            return assignDefaultIcon(userInfo);
-        }
-
-        return picture;
-    }
-
-    /**
-     * Method for scaling a Bitmap icon to a desirable size.
-     *
-     * @param icon Bitmap to scale.
-     * @param desiredSize Wanted size for the icon.
-     * @return Drawable for the icon, scaled to the new size.
-     */
-    public Drawable scaleUserIcon(Bitmap icon, int desiredSize) {
-        Bitmap scaledIcon = Bitmap.createScaledBitmap(
-                icon, desiredSize, desiredSize, true /* filter */);
-        return new BitmapDrawable(mContext.getResources(), scaledIcon);
-    }
-
-    /**
-     * Sets new Username for the user.
-     *
-     * @param user User whose name should be changed.
-     * @param name New username.
-     */
-    public void setUserName(UserInfo user, String name) {
-        mUserManager.setUserName(user.id, name);
-    }
-
-    /**
-     * Gets a bitmap representing the user's default avatar.
-     *
-     * @param userInfo User whose avatar should be returned.
-     * @return Default user icon
-     */
-    public Bitmap getUserDefaultIcon(UserInfo userInfo) {
-        return UserIcons.convertToBitmap(
-                UserIcons.getDefaultUserIcon(mContext.getResources(), userInfo.id, false));
-    }
-
-    /**
-     * Gets a bitmap representing the default icon for a Guest user.
-     *
-     * @return Degault guest icon
-     */
-    public Bitmap getGuestDefaultIcon() {
-        return UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon(
-                mContext.getResources(), UserHandle.USER_NULL, false));
-    }
-
-    private void registerReceiver() {
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_USER_REMOVED);
-        filter.addAction(Intent.ACTION_USER_ADDED);
-        filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
-        filter.addAction(Intent.ACTION_USER_SWITCHED);
-        filter.addAction(Intent.ACTION_USER_STOPPED);
-        filter.addAction(Intent.ACTION_USER_UNLOCKED);
-        mContext.registerReceiverAsUser(mUserChangeReceiver, UserHandle.ALL, filter, null, null);
-    }
-
-    /**
-     * Assigns a default icon to a user according to the user's id.
-     *
-     * @param userInfo User to assign a default icon to.
-     * @return Bitmap that has been assigned to the user.
-     */
-    private Bitmap assignDefaultIcon(UserInfo userInfo) {
-        Bitmap bitmap = userInfo.isGuest() ? getGuestDefaultIcon() : getUserDefaultIcon(userInfo);
-        mUserManager.setUserIcon(userInfo.id, bitmap);
-        return bitmap;
-    }
-
-    private void switchToUserId(int id) {
-        try {
-            mActivityManager.switchUser(id);
-        } catch (Exception e) {
-            Log.e(TAG, "Couldn't switch user.", e);
-        }
-    }
-
-    private void unregisterReceiver() {
-        mContext.unregisterReceiver(mUserChangeReceiver);
-    }
-
-    /**
-     * Interface for listeners that want to register for receiving updates to changes to the users
-     * on the system including removing and adding users, and changing user info.
-     */
-    public interface OnUsersUpdateListener {
-        /**
-         * Method that will get called when users list has been changed.
-         */
-        void onUsersUpdate();
-    }
-}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java
deleted file mode 100644
index 46557d3..0000000
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.settingslib.users;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.UserInfo;
-import android.graphics.Bitmap;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.os.UserManager;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-public class UserManagerHelperTest {
-    @Mock
-    private Context mContext;
-    @Mock
-    private UserManager mUserManager;
-    @Mock
-    private ActivityManager mActivityManager;
-    @Mock
-    private UserManagerHelper.OnUsersUpdateListener mTestListener;
-
-    private UserManagerHelper mHelper;
-    private UserInfo mCurrentProcessUser;
-    private UserInfo mSystemUser;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
-        when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(mActivityManager);
-        when(mContext.getResources())
-                .thenReturn(InstrumentationRegistry.getTargetContext().getResources());
-        mHelper = new UserManagerHelper(mContext);
-
-        mCurrentProcessUser = createUserInfoForId(UserHandle.myUserId());
-        mSystemUser = createUserInfoForId(UserHandle.USER_SYSTEM);
-        when(mUserManager.getUserInfo(UserHandle.myUserId())).thenReturn(mCurrentProcessUser);
-    }
-
-    @Test
-    public void userIsSystemUser() {
-        UserInfo testInfo = new UserInfo();
-
-        testInfo.id = UserHandle.USER_SYSTEM;
-        assertThat(mHelper.userIsSystemUser(testInfo)).isTrue();
-
-        testInfo.id = UserHandle.USER_SYSTEM + 2; // Make it different than system id.
-        assertThat(mHelper.userIsSystemUser(testInfo)).isFalse();
-    }
-
-    @Test
-    public void getAllUsersExcludesSystemUser() {
-        UserInfo otherUser1 = createUserInfoForId(10);
-        UserInfo otherUser2 = createUserInfoForId(11);
-        UserInfo otherUser3 = createUserInfoForId(12);
-
-        List<UserInfo> testUsers = new ArrayList<>();
-        testUsers.add(otherUser1);
-        testUsers.add(otherUser2);
-        testUsers.add(mSystemUser);
-        testUsers.add(otherUser3);
-
-        when(mUserManager.getUsers(true)).thenReturn(testUsers);
-
-        // Should return 3 users that don't have SYSTEM USER id.
-        assertThat(mHelper.getAllUsersExcludesSystemUser()).hasSize(3);
-        assertThat(mHelper.getAllUsersExcludesSystemUser())
-                .containsExactly(otherUser1, otherUser2, otherUser3);
-    }
-
-    @Test
-    public void getAllUsersExceptUser() {
-        UserInfo user1 = createUserInfoForId(10);
-        UserInfo user2 = createUserInfoForId(10);
-        UserInfo user3 = createUserInfoForId(12);
-
-        List<UserInfo> testUsers = new ArrayList<>();
-        testUsers.add(user1);
-        testUsers.add(user2);
-        testUsers.add(user3);
-
-        when(mUserManager.getUsers(true)).thenReturn(new ArrayList<>(testUsers));
-
-        // Should return all 3 users.
-        assertThat(mHelper.getAllUsersExceptUser(9).size()).isEqualTo(3);
-
-        // Should return only user 12.
-        assertThat(mHelper.getAllUsersExceptUser(10).size()).isEqualTo(1);
-        assertThat(mHelper.getAllUsersExceptUser(10)).contains(user3);
-
-        when(mUserManager.getUsers(true)).thenReturn(new ArrayList<>(testUsers));
-
-        // Should drop user 12.
-        assertThat(mHelper.getAllUsersExceptUser(12).size()).isEqualTo(2);
-        assertThat(mHelper.getAllUsersExceptUser(12)).contains(user1);
-        assertThat(mHelper.getAllUsersExceptUser(12)).contains(user2);
-    }
-
-    @Test
-    public void getAllUsers() {
-        int currentUser = UserHandle.myUserId();
-
-        UserInfo otherUser1 = createUserInfoForId(currentUser + 1);
-        UserInfo otherUser2 = createUserInfoForId(currentUser - 1);
-        UserInfo otherUser3 = createUserInfoForId(currentUser + 2);
-
-        List<UserInfo> testUsers = new ArrayList<>();
-        testUsers.add(otherUser1);
-        testUsers.add(otherUser2);
-        testUsers.add(mCurrentProcessUser);
-        testUsers.add(otherUser3);
-
-        when(mUserManager.getUsers(true)).thenReturn(testUsers);
-
-        assertThat(mHelper.getAllUsers().size()).isEqualTo(4);
-        assertThat(mHelper.getAllUsers())
-                .containsExactly(mCurrentProcessUser, otherUser1, otherUser2, otherUser3);
-    }
-
-    @Test
-    public void userCanBeRemoved() {
-        UserInfo testInfo = new UserInfo();
-
-        // System user cannot be removed.
-        testInfo.id = UserHandle.USER_SYSTEM;
-        assertThat(mHelper.userCanBeRemoved(testInfo)).isFalse();
-
-        testInfo.id = UserHandle.USER_SYSTEM + 2; // Make it different than system id.
-        assertThat(mHelper.userCanBeRemoved(testInfo)).isTrue();
-    }
-
-    @Test
-    public void currentProcessCanAddUsers() {
-        when(mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)).thenReturn(false);
-        assertThat(mHelper.currentProcessCanAddUsers()).isTrue();
-
-        when(mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)).thenReturn(true);
-        assertThat(mHelper.currentProcessCanAddUsers()).isFalse();
-    }
-
-    @Test
-    public void currentProcessCanRemoveUsers() {
-        when(mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)).thenReturn(false);
-        assertThat(mHelper.currentProcessCanRemoveUsers()).isTrue();
-
-        when(mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)).thenReturn(true);
-        assertThat(mHelper.currentProcessCanRemoveUsers()).isFalse();
-    }
-
-    @Test
-    public void currentProcessCanSwitchUsers() {
-        when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(false);
-        assertThat(mHelper.currentProcessCanSwitchUsers()).isTrue();
-
-        when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(true);
-        assertThat(mHelper.currentProcessCanSwitchUsers()).isFalse();
-    }
-
-    @Test
-    public void currentProcessRunningAsGuestCannotModifyAccounts() {
-        assertThat(mHelper.currentProcessCanModifyAccounts()).isTrue();
-
-        when(mUserManager.isGuestUser()).thenReturn(true);
-        assertThat(mHelper.currentProcessCanModifyAccounts()).isFalse();
-    }
-
-    @Test
-    public void currentProcessRunningAsDemoUserCannotModifyAccounts() {
-        assertThat(mHelper.currentProcessCanModifyAccounts()).isTrue();
-
-        when(mUserManager.isDemoUser()).thenReturn(true);
-        assertThat(mHelper.currentProcessCanModifyAccounts()).isFalse();
-    }
-
-    @Test
-    public void currentProcessWithDisallowModifyAccountsRestrictionCannotModifyAccounts() {
-        assertThat(mHelper.currentProcessCanModifyAccounts()).isTrue();
-
-        when(mUserManager.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS))
-                .thenReturn(true);
-        assertThat(mHelper.currentProcessCanModifyAccounts()).isFalse();
-    }
-
-    @Test
-    public void createNewUser() {
-        // Verify createUser on UserManager gets called.
-        mHelper.createNewUser("Test User");
-        verify(mUserManager).createUser("Test User", 0);
-
-        when(mUserManager.createUser("Test User", 0)).thenReturn(null);
-        assertThat(mHelper.createNewUser("Test User")).isNull();
-
-        UserInfo newUser = new UserInfo();
-        newUser.name = "Test User";
-        when(mUserManager.createUser("Test User", 0)).thenReturn(newUser);
-        assertThat(mHelper.createNewUser("Test User")).isEqualTo(newUser);
-    }
-
-    @Test
-    public void removeUser() {
-        // Cannot remove system user.
-        assertThat(mHelper.removeUser(mSystemUser)).isFalse();
-
-        // Removing non-current, non-system user, simply calls removeUser.
-        UserInfo userToRemove = createUserInfoForId(mCurrentProcessUser.id + 2);
-
-        mHelper.removeUser(userToRemove);
-        verify(mUserManager).removeUser(mCurrentProcessUser.id + 2);
-    }
-
-    @Test
-    public void startNewGuestSession() {
-        mHelper.startNewGuestSession("Test Guest");
-        verify(mUserManager).createGuest(mContext, "Test Guest");
-
-        UserInfo guestInfo = new UserInfo(21, "Test Guest", UserInfo.FLAG_GUEST);
-        when(mUserManager.createGuest(mContext, "Test Guest")).thenReturn(guestInfo);
-        mHelper.startNewGuestSession("Test Guest");
-        verify(mActivityManager).switchUser(21);
-    }
-
-    @Test
-    public void getUserIcon() {
-        mHelper.getUserIcon(mCurrentProcessUser);
-        verify(mUserManager).getUserIcon(mCurrentProcessUser.id);
-    }
-
-    @Test
-    public void scaleUserIcon() {
-        Bitmap fakeIcon = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
-        Drawable scaledIcon = mHelper.scaleUserIcon(fakeIcon, 300);
-        assertThat(scaledIcon.getIntrinsicWidth()).isEqualTo(300);
-        assertThat(scaledIcon.getIntrinsicHeight()).isEqualTo(300);
-    }
-
-    @Test
-    public void setUserName() {
-        UserInfo testInfo = createUserInfoForId(mCurrentProcessUser.id + 3);
-        mHelper.setUserName(testInfo, "New Test Name");
-        verify(mUserManager).setUserName(mCurrentProcessUser.id + 3, "New Test Name");
-    }
-
-    @Test
-    public void registerUserChangeReceiver() {
-        mHelper.registerOnUsersUpdateListener(mTestListener);
-
-        ArgumentCaptor<BroadcastReceiver> receiverCaptor =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
-        ArgumentCaptor<UserHandle> handleCaptor = ArgumentCaptor.forClass(UserHandle.class);
-        ArgumentCaptor<IntentFilter> filterCaptor = ArgumentCaptor.forClass(IntentFilter.class);
-        ArgumentCaptor<String> permissionCaptor = ArgumentCaptor.forClass(String.class);
-        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
-
-        verify(mContext).registerReceiverAsUser(
-                receiverCaptor.capture(),
-                handleCaptor.capture(),
-                filterCaptor.capture(),
-                permissionCaptor.capture(),
-                handlerCaptor.capture());
-
-        // Verify we're listening to Intents from ALL users.
-        assertThat(handleCaptor.getValue()).isEqualTo(UserHandle.ALL);
-
-        // Verify the presence of each intent in the filter.
-        // Verify the exact number of filters. Every time a new intent is added, this test should
-        // get updated.
-        assertThat(filterCaptor.getValue().countActions()).isEqualTo(6);
-        assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_REMOVED)).isTrue();
-        assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_ADDED)).isTrue();
-        assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_INFO_CHANGED)).isTrue();
-        assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_SWITCHED)).isTrue();
-        assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_STOPPED)).isTrue();
-        assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_UNLOCKED)).isTrue();
-
-
-        // Verify that calling the receiver calls the listener.
-        receiverCaptor.getValue().onReceive(mContext, new Intent());
-        verify(mTestListener).onUsersUpdate();
-
-        assertThat(permissionCaptor.getValue()).isNull();
-        assertThat(handlerCaptor.getValue()).isNull();
-
-
-        // Unregister the receiver.
-        mHelper.unregisterOnUsersUpdateListener();
-        verify(mContext).unregisterReceiver(receiverCaptor.getValue());
-    }
-
-    private UserInfo createUserInfoForId(int id) {
-        UserInfo userInfo = new UserInfo();
-        userInfo.id = id;
-        return userInfo;
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/UserManagerHelperRoboTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/UserManagerHelperRoboTest.java
deleted file mode 100644
index 83cc39a..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/UserManagerHelperRoboTest.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.users;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.os.UserHandle;
-import android.os.UserManager;
-
-import com.android.settingslib.testutils.shadow.ShadowActivityManager;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.annotation.Resetter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = { ShadowActivityManager.class, UserManagerHelperRoboTest.ShadowUserHandle.class})
-public class UserManagerHelperRoboTest {
-    @Mock
-    private Context mContext;
-    @Mock
-    private UserManager mUserManager;
-
-    private UserManagerHelper mHelper;
-
-    @Before
-    public void setUpMocksAndUserManagerHelper() {
-        MockitoAnnotations.initMocks(this);
-        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
-        when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(
-                RuntimeEnvironment.application.getSystemService(ActivityManager.class));
-        mHelper = new UserManagerHelper(mContext);
-    }
-
-    @After
-    public void tearDown() {
-        ShadowActivityManager.getShadow().reset();
-    }
-
-    @Test
-    public void getForegroundUserId() {
-        ShadowActivityManager.setCurrentUser(15);
-        assertThat(mHelper.getForegroundUserId()).isEqualTo(15);
-    }
-
-    @Test
-    public void getForegroundUserInfo() {
-        ShadowActivityManager.setCurrentUser(17);
-        when(mUserManager.getUserInfo(ActivityManager.getCurrentUser()))
-                .thenReturn(createUserInfoForId(ActivityManager.getCurrentUser()));
-        assertThat(mHelper.getForegroundUserInfo().id).isEqualTo(17);
-    }
-
-    @Test
-    public void getCurrentProcessUserId() {
-        ShadowUserHandle.setUid(11);
-        assertThat(mHelper.getCurrentProcessUserId()).isEqualTo(11);
-    }
-
-    @Test
-    public void getCurrentProcessUserInfo() {
-        ShadowUserHandle.setUid(12);
-        when(mUserManager.getUserInfo(UserHandle.myUserId()))
-                .thenReturn(createUserInfoForId(UserHandle.myUserId()));
-        assertThat(mHelper.getCurrentProcessUserInfo().id).isEqualTo(12);
-    }
-
-    @Test
-    public void getAllUsersExcludesCurrentProcessUser() {
-        ShadowUserHandle.setUid(12);
-        UserInfo currentProcessUser = createUserInfoForId(12);
-
-        UserInfo otherUser1 = createUserInfoForId(13);
-        UserInfo otherUser2 = createUserInfoForId(11);
-        UserInfo otherUser3 = createUserInfoForId(14);
-
-        List<UserInfo> testUsers = new ArrayList<>();
-        testUsers.add(otherUser1);
-        testUsers.add(otherUser2);
-        testUsers.add(currentProcessUser);
-        testUsers.add(otherUser3);
-
-        when(mUserManager.getUsers(true)).thenReturn(testUsers);
-
-        // Should return 3 users that don't have currentProcessUser id.
-        assertThat(mHelper.getAllUsersExcludesCurrentProcessUser()).hasSize(3);
-        assertThat(mHelper.getAllUsersExcludesCurrentProcessUser())
-                .containsExactly(otherUser1, otherUser2, otherUser3);
-    }
-
-    @Test
-    public void getAllUsersExcludesForegroundUser() {
-        ShadowActivityManager.setCurrentUser(17);
-        UserInfo foregroundUser = createUserInfoForId(17);
-
-        UserInfo otherUser1 = createUserInfoForId(11);
-        UserInfo otherUser2 = createUserInfoForId(18);
-        UserInfo otherUser3 = createUserInfoForId(16);
-
-        List<UserInfo> testUsers = new ArrayList<>();
-        testUsers.add(otherUser1);
-        testUsers.add(otherUser2);
-        testUsers.add(foregroundUser);
-        testUsers.add(otherUser3);
-
-        when(mUserManager.getUsers(true)).thenReturn(testUsers);
-
-        // Should return 3 users that don't have foregroundUser id.
-        assertThat(mHelper.getAllUsersExcludesForegroundUser()).hasSize(3);
-        assertThat(mHelper.getAllUsersExcludesForegroundUser())
-                .containsExactly(otherUser1, otherUser2, otherUser3);
-    }
-
-    @Test
-    public void userIsForegroundUser() {
-        ShadowActivityManager.setCurrentUser(10);
-        assertThat(mHelper.userIsForegroundUser(createUserInfoForId(10))).isTrue();
-        assertThat(mHelper.userIsForegroundUser(createUserInfoForId(11))).isFalse();
-
-        ShadowActivityManager.setCurrentUser(11);
-        assertThat(mHelper.userIsForegroundUser(createUserInfoForId(11))).isTrue();
-    }
-
-    @Test
-    public void userIsRunningCurrentProcess() {
-        ShadowUserHandle.setUid(10);
-        assertThat(mHelper.userIsRunningCurrentProcess(createUserInfoForId(10))).isTrue();
-        assertThat(mHelper.userIsRunningCurrentProcess(createUserInfoForId(11))).isFalse();
-
-        ShadowUserHandle.setUid(11);
-        assertThat(mHelper.userIsRunningCurrentProcess(createUserInfoForId(11))).isTrue();
-    }
-
-    @Test
-    public void removingCurrentProcessUserSwitchesToSystemUser() {
-        // Set currentProcess user to be user 10.
-        ShadowUserHandle.setUid(10);
-
-        // Removing a currentProcess user, calls "switch" to system user
-        mHelper.removeUser(createUserInfoForId(10));
-        assertThat(ShadowActivityManager.getShadow().getSwitchUserCalled()).isTrue();
-        assertThat(ShadowActivityManager.getShadow().getUserSwitchedTo()).isEqualTo(0);
-
-        verify(mUserManager).removeUser(10);
-    }
-
-    @Test
-    public void switchToUser() {
-        ShadowActivityManager.setCurrentUser(20);
-
-        // Switching to foreground user doesn't do anything.
-        mHelper.switchToUser(createUserInfoForId(20));
-        assertThat(ShadowActivityManager.getShadow().getSwitchUserCalled()).isFalse();
-
-        // Switching to non-foreground user, simply calls switchUser.
-        UserInfo userToSwitchTo = new UserInfo(22, "Test User", 0);
-        mHelper.switchToUser(userToSwitchTo);
-        assertThat(ShadowActivityManager.getShadow().getSwitchUserCalled()).isTrue();
-        assertThat(ShadowActivityManager.getShadow().getUserSwitchedTo()).isEqualTo(22);
-    }
-
-    private UserInfo createUserInfoForId(int id) {
-        UserInfo userInfo = new UserInfo();
-        userInfo.id = id;
-        return userInfo;
-    }
-
-    @Implements(UserHandle.class)
-    public static class ShadowUserHandle {
-        private static int sUid = 0; // SYSTEM by default
-
-        public static void setUid(int uid) {
-            sUid = uid;
-        }
-
-        @Implementation
-        public static int myUserId() {
-            return sUid;
-        }
-
-        @Resetter
-        public static void reset() {
-            sUid = 0;
-        }
-    }
-}
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
index b16e062..49c16be 100644
--- a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
+++ b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
@@ -23,21 +23,20 @@
     android:layout_width="wrap_content"
     android:layout_marginLeft="@dimen/ongoing_appops_chip_margin"
     android:layout_marginRight="@dimen/ongoing_appops_chip_margin"
-    android:layout_gravity="center_vertical|start"
+    android:layout_gravity="center_vertical|end"
     android:gravity="center_vertical"
     android:orientation="horizontal"
-    android:focusable="true">
+    android:focusable="true" >
 
         <FrameLayout
             android:id="@+id/background"
             android:layout_height="@dimen/ongoing_appops_chip_height"
-            android:layout_width="wrap_content"
-        >
+            android:minWidth="48dp"
+            android:layout_width="wrap_content" >
                 <LinearLayout
                     android:id="@+id/icons_container"
                     android:layout_height="match_parent"
                     android:layout_width="wrap_content"
-                    android:layout_gravity="center"
                     android:gravity="center_vertical"
                     />
           </FrameLayout>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 74924fb..bfdb218 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1044,7 +1044,7 @@
     <!-- Margin between icons of Ongoing App Ops chip when QS-->
     <dimen name="ongoing_appops_chip_icon_margin_expanded">2dp</dimen>
     <!-- Icon size of Ongoing App Ops chip -->
-    <dimen name="ongoing_appops_chip_icon_size">@*android:dimen/status_bar_icon_size</dimen>
+    <dimen name="ongoing_appops_chip_icon_size">@dimen/status_bar_icon_drawing_size</dimen>
     <!-- Radius of Ongoing App Ops chip corners -->
     <dimen name="ongoing_appops_chip_bg_corner_radius">16dp</dimen>
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index fa39ccd..fd55708 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1665,7 +1665,7 @@
             }
             mFaceCancelSignal = new CancellationSignal();
             mFaceManager.authenticate(null, mFaceCancelSignal, 0,
-                    mFaceAuthenticationCallback, null);
+                    mFaceAuthenticationCallback, null, userId);
             setFaceRunningState(BIOMETRIC_STATE_RUNNING);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 329b001..6c1d1f9 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -180,10 +180,6 @@
         setClipChildren(false);
         setClipToPadding(false);
         Dependency.get(ConfigurationController.class).observe(viewAttachLifecycle(this), this);
-
-        // Needed for PorderDuff.Mode.CLEAR operations to work properly, but redraws don't happen
-        // enough to justify a hardware layer.
-        setLayerType(LAYER_TYPE_SOFTWARE, null);
     }
 
     private void setupLayoutTransition() {
@@ -405,10 +401,10 @@
                 || mShowPercentMode == MODE_ON || mShowPercentMode == MODE_ESTIMATE) {
             if (!showing) {
                 mBatteryPercentView = loadPercentView();
-                if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor);
                 if (mPercentageStyleId != 0) { // Only set if specified as attribute
                     mBatteryPercentView.setTextAppearance(mPercentageStyleId);
                 }
+                if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor);
                 updatePercentText();
                 addView(mBatteryPercentView,
                         new ViewGroup.LayoutParams(
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 70f2cce..a421940 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -293,6 +293,7 @@
     @Inject Lazy<DevicePolicyManagerWrapper> mDevicePolicyManagerWrapper;
     @Inject Lazy<PackageManagerWrapper> mPackageManagerWrapper;
     @Inject Lazy<SensorPrivacyController> mSensorPrivacyController;
+    @Inject Lazy<DumpController> mDumpController;
 
     @Inject
     public Dependency() {
@@ -464,7 +465,7 @@
         mProviders.put(DevicePolicyManagerWrapper.class, mDevicePolicyManagerWrapper::get);
         mProviders.put(PackageManagerWrapper.class, mPackageManagerWrapper::get);
         mProviders.put(SensorPrivacyController.class, mSensorPrivacyController::get);
-
+        mProviders.put(DumpController.class, mDumpController::get);
 
         // TODO(b/118592525): to support multi-display , we start to add something which is
         //                    per-display, while others may be global. I think it's time to add
@@ -478,6 +479,11 @@
     @Override
     public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         super.dump(fd, pw, args);
+
+        // Make sure that the DumpController gets added to mDependencies, as they are only added
+        // with Dependency#get.
+        getDependency(DumpController.class);
+
         pw.println("Dumping existing controllers:");
         mDependencies.values().stream().filter(obj -> obj instanceof Dumpable)
                 .forEach(o -> ((Dumpable) o).dump(fd, pw, args));
diff --git a/packages/SystemUI/src/com/android/systemui/DumpController.kt b/packages/SystemUI/src/com/android/systemui/DumpController.kt
new file mode 100644
index 0000000..646abb5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/DumpController.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui
+
+import android.util.Log
+import androidx.annotation.GuardedBy
+import com.android.internal.util.Preconditions
+import java.io.FileDescriptor
+import java.io.PrintWriter
+import java.lang.ref.WeakReference
+import javax.inject.Inject
+import javax.inject.Singleton
+
+// TODO: Move all Dumpable dependencies to use DumpController
+/**
+ * Controller that allows any [Dumpable] to subscribe and be dumped along with other SystemUI
+ * dependencies.
+ */
+@Singleton
+class DumpController @Inject constructor() : Dumpable {
+
+    companion object {
+        private const val TAG = "DumpController"
+        private const val DEBUG = false
+    }
+
+    @GuardedBy("listeners")
+    private val listeners = mutableListOf<WeakReference<Dumpable>>()
+    val numListeners: Int
+        get() = listeners.size
+
+    /**
+     * Adds a [Dumpable] listener to be dumped. It will only be added if it is not already tracked.
+     *
+     * @param listener the [Dumpable] to be added
+     */
+    fun addListener(listener: Dumpable) {
+        Preconditions.checkNotNull(listener, "The listener to be added cannot be null")
+        if (DEBUG) Log.v(TAG, "*** register callback for $listener")
+        synchronized<Unit>(listeners) {
+            if (listeners.any { it.get() == listener }) {
+                if (DEBUG) {
+                    Log.e(TAG, "Object tried to add another callback")
+                }
+            } else {
+                listeners.add(WeakReference(listener))
+            }
+        }
+    }
+
+    /**
+     * Removes a listener from the list of elements to be dumped.
+     *
+     * @param listener the [Dumpable] to be removed.
+     */
+    fun removeListener(listener: Dumpable) {
+        if (DEBUG) Log.v(TAG, "*** unregister callback for $listener")
+        synchronized(listeners) {
+            listeners.removeAll { it.get() == listener || it.get() == null }
+        }
+    }
+
+    /**
+     * Dump all the [Dumpable] registered with the controller
+     */
+    override fun dump(fd: FileDescriptor?, pw: PrintWriter, args: Array<String>?) {
+        pw.println("DumpController state:")
+        synchronized(listeners) {
+            listeners.forEach { it.get()?.dump(fd, pw, args) }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 686edad..424cd55 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -926,6 +926,7 @@
                 mFlyout.removeCallbacks(mHideFlyout);
                 mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
             });
+            logBubbleEvent(bubble, StatsLog.BUBBLE_UICHANGED__ACTION__FLYOUT);
         }
     }
 
@@ -1097,7 +1098,8 @@
      * @param action the user interaction enum.
      */
     private void logBubbleEvent(@Nullable Bubble bubble, int action) {
-        if (bubble == null) {
+        if (bubble == null || bubble.entry == null
+                || bubble.entry.notification == null) {
             StatsLog.write(StatsLog.BUBBLE_UI_CHANGED,
                     null /* package name */,
                     null /* notification channel */,
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
index 21406e5..d935466 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
@@ -34,7 +34,6 @@
 
 import android.graphics.Bitmap;
 import android.opengl.GLUtils;
-import android.os.Build;
 import android.util.Log;
 
 import java.nio.ByteBuffer;
@@ -196,58 +195,76 @@
         glUniform1i(mUniTexture, 0);
     }
 
+    /**
+     * This method adjust s(x-axis), t(y-axis) texture coordinates
+     * to prevent the wallpaper from being stretched.
+     * The adjustment happens if either the width or height of the bitmap is larger than
+     * corresponding size of the surface.
+     * If both width and height are larger than corresponding size of the surface,
+     * the adjustment will happen at both s, t side.
+     *
+     * @param bitmapWidth The width of the bitmap.
+     * @param bitmapHeight The height of the bitmap.
+     * @param surfaceWidth The width of the surface.
+     * @param surfaceHeight The height of the surface.
+     * @param xOffset The offset amount along s axis.
+     * @param yOffset The offset amount along t axis.
+     */
     void adjustTextureCoordinates(int bitmapWidth, int bitmapHeight,
             int surfaceWidth, int surfaceHeight, float xOffset, float yOffset) {
-        float ratioW = 1f;
-        float ratioH = 1f;
-        float rX = 0f;
-        float rY = 0f;
-        float[] coordinates = null;
+        float[] coordinates = TEXTURES.clone();
 
-        final boolean adjustWidth = bitmapWidth > surfaceWidth;
-        final boolean adjustHeight = bitmapHeight > surfaceHeight;
-
-        if (adjustWidth || adjustHeight) {
-            coordinates = TEXTURES.clone();
-        }
-
-        if (adjustWidth) {
-            float x = (float) Math.round((bitmapWidth - surfaceWidth) * xOffset) / bitmapWidth;
-            ratioW = (float) surfaceWidth / bitmapWidth;
-            float referenceX = x + ratioW > 1f ? 1f - ratioW : x;
+        if (bitmapWidth > surfaceWidth) {
+            // Calculate the new s pos in pixels.
+            float pixelS = (float) Math.round((bitmapWidth - surfaceWidth) * xOffset);
+            // Calculate the s pos in texture coordinate.
+            float coordinateS = pixelS / bitmapWidth;
+            // Calculate the percentage occupied by the surface width in bitmap width.
+            float surfacePercentageW = (float) surfaceWidth / bitmapWidth;
+            // Need also consider the case if bitmap height is smaller than surface height.
+            if (bitmapHeight < surfaceHeight) {
+                // We will narrow the surface percentage to keep aspect ratio.
+                surfacePercentageW *= (float) bitmapHeight / surfaceHeight;
+            }
+            // Determine the final s pos, also limit the legal s pos to prevent from out of range.
+            float s = coordinateS + surfacePercentageW > 1f ? 1f - surfacePercentageW : coordinateS;
+            // Traverse the s pos in texture coordinates array and adjust the s pos accordingly.
             for (int i = 0; i < coordinates.length; i += 2) {
+                // indices 2, 4 and 6 are the end of s coordinates.
                 if (i == 2 || i == 4 || i == 6) {
-                    coordinates[i] = Math.min(1f, referenceX + ratioW);
+                    coordinates[i] = Math.min(1f, s + surfacePercentageW);
                 } else {
-                    coordinates[i] = referenceX;
+                    coordinates[i] = s;
                 }
             }
-            rX = referenceX;
         }
 
-
-        if (adjustHeight) {
-            float y = (float) Math.round((bitmapHeight - surfaceHeight) * yOffset) / bitmapHeight;
-            ratioH = (float) surfaceHeight / bitmapHeight;
-            float referenceY = y + ratioH > 1f ? 1f - ratioH : y;
+        if (bitmapHeight > surfaceHeight) {
+            // Calculate the new t pos in pixels.
+            float pixelT = (float) Math.round((bitmapHeight - surfaceHeight) * yOffset);
+            // Calculate the t pos in texture coordinate.
+            float coordinateT = pixelT / bitmapHeight;
+            // Calculate the percentage occupied by the surface height in bitmap height.
+            float surfacePercentageH = (float) surfaceHeight / bitmapHeight;
+            // Need also consider the case if bitmap width is smaller than surface width.
+            if (bitmapWidth < surfaceWidth) {
+                // We will narrow the surface percentage to keep aspect ratio.
+                surfacePercentageH *= (float) bitmapWidth / surfaceWidth;
+            }
+            // Determine the final t pos, also limit the legal t pos to prevent from out of range.
+            float t = coordinateT + surfacePercentageH > 1f ? 1f - surfacePercentageH : coordinateT;
+            // Traverse the t pos in texture coordinates array and adjust the t pos accordingly.
             for (int i = 1; i < coordinates.length; i += 2) {
+                // indices 1, 3 and 11 are the end of t coordinates.
                 if (i == 1 || i == 3 || i == 11) {
-                    coordinates[i] = Math.min(1f, referenceY + ratioH);
+                    coordinates[i] = Math.min(1f, t + surfacePercentageH);
                 } else {
-                    coordinates[i] = referenceY;
+                    coordinates[i] = t;
                 }
             }
-            rY = referenceY;
         }
 
-        if (adjustWidth || adjustHeight) {
-            if (Build.IS_DEBUGGABLE) {
-                Log.d(TAG, "adjustTextureCoordinates: sW=" + surfaceWidth + ", sH=" + surfaceHeight
-                        + ", bW=" + bitmapWidth + ", bH=" + bitmapHeight
-                        + ", rW=" + ratioW + ", rH=" + ratioH + ", rX=" + rX + ", rY=" + rY);
-            }
-            mTextureBuffer.put(coordinates);
-            mTextureBuffer.position(0);
-        }
+        mTextureBuffer.put(coordinates);
+        mTextureBuffer.position(0);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
index 23742c0..a5a915b 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
@@ -16,13 +16,12 @@
 
 import android.content.Context
 import android.util.AttributeSet
+import android.view.Gravity
 import android.view.ViewGroup
 import android.widget.FrameLayout
 import android.widget.ImageView
 import android.widget.LinearLayout
-import com.android.systemui.Dependency
 import com.android.systemui.R
-import com.android.systemui.statusbar.policy.KeyguardMonitor
 
 class OngoingPrivacyChip @JvmOverloads constructor(
     context: Context,
@@ -51,8 +50,7 @@
                 updateView()
             }
         }
-    @Suppress("DEPRECATION")
-    private val keyguardMonitor = Dependency.get(KeyguardMonitor::class.java)
+
     var builder = PrivacyDialogBuilder(context, emptyList<PrivacyItem>())
     var privacyList = emptyList<PrivacyItem>()
         set(value) {
@@ -94,14 +92,16 @@
         if (!privacyList.isEmpty()) {
             generateContentDescription()
             setIcons(builder, iconsContainer)
+            val lp = iconsContainer.layoutParams as FrameLayout.LayoutParams
+            lp.gravity = Gravity.CENTER_VERTICAL or
+                    (if (expanded) Gravity.CENTER_HORIZONTAL else Gravity.END)
+            iconsContainer.layoutParams = lp
         } else {
             iconsContainer.removeAllViews()
         }
         requestLayout()
     }
 
-    private fun amISecure() = keyguardMonitor.isShowing && keyguardMonitor.isSecure
-
     private fun generateContentDescription() {
         val typesText = builder.joinTypes()
         contentDescription = context.getString(
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
index 3f581c4d..2909424 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
@@ -24,10 +24,14 @@
 
 typealias Privacy = PrivacyType
 
-enum class PrivacyType(val nameId: Int, val iconId: Int) {
-    TYPE_CAMERA(R.string.privacy_type_camera, R.drawable.stat_sys_camera),
-    TYPE_MICROPHONE(R.string.privacy_type_microphone, R.drawable.stat_sys_mic_none),
-    TYPE_LOCATION(R.string.privacy_type_location, R.drawable.stat_sys_location);
+enum class PrivacyType(private val nameId: Int, val iconId: Int) {
+    // This is uses the icons used by the corresponding permission groups in the AndroidManifest
+    TYPE_CAMERA(R.string.privacy_type_camera,
+            com.android.internal.R.drawable.perm_group_camera),
+    TYPE_MICROPHONE(R.string.privacy_type_microphone,
+            com.android.internal.R.drawable.perm_group_microphone),
+    TYPE_LOCATION(R.string.privacy_type_location,
+            com.android.internal.R.drawable.perm_group_location);
 
     fun getName(context: Context) = context.resources.getString(nameId)
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index bb159a9..ebc3a6a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -91,6 +91,7 @@
         if (mLayoutOrientation != newConfig.orientation) {
             mLayoutOrientation = newConfig.orientation;
             setCurrentItem(0, false);
+            mPageToRestore = 0;
         }
     }
 
@@ -101,6 +102,7 @@
             mLayoutDirection = layoutDirection;
             setAdapter(mAdapter);
             setCurrentItem(0, false);
+            mPageToRestore = 0;
         }
     }
 
@@ -112,6 +114,17 @@
         super.setCurrentItem(item, smoothScroll);
     }
 
+    /**
+     * Obtains the current page number respecting RTL
+     */
+    private int getCurrentPageNumber() {
+        int page = getCurrentItem();
+        if (mLayoutDirection == LAYOUT_DIRECTION_RTL) {
+            page = mPages.size() - 1 - page;
+        }
+        return page;
+    }
+
     @Override
     public void setListening(boolean listening) {
         if (mListening == listening) return;
@@ -199,7 +212,7 @@
         // marquee. This will ensure that accessibility doesn't announce the TYPE_VIEW_SELECTED
         // event on any of the children.
         setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
-        int currentItem = isLayoutRtl() ? mPages.size() - 1 - getCurrentItem() : getCurrentItem();
+        int currentItem = getCurrentPageNumber();
         for (int i = 0; i < mPages.size(); i++) {
             mPages.get(i).setSelected(i == currentItem ? selected : false);
         }
@@ -328,7 +341,7 @@
 
     public int getNumVisibleTiles() {
         if (mPages.size() == 0) return 0;
-        TilePage currentPage = mPages.get(getCurrentItem());
+        TilePage currentPage = mPages.get(getCurrentPageNumber());
         return currentPage.mRecords.size();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 8e77851..ec2feba8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -213,7 +213,11 @@
                 } else { // These tiles disappear when expanding
                     firstPageBuilder.addFloat(quickTileView, "alpha", 1, 0);
                     translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff);
-                    translationXBuilder.addFloat(quickTileView, "translationX", 0, xDiff + width);
+
+                    // xDiff is negative here and this makes it "more" negative
+                    final int translationX = mQsPanel.isLayoutRtl() ? xDiff - width : xDiff + width;
+                    translationXBuilder.addFloat(quickTileView, "translationX", 0,
+                            translationX);
                 }
 
                 mQuickQsViews.add(tileView.getIconWithBackground());
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 00aef9a..72559f5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -498,7 +498,7 @@
         mSysUiStateFlags = 0;
         mSysUiStateFlags |= ActivityManagerWrapper.getInstance().isScreenPinningActive()
                 ? SYSUI_STATE_SCREEN_PINNING : 0;
-        mSysUiStateFlags |= (navBarFragment == null || !navBarFragment.isNavBarWindowVisible())
+        mSysUiStateFlags |= (navBarFragment != null && !navBarFragment.isNavBarWindowVisible())
                 ? SYSUI_STATE_NAV_BAR_HIDDEN : 0;
         mSysUiStateFlags |= panelExpanded
                 ? SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED : 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
index c833ded..907b3ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
@@ -33,6 +33,7 @@
 import android.view.WindowManagerGlobal;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.statusbar.RegisterStatusBarResult;
 import com.android.systemui.Dependency;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.statusbar.CommandQueue.Callbacks;
@@ -81,7 +82,7 @@
     @Override
     public void onDisplayReady(int displayId) {
         Display display = mDisplayManager.getDisplay(displayId);
-        createNavigationBar(display);
+        createNavigationBar(display, null);
     }
 
     // TODO(b/117478341): I use {@code includeDefaultDisplay} to make this method compatible to
@@ -91,11 +92,12 @@
      *
      * @param includeDefaultDisplay {@code true} to create navigation bar on default display.
      */
-    public void createNavigationBars(final boolean includeDefaultDisplay) {
+    public void createNavigationBars(final boolean includeDefaultDisplay,
+            RegisterStatusBarResult result) {
         Display[] displays = mDisplayManager.getDisplays();
         for (Display display : displays) {
             if (includeDefaultDisplay || display.getDisplayId() != DEFAULT_DISPLAY) {
-                createNavigationBar(display);
+                createNavigationBar(display, result);
             }
         }
     }
@@ -107,7 +109,7 @@
      * @param display the display to add navigation bar on.
      */
     @VisibleForTesting
-    void createNavigationBar(Display display) {
+    void createNavigationBar(Display display, RegisterStatusBarResult result) {
         if (display == null) {
             return;
         }
@@ -151,6 +153,12 @@
             navBar.setAutoHideController(autoHideController);
             navBar.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
             mNavigationBars.append(displayId, navBar);
+
+            if (result != null) {
+                navBar.setImeWindowStatus(display.getDisplayId(), result.mImeToken,
+                        result.mImeWindowVis, result.mImeBackDisposition,
+                        result.mShowImeSwitcher);
+            }
         });
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
index 99f5874..b54de5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
@@ -90,6 +90,8 @@
         @Override
         public void onPlaybackStateChanged(PlaybackState state) {
             if (state.getState() != PlaybackState.STATE_PLAYING) {
+                // Update the UI once, in case playback info changed while we were paused
+                mUpdatePlaybackUi.run();
                 clearTimer();
             } else if (mSeekBarTimer == null) {
                 startTimer();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 591b1b4..9eecdb9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -316,6 +316,7 @@
         if (savedInstanceState != null) {
             mNavigationBarView.getLightTransitionsController().restoreState(savedInstanceState);
         }
+        mNavigationBarView.setNavigationIconHints(mNavigationIconHints);
 
         prepareNavigationBarView();
         checkNavBarModes();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 0e9264b..dd957b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1709,7 +1709,8 @@
             min = Math.max(min, minHeight);
         }
         int maxHeight;
-        if (mQsExpandImmediate || mQsExpanded || mIsExpanding && mQsExpandedWhenExpandingStarted) {
+        if (mQsExpandImmediate || mQsExpanded || mIsExpanding && mQsExpandedWhenExpandingStarted
+                || mPulsing) {
             maxHeight = calculatePanelHeightQsExpanded();
         } else {
             maxHeight = calculatePanelHeightShade();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index aaaf3ed..9fccf91 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -660,7 +660,6 @@
         mDisplayId = mDisplay.getDisplayId();
         updateDisplaySize();
 
-        Resources res = mContext.getResources();
         mVibrateOnOpening = mContext.getResources().getBoolean(
                 R.bool.config_vibrateOnIconAnimation);
         mVibratorHelper = Dependency.get(VibratorHelper.class);
@@ -696,7 +695,7 @@
             ex.rethrowFromSystemServer();
         }
 
-        createAndAddWindows();
+        createAndAddWindows(result);
 
         // Make sure we always have the most current wallpaper info.
         IntentFilter wallpaperChangedFilter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
@@ -778,7 +777,7 @@
     // ================================================================================
     // Constructing the view
     // ================================================================================
-    protected void makeStatusBarView() {
+    protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
         final Context context = mContext;
         updateDisplaySize(); // populates mDisplayMetrics
         updateResources();
@@ -871,7 +870,7 @@
         mNotificationLogger.setHeadsUpManager(mHeadsUpManager);
         putComponent(HeadsUpManager.class, mHeadsUpManager);
 
-        createNavigationBar();
+        createNavigationBar(result);
 
         if (ENABLE_LOCKSCREEN_WALLPAPER) {
             mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
@@ -1118,8 +1117,8 @@
 
     // TODO(b/117478341): This was left such that CarStatusBar can override this method.
     // Try to remove this.
-    protected void createNavigationBar() {
-        mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */);
+    protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
+        mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */, result);
     }
 
     /**
@@ -2401,12 +2400,8 @@
         pw.println(BarTransitions.modeToString(transitions.getMode()));
     }
 
-    public void createAndAddWindows() {
-        addStatusBarWindow();
-    }
-
-    private void addStatusBarWindow() {
-        makeStatusBarView();
+    public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
+        makeStatusBarView(result);
         mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
         mStatusBarWindowController.add(mStatusBarWindow, getStatusBarHeight());
     }
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
index 1a9fd53..51ae70b 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
@@ -23,9 +23,11 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import com.google.android.collect.Lists;
 import com.google.android.collect.Sets;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -62,15 +64,18 @@
     static final String OVERLAY_CATEGORY_ICON_LAUNCHER =
             "android.theme.customization.icon_pack.launcher";
 
-    /* All theme customization categories used by the system. */
-    static final Set<String> THEME_CATEGORIES = Sets.newHashSet(
-            OVERLAY_CATEGORY_COLOR,
-            OVERLAY_CATEGORY_FONT,
+    /*
+     * All theme customization categories used by the system, in order that they should be applied,
+     * starts with launcher and grouped by target package.
+     */
+    static final List<String> THEME_CATEGORIES = Lists.newArrayList(
+            OVERLAY_CATEGORY_ICON_LAUNCHER,
             OVERLAY_CATEGORY_SHAPE,
+            OVERLAY_CATEGORY_FONT,
+            OVERLAY_CATEGORY_COLOR,
             OVERLAY_CATEGORY_ICON_ANDROID,
             OVERLAY_CATEGORY_ICON_SYSUI,
-            OVERLAY_CATEGORY_ICON_SETTINGS,
-            OVERLAY_CATEGORY_ICON_LAUNCHER);
+            OVERLAY_CATEGORY_ICON_SETTINGS);
 
     /* Categories that need to applied to the current user as well as the system user. */
     @VisibleForTesting
@@ -115,29 +120,30 @@
      */
     void applyCurrentUserOverlays(
             Map<String, String> categoryToPackage, Set<UserHandle> userHandles) {
-        final Map<Boolean, List<String>> categorySplit = THEME_CATEGORIES.stream().collect(
-                Collectors.partitioningBy((category) -> categoryToPackage.containsKey(category)));
-        final List<String> overlayCategoriesToEnable = categorySplit.get(true);
-        final List<String> overlayCategoriesToDisable = categorySplit.get(false);
-
         // Disable all overlays that have not been specified in the user setting.
-        final List<OverlayInfo> overlays = new ArrayList<>();
-        overlayCategoriesToDisable.stream()
+        final Set<String> overlayCategoriesToDisable = new HashSet<>(THEME_CATEGORIES);
+        overlayCategoriesToDisable.removeAll(categoryToPackage.keySet());
+        final Set<String> targetPackagesToQuery = overlayCategoriesToDisable.stream()
                 .map(category -> mCategoryToTargetPackage.get(category))
-                .collect(Collectors.toSet())
-                .forEach(targetPackage -> overlays.addAll(mOverlayManager
-                        .getOverlayInfosForTarget(targetPackage, UserHandle.SYSTEM)));
-        overlays.stream()
+                .collect(Collectors.toSet());
+        final List<OverlayInfo> overlays = new ArrayList<>();
+        targetPackagesToQuery.forEach(targetPackage -> overlays.addAll(mOverlayManager
+                .getOverlayInfosForTarget(targetPackage, UserHandle.SYSTEM)));
+        final Map<String, String> overlaysToDisable = overlays.stream()
                 .filter(o ->
                         mTargetPackageToCategories.get(o.targetPackageName).contains(o.category))
                 .filter(o -> overlayCategoriesToDisable.contains(o.category))
                 .filter(o -> o.isEnabled())
-                .forEach(o -> setEnabled(o.packageName, o.category, userHandles, false));
+                .collect(Collectors.toMap((o) -> o.category, (o) -> o.packageName));
 
-
-        // Enable all overlays specified in the user setting.
-        overlayCategoriesToEnable.forEach((category) ->
-                setEnabled(categoryToPackage.get(category), category, userHandles, true));
+        // Toggle overlays in the order of THEME_CATEGORIES.
+        for (String category : THEME_CATEGORIES) {
+            if (categoryToPackage.containsKey(category)) {
+                setEnabled(categoryToPackage.get(category), category, userHandles, true);
+            } else if (overlaysToDisable.containsKey(category)) {
+                setEnabled(overlaysToDisable.get(category), category, userHandles, false);
+            }
+        }
     }
 
     private void setEnabled(
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index ffe3ece..6bed43e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -288,7 +288,7 @@
         mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(true);
         mTestableLooper.processAllMessages();
 
-        verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any());
+        verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
         verify(mFaceManager).isHardwareDetected();
         verify(mFaceManager).hasEnrolledTemplates(anyInt());
     }
@@ -298,7 +298,7 @@
         mKeyguardUpdateMonitor.dispatchStartedWakingUp();
         mTestableLooper.processAllMessages();
         mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
-        verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any());
+        verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
     }
 
     @Test
@@ -317,7 +317,7 @@
         mKeyguardUpdateMonitor.setKeyguardOccluded(true);
         mKeyguardUpdateMonitor.setAssistantVisible(true);
 
-        verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any());
+        verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/DumpControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/DumpControllerTest.kt
new file mode 100644
index 0000000..cca35ca
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/DumpControllerTest.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+import java.io.FileDescriptor
+import java.io.PrintWriter
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class DumpControllerTest : SysuiTestCase() {
+
+    private lateinit var controller: DumpController
+    @Mock private lateinit var callback1: Dumpable
+    @Mock private lateinit var callback2: Dumpable
+    @Mock private lateinit var fd: FileDescriptor
+    @Mock private lateinit var pw: PrintWriter
+    private val args = emptyArray<String>()
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        controller = DumpController()
+//        Debug.waitForDebugger()
+    }
+
+    @Test
+    fun testListenerOnlyAddedOnce() {
+        controller.apply {
+            addListener(callback1)
+            addListener(callback1)
+        }
+        assertEquals(1, controller.numListeners)
+
+        controller.dump(fd, pw, args)
+        verify(callback1 /* only once */).dump(fd, pw, args)
+    }
+
+    @Test
+    fun testListenersCalledOnDump() {
+        controller.apply {
+            addListener(callback1)
+            addListener(callback2)
+        }
+
+        controller.dump(fd, pw, args)
+
+        verify(callback1 /* only once */).dump(fd, pw, args)
+        verify(callback2 /* only once */).dump(fd, pw, args)
+    }
+
+    @Test
+    fun testRemoveListener() {
+        controller.apply {
+            addListener(callback1)
+            addListener(callback2)
+            removeListener(callback1)
+        }
+
+        controller.dump(fd, pw, args)
+
+        verify(callback1, never()).dump(any(), any(), any())
+        verify(callback2 /* only once */).dump(fd, pw, args)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java
index 34a726d..7d2ccdc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java
@@ -96,21 +96,21 @@
     @Test
     public void testCreateNavigationBarsIncludeDefaultTrue() {
         initializeDisplayManager();
-        doNothing().when(mNavigationBarController).createNavigationBar(any());
+        doNothing().when(mNavigationBarController).createNavigationBar(any(), any());
 
-        mNavigationBarController.createNavigationBars(true);
+        mNavigationBarController.createNavigationBars(true, null);
 
-        verify(mNavigationBarController).createNavigationBar(any(Display.class));
+        verify(mNavigationBarController).createNavigationBar(any(Display.class), any());
     }
 
     @Test
     public void testCreateNavigationBarsIncludeDefaultFalse() {
         initializeDisplayManager();
-        doNothing().when(mNavigationBarController).createNavigationBar(any());
+        doNothing().when(mNavigationBarController).createNavigationBar(any(), any());
 
-        mNavigationBarController.createNavigationBars(false);
+        mNavigationBarController.createNavigationBars(false, null);
 
-        verify(mNavigationBarController, never()).createNavigationBar(any());
+        verify(mNavigationBarController, never()).createNavigationBar(any(), any());
     }
 
     private void initializeDisplayManager() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java
index da039a4..a904704 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java
@@ -51,7 +51,9 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.InOrder;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 import java.util.HashMap;
@@ -134,6 +136,17 @@
     }
 
     @Test
+    public void allCategoriesSpecified_enabledInOrder() {
+        mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, TEST_USER_HANDLES);
+
+        InOrder inOrder = Mockito.inOrder(mOverlayManager);
+        for (String category : THEME_CATEGORIES) {
+            inOrder.verify(mOverlayManager)
+                    .setEnabledExclusiveInCategory(ALL_CATEGORIES_MAP.get(category), TEST_USER);
+        }
+    }
+
+    @Test
     public void allCategoriesSpecified_sysuiCategoriesAlsoAppliedToSysuiUser() {
         mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, TEST_USER_HANDLES);
 
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_clear.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_clear.xml
deleted file mode 100644
index 59af013..0000000
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_clear.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="24dp"
-    android:viewportHeight="24"
-    android:viewportWidth="24"
-    android:width="24dp" >
-    <path
-        android:fillColor="#000000"
-        android:pathData="M9,20h6c1.66,0,3-1.34,3-3V6h0.5c0.41,0,0.75-0.34,0.75-0.75S18.91,4.5,18.5,4.5H18h-3l-1-1h-4l-1,1H6H5.5 c-0.41,0-0.75,0.34-0.75,0.75S5.09,6,5.5,6H6v11C6,18.66,7.34,20,9,20z M16.5,6v11c0,0.83-0.67,1.5-1.5,1.5H9 c-0.83,0-1.5-0.67-1.5-1.5V6H16.5z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M13.97,16c0.41,0,0.75-0.34,0.75-0.75v-6.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v6.5 C13.22,15.66,13.55,16,13.97,16z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M10,16c0.41,0,0.75-0.34,0.75-0.75v-6.5C10.75,8.34,10.41,8,10,8S9.25,8.34,9.25,8.75v6.5C9.25,15.66,9.59,16,10,16z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml
index b6f7777..798907c 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml
@@ -16,10 +16,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorHint"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M16,4c0-1.1-0.9-2-2-2h-4C8.9,2,8,2.9,8,4v2H2v12c0,1.66,1.34,3,3,3h14c1.66,0,3-1.34,3-3V6h-6V4z M9.5,4 c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5v2h-5V4z M20.5,7.5V18c0,0.83-0.67,1.5-1.5,1.5H5c-0.83,0-1.5-0.67-1.5-1.5V7.5 H20.5z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_drag_handle.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_drag_handle.xml
new file mode 100644
index 0000000..a7ab99e
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_drag_handle.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorHint">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M4.75,10.5h14.5c0.41,0,0.75-0.34,0.75-0.75S19.66,9,19.25,9H4.75C4.34,9,4,9.34,4,9.75S4.34,10.5,4.75,10.5z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M4.75,15h14.5c0.41,0,0.75-0.34,0.75-0.75s-0.34-0.75-0.75-0.75H4.75C4.34,13.5,4,13.84,4,14.25S4.34,15,4.75,15z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_hourglass_top.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_hourglass_top.xml
new file mode 100644
index 0000000..8160e68
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_hourglass_top.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M7,6.8c0,2.23,1.22,4.16,3.02,5.2C8.22,13.04,7,14.97,7,17.2V22h10v-4.8c0-2.23-1.22-4.16-3.02-5.2
+C15.78,10.96,17,9.03,17,6.8V2H7V6.8z
+M15.5,17.2v3.3h-7v-3.3c0-1.6,0.87-3.1,2.26-3.9L12,12.59l1.24,0.71
+C14.63,14.1,15.5,15.6,15.5,17.2z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_info_no_shadow.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_info_no_shadow.xml
index 7bd6028..82924bb 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_info_no_shadow.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_info_no_shadow.xml
@@ -16,16 +16,16 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12C22,6.48,17.52,2,11.99,2z M11.99,20.5 c-4.68,0-8.49-3.81-8.49-8.5c0-4.69,3.81-8.5,8.49-8.5c4.69,0,8.51,3.81,8.51,8.5C20.5,16.69,16.68,20.5,11.99,20.5z" />
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z" />
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_palette.xml
similarity index 87%
rename from packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml
rename to packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_palette.xml
index e58c7b8..964955b 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_palette.xml
@@ -16,7 +16,7 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <group
@@ -26,20 +26,20 @@
             android:translateX="2.000000"
             android:translateY="2.000000" >
             <path
-                android:fillColor="#000000"
+                android:fillColor="@android:color/white"
                 android:pathData="M-109-356.5c4.69,0,8.5,3.36,8.5,7.5c0,2.48-2.02,4.5-4.5,4.5h-1.77c-1.1,0-2,0.9-2,2 c0,0.45,0.16,0.89,0.46,1.27l0.02,0.02l0.02,0.02c0.17,0.2,0.27,0.44,0.27,0.68c0,0.55-0.45,1-1,1c-4.69,0-8.5-3.81-8.5-8.5 S-113.69-356.5-109-356.5 M-109-358c-5.51,0-10,4.49-10,10s4.49,10,10,10c1.38,0,2.5-1.12,2.5-2.5c0-0.61-0.23-1.2-0.64-1.67 c-0.08-0.1-0.13-0.21-0.13-0.33c0-0.28,0.22-0.5,0.5-0.5h1.77c3.31,0,6-2.69,6-6C-99-353.96-103.49-358-109-358L-109-358z" />
         </group>
     </group>
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M 6.5 10 C 7.32842712475 10 8 10.6715728753 8 11.5 C 8 12.3284271247 7.32842712475 13 6.5 13 C 5.67157287525 13 5 12.3284271247 5 11.5 C 5 10.6715728753 5.67157287525 10 6.5 10 Z" />
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M 9.5 6 C 10.3284271247 6 11 6.67157287525 11 7.5 C 11 8.32842712475 10.3284271247 9 9.5 9 C 8.67157287525 9 8 8.32842712475 8 7.5 C 8 6.67157287525 8.67157287525 6 9.5 6 Z" />
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M 14.5 6 C 15.3284271247 6 16 6.67157287525 16 7.5 C 16 8.32842712475 15.3284271247 9 14.5 9 C 13.6715728753 9 13 8.32842712475 13 7.5 C 13 6.67157287525 13.6715728753 6 14.5 6 Z" />
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M 17.5 10 C 18.3284271247 10 19 10.6715728753 19 11.5 C 19 12.3284271247 18.3284271247 13 17.5 13 C 16.6715728753 13 16 12.3284271247 16 11.5 C 16 10.6715728753 16.6715728753 10 17.5 10 Z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_pin.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_pin.xml
new file mode 100644
index 0000000..35c0b81
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_pin.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M4.63,14.62C4.24,15.21,4.66,16,5.37,16h5.88c0,0,0,0,0,0v6.25c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75V16
+c0,0,0,0,0,0h5.84c0.71,0,1.13-0.79,0.74-1.38c-0.84-1.25-1.99-2.26-3.33-2.95V4.5h1.23c0.41,0,0.75-0.34,0.75-0.75
+S17.65,3,17.23,3H6.73C6.32,3,5.98,3.34,5.98,3.75S6.32,4.5,6.73,4.5H8v7.15C6.64,12.34,5.48,13.36,4.63,14.62z
+M14.5,4.5v8.08
+L15.32,13c0.75,0.39,1.43,0.89,2,1.5H6.64c0.58-0.61,1.27-1.12,2.03-1.51l0.82-0.42V4.5H14.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_remove_no_shadow.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
index 458223d..5fa740d 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
@@ -16,10 +16,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M3.97,20.03c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L12,13.06l6.97,6.97c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L13.06,12l6.97-6.97c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0L12,10.94 L5.03,3.97c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12l-6.97,6.97C3.68,19.26,3.68,19.74,3.97,20.03z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml
index abb1b54..afa0a15 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml
@@ -16,10 +16,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M12,8.5c-1.93,0-3.5,1.57-3.5,3.5s1.57,3.5,3.5,3.5c1.93,0,3.5-1.57,3.5-3.5S13.93,8.5,12,8.5z M12,14c-1.1,0-2-0.9-2-2 s0.9-2,2-2c1.1,0,2,0.9,2,2S13.1,14,12,14z M21.29,13.9l-1.83-1.05c-0.3-0.17-0.49-0.49-0.48-0.84v-0.01 c0-0.35,0.18-0.67,0.48-0.84l1.83-1.05c0.48-0.28,0.64-0.89,0.37-1.37l-2-3.46c-0.19-0.32-0.52-0.5-0.87-0.5 c-0.17,0-0.34,0.04-0.5,0.13l-1.84,1.06c-0.14,0.08-0.29,0.12-0.45,0.12c-0.17,0-0.35-0.05-0.5-0.14c0,0-0.01,0-0.01-0.01 C15.2,5.77,15,5.47,15,5.12V3c0-0.55-0.45-1-1-1h-4C9.45,2,9,2.45,9,3v2.12c0,0.34-0.2,0.65-0.5,0.82c0,0-0.01,0-0.01,0.01 c-0.16,0.09-0.33,0.14-0.5,0.14c-0.15,0-0.31-0.04-0.45-0.12L5.71,4.9c-0.16-0.09-0.33-0.13-0.5-0.13c-0.35,0-0.68,0.18-0.87,0.5 l-2,3.46C2.06,9.21,2.23,9.82,2.71,10.1l1.83,1.05c0.3,0.17,0.49,0.49,0.48,0.84v0.01c0,0.35-0.18,0.67-0.48,0.84L2.71,13.9 c-0.48,0.28-0.64,0.89-0.37,1.37l2,3.46c0.19,0.32,0.52,0.5,0.87,0.5c0.17,0,0.34-0.04,0.5-0.13l1.84-1.06 c0.14-0.08,0.29-0.12,0.45-0.12c0.17,0,0.35,0.05,0.5,0.14c0,0,0.01,0,0.01,0.01C8.8,18.23,9,18.53,9,18.88V21c0,0.55,0.45,1,1,1h4 c0.55,0,1-0.45,1-1v-2.12c0-0.34,0.2-0.65,0.5-0.82c0,0,0.01,0,0.01-0.01c0.16-0.09,0.33-0.14,0.5-0.14c0.15,0,0.31,0.04,0.45,0.12 l1.84,1.06c0.16,0.09,0.33,0.13,0.5,0.13c0.35,0,0.68-0.18,0.87-0.5l2-3.46C21.94,14.79,21.77,14.18,21.29,13.9z M18.61,17.55 l-1.41-0.81c-0.36-0.21-0.78-0.32-1.2-0.32c-0.43,0-0.86,0.12-1.25,0.34c-0.77,0.44-1.25,1.25-1.25,2.12v1.62h-3v-1.62 c0-0.87-0.48-1.68-1.26-2.12c-0.38-0.22-0.81-0.33-1.25-0.33c-0.42,0-0.84,0.11-1.2,0.32l-1.41,0.81l-1.5-2.6l1.39-0.8 c0.76-0.44,1.24-1.26,1.23-2.15c0-0.88-0.47-1.7-1.23-2.14l-1.39-0.8l1.5-2.6L6.8,7.26c0.36,0.21,0.78,0.32,1.2,0.32 c0.43,0,0.86-0.12,1.25-0.34c0.77-0.44,1.25-1.25,1.25-2.12V3.5h3v1.62c0,0.87,0.48,1.68,1.26,2.12c0.38,0.22,0.81,0.33,1.25,0.33 c0.42,0,0.84-0.11,1.2-0.32l1.41-0.81l1.5,2.6l-1.39,0.8c-0.76,0.44-1.24,1.26-1.23,2.15c0,0.88,0.47,1.7,1.23,2.14l1.39,0.8 L18.61,17.55z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_smartspace_preferences.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
index f588c16..b7d31a2 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
@@ -16,10 +16,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M15.08,8.01c-0.39-0.39-0.91-0.59-1.42-0.59c-0.51,0-1.02,0.2-1.41,0.59L0.59,19.67l3.75,3.75l11.66-11.66 c0.78-0.78,0.78-2.04,0.01-2.82L15.08,8.01z M4.34,21.29l-1.63-1.63l7.45-7.45l1.63,1.63L4.34,21.29z M14.93,10.7l-2.09,2.09 l-1.63-1.63l2.09-2.09c0.13-0.13,0.28-0.15,0.35-0.15c0.08,0,0.23,0.02,0.36,0.15l0.92,0.93C15.13,10.18,15.13,10.5,14.93,10.7z M17.67,5.25h1.08v1.08c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75V5.25h1.08c0.41,0,0.75-0.34,0.75-0.75 s-0.34-0.75-0.75-0.75h-1.08V2.67c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v1.08h-1.08c-0.41,0-0.75,0.34-0.75,0.75 S17.26,5.25,17.67,5.25z M5.67,5.25h1.08v1.08c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75V5.25h1.08 c0.41,0,0.75-0.34,0.75-0.75S9.74,3.75,9.33,3.75H8.25V2.67c0-0.41-0.34-0.75-0.75-0.75S6.75,2.26,6.75,2.67v1.08H5.67 c-0.41,0-0.75,0.34-0.75,0.75S5.26,5.25,5.67,5.25z M21.33,15.75h-1.08v-1.08c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75 v1.08h-1.08c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h1.08v1.08c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.08 h1.08c0.41,0,0.75-0.34,0.75-0.75S21.74,15.75,21.33,15.75z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_split_screen.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_split_screen.xml
index 081f2d8..649e555 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_split_screen.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_split_screen.xml
@@ -16,13 +16,13 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M4,6v3c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V6c0-1.1-0.9-2-2-2H6C4.9,4,4,4.9,4,6z M18.5,6v3c0,0.28-0.22,0.5-0.5,0.5H6 C5.72,9.5,5.5,9.28,5.5,9V6c0-0.28,0.22-0.5,0.5-0.5h12C18.28,5.5,18.5,5.72,18.5,6z" />
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M4,18c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-3c0-1.1-0.9-2-2-2H6c-1.1,0-2,0.9-2,2V18z M5.5,15c0-0.28,0.22-0.5,0.5-0.5h12 c0.28,0,0.5,0.22,0.5,0.5v3c0,0.28-0.22,0.5-0.5,0.5H6c-0.28,0-0.5-0.22-0.5-0.5V15z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_warning.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_warning.xml
index f9e7423..e78ae9a 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_warning.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_warning.xml
@@ -16,16 +16,16 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M4.47,21h15.06c1.54,0,2.5-1.67,1.73-3L13.73,4.99c-0.39-0.67-1.06-1-1.73-1s-1.35,0.33-1.73,1L2.74,18 C1.97,19.33,2.93,21,4.47,21z M4.04,18.75l7.53-13.01c0.13-0.22,0.33-0.25,0.43-0.25s0.31,0.03,0.43,0.25l7.53,13.01 c0.13,0.22,0.05,0.41,0,0.5c-0.05,0.09-0.18,0.25-0.43,0.25H4.47c-0.25,0-0.38-0.16-0.43-0.25C3.98,19.16,3.91,18.97,4.04,18.75z" />
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M12,14.75c0.41,0,0.75-0.34,0.75-0.75V9.75C12.75,9.33,12.41,9,12,9s-0.75,0.34-0.75,0.75V14 C11.25,14.41,11.59,14.75,12,14.75z" />
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M 12 16 C 12.5522847498 16 13 16.4477152502 13 17 C 13 17.5522847498 12.5522847498 18 12 18 C 11.4477152502 18 11 17.5522847498 11 17 C 11 16.4477152502 11.4477152502 16 12 16 Z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_widget.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_widget.xml
index 6069818..c3bc349 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_widget.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_widget.xml
@@ -16,19 +16,19 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M11,5c0-1.1-0.9-2-2-2H5C3.9,3,3,3.9,3,5v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2V5z M9.5,9c0,0.28-0.22,0.5-0.5,0.5H5 C4.72,9.5,4.5,9.28,4.5,9V5c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5V9z" />
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M9,13H5c-1.1,0-2,0.9-2,2v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2v-4C11,13.9,10.1,13,9,13z M9.5,19c0,0.28-0.22,0.5-0.5,0.5 H5c-0.28,0-0.5-0.22-0.5-0.5v-4c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5V19z" />
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M19,13h-4c-1.1,0-2,0.9-2,2v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2v-4C21,13.9,20.1,13,19,13z M19.5,19 c0,0.28-0.22,0.5-0.5,0.5h-4c-0.28,0-0.5-0.22-0.5-0.5v-4c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5V19z" />
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M18.41,2.76c-0.39-0.39-0.9-0.59-1.41-0.59s-1.02,0.2-1.41,0.59l-2.83,2.83c-0.78,0.78-0.78,2.05,0,2.83l2.83,2.83 c0.39,0.39,0.9,0.59,1.41,0.59s1.02-0.2,1.41-0.59l2.83-2.83c0.78-0.78,0.78-2.05,0-2.83L18.41,2.76z M20.18,7.35l-2.83,2.83 c-0.13,0.13-0.28,0.15-0.35,0.15s-0.23-0.02-0.35-0.15l-2.83-2.83C13.69,7.23,13.67,7.08,13.67,7s0.02-0.23,0.15-0.35l2.83-2.83 c0.13-0.13,0.28-0.15,0.35-0.15s0.23,0.02,0.35,0.15l2.83,2.83c0.13,0.13,0.15,0.28,0.15,0.35S20.31,7.23,20.18,7.35z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_clear.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_clear.xml
deleted file mode 100644
index 49e7f1d..0000000
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_clear.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="24dp"
-    android:viewportHeight="24"
-    android:viewportWidth="24"
-    android:width="24dp" >
-    <path
-        android:fillColor="#000000"
-        android:pathData="M20,4h-1h-4c0-0.55-0.45-1-1-1h-4C9.45,3,9,3.45,9,4H5H4C3.59,4,3.25,4.34,3.25,4.75S3.59,5.5,4,5.5h1V18 c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V5.5h1c0.41,0,0.75-0.34,0.75-0.75S20.41,4,20,4z M17.5,18c0,0.83-0.67,1.5-1.5,1.5H8 c-0.83,0-1.5-0.67-1.5-1.5V5.5h11V18z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M14.25,8c-0.41,0-0.75,0.34-0.75,0.75v7.5c0,0.41,0.34,0.75,0.75,0.75S15,16.66,15,16.25v-7.5C15,8.34,14.66,8,14.25,8z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M9.75,8C9.34,8,9,8.34,9,8.75v7.5C9,16.66,9.34,17,9.75,17s0.75-0.34,0.75-0.75v-7.5C10.5,8.34,10.16,8,9.75,8z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml
index f7b7f77..76d8882 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml
@@ -16,10 +16,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorHint"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M20,6h-4V4c0-1.1-0.9-2-2-2h-4C8.9,2,8,2.9,8,4v2H4C2.9,6,2,6.9,2,8v11c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8 C22,6.9,21.1,6,20,6z M9.5,4c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5v2h-5V4z M20.5,19c0,0.28-0.22,0.5-0.5,0.5H4 c-0.28,0-0.5-0.22-0.5-0.5V8c0-0.28,0.22-0.5,0.5-0.5h16c0.28,0,0.5,0.22,0.5,0.5V19z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M20,6h-4V4c0-1.11-0.89-2-2-2h-4C8.89,2,8,2.89,8,4v2H4C2.89,6,2.01,6.89,2.01,8L2,19c0,1.11,0.89,2,2,2h16 c1.11,0,2-0.89,2-2V8C22,6.89,21.11,6,20,6z M14,6h-4V4h4V6z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_drag_handle.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_drag_handle.xml
new file mode 100644
index 0000000..3117ae1
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_drag_handle.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorHint">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M19,13H5c-0.55,0-1,0.45-1,1s0.45,1,1,1h14c0.55,0,1-0.45,1-1S19.55,13,19,13z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M19,9H5c-0.55,0-1,0.45-1,1s0.45,1,1,1h14c0.55,0,1-0.45,1-1S19.55,9,19,9z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_hourglass_top.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_hourglass_top.xml
new file mode 100644
index 0000000..b389e4b
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_hourglass_top.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M17,2H7C6.45,2,6,2.45,6,3l0.01,3.75c0,0.79,0.32,1.55,0.87,2.11L10,12l-3.12,3.12c-0.56,0.56-0.87,1.32-0.88,2.11L6,21
+c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1v-3.77c0-0.8-0.32-1.56-0.88-2.12L14,12l3.12-3.13C17.68,8.31,18,7.54,18,6.75V3
+C18,2.45,17.55,2,17,2z
+M15.71,16.21c0.19,0.19,0.29,0.44,0.29,0.71V20H8v-3.09c0-0.27,0.11-0.52,0.29-0.71L12,12.5L15.71,16.21z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_info_no_shadow.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_info_no_shadow.xml
index 6c9c732..f50fa2b 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_info_no_shadow.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_info_no_shadow.xml
@@ -16,16 +16,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M4.92,4.94c-3.9,3.91-3.9,10.24,0.01,14.14s10.24,3.9,14.14-0.01C20.95,17.2,22,14.65,22,12c0-2.65-1.06-5.19-2.93-7.07 C15.16,1.03,8.83,1.03,4.92,4.94z M18,18c-1.6,1.59-3.76,2.48-6.02,2.48c-4.69-0.01-8.49-3.83-8.48-8.52 c0.01-4.69,3.83-8.49,8.52-8.48c4.69,0.01,8.49,3.83,8.48,8.52C20.49,14.25,19.6,16.41,18,18z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,17c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-5c0-0.55,0.45-1,1-1s1,0.45,1,1V17z M12,9.25c-0.69,0-1.25-0.56-1.25-1.25S11.31,6.75,12,6.75S13.25,7.31,13.25,8 S12.69,9.25,12,9.25z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_wallpaper.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_palette.xml
similarity index 90%
rename from packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_wallpaper.xml
rename to packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_palette.xml
index 880b2abc..e9a89ec 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_wallpaper.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_palette.xml
@@ -16,10 +16,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M12,2C6.49,2,2,6.49,2,12s4.49,10,10,10c1.38,0,2.5-1.12,2.5-2.5c0-0.61-0.23-1.2-0.64-1.67c-0.08-0.1-0.13-0.21-0.13-0.33 c0-0.28,0.22-0.5,0.5-0.5H16c3.31,0,6-2.69,6-6C22,6.04,17.51,2,12,2z M6.5,13C5.67,13,5,12.33,5,11.5S5.67,10,6.5,10 S8,10.67,8,11.5S7.33,13,6.5,13z M9.5,9C8.67,9,8,8.33,8,7.5S8.67,6,9.5,6S11,6.67,11,7.5S10.33,9,9.5,9z M14.5,9 C13.67,9,13,8.33,13,7.5S13.67,6,14.5,6S16,6.67,16,7.5S15.33,9,14.5,9z M17.5,13c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5 s1.5,0.67,1.5,1.5S18.33,13,17.5,13z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_pin.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_pin.xml
new file mode 100644
index 0000000..698f718
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_pin.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M5.71,14.29C5.08,14.92,5.52,16,6.41,16H11v6c0,0.55,0.45,1,1,1s1-0.45,1-1v-6h4.59c0.89,0,1.34-1.08,0.71-1.71L16,12V5
+h0.5c0.55,0,1-0.45,1-1s-0.45-1-1-1h-9c-0.55,0-1,0.45-1,1s0.45,1,1,1H8v7L5.71,14.29z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_remove_no_shadow.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
index 82c2a31..b3288d9 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
@@ -16,10 +16,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M5.22,18.78C5.37,18.93,5.56,19,5.75,19s0.38-0.07,0.53-0.22L12,13.06l5.72,5.72c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L13.06,12l5.72-5.72c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0L12,10.94 L6.28,5.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12l-5.72,5.72C4.93,18.01,4.93,18.49,5.22,18.78z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M5.7,18.3c0.39,0.39,1.02,0.39,1.41,0L12,13.41l4.89,4.89c0.39,0.39,1.02,0.39,1.41,0s0.39-1.02,0-1.41L13.41,12l4.89-4.89 c0.38-0.38,0.38-1.02,0-1.4c-0.39-0.39-1.02-0.39-1.41,0c0,0,0,0,0,0L12,10.59L7.11,5.7c-0.39-0.39-1.02-0.39-1.41,0 s-0.39,1.02,0,1.41L10.59,12L5.7,16.89C5.31,17.28,5.31,17.91,5.7,18.3z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml
index c4c5eaa..513633b 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml
@@ -16,13 +16,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M2.43,15.45l1.79,3.09c0.25,0.45,0.74,0.73,1.25,0.73c0.17,0,0.35-0.03,0.52-0.09l1.76-0.7c0.25,0.17,0.51,0.31,0.77,0.45 l0.26,1.84c0.09,0.71,0.69,1.24,1.42,1.24h3.61c0.72,0,1.33-0.53,1.43-1.19l0.26-1.86c0.25-0.14,0.51-0.28,0.76-0.45l1.76,0.7 c0.17,0.07,0.35,0.1,0.53,0.1c0.5,0,0.98-0.27,1.23-0.72l1.82-3.14c0.34-0.61,0.19-1.38-0.36-1.82l-1.48-1.16 c0.01-0.15,0.02-0.29,0.02-0.45s-0.01-0.3-0.02-0.45l1.48-1.16c0.55-0.43,0.7-1.19,0.35-1.84l-1.8-3.1 c-0.25-0.45-0.74-0.73-1.26-0.73c-0.17,0-0.35,0.03-0.52,0.09l-1.76,0.7c-0.25-0.17-0.51-0.31-0.77-0.45l-0.26-1.84 c-0.09-0.71-0.69-1.24-1.42-1.24h-3.61c-0.71,0-1.32,0.54-1.41,1.22L8.52,5.09C8.26,5.23,8.01,5.37,7.75,5.54L5.99,4.83 c-0.17-0.07-0.35-0.1-0.52-0.1c-0.5,0-0.98,0.27-1.22,0.72L2.43,8.55c-0.36,0.61-0.21,1.4,0.36,1.84l1.48,1.16 C4.27,11.7,4.26,11.85,4.26,12c0,0.16,0.01,0.3,0.02,0.45l-1.49,1.16C2.24,14.04,2.09,14.8,2.43,15.45z M5.2,13.63l0.63-0.49 l-0.05-0.79c-0.01-0.11-0.01-0.58,0-0.7l0.05-0.79L5.2,10.37L3.77,9.25l1.74-3l1.69,0.68l0.73,0.29l0.66-0.43 c0.19-0.13,0.4-0.25,0.65-0.38l0.67-0.36L10,5.3l0.25-1.79h3.48l0.26,1.8l0.11,0.76l0.69,0.36c0.23,0.12,0.44,0.24,0.64,0.37 l0.65,0.43l0.72-0.29l1.7-0.68l1.75,3.02l-1.43,1.12l-0.62,0.49l0.05,0.79c0.01,0.11,0.01,0.58,0,0.7l-0.05,0.79l0.62,0.49 l1.43,1.12l-1.74,3.02l-1.69-0.68l-0.72-0.29l-0.65,0.43c-0.19,0.13-0.4,0.25-0.65,0.38l-0.67,0.36l-0.11,0.75l-0.25,1.77h-3.5 L10,18.71l-0.11-0.76l-0.69-0.36c-0.23-0.12-0.44-0.24-0.64-0.37l-0.65-0.43l-0.72,0.29L5.5,17.76l-1.73-3.01L5.2,13.63z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,16c2.21,0,4-1.79,4-4s-1.79-4-4-4c-2.21,0-4,1.79-4,4S9.79,16,12,16z M12,9.5c1.38,0,2.5,1.12,2.5,2.5 s-1.12,2.5-2.5,2.5c-1.38,0-2.5-1.12-2.5-2.5S10.62,9.5,12,9.5z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M21.64,8.39l-1.6-2.76c-0.28-0.48-0.88-0.7-1.36-0.5l-2.14,0.91c-0.48-0.37-1.01-0.68-1.57-0.92l-0.27-2.2 C14.64,2.4,14.14,2,13.59,2h-3.18C9.86,2,9.36,2.4,9.3,2.92L9.04,5.11c-0.57,0.24-1.1,0.55-1.58,0.92L5.32,5.12 c-0.48-0.2-1.08,0.02-1.36,0.5l-1.6,2.76C2.08,8.86,2.18,9.48,2.6,9.8l1.94,1.45C4.51,11.49,4.5,11.74,4.5,12s0.01,0.51,0.04,0.76 L2.6,14.2c-0.42,0.31-0.52,0.94-0.24,1.41l1.6,2.76c0.28,0.48,0.88,0.7,1.36,0.5l2.14-0.91c0.48,0.37,1.01,0.68,1.57,0.92 l0.27,2.19C9.36,21.6,9.86,22,10.41,22h3.18c0.55,0,1.04-0.4,1.11-0.92l0.27-2.19c0.56-0.24,1.09-0.55,1.57-0.92l2.14,0.91 c0.48,0.2,1.08-0.02,1.36-0.5l1.6-2.76c0.28-0.48,0.18-1.1-0.24-1.42l-1.94-1.45c0.03-0.25,0.04-0.5,0.04-0.76 s-0.01-0.51-0.04-0.76L21.4,9.8C21.82,9.49,21.92,8.86,21.64,8.39z M12,15.5c-1.93,0-3.5-1.57-3.5-3.5s1.57-3.5,3.5-3.5 s3.5,1.57,3.5,3.5S13.93,15.5,12,15.5z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_smartspace_preferences.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
index 790248a..4ca2967 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
@@ -16,10 +16,16 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M14.38,7.3C14.18,7.1,13.92,7,13.66,7c-0.26,0-0.51,0.1-0.71,0.29L1.29,18.96c-0.39,0.39-0.39,1.02,0,1.41l2.34,2.34 C3.82,22.9,4.08,23,4.34,23s0.51-0.1,0.71-0.29L16.7,11.05c0.39-0.39,0.39-1.02,0-1.41L14.38,7.3z M4.34,21.29l-1.63-1.63 l7.45-7.45l1.63,1.63L4.34,21.29z M12.84,12.78l-1.63-1.63l2.45-2.45l1.62,1.64L12.84,12.78z M17.75,5.25h1v1 C18.75,6.66,19.09,7,19.5,7s0.75-0.34,0.75-0.75v-1h1C21.66,5.25,22,4.91,22,4.5s-0.34-0.75-0.75-0.75h-1v-1 C20.25,2.34,19.91,2,19.5,2s-0.75,0.34-0.75,0.75v1h-1C17.34,3.75,17,4.09,17,4.5S17.34,5.25,17.75,5.25z M5.75,5.25h1v1 C6.75,6.66,7.09,7,7.5,7s0.75-0.34,0.75-0.75v-1h1C9.66,5.25,10,4.91,10,4.5S9.66,3.75,9.25,3.75h-1v-1C8.25,2.34,7.91,2,7.5,2 S6.75,2.34,6.75,2.75v1h-1C5.34,3.75,5,4.09,5,4.5S5.34,5.25,5.75,5.25z M21.25,15.75h-1v-1c0-0.41-0.34-0.75-0.75-0.75 s-0.75,0.34-0.75,0.75v1h-1c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h1v1c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75 v-1h1c0.41,0,0.75-0.34,0.75-0.75S21.66,15.75,21.25,15.75z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M21.23,2.43L19.5,3.4l-1.73-0.97c-0.22-0.12-0.46,0.12-0.34,0.34L18.4,4.5l-0.97,1.73c-0.12,0.22,0.12,0.46,0.34,0.34 L19.5,5.6l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L20.6,4.5l0.97-1.73C21.69,2.55,21.45,2.31,21.23,2.43z M14.37,7.29 c-0.39-0.39-1.02-0.39-1.41,0L1.29,18.96c-0.39,0.39-0.39,1.02,0,1.41l2.34,2.34c0.39,0.39,1.02,0.39,1.41,0L16.7,11.05 c0.39-0.39,0.39-1.02,0-1.41L14.37,7.29z M13.34,12.78l-2.12-2.12l2.44-2.44l2.12,2.12L13.34,12.78z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M21.23,14.43L19.5,15.4l-1.73-0.97c-0.22-0.12-0.46,0.12-0.34,0.34l0.97,1.73l-0.97,1.73c-0.12,0.22,0.12,0.46,0.34,0.34 l1.73-0.97l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L20.6,16.5l0.97-1.73C21.69,14.55,21.45,14.31,21.23,14.43z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M9.23,2.43L7.5,3.4L5.77,2.43C5.55,2.31,5.31,2.55,5.43,2.77L6.4,4.5L5.43,6.23C5.31,6.45,5.55,6.69,5.77,6.57L7.5,5.6 l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L8.6,4.5l0.97-1.73C9.69,2.55,9.45,2.31,9.23,2.43z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_split_screen.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_split_screen.xml
index 013b40f..6eddf3d 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_split_screen.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_split_screen.xml
@@ -16,13 +16,13 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M5,11h14c0.55,0,1-0.45,1-1V4c0-0.55-0.45-1-1-1H5C4.45,3,4,3.45,4,4v6C4,10.55,4.45,11,5,11z M5.5,4.5h13v5h-13V4.5z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M18,2H6C4.9,2,4,2.9,4,4v5c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V4C20,2.9,19.1,2,18,2z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M4,20c0,0.55,0.45,1,1,1h14c0.55,0,1-0.45,1-1v-6c0-0.55-0.45-1-1-1H5c-0.55,0-1,0.45-1,1V20z M5.5,14.5h13v5h-13V14.5z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M18,13H6c-1.1,0-2,0.9-2,2v5c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-5C20,13.9,19.1,13,18,13z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_wallpaper.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_wallpaper.xml
deleted file mode 100644
index e58c7b8..0000000
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_wallpaper.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="24dp"
-    android:viewportHeight="24"
-    android:viewportWidth="24"
-    android:width="24dp" >
-    <group
-        android:translateX="119.000000"
-        android:translateY="358.000000" >
-        <group
-            android:translateX="2.000000"
-            android:translateY="2.000000" >
-            <path
-                android:fillColor="#000000"
-                android:pathData="M-109-356.5c4.69,0,8.5,3.36,8.5,7.5c0,2.48-2.02,4.5-4.5,4.5h-1.77c-1.1,0-2,0.9-2,2 c0,0.45,0.16,0.89,0.46,1.27l0.02,0.02l0.02,0.02c0.17,0.2,0.27,0.44,0.27,0.68c0,0.55-0.45,1-1,1c-4.69,0-8.5-3.81-8.5-8.5 S-113.69-356.5-109-356.5 M-109-358c-5.51,0-10,4.49-10,10s4.49,10,10,10c1.38,0,2.5-1.12,2.5-2.5c0-0.61-0.23-1.2-0.64-1.67 c-0.08-0.1-0.13-0.21-0.13-0.33c0-0.28,0.22-0.5,0.5-0.5h1.77c3.31,0,6-2.69,6-6C-99-353.96-103.49-358-109-358L-109-358z" />
-        </group>
-    </group>
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 6.5 10 C 7.32842712475 10 8 10.6715728753 8 11.5 C 8 12.3284271247 7.32842712475 13 6.5 13 C 5.67157287525 13 5 12.3284271247 5 11.5 C 5 10.6715728753 5.67157287525 10 6.5 10 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 9.5 6 C 10.3284271247 6 11 6.67157287525 11 7.5 C 11 8.32842712475 10.3284271247 9 9.5 9 C 8.67157287525 9 8 8.32842712475 8 7.5 C 8 6.67157287525 8.67157287525 6 9.5 6 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 14.5 6 C 15.3284271247 6 16 6.67157287525 16 7.5 C 16 8.32842712475 15.3284271247 9 14.5 9 C 13.6715728753 9 13 8.32842712475 13 7.5 C 13 6.67157287525 13.6715728753 6 14.5 6 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 17.5 10 C 18.3284271247 10 19 10.6715728753 19 11.5 C 19 12.3284271247 18.3284271247 13 17.5 13 C 16.6715728753 13 16 12.3284271247 16 11.5 C 16 10.6715728753 16.6715728753 10 17.5 10 Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_warning.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_warning.xml
index 4af8a37..4198759 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_warning.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_warning.xml
@@ -16,16 +16,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M4.47,21h15.06c1.54,0,2.5-1.67,1.73-3L13.73,4.99c-0.39-0.67-1.06-1-1.73-1s-1.35,0.33-1.73,1L2.74,18 C1.97,19.33,2.93,21,4.47,21z M4.04,18.75l7.53-13.01c0.13-0.22,0.33-0.25,0.43-0.25s0.31,0.03,0.43,0.25l7.53,13.01 c0.13,0.22,0.05,0.41,0,0.5c-0.05,0.09-0.18,0.25-0.43,0.25H4.47c-0.25,0-0.38-0.16-0.43-0.25C3.98,19.16,3.91,18.97,4.04,18.75z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,14.5c0.41,0,0.75-0.34,0.75-0.75v-4C12.75,9.33,12.41,9,12,9s-0.75,0.34-0.75,0.75v4C11.25,14.16,11.59,14.5,12,14.5z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 12 16 C 12.5522847498 16 13 16.4477152502 13 17 C 13 17.5522847498 12.5522847498 18 12 18 C 11.4477152502 18 11 17.5522847498 11 17 C 11 16.4477152502 11.4477152502 16 12 16 Z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M12.87,3.49c-0.39-0.67-1.35-0.67-1.73,0l-9.27,16C1.48,20.17,1.96,21,2.73,21h18.53c0.77,0,1.25-0.83,0.87-1.5L12.87,3.49 z M11,10c0-0.55,0.45-1,1-1s1,0.45,1,1v3c0,0.55-0.45,1-1,1s-1-0.45-1-1V10z M12,18.25c-0.69,0-1.25-0.56-1.25-1.25 s0.56-1.25,1.25-1.25s1.25,0.56,1.25,1.25S12.69,18.25,12,18.25z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_widget.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_widget.xml
index 7cbf7f1..7316c02d5 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_widget.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_widget.xml
@@ -16,19 +16,19 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M10,3H4C3.45,3,3,3.45,3,4v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1V4C11,3.45,10.55,3,10,3z M9.5,9.5h-5v-5h5V9.5z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M17.7,2.3c-0.4-0.4-1-0.4-1.4,0l-4,4c-0.4,0.4-0.4,1,0,1.4l4,4c0.4,0.4,1,0.4,1.4,0l4-4c0.4-0.4,0.4-1,0-1.4L17.7,2.3z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M10,13H4c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1v-6C11,13.45,10.55,13,10,13z M9.5,19.5h-5v-5h5 V19.5z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M11,4c0-0.5-0.4-1-1-1H4C3.5,3,3,3.5,3,4v6c0,0.6,0.5,1,1,1h6c0.6,0,1-0.4,1-1V4z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M20,13h-6c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1v-6C21,13.45,20.55,13,20,13z M19.5,19.5h-5v-5h5 V19.5z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M20,21c0.5,0,1-0.5,1-1v-6c0-0.6-0.5-1-1-1h-6c-0.6,0-1,0.4-1,1v6c0,0.5,0.4,1,1,1H20z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M21.95,6.29l-4.24-4.24c-0.2-0.2-0.45-0.29-0.71-0.29s-0.51,0.1-0.71,0.29l-4.24,4.24c-0.39,0.39-0.39,1.02,0,1.41 l4.24,4.24c0.2,0.2,0.45,0.29,0.71,0.29s0.51-0.1,0.71-0.29l4.24-4.24C22.34,7.32,22.34,6.68,21.95,6.29z M17,10.54L13.46,7 L17,3.46L20.54,7L17,10.54z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M10,13H4c-0.5,0-1,0.4-1,1v6c0,0.5,0.5,1,1,1h6c0.6,0,1-0.5,1-1v-6C11,13.4,10.6,13,10,13z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_clear.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_clear.xml
deleted file mode 100644
index d04eb1f..0000000
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_clear.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="24dp"
-    android:viewportHeight="24"
-    android:viewportWidth="24"
-    android:width="24dp" >
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18,4h-2.5l-0.71-0.71C14.61,3.11,14.35,3,14.09,3H9.9C9.64,3,9.38,3.11,9.2,3.29L8.49,4h-2.5c-0.55,0-1,0.45-1,1 s0.45,1,1,1h12c0.55,0,1-0.45,1-1C19,4.45,18.55,4,18,4z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M6,19c0,1.1,0.9,2,2,2h8c1.1,0,2-0.9,2-2V7H6V19z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml
index ed39543..dccc23c 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml
@@ -16,10 +16,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorHint"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M20,6h-4V4c0-1.11-0.89-2-2-2h-4C8.89,2,8,2.89,8,4v2H4C2.89,6,2.01,6.89,2.01,8L2,19c0,1.11,0.89,2,2,2h16 c1.11,0,2-0.89,2-2V8C22,6.89,21.11,6,20,6z M14,6h-4V4h4V6z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M20,6h-4V4c0-1.1-0.9-2-2-2h-4C8.9,2,8,2.9,8,4v2H4C2.9,6,2,6.9,2,8v11c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8 C22,6.9,21.1,6,20,6z M9.5,4c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5v2h-5V4z M20.5,19c0,0.28-0.22,0.5-0.5,0.5H4 c-0.28,0-0.5-0.22-0.5-0.5V8c0-0.28,0.22-0.5,0.5-0.5h16c0.28,0,0.5,0.22,0.5,0.5V19z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_drag_handle.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_drag_handle.xml
new file mode 100644
index 0000000..68c0a80
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_drag_handle.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorHint">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M5.75,10.5h12.5c0.41,0,0.75-0.34,0.75-0.75S18.66,9,18.25,9H5.75C5.34,9,5,9.34,5,9.75S5.34,10.5,5.75,10.5z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M18.25,13.5H5.75C5.34,13.5,5,13.84,5,14.25S5.34,15,5.75,15h12.5c0.41,0,0.75-0.34,0.75-0.75S18.66,13.5,18.25,13.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_hourglass_top.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_hourglass_top.xml
new file mode 100644
index 0000000..0fd3229
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_hourglass_top.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M16,3H8C7.45,3,7,3.45,7,4v1.93v0c0,0.33,0.03,0.66,0.1,0.98c0.19,0.96,0.66,1.85,1.37,2.56L11,12l-2.54,2.54
+C7.53,15.47,7,16.74,7,18.07V20c0,0.55,0.45,1,1,1h8c0.55,0,1-0.45,1-1v-1.93c0-1.33-0.53-2.6-1.46-3.54L13,12l2.54-2.54
+c0.7-0.7,1.18-1.59,1.37-2.56C16.97,6.59,17,6.26,17,5.93v0V4C17,3.45,16.55,3,16,3z
+M14.47,15.6c0.66,0.66,1.03,1.54,1.03,2.47
+v1.43h-7v-1.43c0-0.93,0.36-1.81,1.03-2.47L12,13.12L14.47,15.6z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_info_no_shadow.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_info_no_shadow.xml
index dfa17d6..f799d40 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_info_no_shadow.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_info_no_shadow.xml
@@ -16,10 +16,16 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,17c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-5c0-0.55,0.45-1,1-1s1,0.45,1,1V17z M12,9.25c-0.69,0-1.25-0.56-1.25-1.25S11.31,6.75,12,6.75S13.25,7.31,13.25,8 S12.69,9.25,12,9.25z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M4.92,4.94c-3.9,3.91-3.9,10.24,0.01,14.14s10.24,3.9,14.14-0.01C20.95,17.2,22,14.65,22,12c0-2.65-1.06-5.19-2.93-7.07 C15.16,1.03,8.83,1.03,4.92,4.94z M18,18c-1.6,1.59-3.76,2.48-6.02,2.48c-4.69-0.01-8.49-3.83-8.48-8.52 c0.01-4.69,3.83-8.49,8.52-8.48c4.69,0.01,8.49,3.83,8.48,8.52C20.49,14.25,19.6,16.41,18,18z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_palette.xml
similarity index 87%
copy from packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml
copy to packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_palette.xml
index e58c7b8..964955b 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_palette.xml
@@ -16,7 +16,7 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <group
@@ -26,20 +26,20 @@
             android:translateX="2.000000"
             android:translateY="2.000000" >
             <path
-                android:fillColor="#000000"
+                android:fillColor="@android:color/white"
                 android:pathData="M-109-356.5c4.69,0,8.5,3.36,8.5,7.5c0,2.48-2.02,4.5-4.5,4.5h-1.77c-1.1,0-2,0.9-2,2 c0,0.45,0.16,0.89,0.46,1.27l0.02,0.02l0.02,0.02c0.17,0.2,0.27,0.44,0.27,0.68c0,0.55-0.45,1-1,1c-4.69,0-8.5-3.81-8.5-8.5 S-113.69-356.5-109-356.5 M-109-358c-5.51,0-10,4.49-10,10s4.49,10,10,10c1.38,0,2.5-1.12,2.5-2.5c0-0.61-0.23-1.2-0.64-1.67 c-0.08-0.1-0.13-0.21-0.13-0.33c0-0.28,0.22-0.5,0.5-0.5h1.77c3.31,0,6-2.69,6-6C-99-353.96-103.49-358-109-358L-109-358z" />
         </group>
     </group>
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M 6.5 10 C 7.32842712475 10 8 10.6715728753 8 11.5 C 8 12.3284271247 7.32842712475 13 6.5 13 C 5.67157287525 13 5 12.3284271247 5 11.5 C 5 10.6715728753 5.67157287525 10 6.5 10 Z" />
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M 9.5 6 C 10.3284271247 6 11 6.67157287525 11 7.5 C 11 8.32842712475 10.3284271247 9 9.5 9 C 8.67157287525 9 8 8.32842712475 8 7.5 C 8 6.67157287525 8.67157287525 6 9.5 6 Z" />
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M 14.5 6 C 15.3284271247 6 16 6.67157287525 16 7.5 C 16 8.32842712475 15.3284271247 9 14.5 9 C 13.6715728753 9 13 8.32842712475 13 7.5 C 13 6.67157287525 13.6715728753 6 14.5 6 Z" />
     <path
-        android:fillColor="#000000"
+        android:fillColor="@android:color/white"
         android:pathData="M 17.5 10 C 18.3284271247 10 19 10.6715728753 19 11.5 C 19 12.3284271247 18.3284271247 13 17.5 13 C 16.6715728753 13 16 12.3284271247 16 11.5 C 16 10.6715728753 16.6715728753 10 17.5 10 Z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_pin.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_pin.xml
new file mode 100644
index 0000000..f1bf5c3
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_pin.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M5.71,14.29C5.08,14.92,5.53,16,6.42,16h4.83v6.25c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75V16h4.84
+c0.89,0,1.34-1.08,0.71-1.71L16,12V4.5h1.23c0.41,0,0.75-0.34,0.75-0.75S17.65,3,17.23,3H16H8H6.73C6.32,3,5.98,3.34,5.98,3.75
+S6.32,4.5,6.73,4.5H8V12L5.71,14.29z
+M14.5,4.5V12c0,0.4,0.16,0.78,0.44,1.06l1.44,1.44H7.62l1.44-1.44C9.34,12.78,9.5,12.4,9.5,12
+V4.5H14.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_remove_no_shadow.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
index 22401a1..864a047 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
@@ -16,10 +16,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M5.7,18.3c0.39,0.39,1.02,0.39,1.41,0L12,13.41l4.89,4.89c0.39,0.39,1.02,0.39,1.41,0s0.39-1.02,0-1.41L13.41,12l4.89-4.89 c0.38-0.38,0.38-1.02,0-1.4c-0.39-0.39-1.02-0.39-1.41,0c0,0,0,0,0,0L12,10.59L7.11,5.7c-0.39-0.39-1.02-0.39-1.41,0 s-0.39,1.02,0,1.41L10.59,12L5.7,16.89C5.31,17.28,5.31,17.91,5.7,18.3z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M5.22,18.78C5.37,18.93,5.56,19,5.75,19s0.38-0.07,0.53-0.22L12,13.06l5.72,5.72c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L13.06,12l5.72-5.72c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0L12,10.94 L6.28,5.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12l-5.72,5.72C4.93,18.01,4.93,18.49,5.22,18.78z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml
index b4f0478..6ff3144 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml
@@ -16,10 +16,13 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M21.64,8.39l-1.6-2.76c-0.28-0.48-0.88-0.7-1.36-0.5l-2.14,0.91c-0.48-0.37-1.01-0.68-1.57-0.92l-0.27-2.2 C14.64,2.4,14.14,2,13.59,2h-3.18C9.86,2,9.36,2.4,9.3,2.92L9.04,5.11c-0.57,0.24-1.1,0.55-1.58,0.92L5.32,5.12 c-0.48-0.2-1.08,0.02-1.36,0.5l-1.6,2.76C2.08,8.86,2.18,9.48,2.6,9.8l1.94,1.45C4.51,11.49,4.5,11.74,4.5,12s0.01,0.51,0.04,0.76 L2.6,14.2c-0.42,0.31-0.52,0.94-0.24,1.41l1.6,2.76c0.28,0.48,0.88,0.7,1.36,0.5l2.14-0.91c0.48,0.37,1.01,0.68,1.57,0.92 l0.27,2.19C9.36,21.6,9.86,22,10.41,22h3.18c0.55,0,1.04-0.4,1.11-0.92l0.27-2.19c0.56-0.24,1.09-0.55,1.57-0.92l2.14,0.91 c0.48,0.2,1.08-0.02,1.36-0.5l1.6-2.76c0.28-0.48,0.18-1.1-0.24-1.42l-1.94-1.45c0.03-0.25,0.04-0.5,0.04-0.76 s-0.01-0.51-0.04-0.76L21.4,9.8C21.82,9.49,21.92,8.86,21.64,8.39z M12,15.5c-1.93,0-3.5-1.57-3.5-3.5s1.57-3.5,3.5-3.5 s3.5,1.57,3.5,3.5S13.93,15.5,12,15.5z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M2.43,15.45l1.79,3.09c0.25,0.45,0.74,0.73,1.25,0.73c0.17,0,0.35-0.03,0.52-0.09l1.76-0.7c0.25,0.17,0.51,0.31,0.77,0.45 l0.26,1.84c0.09,0.71,0.69,1.24,1.42,1.24h3.61c0.72,0,1.33-0.53,1.43-1.19l0.26-1.86c0.25-0.14,0.51-0.28,0.76-0.45l1.76,0.7 c0.17,0.07,0.35,0.1,0.53,0.1c0.5,0,0.98-0.27,1.23-0.72l1.82-3.14c0.34-0.61,0.19-1.38-0.36-1.82l-1.48-1.16 c0.01-0.15,0.02-0.29,0.02-0.45s-0.01-0.3-0.02-0.45l1.48-1.16c0.55-0.43,0.7-1.19,0.35-1.84l-1.8-3.1 c-0.25-0.45-0.74-0.73-1.26-0.73c-0.17,0-0.35,0.03-0.52,0.09l-1.76,0.7c-0.25-0.17-0.51-0.31-0.77-0.45l-0.26-1.84 c-0.09-0.71-0.69-1.24-1.42-1.24h-3.61c-0.71,0-1.32,0.54-1.41,1.22L8.52,5.09C8.26,5.23,8.01,5.37,7.75,5.54L5.99,4.83 c-0.17-0.07-0.35-0.1-0.52-0.1c-0.5,0-0.98,0.27-1.22,0.72L2.43,8.55c-0.36,0.61-0.21,1.4,0.36,1.84l1.48,1.16 C4.27,11.7,4.26,11.85,4.26,12c0,0.16,0.01,0.3,0.02,0.45l-1.49,1.16C2.24,14.04,2.09,14.8,2.43,15.45z M5.2,13.63l0.63-0.49 l-0.05-0.79c-0.01-0.11-0.01-0.58,0-0.7l0.05-0.79L5.2,10.37L3.77,9.25l1.74-3l1.69,0.68l0.73,0.29l0.66-0.43 c0.19-0.13,0.4-0.25,0.65-0.38l0.67-0.36L10,5.3l0.25-1.79h3.48l0.26,1.8l0.11,0.76l0.69,0.36c0.23,0.12,0.44,0.24,0.64,0.37 l0.65,0.43l0.72-0.29l1.7-0.68l1.75,3.02l-1.43,1.12l-0.62,0.49l0.05,0.79c0.01,0.11,0.01,0.58,0,0.7l-0.05,0.79l0.62,0.49 l1.43,1.12l-1.74,3.02l-1.69-0.68l-0.72-0.29l-0.65,0.43c-0.19,0.13-0.4,0.25-0.65,0.38l-0.67,0.36l-0.11,0.75l-0.25,1.77h-3.5 L10,18.71l-0.11-0.76l-0.69-0.36c-0.23-0.12-0.44-0.24-0.64-0.37l-0.65-0.43l-0.72,0.29L5.5,17.76l-1.73-3.01L5.2,13.63z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M12,16c2.21,0,4-1.79,4-4s-1.79-4-4-4c-2.21,0-4,1.79-4,4S9.79,16,12,16z M12,9.5c1.38,0,2.5,1.12,2.5,2.5 s-1.12,2.5-2.5,2.5c-1.38,0-2.5-1.12-2.5-2.5S10.62,9.5,12,9.5z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_smartspace_preferences.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
index 57ae91f..3cc9e51 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
@@ -16,16 +16,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M21.23,2.43L19.5,3.4l-1.73-0.97c-0.22-0.12-0.46,0.12-0.34,0.34L18.4,4.5l-0.97,1.73c-0.12,0.22,0.12,0.46,0.34,0.34 L19.5,5.6l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L20.6,4.5l0.97-1.73C21.69,2.55,21.45,2.31,21.23,2.43z M14.37,7.29 c-0.39-0.39-1.02-0.39-1.41,0L1.29,18.96c-0.39,0.39-0.39,1.02,0,1.41l2.34,2.34c0.39,0.39,1.02,0.39,1.41,0L16.7,11.05 c0.39-0.39,0.39-1.02,0-1.41L14.37,7.29z M13.34,12.78l-2.12-2.12l2.44-2.44l2.12,2.12L13.34,12.78z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.23,14.43L19.5,15.4l-1.73-0.97c-0.22-0.12-0.46,0.12-0.34,0.34l0.97,1.73l-0.97,1.73c-0.12,0.22,0.12,0.46,0.34,0.34 l1.73-0.97l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L20.6,16.5l0.97-1.73C21.69,14.55,21.45,14.31,21.23,14.43z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M9.23,2.43L7.5,3.4L5.77,2.43C5.55,2.31,5.31,2.55,5.43,2.77L6.4,4.5L5.43,6.23C5.31,6.45,5.55,6.69,5.77,6.57L7.5,5.6 l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L8.6,4.5l0.97-1.73C9.69,2.55,9.45,2.31,9.23,2.43z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M14.38,7.3C14.18,7.1,13.92,7,13.66,7c-0.26,0-0.51,0.1-0.71,0.29L1.29,18.96c-0.39,0.39-0.39,1.02,0,1.41l2.34,2.34 C3.82,22.9,4.08,23,4.34,23s0.51-0.1,0.71-0.29L16.7,11.05c0.39-0.39,0.39-1.02,0-1.41L14.38,7.3z M4.34,21.29l-1.63-1.63 l7.45-7.45l1.63,1.63L4.34,21.29z M12.84,12.78l-1.63-1.63l2.45-2.45l1.62,1.64L12.84,12.78z M17.75,5.25h1v1 C18.75,6.66,19.09,7,19.5,7s0.75-0.34,0.75-0.75v-1h1C21.66,5.25,22,4.91,22,4.5s-0.34-0.75-0.75-0.75h-1v-1 C20.25,2.34,19.91,2,19.5,2s-0.75,0.34-0.75,0.75v1h-1C17.34,3.75,17,4.09,17,4.5S17.34,5.25,17.75,5.25z M5.75,5.25h1v1 C6.75,6.66,7.09,7,7.5,7s0.75-0.34,0.75-0.75v-1h1C9.66,5.25,10,4.91,10,4.5S9.66,3.75,9.25,3.75h-1v-1C8.25,2.34,7.91,2,7.5,2 S6.75,2.34,6.75,2.75v1h-1C5.34,3.75,5,4.09,5,4.5S5.34,5.25,5.75,5.25z M21.25,15.75h-1v-1c0-0.41-0.34-0.75-0.75-0.75 s-0.75,0.34-0.75,0.75v1h-1c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h1v1c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75 v-1h1c0.41,0,0.75-0.34,0.75-0.75S21.66,15.75,21.25,15.75z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_split_screen.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_split_screen.xml
index dc3bd95..aaf4900 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_split_screen.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_split_screen.xml
@@ -16,13 +16,13 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M18,2H6C4.9,2,4,2.9,4,4v5c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V4C20,2.9,19.1,2,18,2z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M5,11h14c0.55,0,1-0.45,1-1V4c0-0.55-0.45-1-1-1H5C4.45,3,4,3.45,4,4v6C4,10.55,4.45,11,5,11z M5.5,4.5h13v5h-13V4.5z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M18,13H6c-1.1,0-2,0.9-2,2v5c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-5C20,13.9,19.1,13,18,13z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M4,20c0,0.55,0.45,1,1,1h14c0.55,0,1-0.45,1-1v-6c0-0.55-0.45-1-1-1H5c-0.55,0-1,0.45-1,1V20z M5.5,14.5h13v5h-13V14.5z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_warning.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_warning.xml
index 184714c..63d7b78 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_warning.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_warning.xml
@@ -16,10 +16,16 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M12.87,3.49c-0.39-0.67-1.35-0.67-1.73,0l-9.27,16C1.48,20.17,1.96,21,2.73,21h18.53c0.77,0,1.25-0.83,0.87-1.5L12.87,3.49 z M11,10c0-0.55,0.45-1,1-1s1,0.45,1,1v3c0,0.55-0.45,1-1,1s-1-0.45-1-1V10z M12,18.25c-0.69,0-1.25-0.56-1.25-1.25 s0.56-1.25,1.25-1.25s1.25,0.56,1.25,1.25S12.69,18.25,12,18.25z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M4.47,21h15.06c1.54,0,2.5-1.67,1.73-3L13.73,4.99c-0.39-0.67-1.06-1-1.73-1s-1.35,0.33-1.73,1L2.74,18 C1.97,19.33,2.93,21,4.47,21z M4.04,18.75l7.53-13.01c0.13-0.22,0.33-0.25,0.43-0.25s0.31,0.03,0.43,0.25l7.53,13.01 c0.13,0.22,0.05,0.41,0,0.5c-0.05,0.09-0.18,0.25-0.43,0.25H4.47c-0.25,0-0.38-0.16-0.43-0.25C3.98,19.16,3.91,18.97,4.04,18.75z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M12,14.5c0.41,0,0.75-0.34,0.75-0.75v-4C12.75,9.33,12.41,9,12,9s-0.75,0.34-0.75,0.75v4C11.25,14.16,11.59,14.5,12,14.5z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M 12 16 C 12.5522847498 16 13 16.4477152502 13 17 C 13 17.5522847498 12.5522847498 18 12 18 C 11.4477152502 18 11 17.5522847498 11 17 C 11 16.4477152502 11.4477152502 16 12 16 Z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_widget.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_widget.xml
index ca09fc9..df3a9fd 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_widget.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_widget.xml
@@ -16,19 +16,19 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24"
+    android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
     android:viewportWidth="24"
     android:width="24dp" >
     <path
-        android:fillColor="#000000"
-        android:pathData="M17.7,2.3c-0.4-0.4-1-0.4-1.4,0l-4,4c-0.4,0.4-0.4,1,0,1.4l4,4c0.4,0.4,1,0.4,1.4,0l4-4c0.4-0.4,0.4-1,0-1.4L17.7,2.3z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M10,3H4C3.45,3,3,3.45,3,4v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1V4C11,3.45,10.55,3,10,3z M9.5,9.5h-5v-5h5V9.5z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M11,4c0-0.5-0.4-1-1-1H4C3.5,3,3,3.5,3,4v6c0,0.6,0.5,1,1,1h6c0.6,0,1-0.4,1-1V4z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M10,13H4c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1v-6C11,13.45,10.55,13,10,13z M9.5,19.5h-5v-5h5 V19.5z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M20,21c0.5,0,1-0.5,1-1v-6c0-0.6-0.5-1-1-1h-6c-0.6,0-1,0.4-1,1v6c0,0.5,0.4,1,1,1H20z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M20,13h-6c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1v-6C21,13.45,20.55,13,20,13z M19.5,19.5h-5v-5h5 V19.5z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M10,13H4c-0.5,0-1,0.4-1,1v6c0,0.5,0.5,1,1,1h6c0.6,0,1-0.5,1-1v-6C11,13.4,10.6,13,10,13z" />
+        android:fillColor="@android:color/white"
+        android:pathData="M21.95,6.29l-4.24-4.24c-0.2-0.2-0.45-0.29-0.71-0.29s-0.51,0.1-0.71,0.29l-4.24,4.24c-0.39,0.39-0.39,1.02,0,1.41 l4.24,4.24c0.2,0.2,0.45,0.29,0.71,0.29s0.51-0.1,0.71-0.29l4.24-4.24C22.34,7.32,22.34,6.68,21.95,6.29z M17,10.54L13.46,7 L17,3.46L20.54,7L17,10.54z" />
 </vector>
\ No newline at end of file
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 833faa6..52a4218 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -1399,8 +1399,8 @@
                 } break;
                 case MSG_TEMP_APP_WHITELIST_TIMEOUT: {
                     // TODO: What is keeping the device awake at this point? Does it need to be?
-                    int uid = msg.arg1;
-                    checkTempAppWhitelistTimeout(uid);
+                    int appId = msg.arg1;
+                    checkTempAppWhitelistTimeout(appId);
                 } break;
                 case MSG_REPORT_MAINTENANCE_ACTIVITY: {
                     // TODO: What is keeping the device awake at this point? Does it need to be?
@@ -1656,9 +1656,9 @@
         }
 
         // duration in milliseconds
-        public void addPowerSaveTempWhitelistAppDirect(int appId, long duration, boolean sync,
+        public void addPowerSaveTempWhitelistAppDirect(int uid, long duration, boolean sync,
                 String reason) {
-            addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration, sync, reason);
+            addPowerSaveTempWhitelistAppDirectInternal(0, uid, duration, sync, reason);
         }
 
         // duration in milliseconds
@@ -2357,8 +2357,7 @@
             long duration, int userId, boolean sync, String reason) {
         try {
             int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId);
-            int appId = UserHandle.getAppId(uid);
-            addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration, sync, reason);
+            addPowerSaveTempWhitelistAppDirectInternal(callingUid, uid, duration, sync, reason);
         } catch (NameNotFoundException e) {
         }
     }
@@ -2367,10 +2366,11 @@
      * Adds an app to the temporary whitelist and resets the endTime for granting the
      * app an exemption to access network and acquire wakelocks.
      */
-    void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId,
+    void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int uid,
             long duration, boolean sync, String reason) {
         final long timeNow = SystemClock.elapsedRealtime();
         boolean informWhitelistChanged = false;
+        int appId = UserHandle.getAppId(uid);
         synchronized (this) {
             int callingAppId = UserHandle.getAppId(callingUid);
             if (callingAppId >= Process.FIRST_APPLICATION_UID) {
@@ -2395,7 +2395,7 @@
                 // No pending timeout for the app id, post a delayed message
                 try {
                     mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START,
-                            reason, appId);
+                            reason, uid);
                 } catch (RemoteException e) {
                 }
                 postTempActiveTimeoutMessage(appId, duration);
@@ -2440,34 +2440,34 @@
         }
     }
 
-    private void postTempActiveTimeoutMessage(int uid, long delay) {
+    private void postTempActiveTimeoutMessage(int appId, long delay) {
         if (DEBUG) {
-            Slog.d(TAG, "postTempActiveTimeoutMessage: uid=" + uid + ", delay=" + delay);
+            Slog.d(TAG, "postTempActiveTimeoutMessage: appId=" + appId + ", delay=" + delay);
         }
-        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0),
-                delay);
+        mHandler.sendMessageDelayed(
+                mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, appId, 0), delay);
     }
 
-    void checkTempAppWhitelistTimeout(int uid) {
+    void checkTempAppWhitelistTimeout(int appId) {
         final long timeNow = SystemClock.elapsedRealtime();
         if (DEBUG) {
-            Slog.d(TAG, "checkTempAppWhitelistTimeout: uid=" + uid + ", timeNow=" + timeNow);
+            Slog.d(TAG, "checkTempAppWhitelistTimeout: appId=" + appId + ", timeNow=" + timeNow);
         }
         synchronized (this) {
-            Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(uid);
+            Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId);
             if (entry == null) {
                 // Nothing to do
                 return;
             }
             if (timeNow >= entry.first.value) {
-                mTempWhitelistAppIdEndTimes.delete(uid);
-                onAppRemovedFromTempWhitelistLocked(uid, entry.second);
+                mTempWhitelistAppIdEndTimes.delete(appId);
+                onAppRemovedFromTempWhitelistLocked(appId, entry.second);
             } else {
                 // Need more time
                 if (DEBUG) {
-                    Slog.d(TAG, "Time to remove UID " + uid + ": " + entry.first.value);
+                    Slog.d(TAG, "Time to remove AppId " + appId + ": " + entry.first.value);
                 }
-                postTempActiveTimeoutMessage(uid, entry.first.value - timeNow);
+                postTempActiveTimeoutMessage(appId, entry.first.value - timeNow);
             }
         }
     }
diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java
index f1882c5..9d979a6 100644
--- a/services/core/java/com/android/server/DynamicSystemService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -18,16 +18,23 @@
 
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.gsi.GsiInstallParams;
 import android.gsi.GsiProgress;
 import android.gsi.IGsiService;
+import android.os.Environment;
 import android.os.IBinder;
 import android.os.IBinder.DeathRecipient;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
+import android.os.UserHandle;
 import android.os.image.IDynamicSystemService;
+import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
 import android.util.Slog;
 
+import java.io.File;
+
 /**
  * DynamicSystemService implements IDynamicSystemService. It provides permission check before
  * passing requests to gsid
@@ -36,7 +43,7 @@
     private static final String TAG = "DynamicSystemService";
     private static final String NO_SERVICE_ERROR = "no gsiservice";
     private static final int GSID_ROUGH_TIMEOUT_MS = 8192;
-
+    private static final String PATH_DEFAULT = "/data/gsi";
     private Context mContext;
     private volatile IGsiService mGsiService;
 
@@ -105,7 +112,32 @@
 
     @Override
     public boolean startInstallation(long systemSize, long userdataSize) throws RemoteException {
-        return getGsiService().startGsiInstall(systemSize, userdataSize, true) == 0;
+        // priority from high to low: sysprop -> sdcard -> /data
+        String path = SystemProperties.get("os.aot.path");
+        if (path.isEmpty()) {
+            final int userId = UserHandle.myUserId();
+            final StorageVolume[] volumes =
+                    StorageManager.getVolumeList(userId, StorageManager.FLAG_FOR_WRITE);
+            for (StorageVolume volume : volumes) {
+                if (volume.isEmulated()) continue;
+                if (!volume.isRemovable()) continue;
+                if (!Environment.MEDIA_MOUNTED.equals(volume.getState())) continue;
+                File sdCard = volume.getPathFile();
+                if (sdCard.isDirectory()) {
+                    path = sdCard.getPath();
+                    break;
+                }
+            }
+            if (path.isEmpty()) {
+                path = PATH_DEFAULT;
+            }
+            Slog.i(TAG, "startInstallation -> " + path);
+        }
+        GsiInstallParams installParams = new GsiInstallParams();
+        installParams.installDir = path;
+        installParams.gsiSize = systemSize;
+        installParams.userdataSize = userdataSize;
+        return getGsiService().beginGsiInstall(installParams) == 0;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index da9cffa..382fdec 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -1693,9 +1693,6 @@
                 // Always remember the new state we just booted with
                 writeSettingsLocked();
             }
-
-            // Execute special logic to recover certain devices
-            recoverFrom128872367();
         }
     }
 
@@ -1756,69 +1753,6 @@
         return maxTime;
     }
 
-    /**
-     * In b/128872367 we lost all app-ops on devices in the wild. This logic
-     * attempts to detect and recover from this by granting
-     * {@link AppOpsManager#OP_LEGACY_STORAGE} to any apps installed before
-     * isolated storage was enabled.
-     */
-    private void recoverFrom128872367() {
-        // We're interested in packages that were installed or updated between
-        // 1/1/2014 and 12/17/2018
-        final long START_TIMESTAMP = 1388534400000L;
-        final long END_TIMESTAMP = 1545004800000L;
-
-        final PackageManager pm = mContext.getPackageManager();
-        final AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
-        final UserManagerInternal um = LocalServices.getService(UserManagerInternal.class);
-
-        boolean activeDuringWindow = false;
-        List<PackageInfo> pendingHolders = new ArrayList<>();
-
-        for (int userId : um.getUserIds()) {
-            final List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser(MATCH_UNINSTALLED_PACKAGES
-                    | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId);
-            for (PackageInfo pkg : pkgs) {
-                // Determine if any apps on this device had been installed or
-                // updated during the period where the feature was disabled
-                activeDuringWindow |= (pkg.firstInstallTime > START_TIMESTAMP
-                        && pkg.firstInstallTime < END_TIMESTAMP);
-                activeDuringWindow |= (pkg.lastUpdateTime > START_TIMESTAMP
-                        && pkg.lastUpdateTime < END_TIMESTAMP);
-
-                // This app should hold legacy op if they were installed before
-                // the cutoff; we only check the end boundary here so that
-                // include system apps, which are always installed on 1/1/2009.
-                final boolean shouldHold = (pkg.firstInstallTime < END_TIMESTAMP);
-                final boolean doesHold = (appOps.checkOpNoThrow(OP_LEGACY_STORAGE,
-                        pkg.applicationInfo.uid,
-                        pkg.applicationInfo.packageName) == MODE_ALLOWED);
-
-                if (doesHold) {
-                    Slog.d(TAG, "Found " + pkg + " holding legacy op; skipping recovery");
-                    return;
-                } else if (shouldHold) {
-                    Slog.d(TAG, "Found " + pkg + " that should hold legacy op");
-                    pendingHolders.add(pkg);
-                }
-            }
-        }
-
-        if (!activeDuringWindow) {
-            Slog.d(TAG, "No packages were active during the time window; skipping grants");
-            return;
-        }
-
-        // If we made it this far, nobody actually holds the legacy op, which
-        // means we probably lost the database, and we should grant the op to
-        // all the apps we identified.
-        for (PackageInfo pkg : pendingHolders) {
-            appOps.setMode(AppOpsManager.OP_LEGACY_STORAGE,
-                    pkg.applicationInfo.uid,
-                    pkg.applicationInfo.packageName, AppOpsManager.MODE_ALLOWED);
-        }
-    }
-
     private void systemReady() {
         LocalServices.getService(ActivityTaskManagerInternal.class)
                 .registerScreenObserver(this);
diff --git a/services/core/java/com/android/server/ThreadPriorityBooster.java b/services/core/java/com/android/server/ThreadPriorityBooster.java
index f74a4385..dab6bc4 100644
--- a/services/core/java/com/android/server/ThreadPriorityBooster.java
+++ b/services/core/java/com/android/server/ThreadPriorityBooster.java
@@ -26,6 +26,7 @@
 public class ThreadPriorityBooster {
 
     private static final boolean ENABLE_LOCK_GUARD = false;
+    private static final int PRIORITY_NOT_ADJUSTED = Integer.MAX_VALUE;
 
     private volatile int mBoostToPriority;
     private final int mLockGuardIndex;
@@ -42,13 +43,12 @@
     }
 
     public void boost() {
-        final int tid = myTid();
         final PriorityState state = mThreadState.get();
         if (state.regionCounter == 0) {
-            final int prevPriority = getThreadPriority(tid);
-            state.prevPriority = prevPriority;
+            final int prevPriority = getThreadPriority(state.tid);
             if (prevPriority > mBoostToPriority) {
-                setThreadPriority(tid, mBoostToPriority);
+                setThreadPriority(state.tid, mBoostToPriority);
+                state.prevPriority = prevPriority;
             }
         }
         state.regionCounter++;
@@ -60,11 +60,9 @@
     public void reset() {
         final PriorityState state = mThreadState.get();
         state.regionCounter--;
-        if (state.regionCounter == 0) {
-            final int currentPriority = getThreadPriority(myTid());
-            if (state.prevPriority != currentPriority) {
-                setThreadPriority(myTid(), state.prevPriority);
-            }
+        if (state.regionCounter == 0 && state.prevPriority != PRIORITY_NOT_ADJUSTED) {
+            setThreadPriority(state.tid, state.prevPriority);
+            state.prevPriority = PRIORITY_NOT_ADJUSTED;
         }
     }
 
@@ -78,16 +76,16 @@
         // variable immediately.
         mBoostToPriority = priority;
         final PriorityState state = mThreadState.get();
-        final int tid = myTid();
         if (state.regionCounter != 0) {
-            final int prevPriority = getThreadPriority(tid);
+            final int prevPriority = getThreadPriority(state.tid);
             if (prevPriority != priority) {
-                setThreadPriority(tid, priority);
+                setThreadPriority(state.tid, priority);
             }
         }
     }
 
     private static class PriorityState {
+        final int tid = myTid();
 
         /**
          * Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
@@ -99,6 +97,6 @@
         /**
          * The thread's previous priority before boosting.
          */
-        int prevPriority;
+        int prevPriority = PRIORITY_NOT_ADJUSTED;
     }
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index f0982d3..4ec90ba 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2117,6 +2117,12 @@
                     Slog.w(TAG, "Service lookup failed: " + msg);
                     return new ServiceLookupResult(null, msg);
                 }
+
+                // Store the defining packageName and uid, as they might be changed in
+                // the ApplicationInfo for external services (which run with the package name
+                // and uid of the caller).
+                String definingPackageName = sInfo.applicationInfo.packageName;
+                int definingUid = sInfo.applicationInfo.uid;
                 if ((sInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0) {
                     if (isBindExternal) {
                         if (!sInfo.exported) {
@@ -2175,8 +2181,8 @@
                                 sInfo.applicationInfo.uid, name.getPackageName(),
                                 name.getClassName());
                     }
-                    r = new ServiceRecord(mAm, ss, className, name, filter, sInfo,
-                            callingFromFg, res);
+                    r = new ServiceRecord(mAm, ss, className, name, definingPackageName,
+                            definingUid, filter, sInfo, callingFromFg, res);
                     res.setService(r);
                     smap.mServicesByInstanceName.put(name, r);
                     smap.mServicesByIntent.put(filter, r);
@@ -2557,7 +2563,7 @@
 
         final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
         final String procName = r.processName;
-        String hostingType = "service";
+        HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);
         ProcessRecord app;
 
         if (!isolated) {
@@ -2588,10 +2594,11 @@
             app = r.isolatedProc;
             if (WebViewZygote.isMultiprocessEnabled()
                     && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
-                hostingType = "webview_service";
+                hostingRecord = HostingRecord.byWebviewZygote(r.instanceName);
             }
             if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) {
-                hostingType = "app_zygote";
+                hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName,
+                        r.definingUid);
             }
         }
 
@@ -2599,7 +2606,7 @@
         // to be executed when the app comes up.
         if (app == null && !permissionsReviewRequired) {
             if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
-                    hostingType, r.instanceName, false, isolated, false)) == null) {
+                    hostingRecord, false, isolated, false)) == null) {
                 String msg = "Unable to launch app "
                         + r.appInfo.packageName + "/"
                         + r.appInfo.uid + " for service "
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0b9e3bb..3b6b404 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1498,6 +1498,7 @@
 
     private ParcelFileDescriptor[] mLifeMonitorFds;
 
+    static final HostingRecord sNullHostingRecord = new HostingRecord(null);
     /**
      * Used to notify activity lifecycle events.
      */
@@ -1963,7 +1964,7 @@
                 ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
                         false,
                         0,
-                        false);
+                        new HostingRecord("system"));
                 app.setPersistent(true);
                 app.pid = MY_PID;
                 app.getWindowProcessController().setPid(MY_PID);
@@ -2894,8 +2895,9 @@
             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
             info.targetSdkVersion = Build.VERSION.SDK_INT;
             ProcessRecord proc = mProcessList.startProcessLocked(processName, info /* info */,
-                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
-                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
+                    false /* knownToBeDead */, 0 /* intentFlags */,
+                    sNullHostingRecord  /* hostingRecord */,
+                    true /* allowWhileBooting */, true /* isolated */,
                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
                     crashHandler);
             return proc != null;
@@ -2905,11 +2907,10 @@
     @GuardedBy("this")
     final ProcessRecord startProcessLocked(String processName,
             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
-            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
+            HostingRecord hostingRecord, boolean allowWhileBooting,
             boolean isolated, boolean keepIfLarge) {
         return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
-                hostingType,
-                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
+                hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                 null /* crashHandler */);
     }
@@ -4692,7 +4693,8 @@
             app.deathRecipient = adr;
         } catch (RemoteException e) {
             app.resetPackageList(mProcessStats);
-            mProcessList.startProcessLocked(app, "link fail", processName);
+            mProcessList.startProcessLocked(app,
+                    new HostingRecord("link fail", processName));
             return false;
         }
 
@@ -4931,7 +4933,7 @@
 
             app.resetPackageList(mProcessStats);
             app.unlinkDeathRecipient();
-            mProcessList.startProcessLocked(app, "bind fail", processName);
+            mProcessList.startProcessLocked(app, new HostingRecord("bind-fail", processName));
             return false;
         }
 
@@ -5013,8 +5015,8 @@
                 app.startTime,
                 (int) (bindApplicationTimeMillis - app.startTime),
                 (int) (SystemClock.elapsedRealtime() - app.startTime),
-                app.hostingType,
-                (app.hostingNameStr != null ? app.hostingNameStr : ""));
+                app.hostingRecord.getType(),
+                (app.hostingRecord.getName() != null ? app.hostingRecord.getName() : ""));
         return true;
     }
 
@@ -5123,7 +5125,7 @@
                 for (int ip=0; ip<NP; ip++) {
                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
                             + procs.get(ip));
-                    mProcessList.startProcessLocked(procs.get(ip), "on-hold", null);
+                    mProcessList.startProcessLocked(procs.get(ip), new HostingRecord("on-hold"));
                 }
             }
             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
@@ -6915,9 +6917,10 @@
                         } else {
                             checkTime(startTime, "getContentProviderImpl: before start process");
                             proc = startProcessLocked(cpi.processName,
-                                    cpr.appInfo, false, 0, "content provider",
+                                    cpr.appInfo, false, 0,
+                                    new HostingRecord("content provider",
                                     new ComponentName(cpi.applicationInfo.packageName,
-                                            cpi.name), false, false, false);
+                                            cpi.name)), false, false, false);
                             checkTime(startTime, "getContentProviderImpl: after start process");
                             if (proc == null) {
                                 Slog.w(TAG, "Unable to launch app "
@@ -7638,7 +7641,9 @@
         }
 
         if (app == null) {
-            app = mProcessList.newProcessRecordLocked(info, customProcess, isolated, 0, false);
+            app = mProcessList.newProcessRecordLocked(info, customProcess, isolated, 0,
+                    new HostingRecord("added application",
+                            customProcess != null ? customProcess : info.processName));
             mProcessList.updateLruProcessLocked(app, false, null);
             updateOomAdjLocked();
         }
@@ -7659,9 +7664,9 @@
         }
         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
             mPersistentStartingProcesses.add(app);
-            mProcessList.startProcessLocked(app, "added application",
-                    customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
-                    mountExtStorageFull, abiOverride);
+            mProcessList.startProcessLocked(app, new HostingRecord("added application",
+                    customProcess != null ? customProcess : app.processName),
+                    disableHiddenApiChecks, mountExtStorageFull, abiOverride);
         }
 
         return app;
@@ -13611,7 +13616,8 @@
             }
             mProcessList.addProcessNameLocked(app);
             app.pendingStart = false;
-            mProcessList.startProcessLocked(app, "restart", app.processName);
+            mProcessList.startProcessLocked(app,
+                    new HostingRecord("restart", app.processName));
             return true;
         } else if (app.pid > 0 && app.pid != MY_PID) {
             // Goodbye!
@@ -13952,9 +13958,12 @@
                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
                             ? new ComponentName(app.packageName, app.backupAgentName)
                             : new ComponentName("android", "FullBackupAgent");
+
             // startProcessLocked() returns existing proc's record if it's already running
             ProcessRecord proc = startProcessLocked(app.processName, app,
-                    false, 0, "backup", hostingName, false, false, false);
+                    false, 0,
+                    new HostingRecord("backup", hostingName),
+                    false, false, false);
             if (proc == null) {
                 Slog.e(TAG, "Unable to start backup agent process " + r);
                 return false;
@@ -18163,8 +18172,9 @@
                 }
                 synchronized (ActivityManagerService.this) {
                     startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
-                            hostingType, hostingName, false /* allowWhileBooting */,
-                            false /* isolated */, true /* keepIfLarge */);
+                            new HostingRecord(hostingType, hostingName),
+                            false /* allowWhileBooting */, false /* isolated */,
+                            true /* keepIfLarge */);
                 }
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index d1379b6..cba9674 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -826,7 +826,7 @@
                     return -1;
                 }
             }
-            process = getNextArg();
+            process = getNextArgRequired();
         } else {
             // Compatibility with old syntax: process is specified first.
             process = cmd;
@@ -2998,15 +2998,22 @@
             pw.println("      start: start tracing IPC transactions.");
             pw.println("      stop: stop tracing IPC transactions and dump the results to file.");
             pw.println("      --dump-file <FILE>: Specify the file the trace should be dumped to.");
-            pw.println("  profile [start|stop] [--user <USER_ID> current] [--sampling INTERVAL]");
-            pw.println("          [--streaming] <PROCESS> <FILE>");
-            pw.println("      Start and stop profiler on a process.  The given <PROCESS> argument");
+            pw.println("  profile start [--user <USER_ID> current]");
+            pw.println("          [--sampling INTERVAL | --streaming] <PROCESS> <FILE>");
+            pw.println("      Start profiler on a process.  The given <PROCESS> argument");
             pw.println("        may be either a process name or pid.  Options are:");
             pw.println("      --user <USER_ID> | current: When supplying a process name,");
-            pw.println("          specify user of process to profile; uses current user if not specified.");
+            pw.println("          specify user of process to profile; uses current user if not");
+            pw.println("          specified.");
             pw.println("      --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
-            pw.println("          between samples");
-            pw.println("      --streaming: stream the profiling output to the specified file");
+            pw.println("          between samples.");
+            pw.println("      --streaming: stream the profiling output to the specified file.");
+            pw.println("  profile stop [--user <USER_ID> current] <PROCESS>");
+            pw.println("      Stop profiler on a process.  The given <PROCESS> argument");
+            pw.println("        may be either a process name or pid.  Options are:");
+            pw.println("      --user <USER_ID> | current: When supplying a process name,");
+            pw.println("          specify user of process to profile; uses current user if not");
+            pw.println("          specified.");
             pw.println("  dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>");
             pw.println("      Dump the heap of a process.  The given <PROCESS> argument may");
             pw.println("        be either a process name or pid.  Options are:");
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 4bfbb78..3c57c3b 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -1623,7 +1623,7 @@
         if ((r.curApp=mService.startProcessLocked(targetProcess,
                 info.activityInfo.applicationInfo, true,
                 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
-                "broadcast", r.curComponent,
+                new HostingRecord("broadcast", r.curComponent),
                 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
                         == null) {
             // Ah, this recipient is unavailable.  Finish it if necessary,
diff --git a/services/core/java/com/android/server/am/HostingRecord.java b/services/core/java/com/android/server/am/HostingRecord.java
new file mode 100644
index 0000000..784dde1
--- /dev/null
+++ b/services/core/java/com/android/server/am/HostingRecord.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.content.ComponentName;
+
+/**
+ * This class describes various information required to start a process.
+ *
+ * The {@code mHostingType} field describes the reason why we started a process, and
+ * is only used for logging and stats.
+ *
+ * The {@code mHostingName} field describes the Component for which we are starting the
+ * process, and is only used for logging and stats.
+ *
+ * The {@code mHostingZygote} field describes from which Zygote the new process should be spawned.
+ *
+ * {@code mDefiningPackageName} contains the packageName of the package that defines the
+ * component we want to start; this can be different from the packageName and uid in the
+ * ApplicationInfo that we're creating the process with, in case the service is a
+ * {@link android.content.Context#BIND_EXTERNAL_SERVICE} service. In that case, the packageName
+ * and uid in the ApplicationInfo will be set to those of the caller, not of the defining package.
+ *
+ * {@code mDefiningUid} contains the uid of the application that defines the component we want to
+ * start; this can be different from the packageName and uid in the ApplicationInfo that we're
+ * creating the process with, in case the service is a
+ * {@link android.content.Context#BIND_EXTERNAL_SERVICE} service. In that case, the packageName
+ * and uid in the ApplicationInfo will be set to those of the caller, not of the defining package.
+ *
+ */
+
+public final class HostingRecord {
+    private static final int REGULAR_ZYGOTE = 0;
+    private static final int WEBVIEW_ZYGOTE = 1;
+    private static final int APP_ZYGOTE = 2;
+
+    private final String mHostingType;
+    private final String mHostingName;
+    private final int mHostingZygote;
+    private final String mDefiningPackageName;
+    private final int mDefiningUid;
+
+    public HostingRecord(String hostingType) {
+        this(hostingType, null, REGULAR_ZYGOTE, null, -1);
+    }
+
+    public HostingRecord(String hostingType, ComponentName hostingName) {
+        this(hostingType, hostingName, REGULAR_ZYGOTE);
+    }
+
+    public HostingRecord(String hostingType, String hostingName) {
+        this(hostingType, hostingName, REGULAR_ZYGOTE);
+    }
+
+    private HostingRecord(String hostingType, ComponentName hostingName, int hostingZygote) {
+        this(hostingType, hostingName.toShortString(), hostingZygote);
+    }
+
+    private HostingRecord(String hostingType, String hostingName, int hostingZygote) {
+        this(hostingType, hostingName, hostingZygote, null, -1);
+    }
+
+    private HostingRecord(String hostingType, String hostingName, int hostingZygote,
+            String definingPackageName, int definingUid) {
+        mHostingType = hostingType;
+        mHostingName = hostingName;
+        mHostingZygote = hostingZygote;
+        mDefiningPackageName = definingPackageName;
+        mDefiningUid = definingUid;
+    }
+
+    public String getType() {
+        return mHostingType;
+    }
+
+    public String getName() {
+        return mHostingName;
+    }
+
+    /**
+     * Returns the UID of the package defining the component we want to start. Only valid
+     * when {@link #usesAppZygote()} returns true.
+     *
+     * @return the UID of the hosting application
+     */
+    public int getDefiningUid() {
+        return mDefiningUid;
+    }
+
+    /**
+     * Returns the packageName of the package defining the component we want to start. Only valid
+     * when {@link #usesAppZygote()} returns true.
+     *
+     * @return the packageName of the hosting application
+     */
+    public String getDefiningPackageName() {
+        return mDefiningPackageName;
+    }
+
+    /**
+     * Creates a HostingRecord for a process that must spawn from the webview zygote
+     * @param hostingName name of the component to be hosted in this process
+     * @return The constructed HostingRecord
+     */
+    public static HostingRecord byWebviewZygote(ComponentName hostingName) {
+        return new HostingRecord("", hostingName.toShortString(), WEBVIEW_ZYGOTE);
+    }
+
+    /**
+     * Creates a HostingRecord for a process that must spawn from the application zygote
+     * @param hostingName name of the component to be hosted in this process
+     * @param definingPackageName name of the package defining the service
+     * @param definingUid uid of the package defining the service
+     * @return The constructed HostingRecord
+     */
+    public static HostingRecord byAppZygote(ComponentName hostingName, String definingPackageName,
+            int definingUid) {
+        return new HostingRecord("", hostingName.toShortString(), APP_ZYGOTE,
+                definingPackageName, definingUid);
+    }
+
+    /**
+     * @return whether the process should spawn from the application zygote
+     */
+    public boolean usesAppZygote() {
+        return mHostingZygote == APP_ZYGOTE;
+    }
+
+    /**
+     * @return whether the process should spawn from the webview zygote
+     */
+    public boolean usesWebviewZygote() {
+        return mHostingZygote == WEBVIEW_ZYGOTE;
+    }
+}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 9780a7f..0a926f9 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -454,13 +454,13 @@
         }
 
         @GuardedBy("ProcessList.this.mService")
-        IsolatedUidRange getIsolatedUidRangeLocked(ApplicationInfo info) {
-            return mAppRanges.get(info.processName, info.uid);
+        IsolatedUidRange getIsolatedUidRangeLocked(String processName, int uid) {
+            return mAppRanges.get(processName, uid);
         }
 
         @GuardedBy("ProcessList.this.mService")
-        IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info) {
-            IsolatedUidRange range = getIsolatedUidRangeLocked(info);
+        IsolatedUidRange getOrCreateIsolatedUidRangeLocked(String processName, int uid) {
+            IsolatedUidRange range = getIsolatedUidRangeLocked(processName, uid);
             if (range == null) {
                 int uidRangeIndex = mAvailableUidRanges.nextSetBit(0);
                 if (uidRangeIndex < 0) {
@@ -470,7 +470,7 @@
                 mAvailableUidRanges.clear(uidRangeIndex);
                 int actualUid = mFirstUid + uidRangeIndex * mNumUidsPerRange;
                 range = new IsolatedUidRange(actualUid, actualUid + mNumUidsPerRange - 1);
-                mAppRanges.put(info.processName, info.uid, range);
+                mAppRanges.put(processName, uid, range);
             }
             return range;
         }
@@ -1427,14 +1427,13 @@
     /**
      * @return {@code true} if process start is successful, false otherwise.
      * @param app
-     * @param hostingType
-     * @param hostingNameStr
+     * @param hostingRecord
      * @param disableHiddenApiChecks
      * @param abiOverride
      */
     @GuardedBy("mService")
-    boolean startProcessLocked(ProcessRecord app, String hostingType,
-            String hostingNameStr, boolean disableHiddenApiChecks, boolean mountExtStorageFull,
+    boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
+            boolean disableHiddenApiChecks, boolean mountExtStorageFull,
             String abiOverride) {
         if (app.pendingStart) {
             return true;
@@ -1625,7 +1624,7 @@
             // the PID of the new process, or else throw a RuntimeException.
             final String entryPoint = "android.app.ActivityThread";
 
-            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
+            return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                     runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                     startTime);
         } catch (RuntimeException e) {
@@ -1644,7 +1643,7 @@
     }
 
     @GuardedBy("mService")
-    boolean startProcessLocked(String hostingType, String hostingNameStr,
+    boolean startProcessLocked(HostingRecord hostingRecord,
             String entryPoint,
             ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
@@ -1654,7 +1653,7 @@
         app.removed = false;
         app.killed = false;
         final long startSeq = app.startSeq = ++mProcStartSeqCounter;
-        app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
+        app.setStartParams(uid, hostingRecord, seInfo, startTime);
         if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
             if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
                     "Posting procStart msg for " + app.toShortString());
@@ -1672,7 +1671,7 @@
                                 || SystemProperties.get("wrap." + app.processName) != null);
                         mPendingStarts.put(startSeq, app);
                     }
-                    final Process.ProcessStartResult startResult = startProcess(app.hostingType,
+                    final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
                             entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
                             app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
                     synchronized (mService) {
@@ -1693,7 +1692,7 @@
             return true;
         } else {
             try {
-                final Process.ProcessStartResult startResult = startProcess(hostingType,
+                final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                         entryPoint, app,
                         uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
                         invokeWith, startTime);
@@ -1727,12 +1726,14 @@
     private void removeProcessFromAppZygoteLocked(final ProcessRecord app) {
         // Free the isolated uid for this process
         final IsolatedUidRange appUidRange =
-                mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info);
+                mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info.processName,
+                        app.hostingRecord.getDefiningUid());
         if (appUidRange != null) {
             appUidRange.freeIsolatedUidLocked(app.uid);
         }
 
-        final AppZygote appZygote = mAppZygotes.get(app.info.processName, app.info.uid);
+        final AppZygote appZygote = mAppZygotes.get(app.info.processName,
+                app.hostingRecord.getDefiningUid());
         if (appZygote != null) {
             ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
             zygoteProcesses.remove(app);
@@ -1753,21 +1754,40 @@
 
     private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) {
         synchronized (mService) {
-            AppZygote appZygote = mAppZygotes.get(app.info.processName, app.info.uid);
+            // The UID for the app zygote should be the UID of the application hosting
+            // the service.
+            final int uid = app.hostingRecord.getDefiningUid();
+            AppZygote appZygote = mAppZygotes.get(app.info.processName, uid);
             final ArrayList<ProcessRecord> zygoteProcessList;
             if (appZygote == null) {
+                if (DEBUG_PROCESSES) {
+                    Slog.d(TAG_PROCESSES, "Creating new app zygote.");
+                }
                 final IsolatedUidRange uidRange =
-                        mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info);
-                final int userId = UserHandle.getUserId(app.info.uid);
+                        mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(
+                                app.info.processName, app.hostingRecord.getDefiningUid());
+                final int userId = UserHandle.getUserId(uid);
                 // Create the app-zygote and provide it with the UID-range it's allowed
                 // to setresuid/setresgid to.
                 final int firstUid = UserHandle.getUid(userId, uidRange.mFirstUid);
                 final int lastUid = UserHandle.getUid(userId, uidRange.mLastUid);
-                appZygote = new AppZygote(app.info, app.info.uid, firstUid, lastUid);
-                mAppZygotes.put(app.info.processName, app.info.uid, appZygote);
+                ApplicationInfo appInfo = new ApplicationInfo(app.info);
+                // If this was an external service, the package name and uid in the passed in
+                // ApplicationInfo have been changed to match those of the calling package;
+                // that is not what we want for the AppZygote though, which needs to have the
+                // packageName and uid of the defining application. This is because the
+                // preloading only makes sense in the context of the defining application,
+                // not the calling one.
+                appInfo.packageName = app.hostingRecord.getDefiningPackageName();
+                appInfo.uid = uid;
+                appZygote = new AppZygote(appInfo, uid, firstUid, lastUid);
+                mAppZygotes.put(app.info.processName, uid, appZygote);
                 zygoteProcessList = new ArrayList<ProcessRecord>();
                 mAppZygoteProcesses.put(appZygote, zygoteProcessList);
             } else {
+                if (DEBUG_PROCESSES) {
+                    Slog.d(TAG_PROCESSES, "Reusing existing app zygote.");
+                }
                 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote);
                 zygoteProcessList = mAppZygoteProcesses.get(appZygote);
             }
@@ -1781,7 +1801,7 @@
         }
     }
 
-    private Process.ProcessStartResult startProcess(String hostingType, String entryPoint,
+    private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
             ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
             long startTime) {
@@ -1797,7 +1817,7 @@
                     app.processName);
             checkSlow(startTime, "startProcess: asking zygote to start proc");
             final Process.ProcessStartResult startResult;
-            if (hostingType.equals("webview_service")) {
+            if (hostingRecord.usesWebviewZygote()) {
                 startResult = startWebView(entryPoint,
                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
@@ -1805,7 +1825,7 @@
                         packageNames, sandboxId,
                         new String[] {PROC_START_SEQ_IDENT + app.startSeq},
                         useSystemGraphicsDriver);
-            } else if (hostingType.equals("app_zygote")) {
+            } else if (hostingRecord.usesAppZygote()) {
                 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
 
                 startResult = appZygote.getProcess().start(entryPoint,
@@ -1832,21 +1852,20 @@
     }
 
     @GuardedBy("mService")
-    final void startProcessLocked(ProcessRecord app,
-            String hostingType, String hostingNameStr) {
-        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
+    final void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord) {
+        startProcessLocked(app, hostingRecord, null /* abiOverride */);
     }
 
     @GuardedBy("mService")
-    final boolean startProcessLocked(ProcessRecord app,
-            String hostingType, String hostingNameStr, String abiOverride) {
-        return startProcessLocked(app, hostingType, hostingNameStr,
+    final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
+            String abiOverride) {
+        return startProcessLocked(app, hostingRecord,
                 false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
     }
 
     @GuardedBy("mService")
     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
-            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
+            boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
         long startTime = SystemClock.elapsedRealtime();
@@ -1916,13 +1935,9 @@
             checkSlow(startTime, "startProcess: done killing old proc");
         }
 
-        String hostingNameStr = hostingName != null
-                ? hostingName.flattenToShortString() : null;
-
         if (app == null) {
-            final boolean fromAppZygote = "app_zygote".equals(hostingType);
             checkSlow(startTime, "startProcess: creating new process record");
-            app = newProcessRecordLocked(info, processName, isolated, isolatedUid, fromAppZygote);
+            app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
             if (app == null) {
                 Slog.w(TAG, "Failed making new process record for "
                         + processName + "/" + info.uid + " isolated=" + isolated);
@@ -1953,8 +1968,7 @@
         }
 
         checkSlow(startTime, "startProcess: stepping in to startProcess");
-        final boolean success = startProcessLocked(app, hostingType, hostingNameStr,
-                abiOverride);
+        final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
         checkSlow(startTime, "startProcess: done starting proc!");
         return success ? app : null;
     }
@@ -2015,8 +2029,8 @@
 
         EventLog.writeEvent(EventLogTags.AM_PROC_START,
                 UserHandle.getUserId(app.startUid), pid, app.startUid,
-                app.processName, app.hostingType,
-                app.hostingNameStr != null ? app.hostingNameStr : "");
+                app.processName, app.hostingRecord.getType(),
+                app.hostingRecord.getName() != null ? app.hostingRecord.getName() : "");
 
         try {
             AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
@@ -2044,10 +2058,10 @@
             buf.append("]");
         }
         buf.append(" for ");
-        buf.append(app.hostingType);
-        if (app.hostingNameStr != null) {
+        buf.append(app.hostingRecord.getType());
+        if (app.hostingRecord.getName() != null) {
             buf.append(" ");
-            buf.append(app.hostingNameStr);
+            buf.append(app.hostingRecord.getName());
         }
         mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
         app.setPid(pid);
@@ -2307,24 +2321,25 @@
 
     @GuardedBy("mService")
     private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info,
-            boolean fromAppZygote) {
-        if (!fromAppZygote) {
+            HostingRecord hostingRecord) {
+        if (hostingRecord == null || !hostingRecord.usesAppZygote()) {
             // Allocate an isolated UID from the global range
             return mGlobalIsolatedUids;
         } else {
-            return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(info);
+            return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(
+                    info.processName, hostingRecord.getDefiningUid());
         }
     }
 
     @GuardedBy("mService")
     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
-            boolean isolated, int isolatedUid, boolean fromAppZygote) {
+            boolean isolated, int isolatedUid, HostingRecord hostingRecord) {
         String proc = customProcess != null ? customProcess : info.processName;
         final int userId = UserHandle.getUserId(info.uid);
         int uid = info.uid;
         if (isolated) {
             if (isolatedUid == 0) {
-                IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, fromAppZygote);
+                IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord);
                 if (uidRange == null) {
                     return null;
                 }
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index ce13cd8..933f41c 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -301,18 +301,16 @@
     boolean whitelistManager;
 
     // Params used in starting this process.
-    String hostingType;
-    String hostingNameStr;
+    HostingRecord hostingRecord;
     String seInfo;
     long startTime;
     // This will be same as {@link #uid} usually except for some apps used during factory testing.
     int startUid;
 
-    void setStartParams(int startUid, String hostingType, String hostingNameStr, String seInfo,
+    void setStartParams(int startUid, HostingRecord hostingRecord, String seInfo,
             long startTime) {
         this.startUid = startUid;
-        this.hostingType = hostingType;
-        this.hostingNameStr = hostingNameStr;
+        this.hostingRecord = hostingRecord;
         this.seInfo = seInfo;
         this.startTime = startTime;
     }
@@ -878,13 +876,6 @@
         return null;
     }
 
-    @Override
-    public void addPackage(String pkg, long versionCode) {
-        synchronized (mService) {
-            addPackage(pkg, versionCode, mService.mProcessStats);
-        }
-    }
-
     /*
      *  Return true if package has been added false if not
      */
@@ -1302,15 +1293,13 @@
     }
 
     @Override
-    public void updateProcessInfo(boolean updateServiceConnectionActivities, boolean updateLru,
-            boolean activityChange, boolean updateOomAdj) {
+    public void updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange,
+            boolean updateOomAdj) {
         synchronized (mService) {
             if (updateServiceConnectionActivities) {
                 mService.mServices.updateServiceConnectionActivitiesLocked(this);
             }
-            if (updateLru) {
-                mService.mProcessList.updateLruProcessLocked(this, activityChange, null);
-            }
+            mService.mProcessList.updateLruProcessLocked(this, activityChange, null /* client */);
             if (updateOomAdj) {
                 mService.updateOomAdjLocked();
             }
@@ -1332,19 +1321,20 @@
     }
 
     @Override
-    public void clearWaitingToKill() {
+    public void onStartActivity(int topProcessState, boolean setProfileProc, String packageName,
+            long versionCode) {
         synchronized (mService) {
             waitingToKill = null;
-        }
-    }
-
-    @Override
-    public void onStartActivity(int topProcessState, boolean setProfileProc) {
-        synchronized (mService) {
             if (setProfileProc) {
                 mService.mProfileData.setProfileProc(this);
             }
+            if (packageName != null) {
+                addPackage(packageName, versionCode, mService.mProcessStats);
+            }
 
+            // Update oom adj first, we don't want the additional states are involved in this round.
+            updateProcessInfo(false /* updateServiceConnectionActivities */,
+                    true /* activityChange */, true /* updateOomAdj */);
             hasShownUi = true;
             setPendingUiClean(true);
             forceProcessStateUpTo(topProcessState);
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 217fd6d..27c62d0 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -73,6 +73,10 @@
     final ComponentName name; // service component.
     final ComponentName instanceName; // service component's per-instance name.
     final String shortInstanceName; // instanceName.flattenToShortString().
+    final String definingPackageName;
+                            // Can be different from appInfo.packageName for external services
+    final int definingUid;
+                            // Can be different from appInfo.uid for external services
     final Intent.FilterComparison intent;
                             // original intent used to find service.
     final ServiceInfo serviceInfo;
@@ -474,7 +478,7 @@
 
     ServiceRecord(ActivityManagerService ams,
             BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name,
-            ComponentName instanceName,
+            ComponentName instanceName, String definingPackageName, int definingUid,
             Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg,
             Runnable restarter) {
         this.ams = ams;
@@ -482,6 +486,8 @@
         this.name = name;
         this.instanceName = instanceName;
         shortInstanceName = instanceName.flattenToShortString();
+        this.definingPackageName = definingPackageName;
+        this.definingUid = definingUid;
         this.intent = intent;
         serviceInfo = sInfo;
         appInfo = sInfo.applicationInfo;
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 4c3bb8c..873cadb 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -220,7 +220,8 @@
      * global Settings. Any access to this class or its fields should be done while
      * holding the AppOpsService lock.
      */
-    private final class Constants extends ContentObserver {
+    @VisibleForTesting
+    final class Constants extends ContentObserver {
         // Key names stored in the settings value.
         private static final String KEY_TOP_STATE_SETTLE_TIME = "top_state_settle_time";
         private static final String KEY_FG_SERVICE_STATE_SETTLE_TIME
@@ -305,7 +306,8 @@
         }
     }
 
-    private final Constants mConstants;
+    @VisibleForTesting
+    final Constants mConstants;
 
     @VisibleForTesting
     static final class UidState {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index b774647..44c1715 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -406,6 +406,10 @@
         mAudioService.checkVolumeCecOnHdmiConnection(state, caller);
     }
 
+    /*package*/ boolean hasAudioFocusUsers() {
+        return mAudioService.hasAudioFocusUsers();
+    }
+
     //---------------------------------------------------------------------
     // Message handling on behalf of helper classes
     /*package*/ void postBroadcastScoConnectionState(int state) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 7750bfe..91b51b4 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -819,11 +819,12 @@
         if (((device == musicDevice) || mDeviceBroker.isInCommunication())
                 && (device == devices) && !mDeviceBroker.hasMediaDynamicPolicy()
                         && ((musicDevice & AudioSystem.DEVICE_OUT_REMOTE_SUBMIX) == 0)) {
-            if (!AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0 /*not looking in past*/)) {
+            if (!AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0 /*not looking in past*/)
+                    && !mDeviceBroker.hasAudioFocusUsers()) {
                 // no media playback, not a "becoming noisy" situation, otherwise it could cause
                 // the pausing of some apps that are playing remotely
                 AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
-                        "dropping ACTION_AUDIO_BECOMING_NOISY, no media playback")).printLog(TAG));
+                        "dropping ACTION_AUDIO_BECOMING_NOISY")).printLog(TAG));
                 return 0;
             }
             mDeviceBroker.postBroadcastBecomingNoisy();
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index d58888a..70af907 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -90,9 +90,8 @@
 import android.media.audiopolicy.AudioMix;
 import android.media.audiopolicy.AudioPolicy;
 import android.media.audiopolicy.AudioPolicyConfig;
-import android.media.audiopolicy.AudioProductStrategies;
+import android.media.audiopolicy.AudioProductStrategy;
 import android.media.audiopolicy.AudioVolumeGroup;
-import android.media.audiopolicy.AudioVolumeGroups;
 import android.media.audiopolicy.IAudioPolicyCallback;
 import android.media.projection.IMediaProjection;
 import android.media.projection.IMediaProjectionManager;
@@ -281,11 +280,6 @@
 
     private SettingsObserver mSettingsObserver;
 
-    /** @see AudioProductStrategies */
-    private static AudioProductStrategies sAudioProductStrategies;
-    /** @see AudioVolumeGroups */
-    private static AudioVolumeGroups sAudioVolumeGroups;
-
     private int mMode = AudioSystem.MODE_NORMAL;
     // protects mRingerMode
     private final Object mSettingsLock = new Object();
@@ -636,19 +630,17 @@
         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
         mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
 
-        sAudioProductStrategies = new AudioProductStrategies();
-        sAudioVolumeGroups = new AudioVolumeGroups();
-
         // Initialize volume
         // Priority 1 - Android Property
         // Priority 2 - Audio Policy Service
         // Priority 3 - Default Value
-        if (sAudioProductStrategies.size() > 0) {
+        if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
             int numStreamTypes = AudioSystem.getNumStreamTypes();
 
             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
                 AudioAttributes attr =
-                        sAudioProductStrategies.getAudioAttributesForLegacyStreamType(streamType);
+                        AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
+                                streamType);
                 int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr);
                 if (maxVolume != -1) {
                     MAX_STREAM_VOLUME[streamType] = maxVolume;
@@ -1023,19 +1015,21 @@
     }
 
     /**
-     * @return the {@link android.media.audiopolicy.AudioProductStrategies} discovered from the
+     * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the
      * platform configuration file.
      */
-    public @NonNull AudioProductStrategies getAudioProductStrategies() {
-        return sAudioProductStrategies;
+    @NonNull
+    public List<AudioProductStrategy> getAudioProductStrategies() {
+        return AudioProductStrategy.getAudioProductStrategies();
     }
 
     /**
-     * @return the {@link android.media.audiopolicy.AudioVolumeGroups} discovered from the
+     * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the
      * platform configuration file.
      */
-    public @NonNull AudioVolumeGroups listAudioVolumeGroups() {
-        return sAudioVolumeGroups;
+    @NonNull
+    public List<AudioVolumeGroup> getAudioVolumeGroups() {
+        return AudioVolumeGroup.getAudioVolumeGroups();
     }
 
     private void checkAllAliasStreamVolumes() {
@@ -1529,9 +1523,11 @@
                 + ", flags=" + flags + ", caller=" + caller
                 + ", volControlStream=" + mVolumeControlStream
                 + ", userSelect=" + mUserSelectedVolumeControlStream);
-        sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType,
-                direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
-                        .append("/").append(caller).append(" uid:").append(uid).toString()));
+        if (direction != AudioManager.ADJUST_SAME) {
+            sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType,
+                    direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
+                    .append("/").append(caller).append(" uid:").append(uid).toString()));
+        }
         final int streamType;
         synchronized (mForceControlStreamLock) {
             // Request lock in case mVolumeControlStream is changed by other thread.
@@ -1947,15 +1943,15 @@
         enforceModifyAudioRoutingPermission();
         Preconditions.checkNotNull(attr, "attr must not be null");
         // @todo not hold the caller context, post message
-        int stream = sAudioProductStrategies.getLegacyStreamTypeForAudioAttributes(attr);
+        int stream = AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes(attr);
         final int device = getDeviceForStream(stream);
 
         int oldIndex = AudioSystem.getVolumeIndexForAttributes(attr, device);
 
         AudioSystem.setVolumeIndexForAttributes(attr, index, device);
 
-        final int volumeGroup = sAudioProductStrategies.getVolumeGroupIdForAttributes(attr);
-        final AudioVolumeGroup avg = sAudioVolumeGroups.getById(volumeGroup);
+        final int volumeGroup = getVolumeGroupIdForAttributes(attr);
+        final AudioVolumeGroup avg = getAudioVolumeGroupById(volumeGroup);
         if (avg == null) {
             return;
         }
@@ -1965,11 +1961,23 @@
         }
     }
 
+    @Nullable
+    private AudioVolumeGroup getAudioVolumeGroupById(int volumeGroupId) {
+        for (final AudioVolumeGroup avg : AudioVolumeGroup.getAudioVolumeGroups()) {
+            if (avg.getId() == volumeGroupId) {
+                return avg;
+            }
+        }
+
+        Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested");
+        return null;
+    }
+
     /** @see AudioManager#getVolumeIndexForAttributes(attr) */
     public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
         enforceModifyAudioRoutingPermission();
         Preconditions.checkNotNull(attr, "attr must not be null");
-        int stream = sAudioProductStrategies.getLegacyStreamTypeForAudioAttributes(attr);
+        int stream = AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes(attr);
         final int device = getDeviceForStream(stream);
 
         return AudioSystem.getVolumeIndexForAttributes(attr, device);
@@ -2144,6 +2152,32 @@
         sendVolumeUpdate(streamType, oldIndex, index, flags);
     }
 
+
+
+    private int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) {
+        Preconditions.checkNotNull(attributes, "attributes must not be null");
+        int volumeGroupId = getVolumeGroupIdForAttributesInt(attributes);
+        if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
+            return volumeGroupId;
+        }
+        // The default volume group is the one hosted by default product strategy, i.e.
+        // supporting Default Attributes
+        return getVolumeGroupIdForAttributesInt(AudioProductStrategy.sDefaultAttributes);
+    }
+
+    private int getVolumeGroupIdForAttributesInt(@NonNull AudioAttributes attributes) {
+        Preconditions.checkNotNull(attributes, "attributes must not be null");
+        for (final AudioProductStrategy productStrategy :
+                AudioProductStrategy.getAudioProductStrategies()) {
+            int volumeGroupId = productStrategy.getVolumeGroupIdForAudioAttributes(attributes);
+            if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
+                return volumeGroupId;
+            }
+        }
+        return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
+    }
+
+
     // No ringer or zen muted stream volumes can be changed unless it'll exit dnd
     private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) {
         switch (mNm.getZenMode()) {
@@ -5546,6 +5580,10 @@
         return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr);
     }
 
+    /*package*/ boolean hasAudioFocusUsers() {
+        return mMediaFocusControl.hasAudioFocusUsers();
+    }
+
     //==========================================================================================
     private boolean readCameraSoundForced() {
         return SystemProperties.getBoolean("audio.camerasound.force", false) ||
@@ -6288,6 +6326,11 @@
         @Override
         public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
                 String callingPackage, int uid) {
+            if (direction != AudioManager.ADJUST_SAME) {
+                sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType,
+                        direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
+                        .append(" uid:").append(uid).toString()));
+            }
             adjustStreamVolume(streamType, direction, flags, callingPackage,
                     callingPackage, uid);
         }
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index 7ccb45e..d999217 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -94,6 +94,7 @@
         static final int VOL_SET_STREAM_VOL = 2;
         static final int VOL_SET_HEARING_AID_VOL = 3;
         static final int VOL_SET_AVRCP_VOL = 4;
+        static final int VOL_ADJUST_VOL_UID = 5;
 
         final int mOp;
         final int mStream;
@@ -160,6 +161,13 @@
                     return new StringBuilder("setAvrcpVolume:")
                             .append(" index:").append(mVal1)
                             .toString();
+                case VOL_ADJUST_VOL_UID:
+                    return new StringBuilder("adjustStreamVolumeForUid(stream:")
+                            .append(AudioSystem.streamToString(mStream))
+                            .append(" dir:").append(AudioManager.adjustToString(mVal1))
+                            .append(" flags:0x").append(Integer.toHexString(mVal2))
+                            .append(") from ").append(mCaller)
+                            .toString();
                default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
             }
         }
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index 1e58b45..5c93071 100644
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -162,6 +162,12 @@
         }
     }
 
+    /*package*/ boolean hasAudioFocusUsers() {
+        synchronized (mAudioFocusLock) {
+            return !mFocusStack.empty();
+        }
+    }
+
     /**
      * Discard the current audio focus owner.
      * Notify top of audio focus stack that it lost focus (regardless of possibility to reassign
diff --git a/services/core/java/com/android/server/biometrics/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
index b2c5c05..91da7af 100644
--- a/services/core/java/com/android/server/biometrics/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
@@ -134,7 +134,8 @@
                     + ", Owner: " + getOwnerString()
                     + ", isBP: " + isBiometricPrompt()
                     + ", listener: " + listener
-                    + ", requireConfirmation: " + mRequireConfirmation);
+                    + ", requireConfirmation: " + mRequireConfirmation
+                    + ", user: " + getTargetUserId());
 
             if (authenticated) {
                 mAlreadyDone = true;
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index aa52621..e218c6b 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -42,14 +42,13 @@
 import android.os.Build;
 import android.os.Environment;
 import android.os.IBinder;
+import android.os.NativeHandle;
 import android.os.RemoteException;
 import android.os.SELinux;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.service.restricted_image.RestrictedImageProto;
-import android.service.restricted_image.RestrictedImageSetProto;
-import android.service.restricted_image.RestrictedImagesDumpProto;
+import android.provider.Settings;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
@@ -70,8 +69,11 @@
 
 import java.io.File;
 import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -286,8 +288,8 @@
 
             final long ident = Binder.clearCallingIdentity();
             try {
-                if (args.length == 1 && "--restricted_image".equals(args[0])) {
-                    dumpRestrictedImage(fd);
+                if (args.length > 1 && "--hal".equals(args[0])) {
+                    dumpHal(fd, Arrays.copyOfRange(args, 1, args.length, args.getClass()));
                 } else if (args.length > 0 && "--proto".equals(args[0])) {
                     dumpProto(fd);
                 } else {
@@ -546,7 +548,8 @@
                 throws RemoteException {
             if (mFaceServiceReceiver != null) {
                 if (biometric == null || biometric instanceof Face) {
-                    mFaceServiceReceiver.onAuthenticationSucceeded(deviceId, (Face)biometric);
+                    mFaceServiceReceiver.onAuthenticationSucceeded(deviceId, (Face) biometric,
+                            userId);
                 } else {
                     Slog.e(TAG, "onAuthenticationSucceeded received non-face biometric");
                 }
@@ -1078,7 +1081,7 @@
         mCryptoPerformanceMap.clear();
     }
 
-    private void dumpRestrictedImage(FileDescriptor fd) {
+    private void dumpHal(FileDescriptor fd, String[] args) {
         // WARNING: CDD restricts image data from leaving TEE unencrypted on
         //          production devices:
         // [C-1-10] MUST not allow unencrypted access to identifiable biometric
@@ -1099,59 +1102,28 @@
             return;
         }
 
-        final ProtoOutputStream proto = new ProtoOutputStream(fd);
-
-        final long setToken = proto.start(RestrictedImagesDumpProto.SETS);
-
-        // Name of the service
-        proto.write(RestrictedImageSetProto.CATEGORY, "face");
-
-        // Individual images
-        for (int i = 0; i < 5; i++) {
-            final long imageToken = proto.start(RestrictedImageSetProto.IMAGES);
-            proto.write(RestrictedImageProto.MIME_TYPE, "image/png");
-            proto.write(RestrictedImageProto.IMAGE_DATA, new byte[] {
-                    // png image data
-                    -119,   80,   78,   71,   13,   10,   26,   10,
-                       0,    0,    0,   13,   73,   72,   68,   82,
-                       0,    0,    0,  100,    0,    0,    0,  100,
-                       1,    3,    0,    0,    0,   74,   44,    7,
-                      23,    0,    0,    0,    4,  103,   65,   77,
-                      65,    0,    0,  -79, -113,   11,   -4,   97,
-                       5,    0,    0,    0,    1,  115,   82,   71,
-                      66,    0,  -82,  -50,   28,  -23,    0,    0,
-                       0,    6,   80,   76,   84,   69,   -1,   -1,
-                      -1,    0,    0,    0,   85,  -62,  -45,  126,
-                       0,    0,    0, -115,   73,   68,   65,   84,
-                      56,  -53,  -19,  -46,  -79,   17, -128,   32,
-                      12,    5,  -48,  120,   22, -106, -116,  -32,
-                      40,  -84,  101, -121,  -93,   57,   10,   35,
-                      88,   82,  112,  126,    3,  -60,  104,    6,
-                    -112,   70,  127,  -59,  -69,  -53,   29,   33,
-                    -127,  -24,   79,  -49,  -52,  -15,   41,   36,
-                      34, -105,   85,  124,  -14,   88,   27,    6,
-                      28,   68,    1,   82,   62,   22,  -95, -108,
-                      55,  -95,   40,   -9, -110,  -12,   98, -107,
-                      76,  -41, -105,  -62,  -50,  111,  -60,   46,
-                     -14,   -4,   24,  -89,   42, -103,   16,   63,
-                     -72,  -11,  -15,   48,  -62,  102,  -44,  102,
-                     -73,  -56,   56,  -21, -128,   92,  -70, -124,
-                     117,  -46,  -67,  -77,   82,   80,  121,  -44,
-                     -56,  116,   93,  -45,  -90,   -5,  -29,  -24,
-                     -83,  -75,   52,  -34,   55,  -22,  102,  -21,
-                    -105, -124,  -23,   71,   87,   -7,  -25,  -59,
-                    -100,  -73,  -92, -122,   -7, -109,  -49,  -80,
-                     -89,    0,    0,    0,    0,   73,   69,   78,
-                      68,  -82,   66,   96, -126
-            });
-            // proto.write(RestrictedImageProto.METADATA, flattened_protobuf);
-            proto.end(imageToken);
+        // The debug method takes two file descriptors. The first is for text
+        // output, which we will drop.  The second is for binary data, which
+        // will be the protobuf data.
+        final IBiometricsFace daemon = getFaceDaemon();
+        if (daemon != null) {
+            FileOutputStream devnull = null;
+            try {
+                devnull = new FileOutputStream("/dev/null");
+                final NativeHandle handle = new NativeHandle(
+                        new FileDescriptor[] { devnull.getFD(), fd },
+                        new int[0], false);
+                daemon.debug(handle, new ArrayList<String>(Arrays.asList(args)));
+            } catch (IOException | RemoteException ex) {
+                Slog.d(TAG, "error while reading face debugging data", ex);
+            } finally {
+                if (devnull != null) {
+                    try {
+                        devnull.close();
+                    } catch (IOException ex) {
+                    }
+                }
+            }
         }
-
-        // Face service metadata
-        // proto.write(RestrictedImageSetProto.METADATA, flattened_protobuf);
-
-        proto.end(setToken);
-        proto.flush();
     }
 }
diff --git a/services/core/java/com/android/server/incident/IncidentCompanionService.java b/services/core/java/com/android/server/incident/IncidentCompanionService.java
index 9989c1a..87fe785 100644
--- a/services/core/java/com/android/server/incident/IncidentCompanionService.java
+++ b/services/core/java/com/android/server/incident/IncidentCompanionService.java
@@ -55,7 +55,8 @@
      * Dump argument for proxying restricted image dumps to the services
      * listed in the config.
      */
-    private static String[] RESTRICTED_IMAGE_DUMP_ARGS = new String[] { "--restricted_image" };
+    private static String[] RESTRICTED_IMAGE_DUMP_ARGS = new String[] {
+        "--hal", "--restricted_image" };
 
     /**
      * The two permissions, for sendBroadcastAsUserMultiplePermissions.
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index cec4d69..75b9705 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -523,11 +523,17 @@
         }
 
 
-        InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
-        InputMonitorHost host = new InputMonitorHost(inputChannels[0]);
-        inputChannels[0].setToken(host.asBinder());
-        nativeRegisterInputMonitor(mPtr, inputChannels[0], displayId, true /*isGestureMonitor*/);
-        return new InputMonitor(inputChannelName, inputChannels[1], host);
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
+            InputMonitorHost host = new InputMonitorHost(inputChannels[0]);
+            inputChannels[0].setToken(host.asBinder());
+            nativeRegisterInputMonitor(mPtr, inputChannels[0], displayId,
+                    true /*isGestureMonitor*/);
+            return new InputMonitor(inputChannelName, inputChannels[1], host);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index e88d62f..3c97c39 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -4710,10 +4710,10 @@
     @ShellCommandResult
     private int handleShellCommandEnableDisableInputMethod(
             @NonNull ShellCommand shellCommand, boolean enabled) {
+        final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
         final String imeId = shellCommand.getNextArgRequired();
         final PrintWriter out = shellCommand.getOutPrintWriter();
         final PrintWriter error = shellCommand.getErrPrintWriter();
-        final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
         synchronized (mMethodMap) {
             final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
                     mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
@@ -4733,6 +4733,10 @@
      *
      * <p>You cannot use this helper method if the command has other options.</p>
      *
+     * <p>CAVEAT: This method must be called only once before any other
+     * {@link ShellCommand#getNextArg()} and {@link ShellCommand#getNextArgRequired()} for the
+     * main arguments.</p>
+     *
      * @param shellCommand {@link ShellCommand} from which options should be obtained.
      * @return User ID to be resolved. {@link UserHandle#CURRENT} if not specified.
      */
@@ -4819,10 +4823,10 @@
     @BinderThread
     @ShellCommandResult
     private int handleShellCommandSetInputMethod(@NonNull ShellCommand shellCommand) {
+        final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
         final String imeId = shellCommand.getNextArgRequired();
         final PrintWriter out = shellCommand.getOutPrintWriter();
         final PrintWriter error = shellCommand.getErrPrintWriter();
-        final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
         synchronized (mMethodMap) {
             final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
                     mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
@@ -4864,7 +4868,7 @@
                     out.print("Input method ");
                     out.print(imeId);
                     out.print(" selected for user #");
-                    error.println(userId);
+                    out.println(userId);
                 }
             }
         }
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index e28f89c..96fc6ec 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -495,6 +495,7 @@
     @Override
     public void onUpdateSatelliteBlacklist(int[] constellations, int[] svids) {
         mHandler.post(() -> mGnssConfiguration.setSatelliteBlacklist(constellations, svids));
+        mGnssMetrics.resetConstellationTypes();
     }
 
     private void subscriptionOrCarrierConfigChanged(Context context) {
@@ -1443,6 +1444,13 @@
                                 GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
                                 ? "" : "F"));
             }
+
+            if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
+                int constellationType =
+                        (info.mSvidWithFlags[i] >> GnssStatus.CONSTELLATION_TYPE_SHIFT_WIDTH)
+                                & GnssStatus.CONSTELLATION_TYPE_MASK;
+                mGnssMetrics.logConstellationType(constellationType);
+            }
         }
         if (usedInFixCount > 0) {
             meanCn0 /= usedInFixCount;
diff --git a/services/core/java/com/android/server/locksettings/PasswordSlotManager.java b/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
index 686ae2b..5cbd237 100644
--- a/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
+++ b/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
@@ -52,10 +52,12 @@
     // This maps each used password slot to the OS image that created it. Password slots are
     // integer keys/indices into secure storage. The OS image is recorded as a string. The factory
     // image is "host" and GSIs are "gsi<N>" where N >= 1.
-    private final Map<Integer, String> mSlotMap;
+    private Map<Integer, String> mSlotMap;
+
+    // Cache the active slots until loadSlotMap() is called.
+    private Set<Integer> mActiveSlots;
 
     public PasswordSlotManager() {
-        mSlotMap = loadSlotMap();
     }
 
     @VisibleForTesting
@@ -74,6 +76,11 @@
      * @throws RuntimeException
      */
     public void refreshActiveSlots(Set<Integer> activeSlots) throws RuntimeException {
+        if (mSlotMap == null) {
+            mActiveSlots = new HashSet<Integer>(activeSlots);
+            return;
+        }
+
         // Update which slots are owned by the current image.
         final HashSet<Integer> slotsToDelete = new HashSet<Integer>();
         for (Map.Entry<Integer, String> entry : mSlotMap.entrySet()) {
@@ -100,6 +107,7 @@
      * @throws RuntimeException
      */
     public void markSlotInUse(int slot) throws RuntimeException {
+        ensureSlotMapLoaded();
         if (mSlotMap.containsKey(slot) && !mSlotMap.get(slot).equals(getMode())) {
             throw new RuntimeException("password slot " + slot + " is not available");
         }
@@ -113,6 +121,7 @@
      * @throws RuntimeException
      */
     public void markSlotDeleted(int slot) throws RuntimeException {
+        ensureSlotMapLoaded();
         if (mSlotMap.containsKey(slot) && mSlotMap.get(slot) != getMode()) {
             throw new RuntimeException("password slot " + slot + " cannot be deleted");
         }
@@ -126,6 +135,7 @@
      * @return Integer set of all used slots.
      */
     public Set<Integer> getUsedSlots() {
+        ensureSlotMapLoaded();
         return Collections.unmodifiableSet(mSlotMap.keySet());
     }
 
@@ -167,8 +177,21 @@
         return new HashMap<Integer, String>();
     }
 
+    private void ensureSlotMapLoaded() {
+        if (mSlotMap == null) {
+            mSlotMap = loadSlotMap();
+            if (mActiveSlots != null) {
+                refreshActiveSlots(mActiveSlots);
+                mActiveSlots = null;
+            }
+        }
+    }
+
     @VisibleForTesting
     protected void saveSlotMap(OutputStream stream) throws IOException {
+        if (mSlotMap == null) {
+            return;
+        }
         final Properties props = new Properties();
         for (Map.Entry<Integer, String> entry : mSlotMap.entrySet()) {
             props.setProperty(entry.getKey().toString(), entry.getValue());
@@ -177,6 +200,9 @@
     }
 
     private void saveSlotMap() {
+        if (mSlotMap == null) {
+            return;
+        }
         if (!getSlotMapFile().getParentFile().exists()) {
             Slog.w(TAG, "Not saving slot map, " + getSlotMapDir() + " does not exist");
             return;
diff --git a/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java b/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java
index 603d7cf..eb706d7 100644
--- a/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java
+++ b/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java
@@ -142,7 +142,8 @@
 
     /**
      * Returns the sorted list of UIDs that have had active audio playback. (i.e. playing an
-     * audio/video) The UID whose audio playback becomes active at the last comes first.
+     * audio/video) The UID whose audio is currently playing comes first, then the UID whose audio
+     * playback becomes active at the last comes next.
      */
     public IntArray getSortedAudioPlaybackClientUids() {
         IntArray sortedAudioPlaybackClientUids = new IntArray();
@@ -253,6 +254,26 @@
                         mSortedAudioPlaybackClientUids.add(0, uid);
                     }
                 }
+
+                if (mActiveAudioUids.size() > 0
+                        && !mActiveAudioUids.contains(mSortedAudioPlaybackClientUids.get(0))) {
+                    int firstActiveUid = -1;
+                    int firatActiveUidIndex = -1;
+                    for (int i = 1; i < mSortedAudioPlaybackClientUids.size(); ++i) {
+                        int uid = mSortedAudioPlaybackClientUids.get(i);
+                        if (mActiveAudioUids.contains(uid)) {
+                            firatActiveUidIndex = i;
+                            firstActiveUid = uid;
+                            break;
+                        }
+                    }
+                    for (int i = firatActiveUidIndex; i > 0; --i) {
+                        mSortedAudioPlaybackClientUids.set(i,
+                                mSortedAudioPlaybackClientUids.get(i - 1));
+                    }
+                    mSortedAudioPlaybackClientUids.set(0, firstActiveUid);
+                }
+
                 // Notify the active state change of audio players.
                 for (AudioPlaybackConfiguration config : configs) {
                     final int pii = config.getPlayerInterfaceId();
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
deleted file mode 100644
index d284c60..0000000
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.media;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.media.IMediaRoute2Callback;
-import android.media.IMediaRoute2Provider;
-import android.media.MediaRoute2ProviderService;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IBinder.DeathRecipient;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.Log;
-import android.util.Slog;
-
-import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-
-/**
- * Maintains a connection to a particular media route provider service.
- */
-final class MediaRoute2ProviderProxy implements ServiceConnection {
-    private static final String TAG = "MediaRoute2ProviderProxy";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private final Context mContext;
-    private final ComponentName mComponentName;
-    private final int mUserId;
-    private final Handler mHandler;
-
-    private Callback mCallback;
-
-    // Selected Route info
-    public int mSelectedUid;
-    public String mSelectedRouteId;
-
-    // Connection state
-    private boolean mRunning;
-    private boolean mBound;
-    private Connection mActiveConnection;
-    private boolean mConnectionReady;
-
-    MediaRoute2ProviderProxy(Context context, ComponentName componentName, int userId) {
-        mContext = context;
-        mComponentName = componentName;
-        mUserId = userId;
-        mHandler = new Handler();
-    }
-
-    public void dump(PrintWriter pw, String prefix) {
-        pw.println(prefix + "Proxy");
-        pw.println(prefix + "  mUserId=" + mUserId);
-        pw.println(prefix + "  mRunning=" + mRunning);
-        pw.println(prefix + "  mBound=" + mBound);
-        pw.println(prefix + "  mActiveConnection=" + mActiveConnection);
-        pw.println(prefix + "  mConnectionReady=" + mConnectionReady);
-    }
-
-    public void setCallback(Callback callback) {
-        mCallback = callback;
-    }
-
-    public void setSelectedRoute(int uid, String routeId) {
-        if (mConnectionReady) {
-            mActiveConnection.selectRoute(uid, routeId);
-            updateBinding();
-        }
-    }
-
-    public boolean hasComponentName(String packageName, String className) {
-        return mComponentName.getPackageName().equals(packageName)
-                && mComponentName.getClassName().equals(className);
-    }
-
-    public String getFlattenedComponentName() {
-        return mComponentName.flattenToShortString();
-    }
-
-    public void start() {
-        if (!mRunning) {
-            if (DEBUG) {
-                Slog.d(TAG, this + ": Starting");
-            }
-
-            mRunning = true;
-            updateBinding();
-        }
-    }
-
-    public void stop() {
-        if (mRunning) {
-            if (DEBUG) {
-                Slog.d(TAG, this + ": Stopping");
-            }
-
-            mRunning = false;
-            updateBinding();
-        }
-    }
-
-    public void rebindIfDisconnected() {
-        if (mActiveConnection == null && shouldBind()) {
-            unbind();
-            bind();
-        }
-    }
-
-    private void updateBinding() {
-        if (shouldBind()) {
-            bind();
-        } else {
-            unbind();
-        }
-    }
-
-    private boolean shouldBind() {
-        //TODO: binding could be delayed until it's necessary.
-        if (mRunning) {
-            return true;
-        }
-        return false;
-    }
-
-    private void bind() {
-        if (!mBound) {
-            if (DEBUG) {
-                Slog.d(TAG, this + ": Binding");
-            }
-
-            Intent service = new Intent(MediaRoute2ProviderService.SERVICE_INTERFACE);
-            service.setComponent(mComponentName);
-            try {
-                mBound = mContext.bindServiceAsUser(service, this,
-                        Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
-                        new UserHandle(mUserId));
-                if (!mBound && DEBUG) {
-                    Slog.d(TAG, this + ": Bind failed");
-                }
-            } catch (SecurityException ex) {
-                if (DEBUG) {
-                    Slog.d(TAG, this + ": Bind failed", ex);
-                }
-            }
-        }
-    }
-
-    private void unbind() {
-        if (mBound) {
-            if (DEBUG) {
-                Slog.d(TAG, this + ": Unbinding");
-            }
-
-            mBound = false;
-            disconnect();
-            mContext.unbindService(this);
-        }
-    }
-
-    @Override
-    public void onServiceConnected(ComponentName name, IBinder service) {
-        if (DEBUG) {
-            Slog.d(TAG, this + ": Connected");
-        }
-
-        if (mBound) {
-            disconnect();
-
-            IMediaRoute2Provider provider = IMediaRoute2Provider.Stub.asInterface(service);
-            if (provider != null) {
-                Connection connection = new Connection(provider);
-                if (connection.register()) {
-                    mActiveConnection = connection;
-                } else {
-                    if (DEBUG) {
-                        Slog.d(TAG, this + ": Registration failed");
-                    }
-                }
-            } else {
-                Slog.e(TAG, this + ": Service returned invalid remote display provider binder");
-            }
-        }
-    }
-
-    @Override
-    public void onServiceDisconnected(ComponentName name) {
-        if (DEBUG) {
-            Slog.d(TAG, this + ": Service disconnected");
-        }
-        disconnect();
-    }
-
-    private void onConnectionReady(Connection connection) {
-        if (mActiveConnection == connection) {
-            mConnectionReady = true;
-        }
-    }
-
-    private void onConnectionDied(Connection connection) {
-        if (mActiveConnection == connection) {
-            if (DEBUG) {
-                Slog.d(TAG, this + ": Service connection died");
-            }
-            disconnect();
-        }
-    }
-
-    private void onRouteSelected(Connection connection, int uid, String routeId) {
-        mSelectedUid = uid;
-        mSelectedRouteId = routeId;
-
-        if (mActiveConnection == connection) {
-            if (DEBUG) {
-                Slog.d(TAG, this + ": State changed ");
-            }
-            mHandler.post(mStateChanged);
-        }
-    }
-
-    private void disconnect() {
-        if (mActiveConnection != null) {
-            mConnectionReady = false;
-            mActiveConnection.dispose();
-            mActiveConnection = null;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "Service connection " + mComponentName.flattenToShortString();
-    }
-
-    private final Runnable mStateChanged = new Runnable() {
-        @Override
-        public void run() {
-            if (mCallback != null) {
-                mCallback.onProviderStateChanged(MediaRoute2ProviderProxy.this);
-            }
-        }
-    };
-
-    public interface Callback {
-        void onProviderStateChanged(MediaRoute2ProviderProxy provider);
-    }
-
-    private final class Connection implements DeathRecipient {
-        private final IMediaRoute2Provider mProvider;
-        private final ProviderCallback mCallback;
-
-        Connection(IMediaRoute2Provider provider) {
-            mProvider = provider;
-            mCallback = new ProviderCallback(this);
-        }
-
-        public boolean register() {
-            try {
-                mProvider.asBinder().linkToDeath(this, 0);
-                mProvider.setCallback(mCallback);
-                mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        onConnectionReady(Connection.this);
-                    }
-                });
-                return true;
-            } catch (RemoteException ex) {
-                binderDied();
-            }
-            return false;
-        }
-
-        public void dispose() {
-            mProvider.asBinder().unlinkToDeath(this, 0);
-            mCallback.dispose();
-        }
-
-        public void selectRoute(int uid, String id) {
-            try {
-                mProvider.selectRoute(uid, id);
-            } catch (RemoteException ex) {
-                Slog.e(TAG, "Failed to deliver request to set discovery mode.", ex);
-            }
-        }
-
-        @Override
-        public void binderDied() {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    onConnectionDied(Connection.this);
-                }
-            });
-        }
-
-        void postRouteSelected(int uid, String routeId) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    onRouteSelected(Connection.this, uid, routeId);
-                }
-            });
-        }
-    }
-
-    private static final class ProviderCallback extends IMediaRoute2Callback.Stub  {
-        private final WeakReference<Connection> mConnectionRef;
-
-        ProviderCallback(Connection connection) {
-            mConnectionRef = new WeakReference<Connection>(connection);
-        }
-
-        public void dispose() {
-            mConnectionRef.clear();
-        }
-
-        @Override
-        public void onRouteSelected(int uid, String routeId) throws RemoteException {
-            Connection connection = mConnectionRef.get();
-            if (connection != null) {
-                connection.postRouteSelected(uid, routeId);
-            }
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
deleted file mode 100644
index 08d8c58..0000000
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.media;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.media.MediaRoute2ProviderService;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.util.Log;
-import android.util.Slog;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- */
-final class MediaRoute2ProviderWatcher {
-    private static final String TAG = "MediaRouteProvider";  // max. 23 chars
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private final Context mContext;
-    private final Callback mCallback;
-    private final Handler mHandler;
-    private final int mUserId;
-    private final PackageManager mPackageManager;
-
-    private final ArrayList<MediaRoute2ProviderProxy> mProviders = new ArrayList<>();
-    private boolean mRunning;
-
-    MediaRoute2ProviderWatcher(Context context,
-            Callback callback, Handler handler, int userId) {
-        mContext = context;
-        mCallback = callback;
-        mHandler = handler;
-        mUserId = userId;
-        mPackageManager = context.getPackageManager();
-    }
-
-    public void dump(PrintWriter pw, String prefix) {
-        pw.println(prefix + "Watcher");
-        pw.println(prefix + "  mUserId=" + mUserId);
-        pw.println(prefix + "  mRunning=" + mRunning);
-        pw.println(prefix + "  mProviders.size()=" + mProviders.size());
-    }
-
-    public void start() {
-        if (!mRunning) {
-            mRunning = true;
-
-            IntentFilter filter = new IntentFilter();
-            filter.addAction(Intent.ACTION_PACKAGE_ADDED);
-            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-            filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-            filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
-            filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
-            filter.addDataScheme("package");
-            mContext.registerReceiverAsUser(mScanPackagesReceiver,
-                    new UserHandle(mUserId), filter, null, mHandler);
-
-            // Scan packages.
-            // Also has the side-effect of restarting providers if needed.
-            mHandler.post(mScanPackagesRunnable);
-        }
-    }
-
-    public void stop() {
-        if (mRunning) {
-            mRunning = false;
-
-            mContext.unregisterReceiver(mScanPackagesReceiver);
-            mHandler.removeCallbacks(mScanPackagesRunnable);
-
-            // Stop all providers.
-            for (int i = mProviders.size() - 1; i >= 0; i--) {
-                mProviders.get(i).stop();
-            }
-        }
-    }
-
-    private void scanPackages() {
-        if (!mRunning) {
-            return;
-        }
-
-        // Add providers for all new services.
-        // Reorder the list so that providers left at the end will be the ones to remove.
-        int targetIndex = 0;
-        Intent intent = new Intent(MediaRoute2ProviderService.SERVICE_INTERFACE);
-        for (ResolveInfo resolveInfo : mPackageManager.queryIntentServicesAsUser(
-                intent, 0, mUserId)) {
-            ServiceInfo serviceInfo = resolveInfo.serviceInfo;
-            if (serviceInfo != null) {
-                int sourceIndex = findProvider(serviceInfo.packageName, serviceInfo.name);
-                if (sourceIndex < 0) {
-                    MediaRoute2ProviderProxy provider =
-                            new MediaRoute2ProviderProxy(mContext,
-                            new ComponentName(serviceInfo.packageName, serviceInfo.name),
-                            mUserId);
-                    provider.start();
-                    mProviders.add(targetIndex++, provider);
-                    mCallback.addProvider(provider);
-                } else if (sourceIndex >= targetIndex) {
-                    MediaRoute2ProviderProxy provider = mProviders.get(sourceIndex);
-                    provider.start(); // restart the provider if needed
-                    provider.rebindIfDisconnected();
-                    Collections.swap(mProviders, sourceIndex, targetIndex++);
-                }
-            }
-        }
-
-        // Remove providers for missing services.
-        if (targetIndex < mProviders.size()) {
-            for (int i = mProviders.size() - 1; i >= targetIndex; i--) {
-                MediaRoute2ProviderProxy provider = mProviders.get(i);
-                mCallback.removeProvider(provider);
-                mProviders.remove(provider);
-                provider.stop();
-            }
-        }
-    }
-
-    private int findProvider(String packageName, String className) {
-        int count = mProviders.size();
-        for (int i = 0; i < count; i++) {
-            MediaRoute2ProviderProxy provider = mProviders.get(i);
-            if (provider.hasComponentName(packageName, className)) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    private final BroadcastReceiver mScanPackagesReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (DEBUG) {
-                Slog.d(TAG, "Received package manager broadcast: " + intent);
-            }
-            scanPackages();
-        }
-    };
-
-    private final Runnable mScanPackagesRunnable = new Runnable() {
-        @Override
-        public void run() {
-            scanPackages();
-        }
-    };
-
-    public interface Callback {
-        void addProvider(MediaRoute2ProviderProxy provider);
-        void removeProvider(MediaRoute2ProviderProxy provider);
-    }
-}
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index a43533f..23d3ce0 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -30,7 +30,6 @@
 import android.media.AudioSystem;
 import android.media.IAudioRoutesObserver;
 import android.media.IAudioService;
-import android.media.IMediaRouter2ManagerClient;
 import android.media.IMediaRouterClient;
 import android.media.IMediaRouterService;
 import android.media.MediaRouter;
@@ -50,7 +49,6 @@
 import android.util.ArrayMap;
 import android.util.IntArray;
 import android.util.Log;
-import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TimeUtils;
@@ -98,7 +96,6 @@
     private final Object mLock = new Object();
     private final SparseArray<UserRecord> mUserRecords = new SparseArray<>();
     private final ArrayMap<IBinder, ClientRecord> mAllClientRecords = new ArrayMap<>();
-    private final ArrayMap<IBinder, ManagerRecord> mAllManagerRecords = new ArrayMap<>();
     private int mCurrentUserId = -1;
     private final IAudioService mAudioService;
     private final AudioPlayerStateMonitor mAudioPlayerStateMonitor;
@@ -307,22 +304,6 @@
 
     // Binder call
     @Override
-    public void setControlCategories(IMediaRouterClient client, List<String> categories) {
-        if (client == null) {
-            throw new IllegalArgumentException("client must not be null");
-        }
-        final long token = Binder.clearCallingIdentity();
-        try {
-            synchronized (mLock) {
-                setControlCategoriesLocked(client, categories);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    // Binder call
-    @Override
     public void setDiscoveryRequest(IMediaRouterClient client,
             int routeTypes, boolean activeScan) {
         if (client == null) {
@@ -421,65 +402,6 @@
         }
     }
 
-    // Binder call
-    @Override
-    public void registerManagerAsUser(IMediaRouter2ManagerClient client,
-            String packageName, int userId) {
-        if (client == null) {
-            throw new IllegalArgumentException("client must not be null");
-        }
-        //TODO: should check permission
-        final boolean trusted = true;
-
-        final int uid = Binder.getCallingUid();
-        if (!validatePackageName(uid, packageName)) {
-            throw new SecurityException("packageName must match the calling uid");
-        }
-
-        final int pid = Binder.getCallingPid();
-        final int resolvedUserId = ActivityManager.handleIncomingUser(pid, uid, userId,
-                false /*allowAll*/, true /*requireFull*/, "registerManagerAsUser", packageName);
-        final long token = Binder.clearCallingIdentity();
-        try {
-            synchronized (mLock) {
-                registerManagerLocked(client, uid, pid, packageName, resolvedUserId, trusted);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    // Binder call
-    @Override
-    public void unregisterManager(IMediaRouter2ManagerClient client) {
-        if (client == null) {
-            throw new IllegalArgumentException("client must not be null");
-        }
-
-        final long token = Binder.clearCallingIdentity();
-        try {
-            synchronized (mLock) {
-                unregisterManagerLocked(client, false);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    // Binder call
-    @Override
-    public void setRemoteRoute(IMediaRouter2ManagerClient client,
-            int uid, String routeId, boolean explicit) {
-        final long token = Binder.clearCallingIdentity();
-        try {
-            synchronized (mLock) {
-                setRemoteRouteLocked(client, uid, routeId, explicit);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
     void restoreBluetoothA2dp() {
         try {
             boolean a2dpOn;
@@ -551,12 +473,6 @@
         }
     }
 
-    void clientDied(ManagerRecord managerRecord) {
-        synchronized (mLock) {
-            unregisterManagerLocked(managerRecord.mClient, true);
-        }
-    }
-
     private void registerClientLocked(IMediaRouterClient client,
             int uid, int pid, String packageName, int userId, boolean trusted) {
         final IBinder binder = client.asBinder();
@@ -604,17 +520,6 @@
         return null;
     }
 
-    private void setControlCategoriesLocked(IMediaRouterClient client, List<String> categories) {
-        final IBinder binder = client.asBinder();
-        ClientRecord clientRecord = mAllClientRecords.get(binder);
-
-        if (clientRecord != null) {
-            clientRecord.mControlCategories = categories;
-            clientRecord.mUserRecord.mHandler.obtainMessage(
-                    UserHandler.MSG_UPDATE_CLIENT_USAGE, clientRecord).sendToTarget();
-        }
-    }
-
     private void setDiscoveryRequestLocked(IMediaRouterClient client,
             int routeTypes, boolean activeScan) {
         final IBinder binder = client.asBinder();
@@ -668,63 +573,6 @@
         }
     }
 
-    private void registerManagerLocked(IMediaRouter2ManagerClient client,
-            int uid, int pid, String packageName, int userId, boolean trusted) {
-        final IBinder binder = client.asBinder();
-        ManagerRecord managerRecord = mAllManagerRecords.get(binder);
-        if (managerRecord == null) {
-            boolean newUser = false;
-            UserRecord userRecord = mUserRecords.get(userId);
-            if (userRecord == null) {
-                userRecord = new UserRecord(userId);
-                newUser = true;
-            }
-            managerRecord = new ManagerRecord(userRecord, client, uid, pid, packageName, trusted);
-            try {
-                binder.linkToDeath(managerRecord, 0);
-            } catch (RemoteException ex) {
-                throw new RuntimeException("Media router client died prematurely.", ex);
-            }
-
-            if (newUser) {
-                mUserRecords.put(userId, userRecord);
-                initializeUserLocked(userRecord);
-            }
-
-            userRecord.mManagerRecords.add(managerRecord);
-            mAllManagerRecords.put(binder, managerRecord);
-
-            // send client usage to manager
-            final int clientCount = userRecord.mClientRecords.size();
-            for (int i = 0; i < clientCount; i++) {
-                userRecord.mHandler.obtainMessage(UserHandler.MSG_UPDATE_CLIENT_USAGE,
-                        userRecord.mClientRecords.get(i)).sendToTarget();
-            }
-        }
-    }
-
-    private void unregisterManagerLocked(IMediaRouter2ManagerClient client, boolean died) {
-        ManagerRecord clientRecord = mAllManagerRecords.remove(client.asBinder());
-        if (clientRecord != null) {
-            UserRecord userRecord = clientRecord.mUserRecord;
-            userRecord.mManagerRecords.remove(clientRecord);
-            clientRecord.dispose();
-            disposeUserIfNeededLocked(userRecord); // since client removed from user
-        }
-    }
-
-    private void setRemoteRouteLocked(IMediaRouter2ManagerClient client,
-            int uid, String routeId, boolean explicit) {
-        ManagerRecord managerRecord = mAllManagerRecords.get(client.asBinder());
-        if (managerRecord != null) {
-            if (explicit && managerRecord.mTrusted) {
-                Pair<Integer, String> obj = new Pair<>(uid, routeId);
-                managerRecord.mUserRecord.mHandler.obtainMessage(
-                        UserHandler.MSG_SELECT_REMOTE_ROUTE, obj).sendToTarget();
-            }
-        }
-    }
-
     private void requestSetVolumeLocked(IMediaRouterClient client,
             String routeId, int volume) {
         final IBinder binder = client.asBinder();
@@ -817,46 +665,6 @@
         }
     }
 
-    final class ManagerRecord implements DeathRecipient {
-        public final UserRecord mUserRecord;
-        public final IMediaRouter2ManagerClient mClient;
-        public final int mUid;
-        public final int mPid;
-        public final String mPackageName;
-        public final boolean mTrusted;
-
-        ManagerRecord(UserRecord userRecord, IMediaRouter2ManagerClient client,
-                int uid, int pid, String packageName, boolean trusted) {
-            mUserRecord = userRecord;
-            mClient = client;
-            mUid = uid;
-            mPid = pid;
-            mPackageName = packageName;
-            mTrusted = trusted;
-        }
-
-        public void dispose() {
-            mClient.asBinder().unlinkToDeath(this, 0);
-        }
-
-        @Override
-        public void binderDied() {
-            clientDied(this);
-        }
-
-        public void dump(PrintWriter pw, String prefix) {
-            pw.println(prefix + this);
-
-            final String indent = prefix + "  ";
-            pw.println(indent + "mTrusted=" + mTrusted);
-        }
-
-        @Override
-        public String toString() {
-            return "Client " + mPackageName + " (pid " + mPid + ")";
-        }
-    }
-
     /**
      * Information about a particular client of the media router.
      * The contents of this object is guarded by mLock.
@@ -868,7 +676,6 @@
         public final int mPid;
         public final String mPackageName;
         public final boolean mTrusted;
-        public List<String> mControlCategories;
 
         public int mRouteTypes;
         public boolean mActiveScan;
@@ -919,8 +726,7 @@
      */
     final class UserRecord {
         public final int mUserId;
-        public final ArrayList<ClientRecord> mClientRecords = new ArrayList<>();
-        public final ArrayList<ManagerRecord> mManagerRecords = new ArrayList<>();
+        public final ArrayList<ClientRecord> mClientRecords = new ArrayList<ClientRecord>();
         public final UserHandler mHandler;
         public MediaRouterClientState mRouterState;
 
@@ -975,9 +781,7 @@
      */
     static final class UserHandler extends Handler
             implements RemoteDisplayProviderWatcher.Callback,
-            RemoteDisplayProviderProxy.Callback,
-            MediaRoute2ProviderWatcher.Callback,
-            MediaRoute2ProviderProxy.Callback {
+            RemoteDisplayProviderProxy.Callback {
         public static final int MSG_START = 1;
         public static final int MSG_STOP = 2;
         public static final int MSG_UPDATE_DISCOVERY_REQUEST = 3;
@@ -988,9 +792,6 @@
         private static final int MSG_UPDATE_CLIENT_STATE = 8;
         private static final int MSG_CONNECTION_TIMED_OUT = 9;
 
-        private static final int MSG_SELECT_REMOTE_ROUTE = 10;
-        private static final int MSG_UPDATE_CLIENT_USAGE = 11;
-
         private static final int TIMEOUT_REASON_NOT_AVAILABLE = 1;
         private static final int TIMEOUT_REASON_CONNECTION_LOST = 2;
         private static final int TIMEOUT_REASON_WAITING_FOR_CONNECTING = 3;
@@ -1006,17 +807,11 @@
         private final MediaRouterService mService;
         private final UserRecord mUserRecord;
         private final RemoteDisplayProviderWatcher mWatcher;
-        private final MediaRoute2ProviderWatcher mMediaWatcher;
-
         private final ArrayList<ProviderRecord> mProviderRecords =
                 new ArrayList<ProviderRecord>();
         private final ArrayList<IMediaRouterClient> mTempClients =
                 new ArrayList<IMediaRouterClient>();
 
-        private final ArrayList<MediaRoute2ProviderProxy> mMediaProviders =
-                new ArrayList<>();
-        private final ArrayList<IMediaRouter2ManagerClient> mTempManagers = new ArrayList<>();
-
         private boolean mRunning;
         private int mDiscoveryMode = RemoteDisplayState.DISCOVERY_MODE_NONE;
         private RouteRecord mSelectedRouteRecord;
@@ -1031,8 +826,6 @@
             mUserRecord = userRecord;
             mWatcher = new RemoteDisplayProviderWatcher(service.mContext, this,
                     this, mUserRecord.mUserId);
-            mMediaWatcher = new MediaRoute2ProviderWatcher(service.mContext, this,
-                    this, mUserRecord.mUserId);
         }
 
         @Override
@@ -1074,15 +867,6 @@
                     connectionTimedOut();
                     break;
                 }
-                case MSG_SELECT_REMOTE_ROUTE: {
-                    Pair<Integer, String> obj = (Pair<Integer, String>) msg.obj;
-                    selectRemoteRoute(obj.first, obj.second);
-                    break;
-                }
-                case MSG_UPDATE_CLIENT_USAGE: {
-                    updateClientUsage((ClientRecord) msg.obj);
-                    break;
-                }
             }
         }
 
@@ -1114,7 +898,6 @@
             if (!mRunning) {
                 mRunning = true;
                 mWatcher.start(); // also starts all providers
-                mMediaWatcher.start();
             }
         }
 
@@ -1123,7 +906,6 @@
                 mRunning = false;
                 unselectSelectedRoute();
                 mWatcher.stop(); // also stops all providers
-                mMediaWatcher.stop();
             }
         }
 
@@ -1255,26 +1037,6 @@
             }
         }
 
-        @Override
-        public void addProvider(MediaRoute2ProviderProxy provider) {
-            provider.setCallback(this);
-            mMediaProviders.add(provider);
-        }
-
-        @Override
-        public void removeProvider(MediaRoute2ProviderProxy provider) {
-            mMediaProviders.remove(provider);
-        }
-
-        @Override
-        public void onProviderStateChanged(MediaRoute2ProviderProxy provider) {
-            updateProvider(provider);
-        }
-
-        private void updateProvider(MediaRoute2ProviderProxy provider) {
-            scheduleUpdateClientState();
-        }
-
         /**
          * This function is called whenever the state of the selected route may have changed.
          * It checks the state and updates timeouts or unselects the route as appropriate.
@@ -1385,17 +1147,6 @@
             unselectSelectedRoute();
         }
 
-        private void selectRemoteRoute(int uid, String routeId) {
-            if (routeId != null) {
-                final int providerCount = mMediaProviders.size();
-
-                //TODO: should find proper provider (currently assumes a single provider)
-                for (int i = 0; i < providerCount; ++i) {
-                    mMediaProviders.get(i).setSelectedRoute(uid, routeId);
-                }
-            }
-        }
-
         private void scheduleUpdateClientState() {
             if (!mClientStateUpdateScheduled) {
                 mClientStateUpdateScheduled = true;
@@ -1413,15 +1164,6 @@
                 mProviderRecords.get(i).appendClientState(routerState);
             }
 
-            //TODO: send provider info
-            int selectedUid = 0;
-            String selectedRouteId = null;
-            final int mediaCount = mMediaProviders.size();
-            for (int i = 0; i < mediaCount; i++) {
-                selectedUid = mMediaProviders.get(i).mSelectedUid;
-                selectedRouteId = mMediaProviders.get(i).mSelectedRouteId;
-            }
-
             try {
                 synchronized (mService.mLock) {
                     // Update the UserRecord.
@@ -1432,11 +1174,6 @@
                     for (int i = 0; i < count; i++) {
                         mTempClients.add(mUserRecord.mClientRecords.get(i).mClient);
                     }
-
-                    final int count2 = mUserRecord.mManagerRecords.size();
-                    for (int i = 0; i < count2; i++) {
-                        mTempManagers.add(mUserRecord.mManagerRecords.get(i).mClient);
-                    }
                 }
 
                 // Notify all clients (outside of the lock).
@@ -1448,39 +1185,9 @@
                         Slog.w(TAG, "Failed to call onStateChanged. Client probably died.");
                     }
                 }
-                //TODO: Call proper callbacks when provider descriptor is implemented.
-                final int count2 = mTempManagers.size();
-                for (int i = 0; i < count2; i++) {
-                    try {
-                        mTempManagers.get(i).onRouteSelected(selectedUid, selectedRouteId);
-                    } catch (RemoteException ex) {
-                        Slog.w(TAG, "Failed to call onStateChanged. Manager probably died.", ex);
-                    }
-                }
             } finally {
                 // Clear the list in preparation for the next time.
                 mTempClients.clear();
-                mTempManagers.clear();
-            }
-        }
-
-        private void updateClientUsage(ClientRecord clientRecord) {
-            List<IMediaRouter2ManagerClient> managers = new ArrayList<>();
-            synchronized (mService.mLock) {
-                final int count = mUserRecord.mManagerRecords.size();
-                for (int i = 0; i < count; i++) {
-                    managers.add(mUserRecord.mManagerRecords.get(i).mClient);
-                }
-            }
-            final int count = managers.size();
-            for (int i = 0; i < count; i++) {
-                try {
-                    managers.get(i).onControlCategoriesChanged(clientRecord.mUid,
-                            clientRecord.mControlCategories);
-                } catch (RemoteException ex) {
-                    Slog.w(TAG, "Failed to call onControlCategoriesChanged. "
-                            + "Manager probably died.", ex);
-                }
             }
         }
 
@@ -1867,5 +1574,4 @@
             }
         }
     }
-
 }
diff --git a/services/core/java/com/android/server/media/MediaSessionServiceImpl.java b/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
index de36dea..a5f2217 100644
--- a/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
@@ -171,7 +171,7 @@
         mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance(mContext);
         mAudioPlayerStateMonitor.registerListener(
                 (config, isRemoved) -> {
-                    if (isRemoved || !config.isActive() || config.getPlayerType()
+                    if (config.getPlayerType()
                             == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
                         return;
                     }
@@ -1037,8 +1037,9 @@
                 //       it's closed.
                 // TODO: Keep controller as well for better readability
                 //       because the GC behavior isn't straightforward.
-                MediaController2 controller = new MediaController2(mContext, sessionToken,
-                        new HandlerExecutor(mHandler), callback);
+                MediaController2 controller = new MediaController2.Builder(mContext, sessionToken)
+                        .setControllerCallback(new HandlerExecutor(mHandler), callback)
+                        .build();
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 7f1b25ca..ee2e4f5 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -455,6 +455,7 @@
     private int mAutoGroupAtCount;
     private boolean mIsTelevision;
     private boolean mIsAutomotive;
+    private boolean mNotificationEffectsEnabledForAutomotive;
 
     private MetricsLogger mMetricsLogger;
     private TriPredicate<String, Integer, String> mAllowedManagedServicePackages;
@@ -1686,6 +1687,8 @@
 
         mIsAutomotive =
                 mPackageManagerClient.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0);
+        mNotificationEffectsEnabledForAutomotive =
+                resources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive);
 
         mPreferencesHelper.lockChannelsForOEM(getContext().getResources().getStringArray(
                 com.android.internal.R.array.config_nonBlockableNotificationPackages));
@@ -5560,6 +5563,9 @@
     @VisibleForTesting
     @GuardedBy("mNotificationLock")
     void buzzBeepBlinkLocked(NotificationRecord record) {
+        if (mIsAutomotive && !mNotificationEffectsEnabledForAutomotive) {
+            return;
+        }
         boolean buzz = false;
         boolean beep = false;
         boolean blink = false;
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index ec53e98..3a84b1e 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -452,10 +452,7 @@
             final OverlayInfo overlayInfo = mSettings.getOverlayInfo(packageName, userId);
             if (mSettings.remove(packageName, userId)) {
                 removeIdmapIfPossible(overlayInfo);
-                if (overlayInfo.isEnabled()) {
-                    // Only trigger updates if the overlay was enabled.
-                    mListener.onOverlaysChanged(overlayInfo.targetPackageName, userId);
-                }
+                mListener.onOverlaysChanged(overlayInfo.targetPackageName, userId);
             }
         } catch (OverlayManagerSettings.BadKeyException e) {
             Slog.e(TAG, "failed to remove overlay", e);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 7f48970..e6313d9 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -813,7 +813,7 @@
 
     @Override
     public void uninstall(VersionedPackage versionedPackage, String callerPackageName, int flags,
-                IntentSender statusReceiver, int userId) throws RemoteException {
+                IntentSender statusReceiver, int userId) {
         final int callingUid = Binder.getCallingUid();
         mPermissionManager.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
         if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) {
@@ -952,6 +952,9 @@
 
         @Override
         public void onUserActionRequired(Intent intent) {
+            if (mTarget == null) {
+                return;
+            }
             final Intent fillIn = new Intent();
             fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, mPackageName);
             fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
@@ -972,6 +975,9 @@
                         SystemMessage.NOTE_PACKAGE_STATE,
                         mNotification);
             }
+            if (mTarget == null) {
+                return;
+            }
             final Intent fillIn = new Intent();
             fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, mPackageName);
             fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c68974b..7b418b5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1990,31 +1990,31 @@
 
             // Work that needs to happen on first install within each user
             if (firstUserIds != null && firstUserIds.length > 0) {
-                synchronized (mPackages) {
-                    for (int userId : firstUserIds) {
-                        // If this app is a browser and it's newly-installed for some
-                        // users, clear any default-browser state in those users. The
-                        // app's nature doesn't depend on the user, so we can just check
-                        // its browser nature in any user and generalize.
-                        if (packageIsBrowser(packageName, userId)) {
-                            // If this browser is restored from user's backup, do not clear
-                            // default-browser state for this user
+                for (int userId : firstUserIds) {
+                    // If this app is a browser and it's newly-installed for some
+                    // users, clear any default-browser state in those users. The
+                    // app's nature doesn't depend on the user, so we can just check
+                    // its browser nature in any user and generalize.
+                    if (packageIsBrowser(packageName, userId)) {
+                        // If this browser is restored from user's backup, do not clear
+                        // default-browser state for this user
+                        synchronized (mPackages) {
                             final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
                             if (pkgSetting.getInstallReason(userId)
                                     != PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
                                 setDefaultBrowserAsyncLPw(null, userId);
                             }
                         }
-
-                        // We may also need to apply pending (restored) runtime permission grants
-                        // within these users.
-                        mPermissionManager.restoreDelayedRuntimePermissions(packageName,
-                                UserHandle.of(userId));
-
-                        // Persistent preferred activity might have came into effect due to this
-                        // install.
-                        updateDefaultHomeLPw(userId);
                     }
+
+                    // We may also need to apply pending (restored) runtime permission grants
+                    // within these users.
+                    mPermissionManager.restoreDelayedRuntimePermissions(packageName,
+                            UserHandle.of(userId));
+
+                    // Persistent preferred activity might have came into effect due to this
+                    // install.
+                    updateDefaultHomeNotLocked(userId);
                 }
             }
 
@@ -5158,7 +5158,7 @@
                             getPackagesUsingSharedLibraryLPr(libInfo, flags, userId),
                             (libInfo.getDependencies() == null
                                     ? null
-                                    : new ArrayList(libInfo.getDependencies())));
+                                    : new ArrayList<>(libInfo.getDependencies())));
 
                     if (result == null) {
                         result = new ArrayList<>();
@@ -6475,8 +6475,8 @@
         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
                 userId);
         // Find any earlier preferred or last chosen entries and nuke them
-        findPreferredActivity(intent, resolvedType,
-                flags, query, 0, false, true, false, userId);
+        findPreferredActivityNotLocked(
+                intent, resolvedType, flags, query, 0, false, true, false, userId);
         // Add the new activity as the last chosen for this filter
         addPreferredActivityInternal(filter, match, null, activity, false, userId,
                 "Setting last chosen");
@@ -6491,8 +6491,8 @@
         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
                 userId);
-        return findPreferredActivity(intent, resolvedType, flags, query, 0,
-                false, false, false, userId);
+        return findPreferredActivityNotLocked(
+                intent, resolvedType, flags, query, 0, false, false, false, userId);
     }
 
     /**
@@ -6605,7 +6605,7 @@
                 }
                 // If we have saved a preference for a preferred activity for
                 // this Intent, use that.
-                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
+                ResolveInfo ri = findPreferredActivityNotLocked(intent, resolvedType,
                         flags, query, r0.priority, true, false, debug, userId);
                 if (ri != null) {
                     return ri;
@@ -6744,9 +6744,14 @@
     }
 
     // TODO: handle preferred activities missing while user has amnesia
-    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
+    /** <b>must not hold {@link #mPackages}</b> */
+    ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
             List<ResolveInfo> query, int priority, boolean always,
             boolean removeMatches, boolean debug, int userId) {
+        if (Thread.holdsLock(mPackages)) {
+            Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
+                    + " is holding mPackages", new Throwable());
+        }
         if (!sUserManager.exists(userId)) return null;
         final int callingUid = Binder.getCallingUid();
         // Do NOT hold the packages lock; this calls up into the settings provider which
@@ -18599,10 +18604,10 @@
         int removedAppId = -1;
 
         // writer
-        synchronized (mPackages) {
-            boolean installedStateChanged = false;
-            if (deletedPs != null) {
-                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
+        boolean installedStateChanged = false;
+        if (deletedPs != null) {
+            if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
+                synchronized (mPackages) {
                     clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
                     clearDefaultBrowserIfNeeded(packageName);
                     mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
@@ -18633,26 +18638,34 @@
                             }
                         }
                     }
-                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
                 }
-                // make sure to preserve per-user disabled state if this removal was just
-                // a downgrade of a system app to the factory package
-                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
-                    if (DEBUG_REMOVE) {
-                        Slog.d(TAG, "Propagating install state across downgrade");
-                    }
-                    for (int userId : allUserHandles) {
-                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
-                        if (DEBUG_REMOVE) {
-                            Slog.d(TAG, "    user " + userId + " => " + installed);
-                        }
-                        if (installed != deletedPs.getInstalled(userId)) {
-                            installedStateChanged = true;
-                        }
-                        deletedPs.setInstalled(installed, userId);
-                    }
+                final SparseBooleanArray changedUsers = new SparseBooleanArray();
+                clearPackagePreferredActivitiesLPw(
+                        deletedPs.name, changedUsers, UserHandle.USER_ALL);
+                if (changedUsers.size() > 0) {
+                    updateDefaultHomeNotLocked(changedUsers);
+                    postPreferredActivityChangedBroadcast(UserHandle.USER_ALL);
                 }
             }
+            // make sure to preserve per-user disabled state if this removal was just
+            // a downgrade of a system app to the factory package
+            if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
+                if (DEBUG_REMOVE) {
+                    Slog.d(TAG, "Propagating install state across downgrade");
+                }
+                for (int userId : allUserHandles) {
+                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
+                    if (DEBUG_REMOVE) {
+                        Slog.d(TAG, "    user " + userId + " => " + installed);
+                    }
+                    if (installed != deletedPs.getInstalled(userId)) {
+                        installedStateChanged = true;
+                    }
+                    deletedPs.setInstalled(installed, userId);
+                }
+            }
+        }
+        synchronized (mPackages) {
             // can downgrade to reader
             if (writeSettings) {
                 // Save settings now
@@ -19138,22 +19151,22 @@
         final UserHandle user = action.user;
         final int flags = action.flags;
         final boolean systemApp = isSystemApp(ps);
-        synchronized (mPackages) {
 
-            if (ps.parentPackageName != null
-                    && (!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
-                if (DEBUG_REMOVE) {
-                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
-                            + ((user == null) ? UserHandle.USER_ALL : user));
-                }
-                final int removedUserId = (user != null) ? user.getIdentifier()
-                        : UserHandle.USER_ALL;
+        if (ps.parentPackageName != null
+                && (!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
+            if (DEBUG_REMOVE) {
+                Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
+                        + ((user == null) ? UserHandle.USER_ALL : user));
+            }
+            final int removedUserId = (user != null) ? user.getIdentifier()
+                    : UserHandle.USER_ALL;
 
-                clearPackageStateForUserLIF(ps, removedUserId, outInfo, flags);
+            clearPackageStateForUserLIF(ps, removedUserId, outInfo, flags);
+            synchronized (mPackages) {
                 markPackageUninstalledForUserLPw(ps, user);
                 scheduleWritePackageRestrictionsLocked(user);
-                return;
             }
+            return;
         }
 
         final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
@@ -19167,6 +19180,7 @@
             // its data. If this is a system app, we only allow this to happen if
             // they have set the special DELETE_SYSTEM_APP which requests different
             // semantics than normal for uninstalling system apps.
+            final boolean clearPackageStateAndReturn;
             synchronized (mPackages) {
                 markPackageUninstalledForUserLPw(ps, user);
                 if (!systemApp) {
@@ -19177,15 +19191,14 @@
                         // we need to do is clear this user's data and save that
                         // it is uninstalled.
                         if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
-                        clearPackageStateForUserLIF(ps, userId, outInfo, flags);
-                        scheduleWritePackageRestrictionsLocked(user);
-                        return;
+                        clearPackageStateAndReturn = true;
                     } else {
                         // We need to set it back to 'installed' so the uninstall
                         // broadcasts will be sent correctly.
                         if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
                         ps.setInstalled(true, userId);
                         mSettings.writeKernelMappingLPr(ps);
+                        clearPackageStateAndReturn = false;
                     }
                 } else {
                     // This is a system app, so we assume that the
@@ -19193,11 +19206,16 @@
                     // we need to do is clear this user's data and save that
                     // it is uninstalled.
                     if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
-                    clearPackageStateForUserLIF(ps, userId, outInfo, flags);
-                    scheduleWritePackageRestrictionsLocked(user);
-                    return;
+                    clearPackageStateAndReturn = true;
                 }
             }
+            if (clearPackageStateAndReturn) {
+                clearPackageStateForUserLIF(ps, userId, outInfo, flags);
+                synchronized (mPackages) {
+                    scheduleWritePackageRestrictionsLocked(user);
+                }
+                return;
+            }
         }
 
         // If we are deleting a composite package for all users, keep track
@@ -19330,10 +19348,17 @@
             destroyAppDataLIF(pkg, nextUserId,
                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
             clearDefaultBrowserIfNeededForUser(ps.name, nextUserId);
-            synchronized (mPackages) {
-                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
+            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
+            final SparseBooleanArray changedUsers = new SparseBooleanArray();
+            clearPackagePreferredActivitiesLPw(ps.name, changedUsers, nextUserId);
+            if (changedUsers.size() > 0) {
+                updateDefaultHomeNotLocked(changedUsers);
+                postPreferredActivityChangedBroadcast(nextUserId);
+                synchronized (mPackages) {
                     scheduleWritePackageRestrictionsLocked(nextUserId);
                 }
+            }
+            synchronized (mPackages) {
                 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
             }
             // Also delete contributed media, when requested
@@ -19796,33 +19821,34 @@
         int callingUid = Binder.getCallingUid();
         mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
+        if (mContext.checkCallingOrSelfPermission(
+                android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
+                != PackageManager.PERMISSION_GRANTED) {
+            if (getUidTargetSdkVersionLockedLPr(callingUid)
+                    < Build.VERSION_CODES.FROYO) {
+                Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
+                        + callingUid);
+                return;
+            }
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+        }
         if (filter.countActions() == 0) {
             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
             return;
         }
-        synchronized (mPackages) {
-            if (mContext.checkCallingOrSelfPermission(
-                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
-                    != PackageManager.PERMISSION_GRANTED) {
-                if (getUidTargetSdkVersionLockedLPr(callingUid)
-                        < Build.VERSION_CODES.FROYO) {
-                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
-                            + callingUid);
-                    return;
-                }
-                mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
-            }
-
-            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
+        if (DEBUG_PREFERRED) {
             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
                     + userId + ":");
             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
+        }
+        if (!updateDefaultHomeNotLocked(userId)) {
+            postPreferredActivityChangedBroadcast(userId);
+        }
+        synchronized (mPackages) {
+            final PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
             scheduleWritePackageRestrictionsLocked(userId);
-            if (!updateDefaultHomeLPw(userId)) {
-                postPreferredActivityChangedBroadcast(userId);
-            }
         }
     }
 
@@ -19963,25 +19989,24 @@
                     && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
                 return;
             }
-            int user = UserHandle.getCallingUserId();
-            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
-                scheduleWritePackageRestrictionsLocked(user);
+        }
+        int callingUserId = UserHandle.getCallingUserId();
+        final SparseBooleanArray changedUsers = new SparseBooleanArray();
+        clearPackagePreferredActivitiesLPw(packageName, changedUsers, callingUserId);
+        if (changedUsers.size() > 0) {
+            updateDefaultHomeNotLocked(changedUsers);
+            postPreferredActivityChangedBroadcast(callingUserId);
+            synchronized (mPackages) {
+                scheduleWritePackageRestrictionsLocked(callingUserId);
             }
         }
     }
 
     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
     @GuardedBy("mPackages")
-    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
-        return clearPackagePreferredActivitiesLPw(packageName, false, userId);
-    }
-
-    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
-    @GuardedBy("mPackages")
-    private boolean clearPackagePreferredActivitiesLPw(String packageName,
-            boolean skipUpdateDefaultHome, int userId) {
+    private void clearPackagePreferredActivitiesLPw(String packageName,
+            @NonNull SparseBooleanArray outUserChanged, int userId) {
         ArrayList<PreferredActivity> removed = null;
-        boolean changed = false;
         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
@@ -20007,16 +20032,9 @@
                     PreferredActivity pa = removed.get(j);
                     pir.removeFilter(pa);
                 }
-                changed = true;
-                if (!skipUpdateDefaultHome) {
-                    updateDefaultHomeLPw(thisUserId);
-                }
+                outUserChanged.setValueAt(thisUserId, true);
             }
         }
-        if (changed) {
-            postPreferredActivityChangedBroadcast(userId);
-        }
-        return changed;
     }
 
     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
@@ -20069,21 +20087,27 @@
         final long identity = Binder.clearCallingIdentity();
         // writer
         try {
+            final SparseBooleanArray changedUsers = new SparseBooleanArray();
+            clearPackagePreferredActivitiesLPw(null, changedUsers, userId);
+            if (changedUsers.size() > 0) {
+                postPreferredActivityChangedBroadcast(userId);
+            }
             synchronized (mPackages) {
-                clearPackagePreferredActivitiesLPw(null, true, userId);
                 mSettings.applyDefaultPreferredAppsLPw(userId);
-                updateDefaultHomeLPw(userId);
-                // TODO: We have to reset the default SMS and Phone. This requires
-                // significant refactoring to keep all default apps in the package
-                // manager (cleaner but more work) or have the services provide
-                // callbacks to the package manager to request a default app reset.
-                setDefaultBrowserPackageName(null, userId);
                 clearIntentFilterVerificationsLPw(userId);
                 primeDomainVerificationsLPw(userId);
                 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
+            }
+            updateDefaultHomeNotLocked(userId);
+            // TODO: We have to reset the default SMS and Phone. This requires
+            // significant refactoring to keep all default apps in the package
+            // manager (cleaner but more work) or have the services provide
+            // callbacks to the package manager to request a default app reset.
+            setDefaultBrowserPackageName(null, userId);
+            resetNetworkPolicies(userId);
+            synchronized (mPackages) {
                 scheduleWritePackageRestrictionsLocked(userId);
             }
-            resetNetworkPolicies(userId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -20133,15 +20157,17 @@
             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
             return;
         }
-        synchronized (mPackages) {
-            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
-                    ":");
+        if (DEBUG_PREFERRED) {
+            Slog.i(TAG, "Adding persistent preferred activity " + activity
+                    + " for user " + userId + ":");
             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
+        }
+        updateDefaultHomeNotLocked(userId);
+        postPreferredActivityChangedBroadcast(userId);
+        synchronized (mPackages) {
             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
                     new PersistentPreferredActivity(filter, activity));
             scheduleWritePackageRestrictionsLocked(userId);
-            postPreferredActivityChangedBroadcast(userId);
-            updateDefaultHomeLPw(userId);
         }
     }
 
@@ -20181,11 +20207,12 @@
                     changed = true;
                 }
             }
-
-            if (changed) {
+        }
+        if (changed) {
+            updateDefaultHomeNotLocked(userId);
+            postPreferredActivityChangedBroadcast(userId);
+            synchronized (mPackages) {
                 scheduleWritePackageRestrictionsLocked(userId);
-                postPreferredActivityChangedBroadcast(userId);
-                updateDefaultHomeLPw(userId);
             }
         }
     }
@@ -20273,8 +20300,8 @@
                     (readParser, readUserId) -> {
                         synchronized (mPackages) {
                             mSettings.readPreferredActivitiesLPw(readParser, readUserId);
-                            updateDefaultHomeLPw(readUserId);
                         }
+                        updateDefaultHomeNotLocked(readUserId);
                     });
         } catch (Exception e) {
             if (DEBUG_BACKUP) {
@@ -20601,29 +20628,55 @@
         return null;
     }
 
+    /** <b>must not hold {@link #mPackages}</b> */
+    private void updateDefaultHomeNotLocked(SparseBooleanArray userIds) {
+        if (Thread.holdsLock(mPackages)) {
+            Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
+                    + " is holding mPackages", new Throwable());
+        }
+        for (int i = userIds.size() - 1; i >= 0; --i) {
+            final int userId = userIds.keyAt(i);
+            updateDefaultHomeNotLocked(userId);
+        }
+    }
+
     /**
+     * <b>must not hold {@link #mPackages}</b>
+     *
      * @return Whether the ACTION_PREFERRED_ACTIVITY_CHANGED broadcast has been scheduled.
      */
-    private boolean updateDefaultHomeLPw(int userId) {
-        Intent intent = getHomeIntent();
-        List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
+    private boolean updateDefaultHomeNotLocked(int userId) {
+        if (Thread.holdsLock(mPackages)) {
+            Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
+                    + " is holding mPackages", new Throwable());
+        }
+        final Intent intent = getHomeIntent();
+        final List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
                 PackageManager.GET_META_DATA, userId);
-        ResolveInfo preferredResolveInfo = findPreferredActivity(intent, null, 0, resolveInfos,
-                0, true, false, false, userId);
-        String packageName = preferredResolveInfo != null
+        final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(
+                intent, null, 0, resolveInfos, 0, true, false, false, userId);
+        final String packageName = preferredResolveInfo != null
                 && preferredResolveInfo.activityInfo != null
                 ? preferredResolveInfo.activityInfo.packageName : null;
-        String currentPackageName = mDefaultHomeProvider.getDefaultHome(userId);
+        final PackageManagerInternal.DefaultHomeProvider provider;
+        synchronized (mPackages) {
+            provider = mDefaultHomeProvider;
+        }
+        if (provider == null) {
+            Slog.e(TAG, "Default home provider has not been set");
+            return false;
+        }
+        final String currentPackageName = provider.getDefaultHome(userId);
         if (TextUtils.equals(currentPackageName, packageName)) {
             return false;
         }
-        String[] callingPackages = getPackagesForUid(Binder.getCallingUid());
+        final String[] callingPackages = getPackagesForUid(Binder.getCallingUid());
         if (callingPackages != null && ArrayUtils.contains(callingPackages,
                 mRequiredPermissionControllerPackage)) {
             // PermissionController manages default home directly.
             return false;
         }
-        mDefaultHomeProvider.setDefaultHomeAsync(packageName, userId, (successful) -> {
+        provider.setDefaultHomeAsync(packageName, userId, (successful) -> {
             if (successful) {
                 postPreferredActivityChangedBroadcast(userId);
             }
@@ -23720,9 +23773,7 @@
             }
             return ((appInfo.isSystemApp() ? IPackageManagerNative.LOCATION_SYSTEM : 0)
                     | (appInfo.isVendor() ? IPackageManagerNative.LOCATION_VENDOR : 0)
-                    | (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0)
-                    | (appInfo.isProductServices()
-                            ? IPackageManagerNative.LOCATION_PRODUCT_SERVICES : 0));
+                    | (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0));
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 72d5438..803ab2d 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -261,13 +261,13 @@
             if (storageManager.supportsCheckpoint()) {
                 storageManager.startCheckpoint(1 /* numRetries */);
             }
-        } catch (RemoteException e) {
+        } catch (Exception e) { // TODO(b/130190815) make a RemoteException again
             // While StorageManager lives in the same process, the native implementation
             // it calls through lives in 'vold'; so, this call can fail if 'vold' isn't
             // reachable.
             // Since we can live without filesystem checkpointing, just warn in this case
             // and continue.
-            Slog.w(TAG, "Could not start filesystem checkpoint.");
+            Slog.w(TAG, "Could not start filesystem checkpoint:", e);
         }
 
         session.setStagedSessionReady();
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 96924c04..10ed88f 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -92,6 +92,7 @@
 import android.os.storage.DiskInfo;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
+import android.provider.Settings;
 import android.stats.storage.StorageEnums;
 import android.telephony.ModemActivityInfo;
 import android.telephony.TelephonyManager;
@@ -2057,6 +2058,40 @@
         }
     }
 
+    private void pullFaceSettings(int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
+        long callingToken = Binder.clearCallingIdentity();
+        try {
+            List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
+            int numUsers = users.size();
+            for (int userNum = 0; userNum < numUsers; userNum++) {
+                int userId = users.get(userNum).getUserHandle().getIdentifier();
+
+                StatsLogEventWrapper e =
+                        new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
+                e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                        Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED, 1,
+                        userId) != 0);
+                e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                        Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD,
+                        0, userId) != 0);
+                e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                        Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, 1,
+                        userId) != 0);
+                e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                        Settings.Secure.FACE_UNLOCK_APP_ENABLED, 1,
+                        userId) != 0);
+                e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                        Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, 0,
+                        userId) != 0);
+
+                pulledData.add(e);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(callingToken);
+        }
+    }
+
     /**
      * Pulls various data.
      */
@@ -2261,6 +2296,10 @@
                 pullAppsOnExternalStorageInfo(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
+            case StatsLog.FACE_SETTINGS: {
+                pullFaceSettings(tagId, elapsedNanos, wallClockNanos, ret);
+                break;
+            }
             default:
                 Slog.w(TAG, "No such tagId data as " + tagId);
                 return null;
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index d916e39..10afbef 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -26,20 +26,6 @@
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_REPORTED_DRAWN_MS;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_STARTING_WINDOW_DELAY_MS;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_FLAGS;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_FULLSCREEN;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_VISIBLE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_LAUNCH_MODE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_PROCESS_NAME;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_REAL_ACTIVITY;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_PACKAGE_NAME;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW;
@@ -62,12 +48,7 @@
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_PROC_STATE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_PACKAGE_NAME;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_SHORT_COMPONENT_NAME;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID_PROC_STATE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_WHITELIST_TAG;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_FILTER;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_REASON;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_COLD_LAUNCH;
@@ -671,6 +652,11 @@
             final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(index);
             final int type = getTransitionType(info);
             if (type == INVALID_TRANSITION_TYPE) {
+                if (DEBUG_METRICS) {
+                    Slog.i(TAG, "invalid transition type"
+                            + " processRunning=" + info.currentTransitionProcessRunning
+                            + " startResult=" + info.startResult);
+                }
                 return;
             }
 
@@ -921,7 +907,10 @@
             } else if (info.startResult == START_TASK_TO_FRONT) {
                 return TYPE_TRANSITION_HOT_LAUNCH;
             }
-        } else if (info.startResult == START_SUCCESS) {
+        } else if (info.startResult == START_SUCCESS
+                || (info.startResult == START_TASK_TO_FRONT)) {
+            // TaskRecord may still exist when cold launching an activity and the start
+            // result will be set to START_TASK_TO_FRONT. Treat this as a COLD launch.
             return TYPE_TRANSITION_COLD_LAUNCH;
         }
         return INVALID_TRANSITION_TYPE;
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 419f5be..76b0351 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -2753,7 +2753,7 @@
             // happens to be sitting towards the end.
             if (next.attachedToProcess()) {
                 next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
-                        true /* updateLru */, true /* activityChange */, false /* updateOomAdj */);
+                        true /* activityChange */, false /* updateOomAdj */);
             }
             if (lastResumed != null) {
                 lastResumed.setWillCloseOrEnterPip(true);
@@ -2903,7 +2903,7 @@
             next.setState(RESUMED, "resumeTopActivityInnerLocked");
 
             next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
-                    true /* updateLru */, true /* activityChange */, true /* updateOomAdj */);
+                    true /* activityChange */, true /* updateOomAdj */);
             updateLRUListLocked(next);
 
             // Have the window manager re-evaluate the orientation of
@@ -4600,7 +4600,8 @@
                     // Update any services we are bound to that might care about whether
                     // their client may have activities.
                     // No longer have activities, so update LRU list and oom adj.
-                    r.app.updateProcessInfo(true, true, false, true);
+                    r.app.updateProcessInfo(true /* updateServiceConnectionActivities */,
+                            false /* activityChange */, true /* updateOomAdj */);
                 }
             }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index a9d76a6..5790a1b 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -769,14 +769,12 @@
                                 + " old=" + r.app + " new=" + proc);
             }
 
-            proc.clearWaitingToKill();
             r.launchCount++;
             r.lastLaunchTime = SystemClock.uptimeMillis();
 
             if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);
 
             proc.addActivityIfNeeded(r);
-            proc.updateProcessInfo(false, true, true, true);
 
             final LockTaskController lockTaskController = mService.getLockTaskController();
             if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
@@ -814,7 +812,6 @@
                 r.forceNewConfig = false;
                 mService.getAppWarningsLocked().onStartActivity(r);
                 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
-                ProfilerInfo profilerInfo = proc.onStartActivity(mService.mTopProcessState);
 
                 // Because we could be starting an Activity in the system process this may not go
                 // across a Binder interface which would create a new Configuration. Consequently
@@ -840,7 +837,7 @@
                         mergedConfiguration.getOverrideConfiguration(), r.compat,
                         r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                         r.icicle, r.persistentState, results, newIntents,
-                        dc.isNextTransitionForward(), profilerInfo));
+                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded()));
 
                 // Set desired final state.
                 final ActivityLifecycleItem lifecycleItem;
@@ -910,6 +907,9 @@
                     "Moving to PAUSED: " + r + " (starting in paused state)");
             r.setState(PAUSED, "realStartActivityLocked");
         }
+        // Perform OOM scoring after the activity state is set, so the process can be updated with
+        // the latest state.
+        proc.onStartActivity(mService.mTopProcessState, r.info);
 
         // Launch the new version setup screen if needed.  We do this -after-
         // launching the initial activity (that is, home), so that it can have
@@ -960,13 +960,6 @@
         boolean knownToBeDead = false;
         if (wpc != null && wpc.hasThread()) {
             try {
-                if ((r.info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0
-                        || !"android".equals(r.info.packageName)) {
-                    // Don't add this if it is a platform component that is marked to run in
-                    // multiple processes, because this is actually part of the framework so doesn't
-                    // make sense to track as a separate apk in the process.
-                    wpc.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode);
-                }
                 realStartActivityLocked(r, wpc, andResume, checkConfig);
                 return;
             } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 473a875..8957444 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -937,7 +937,7 @@
                 || callingUid == Process.NFC_UID) {
             return false;
         }
-        // don't abort if the callingUid is in the foreground or is a persistent system process
+        // don't abort if the callingUid has a visible window or is a persistent system process
         final int callingUidProcState = mService.getUidState(callingUid);
         final boolean callingUidHasAnyVisibleWindow =
                 mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid);
@@ -946,7 +946,7 @@
                 || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP;
         final boolean isCallingUidPersistentSystemProcess = (callingUid == Process.SYSTEM_UID)
                 || callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
-        if (isCallingUidForeground || isCallingUidPersistentSystemProcess) {
+        if (callingUidHasAnyVisibleWindow || isCallingUidPersistentSystemProcess) {
             return false;
         }
         // take realCallingUid into consideration
@@ -965,8 +965,8 @@
                 : (realCallingUid == Process.SYSTEM_UID)
                         || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
         if (realCallingUid != callingUid) {
-            // don't abort if the realCallingUid is in the foreground and callingUid isn't
-            if (isRealCallingUidForeground) {
+            // don't abort if the realCallingUid has a visible window
+            if (realCallingUidHasAnyVisibleWindow) {
                 return false;
             }
             // if the realCallingUid is a persistent system process, abort if the IntentSender
@@ -988,10 +988,6 @@
             callerApp = mService.getProcessController(realCallingPid, realCallingUid);
         }
         if (callerApp != null) {
-            // don't abort if the callerApp has any visible activity
-            if (callerApp.hasForegroundActivities()) {
-                return false;
-            }
             // don't abort if the callerApp is instrumenting with background activity starts privs
             if (callerApp.isInstrumentingWithBackgroundActivityStartPrivileges()) {
                 return false;
@@ -1061,8 +1057,7 @@
         final ArraySet<Integer> boundClientUids = callerApp.getBoundClientUids();
         for (int i = boundClientUids.size() - 1; i >= 0; --i) {
             final int uid = boundClientUids.valueAt(i);
-            if (mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid)
-                    || mService.getUidState(uid) == ActivityManager.PROCESS_STATE_TOP) {
+            if (mService.isUidForeground(uid)) {
                 return true;
             }
         }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index 7d25466..48aee20 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -503,7 +503,7 @@
     public abstract ActivityManager.TaskSnapshot getTaskSnapshot(int taskId,
             boolean reducedResolution);
 
-    /** Returns true if uid has a visible window or its process is in a top state. */
+    /** Returns true if uid is considered foreground for activity start purposes. */
     public abstract boolean isUidForeground(int uid);
 
     /**
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index b424904..76774d7 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -5872,8 +5872,8 @@
     }
 
     boolean isUidForeground(int uid) {
-        return (getUidState(uid) == ActivityManager.PROCESS_STATE_TOP)
-                || mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid);
+        // A uid is considered to be foreground if it has a visible non-toast window.
+        return mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid);
     }
 
     boolean isDeviceOwner(int uid) {
@@ -6480,9 +6480,10 @@
          */
         @Override
         public void onImeWindowSetOnDisplay(final int pid, final int displayId) {
-            // Update display configuration for IME process only when Single-client IME window
-            // moving to another display.
-            if (!InputMethodSystemProperty.MULTI_CLIENT_IME_ENABLED) return;
+            // Don't update process-level configuration for Multi-Client IME process since other
+            // IMEs on other displays will also receive this configuration change due to IME
+            // services use the same application config/context.
+            if (InputMethodSystemProperty.MULTI_CLIENT_IME_ENABLED) return;
 
             if (pid == MY_PID || pid < 0) {
                 if (DEBUG_CONFIGURATION) {
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index e967a92f..78f1e69 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -106,6 +106,10 @@
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mService.mGlobalLock) {
+                if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, -1, -1,
+                        "Move to front")) {
+                    return;
+                }
                 WindowProcessController callerApp = null;
                 if (appThread != null) {
                     callerApp = mService.getProcessController(appThread);
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 1ca31f1..f9fd541 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -314,9 +314,10 @@
      * Returns true if the callingUid has any non-toast window currently visible to the user.
      */
     boolean isAnyNonToastWindowVisibleForUid(int callingUid) {
-        return forAllWindows(w -> {
-            return w.getOwningUid() == callingUid && w.isVisible() && w.mAttrs.type != TYPE_TOAST;
-        }, true /* traverseTopToBottom */);
+        return forAllWindows(w ->
+                        w.getOwningUid() == callingUid && w.mAttrs.type != TYPE_TOAST
+                        && w.isVisibleNow(),
+                true /* traverseTopToBottom */);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index f31416c..432ca33 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -292,9 +292,9 @@
         }
         final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE;
         return new TaskSnapshot(appWindowToken.mActivityComponent, buffer,
-                appWindowToken.getConfiguration().orientation, getInsets(mainWindow),
-                isLowRamDevice /* reduced */, scaleFraction /* scale */, true /* isRealSnapshot */,
-                task.getWindowingMode(), getSystemUiVisibility(task),
+                screenshotBuffer.getColorSpace(), appWindowToken.getConfiguration().orientation,
+                getInsets(mainWindow), isLowRamDevice /* reduced */, scaleFraction /* scale */,
+                true /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task),
                 !appWindowToken.fillsParent() || isWindowTranslucent);
     }
 
@@ -383,10 +383,10 @@
         // Note, the app theme snapshot is never translucent because we enforce a non-translucent
         // color above
         return new TaskSnapshot(topChild.mActivityComponent, hwBitmap.createGraphicBufferHandle(),
-                topChild.getConfiguration().orientation, mainWindow.getStableInsets(),
-                ActivityManager.isLowRamDeviceStatic() /* reduced */, 1.0f /* scale */,
-                false /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task),
-                false);
+                hwBitmap.getColorSpace(), topChild.getConfiguration().orientation,
+                mainWindow.getStableInsets(), ActivityManager.isLowRamDeviceStatic() /* reduced */,
+                1.0f /* scale */, false /* isRealSnapshot */, task.getWindowingMode(),
+                getSystemUiVisibility(task), false);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
index d30843b..f7b8945 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
@@ -89,7 +89,8 @@
             }
             ComponentName topActivityComponent = ComponentName.unflattenFromString(
                     proto.topActivityComponent);
-            return new TaskSnapshot(topActivityComponent, buffer, proto.orientation,
+            return new TaskSnapshot(topActivityComponent, buffer, bitmap.getColorSpace(),
+                    proto.orientation,
                     new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom),
                     reducedResolution, reducedResolution ? mPersister.getReducedScale() : 1f,
                     proto.isRealSnapshot, proto.windowingMode, proto.systemUiVisibility,
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ce496f4..8ed2a15 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2107,7 +2107,7 @@
             if (shouldRelayout) {
                 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_1");
 
-                result = win.relayoutVisibleWindow(result, attrChanges, oldVisibility);
+                result = win.relayoutVisibleWindow(result, attrChanges);
 
                 try {
                     result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 33561d3a..4ca35f7 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -44,6 +44,7 @@
 import android.app.ProfilerInfo;
 import android.app.servertransaction.ConfigurationChangeItem;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.res.Configuration;
 import android.os.Message;
@@ -771,13 +772,12 @@
                 WindowProcessListener::clearProfilerIfNeeded, mListener));
     }
 
-    void updateProcessInfo(boolean updateServiceConnectionActivities, boolean updateLru,
-            boolean activityChange, boolean updateOomAdj) {
+    void updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange,
+            boolean updateOomAdj) {
         if (mListener == null) return;
         // Posting on handler so WM lock isn't held when we call into AM.
         final Message m = PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo,
-                mListener, updateServiceConnectionActivities, updateLru, activityChange,
-                updateOomAdj);
+                mListener, updateServiceConnectionActivities, activityChange, updateOomAdj);
         mAtm.mH.sendMessage(m);
     }
 
@@ -801,53 +801,44 @@
         return mListener == null ? false : mListener.isRemoved();
     }
 
-    void clearWaitingToKill() {
-        if (mListener == null) return;
-        // Posting on handler so WM lock isn't held when we call into AM.
-        final Message m = PooledLambda.obtainMessage(
-                WindowProcessListener::clearWaitingToKill, mListener);
-        mAtm.mH.sendMessage(m);
+    private boolean shouldSetProfileProc() {
+        return mAtm.mProfileApp != null && mAtm.mProfileApp.equals(mName)
+                && (mAtm.mProfileProc == null || mAtm.mProfileProc == this);
     }
 
-    void addPackage(String pkg, long versionCode) {
-        if (mListener == null) return;
-        // Posting on handler so WM lock isn't held when we call into AM.
-        final Message m = PooledLambda.obtainMessage(
-                WindowProcessListener::addPackage, mListener, pkg, versionCode);
-        mAtm.mH.sendMessage(m);
-    }
-
-    ProfilerInfo onStartActivity(int topProcessState) {
-        ProfilerInfo profilerInfo = null;
-        boolean setProfileProc = false;
-        if (mAtm.mProfileApp != null
-                && mAtm.mProfileApp.equals(mName)) {
-            if (mAtm.mProfileProc == null || mAtm.mProfileProc == this) {
-                setProfileProc = true;
-                final ProfilerInfo profilerInfoSvc = mAtm.mProfilerInfo;
-                if (profilerInfoSvc != null && profilerInfoSvc.profileFile != null) {
-                    if (profilerInfoSvc.profileFd != null) {
-                        try {
-                            profilerInfoSvc.profileFd = profilerInfoSvc.profileFd.dup();
-                        } catch (IOException e) {
-                            profilerInfoSvc.closeFd();
-                        }
-                    }
-
-                    profilerInfo = new ProfilerInfo(profilerInfoSvc);
-                }
+    ProfilerInfo createProfilerInfoIfNeeded() {
+        final ProfilerInfo currentProfilerInfo = mAtm.mProfilerInfo;
+        if (currentProfilerInfo == null || currentProfilerInfo.profileFile == null
+                || !shouldSetProfileProc()) {
+            return null;
+        }
+        if (currentProfilerInfo.profileFd != null) {
+            try {
+                currentProfilerInfo.profileFd = currentProfilerInfo.profileFd.dup();
+            } catch (IOException e) {
+                currentProfilerInfo.closeFd();
             }
         }
+        return new ProfilerInfo(currentProfilerInfo);
+    }
 
-
-        if (mListener != null) {
-            // Posting on handler so WM lock isn't held when we call into AM.
-            final Message m = PooledLambda.obtainMessage(WindowProcessListener::onStartActivity,
-                    mListener, topProcessState, setProfileProc);
-            mAtm.mH.sendMessage(m);
+    void onStartActivity(int topProcessState, ActivityInfo info) {
+        if (mListener == null) return;
+        String packageName = null;
+        if ((info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0
+                || !"android".equals(info.packageName)) {
+            // Don't add this if it is a platform component that is marked to run in multiple
+            // processes, because this is actually part of the framework so doesn't make sense
+            // to track as a separate apk in the process.
+            packageName = info.packageName;
         }
-
-        return profilerInfo;
+        // Posting the message at the front of queue so WM lock isn't held when we call into AM,
+        // and the process state of starting activity can be updated quicker which will give it a
+        // higher scheduling group.
+        final Message m = PooledLambda.obtainMessage(WindowProcessListener::onStartActivity,
+                mListener, topProcessState, shouldSetProfileProc(), packageName,
+                info.applicationInfo.longVersionCode);
+        mAtm.mH.sendMessageAtFrontOfQueue(m);
     }
 
     public void appDied() {
diff --git a/services/core/java/com/android/server/wm/WindowProcessListener.java b/services/core/java/com/android/server/wm/WindowProcessListener.java
index d732e4e..527d54a 100644
--- a/services/core/java/com/android/server/wm/WindowProcessListener.java
+++ b/services/core/java/com/android/server/wm/WindowProcessListener.java
@@ -41,8 +41,8 @@
     void setPendingUiCleanAndForceProcessStateUpTo(int newState);
 
     /** Update the process information. */
-    void updateProcessInfo(boolean updateServiceConnectionActivities, boolean updateLru,
-            boolean activityChange, boolean updateOomAdj);
+    void updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange,
+            boolean updateOomAdj);
 
     /**
      * Returns true if the process is removed and we should completely clean up the related records
@@ -53,14 +53,9 @@
     /** Returns the total time (in milliseconds) spent executing in both user and system code. */
     long getCpuTime();
 
-    /** Clears the waiting to kill reason for this process. */
-    void clearWaitingToKill();
-
-    /** Adds the package to the process. */
-    void addPackage(String pkg, long versionCode);
-
     /** Called when we are in the process on starting an activity. */
-    void onStartActivity(int topProcessState, boolean setProfileProc);
+    void onStartActivity(int topProcessState, boolean setProfileProc, String packageName,
+            long versionCode);
 
     /** App died :(...oh well */
     void appDied();
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 08ade37..d990e6c 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -4446,7 +4446,7 @@
         return !mLastSurfaceInsets.equals(mAttrs.surfaceInsets);
     }
 
-    int relayoutVisibleWindow(int result, int attrChanges, int oldVisibility) {
+    int relayoutVisibleWindow(int result, int attrChanges) {
         final boolean wasVisible = isVisibleLw();
 
         result |= (!wasVisible || !isDrawnLw()) ? RELAYOUT_RES_FIRST_TIME : 0;
@@ -4466,7 +4466,7 @@
             mDestroying = false;
             mWmService.mDestroySurface.remove(this);
         }
-        if (oldVisibility == View.GONE) {
+        if (!wasVisible) {
             mWinAnimator.mEnterAnimationPending = true;
         }
 
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 73e9bf0..b470ec7 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -1693,7 +1693,7 @@
     // 1.1@IGnss can be paired {1.0, 1.1}@IGnssMeasurement
     // 1.0@IGnss is paired with 1.0@IGnssMeasurement
     gnssMeasurementIface = nullptr;
-    if (gnssHal_V2_0 != nullptr && gnssMeasurementIface == nullptr) {
+    if (gnssHal_V2_0 != nullptr) {
         auto gnssMeasurement = gnssHal_V2_0->getExtensionGnssMeasurement_2_0();
         if (!gnssMeasurement.isOk()) {
             ALOGD("Unable to get a handle to GnssMeasurement_V2_0");
@@ -1730,6 +1730,10 @@
         }
     }
 
+    // Allow all causal combinations between IGnss.hal and IGnssDebug.hal. That means,
+    // 2.0@IGnss can be paired with {1.0, 2.0}@IGnssDebug
+    // 1.0@IGnss is paired with 1.0@IGnssDebug
+    gnssDebugIface = nullptr;
     if (gnssHal_V2_0 != nullptr) {
         auto gnssDebug = gnssHal_V2_0->getExtensionGnssDebug_2_0();
         if (!gnssDebug.isOk()) {
@@ -1738,7 +1742,8 @@
             gnssDebugIface_V2_0 = gnssDebug;
             gnssDebugIface = gnssDebugIface_V2_0;
         }
-    } else {
+    }
+    if (gnssDebugIface == nullptr) {
         auto gnssDebug = gnssHal->getExtensionGnssDebug();
         if (!gnssDebug.isOk()) {
             ALOGD("Unable to get a handle to GnssDebug");
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/AbUpdateInstaller.java b/services/devicepolicy/java/com/android/server/devicepolicy/AbUpdateInstaller.java
index d5cfab9..5acf83a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/AbUpdateInstaller.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/AbUpdateInstaller.java
@@ -194,8 +194,17 @@
         }
 
         UpdateEngine updateEngine = buildBoundUpdateEngine();
-        updateEngine.applyPayload(
-                updatePath, mOffsetForUpdate, mSizeForUpdate, headerKeyValuePairs);
+        try {
+            updateEngine.applyPayload(
+                    updatePath, mOffsetForUpdate, mSizeForUpdate, headerKeyValuePairs);
+        } catch (Exception e) {
+            // Prevent an automatic restart when an update is already being processed
+            // (http://b/124106342).
+            Log.w(UpdateInstaller.TAG, "Failed to install update from file.", e);
+            notifyCallbackOnError(
+                    InstallSystemUpdateCallback.UPDATE_ERROR_UNKNOWN,
+                    "Failed to install update from file.");
+        }
     }
 
     private boolean updateStateForPayload() throws IOException {
diff --git a/services/tests/servicestests/src/com/android/server/ThreadPriorityBoosterTest.java b/services/tests/servicestests/src/com/android/server/ThreadPriorityBoosterTest.java
new file mode 100644
index 0000000..b4e9ff7
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/ThreadPriorityBoosterTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static android.os.Process.getThreadPriority;
+import static android.os.Process.myTid;
+import static android.os.Process.setThreadPriority;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.Process;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Tests for {@link ThreadPriorityBooster}.
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:ThreadPriorityBoosterTest
+ */
+@SmallTest
+@Presubmit
+public class ThreadPriorityBoosterTest {
+    private static final int PRIORITY_BOOST = Process.THREAD_PRIORITY_FOREGROUND;
+    private static final int PRIORITY_BOOST_MORE = Process.THREAD_PRIORITY_DISPLAY;
+
+    private final ThreadPriorityBooster mBooster = new ThreadPriorityBooster(PRIORITY_BOOST,
+            0 /* lockGuardIndex */);
+
+    @Test
+    public void testThreadPriorityBooster() {
+        joinNewThread(() -> {
+            final int origPriority = Process.THREAD_PRIORITY_DEFAULT;
+            setThreadPriority(origPriority);
+
+            boost(() -> {
+                assertThreadPriority(PRIORITY_BOOST);
+                boost(() -> {
+                    // Inside the boost region, the priority should also apply to current thread.
+                    mBooster.setBoostToPriority(PRIORITY_BOOST_MORE);
+                    assertThreadPriority(PRIORITY_BOOST_MORE);
+                });
+                // It is still in the boost region so the set priority should be kept.
+                assertThreadPriority(PRIORITY_BOOST_MORE);
+
+                joinNewThread(() -> boost(() -> assertThreadPriority(PRIORITY_BOOST_MORE)));
+            });
+            // The priority should be restored after leaving the boost region.
+            assertThreadPriority(origPriority);
+
+            // It doesn't apply to current thread because outside of the boost region, but the boost
+            // in other threads will use the set priority.
+            mBooster.setBoostToPriority(PRIORITY_BOOST);
+            joinNewThread(() -> boost(() -> assertThreadPriority(PRIORITY_BOOST)));
+
+            assertThreadPriority(origPriority);
+        });
+    }
+
+    private static void assertThreadPriority(int expectedPriority) {
+        assertEquals(expectedPriority, getThreadPriority(myTid()));
+    }
+
+    private static void joinNewThread(Runnable action) {
+        final Thread thread = new Thread(action);
+        thread.start();
+        try {
+            thread.join();
+        } catch (InterruptedException ignored) {
+        }
+    }
+
+    private void boost(Runnable action) {
+        try {
+            mBooster.boost();
+            action.run();
+        } finally {
+            mBooster.reset();
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 4e21fd0c..3df6976 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -322,7 +322,8 @@
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.processName = "com.android.test.app";
         appInfo.uid = 10000;
-        final IsolatedUidRange range = allocator.getOrCreateIsolatedUidRangeLocked(appInfo);
+        final IsolatedUidRange range = allocator.getOrCreateIsolatedUidRangeLocked(
+                appInfo.processName, appInfo.uid);
         validateAppZygoteIsolatedUidRange(range);
         verifyIsolatedUidAllocator(range);
 
@@ -330,7 +331,8 @@
         ApplicationInfo appInfo2 = new ApplicationInfo();
         appInfo2.processName = "com.android.test.app2";
         appInfo2.uid = 10001;
-        IsolatedUidRange range2 = allocator.getOrCreateIsolatedUidRangeLocked(appInfo2);
+        IsolatedUidRange range2 = allocator.getOrCreateIsolatedUidRangeLocked(
+                appInfo2.processName, appInfo2.uid);
         validateAppZygoteIsolatedUidRange(range2);
         verifyIsolatedUidAllocator(range2);
 
@@ -339,7 +341,7 @@
 
         // Free range, reallocate and verify
         allocator.freeUidRangeLocked(appInfo2);
-        range2 = allocator.getOrCreateIsolatedUidRangeLocked(appInfo2);
+        range2 = allocator.getOrCreateIsolatedUidRangeLocked(appInfo2.processName, appInfo2.uid);
         validateAppZygoteIsolatedUidRange(range2);
         verifyUidRangesNoOverlap(range, range2);
         verifyIsolatedUidAllocator(range2);
@@ -354,7 +356,8 @@
             appInfo = new ApplicationInfo();
             appInfo.uid = 10000 + i;
             appInfo.processName = "com.android.test.app" + Integer.toString(i);
-            IsolatedUidRange uidRange = allocator.getOrCreateIsolatedUidRangeLocked(appInfo);
+            IsolatedUidRange uidRange = allocator.getOrCreateIsolatedUidRangeLocked(
+                    appInfo.processName, appInfo.uid);
             validateAppZygoteIsolatedUidRange(uidRange);
             verifyIsolatedUidAllocator(uidRange);
         }
@@ -363,7 +366,8 @@
         appInfo = new ApplicationInfo();
         appInfo.uid = 9000;
         appInfo.processName = "com.android.test.app.failed";
-        IsolatedUidRange failedRange = allocator.getOrCreateIsolatedUidRangeLocked(appInfo);
+        IsolatedUidRange failedRange = allocator.getOrCreateIsolatedUidRangeLocked(
+                appInfo.processName, appInfo.uid);
 
         assertNull(failedRange);
     }
diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java
index 36f84d0..c42a718 100644
--- a/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -15,8 +15,11 @@
  */
 package com.android.server.appop;
 
+import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.MODE_ERRORED;
+import static android.app.AppOpsManager.MODE_FOREGROUND;
 import static android.app.AppOpsManager.OP_COARSE_LOCATION;
 import static android.app.AppOpsManager.OP_READ_SMS;
 import static android.app.AppOpsManager.OP_WIFI_SCAN;
@@ -25,6 +28,7 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import android.app.ActivityManager;
 import android.app.AppOpsManager.OpEntry;
 import android.app.AppOpsManager.PackageOps;
 import android.content.Context;
@@ -37,6 +41,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.appop.AppOpsService;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -222,6 +227,108 @@
         assertThat(getLoggedOps()).isNull();
     }
 
+    private void setupProcStateTests() {
+        // For the location proc state tests
+        mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, mMyPackageName, MODE_FOREGROUND);
+        mAppOpsService.mConstants.FG_SERVICE_STATE_SETTLE_TIME = 0;
+        mAppOpsService.mConstants.TOP_STATE_SETTLE_TIME = 0;
+        mAppOpsService.mConstants.BG_STATE_SETTLE_TIME = 0;
+    }
+
+    @Test
+    public void testUidProcStateChange_cachedToTopToCached() throws Exception {
+        setupProcStateTests();
+
+        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+                .isNotEqualTo(MODE_ALLOWED);
+
+        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP);
+        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+                .isEqualTo(MODE_ALLOWED);
+
+        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+        // Second time to make sure that settle time is overcome
+        Thread.sleep(50);
+        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+                .isNotEqualTo(MODE_ALLOWED);
+    }
+
+    @Test
+    public void testUidProcStateChange_cachedToFgs() throws Exception {
+        setupProcStateTests();
+
+        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+                .isNotEqualTo(MODE_ALLOWED);
+
+        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+                .isNotEqualTo(MODE_ALLOWED);
+    }
+
+    @Test
+    public void testUidProcStateChange_cachedToFgsLocation() throws Exception {
+        setupProcStateTests();
+
+        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+                .isNotEqualTo(MODE_ALLOWED);
+
+        mAppOpsService.updateUidProcState(mMyUid,
+                PROCESS_STATE_FOREGROUND_SERVICE_LOCATION);
+        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+                .isEqualTo(MODE_ALLOWED);
+    }
+
+    @Test
+    public void testUidProcStateChange_topToFgs() throws Exception {
+        setupProcStateTests();
+
+        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+                .isNotEqualTo(MODE_ALLOWED);
+
+        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP);
+        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+                .isEqualTo(MODE_ALLOWED);
+
+        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+        // Second time to make sure that settle time is overcome
+        Thread.sleep(50);
+        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+                .isNotEqualTo(MODE_ALLOWED);
+    }
+
+    @Test
+    public void testUidProcStateChange_topToFgsLocationToFgs() throws Exception {
+        setupProcStateTests();
+
+        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+                .isNotEqualTo(MODE_ALLOWED);
+
+        mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP);
+        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+                .isEqualTo(MODE_ALLOWED);
+
+        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE_LOCATION);
+        // Second time to make sure that settle time is overcome
+        Thread.sleep(50);
+        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE_LOCATION);
+        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+                .isEqualTo(MODE_ALLOWED);
+
+        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+        // Second time to make sure that settle time is overcome
+        Thread.sleep(50);
+        mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+        assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+                .isNotEqualTo(MODE_ALLOWED);
+    }
+
     private List<PackageOps> getLoggedOps() {
         return mAppOpsService.getOpsForPackage(mMyUid, mMyPackageName, null /* all ops */);
     }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 6be2c2e..49ee8b3 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -48,8 +48,8 @@
 import android.app.Notification.Builder;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
-import android.content.Context;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.graphics.Color;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
@@ -63,6 +63,7 @@
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.TestableContext;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.IAccessibilityManager;
@@ -70,6 +71,7 @@
 
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.R;
 import com.android.internal.util.IntPair;
 import com.android.server.UiServiceTestCase;
 import com.android.server.lights.Light;
@@ -86,6 +88,7 @@
 @RunWith(AndroidJUnit4.class)
 public class BuzzBeepBlinkTest extends UiServiceTestCase {
 
+    private TestableContext mContext = spy(getContext());
     @Mock AudioManager mAudioManager;
     @Mock Vibrator mVibrator;
     @Mock android.media.IRingtonePlayer mRingtonePlayer;
@@ -96,6 +99,8 @@
     NotificationUsageStats mUsageStats;
     @Mock
     IAccessibilityManager mAccessibilityService;
+    @Mock
+    Resources mResources;
 
     private NotificationManagerService mService;
     private String mPkg = "com.android.server.notification";
@@ -145,7 +150,7 @@
         verify(mAccessibilityService).addClient(any(IAccessibilityManagerClient.class), anyInt());
         assertTrue(accessibilityManager.isEnabled());
 
-        mService = spy(new NotificationManagerService(getContext()));
+        mService = spy(new NotificationManagerService(mContext));
         mService.setAudioManager(mAudioManager);
         mService.setVibrator(mVibrator);
         mService.setSystemReady(true);
@@ -275,7 +280,7 @@
             boolean isLeanback) {
         NotificationChannel channel =
                 new NotificationChannel("test", "test", IMPORTANCE_HIGH);
-        final Builder builder = new Builder(getContext())
+        final Builder builder = new Builder(mContext)
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
                 .setPriority(Notification.PRIORITY_HIGH)
@@ -321,15 +326,14 @@
             n.flags |= Notification.FLAG_INSISTENT;
         }
 
-        Context context = spy(getContext());
-        PackageManager packageManager = spy(context.getPackageManager());
-        when(context.getPackageManager()).thenReturn(packageManager);
+        PackageManager packageManager = spy(mContext.getPackageManager());
+        when(mContext.getPackageManager()).thenReturn(packageManager);
         when(packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK))
                 .thenReturn(isLeanback);
 
         StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid,
                 mPid, n, mUser, null, System.currentTimeMillis());
-        NotificationRecord r = new NotificationRecord(context, sbn, channel);
+        NotificationRecord r = new NotificationRecord(mContext, sbn, channel);
         mService.addNotification(r);
         return r;
     }
@@ -455,7 +459,25 @@
     }
 
     @Test
-    public void testNoBeepForImportanceDefaultInAutomotive() throws Exception {
+    public void testNoBeepForAutomotiveIfEffectsDisabled() throws Exception {
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive))
+                .thenReturn(false);
+        mService.setIsAutomotive(true);
+
+        NotificationRecord r = getBeepyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyNeverBeep();
+        assertFalse(r.isInterruptive());
+    }
+
+    @Test
+    public void testNoBeepForImportanceDefaultInAutomotiveIfEffectsEnabled() throws Exception {
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive))
+                .thenReturn(true);
         mService.setIsAutomotive(true);
 
         NotificationRecord r = getBeepyNotification();
@@ -468,7 +490,10 @@
     }
 
     @Test
-    public void testBeepForImportanceHighInAutomotive() throws Exception {
+    public void testBeepForImportanceHighInAutomotiveIfEffectsEnabled() throws Exception {
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive))
+                .thenReturn(true);
         mService.setIsAutomotive(true);
 
         NotificationRecord r = getBeepyNotification();
@@ -1015,12 +1040,12 @@
     public void testEmptyUriSoundTreatedAsNoSound() throws Exception {
         NotificationChannel channel = new NotificationChannel("test", "test", IMPORTANCE_HIGH);
         channel.setSound(Uri.EMPTY, null);
-        final Notification n = new Builder(getContext(), "test")
+        final Notification n = new Builder(mContext, "test")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
 
         StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
                 mPid, n, mUser, null, System.currentTimeMillis());
-        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+        NotificationRecord r = new NotificationRecord(mContext, sbn, channel);
         mService.addNotification(r);
 
         mService.buzzBeepBlinkLocked(r);
@@ -1069,13 +1094,13 @@
 
     @Test
     public void testCrossUserSoundMuted() throws Exception {
-        final Notification n = new Builder(getContext(), "test")
+        final Notification n = new Builder(mContext, "test")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
 
         int userId = mUser.getIdentifier() + 1;
         StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
                 mPid, n, UserHandle.of(userId), null, System.currentTimeMillis());
-        NotificationRecord r = new NotificationRecord(getContext(), sbn,
+        NotificationRecord r = new NotificationRecord(mContext, sbn,
                 new NotificationChannel("test", "test", IMPORTANCE_HIGH));
 
         mService.buzzBeepBlinkLocked(r);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 44aa55d..45d5219 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -577,12 +577,27 @@
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
                 false, false, false, false, false, false);
+        runAndVerifyBackgroundActivityStartsSubtest(
+                "disallowed_callingUidProcessStateTop_aborted", true,
+                UNIMPORTANT_UID, false, PROCESS_STATE_TOP,
+                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
+                false, false, false, false, false, false);
+        runAndVerifyBackgroundActivityStartsSubtest(
+                "disallowed_realCallingUidProcessStateTop_aborted", true,
+                UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
+                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP,
+                false, false, false, false, false, false);
+        runAndVerifyBackgroundActivityStartsSubtest(
+                "disallowed_hasForegroundActivities_aborted", true,
+                UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
+                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
+                true, false, false, false, false, false);
     }
 
     /**
      * This test ensures that supported usecases aren't aborted when background starts are
      * disallowed.
-     * The scenarios each have only one condidion that makes them supported.
+     * The scenarios each have only one condition that makes them supported.
      */
     @Test
     public void testBackgroundActivityStartsDisallowed_supportedStartsNotAborted() {
@@ -606,26 +621,11 @@
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
                 false, false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
-                "disallowed_callingUidProcessStateTop_notAborted", false,
-                UNIMPORTANT_UID, false, PROCESS_STATE_TOP,
-                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
-        runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_realCallingUidHasVisibleWindow_notAborted", false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, true, PROCESS_STATE_TOP + 1,
                 false, false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
-                "disallowed_realCallingUidProcessStateTop_notAborted", false,
-                UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
-                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP,
-                false, false, false, false, false, false);
-        runAndVerifyBackgroundActivityStartsSubtest(
-                "disallowed_hasForegroundActivities_notAborted", false,
-                UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
-                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                true, false, false, false, false, false);
-        runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_callerIsRecents_notAborted", false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index c4009df..ca3f684 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -52,6 +52,7 @@
 import android.view.Surface;
 import android.view.WindowManager;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
@@ -383,6 +384,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 130392471)
     public void testAddRemoveRace() {
         // There was once a race condition between adding and removing starting windows
         for (int i = 0; i < 1000; i++) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
index 329af95..bb574ce 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
@@ -48,6 +48,7 @@
 import android.util.Log;
 import android.view.IWindowManager;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 
 import com.android.server.am.AssistDataRequester;
@@ -150,6 +151,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 130388718)
     public void testRequestData() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
                 CALLER_ASSIST_SCREENSHOT_ALLOWED);
@@ -250,6 +252,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 130388718)
     public void testNoFetchScreenshots_expectNoScreenshotCallbacks() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
                 CALLER_ASSIST_SCREENSHOT_ALLOWED);
@@ -260,6 +263,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 130388718)
     public void testDisallowAssistScreenshot_expectNullScreenshotCallback() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
                 !CALLER_ASSIST_SCREENSHOT_ALLOWED);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 35a8ec3..263f650 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -50,8 +50,8 @@
         toastyToast.mHasSurface = true;
         app.mHasSurface = true;
 
-        assertTrue(toastyToast.isVisible());
-        assertTrue(app.isVisible());
+        assertTrue(toastyToast.isVisibleNow());
+        assertTrue(app.isVisibleNow());
         assertTrue(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
     }
 
@@ -60,7 +60,7 @@
         final WindowState toastyToast = createWindow(null, TYPE_TOAST, "toast", FAKE_CALLING_UID);
         toastyToast.mHasSurface = true;
 
-        assertTrue(toastyToast.isVisible());
+        assertTrue(toastyToast.isVisibleNow());
         assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
     }
 
@@ -69,8 +69,8 @@
         final WindowState topBar = createWindow(null, TYPE_STATUS_BAR, "topBar", FAKE_CALLING_UID);
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app", FAKE_CALLING_UID);
 
-        assertFalse(topBar.isVisible());
-        assertFalse(app.isVisible());
+        assertFalse(topBar.isVisibleNow());
+        assertFalse(app.isVisibleNow());
         assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
index d29e3fa..c3b0a67 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -27,6 +27,7 @@
 import android.content.ComponentName;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.ColorSpace;
 import android.graphics.GraphicBuffer;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
@@ -127,8 +128,9 @@
             Canvas c = buffer.lockCanvas();
             c.drawColor(Color.RED);
             buffer.unlockCanvasAndPost(c);
-            return new TaskSnapshot(new ComponentName("", ""), buffer, ORIENTATION_PORTRAIT,
-                    TEST_INSETS, mScale < 1f /* reducedResolution */, mScale, mIsRealSnapshot,
+            return new TaskSnapshot(new ComponentName("", ""), buffer,
+                    ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, TEST_INSETS,
+                    mScale < 1f /* reducedResolution */, mScale, mIsRealSnapshot,
                     mWindowingMode, mSystemUiVisibility, mIsTranslucent);
         }
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
index cb6dc6d..4ca01ec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
@@ -35,6 +35,7 @@
 import android.content.ComponentName;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.ColorSpace;
 import android.graphics.GraphicBuffer;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
@@ -64,8 +65,9 @@
         final GraphicBuffer buffer = GraphicBuffer.create(width, height, PixelFormat.RGBA_8888,
                 GraphicBuffer.USAGE_SW_READ_RARELY | GraphicBuffer.USAGE_SW_WRITE_NEVER);
         final TaskSnapshot snapshot = new TaskSnapshot(new ComponentName("", ""), buffer,
-                ORIENTATION_PORTRAIT, contentInsets, false, 1.0f, true /* isRealSnapshot */,
-                WINDOWING_MODE_FULLSCREEN, 0 /* systemUiVisibility */, false /* isTranslucent */);
+                ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, contentInsets, false,
+                1.0f, true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN,
+                0 /* systemUiVisibility */, false /* isTranslucent */);
         mSurface = new TaskSnapshotSurface(mWm, new Window(), new SurfaceControl(), snapshot, "Test",
                 createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), sysuiVis, windowFlags, 0,
                 taskBounds, ORIENTATION_PORTRAIT);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
index 9722d2c..62247d8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
@@ -39,6 +39,7 @@
 import android.support.test.uiautomator.UiDevice;
 import android.text.TextUtils;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 
 import com.android.internal.annotations.GuardedBy;
@@ -78,6 +79,7 @@
 
     @Test
     @Presubmit
+    @FlakyTest(bugId = 130388819)
     public void testTaskStackChanged_afterFinish() throws Exception {
         registerTaskStackChangedListener(new TaskStackListener() {
             @Override
@@ -159,6 +161,7 @@
      */
     @Test
     @Presubmit
+    @FlakyTest(bugId = 130388819)
     public void testTaskChangeCallBacks() throws Exception {
         final Object[] params = new Object[2];
         final CountDownLatch taskCreatedLaunchLatch = new CountDownLatch(1);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
index 78fca0f..06bcdf8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
@@ -36,6 +36,7 @@
 import android.view.IWindow;
 import android.view.WindowManager;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import com.android.server.wm.utils.WmDisplayCutout;
@@ -323,6 +324,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 130388666)
     public void testCalculatePolicyCrop() {
         final FrameTestWindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
@@ -423,6 +425,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 130388666)
     public void testDisplayCutout() {
         // Regular fullscreen task and window
         WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
@@ -446,6 +449,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 130388666)
     public void testDisplayCutout_tempDisplayedBounds() {
         // Regular fullscreen task and window
         WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 2d8a8cb..037e475 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -3394,6 +3394,7 @@
          * {@link SubscriptionManager#getDefaultSubscriptionId()}. To specify subId for MSIM,
          * use {@link Uri#withAppendedPath(Uri, String)} to append with subscription id.
          */
+        @NonNull
         public static final Uri CONTENT_URI = Uri.parse("content://telephony/carriers");
 
         /**
@@ -3406,6 +3407,7 @@
          * {@link SubscriptionManager#getDefaultSubscriptionId()}. To specify subId for MSIM,
          * use {@link Uri#withAppendedPath(Uri, String)} to append with subscription id.
          */
+        @NonNull
         public static final Uri SIM_APN_URI = Uri.parse(
                 "content://telephony/carriers/sim_apn_list");
 
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 9f6528b..d2f88bb 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2804,7 +2804,7 @@
      * @hide
      */
     public static final String KEY_SUBSCRIPTION_GROUP_UUID_STRING =
-            "key_subscription_group_uuid_string";
+            "subscription_group_uuid_string";
 
     /**
     * A boolean property indicating whether this subscription should be managed as an opportunistic
@@ -2819,7 +2819,7 @@
     * @hide
     */
     public static final String KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL =
-            "key_is_opportunistic_subscription_bool";
+            "is_opportunistic_subscription_bool";
 
     /**
      * A list of 4 GSM RSSI thresholds above which a signal level is considered POOR,
diff --git a/telephony/java/android/telephony/CarrierRestrictionRules.java b/telephony/java/android/telephony/CarrierRestrictionRules.java
index 78623e7..950ae6c 100644
--- a/telephony/java/android/telephony/CarrierRestrictionRules.java
+++ b/telephony/java/android/telephony/CarrierRestrictionRules.java
@@ -336,7 +336,6 @@
     public static final class Builder {
         private final CarrierRestrictionRules mRules;
 
-        /** {@hide} */
         public Builder() {
             mRules = new CarrierRestrictionRules();
         }