Merge "API Council Feedbacks" into rvc-dev
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index b905273..ae8976a 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -53,9 +53,8 @@
  * Container of data passed to the {@link android.app.job.JobScheduler} fully encapsulating the
  * parameters required to schedule work against the calling application. These are constructed
  * using the {@link JobInfo.Builder}.
- * You must specify at least one sort of constraint on the JobInfo object that you are creating.
  * The goal here is to provide the scheduler with high-level semantics about the work you want to
- * accomplish. Doing otherwise with throw an exception in your app.
+ * accomplish.
  */
 public class JobInfo implements Parcelable {
     private static String TAG = "JobInfo";
@@ -147,7 +146,7 @@
 
     /**
      * Query the minimum interval allowed for periodic scheduled jobs.  Attempting
-     * to declare a smaller period that this when scheduling a job will result in a
+     * to declare a smaller period than this when scheduling a job will result in a
      * job that is still periodic, but will run with this effective period.
      *
      * @return The minimum available interval for scheduling periodic jobs, in milliseconds.
diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java
index b219fd41..29c48ad 100644
--- a/apex/media/framework/java/android/media/MediaParser.java
+++ b/apex/media/framework/java/android/media/MediaParser.java
@@ -139,7 +139,7 @@
  *     @Override
  *     public void onSampleCompleted(
  *         int trackIndex,
- *         long timeUs,
+ *         long timeMicros,
  *         int flags,
  *         int size,
  *         int offset,
@@ -163,7 +163,7 @@
  *           /* destPos= */ 0,
  *           /* size= */ offset);
  *       bytesWrittenCount = bytesWrittenCount - offset;
- *       publishSample(sampleData, timeUs, flags);
+ *       publishSample(sampleData, timeMicros, flags);
  *     }
  *
  *    private void ensureSpaceInBuffer(int numberOfBytesToRead) {
@@ -187,7 +187,7 @@
      */
     public static final class SeekMap {
 
-        /** Returned by {@link #getDurationUs()} when the duration is unknown. */
+        /** Returned by {@link #getDurationMicros()} when the duration is unknown. */
         public static final int UNKNOWN_DURATION = Integer.MIN_VALUE;
 
         private final com.google.android.exoplayer2.extractor.SeekMap mExoPlayerSeekMap;
@@ -205,26 +205,26 @@
          * Returns the duration of the stream in microseconds or {@link #UNKNOWN_DURATION} if the
          * duration is unknown.
          */
-        public long getDurationUs() {
+        public long getDurationMicros() {
             return mExoPlayerSeekMap.getDurationUs();
         }
 
         /**
          * Obtains {@link SeekPoint SeekPoints} for the specified seek time in microseconds.
          *
-         * <p>{@code getSeekPoints(timeUs).first} contains the latest seek point for samples with
-         * timestamp equal to or smaller than {@code timeUs}.
+         * <p>{@code getSeekPoints(timeMicros).first} contains the latest seek point for samples
+         * with timestamp equal to or smaller than {@code timeMicros}.
          *
-         * <p>{@code getSeekPoints(timeUs).second} contains the earliest seek point for samples with
-         * timestamp equal to or greater than {@code timeUs}. If a seek point exists for {@code
-         * timeUs}, the returned pair will contain the same {@link SeekPoint} twice.
+         * <p>{@code getSeekPoints(timeMicros).second} contains the earliest seek point for samples
+         * with timestamp equal to or greater than {@code timeMicros}. If a seek point exists for
+         * {@code timeMicros}, the returned pair will contain the same {@link SeekPoint} twice.
          *
-         * @param timeUs A seek time in microseconds.
+         * @param timeMicros A seek time in microseconds.
          * @return The corresponding {@link SeekPoint SeekPoints}.
          */
         @NonNull
-        public Pair<SeekPoint, SeekPoint> getSeekPoints(long timeUs) {
-            SeekPoints seekPoints = mExoPlayerSeekMap.getSeekPoints(timeUs);
+        public Pair<SeekPoint, SeekPoint> getSeekPoints(long timeMicros) {
+            SeekPoints seekPoints = mExoPlayerSeekMap.getSeekPoints(timeMicros);
             return new Pair<>(toSeekPoint(seekPoints.first), toSeekPoint(seekPoints.second));
         }
     }
@@ -254,24 +254,24 @@
         @NonNull public static final SeekPoint START = new SeekPoint(0, 0);
 
         /** The time of the seek point, in microseconds. */
-        public final long timeUs;
+        public final long timeMicros;
 
         /** The byte offset of the seek point. */
         public final long position;
 
         /**
-         * @param timeUs The time of the seek point, in microseconds.
+         * @param timeMicros The time of the seek point, in microseconds.
          * @param position The byte offset of the seek point.
          */
-        private SeekPoint(long timeUs, long position) {
-            this.timeUs = timeUs;
+        private SeekPoint(long timeMicros, long position) {
+            this.timeMicros = timeMicros;
             this.position = position;
         }
 
         @Override
         @NonNull
         public String toString() {
-            return "[timeUs=" + timeUs + ", position=" + position + "]";
+            return "[timeMicros=" + timeMicros + ", position=" + position + "]";
         }
 
         @Override
@@ -283,12 +283,12 @@
                 return false;
             }
             SeekPoint other = (SeekPoint) obj;
-            return timeUs == other.timeUs && position == other.position;
+            return timeMicros == other.timeMicros && position == other.position;
         }
 
         @Override
         public int hashCode() {
-            int result = (int) timeUs;
+            int result = (int) timeMicros;
             result = 31 * result + (int) position;
             return result;
         }
@@ -345,25 +345,25 @@
          *
          * @param seekMap The extracted {@link SeekMap}.
          */
-        void onSeekMap(@NonNull SeekMap seekMap);
+        void onSeekMapFound(@NonNull SeekMap seekMap);
 
         /**
          * Called when the number of tracks is found.
          *
          * @param numberOfTracks The number of tracks in the stream.
          */
-        void onTracksFound(int numberOfTracks);
+        void onTrackCountFound(int numberOfTracks);
 
         /**
-         * Called when new {@link TrackData} is extracted from the stream.
+         * Called when new {@link TrackData} is found in the stream.
          *
          * @param trackIndex The index of the track for which the {@link TrackData} was extracted.
          * @param trackData The extracted {@link TrackData}.
          */
-        void onTrackData(int trackIndex, @NonNull TrackData trackData);
+        void onTrackDataFound(int trackIndex, @NonNull TrackData trackData);
 
         /**
-         * Called to write sample data to the output.
+         * Called when sample data is found in the stream.
          *
          * <p>If the invocation of this method returns before the entire {@code inputReader} {@link
          * InputReader#getLength() length} is consumed, the method will be called again for the
@@ -374,15 +374,15 @@
          * @param inputReader The {@link InputReader} from which to read the data.
          * @throws IOException If an exception occurs while reading from {@code inputReader}.
          */
-        void onSampleData(int trackIndex, @NonNull InputReader inputReader) throws IOException;
+        void onSampleDataFound(int trackIndex, @NonNull InputReader inputReader) throws IOException;
 
         /**
-         * Called once all the data of a sample has been passed to {@link #onSampleData}.
+         * Called once all the data of a sample has been passed to {@link #onSampleDataFound}.
          *
          * <p>Also includes sample metadata, like presentation timestamp and flags.
          *
          * @param trackIndex The index of the track to which the sample corresponds.
-         * @param timeUs The media timestamp associated with the sample, in microseconds.
+         * @param timeMicros The media timestamp associated with the sample, in microseconds.
          * @param flags Flags associated with the sample. See {@link MediaCodec
          *     MediaCodec.BUFFER_FLAG_*}.
          * @param size The size of the sample data, in bytes.
@@ -394,7 +394,7 @@
          */
         void onSampleCompleted(
                 int trackIndex,
-                long timeUs,
+                long timeMicros,
                 int flags,
                 int size,
                 int offset,
@@ -632,7 +632,7 @@
     private Extractor mExtractor;
     private ExtractorInput mExtractorInput;
     private long mPendingSeekPosition;
-    private long mPendingSeekTimeUs;
+    private long mPendingSeekTimeMicros;
 
     // Public methods.
 
@@ -760,7 +760,7 @@
         }
 
         if (isPendingSeek()) {
-            mExtractor.seek(mPendingSeekPosition, mPendingSeekTimeUs);
+            mExtractor.seek(mPendingSeekPosition, mPendingSeekTimeMicros);
             removePendingSeek();
         }
 
@@ -786,7 +786,7 @@
      * Seeks within the media container being extracted.
      *
      * <p>{@link SeekPoint SeekPoints} can be obtained from the {@link SeekMap} passed to {@link
-     * OutputConsumer#onSeekMap(SeekMap)}.
+     * OutputConsumer#onSeekMapFound(SeekMap)}.
      *
      * <p>Following a call to this method, the {@link InputReader} passed to the next invocation of
      * {@link #advance} must provide data starting from {@link SeekPoint#position} in the stream.
@@ -796,9 +796,9 @@
     public void seek(@NonNull SeekPoint seekPoint) {
         if (mExtractor == null) {
             mPendingSeekPosition = seekPoint.position;
-            mPendingSeekTimeUs = seekPoint.timeUs;
+            mPendingSeekTimeMicros = seekPoint.timeMicros;
         } else {
-            mExtractor.seek(seekPoint.position, seekPoint.timeUs);
+            mExtractor.seek(seekPoint.position, seekPoint.timeMicros);
         }
     }
 
@@ -836,7 +836,7 @@
 
     private void removePendingSeek() {
         mPendingSeekPosition = -1;
-        mPendingSeekTimeUs = -1;
+        mPendingSeekTimeMicros = -1;
     }
 
     // Private classes.
@@ -897,12 +897,12 @@
 
         @Override
         public void endTracks() {
-            mOutputConsumer.onTracksFound(mTrackOutputAdapters.size());
+            mOutputConsumer.onTrackCountFound(mTrackOutputAdapters.size());
         }
 
         @Override
         public void seekMap(com.google.android.exoplayer2.extractor.SeekMap exoplayerSeekMap) {
-            mOutputConsumer.onSeekMap(new SeekMap(exoplayerSeekMap));
+            mOutputConsumer.onSeekMapFound(new SeekMap(exoplayerSeekMap));
         }
     }
 
@@ -916,7 +916,7 @@
 
         @Override
         public void format(Format format) {
-            mOutputConsumer.onTrackData(
+            mOutputConsumer.onTrackDataFound(
                     mTrackIndex,
                     new TrackData(
                             toMediaFormat(format), toFrameworkDrmInitData(format.drmInitData)));
@@ -927,7 +927,7 @@
                 throws IOException {
             mScratchExtractorInputAdapter.setExtractorInput(input, length);
             long positionBeforeReading = mScratchExtractorInputAdapter.getPosition();
-            mOutputConsumer.onSampleData(mTrackIndex, mScratchExtractorInputAdapter);
+            mOutputConsumer.onSampleDataFound(mTrackIndex, mScratchExtractorInputAdapter);
             return (int) (mScratchExtractorInputAdapter.getPosition() - positionBeforeReading);
         }
 
@@ -935,7 +935,7 @@
         public void sampleData(ParsableByteArray data, int length) {
             mScratchParsableByteArrayAdapter.resetWithByteArray(data, length);
             try {
-                mOutputConsumer.onSampleData(mTrackIndex, mScratchParsableByteArrayAdapter);
+                mOutputConsumer.onSampleDataFound(mTrackIndex, mScratchParsableByteArrayAdapter);
             } catch (IOException e) {
                 // Unexpected.
                 throw new RuntimeException(e);
diff --git a/api/current.txt b/api/current.txt
index 416bb33..1b7f6e5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -572,6 +572,7 @@
     field public static final int elevation = 16843840; // 0x1010440
     field public static final int ellipsize = 16842923; // 0x10100ab
     field public static final int ems = 16843096; // 0x1010158
+    field public static final int enableGwpAsan = 16844310; // 0x1010616
     field public static final int enableVrMode = 16844069; // 0x1010525
     field public static final int enabled = 16842766; // 0x101000e
     field public static final int end = 16843996; // 0x10104dc
@@ -11439,6 +11440,7 @@
     method public int describeContents();
     method public void dump(android.util.Printer, String);
     method public static CharSequence getCategoryTitle(android.content.Context, int);
+    method @Nullable public Boolean isGwpAsanEnabled();
     method public boolean isProfileableByShell();
     method public boolean isResourceOverlay();
     method public boolean isVirtualPreload();
@@ -11572,6 +11574,7 @@
     method @NonNull public CharSequence getProfileSwitchingLabel(@NonNull android.os.UserHandle);
     method @NonNull public java.util.List<android.os.UserHandle> getTargetUserProfiles();
     method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, "android.permission.INTERACT_ACROSS_USERS"}) public void startActivity(@NonNull android.content.Intent, @NonNull android.os.UserHandle, @Nullable android.app.Activity);
+    method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, "android.permission.INTERACT_ACROSS_USERS"}) public void startActivity(@NonNull android.content.Intent, @NonNull android.os.UserHandle, @Nullable android.app.Activity, @Nullable android.os.Bundle);
     method public void startMainActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle);
     field public static final String ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED = "android.content.pm.action.CAN_INTERACT_ACROSS_PROFILES_CHANGED";
   }
@@ -26449,14 +26452,14 @@
 
   public static interface MediaParser.OutputConsumer {
     method public void onSampleCompleted(int, long, int, int, int, @Nullable android.media.MediaCodec.CryptoInfo);
-    method public void onSampleData(int, @NonNull android.media.MediaParser.InputReader) throws java.io.IOException;
-    method public void onSeekMap(@NonNull android.media.MediaParser.SeekMap);
-    method public void onTrackData(int, @NonNull android.media.MediaParser.TrackData);
-    method public void onTracksFound(int);
+    method public void onSampleDataFound(int, @NonNull android.media.MediaParser.InputReader) throws java.io.IOException;
+    method public void onSeekMapFound(@NonNull android.media.MediaParser.SeekMap);
+    method public void onTrackCountFound(int);
+    method public void onTrackDataFound(int, @NonNull android.media.MediaParser.TrackData);
   }
 
   public static final class MediaParser.SeekMap {
-    method public long getDurationUs();
+    method public long getDurationMicros();
     method @NonNull public android.util.Pair<android.media.MediaParser.SeekPoint,android.media.MediaParser.SeekPoint> getSeekPoints(long);
     method public boolean isSeekable();
     field public static final int UNKNOWN_DURATION = -2147483648; // 0x80000000
@@ -26465,7 +26468,7 @@
   public static final class MediaParser.SeekPoint {
     field @NonNull public static final android.media.MediaParser.SeekPoint START;
     field public final long position;
-    field public final long timeUs;
+    field public final long timeMicros;
   }
 
   public static interface MediaParser.SeekableInputReader extends android.media.MediaParser.InputReader {
diff --git a/api/lint-baseline.txt b/api/lint-baseline.txt
index 569e838..83c78fe 100644
--- a/api/lint-baseline.txt
+++ b/api/lint-baseline.txt
@@ -15,6 +15,16 @@
     
 ArrayReturn: android.content.ContentProviderOperation#resolveExtrasBackReferences(android.content.ContentProviderResult[], int) parameter #0:
     
+ArrayReturn: android.location.GnssAntennaInfo.SphericalCorrections#SphericalCorrections(double[][], double[][]) parameter #0:
+    Method parameter should be Collection<> (or subclass) instead of raw array; was `double[][]`
+ArrayReturn: android.location.GnssAntennaInfo.SphericalCorrections#SphericalCorrections(double[][], double[][]) parameter #1:
+    Method parameter should be Collection<> (or subclass) instead of raw array; was `double[][]`
+ArrayReturn: android.location.GnssAntennaInfo.SphericalCorrections#getCorrectionUncertaintiesArray():
+    Method should return Collection<> (or subclass) instead of raw array; was `double[][]`
+ArrayReturn: android.location.GnssAntennaInfo.SphericalCorrections#getCorrectionsArray():
+    Method should return Collection<> (or subclass) instead of raw array; was `double[][]`
+ArrayReturn: android.service.autofill.FillResponse.Builder#setAuthentication(android.view.autofill.AutofillId[], android.content.IntentSender, android.widget.RemoteViews, android.service.autofill.InlinePresentation) parameter #0:
+    Method parameter should be Collection<AutofillId> (or subclass) instead of raw array; was `android.view.autofill.AutofillId[]`
 
 
 BroadcastBehavior: android.app.AlarmManager#ACTION_NEXT_ALARM_CLOCK_CHANGED:
@@ -453,8 +463,12 @@
     
 
 
+ExecutorRegistration: android.media.MediaRouter2#setOnGetControllerHintsListener(android.media.MediaRouter2.OnGetControllerHintsListener):
+    Registration methods should have overload that accepts delivery Executor: `setOnGetControllerHintsListener`
+
+
 GenericException: android.content.res.loader.ResourcesProvider#finalize():
-    Methods must not throw generic exceptions (`java.lang.Throwable`)
+    
 
 
 HiddenSuperclass: android.content.res.ColorStateList:
@@ -499,6 +513,30 @@
     
 
 
+IntentBuilderName: android.net.VpnManager#provisionVpnProfile(android.net.PlatformVpnProfile):
+    Methods creating an Intent should be named `create<Foo>Intent()`, was `provisionVpnProfile`
+
+
+KotlinOperator: android.media.AudioMetadata.Map#set(android.media.AudioMetadata.Key<T>, T):
+    Method can be invoked with an indexing operator from Kotlin: `set` (this is usually desirable; just make sure it makes sense for this type of object)
+KotlinOperator: android.media.AudioMetadata.ReadMap#get(android.media.AudioMetadata.Key<T>):
+    Method can be invoked with an indexing operator from Kotlin: `get` (this is usually desirable; just make sure it makes sense for this type of object)
+
+
+MethodNameUnits: android.media.MediaParser.SeekMap#getDurationMicros():
+    Returned time values are strongly encouraged to be in milliseconds unless you need the extra precision, was `getDurationMicros`
+
+
+MinMaxConstant: android.telephony.DataFailCause#MAX_ACCESS_PROBE:
+    If min/max could change in future, make them dynamic methods: android.telephony.DataFailCause#MAX_ACCESS_PROBE
+MinMaxConstant: android.telephony.DataFailCause#MAX_IPV4_CONNECTIONS:
+    If min/max could change in future, make them dynamic methods: android.telephony.DataFailCause#MAX_IPV4_CONNECTIONS
+MinMaxConstant: android.telephony.DataFailCause#MAX_IPV6_CONNECTIONS:
+    If min/max could change in future, make them dynamic methods: android.telephony.DataFailCause#MAX_IPV6_CONNECTIONS
+MinMaxConstant: android.telephony.DataFailCause#MAX_PPP_INACTIVITY_TIMER_EXPIRED:
+    If min/max could change in future, make them dynamic methods: android.telephony.DataFailCause#MAX_PPP_INACTIVITY_TIMER_EXPIRED
+
+
 MissingNullability: android.app.AsyncNotedAppOp#equals(Object) parameter #0:
     
 MissingNullability: android.app.AsyncNotedAppOp#writeToParcel(android.os.Parcel, int) parameter #0:
@@ -506,11 +544,11 @@
 MissingNullability: android.app.SyncNotedAppOp#equals(Object) parameter #0:
     
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#CHORASMIAN:
-    Missing nullability on field `CHORASMIAN` in class `class android.icu.lang.UCharacter.UnicodeBlock`
+    
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#CJK_UNIFIED_IDEOGRAPHS_EXTENSION_G:
-    Missing nullability on field `CJK_UNIFIED_IDEOGRAPHS_EXTENSION_G` in class `class android.icu.lang.UCharacter.UnicodeBlock`
+    
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#DIVES_AKURU:
-    Missing nullability on field `DIVES_AKURU` in class `class android.icu.lang.UCharacter.UnicodeBlock`
+    
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#EGYPTIAN_HIEROGLYPH_FORMAT_CONTROLS:
     
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#ELYMAIC:
@@ -556,14 +594,39 @@
 MissingNullability: android.icu.util.VersionInfo#UNICODE_12_1:
     
 MissingNullability: android.icu.util.VersionInfo#UNICODE_13_0:
-    Missing nullability on field `UNICODE_13_0` in class `class android.icu.util.VersionInfo`
+    
 MissingNullability: android.media.MediaMetadataRetriever#getFrameAtTime(long, int, android.media.MediaMetadataRetriever.BitmapParams):
     
 MissingNullability: android.media.MediaMetadataRetriever#getScaledFrameAtTime(long, int, int, int, android.media.MediaMetadataRetriever.BitmapParams):
-
     
 MissingNullability: java.time.chrono.JapaneseEra#REIWA:
-    Missing nullability on field `REIWA` in class `class java.time.chrono.JapaneseEra`
+    
+
+
+NotCloseable: android.media.MediaCodec.GraphicBlock:
+    Classes that release resources (finalize()) should implement AutoClosable and CloseGuard: class android.media.MediaCodec.GraphicBlock
+NotCloseable: android.media.MediaCodec.LinearBlock:
+    Classes that release resources (finalize()) should implement AutoClosable and CloseGuard: class android.media.MediaCodec.LinearBlock
+NotCloseable: android.media.MediaParser:
+    Classes that release resources (release()) should implement AutoClosable and CloseGuard: class android.media.MediaParser
+NotCloseable: android.media.MediaRouter2.RoutingController:
+    Classes that release resources (release()) should implement AutoClosable and CloseGuard: class android.media.MediaRouter2.RoutingController
+NotCloseable: android.util.CloseGuard:
+    Classes that release resources (close()) should implement AutoClosable and CloseGuard: class android.util.CloseGuard
+NotCloseable: android.view.SurfaceControlViewHost:
+    Classes that release resources (release()) should implement AutoClosable and CloseGuard: class android.view.SurfaceControlViewHost
+
+
+OnNameExpected: android.app.admin.DevicePolicyKeyguardService#dismiss():
+    If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+OnNameExpected: android.service.controls.ControlsProviderService#createPublisherFor(java.util.List<java.lang.String>):
+    Methods implemented by developers should follow the on<Something> style, was `createPublisherFor`
+OnNameExpected: android.service.controls.ControlsProviderService#createPublisherForAllAvailable():
+    Methods implemented by developers should follow the on<Something> style, was `createPublisherForAllAvailable`
+OnNameExpected: android.service.controls.ControlsProviderService#createPublisherForSuggested():
+    If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+OnNameExpected: android.service.controls.ControlsProviderService#performControlAction(String, android.service.controls.actions.ControlAction, java.util.function.Consumer<java.lang.Integer>):
+    Methods implemented by developers should follow the on<Something> style, was `performControlAction`
 
 
 RequiresPermission: android.accounts.AccountManager#getAccountsByTypeAndFeatures(String, String[], android.accounts.AccountManagerCallback<android.accounts.Account[]>, android.os.Handler):
@@ -1189,11 +1252,13 @@
 SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(String, long, float, java.util.concurrent.Executor, android.location.LocationListener):
     
 SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(long, float, android.location.Criteria, java.util.concurrent.Executor, android.location.LocationListener):
+    
 
 
-
+StreamFiles: android.content.res.loader.DirectoryAssetsProvider#DirectoryAssetsProvider(java.io.File):
+    Methods accepting `File` should also accept `FileDescriptor` or streams: constructor android.content.res.loader.DirectoryAssetsProvider(java.io.File)
 StreamFiles: android.content.res.loader.DirectoryResourceLoader#DirectoryResourceLoader(java.io.File):
-    Methods accepting `File` should also accept `FileDescriptor` or streams: constructor android.content.res.loader.DirectoryResourceLoader(java.io.File)
+    
 
 
 Todo: android.hardware.camera2.params.StreamConfigurationMap:
diff --git a/api/system-current.txt b/api/system-current.txt
index 3c4b872..c102e66 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5620,8 +5620,8 @@
     method public int getConstellation();
     method public int getGuardInterval();
     method public int getHierarchy();
-    method public int getHpCodeRate();
-    method public int getLpCodeRate();
+    method public int getHighPriorityCodeRate();
+    method public int getLowPriorityCodeRate();
     method public int getPlpGroupId();
     method public int getPlpId();
     method public int getPlpMode();
@@ -5649,20 +5649,20 @@
     field public static final int CODERATE_8_9 = 512; // 0x200
     field public static final int CODERATE_AUTO = 1; // 0x1
     field public static final int CODERATE_UNDEFINED = 0; // 0x0
+    field public static final int CONSTELLATION_16QAM = 4; // 0x4
+    field public static final int CONSTELLATION_256QAM = 16; // 0x10
+    field public static final int CONSTELLATION_64QAM = 8; // 0x8
     field public static final int CONSTELLATION_AUTO = 1; // 0x1
-    field public static final int CONSTELLATION_CONSTELLATION_16QAM = 4; // 0x4
-    field public static final int CONSTELLATION_CONSTELLATION_256QAM = 16; // 0x10
-    field public static final int CONSTELLATION_CONSTELLATION_64QAM = 8; // 0x8
-    field public static final int CONSTELLATION_CONSTELLATION_QPSK = 2; // 0x2
+    field public static final int CONSTELLATION_QPSK = 2; // 0x2
     field public static final int CONSTELLATION_UNDEFINED = 0; // 0x0
+    field public static final int GUARD_INTERVAL_19_128 = 64; // 0x40
+    field public static final int GUARD_INTERVAL_19_256 = 128; // 0x80
+    field public static final int GUARD_INTERVAL_1_128 = 32; // 0x20
+    field public static final int GUARD_INTERVAL_1_16 = 4; // 0x4
+    field public static final int GUARD_INTERVAL_1_32 = 2; // 0x2
+    field public static final int GUARD_INTERVAL_1_4 = 16; // 0x10
+    field public static final int GUARD_INTERVAL_1_8 = 8; // 0x8
     field public static final int GUARD_INTERVAL_AUTO = 1; // 0x1
-    field public static final int GUARD_INTERVAL_INTERVAL_19_128 = 64; // 0x40
-    field public static final int GUARD_INTERVAL_INTERVAL_19_256 = 128; // 0x80
-    field public static final int GUARD_INTERVAL_INTERVAL_1_128 = 32; // 0x20
-    field public static final int GUARD_INTERVAL_INTERVAL_1_16 = 4; // 0x4
-    field public static final int GUARD_INTERVAL_INTERVAL_1_32 = 2; // 0x2
-    field public static final int GUARD_INTERVAL_INTERVAL_1_4 = 16; // 0x10
-    field public static final int GUARD_INTERVAL_INTERVAL_1_8 = 8; // 0x8
     field public static final int GUARD_INTERVAL_UNDEFINED = 0; // 0x0
     field public static final int HIERARCHY_1_INDEPTH = 64; // 0x40
     field public static final int HIERARCHY_1_NATIVE = 4; // 0x4
@@ -5697,8 +5697,8 @@
     method @NonNull public android.media.tv.tuner.frontend.DvbtFrontendSettings.Builder setGuardInterval(int);
     method @NonNull public android.media.tv.tuner.frontend.DvbtFrontendSettings.Builder setHierarchy(int);
     method @NonNull public android.media.tv.tuner.frontend.DvbtFrontendSettings.Builder setHighPriority(boolean);
-    method @NonNull public android.media.tv.tuner.frontend.DvbtFrontendSettings.Builder setHpCodeRate(int);
-    method @NonNull public android.media.tv.tuner.frontend.DvbtFrontendSettings.Builder setLpCodeRate(int);
+    method @NonNull public android.media.tv.tuner.frontend.DvbtFrontendSettings.Builder setHighPriorityCodeRate(int);
+    method @NonNull public android.media.tv.tuner.frontend.DvbtFrontendSettings.Builder setLowPriorityCodeRate(int);
     method @NonNull public android.media.tv.tuner.frontend.DvbtFrontendSettings.Builder setMiso(boolean);
     method @NonNull public android.media.tv.tuner.frontend.DvbtFrontendSettings.Builder setPlpGroupId(int);
     method @NonNull public android.media.tv.tuner.frontend.DvbtFrontendSettings.Builder setPlpId(int);
@@ -7158,7 +7158,7 @@
     method @NonNull public java.util.List<android.net.MacAddress> getBlockedClientList();
     method public int getChannel();
     method public int getMaxNumberOfClients();
-    method public int getShutdownTimeoutMillis();
+    method public long getShutdownTimeoutMillis();
     method public boolean isAutoShutdownEnabled();
     method public boolean isClientControlByUserEnabled();
     method @Nullable public android.net.wifi.WifiConfiguration toWifiConfiguration();
@@ -7172,16 +7172,17 @@
     ctor public SoftApConfiguration.Builder();
     ctor public SoftApConfiguration.Builder(@NonNull android.net.wifi.SoftApConfiguration);
     method @NonNull public android.net.wifi.SoftApConfiguration build();
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder enableClientControlByUser(boolean);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setAllowedClientList(@NonNull java.util.List<android.net.MacAddress>);
     method @NonNull public android.net.wifi.SoftApConfiguration.Builder setAutoShutdownEnabled(boolean);
     method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBand(int);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBlockedClientList(@NonNull java.util.List<android.net.MacAddress>);
     method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBssid(@Nullable android.net.MacAddress);
     method @NonNull public android.net.wifi.SoftApConfiguration.Builder setChannel(int, int);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setClientList(@NonNull java.util.List<android.net.MacAddress>, @NonNull java.util.List<android.net.MacAddress>);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setClientControlByUserEnabled(boolean);
     method @NonNull public android.net.wifi.SoftApConfiguration.Builder setHiddenSsid(boolean);
     method @NonNull public android.net.wifi.SoftApConfiguration.Builder setMaxNumberOfClients(@IntRange(from=0) int);
     method @NonNull public android.net.wifi.SoftApConfiguration.Builder setPassphrase(@Nullable String, int);
-    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setShutdownTimeoutMillis(@IntRange(from=0) int);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setShutdownTimeoutMillis(@IntRange(from=0) long);
     method @NonNull public android.net.wifi.SoftApConfiguration.Builder setSsid(@Nullable String);
   }
 
@@ -9069,18 +9070,6 @@
 
 package android.provider {
 
-  public class BlockedNumberContract {
-    field public static final String METHOD_NOTIFY_EMERGENCY_CONTACT = "notify_emergency_contact";
-    field public static final String METHOD_SHOULD_SYSTEM_BLOCK_NUMBER = "should_system_block_number";
-    field public static final String RES_BLOCK_STATUS = "block_status";
-    field public static final int STATUS_BLOCKED_IN_LIST = 1; // 0x1
-    field public static final int STATUS_BLOCKED_NOT_IN_CONTACTS = 5; // 0x5
-    field public static final int STATUS_BLOCKED_PAYPHONE = 4; // 0x4
-    field public static final int STATUS_BLOCKED_RESTRICTED = 2; // 0x2
-    field public static final int STATUS_BLOCKED_UNKNOWN_NUMBER = 3; // 0x3
-    field public static final int STATUS_NOT_BLOCKED = 0; // 0x0
-  }
-
   @Deprecated public static final class ContactsContract.MetadataSync implements android.provider.BaseColumns android.provider.ContactsContract.MetadataSyncColumns {
     field @Deprecated public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact_metadata";
     field @Deprecated public static final String CONTENT_TYPE = "vnd.android.cursor.dir/contact_metadata";
@@ -11319,7 +11308,6 @@
   public class ServiceState implements android.os.Parcelable {
     method public void fillInNotifierBundle(@NonNull android.os.Bundle);
     method public int getDataNetworkType();
-    method public int getDataRegistrationState();
     method @Nullable public android.telephony.NetworkRegistrationInfo getNetworkRegistrationInfo(int, int);
     method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int);
     method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int);
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp
index f84e4b5..8f5e49d 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.cpp
+++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp
@@ -113,7 +113,7 @@
 Status Idmap2Service::createIdmap(const std::string& target_apk_path,
                                   const std::string& overlay_apk_path, int32_t fulfilled_policies,
                                   bool enforce_overlayable, int32_t user_id ATTRIBUTE_UNUSED,
-                                  std::unique_ptr<std::string>* _aidl_return) {
+                                  aidl::nullable<std::string>* _aidl_return) {
   assert(_aidl_return);
   SYSTRACE << "Idmap2Service::createIdmap " << target_apk_path << " " << overlay_apk_path;
   _aidl_return->reset(nullptr);
@@ -155,7 +155,7 @@
     return error("failed to write to idmap path " + idmap_path);
   }
 
-  *_aidl_return = std::make_unique<std::string>(idmap_path);
+  *_aidl_return = aidl::make_nullable<std::string>(idmap_path);
   return ok();
 }
 
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.h b/cmds/idmap2/idmap2d/Idmap2Service.h
index 94d2af4..b6f5136 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.h
+++ b/cmds/idmap2/idmap2d/Idmap2Service.h
@@ -19,9 +19,7 @@
 
 #include <android-base/unique_fd.h>
 #include <binder/BinderService.h>
-
-#include <memory>
-#include <string>
+#include <binder/Nullable.h>
 
 #include "android/os/BnIdmap2.h"
 
@@ -46,7 +44,7 @@
   binder::Status createIdmap(const std::string& target_apk_path,
                              const std::string& overlay_apk_path, int32_t fulfilled_policies,
                              bool enforce_overlayable, int32_t user_id,
-                             std::unique_ptr<std::string>* _aidl_return) override;
+                             aidl::nullable<std::string>* _aidl_return) override;
 };
 
 }  // namespace android::os
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 32a5243..56f2340 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -402,7 +402,7 @@
     }
 
     // Pulled events will start at field 10000.
-    // Next: 10076
+    // Next: 10080
     oneof pulled {
         WifiBytesTransfer wifi_bytes_transfer = 10000 [(module) = "framework"];
         WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001 [(module) = "framework"];
@@ -486,6 +486,10 @@
                 10073 [(module) = "framework"];
         GnssStats gnss_stats = 10074 [(module) = "framework"];
         AppFeaturesOps app_features_ops = 10075 [(module) = "framework"];
+        VoiceCallSession voice_call_session = 10076 [(module) = "telephony"];
+        VoiceCallRatUsage voice_call_rat_usage = 10077 [(module) = "telephony"];
+        SimSlotState sim_slot_state = 10078 [(module) = "telephony"];
+        SupportedRadioAccessFamily supported_radio_access_family = 10079 [(module) = "telephony"];
     }
 
     // DO NOT USE field numbers above 100,000 in AOSP.
@@ -4477,8 +4481,7 @@
  * after an OTA.
  *
  * Logged from:
- *  - system/core/fs_mgr/libsnapshot/snapshot.cpp
- *  - system/core/fs_mgr/libsnapshot/snapshotctl.cpp
+ *  - system/update_engine/cleanup_previous_update_action.cc
  */
 message SnapshotMergeReported {
     // Keep in sync with
@@ -8672,6 +8675,154 @@
 }
 
 /**
+ * Pulls information for a single voice call.
+ *
+ * Each pull creates multiple atoms, one for each call. The sequence is randomized when pulled.
+ *
+ * Pulled from:
+ *   frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/PersistPullers.java
+ */
+message VoiceCallSession {
+    // Bearer (IMS or CS) when the call started.
+    optional android.telephony.CallBearerEnum bearer_at_start = 1;
+
+    // Bearer (IMS or CS) when the call ended.
+    // The bearer may change during the call, e.g. due to SRVCC.
+    optional android.telephony.CallBearerEnum bearer_at_end = 2;
+
+    // Direction of the call (incoming or outgoing).
+    optional android.telephony.CallDirectionEnum direction = 3;
+
+    // Time spent setting up the call.
+    optional android.telephony.CallSetupDurationEnum setup_duration = 4;
+
+    // Whether the call ended before the setup was completed.
+    optional bool setup_failed = 5;
+
+    // IMS reason code or CS disconnect cause.
+    // For IMS, see: frameworks/base/telephony/java/android/telephony/ims/ImsReasonInfo.java
+    // For CS, see: frameworks/base/telephony/java/android/telephony/DisconnectCause.java
+    optional int32 disconnect_reason_code = 6;
+
+    // IMS extra code or CS precise disconnect cause.
+    // For IMS, this code is vendor-specific
+    // For CS, see: frameworks/base/telephony/java/android/telephony/PreciseDisconnectCause.java
+    optional int32 disconnect_extra_code = 7;
+
+    // IMS extra message or CS vendor cause.
+    optional string disconnect_extra_message = 8;
+
+    // Radio access technology (RAT) used when call started.
+    optional android.telephony.NetworkTypeEnum rat_at_start = 9;
+
+    // Radio access technology (RAT) used when call terminated.
+    optional android.telephony.NetworkTypeEnum rat_at_end = 10;
+
+    // Number of times RAT changed during the call.
+    optional int64 rat_switch_count = 11;
+
+    // A bitmask of all codecs used during the call.
+    // See: frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
+    optional int64 codec_bitmask = 12;
+
+    // Number of other calls going on during call setup, for the same SIM slot.
+    optional int32 concurrent_call_count_at_start = 13;
+
+    // Number of other calls going on during call termination, for the same SIM slot.
+    optional int32 concurrent_call_count_at_end = 14;
+
+    // Index of the SIM is used, 0 for single-SIM devices.
+    optional int32 sim_slot_index = 15;
+
+    // Whether the device was in multi-SIM mode (with multiple active SIM profiles).
+    optional bool is_multi_sim = 16;
+
+    // Whether the call was made with an eSIM profile.
+    optional bool is_esim = 17;
+
+    // Carrier ID of the SIM card.
+    // See https://source.android.com/devices/tech/config/carrierid.
+    optional int32 carrier_id = 18;
+
+    // Whether an SRVCC has been completed successfully.
+    // SRVCC (CS fallback) should be recorded in the IMS call since there will be no more SRVCC
+    // events once the call is switched to CS.
+    optional bool srvcc_completed = 19;
+
+    // Number of SRVCC failures.
+    optional int64 srvcc_failure_count = 20;
+
+    // Number of SRVCC cancellations.
+    optional int64 srvcc_cancellation_count = 21;
+
+    // Whether the Real-Time Text (RTT) was ever used in the call.
+    optional bool rtt_enabled = 22;
+
+    // Whether this was an emergency call.
+    optional bool is_emergency = 23;
+
+    // Whether the call was performed while roaming.
+    optional bool is_roaming = 24;
+}
+
+/**
+ * Pulls voice call radio access technology (RAT) usage.
+ *
+ * Each pull creates multiple atoms, one for each carrier/RAT, the order of which is irrelevant to
+ * time. The atom will be skipped if not enough data is available.
+ *
+ * Pulled from:
+ *   frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/PersistPullers.java
+ */
+message VoiceCallRatUsage {
+    // Carrier ID (https://source.android.com/devices/tech/config/carrierid).
+    optional int32 carrier_id = 1;
+
+    // Radio access technology.
+    optional android.telephony.NetworkTypeEnum rat = 2;
+
+    // Total duration that voice calls spent on this carrier and RAT.
+    optional int64 total_duration_seconds = 3;
+
+    // Total number of calls using this carrier and RAT.
+    // A call is counted once even if it used the RAT multiple times.
+    optional int64 call_count = 4;
+}
+
+/**
+ * Pulls the number of active SIM slots and SIMs/eSIM profiles.
+ *
+ * Pulled from:
+ *   frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/NonPersistPullers.java
+ */
+message SimSlotState {
+    // Number of active SIM slots (both physical and eSIM profiles) in the device.
+    optional int32 active_slot_count = 1;
+
+    // Number of SIM cards (both physical and active eSIM profiles).
+    // This number is always equal to or less than the number of active SIM slots.
+    optional int32 sim_count = 2;
+
+    // Number of active eSIM profiles.
+    // This number is always equal to or less than the number of SIMs.
+    optional int32 esim_count = 3;
+}
+
+/**
+ * Pulls supported cellular radio access technologies.
+ *
+ * This atom reports the capabilities of the device, rather than the network it has access to.
+ *
+ * Pulled from:
+ *   frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/NonPersistPullers.java
+ */
+message SupportedRadioAccessFamily {
+    // A bitmask of supported radio technologies.
+    // See android.telephony.TelephonyManager.NetworkTypeBitMask.
+    optional int64 network_type_bitmask = 1;
+}
+
+/**
  * Logs gnss stats from location service provider
  *
  * Pulled from:
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 3a3eea9..e7036bb 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -48,6 +48,7 @@
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.KeyEvent;
+import android.view.SurfaceControl;
 import android.view.SurfaceView;
 import android.view.WindowManager;
 import android.view.WindowManagerImpl;
@@ -1937,8 +1938,8 @@
      * to declare the capability to take screenshot by setting the
      * {@link android.R.styleable#AccessibilityService_canTakeScreenshot}
      * property in its meta-data. For details refer to {@link #SERVICE_META_DATA}.
-     * Besides, This API is only supported for default display now
-     * {@link Display#DEFAULT_DISPLAY}.
+     * This API only will support {@link Display#DEFAULT_DISPLAY} until {@link SurfaceControl}
+     * supports non-default displays.
      * </p>
      *
      * @param displayId The logic display id, must be {@link Display#DEFAULT_DISPLAY} for
@@ -1948,11 +1949,17 @@
      *
      * @return {@code true} if the taking screenshot accepted, {@code false} if too little time
      * has elapsed since the last screenshot, invalid display or internal errors.
+     * @throws IllegalArgumentException if displayId is not {@link Display#DEFAULT_DISPLAY}.
      */
     public boolean takeScreenshot(int displayId, @NonNull @CallbackExecutor Executor executor,
             @NonNull Consumer<ScreenshotResult> callback) {
         Preconditions.checkNotNull(executor, "executor cannot be null");
         Preconditions.checkNotNull(callback, "callback cannot be null");
+
+        if (displayId != Display.DEFAULT_DISPLAY) {
+            throw new IllegalArgumentException("DisplayId isn't the default display");
+        }
+
         final IAccessibilityServiceConnection connection =
                 AccessibilityInteractionClient.getInstance().getConnection(
                         mConnectionId);
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index ca37e9b..2c41e8d 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -18,6 +18,7 @@
 
 import android.annotation.CallSuper;
 import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
@@ -269,6 +270,11 @@
     private float mDurationScale = -1f;
 
     /**
+     * Animation handler used to schedule updates for this animation.
+     */
+    private AnimationHandler mAnimationHandler;
+
+    /**
      * Public constants
      */
 
@@ -1684,6 +1690,15 @@
      * @hide
      */
     public AnimationHandler getAnimationHandler() {
-        return AnimationHandler.getInstance();
+        return mAnimationHandler != null ? mAnimationHandler : AnimationHandler.getInstance();
+    }
+
+    /**
+     * Sets the animation handler used to schedule updates for this animator or {@code null} to use
+     * the default handler.
+     * @hide
+     */
+    public void setAnimationHandler(@Nullable AnimationHandler animationHandler) {
+        mAnimationHandler = animationHandler;
     }
 }
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 6564dc9..9925d69 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -27,6 +27,7 @@
 import android.annotation.SystemService;
 import android.annotation.TestApi;
 import android.app.usage.UsageStatsManager;
+import android.compat.Compatibility;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.EnabledAfter;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -385,6 +386,13 @@
      */
     public static final int WATCH_FOREGROUND_CHANGES = 1 << 0;
 
+    /**
+     * Flag for {@link #startWatchingMode} that causes the callback to happen on the switch-op
+     * instead the op the callback was registered. (This simulates pre-R behavior).
+     *
+     * @hide
+     */
+    public static final int CALL_BACK_ON_SWITCHED_OP = 1 << 1;
 
     /**
      * Flag to determine whether we should log noteOp/startOp calls to make sure they
@@ -6712,6 +6720,13 @@
                 };
                 mModeWatchers.put(callback, cb);
             }
+
+            // See CALL_BACK_ON_CHANGED_LISTENER_WITH_SWITCHED_OP_CHANGE
+            if (!Compatibility.isChangeEnabled(
+                    CALL_BACK_ON_CHANGED_LISTENER_WITH_SWITCHED_OP_CHANGE)) {
+                flags |= CALL_BACK_ON_SWITCHED_OP;
+            }
+
             try {
                 mService.startWatchingModeWithFlags(op, packageName, flags, cb);
             } catch (RemoteException e) {
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 34684c4..4cb8d93 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -175,11 +175,4 @@
      * Called from SystemUI when it shows the AoD UI.
      */
     oneway void setInAmbientMode(boolean inAmbientMode, long animationDuration);
-
-    /**
-     * Called when the wallpaper needs to zoom out.
-     * The zoom value goes from 0 to 1 (inclusive) where 1 means fully zoomed out,
-     * 0 means fully zoomed in
-     */
-    oneway void setWallpaperZoomOut(float zoom, String callingPackage, int displayId);
 }
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index d9405e1..345eaae 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -1858,13 +1858,12 @@
      *
      * @hide
      */
-    public void setWallpaperZoomOut(float zoom) {
+    public void setWallpaperZoomOut(IBinder windowToken, float zoom) {
         if (zoom < 0 || zoom > 1f) {
             throw new IllegalArgumentException("zoom must be between 0 and one: " + zoom);
         }
         try {
-            sGlobals.mService.setWallpaperZoomOut(zoom, mContext.getOpPackageName(),
-                    mContext.getDisplayId());
+            WindowManagerGlobal.getWindowSession().setWallpaperZoomOut(windowToken, zoom);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index a15afe0..c82fffa 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -25,6 +25,7 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ProcessInfo;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
@@ -38,6 +39,8 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.Parcelling;
+import com.android.internal.util.Parcelling.BuiltIn.ForBoolean;
 import com.android.server.SystemConfig;
 
 import java.lang.annotation.Retention;
@@ -56,7 +59,8 @@
  * &lt;application&gt; tag.
  */
 public class ApplicationInfo extends PackageItemInfo implements Parcelable {
-    
+    private static ForBoolean sForBoolean = Parcelling.Cache.getOrCreate(ForBoolean.class);
+
     /**
      * Default task affinity of all activities in this application. See 
      * {@link ActivityInfo#taskAffinity} for more information.  This comes 
@@ -1273,6 +1277,14 @@
     public String zygotePreloadName;
 
     /**
+     * Indicates if the application has requested GWP-ASan to be enabled, disabled, or left
+     * unspecified. Processes can override this setting.
+     * @hide
+     */
+    @Nullable
+    public Boolean enableGwpAsan;
+
+    /**
      * Represents the default policy. The actual policy used will depend on other properties of
      * the application, e.g. the target SDK version.
      * @hide
@@ -1413,6 +1425,9 @@
             pw.println(prefix + "usesNonSdkApi=" + usesNonSdkApi());
             pw.println(prefix + "allowsPlaybackCapture="
                         + (isAudioPlaybackCaptureAllowed() ? "true" : "false"));
+            if (enableGwpAsan != null) {
+                pw.println(prefix + "enableGwpAsan=" + enableGwpAsan);
+            }
         }
         super.dumpBack(pw, prefix);
     }
@@ -1511,6 +1526,9 @@
             if (category != CATEGORY_UNDEFINED) {
                 proto.write(ApplicationInfoProto.Detail.CATEGORY, category);
             }
+            if (enableGwpAsan != null) {
+                proto.write(ApplicationInfoProto.Detail.ENABLE_GWP_ASAN, enableGwpAsan);
+            }
             proto.end(detailToken);
         }
         proto.end(token);
@@ -1620,6 +1638,7 @@
         mHiddenApiPolicy = orig.mHiddenApiPolicy;
         hiddenUntilInstalled = orig.hiddenUntilInstalled;
         zygotePreloadName = orig.zygotePreloadName;
+        enableGwpAsan = orig.enableGwpAsan;
     }
 
     public String toString() {
@@ -1703,6 +1722,7 @@
         dest.writeInt(mHiddenApiPolicy);
         dest.writeInt(hiddenUntilInstalled ? 1 : 0);
         dest.writeString(zygotePreloadName);
+        sForBoolean.parcel(enableGwpAsan, dest, parcelableFlags);
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<ApplicationInfo> CREATOR
@@ -1783,6 +1803,7 @@
         mHiddenApiPolicy = source.readInt();
         hiddenUntilInstalled = source.readInt() != 0;
         zygotePreloadName = source.readString();
+        enableGwpAsan = sForBoolean.unparcel(source);
     }
 
     /**
@@ -2161,6 +2182,7 @@
     /** {@hide} */ public void setResourcePath(String resourcePath) { scanPublicSourceDir = resourcePath; }
     /** {@hide} */ public void setBaseResourcePath(String baseResourcePath) { publicSourceDir = baseResourcePath; }
     /** {@hide} */ public void setSplitResourcePaths(String[] splitResourcePaths) { splitPublicSourceDirs = splitResourcePaths; }
+    /** {@hide} */ public void setGwpAsanEnabled(@Nullable Boolean value) { enableGwpAsan = value; }
 
     /** {@hide} */
     @UnsupportedAppUsage
@@ -2172,4 +2194,6 @@
     @UnsupportedAppUsage
     public String getBaseResourcePath() { return publicSourceDir; }
     /** {@hide} */ public String[] getSplitResourcePaths() { return splitPublicSourceDirs; }
+    @Nullable
+    public Boolean isGwpAsanEnabled() { return enableGwpAsan; }
 }
diff --git a/core/java/android/content/pm/CrossProfileApps.java b/core/java/android/content/pm/CrossProfileApps.java
index 3261cb1..5e7e0c8 100644
--- a/core/java/android/content/pm/CrossProfileApps.java
+++ b/core/java/android/content/pm/CrossProfileApps.java
@@ -27,6 +27,7 @@
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -128,6 +129,35 @@
             @NonNull Intent intent,
             @NonNull UserHandle targetUser,
             @Nullable Activity callingActivity) {
+        startActivity(intent, targetUser, callingActivity, /* options= */ null);
+    }
+
+    /**
+     * Starts the specified activity of the caller package in the specified profile.
+     *
+     * <p>The caller must have the {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES},
+     * {@code android.Manifest.permission#INTERACT_ACROSS_USERS}, or {@code
+     * android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission. Both the caller and
+     * target user profiles must be in the same profile group. The target user must be a valid user
+     * returned from {@link #getTargetUserProfiles()}.
+     *
+     * @param intent The intent to launch. A component in the caller package must be specified.
+     * @param targetUser The {@link UserHandle} of the profile; must be one of the users returned by
+     *        {@link #getTargetUserProfiles()} if different to the calling user, otherwise a
+     *        {@link SecurityException} will be thrown.
+     * @param callingActivity The activity to start the new activity from for the purposes of
+     *        deciding which task the new activity should belong to. If {@code null}, the activity
+     *        will always be started in a new task.
+     * @param options The activity options or {@code null}. See {@link android.app.ActivityOptions}.
+     */
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.INTERACT_ACROSS_PROFILES,
+            android.Manifest.permission.INTERACT_ACROSS_USERS})
+    public void startActivity(
+            @NonNull Intent intent,
+            @NonNull UserHandle targetUser,
+            @Nullable Activity callingActivity,
+            @Nullable Bundle options) {
         try {
             mService.startActivityAsUserByIntent(
                     mContext.getIApplicationThread(),
@@ -135,7 +165,8 @@
                     mContext.getFeatureId(),
                     intent,
                     targetUser.getIdentifier(),
-                    callingActivity != null ? callingActivity.getActivityToken() : null);
+                    callingActivity != null ? callingActivity.getActivityToken() : null,
+                    options);
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
         }
diff --git a/core/java/android/content/pm/ICrossProfileApps.aidl b/core/java/android/content/pm/ICrossProfileApps.aidl
index 5a6e008..4cecb30 100644
--- a/core/java/android/content/pm/ICrossProfileApps.aidl
+++ b/core/java/android/content/pm/ICrossProfileApps.aidl
@@ -31,7 +31,8 @@
             in String callingFeatureId, in ComponentName component, int userId,
             boolean launchMainActivity);
     void startActivityAsUserByIntent(in IApplicationThread caller, in String callingPackage,
-            in String callingFeatureId, in Intent intent, int userId, in IBinder callingActivity);
+            in String callingFeatureId, in Intent intent, int userId, in IBinder callingActivity,
+            in Bundle options);
     List<UserHandle> getTargetUserProfiles(in String callingPackage);
     boolean canInteractAcrossProfiles(in String callingPackage);
     boolean canRequestInteractAcrossProfiles(in String callingPackage);
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 1f53176..ec3590f 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -2323,6 +2323,7 @@
 
         /**
          * Get the value set in {@link SessionParams#setOriginatingUri(Uri)}.
+         * Note: This value will only be non-null for the owner of the session.
          */
         public @Nullable Uri getOriginatingUri() {
             return originatingUri;
@@ -2337,6 +2338,7 @@
 
         /**
          * Get the value set in {@link SessionParams#setReferrerUri(Uri)}
+         * Note: This value will only be non-null for the owner of the session.
          */
         public @Nullable Uri getReferrerUri() {
             return referrerUri;
diff --git a/core/java/android/content/pm/ProcessInfo.java b/core/java/android/content/pm/ProcessInfo.java
index c77a267..a373067 100644
--- a/core/java/android/content/pm/ProcessInfo.java
+++ b/core/java/android/content/pm/ProcessInfo.java
@@ -23,66 +23,157 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 
+import com.android.internal.util.DataClass;
+import com.android.internal.util.Parcelling;
+
 /**
  * Information about a process an app may run.  This corresponds to information collected from the
  * AndroidManifest.xml's &lt;permission-group&gt; tags.
  * @hide
  */
+@DataClass(genGetters = true, genSetters = false, genParcelable = true, genAidl = false,
+        genBuilder = false)
 public class ProcessInfo implements Parcelable {
     /**
      * The name of the process, fully-qualified based on the app's package name.
      */
+    @NonNull
     public String name;
 
     /**
      * If non-null, these are permissions that are not allowed in this process.
      */
     @Nullable
+    @DataClass.ParcelWith(Parcelling.BuiltIn.ForInternedStringArraySet.class)
     public ArraySet<String> deniedPermissions;
 
-    public ProcessInfo(String name, ArraySet<String> deniedPermissions) {
-        this.name = name;
-        this.deniedPermissions = deniedPermissions;
-    }
+    /**
+     * Indicates if the process has requested GWP-ASan to be enabled, disabled, or left unspecified.
+     */
+    @Nullable
+    public Boolean enableGwpAsan;
 
     @Deprecated
     public ProcessInfo(@NonNull ProcessInfo orig) {
         this.name = orig.name;
         this.deniedPermissions = orig.deniedPermissions;
+        this.enableGwpAsan = orig.enableGwpAsan;
     }
 
-    public int describeContents() {
-        return 0;
+
+
+    // Code below generated by codegen v1.0.15.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/ProcessInfo.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    /**
+     * Creates a new ProcessInfo.
+     *
+     * @param name
+     *   The name of the process, fully-qualified based on the app's package name.
+     * @param deniedPermissions
+     *   If non-null, these are permissions that are not allowed in this process.
+     * @param enableGwpAsan
+     *   Indicates if the process has requested GWP-ASan to be enabled, disabled, or left unspecified.
+     */
+    @DataClass.Generated.Member
+    public ProcessInfo(
+            @NonNull String name,
+            @Nullable ArraySet<String> deniedPermissions,
+            @Nullable Boolean enableGwpAsan) {
+        this.name = name;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, name);
+        this.deniedPermissions = deniedPermissions;
+        this.enableGwpAsan = enableGwpAsan;
+
+        // onConstructed(); // You can define this method to get a callback
     }
 
-    public void writeToParcel(Parcel dest, int parcelableFlags) {
-        dest.writeString(this.name);
-        final int numDenied = this.deniedPermissions != null
-                ? this.deniedPermissions.size() : 0;
-        dest.writeInt(numDenied);
-        for (int i = 0; i < numDenied; i++) {
-            dest.writeString(this.deniedPermissions.valueAt(i));
+    @DataClass.Generated.Member
+    static Parcelling<ArraySet<String>> sParcellingForDeniedPermissions =
+            Parcelling.Cache.get(
+                    Parcelling.BuiltIn.ForInternedStringArraySet.class);
+    static {
+        if (sParcellingForDeniedPermissions == null) {
+            sParcellingForDeniedPermissions = Parcelling.Cache.put(
+                    new Parcelling.BuiltIn.ForInternedStringArraySet());
         }
     }
 
-    public static final @NonNull Creator<ProcessInfo> CREATOR =
-            new Creator<ProcessInfo>() {
-                public ProcessInfo createFromParcel(Parcel source) {
-                    return new ProcessInfo(source);
-                }
-                public ProcessInfo[] newArray(int size) {
-                    return new ProcessInfo[size];
-                }
-            };
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
 
-    private ProcessInfo(Parcel source) {
-        this.name = source.readString();
-        final int numDenied = source.readInt();
-        if (numDenied > 0) {
-            this.deniedPermissions = new ArraySet<>(numDenied);
-            for (int i = numDenied - 1; i >= 0; i--) {
-                this.deniedPermissions.add(TextUtils.safeIntern(source.readString()));
-            }
-        }
+        byte flg = 0;
+        if (deniedPermissions != null) flg |= 0x2;
+        if (enableGwpAsan != null) flg |= 0x4;
+        dest.writeByte(flg);
+        dest.writeString(name);
+        sParcellingForDeniedPermissions.parcel(deniedPermissions, dest, flags);
+        if (enableGwpAsan != null) dest.writeBoolean(enableGwpAsan);
     }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    protected ProcessInfo(@NonNull Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        byte flg = in.readByte();
+        String _name = in.readString();
+        ArraySet<String> _deniedPermissions = sParcellingForDeniedPermissions.unparcel(in);
+        Boolean _enableGwpAsan = (flg & 0x4) == 0 ? null : (Boolean) in.readBoolean();
+
+        this.name = _name;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, name);
+        this.deniedPermissions = _deniedPermissions;
+        this.enableGwpAsan = _enableGwpAsan;
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<ProcessInfo> CREATOR
+            = new Parcelable.Creator<ProcessInfo>() {
+        @Override
+        public ProcessInfo[] newArray(int size) {
+            return new ProcessInfo[size];
+        }
+
+        @Override
+        public ProcessInfo createFromParcel(@NonNull Parcel in) {
+            return new ProcessInfo(in);
+        }
+    };
+
+    @DataClass.Generated(
+            time = 1582840056156L,
+            codegenVersion = "1.0.15",
+            sourceFile = "frameworks/base/core/java/android/content/pm/ProcessInfo.java",
+            inputSignatures = "public @android.annotation.NonNull java.lang.String name\npublic @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringArraySet.class) android.util.ArraySet<java.lang.String> deniedPermissions\npublic @android.annotation.Nullable java.lang.Boolean enableGwpAsan\nclass ProcessInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
 }
diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java
index aa93d80..a479b2e 100644
--- a/core/java/android/content/pm/parsing/ParsingPackage.java
+++ b/core/java/android/content/pm/parsing/ParsingPackage.java
@@ -236,6 +236,8 @@
 
     ParsingPackage setEnabled(boolean enabled);
 
+    ParsingPackage setGwpAsanEnabled(Boolean enableGwpAsan);
+
     ParsingPackage setCrossProfile(boolean crossProfile);
 
     ParsingPackage setFullBackupContent(int fullBackupContent);
diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
index a9b72d0..f6a415e 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
@@ -30,6 +30,7 @@
 import android.content.pm.FeatureInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageParser;
+import android.content.pm.ProcessInfo;
 import android.content.pm.parsing.component.ParsedActivity;
 import android.content.pm.parsing.component.ParsedComponent;
 import android.content.pm.parsing.component.ParsedFeature;
@@ -406,6 +407,10 @@
     private boolean allowNativeHeapPointerTagging;
     private boolean preserveLegacyExternalStorage;
 
+    @Nullable
+    @DataClass.ParcelWith(ForBoolean.class)
+    protected Boolean enableGwpAsan = null;
+
     // TODO(chiuwinson): Non-null
     @Nullable
     private ArraySet<String> mimeGroups;
@@ -904,7 +909,7 @@
         appInfo.volumeUuid = volumeUuid;
         appInfo.zygotePreloadName = zygotePreloadName;
         appInfo.crossProfile = isCrossProfile();
-
+        appInfo.setGwpAsanEnabled(enableGwpAsan);
         appInfo.setBaseCodePath(baseCodePath);
         appInfo.setBaseResourcePath(baseCodePath);
         appInfo.setCodePath(codePath);
@@ -1086,6 +1091,7 @@
         dest.writeBoolean(this.allowNativeHeapPointerTagging);
         dest.writeBoolean(this.preserveLegacyExternalStorage);
         dest.writeArraySet(this.mimeGroups);
+        sForBoolean.parcel(this.enableGwpAsan, dest, flags);
     }
 
     public ParsingPackageImpl(Parcel in) {
@@ -1243,6 +1249,7 @@
         this.allowNativeHeapPointerTagging = in.readBoolean();
         this.preserveLegacyExternalStorage = in.readBoolean();
         this.mimeGroups = (ArraySet<String>) in.readArraySet(boot);
+        this.enableGwpAsan = sForBoolean.unparcel(in);
     }
 
     public static final Parcelable.Creator<ParsingPackageImpl> CREATOR =
@@ -1965,6 +1972,12 @@
     }
 
     @Override
+    @Nullable
+    public Boolean isGwpAsanEnabled() {
+        return enableGwpAsan;
+    }
+
+    @Override
     public boolean isPartiallyDirectBootAware() {
         return partiallyDirectBootAware;
     }
@@ -2420,6 +2433,12 @@
     }
 
     @Override
+    public ParsingPackageImpl setGwpAsanEnabled(@Nullable Boolean value) {
+        enableGwpAsan = value;
+        return this;
+    }
+
+    @Override
     public ParsingPackageImpl setPartiallyDirectBootAware(boolean value) {
         partiallyDirectBootAware = value;
         return this;
diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java
index 048b924..61d7824 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageRead.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java
@@ -840,6 +840,13 @@
     @Nullable
     Set<String> getMimeGroups();
 
+    /**
+     * @see ApplicationInfo#enableGwpAsan
+     * @see R.styleable#AndroidManifest_enableGwpAsan
+     */
+    @Nullable
+    public Boolean isGwpAsanEnabled();
+
     // TODO(b/135203078): Hide and enforce going through PackageInfoUtils
     ApplicationInfo toAppInfoWithoutState();
 }
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index b4f2159..19da71c 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -40,6 +40,7 @@
 import android.content.pm.FeatureGroupInfo;
 import android.content.pm.FeatureInfo;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageItemInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageParser;
 import android.content.pm.PackageParser.PackageParserException;
@@ -1660,6 +1661,11 @@
                     && !ClassLoaderFactory.isValidClassLoaderName(classLoaderName)) {
                 return input.error("Invalid class loader name: " + classLoaderName);
             }
+
+            if (sa.hasValue(R.styleable.AndroidManifestApplication_enableGwpAsan)) {
+                pkg.setGwpAsanEnabled(
+                        sa.getBoolean(R.styleable.AndroidManifestApplication_enableGwpAsan, false));
+            }
         } finally {
             sa.recycle();
         }
diff --git a/core/java/android/content/pm/parsing/component/ParsedProcess.java b/core/java/android/content/pm/parsing/component/ParsedProcess.java
index da7bf98..3b6020a 100644
--- a/core/java/android/content/pm/parsing/component/ParsedProcess.java
+++ b/core/java/android/content/pm/parsing/component/ParsedProcess.java
@@ -41,6 +41,9 @@
     @DataClass.ParcelWith(Parcelling.BuiltIn.ForInternedStringSet.class)
     protected Set<String> deniedPermissions = emptySet();
 
+    @Nullable
+    protected Boolean enableGwpAsan = null;
+
     public ParsedProcess() {
     }
 
@@ -71,13 +74,15 @@
     @DataClass.Generated.Member
     public ParsedProcess(
             @NonNull String name,
-            @NonNull Set<String> deniedPermissions) {
+            @NonNull Set<String> deniedPermissions,
+            @Nullable Boolean enableGwpAsan) {
         this.name = name;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, name);
         this.deniedPermissions = deniedPermissions;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, deniedPermissions);
+        this.enableGwpAsan = enableGwpAsan;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -93,6 +98,11 @@
     }
 
     @DataClass.Generated.Member
+    public @Nullable Boolean getEnableGwpAsan() {
+        return enableGwpAsan;
+    }
+
+    @DataClass.Generated.Member
     static Parcelling<Set<String>> sParcellingForDeniedPermissions =
             Parcelling.Cache.get(
                     Parcelling.BuiltIn.ForInternedStringSet.class);
@@ -109,8 +119,12 @@
         // You can override field parcelling by defining methods like:
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
+        byte flg = 0;
+        if (enableGwpAsan != null) flg |= 0x4;
+        dest.writeByte(flg);
         dest.writeString(name);
         sParcellingForDeniedPermissions.parcel(deniedPermissions, dest, flags);
+        if (enableGwpAsan != null) dest.writeBoolean(enableGwpAsan);
     }
 
     @Override
@@ -124,8 +138,10 @@
         // You can override field unparcelling by defining methods like:
         // static FieldType unparcelFieldName(Parcel in) { ... }
 
+        byte flg = in.readByte();
         String _name = in.readString();
         Set<String> _deniedPermissions = sParcellingForDeniedPermissions.unparcel(in);
+        Boolean _enableGwpAsan = (flg & 0x4) == 0 ? null : (Boolean) in.readBoolean();
 
         this.name = _name;
         com.android.internal.util.AnnotationValidations.validate(
@@ -133,6 +149,7 @@
         this.deniedPermissions = _deniedPermissions;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, deniedPermissions);
+        this.enableGwpAsan = _enableGwpAsan;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -152,10 +169,10 @@
     };
 
     @DataClass.Generated(
-            time = 1581452315946L,
+            time = 1582589960479L,
             codegenVersion = "1.0.14",
             sourceFile = "frameworks/base/core/java/android/content/pm/parsing/component/ParsedProcess.java",
-            inputSignatures = "protected @android.annotation.NonNull java.lang.String name\nprotected @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringSet.class) java.util.Set<java.lang.String> deniedPermissions\npublic  void addStateFrom(android.content.pm.parsing.component.ParsedProcess)\nclass ParsedProcess extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
+            inputSignatures = "protected @android.annotation.NonNull java.lang.String name\nprotected @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringSet.class) java.util.Set<java.lang.String> deniedPermissions\nprotected @android.annotation.Nullable java.lang.Boolean enableGwpAsan\npublic  void addStateFrom(android.content.pm.parsing.component.ParsedProcess)\nclass ParsedProcess extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java b/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java
index 4825066..3820790 100644
--- a/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java
+++ b/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java
@@ -103,6 +103,11 @@
             if (proc.name == null || proc.name.length() <= 0) {
                 return input.error("<process> does not specify android:process");
             }
+
+            if (sa.hasValue(R.styleable.AndroidManifestProcess_enableGwpAsan)) {
+                proc.enableGwpAsan =
+                        sa.getBoolean(R.styleable.AndroidManifestProcess_enableGwpAsan, false);
+            }
         } finally {
             sa.recycle();
         }
diff --git a/core/java/android/provider/BlockedNumberContract.java b/core/java/android/provider/BlockedNumberContract.java
index 1eb7664..dd2ea81 100644
--- a/core/java/android/provider/BlockedNumberContract.java
+++ b/core/java/android/provider/BlockedNumberContract.java
@@ -16,7 +16,6 @@
 package android.provider;
 
 import android.annotation.IntDef;
-import android.annotation.SystemApi;
 import android.annotation.WorkerThread;
 import android.content.Context;
 import android.net.Uri;
@@ -240,7 +239,6 @@
      * blocked.
      * @hide
      */
-    @SystemApi
     public static final int STATUS_NOT_BLOCKED = 0;
 
     /**
@@ -248,7 +246,6 @@
      * because it is in the list of blocked numbers maintained by the provider.
      * @hide
      */
-    @SystemApi
     public static final int STATUS_BLOCKED_IN_LIST = 1;
 
     /**
@@ -256,7 +253,6 @@
      * because it is from a restricted number.
      * @hide
      */
-    @SystemApi
     public static final int STATUS_BLOCKED_RESTRICTED = 2;
 
     /**
@@ -264,7 +260,6 @@
      * because it is from an unknown number.
      * @hide
      */
-    @SystemApi
     public static final int STATUS_BLOCKED_UNKNOWN_NUMBER = 3;
 
     /**
@@ -272,7 +267,6 @@
      * because it is from a pay phone.
      * @hide
      */
-    @SystemApi
     public static final int STATUS_BLOCKED_PAYPHONE = 4;
 
     /**
@@ -280,14 +274,12 @@
      * because it is from a number not in the users contacts.
      * @hide
      */
-    @SystemApi
     public static final int STATUS_BLOCKED_NOT_IN_CONTACTS = 5;
 
     /**
      * Integer reason indicating whether a call was blocked, and if so why.
      * @hide
      */
-    @SystemApi
     public static final String RES_BLOCK_STATUS = "block_status";
 
     /** @hide */
@@ -298,31 +290,6 @@
             "can_current_user_block_numbers";
 
     /** @hide */
-    @SystemApi
-    public static final String METHOD_NOTIFY_EMERGENCY_CONTACT = "notify_emergency_contact";
-
-    /** @hide */
-    public static final String METHOD_END_BLOCK_SUPPRESSION = "end_block_suppression";
-
-    /** @hide */
-    @SystemApi
-    public static final String METHOD_SHOULD_SYSTEM_BLOCK_NUMBER = "should_system_block_number";
-
-    /** @hide */
-    public static final String METHOD_GET_BLOCK_SUPPRESSION_STATUS =
-            "get_block_suppression_status";
-
-    /** @hide */
-    public static final String METHOD_SHOULD_SHOW_EMERGENCY_CALL_NOTIFICATION =
-            "should_show_emergency_call_notification";
-
-    /** @hide */
-    public static final String METHOD_GET_ENHANCED_BLOCK_SETTING = "get_enhanced_block_setting";
-
-    /** @hide */
-    public static final String METHOD_SET_ENHANCED_BLOCK_SETTING = "set_enhanced_block_setting";
-
-    /** @hide */
     public static final String RES_CAN_BLOCK_NUMBERS = "can_block";
 
     /** @hide */
@@ -439,11 +406,26 @@
         public static final String ACTION_BLOCK_SUPPRESSION_STATE_CHANGED =
                 "android.provider.action.BLOCK_SUPPRESSION_STATE_CHANGED";
 
+        public static final String METHOD_NOTIFY_EMERGENCY_CONTACT = "notify_emergency_contact";
+
+        public static final String METHOD_END_BLOCK_SUPPRESSION = "end_block_suppression";
+
+        public static final String METHOD_SHOULD_SYSTEM_BLOCK_NUMBER = "should_system_block_number";
+
+        public static final String METHOD_GET_BLOCK_SUPPRESSION_STATUS =
+                "get_block_suppression_status";
+
+        public static final String METHOD_SHOULD_SHOW_EMERGENCY_CALL_NOTIFICATION =
+                "should_show_emergency_call_notification";
+
         public static final String RES_IS_BLOCKING_SUPPRESSED = "blocking_suppressed";
 
         public static final String RES_BLOCKING_SUPPRESSED_UNTIL_TIMESTAMP =
                 "blocking_suppressed_until_timestamp";
 
+        public static final String METHOD_GET_ENHANCED_BLOCK_SETTING = "get_enhanced_block_setting";
+        public static final String METHOD_SET_ENHANCED_BLOCK_SETTING = "set_enhanced_block_setting";
+
         /* Preference key of block numbers not in contacts setting. */
         public static final String ENHANCED_SETTING_KEY_BLOCK_UNREGISTERED =
                 "block_numbers_not_in_contacts_setting";
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index bf3c088..f531e12 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -124,8 +124,6 @@
     private static final int MSG_REQUEST_WALLPAPER_COLORS = 10050;
     private static final int MSG_SCALE = 10100;
 
-    private static final float MAX_SCALE = 1.15f;
-
     private static final int NOTIFY_COLORS_RATE_LIMIT_MS = 1000;
 
     private final ArrayList<Engine> mActiveEngines
@@ -351,7 +349,7 @@
 
             @Override
             public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
-                    boolean sync) {
+                    float zoom, boolean sync) {
                 synchronized (mLock) {
                     if (DEBUG) Log.v(TAG, "Dispatch wallpaper offsets: " + x + ", " + y);
                     mPendingXOffset = x;
@@ -366,6 +364,8 @@
                         Message msg = mCaller.obtainMessage(MSG_WALLPAPER_OFFSETS);
                         mCaller.sendMessage(msg);
                     }
+                    Message msg = mCaller.obtainMessageI(MSG_SCALE, Float.floatToIntBits(zoom));
+                    mCaller.sendMessage(msg);
                 }
             }
 
@@ -462,6 +462,18 @@
         }
 
         /**
+         * This will be called when the wallpaper is first started. If true is returned, the system
+         * will zoom in the wallpaper by default and zoom it out as the user interacts,
+         * to create depth. Otherwise, zoom will have to be handled manually
+         * in {@link #onZoomChanged(float)}.
+         *
+         * @hide
+         */
+        public boolean shouldZoomOutWallpaper() {
+            return false;
+        }
+
+        /**
          * Control whether this wallpaper will receive raw touch events
          * from the window manager as the user interacts with the window
          * that is currently displaying the wallpaper.  By default they
@@ -870,6 +882,7 @@
                             Log.w(TAG, "Failed to add window while updating wallpaper surface.");
                             return;
                         }
+                        mSession.setShouldZoomOutWallpaper(mWindow, shouldZoomOutWallpaper());
                         mCreated = true;
 
                         mInputEventReceiver = new WallpaperInputEventReceiver(
@@ -964,7 +977,6 @@
                                     c.surfaceCreated(mSurfaceHolder);
                                 }
                             }
-                            onZoomChanged(0f);
                         }
 
                         redrawNeeded |= creating || (relayoutResult
@@ -1125,7 +1137,6 @@
                 mIsInAmbientMode = inAmbientMode;
                 if (mCreated) {
                     onAmbientModeChanged(inAmbientMode, animationDuration);
-                    setZoom(0);
                 }
             }
         }
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 3927ebf..9f2d36d 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -102,9 +102,9 @@
     void closeSystemDialogs(String reason);
 
     /**
-     * Called for wallpaper windows when their offsets change.
+     * Called for wallpaper windows when their offsets or zoom level change.
      */
-    void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep, boolean sync);
+    void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep, float zoom, boolean sync);
 
     void dispatchWallpaperCommand(String action, int x, int y,
             int z, in Bundle extras, boolean sync);
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 91000a9..dfe89a3 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -221,6 +221,19 @@
      */
     void setWallpaperPosition(IBinder windowToken, float x, float y, float xstep, float ystep);
 
+    /**
+     * For wallpaper windows, sets the scale of the wallpaper based on
+     * SystemUI behavior.
+     */
+    void setWallpaperZoomOut(IBinder windowToken, float scale);
+
+    /**
+     * For wallpaper windows, sets whether the wallpaper should actually be
+     * scaled when setWallpaperZoomOut is called. If set to false, the WallpaperService will
+     * receive the zoom out value but the surface won't be scaled.
+     */
+    void setShouldZoomOutWallpaper(IBinder windowToken, boolean shouldZoom);
+
     @UnsupportedAppUsage
     void wallpaperOffsetsComplete(IBinder window);
 
diff --git a/core/java/android/view/InsetsAnimationControlCallbacks.java b/core/java/android/view/InsetsAnimationControlCallbacks.java
index 5d5edec..a15d6c7 100644
--- a/core/java/android/view/InsetsAnimationControlCallbacks.java
+++ b/core/java/android/view/InsetsAnimationControlCallbacks.java
@@ -16,7 +16,6 @@
 
 package android.view;
 
-import android.view.InsetsController.LayoutInsetsDuringAnimation;
 import android.view.WindowInsetsAnimation.Bounds;
 
 /**
@@ -37,7 +36,7 @@
     void startAnimation(InsetsAnimationControlImpl controller,
             WindowInsetsAnimationControlListener listener, int types,
             WindowInsetsAnimation animation,
-            Bounds bounds, @LayoutInsetsDuringAnimation int layoutDuringAnimation);
+            Bounds bounds);
 
     /**
      * Schedule the apply by posting the animation callback.
@@ -46,10 +45,10 @@
 
     /**
      * Finish the final steps after the animation.
-     * @param controller The controller used to control the animation.
+     * @param runner The runner used to run the animation.
      * @param shown {@code true} if the insets are shown.
      */
-    void notifyFinished(InsetsAnimationControlImpl controller, boolean shown);
+    void notifyFinished(InsetsAnimationControlRunner runner, boolean shown);
 
     /**
      * Apply the new params to the surface.
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index ae509f3..2b30c2d 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -31,9 +31,7 @@
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.util.SparseSetArray;
-import android.view.InsetsController.LayoutInsetsDuringAnimation;
 import android.view.InsetsState.InternalInsetsSide;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
 import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowInsetsAnimation.Bounds;
@@ -49,7 +47,8 @@
  * @hide
  */
 @VisibleForTesting
-public class InsetsAnimationControlImpl implements WindowInsetsAnimationController  {
+public class InsetsAnimationControlImpl implements WindowInsetsAnimationController,
+        InsetsAnimationControlRunner {
 
     private final Rect mTmpFrame = new Rect();
 
@@ -84,8 +83,7 @@
             InsetsState state, WindowInsetsAnimationControlListener listener,
             @InsetsType int types,
             InsetsAnimationControlCallbacks controller, long durationMs, Interpolator interpolator,
-            boolean fade, @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
-            @AnimationType int animationType) {
+            boolean fade, @AnimationType int animationType) {
         mControls = controls;
         mListener = listener;
         mTypes = types;
@@ -105,7 +103,7 @@
         mAnimation.setAlpha(getCurrentAlpha());
         mAnimationType = animationType;
         mController.startAnimation(this, listener, types, mAnimation,
-                new Bounds(mHiddenInsets, mShownInsets), layoutInsetsDuringAnimation);
+                new Bounds(mHiddenInsets, mShownInsets));
     }
 
     @Override
@@ -133,11 +131,8 @@
         return mTypes;
     }
 
-    boolean controlsInternalType(@InternalInsetsType int type) {
-        return InsetsState.toInternalType(mTypes).contains(type);
-    }
-
-    @AnimationType int getAnimationType() {
+    @Override
+    public @AnimationType int getAnimationType() {
         return mAnimationType;
     }
 
@@ -205,7 +200,8 @@
         return mAnimation.getFraction();
     }
 
-    public void onCancelled() {
+    @Override
+    public void cancel() {
         if (mFinished) {
             return;
         }
@@ -217,7 +213,8 @@
         return mCancelled;
     }
 
-    WindowInsetsAnimation getAnimation() {
+    @Override
+    public WindowInsetsAnimation getAnimation() {
         return mAnimation;
     }
 
@@ -225,6 +222,10 @@
         return mListener;
     }
 
+    SparseArray<InsetsSourceControl> getControls() {
+        return mControls;
+    }
+
     private Insets calculateInsets(InsetsState state, Rect frame,
             SparseArray<InsetsSourceControl> controls, boolean shown,
             @Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
diff --git a/core/java/android/view/InsetsAnimationControlRunner.java b/core/java/android/view/InsetsAnimationControlRunner.java
new file mode 100644
index 0000000..0711c3e
--- /dev/null
+++ b/core/java/android/view/InsetsAnimationControlRunner.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.view.InsetsController.AnimationType;
+import android.view.InsetsState.InternalInsetsType;
+import android.view.WindowInsets.Type.InsetsType;
+
+/**
+ * Interface representing a runner for an insets animation.
+ *
+ * @hide
+ */
+public interface InsetsAnimationControlRunner {
+
+    /**
+     * @return The {@link InsetsType} the animation of this runner is controlling.
+     */
+    @InsetsType int getTypes();
+
+    /**
+     * Cancels the animation.
+     */
+    void cancel();
+
+    /**
+     * @return The animation this runner is running.
+     */
+    WindowInsetsAnimation getAnimation();
+
+    /**
+     * @return Whether {@link #getTypes()} maps to a specific {@link InternalInsetsType}.
+     */
+    default boolean controlsInternalType(@InternalInsetsType int type) {
+        return InsetsState.toInternalType(getTypes()).contains(type);
+    }
+
+    /**
+     * @return The animation type this runner is running.
+     */
+    @AnimationType int getAnimationType();
+}
diff --git a/core/java/android/view/InsetsAnimationThread.java b/core/java/android/view/InsetsAnimationThread.java
new file mode 100644
index 0000000..cdf9733
--- /dev/null
+++ b/core/java/android/view/InsetsAnimationThread.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Trace;
+
+/**
+ * Thread to be used for inset animations to be running off the main thread.
+ * @hide
+ */
+public class InsetsAnimationThread extends HandlerThread {
+
+    private static InsetsAnimationThread sInstance;
+    private static Handler sHandler;
+
+    private InsetsAnimationThread() {
+        // TODO: Should this use higher priority?
+        super("InsetsAnimations");
+    }
+
+    private static void ensureThreadLocked() {
+        if (sInstance == null) {
+            sInstance = new InsetsAnimationThread();
+            sInstance.start();
+            sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_VIEW);
+            sHandler = new Handler(sInstance.getLooper());
+        }
+    }
+
+    public static void release() {
+        synchronized (InsetsAnimationThread.class) {
+            if (sInstance == null) {
+                return;
+            }
+            sInstance.getLooper().quitSafely();
+            sInstance = null;
+            sHandler = null;
+        }
+    }
+
+    public static InsetsAnimationThread get() {
+        synchronized (InsetsAnimationThread.class) {
+            ensureThreadLocked();
+            return sInstance;
+        }
+    }
+
+    public static Handler getHandler() {
+        synchronized (InsetsAnimationThread.class) {
+            ensureThreadLocked();
+            return sHandler;
+        }
+    }
+}
diff --git a/core/java/android/view/InsetsAnimationThreadControlRunner.java b/core/java/android/view/InsetsAnimationThreadControlRunner.java
new file mode 100644
index 0000000..9c27802
--- /dev/null
+++ b/core/java/android/view/InsetsAnimationThreadControlRunner.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import static android.view.SyncRtSurfaceTransactionApplier.applyParams;
+
+import android.annotation.UiThread;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.util.SparseArray;
+import android.view.InsetsController.AnimationType;
+import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
+import android.view.WindowInsets.Type.InsetsType;
+import android.view.WindowInsetsAnimation.Bounds;
+import android.view.animation.Interpolator;
+
+/**
+ * Insets animation runner that uses {@link InsetsAnimationThread} to run the animation off from the
+ * main thread.
+ *
+ * @hide
+ */
+public class InsetsAnimationThreadControlRunner implements InsetsAnimationControlRunner {
+
+    private final InsetsAnimationControlImpl mControl;
+    private final InsetsAnimationControlCallbacks mOuterCallbacks;
+    private final Handler mMainThreadHandler;
+    private final InsetsState mState = new InsetsState();
+    private final InsetsAnimationControlCallbacks mCallbacks =
+            new InsetsAnimationControlCallbacks() {
+
+        private final float[] mTmpFloat9 = new float[9];
+
+        @Override
+        @UiThread
+        public void startAnimation(InsetsAnimationControlImpl controller,
+                WindowInsetsAnimationControlListener listener, int types,
+                WindowInsetsAnimation animation, Bounds bounds) {
+            // Animation will be started in constructor already.
+        }
+
+        @Override
+        public void scheduleApplyChangeInsets() {
+            mControl.applyChangeInsets(mState);
+        }
+
+        @Override
+        public void notifyFinished(InsetsAnimationControlRunner runner, boolean shown) {
+            releaseControls(mControl.getControls());
+            mMainThreadHandler.post(() ->
+                    mOuterCallbacks.notifyFinished(InsetsAnimationThreadControlRunner.this, shown));
+        }
+
+        @Override
+        public void applySurfaceParams(SurfaceParams... params) {
+            SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+            for (int i = params.length - 1; i >= 0; i--) {
+                SyncRtSurfaceTransactionApplier.SurfaceParams surfaceParams = params[i];
+                applyParams(t, surfaceParams, mTmpFloat9);
+            }
+            t.apply();
+            t.close();
+        }
+    };
+
+    @UiThread
+    public InsetsAnimationThreadControlRunner(SparseArray<InsetsSourceControl> controls, Rect frame,
+            InsetsState state, WindowInsetsAnimationControlListener listener,
+            @InsetsType int types,
+            InsetsAnimationControlCallbacks controller, long durationMs, Interpolator interpolator,
+            boolean fade, @AnimationType int animationType, Handler mainThreadHandler) {
+        mMainThreadHandler = mainThreadHandler;
+        mOuterCallbacks = controller;
+        mControl = new InsetsAnimationControlImpl(copyControls(controls), frame, state, listener,
+                types, mCallbacks, durationMs, interpolator, fade, animationType);
+        InsetsAnimationThread.getHandler().post(() -> listener.onReady(mControl, types));
+    }
+
+    private void releaseControls(SparseArray<InsetsSourceControl> controls) {
+        for (int i = controls.size() - 1; i >= 0; i--) {
+            controls.valueAt(i).release(SurfaceControl::release);
+        }
+    }
+
+    private SparseArray<InsetsSourceControl> copyControls(
+            SparseArray<InsetsSourceControl> controls) {
+        SparseArray<InsetsSourceControl> copy = new SparseArray<>(controls.size());
+        for (int i = 0; i < controls.size(); i++) {
+            copy.append(controls.keyAt(i), new InsetsSourceControl(controls.valueAt(i)));
+        }
+        return copy;
+    }
+
+    @Override
+    @UiThread
+    public int getTypes() {
+        return mControl.getTypes();
+    }
+
+    @Override
+    @UiThread
+    public void cancel() {
+        InsetsAnimationThread.getHandler().post(mControl::cancel);
+    }
+
+    @Override
+    @UiThread
+    public WindowInsetsAnimation getAnimation() {
+        return mControl.getAnimation();
+    }
+
+    @Override
+    public int getAnimationType() {
+        return mControl.getAnimationType();
+    }
+}
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 607886f..c1763d6 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -23,6 +23,7 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APPEARANCE_CONTROLLED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
 
+import android.animation.AnimationHandler;
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
@@ -53,6 +54,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
+import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -167,10 +169,22 @@
 
         private WindowInsetsAnimationController mController;
         private ObjectAnimator mAnimator;
-        protected boolean mShow;
+        private final boolean mShow;
+        private final boolean mUseSfVsync;
 
-        public InternalAnimationControlListener(boolean show) {
+        private ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal =
+                new ThreadLocal<AnimationHandler>() {
+            @Override
+            protected AnimationHandler initialValue() {
+                AnimationHandler handler = new AnimationHandler();
+                handler.setProvider(new SfVsyncFrameCallbackProvider());
+                return handler;
+            }
+        };
+
+        public InternalAnimationControlListener(boolean show, boolean useSfVsync) {
             mShow = show;
+            mUseSfVsync = useSfVsync;
         }
 
         @Override
@@ -193,6 +207,9 @@
                     onAnimationFinish();
                 }
             });
+            if (mUseSfVsync) {
+                mAnimator.setAnimationHandler(mSfAnimationHandlerThreadLocal.get());
+            }
             mAnimator.start();
         }
 
@@ -228,12 +245,12 @@
      */
     private static class RunningAnimation {
 
-        RunningAnimation(InsetsAnimationControlImpl control, int type) {
-            this.control = control;
+        RunningAnimation(InsetsAnimationControlRunner runner, int type) {
+            this.runner = runner;
             this.type = type;
         }
 
-        final InsetsAnimationControlImpl control;
+        final InsetsAnimationControlRunner runner;
         final @AnimationType int type;
 
         /**
@@ -252,7 +269,7 @@
         PendingControlRequest(@InsetsType int types, WindowInsetsAnimationControlListener listener,
                 long durationMs, Interpolator interpolator, @AnimationType int animationType,
                 @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
-                CancellationSignal cancellationSignal) {
+                CancellationSignal cancellationSignal, boolean useInsetsAnimationThread) {
             this.types = types;
             this.listener = listener;
             this.durationMs = durationMs;
@@ -260,6 +277,7 @@
             this.animationType = animationType;
             this.layoutInsetsDuringAnimation = layoutInsetsDuringAnimation;
             this.cancellationSignal = cancellationSignal;
+            this.useInsetsAnimationThread = useInsetsAnimationThread;
         }
 
         final @InsetsType int types;
@@ -269,6 +287,7 @@
         final @AnimationType int animationType;
         final @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation;
         final CancellationSignal cancellationSignal;
+        final boolean useInsetsAnimationThread;
     }
 
     private final String TAG = "InsetsControllerImpl";
@@ -347,15 +366,20 @@
             InsetsState state = new InsetsState(mState, true /* copySources */);
             for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
                 RunningAnimation runningAnimation = mRunningAnimations.get(i);
-                InsetsAnimationControlImpl control = runningAnimation.control;
+                InsetsAnimationControlRunner runner = runningAnimation.runner;
+                if (runner instanceof InsetsAnimationControlImpl) {
+                    InsetsAnimationControlImpl control = (InsetsAnimationControlImpl) runner;
 
-                // Keep track of running animation to be dispatched. Aggregate it here such that if
-                // it gets finished within applyChangeInsets we still dispatch it to onProgress.
-                if (runningAnimation.startDispatched) {
-                    mTmpRunningAnims.add(control.getAnimation());
-                }
-                if (control.applyChangeInsets(state)) {
-                    mTmpFinishedControls.add(control);
+                    // Keep track of running animation to be dispatched. Aggregate it here such that
+                    // if it gets finished within applyChangeInsets we still dispatch it to
+                    // onProgress.
+                    if (runningAnimation.startDispatched) {
+                        mTmpRunningAnims.add(control.getAnimation());
+                    }
+
+                    if (control.applyChangeInsets(state)) {
+                        mTmpFinishedControls.add(control);
+                    }
                 }
             }
 
@@ -499,7 +523,8 @@
                     pendingRequest.listener, mFrame,
                     true /* fromIme */, pendingRequest.durationMs, pendingRequest.interpolator,
                     false /* fade */, pendingRequest.animationType,
-                    pendingRequest.layoutInsetsDuringAnimation);
+                    pendingRequest.layoutInsetsDuringAnimation,
+                    pendingRequest.useInsetsAnimationThread);
             pendingRequest.cancellationSignal.setOnCancelListener(cancellationSignal::cancel);
             return;
         }
@@ -563,7 +588,8 @@
             return cancellationSignal;
         }
         return controlAnimationUnchecked(types, listener, mFrame, fromIme, durationMs, interpolator,
-                false /* fade */, animationType, getLayoutInsetsDuringAnimationMode(types));
+                false /* fade */, animationType, getLayoutInsetsDuringAnimationMode(types),
+                false /* useInsetsAnimationThread */);
     }
 
     private boolean checkDisplayFramesForControlling() {
@@ -577,7 +603,8 @@
             WindowInsetsAnimationControlListener listener, Rect frame, boolean fromIme,
             long durationMs, Interpolator interpolator, boolean fade,
             @AnimationType int animationType,
-            @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation) {
+            @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
+            boolean useInsetsAnimationThread) {
         CancellationSignal cancellationSignal = new CancellationSignal();
         if (types == 0) {
             // nothing to animate.
@@ -600,7 +627,8 @@
             abortPendingImeControlRequest();
             final PendingControlRequest request = new PendingControlRequest(types,
                     listener, durationMs,
-                    interpolator, animationType, layoutInsetsDuringAnimation, cancellationSignal);
+                    interpolator, animationType, layoutInsetsDuringAnimation, cancellationSignal,
+                    useInsetsAnimationThread);
             mPendingImeControlRequest = request;
             mHandler.postDelayed(mPendingControlTimeout, PENDING_CONTROL_TIMEOUT_MS);
             cancellationSignal.setOnCancelListener(() -> {
@@ -617,11 +645,21 @@
             return cancellationSignal;
         }
 
-        final InsetsAnimationControlImpl controller = new InsetsAnimationControlImpl(controls,
-                frame, mState, listener, typesReady, this, durationMs, interpolator, fade,
-                layoutInsetsDuringAnimation, animationType);
-        mRunningAnimations.add(new RunningAnimation(controller, animationType));
-        cancellationSignal.setOnCancelListener(controller::onCancelled);
+
+        final InsetsAnimationControlRunner runner = useInsetsAnimationThread
+                ? new InsetsAnimationThreadControlRunner(controls,
+                        frame, mState, listener, typesReady, this, durationMs, interpolator, fade,
+                        animationType, mViewRoot.mHandler)
+                : new InsetsAnimationControlImpl(controls,
+                        frame, mState, listener, typesReady, this, durationMs, interpolator, fade,
+                        animationType);
+        mRunningAnimations.add(new RunningAnimation(runner, animationType));
+        cancellationSignal.setOnCancelListener(runner::cancel);
+        if (layoutInsetsDuringAnimation == LAYOUT_INSETS_DURING_ANIMATION_SHOWN) {
+            showDirectly(types);
+        } else {
+            hideDirectly(types, false /* animationFinished */, animationType);
+        }
         return cancellationSignal;
     }
 
@@ -705,7 +743,7 @@
 
     private void cancelExistingControllers(@InsetsType int types) {
         for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
-            InsetsAnimationControlImpl control = mRunningAnimations.get(i).control;
+            InsetsAnimationControlRunner control = mRunningAnimations.get(i).runner;
             if ((control.getTypes() & types) != 0) {
                 cancelAnimation(control, true /* invokeCallback */);
             }
@@ -725,13 +763,13 @@
 
     @VisibleForTesting
     @Override
-    public void notifyFinished(InsetsAnimationControlImpl controller, boolean shown) {
-        cancelAnimation(controller, false /* invokeCallback */);
+    public void notifyFinished(InsetsAnimationControlRunner runner, boolean shown) {
+        cancelAnimation(runner, false /* invokeCallback */);
         if (shown) {
-            showDirectly(controller.getTypes());
+            showDirectly(runner.getTypes());
         } else {
-            hideDirectly(controller.getTypes(), true /* animationFinished */,
-                    controller.getAnimationType());
+            hideDirectly(runner.getTypes(), true /* animationFinished */,
+                    runner.getAnimationType());
         }
     }
 
@@ -756,7 +794,7 @@
 
     void notifyControlRevoked(InsetsSourceConsumer consumer) {
         for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
-            InsetsAnimationControlImpl control = mRunningAnimations.get(i).control;
+            InsetsAnimationControlRunner control = mRunningAnimations.get(i).runner;
             if ((control.getTypes() & toPublicType(consumer.getType())) != 0) {
                 cancelAnimation(control, true /* invokeCallback */);
             }
@@ -766,12 +804,12 @@
         }
     }
 
-    private void cancelAnimation(InsetsAnimationControlImpl control, boolean invokeCallback) {
+    private void cancelAnimation(InsetsAnimationControlRunner control, boolean invokeCallback) {
         if (invokeCallback) {
-            control.onCancelled();
+            control.cancel();
         }
         for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
-            if (mRunningAnimations.get(i).control == control) {
+            if (mRunningAnimations.get(i).runner == control) {
                 mRunningAnimations.remove(i);
                 break;
             }
@@ -844,7 +882,7 @@
     @VisibleForTesting
     public @AnimationType int getAnimationType(@InternalInsetsType int type) {
         for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
-            InsetsAnimationControlImpl control = mRunningAnimations.get(i).control;
+            InsetsAnimationControlRunner control = mRunningAnimations.get(i).runner;
             if (control.controlsInternalType(type)) {
                 return mRunningAnimations.get(i).type;
             }
@@ -878,15 +916,24 @@
             return;
         }
 
+        boolean useInsetsAnimationThread = canUseInsetsAnimationThread();
         final InternalAnimationControlListener listener =
-                new InternalAnimationControlListener(show);
+                new InternalAnimationControlListener(show, useInsetsAnimationThread);
         // Show/hide animations always need to be relative to the display frame, in order that shown
         // and hidden state insets are correct.
         controlAnimationUnchecked(
                 types, listener, mState.getDisplayFrame(), fromIme, listener.getDurationMs(),
                 INTERPOLATOR, true /* fade */, show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE,
                 show ? LAYOUT_INSETS_DURING_ANIMATION_SHOWN
-                        : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN);
+                        : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN,
+                useInsetsAnimationThread);
+    }
+
+    private boolean canUseInsetsAnimationThread() {
+        if (mViewRoot.mView == null) {
+            return true;
+        }
+        return !mViewRoot.mView.hasWindowInsetsAnimationCallback();
     }
 
     private void hideDirectly(
@@ -921,13 +968,7 @@
     @Override
     public void startAnimation(InsetsAnimationControlImpl controller,
             WindowInsetsAnimationControlListener listener, int types,
-            WindowInsetsAnimation animation, Bounds bounds, int layoutDuringAnimation) {
-        if (layoutDuringAnimation == LAYOUT_INSETS_DURING_ANIMATION_SHOWN) {
-            showDirectly(types);
-        } else {
-            hideDirectly(types, false /* animationFinished */, controller.getAnimationType());
-        }
-
+            WindowInsetsAnimation animation, Bounds bounds) {
         if (mViewRoot.mView == null) {
             return;
         }
@@ -941,7 +982,7 @@
                 }
                 for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
                     RunningAnimation runningAnimation = mRunningAnimations.get(i);
-                    if (runningAnimation.control == controller) {
+                    if (runningAnimation.runner == controller) {
                         runningAnimation.startDispatched = true;
                     }
                 }
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 252fc0c..3325734 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -117,7 +117,7 @@
             }
         }
         if (lastControl != null) {
-            lastControl.release(mController);
+            lastControl.release(mController::releaseSurfaceControlFromRt);
         }
     }
 
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
index 75f6eab..f3ec65f 100644
--- a/core/java/android/view/InsetsSourceControl.java
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -22,6 +22,8 @@
 import android.os.Parcelable;
 import android.view.InsetsState.InternalInsetsType;
 
+import java.util.function.Consumer;
+
 /**
  * Represents a parcelable object to allow controlling a single {@link InsetsSource}.
  * @hide
@@ -94,9 +96,9 @@
         dest.writeParcelable(mSurfacePosition, 0 /* flags*/);
     }
 
-    public void release(InsetsController controller) {
+    public void release(Consumer<SurfaceControl> surfaceReleaseConsumer) {
         if (mLeash != null) {
-            controller.releaseSurfaceControlFromRt(mLeash);
+            surfaceReleaseConsumer.accept(mLeash);
         }
     }
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6236e6e..879f284 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -11227,6 +11227,15 @@
     }
 
     /**
+     * @return {@code true} if any {@link WindowInsetsAnimation.Callback} is registered on the view
+     *         or view tree of the sub-hierarchy {@code false} otherwise.
+     * @hide
+     */
+    public boolean hasWindowInsetsAnimationCallback() {
+        return getListenerInfo().mWindowInsetsAnimationCallback != null;
+    }
+
+    /**
      * Dispatches {@link WindowInsetsAnimation.Callback#onPrepare(WindowInsetsAnimation)}
      * when Window Insets animation is being prepared.
      * @param animation current animation
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 7d4ec3d..e34e84c 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -7258,6 +7258,34 @@
                 : DISPATCH_MODE_CONTINUE_ON_SUBTREE;
     }
 
+    /**
+     * @hide
+     */
+    @Override
+    public boolean hasWindowInsetsAnimationCallback() {
+        if (super.hasWindowInsetsAnimationCallback()) {
+            return true;
+        }
+
+        // If we are root-level content view that fits insets, we imitate consuming behavior, so
+        // no child will retrieve window insets animation callback.
+        // See dispatchWindowInsetsAnimationPrepare.
+        boolean isOptionalFitSystemWindows = (mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) != 0
+                || isFrameworkOptionalFitsSystemWindows();
+        if (isOptionalFitSystemWindows && mAttachInfo != null
+                && mAttachInfo.mContentOnApplyWindowInsetsListener != null) {
+            return false;
+        }
+
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            if (getChildAt(i).hasWindowInsetsAnimationCallback()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     @Override
     public void dispatchWindowInsetsAnimationPrepare(
             @NonNull WindowInsetsAnimation animation) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9e5298b..26ac4fc 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -9054,7 +9054,7 @@
 
         @Override
         public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
-                boolean sync) {
+                float zoom, boolean sync) {
             if (sync) {
                 try {
                     mWindowSession.wallpaperOffsetsComplete(asBinder());
diff --git a/core/java/android/view/WindowContainerTransaction.java b/core/java/android/view/WindowContainerTransaction.java
index e05c374..9c16e13 100644
--- a/core/java/android/view/WindowContainerTransaction.java
+++ b/core/java/android/view/WindowContainerTransaction.java
@@ -131,6 +131,31 @@
     }
 
     /**
+     * Set the windowing mode of children of a given root task, without changing
+     * the windowing mode of the Task itself. This can be used during transitions
+     * for example to make the activity render it's fullscreen configuration
+     * while the Task is still in PIP, so you can complete the animation.
+     *
+     * TODO(b/134365562): Can be removed once TaskOrg drives full-screen
+     */
+    public WindowContainerTransaction setActivityWindowingMode(IWindowContainer container,
+            int windowingMode) {
+        Change chg = getOrCreateChange(container.asBinder());
+        chg.mActivityWindowingMode = windowingMode;
+        return this;
+    }
+
+    /**
+     * Sets the windowing mode of the given container.
+     */
+    public WindowContainerTransaction setWindowingMode(IWindowContainer container,
+            int windowingMode) {
+        Change chg = getOrCreateChange(container.asBinder());
+        chg.mWindowingMode = windowingMode;
+        return this;
+    }
+
+    /**
      * Sets whether a container or any of its children can be focusable. When {@code false}, no
      * child can be focused; however, when {@code true}, it is still possible for children to be
      * non-focusable due to WM policy.
@@ -235,6 +260,9 @@
         private Rect mPinnedBounds = null;
         private SurfaceControl.Transaction mBoundsChangeTransaction = null;
 
+        private int mActivityWindowingMode = -1;
+        private int mWindowingMode = -1;
+
         public Change() {}
 
         protected Change(Parcel in) {
@@ -251,6 +279,17 @@
                 mBoundsChangeTransaction =
                     SurfaceControl.Transaction.CREATOR.createFromParcel(in);
             }
+
+            mWindowingMode = in.readInt();
+            mActivityWindowingMode = in.readInt();
+        }
+
+        public int getWindowingMode() {
+            return mWindowingMode;
+        }
+
+        public int getActivityWindowingMode() {
+            return mActivityWindowingMode;
         }
 
         public Configuration getConfiguration() {
@@ -340,6 +379,9 @@
             if (mBoundsChangeTransaction != null) {
                 mBoundsChangeTransaction.writeToParcel(dest, flags);
             }
+
+            dest.writeInt(mWindowingMode);
+            dest.writeInt(mActivityWindowingMode);
         }
 
         @Override
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 01a1c77..410d9af 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -504,6 +504,7 @@
     }
 
     void doRemoveView(ViewRootImpl root) {
+        boolean allViewsRemoved;
         synchronized (mLock) {
             final int index = mRoots.indexOf(root);
             if (index >= 0) {
@@ -512,10 +513,17 @@
                 final View view = mViews.remove(index);
                 mDyingViews.remove(view);
             }
+            allViewsRemoved = mRoots.isEmpty();
         }
         if (ThreadedRenderer.sTrimForeground && ThreadedRenderer.isAvailable()) {
             doTrimForeground();
         }
+
+        // If we don't have any views anymore in our process, we no longer need the
+        // InsetsAnimationThread to save some resources.
+        if (allViewsRemoved) {
+            InsetsAnimationThread.release();
+        }
     }
 
     private int findViewLocked(View view, boolean required) {
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 87dcba0..144f8e3 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -312,6 +312,14 @@
     }
 
     @Override
+    public void setWallpaperZoomOut(android.os.IBinder windowToken, float zoom) {
+    }
+
+    @Override
+    public void setShouldZoomOutWallpaper(android.os.IBinder windowToken, boolean shouldZoom) {
+    }
+
+    @Override
     public void wallpaperOffsetsComplete(android.os.IBinder window) {
     }
 
diff --git a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
index e50da40..8e8c7df 100644
--- a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
+++ b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
@@ -44,15 +44,15 @@
     public static final int SUGGESTION_COUNT_UNLIMITED = Integer.MAX_VALUE;
 
     /**
-     * Max number of suggestions expected from the response. Defaults to {@code
-     * SUGGESTION_COUNT_UNLIMITED} if not set.
+     * Max number of suggestions expected from the response. It must be a positive value.
+     * Defaults to {@code SUGGESTION_COUNT_UNLIMITED} if not set.
      */
     private final int mMaxSuggestionCount;
 
     /**
      * The {@link InlinePresentationSpec} for each suggestion in the response. If the max suggestion
      * count is larger than the number of specs in the list, then the last spec is used for the
-     * remainder of the suggestions.
+     * remainder of the suggestions. The list should not be empty.
      */
     private final @NonNull List<InlinePresentationSpec> mPresentationSpecs;
 
@@ -72,6 +72,7 @@
     /**
      * The extras state propagated from the IME to pass extra data.
      */
+    @DataClass.MaySetToNull
     private @Nullable Bundle mExtras;
 
     /**
@@ -80,6 +81,7 @@
      *
      * @hide
      */
+    @DataClass.MaySetToNull
     private @Nullable IBinder mHostInputToken;
 
     /**
@@ -117,6 +119,7 @@
     }
 
     private void onConstructed() {
+        Preconditions.checkState(!mPresentationSpecs.isEmpty());
         Preconditions.checkState(mMaxSuggestionCount >= mPresentationSpecs.size());
     }
 
@@ -162,7 +165,7 @@
 
 
 
-    // Code below generated by codegen v1.0.14.
+    // Code below generated by codegen v1.0.15.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -202,8 +205,8 @@
     }
 
     /**
-     * Max number of suggestions expected from the response. Defaults to {@code
-     * SUGGESTION_COUNT_UNLIMITED} if not set.
+     * Max number of suggestions expected from the response. It must be a positive value.
+     * Defaults to {@code SUGGESTION_COUNT_UNLIMITED} if not set.
      */
     @DataClass.Generated.Member
     public int getMaxSuggestionCount() {
@@ -213,7 +216,7 @@
     /**
      * The {@link InlinePresentationSpec} for each suggestion in the response. If the max suggestion
      * count is larger than the number of specs in the list, then the last spec is used for the
-     * remainder of the suggestions.
+     * remainder of the suggestions. The list should not be empty.
      */
     @DataClass.Generated.Member
     public @NonNull List<InlinePresentationSpec> getPresentationSpecs() {
@@ -419,7 +422,7 @@
          * @param presentationSpecs
          *   The {@link InlinePresentationSpec} for each suggestion in the response. If the max suggestion
          *   count is larger than the number of specs in the list, then the last spec is used for the
-         *   remainder of the suggestions.
+         *   remainder of the suggestions. The list should not be empty.
          */
         public Builder(
                 @NonNull List<InlinePresentationSpec> presentationSpecs) {
@@ -429,8 +432,8 @@
         }
 
         /**
-         * Max number of suggestions expected from the response. Defaults to {@code
-         * SUGGESTION_COUNT_UNLIMITED} if not set.
+         * Max number of suggestions expected from the response. It must be a positive value.
+         * Defaults to {@code SUGGESTION_COUNT_UNLIMITED} if not set.
          */
         @DataClass.Generated.Member
         public @NonNull Builder setMaxSuggestionCount(int value) {
@@ -443,7 +446,7 @@
         /**
          * The {@link InlinePresentationSpec} for each suggestion in the response. If the max suggestion
          * count is larger than the number of specs in the list, then the last spec is used for the
-         * remainder of the suggestions.
+         * remainder of the suggestions. The list should not be empty.
          */
         @DataClass.Generated.Member
         @Override
@@ -575,10 +578,10 @@
     }
 
     @DataClass.Generated(
-            time = 1582339908980L,
-            codegenVersion = "1.0.14",
+            time = 1583975428858L,
+            codegenVersion = "1.0.15",
             sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestionsRequest.java",
-            inputSignatures = "public static final  int SUGGESTION_COUNT_UNLIMITED\nprivate final  int mMaxSuggestionCount\nprivate final @android.annotation.NonNull java.util.List<android.view.inline.InlinePresentationSpec> mPresentationSpecs\nprivate @android.annotation.NonNull java.lang.String mHostPackageName\nprivate @android.annotation.NonNull android.os.LocaleList mSupportedLocales\nprivate @android.annotation.Nullable android.os.Bundle mExtras\nprivate @android.annotation.Nullable android.os.IBinder mHostInputToken\nprivate  int mHostDisplayId\npublic  void setHostInputToken(android.os.IBinder)\nprivate  void parcelHostInputToken(android.os.Parcel,int)\nprivate @android.annotation.Nullable android.os.IBinder unparcelHostInputToken(android.os.Parcel)\npublic  void setHostDisplayId(int)\nprivate  void onConstructed()\nprivate static  int defaultMaxSuggestionCount()\nprivate static  java.lang.String defaultHostPackageName()\nprivate static  android.os.LocaleList defaultSupportedLocales()\nprivate static @android.annotation.Nullable android.os.IBinder defaultHostInputToken()\nprivate static @android.annotation.Nullable int defaultHostDisplayId()\nprivate static @android.annotation.Nullable android.os.Bundle defaultExtras()\nclass InlineSuggestionsRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setPresentationSpecs(java.util.List<android.view.inline.InlinePresentationSpec>)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostDisplayId(int)\nclass BaseBuilder extends java.lang.Object implements []")
+            inputSignatures = "public static final  int SUGGESTION_COUNT_UNLIMITED\nprivate final  int mMaxSuggestionCount\nprivate final @android.annotation.NonNull java.util.List<android.view.inline.InlinePresentationSpec> mPresentationSpecs\nprivate @android.annotation.NonNull java.lang.String mHostPackageName\nprivate @android.annotation.NonNull android.os.LocaleList mSupportedLocales\nprivate @com.android.internal.util.DataClass.MaySetToNull @android.annotation.Nullable android.os.Bundle mExtras\nprivate @com.android.internal.util.DataClass.MaySetToNull @android.annotation.Nullable android.os.IBinder mHostInputToken\nprivate  int mHostDisplayId\npublic  void setHostInputToken(android.os.IBinder)\nprivate  void parcelHostInputToken(android.os.Parcel,int)\nprivate @android.annotation.Nullable android.os.IBinder unparcelHostInputToken(android.os.Parcel)\npublic  void setHostDisplayId(int)\nprivate  void onConstructed()\nprivate static  int defaultMaxSuggestionCount()\nprivate static  java.lang.String defaultHostPackageName()\nprivate static  android.os.LocaleList defaultSupportedLocales()\nprivate static @android.annotation.Nullable android.os.IBinder defaultHostInputToken()\nprivate static @android.annotation.Nullable int defaultHostDisplayId()\nprivate static @android.annotation.Nullable android.os.Bundle defaultExtras()\nclass InlineSuggestionsRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setPresentationSpecs(java.util.List<android.view.inline.InlinePresentationSpec>)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostDisplayId(int)\nclass BaseBuilder extends java.lang.Object implements []")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
index d50826f..fa567f2 100644
--- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
@@ -452,7 +452,7 @@
             mEmptyStateView = rootView.findViewById(R.id.resolver_empty_state);
         }
 
-        private ViewGroup getEmptyStateView() {
+        protected ViewGroup getEmptyStateView() {
             return mEmptyStateView;
         }
     }
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index c099301..5620bff 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -2411,6 +2411,8 @@
                 mChooserMultiProfilePagerAdapter.getActiveAdapterView()
                         .setAdapter(mChooserMultiProfilePagerAdapter.getCurrentRootAdapter());
                 return;
+            } else if (mChooserMultiProfilePagerAdapter.getCurrentUserHandle() != getUser()) {
+                return;
             }
 
             getMainThreadHandler().post(() -> {
@@ -2455,39 +2457,46 @@
                     offset += tabDivider.getHeight();
                 }
 
-                int directShareHeight = 0;
-                rowsToShow = Math.min(4, rowsToShow);
-                mLastNumberOfChildren = recyclerView.getChildCount();
-                for (int i = 0, childCount = recyclerView.getChildCount();
-                        i < childCount && rowsToShow > 0; i++) {
-                    View child = recyclerView.getChildAt(i);
-                    if (((GridLayoutManager.LayoutParams)
-                            child.getLayoutParams()).getSpanIndex() != 0) {
-                        continue;
+                if (recyclerView.getVisibility() == View.VISIBLE) {
+                    int directShareHeight = 0;
+                    rowsToShow = Math.min(4, rowsToShow);
+                    mLastNumberOfChildren = recyclerView.getChildCount();
+                    for (int i = 0, childCount = recyclerView.getChildCount();
+                            i < childCount && rowsToShow > 0; i++) {
+                        View child = recyclerView.getChildAt(i);
+                        if (((GridLayoutManager.LayoutParams)
+                                child.getLayoutParams()).getSpanIndex() != 0) {
+                            continue;
+                        }
+                        int height = child.getHeight();
+                        offset += height;
+
+                        if (gridAdapter.getTargetType(
+                                recyclerView.getChildAdapterPosition(child))
+                                == ChooserListAdapter.TARGET_SERVICE) {
+                            directShareHeight = height;
+                        }
+                        rowsToShow--;
                     }
-                    int height = child.getHeight();
-                    offset += height;
 
-                    if (gridAdapter.getTargetType(
-                            recyclerView.getChildAdapterPosition(child))
-                            == ChooserListAdapter.TARGET_SERVICE) {
-                        directShareHeight = height;
+                    boolean isExpandable = getResources().getConfiguration().orientation
+                            == Configuration.ORIENTATION_PORTRAIT && !isInMultiWindowMode();
+                    if (directShareHeight != 0 && isSendAction(getTargetIntent())
+                            && isExpandable) {
+                        // make sure to leave room for direct share 4->8 expansion
+                        int requiredExpansionHeight =
+                                (int) (directShareHeight / DIRECT_SHARE_EXPANSION_RATE);
+                        int topInset = mSystemWindowInsets != null ? mSystemWindowInsets.top : 0;
+                        int minHeight = bottom - top - mResolverDrawerLayout.getAlwaysShowHeight()
+                                - requiredExpansionHeight - topInset - bottomInset;
+
+                        offset = Math.min(offset, minHeight);
                     }
-                    rowsToShow--;
-                }
-
-                boolean isExpandable = getResources().getConfiguration().orientation
-                        == Configuration.ORIENTATION_PORTRAIT && !isInMultiWindowMode();
-                if (directShareHeight != 0 && isSendAction(getTargetIntent())
-                        && isExpandable) {
-                    // make sure to leave room for direct share 4->8 expansion
-                    int requiredExpansionHeight =
-                            (int) (directShareHeight / DIRECT_SHARE_EXPANSION_RATE);
-                    int topInset = mSystemWindowInsets != null ? mSystemWindowInsets.top : 0;
-                    int minHeight = bottom - top - mResolverDrawerLayout.getAlwaysShowHeight()
-                                        - requiredExpansionHeight - topInset - bottomInset;
-
-                    offset = Math.min(offset, minHeight);
+                } else {
+                    ViewGroup currentEmptyStateView = getCurrentEmptyStateView();
+                    if (currentEmptyStateView.getVisibility() == View.VISIBLE) {
+                        offset += currentEmptyStateView.getHeight();
+                    }
                 }
 
                 mResolverDrawerLayout.setCollapsibleHeightReserved(Math.min(offset, bottom - top));
@@ -2495,6 +2504,11 @@
         }
     }
 
+    private ViewGroup getCurrentEmptyStateView() {
+        int currentPage = mChooserMultiProfilePagerAdapter.getCurrentPage();
+        return mChooserMultiProfilePagerAdapter.getItem(currentPage).getEmptyStateView();
+    }
+
     static class BaseChooserTargetComparator implements Comparator<ChooserTarget> {
         @Override
         public int compare(ChooserTarget lhs, ChooserTarget rhs) {
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index 73ef8c6..2f048c9 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -430,7 +430,7 @@
             if (shouldHide(file)) continue;
 
             if (file.isDirectory()) {
-                for (File child : file.listFiles()) {
+                for (File child : FileUtils.listFilesOrEmpty(file)) {
                     pending.add(child);
                 }
             }
diff --git a/core/java/com/android/internal/notification/SystemNotificationChannels.java b/core/java/com/android/internal/notification/SystemNotificationChannels.java
index 91ef0b5..1296ddc 100644
--- a/core/java/com/android/internal/notification/SystemNotificationChannels.java
+++ b/core/java/com/android/internal/notification/SystemNotificationChannels.java
@@ -116,6 +116,7 @@
                 NETWORK_STATUS,
                 context.getString(R.string.notification_channel_network_status),
                 NotificationManager.IMPORTANCE_LOW);
+        network.setBlockableSystem(true);
         channelsList.add(network);
 
         final NotificationChannel networkAlertsChannel = new NotificationChannel(
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 94924a5..633aa2c 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -140,6 +140,33 @@
      */
     public static final int MEMORY_TAG_LEVEL_SYNC = 3 << 19;
 
+    /**
+     * A two-bit field for GWP-ASan level of this process. See the possible values below.
+     */
+    public static final int GWP_ASAN_LEVEL_MASK = (1 << 21) | (1 << 22);
+
+    /**
+     * Disable GWP-ASan in this process.
+     * GWP-ASan is a low-overhead memory bug detector using guard pages on a small
+     * subset of heap allocations.
+     */
+    public static final int GWP_ASAN_LEVEL_NEVER = 0 << 21;
+
+    /**
+     * Enable GWP-ASan in this process with a small sampling rate.
+     * With approx. 1% chance GWP-ASan will be activated and apply its protection
+     * to a small subset of heap allocations.
+     * Otherwise (~99% chance) this process is unaffected.
+     */
+    public static final int GWP_ASAN_LEVEL_LOTTERY = 1 << 21;
+
+    /**
+     * Always enable GWP-ASan in this process.
+     * GWP-ASan is activated unconditionally (but still, only a small subset of
+     * allocations is protected).
+     */
+    public static final int GWP_ASAN_LEVEL_ALWAYS = 2 << 21;
+
     /** No external storage should be mounted. */
     public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
     /** Default external storage should be mounted. */
diff --git a/core/java/com/android/internal/util/Parcelling.java b/core/java/com/android/internal/util/Parcelling.java
index 7f567b9..dd64c40 100644
--- a/core/java/com/android/internal/util/Parcelling.java
+++ b/core/java/com/android/internal/util/Parcelling.java
@@ -221,6 +221,33 @@
             }
         }
 
+        class ForInternedStringArraySet implements Parcelling<ArraySet<String>> {
+            @Override
+            public void parcel(ArraySet<String> item, Parcel dest, int parcelFlags) {
+                if (item == null) {
+                    dest.writeInt(-1);
+                } else {
+                    dest.writeInt(item.size());
+                    for (String string : item) {
+                        dest.writeString(string);
+                    }
+                }
+            }
+
+            @Override
+            public ArraySet<String> unparcel(Parcel source) {
+                final int size = source.readInt();
+                if (size < 0) {
+                  return null;
+                }
+                ArraySet<String> set = new ArraySet<>();
+                for (int count = 0; count < size; count++) {
+                    set.add(TextUtils.safeIntern(source.readString()));
+                }
+                return set;
+            }
+        }
+
         class ForBoolean implements Parcelling<Boolean> {
             @Override
             public void parcel(@Nullable Boolean item, Parcel dest, int parcelFlags) {
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 5dd3389b..47f094f 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -116,7 +116,8 @@
     }
 
     @Override
-    public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep, boolean sync) {
+    public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep, float zoom,
+            boolean sync) {
         if (sync) {
             try {
                 mSession.wallpaperOffsetsComplete(asBinder());
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 0d0dc3e..f7c6dbd 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -853,8 +853,11 @@
     } cfg_state = CONFIG_UNKNOWN;
 
     if (cfg_state == CONFIG_UNKNOWN) {
-        const std::map<std::string, std::string> configs =
-            vintf::VintfObject::GetInstance()->getRuntimeInfo()->kernelConfigs();
+        auto runtime_info = vintf::VintfObject::GetInstance()
+                                    ->getRuntimeInfo(false /* skip cache */,
+                                                     vintf::RuntimeInfo::FetchFlag::CONFIG_GZ);
+        CHECK(runtime_info != nullptr) << "Kernel configs cannot be fetched. b/151092221";
+        const std::map<std::string, std::string>& configs = runtime_info->kernelConfigs();
         std::map<std::string, std::string>::const_iterator it = configs.find("CONFIG_VMAP_STACK");
         cfg_state = (it != configs.end() && it->second == "y") ? CONFIG_SET : CONFIG_UNSET;
     }
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 2128f99..f9885e2 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -356,10 +356,14 @@
 
 // Must match values in com.android.internal.os.Zygote.
 enum RuntimeFlags : uint32_t {
-  DEBUG_ENABLE_JDWP = 1,
-  PROFILE_FROM_SHELL = 1 << 15,
-  MEMORY_TAG_LEVEL_MASK = (1 << 19) | (1 << 20),
-  MEMORY_TAG_LEVEL_TBI = 1 << 19,
+    DEBUG_ENABLE_JDWP = 1,
+    PROFILE_FROM_SHELL = 1 << 15,
+    MEMORY_TAG_LEVEL_MASK = (1 << 19) | (1 << 20),
+    MEMORY_TAG_LEVEL_TBI = 1 << 19,
+    GWP_ASAN_LEVEL_MASK = (1 << 21) | (1 << 22),
+    GWP_ASAN_LEVEL_NEVER = 0 << 21,
+    GWP_ASAN_LEVEL_LOTTERY = 1 << 21,
+    GWP_ASAN_LEVEL_ALWAYS = 2 << 21,
 };
 
 enum UnsolicitedZygoteMessageTypes : uint32_t {
@@ -1741,6 +1745,18 @@
   }
   android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &heap_tagging_level, sizeof(heap_tagging_level));
 
+  bool forceEnableGwpAsan = false;
+  switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) {
+      default:
+      case RuntimeFlags::GWP_ASAN_LEVEL_NEVER:
+          break;
+      case RuntimeFlags::GWP_ASAN_LEVEL_ALWAYS:
+          forceEnableGwpAsan = true;
+          [[fallthrough]];
+      case RuntimeFlags::GWP_ASAN_LEVEL_LOTTERY:
+          android_mallopt(M_INITIALIZE_GWP_ASAN, &forceEnableGwpAsan, sizeof(forceEnableGwpAsan));
+  }
+
   if (NeedsNoRandomizeWorkaround()) {
     // Work around ARM kernel ASLR lossage (http://b/5817320).
     int old_personality = personality(0xffffffff);
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 030483b..ef6eb38 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -724,6 +724,16 @@
     // CATEGORY: SETTINGS
     // OS: R
     ACTION_ADB_WIRELESS_OFF = 1735;
+
+    // ACTION: Change Wi-Fi hotspot name
+    // CATEGORY: SETTINGS
+    // OS: R
+    ACTION_SETTINGS_CHANGE_WIFI_HOTSPOT_NAME = 1736;
+
+    // ACTION: Change Wi-Fi hotspot password
+    // CATEGORY: SETTINGS
+    // OS: R
+    ACTION_SETTINGS_CHANGE_WIFI_HOTSPOT_PASSWORD = 1737;
 }
 
 /**
diff --git a/core/proto/android/content/package_item_info.proto b/core/proto/android/content/package_item_info.proto
index 4a7d043..e8ae1b3 100644
--- a/core/proto/android/content/package_item_info.proto
+++ b/core/proto/android/content/package_item_info.proto
@@ -109,6 +109,7 @@
         }
         optional int32 network_security_config_res = 17;
         optional int32 category = 18;
+        optional bool enable_gwp_asan = 19;
     }
     optional Detail detail = 17;
 }
diff --git a/core/proto/android/telephony/enums.proto b/core/proto/android/telephony/enums.proto
index 4777169..f14e3ed 100644
--- a/core/proto/android/telephony/enums.proto
+++ b/core/proto/android/telephony/enums.proto
@@ -20,6 +20,43 @@
 option java_outer_classname = "TelephonyProtoEnums";
 option java_multiple_files = true;
 
+enum CallBearerEnum {
+    /** Call bearer is unknown or invalid */
+    CALL_BEARER_UNKNOWN = 0;
+
+    /** Call bearer is legacy CS */
+    CALL_BEARER_CS = 1;
+
+    /** Call bearer is IMS */
+    CALL_BEARER_IMS = 2;
+}
+
+enum CallDirectionEnum {
+    /** Call direction: unknown or invalid */
+    CALL_DIRECTION_UNKNOWN = 0;
+
+    /** Call direction: mobile originated (outgoing for this device) */
+    CALL_DIRECTION_MO = 1;
+
+    /** Call direction: mobile terminated (incoming for this device) */
+    CALL_DIRECTION_MT = 2;
+}
+
+// Call setup duration buckets.
+// See com.android.internal.telephony.metrics.VoiceCallSessionStats for definition.
+enum CallSetupDurationEnum {
+    CALL_SETUP_DURATION_UNKNOWN = 0;
+    CALL_SETUP_DURATION_EXTREMELY_FAST = 1;
+    CALL_SETUP_DURATION_ULTRA_FAST = 2;
+    CALL_SETUP_DURATION_VERY_FAST = 3;
+    CALL_SETUP_DURATION_FAST = 4;
+    CALL_SETUP_DURATION_NORMAL = 5;
+    CALL_SETUP_DURATION_SLOW = 6;
+    CALL_SETUP_DURATION_VERY_SLOW = 7;
+    CALL_SETUP_DURATION_ULTRA_SLOW = 8;
+    CALL_SETUP_DURATION_EXTREMELY_SLOW = 9;
+}
+
 // Data conn. power states, primarily used by android/telephony/DataConnectionRealTimeInfo.java.
 enum DataConnectionPowerStateEnum {
     DATA_CONNECTION_POWER_STATE_LOW = 1;
@@ -63,7 +100,6 @@
     SIGNAL_STRENGTH_GREAT = 4;
 }
 
-
 enum ServiceStateEnum {
     /**
      * Normal operation condition, the phone is registered
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 0dd3ad6..071bb11 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5200,6 +5200,7 @@
         <activity android:name="com.android.internal.app.BlockedAppActivity"
                 android:theme="@style/Theme.Dialog.Confirmation"
                 android:excludeFromRecents="true"
+                android:lockTaskMode="always"
                 android:process=":ui">
         </activity>
 
diff --git a/core/res/res/layout-car/car_resolver_different_item_header.xml b/core/res/res/layout-car/car_resolver_different_item_header.xml
deleted file mode 100644
index 222ecc6..0000000
--- a/core/res/res/layout-car/car_resolver_different_item_header.xml
+++ /dev/null
@@ -1,33 +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.
- */
--->
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_alwaysShow="true"
-    android:text="@*android:string/use_a_different_app"
-    android:minHeight="56dp"
-    android:textAppearance="?android:attr/textAppearanceLarge"
-    android:gravity="start|center_vertical"
-    android:paddingStart="16dp"
-    android:paddingEnd="16dp"
-    android:paddingTop="8dp"
-    android:paddingBottom="8dp"
-    android:elevation="8dp"
-/>
\ No newline at end of file
diff --git a/core/res/res/layout-car/car_resolver_list.xml b/core/res/res/layout-car/car_resolver_list.xml
index 15a8645..755cbfe 100644
--- a/core/res/res/layout-car/car_resolver_list.xml
+++ b/core/res/res/layout-car/car_resolver_list.xml
@@ -23,90 +23,142 @@
     android:id="@id/contentPanel">
 
     <LinearLayout
-        android:id="@+id/button_bar"
-        android:visibility="gone"
-        style="?attr/buttonBarStyle"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_ignoreOffset="true"
-        android:layout_alwaysShow="true"
-        android:layout_hasNestedScrollIndicator="true"
-        android:background="?attr/colorBackgroundFloating"
-        android:orientation="horizontal"
-        android:paddingTop="8dp"
-        android:paddingBottom="8dp"
-        android:paddingStart="12dp"
+        android:layout_height="match_parent"
         android:weightSum="5"
-        android:paddingEnd="12dp"
+        android:layout_alwaysShow="true"
+        android:orientation="vertical"
+        android:background="?attr/colorBackgroundFloating"
         android:elevation="8dp">
 
-        <TextView
-            android:id="@+id/profile_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginEnd="8dp"
-            android:paddingStart="8dp"
-            android:paddingEnd="8dp"
-            android:textSize="40sp"
-            android:layout_weight="5"
-            android:layout_gravity = "left"
+        <LinearLayout
+            android:id="@+id/button_bar"
             android:visibility="gone"
-            android:textColor="?attr/colorAccent"
-            android:singleLine="true"/>
-
-        <TextView
-            android:id="@+id/title"
-            android:layout_width="wrap_content"
+            style="?attr/buttonBarStyle"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:minHeight="56dp"
-            android:layout_gravity = "left"
-            android:layout_weight="3"
+            android:layout_ignoreOffset="true"
+            android:layout_alwaysShow="true"
+            android:layout_hasNestedScrollIndicator="true"
+            android:background="?attr/colorBackgroundFloating"
+            android:orientation="horizontal"
             android:paddingTop="8dp"
-            android:layout_below="@id/profile_button"
-            android:paddingBottom="8dp"/>
+            android:paddingStart="12dp"
+            android:weightSum="4"
+            android:paddingEnd="12dp"
+            android:elevation="8dp">
 
-        <Button
-            android:id="@+id/button_once"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:enabled="false"
-            android:layout_gravity = "right"
-            android:text="@string/activity_resolver_use_once"
-            android:layout_weight="1"
-            android:onClick="onButtonClick"/>
+            <TextView
+                android:id="@+id/profile_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginEnd="8dp"
+                android:paddingStart="8dp"
+                android:paddingEnd="8dp"
+                android:textSize="40sp"
+                android:layout_weight="4"
+                android:layout_gravity="left"
+                android:visibility="gone"
+                android:textColor="?attr/colorAccent"
+                android:singleLine="true"/>
 
-        <Button
-            android:id="@+id/button_always"
-            android:layout_marginLeft="10dp"
-            android:layout_width="wrap_content"
+            <TextView
+                android:id="@+id/title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="left"
+                android:layout_weight="3"
+                android:paddingTop="8dp"
+                android:layout_below="@id/profile_button"
+                android:textAppearance="?android:attr/textAppearanceLarge"
+                android:paddingBottom="8dp"/>
+
+            <Button
+                android:id="@+id/button_once"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:enabled="false"
+                android:layout_gravity="right"
+                style="?attr/buttonBarButtonStyle"
+                android:text="@string/activity_resolver_use_once"
+                android:layout_weight="0.5"
+                android:onClick="onButtonClick"/>
+
+            <Button
+                android:id="@+id/button_always"
+                android:layout_marginLeft="2dp"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:enabled="false"
+                android:layout_gravity="right"
+                style="?attr/buttonBarButtonStyle"
+                android:text="@string/activity_resolver_use_always"
+                android:layout_weight="0.5"
+                android:onClick="onButtonClick"/>
+        </LinearLayout>
+
+        <FrameLayout
+            android:id="@+id/stub"
+            android:visibility="gone"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:enabled="false"
-            android:layout_gravity = "right"
-            android:text="@string/activity_resolver_use_always"
-            android:layout_weight="1"
-            android:onClick="onButtonClick"/>
+            android:background="?attr/colorBackgroundFloating"/>
+
+        <TabHost
+            android:id="@+id/profile_tabhost"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_alignParentTop="true"
+            android:layout_centerHorizontal="true"
+            android:background="?attr/colorBackgroundFloating">
+            <LinearLayout
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+                <TabWidget
+                    android:id="@android:id/tabs"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:visibility="gone">
+                </TabWidget>
+                <View
+                    android:id="@+id/resolver_tab_divider"
+                    android:visibility="gone"
+                    android:layout_width="match_parent"
+                    android:layout_height="1dp"
+                    android:background="?attr/colorBackgroundFloating"
+                    android:foreground="?attr/dividerVertical"
+                    android:layout_marginBottom="8dp"/>
+                <FrameLayout
+                    android:id="@android:id/tabcontent"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content">
+                    <com.android.internal.app.ResolverViewPager
+                        android:id="@+id/profile_pager"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"/>
+                </FrameLayout>
+            </LinearLayout>
+        </TabHost>
+
+        <View
+            android:layout_alwaysShow="true"
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:background="?attr/colorBackgroundFloating"
+            android:foreground="?attr/dividerVertical"/>
+
+        <TextView android:id="@+id/empty"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:background="?attr/colorBackgroundFloating"
+                  android:elevation="8dp"
+                  android:layout_alwaysShow="true"
+                  android:text="@string/noApplications"
+                  android:padding="32dp"
+                  android:gravity="center"
+                  android:visibility="gone"/>
+
     </LinearLayout>
 
-    <ListView
-        android:layout_width="match_parent"
-        android:layout_height="500dp"
-        android:id="@+id/resolver_list"
-        android:clipToPadding="false"
-        android:scrollbarStyle="outsideOverlay"
-        android:background="?attr/colorBackgroundFloating"
-        android:elevation="8dp"
-        android:nestedScrollingEnabled="true"
-        android:scrollIndicators="top|bottom"/>
-
-    <TextView android:id="@+id/empty"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:background="?attr/colorBackgroundFloating"
-              android:elevation="8dp"
-              android:layout_alwaysShow="true"
-              android:text="@string/noApplications"
-              android:padding="32dp"
-              android:gravity="center"
-              android:visibility="gone"/>
-
 </com.android.internal.widget.ResolverDrawerLayout>
diff --git a/core/res/res/layout-car/car_resolver_list_with_default.xml b/core/res/res/layout-car/car_resolver_list_with_default.xml
index 2aed00b..5e450b2 100644
--- a/core/res/res/layout-car/car_resolver_list_with_default.xml
+++ b/core/res/res/layout-car/car_resolver_list_with_default.xml
@@ -40,12 +40,12 @@
 
             <ImageView
                 android:id="@+id/icon"
-                android:layout_width="24dp"
-                android:layout_height="24dp"
+                android:layout_width="60dp"
+                android:layout_height="60dp"
                 android:layout_gravity="start|top"
-                android:layout_marginStart="16dp"
-                android:layout_marginEnd="16dp"
-                android:layout_marginTop="20dp"
+                android:layout_marginStart="10dp"
+                android:layout_marginEnd="5dp"
+                android:layout_marginTop="10dp"
                 android:src="@drawable/resolver_icon_placeholder"
                 android:scaleType="fitCenter"/>
 
@@ -55,7 +55,7 @@
                 android:layout_weight="1"
                 android:layout_height="?attr/listPreferredItemHeight"
                 android:layout_marginStart="16dp"
-                android:textAppearance="?attr/textAppearanceMedium"
+                android:textAppearance="?android:attr/textAppearanceLarge"
                 android:gravity="start|center_vertical"
                 android:paddingEnd="16dp"/>
 
@@ -120,7 +120,7 @@
                 android:layout_width="wrap_content"
                 android:layout_gravity="start"
                 android:maxLines="2"
-                style="?attr/buttonBarNegativeButtonStyle"
+                style="?attr/buttonBarButtonStyle"
                 android:minHeight="@dimen/alert_dialog_button_bar_height"
                 android:layout_height="wrap_content"
                 android:enabled="false"
@@ -133,29 +133,64 @@
                 android:layout_gravity="end"
                 android:maxLines="2"
                 android:minHeight="@dimen/alert_dialog_button_bar_height"
-                style="?attr/buttonBarPositiveButtonStyle"
+                style="?attr/buttonBarButtonStyle"
                 android:layout_height="wrap_content"
                 android:enabled="false"
                 android:text="@string/activity_resolver_use_always"
                 android:onClick="onButtonClick"/>
         </LinearLayout>
 
+        <FrameLayout
+            android:id="@+id/stub"
+            android:layout_alwaysShow="true"
+            android:visibility="gone"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="?attr/colorBackgroundFloating"/>
+
+        <TabHost
+            android:layout_alwaysShow="true"
+            android:id="@+id/profile_tabhost"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_alignParentTop="true"
+            android:layout_centerHorizontal="true"
+            android:background="?attr/colorBackgroundFloating">
+            <LinearLayout
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+                <TabWidget
+                    android:id="@android:id/tabs"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:visibility="gone">
+                </TabWidget>
+                <View
+                    android:id="@+id/resolver_tab_divider"
+                    android:visibility="gone"
+                    android:layout_width="match_parent"
+                    android:layout_height="1dp"
+                    android:background="?attr/colorBackgroundFloating"
+                    android:foreground="?attr/dividerVertical"
+                    android:layout_marginBottom="8dp"/>
+                <FrameLayout
+                    android:id="@android:id/tabcontent"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content">
+                    <com.android.internal.app.ResolverViewPager
+                        android:id="@+id/profile_pager"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content">
+                    </com.android.internal.app.ResolverViewPager>
+                </FrameLayout>
+            </LinearLayout>
+        </TabHost>
+
         <View
             android:layout_width="match_parent"
             android:layout_height="1dp"
             android:background="?attr/dividerVertical"/>
-
-        <ListView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:id="@+id/resolver_list"
-            android:layout_weight="4"
-            android:clipToPadding="false"
-            android:scrollbarStyle="outsideOverlay"
-            android:background="?attr/colorBackgroundFloating"
-            android:elevation="8dp"
-            android:nestedScrollingEnabled="true"
-            android:divider="@null"/>
     </LinearLayout>
 
 </com.android.internal.widget.ResolverDrawerLayout>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index c245131..ba939ea 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1541,6 +1541,28 @@
         <flag name="microphone" value="0x80" />
     </attr>
 
+    <!-- Enable sampled memory bug detection in this process.
+         When enabled, a very small, random subset of native
+         memory allocations are protected with guard pages, providing an
+         ASan-like error report in case of a memory corruption bug.
+
+         GWP-ASan is a recursive acronym. It stands for “GWP-ASan Will Provide Allocation SANity”.
+         See the <a href="http://llvm.org/docs/GwpAsan.html">LLVM documentation</a>
+         for more information about this feature.
+
+         <p>This tag can be applied to any tag that allows
+         {@link android.R.styleable#AndroidManifestProcess process} tag:
+         {@link android.R.styleable#AndroidManifestApplication application} tag (to supply
+         a default setting for all application components), or with the
+         {@link android.R.styleable#AndroidManifestProvider provider},
+         {@link android.R.styleable#AndroidManifestService service},
+         {@link android.R.styleable#AndroidManifestReceiver receiver},
+         {@link android.R.styleable#AndroidManifestActivity activity} tag.
+         When multiple components run in the same process,
+         the first component to start determines the behavior of the entire process.
+
+         The default value is {@code false}. -->
+    <attr name="enableGwpAsan" format="boolean" />
 
     <!-- The <code>manifest</code> tag is the root of an
          <code>AndroidManifest.xml</code> file,
@@ -1806,6 +1828,9 @@
 
              The default value is {@code true}. -->
         <attr name="allowNativeHeapPointerTagging" format="boolean" />
+
+        <attr name="enableGwpAsan" />
+
     </declare-styleable>
 
     <!-- The <code>feature</code> tag declares a feature. A feature is a logical part of an app.
@@ -2312,6 +2337,7 @@
     <declare-styleable name="AndroidManifestProcess" parent="AndroidManifestProcesses">
         <!-- Required name of the process that is allowed -->
         <attr name="process" />
+        <attr name="enableGwpAsan" />
     </declare-styleable>
 
     <!-- The <code>deny-permission</code> tag specifies that a permission is to be denied
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 617949d..6f468e0 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4418,4 +4418,7 @@
 
     <!-- Package name of custom session policy provider class used by MediaSessionService. -->
     <string name="config_customSessionPolicyProvider"></string>
+
+    <!-- The max scale for the wallpaper when it's zoomed in -->
+    <item name="config_wallpaperMaxScale" format="float" type="dimen">1</item>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 39e8197..a823e52 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3015,6 +3015,7 @@
       <public name="allowNativeHeapPointerTagging" />
       <public name="preserveLegacyExternalStorage" />
       <public name="mimeGroup" />
+      <public name="enableGwpAsan" />
     </public-group>
 
     <public-group type="drawable" first-id="0x010800b5">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8316081..a9008d7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3926,4 +3926,6 @@
 
   <java-symbol type="string" name="config_customMediaKeyDispatcher" />
   <java-symbol type="string" name="config_customSessionPolicyProvider" />
+  <!-- The max scale for the wallpaper when it's zoomed in -->
+  <java-symbol type="dimen" name="config_wallpaperMaxScale"/>
 </resources>
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index 50cd5a3..fe25e79 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -123,7 +123,7 @@
         mController = new InsetsAnimationControlImpl(controls,
                 new Rect(0, 0, 500, 500), mInsetsState, mMockListener, systemBars(),
                 mMockController, 10 /* durationMs */, new LinearInterpolator(),
-                false /* fade */, LAYOUT_INSETS_DURING_ANIMATION_SHOWN, 0 /* animationType */);
+                false /* fade */, 0 /* animationType */);
     }
 
     @Test
@@ -182,7 +182,7 @@
 
     @Test
     public void testCancelled() {
-        mController.onCancelled();
+        mController.cancel();
         try {
             mController.setInsetsAndAlpha(Insets.NONE, 1f /*alpha */, 0f /* fraction */);
             fail("Expected exception to be thrown");
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index 023fc17..f1ab8dd 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -31,6 +31,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
@@ -47,6 +48,7 @@
 import android.graphics.Rect;
 import android.os.CancellationSignal;
 import android.platform.test.annotations.Presubmit;
+import android.view.InsetsState.InternalInsetsType;
 import android.view.SurfaceControl.Transaction;
 import android.view.WindowInsets.Type;
 import android.view.WindowInsetsController.OnControllableInsetsChangedListener;
@@ -169,11 +171,8 @@
 
     @Test
     public void testControlsChanged() {
-        InsetsSourceControl control =
-                new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point());
-        mController.onControlsChanged(new InsetsSourceControl[] { control });
-        assertEquals(mLeash,
-                mController.getSourceConsumer(ITYPE_STATUS_BAR).getControl().getLeash());
+        mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR));
+        assertNotNull(mController.getSourceConsumer(ITYPE_STATUS_BAR).getControl().getLeash());
         mController.addOnControllableInsetsChangedListener(
                 ((controller, typeMask) -> assertEquals(statusBars(), typeMask)));
     }
@@ -183,9 +182,7 @@
         OnControllableInsetsChangedListener listener
                 = mock(OnControllableInsetsChangedListener.class);
         mController.addOnControllableInsetsChangedListener(listener);
-        InsetsSourceControl control =
-                new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point());
-        mController.onControlsChanged(new InsetsSourceControl[] { control });
+        mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR));
         mController.onControlsChanged(new InsetsSourceControl[0]);
         assertNull(mController.getSourceConsumer(ITYPE_STATUS_BAR).getControl());
         InOrder inOrder = Mockito.inOrder(listener);
@@ -197,9 +194,7 @@
     @Test
     public void testControlsRevoked_duringAnim() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            InsetsSourceControl control =
-                    new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point());
-            mController.onControlsChanged(new InsetsSourceControl[] { control });
+            mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR));
 
             WindowInsetsAnimationControlListener mockListener =
                     mock(WindowInsetsAnimationControlListener.class);
@@ -262,11 +257,8 @@
 
     @Test
     public void testApplyImeVisibility() {
-        final InsetsSourceControl ime = new InsetsSourceControl(ITYPE_IME, mLeash, new Point());
-
-        InsetsSourceControl[] controls = new InsetsSourceControl[3];
-        controls[0] = ime;
-        mController.onControlsChanged(controls);
+        InsetsSourceControl ime = createControl(ITYPE_IME);
+        mController.onControlsChanged(new InsetsSourceControl[] { ime });
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             mController.getSourceConsumer(ITYPE_IME).onWindowFocusGained();
             mController.applyImeVisibility(true);
@@ -429,9 +421,7 @@
 
     @Test
     public void testRestoreStartsAnimation() {
-        InsetsSourceControl control =
-                new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point());
-        mController.onControlsChanged(new InsetsSourceControl[]{control});
+        mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR));
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             mController.hide(Type.statusBars());
@@ -448,7 +438,7 @@
             assertTrue(mController.getState().getSource(ITYPE_STATUS_BAR).isVisible());
 
             // Gaining control
-            mController.onControlsChanged(new InsetsSourceControl[]{control});
+            mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR));
             assertEquals(ANIMATION_TYPE_HIDE, mController.getAnimationType(ITYPE_STATUS_BAR));
             mController.cancelExistingAnimation();
             assertFalse(mController.getSourceConsumer(ITYPE_STATUS_BAR).isRequestedVisible());
@@ -459,8 +449,6 @@
 
     @Test
     public void testStartImeAnimationAfterGettingControl() {
-        InsetsSourceControl control =
-                new InsetsSourceControl(ITYPE_IME, mLeash, new Point());
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
 
@@ -471,7 +459,7 @@
             mController.show(ime(), true /* fromIme */);
 
             // Gaining control shortly after
-            mController.onControlsChanged(new InsetsSourceControl[]{control});
+            mController.onControlsChanged(createSingletonControl(ITYPE_IME));
 
             assertEquals(ANIMATION_TYPE_SHOW, mController.getAnimationType(ITYPE_IME));
             mController.cancelExistingAnimation();
@@ -483,16 +471,13 @@
 
     @Test
     public void testStartImeAnimationAfterGettingControl_imeLater() {
-        InsetsSourceControl control =
-                new InsetsSourceControl(ITYPE_IME, mLeash, new Point());
-
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
 
             mController.show(ime());
             assertFalse(mController.getState().getSource(ITYPE_IME).isVisible());
 
             // Gaining control shortly after
-            mController.onControlsChanged(new InsetsSourceControl[]{control});
+            mController.onControlsChanged(createSingletonControl(ITYPE_IME));
 
             // Pretend IME is calling
             mController.show(ime(), true /* fromIme */);
@@ -507,9 +492,7 @@
 
     @Test
     public void testAnimationEndState_controller() throws Exception {
-        InsetsSourceControl control =
-                new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point());
-        mController.onControlsChanged(new InsetsSourceControl[] { control });
+        mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR));
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             WindowInsetsAnimationControlListener mockListener =
@@ -535,9 +518,7 @@
 
     @Test
     public void testCancellation_afterGainingControl() throws Exception {
-        InsetsSourceControl control =
-                new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point());
-        mController.onControlsChanged(new InsetsSourceControl[] { control });
+        mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR));
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             WindowInsetsAnimationControlListener mockListener =
@@ -655,12 +636,23 @@
         latch.await();
     }
 
+    private InsetsSourceControl createControl(@InternalInsetsType int type) {
+
+        // Simulate binder behavior by copying SurfaceControl. Otherwise, InsetsController will
+        // attempt to release mLeash directly.
+        SurfaceControl copy = new SurfaceControl();
+        copy.copyFrom(mLeash);
+        return new InsetsSourceControl(type, copy, new Point());
+    }
+
+    private InsetsSourceControl[] createSingletonControl(@InternalInsetsType int type) {
+        return new InsetsSourceControl[] { createControl(type) };
+    }
+
     private InsetsSourceControl[] prepareControls() {
-        final InsetsSourceControl navBar = new InsetsSourceControl(ITYPE_NAVIGATION_BAR, mLeash,
-                new Point());
-        final InsetsSourceControl statusBar = new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash,
-                new Point());
-        final InsetsSourceControl ime = new InsetsSourceControl(ITYPE_IME, mLeash, new Point());
+        final InsetsSourceControl navBar = createControl(ITYPE_NAVIGATION_BAR);
+        final InsetsSourceControl statusBar = createControl(ITYPE_STATUS_BAR);
+        final InsetsSourceControl ime = createControl(ITYPE_IME);
 
         InsetsSourceControl[] controls = new InsetsSourceControl[3];
         controls[0] = navBar;
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 49edcf7..487a6e9 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -164,6 +164,7 @@
         <permission name="android.permission.REBOOT"/>
         <permission name="android.permission.REGISTER_CALL_PROVIDER"/>
         <permission name="android.permission.REGISTER_SIM_SUBSCRIPTION"/>
+        <permission name="android.permission.REGISTER_STATS_PULL_ATOM"/>
         <permission name="android.permission.SEND_RESPOND_VIA_MESSAGE"/>
         <permission name="android.permission.SET_TIME_ZONE"/>
         <permission name="android.permission.SHUTDOWN"/>
diff --git a/media/java/android/media/tv/tuner/frontend/DvbtFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/DvbtFrontendSettings.java
index e99fd36f..1510b2d 100644
--- a/media/java/android/media/tv/tuner/frontend/DvbtFrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/DvbtFrontendSettings.java
@@ -125,9 +125,9 @@
     /** @hide */
     @IntDef(flag = true,
             prefix = "CONSTELLATION_",
-            value = {CONSTELLATION_UNDEFINED, CONSTELLATION_AUTO, CONSTELLATION_CONSTELLATION_QPSK,
-                    CONSTELLATION_CONSTELLATION_16QAM, CONSTELLATION_CONSTELLATION_64QAM,
-                    CONSTELLATION_CONSTELLATION_256QAM})
+            value = {CONSTELLATION_UNDEFINED, CONSTELLATION_AUTO, CONSTELLATION_QPSK,
+                    CONSTELLATION_16QAM, CONSTELLATION_64QAM,
+                    CONSTELLATION_256QAM})
     @Retention(RetentionPolicy.SOURCE)
     public @interface Constellation {}
 
@@ -142,22 +142,22 @@
     /**
      * QPSK Constellation.
      */
-    public static final int CONSTELLATION_CONSTELLATION_QPSK =
+    public static final int CONSTELLATION_QPSK =
             Constants.FrontendDvbtConstellation.CONSTELLATION_QPSK;
     /**
      * 16QAM Constellation.
      */
-    public static final int CONSTELLATION_CONSTELLATION_16QAM =
+    public static final int CONSTELLATION_16QAM =
             Constants.FrontendDvbtConstellation.CONSTELLATION_16QAM;
     /**
      * 64QAM Constellation.
      */
-    public static final int CONSTELLATION_CONSTELLATION_64QAM =
+    public static final int CONSTELLATION_64QAM =
             Constants.FrontendDvbtConstellation.CONSTELLATION_64QAM;
     /**
      * 256QAM Constellation.
      */
-    public static final int CONSTELLATION_CONSTELLATION_256QAM =
+    public static final int CONSTELLATION_256QAM =
             Constants.FrontendDvbtConstellation.CONSTELLATION_256QAM;
 
 
@@ -275,11 +275,11 @@
     @IntDef(flag = true,
             prefix = "GUARD_INTERVAL_",
             value = {GUARD_INTERVAL_UNDEFINED, GUARD_INTERVAL_AUTO,
-            GUARD_INTERVAL_INTERVAL_1_32, GUARD_INTERVAL_INTERVAL_1_16,
-            GUARD_INTERVAL_INTERVAL_1_8, GUARD_INTERVAL_INTERVAL_1_4,
-            GUARD_INTERVAL_INTERVAL_1_128,
-            GUARD_INTERVAL_INTERVAL_19_128,
-            GUARD_INTERVAL_INTERVAL_19_256})
+            GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16,
+            GUARD_INTERVAL_1_8, GUARD_INTERVAL_1_4,
+            GUARD_INTERVAL_1_128,
+            GUARD_INTERVAL_19_128,
+            GUARD_INTERVAL_19_256})
     @Retention(RetentionPolicy.SOURCE)
     public @interface GuardInterval {}
 
@@ -295,37 +295,37 @@
     /**
      * 1/32 Guard Interval.
      */
-    public static final int GUARD_INTERVAL_INTERVAL_1_32 =
+    public static final int GUARD_INTERVAL_1_32 =
             Constants.FrontendDvbtGuardInterval.INTERVAL_1_32;
     /**
      * 1/16 Guard Interval.
      */
-    public static final int GUARD_INTERVAL_INTERVAL_1_16 =
+    public static final int GUARD_INTERVAL_1_16 =
             Constants.FrontendDvbtGuardInterval.INTERVAL_1_16;
     /**
      * 1/8 Guard Interval.
      */
-    public static final int GUARD_INTERVAL_INTERVAL_1_8 =
+    public static final int GUARD_INTERVAL_1_8 =
             Constants.FrontendDvbtGuardInterval.INTERVAL_1_8;
     /**
      * 1/4 Guard Interval.
      */
-    public static final int GUARD_INTERVAL_INTERVAL_1_4 =
+    public static final int GUARD_INTERVAL_1_4 =
             Constants.FrontendDvbtGuardInterval.INTERVAL_1_4;
     /**
      * 1/128 Guard Interval.
      */
-    public static final int GUARD_INTERVAL_INTERVAL_1_128 =
+    public static final int GUARD_INTERVAL_1_128 =
             Constants.FrontendDvbtGuardInterval.INTERVAL_1_128;
     /**
      * 19/128 Guard Interval.
      */
-    public static final int GUARD_INTERVAL_INTERVAL_19_128 =
+    public static final int GUARD_INTERVAL_19_128 =
             Constants.FrontendDvbtGuardInterval.INTERVAL_19_128;
     /**
      * 19/256 Guard Interval.
      */
-    public static final int GUARD_INTERVAL_INTERVAL_19_256 =
+    public static final int GUARD_INTERVAL_19_256 =
             Constants.FrontendDvbtGuardInterval.INTERVAL_19_256;
 
     /** @hide */
@@ -435,14 +435,14 @@
      * Gets Code Rate for High Priority level.
      */
     @CodeRate
-    public int getHpCodeRate() {
+    public int getHighPriorityCodeRate() {
         return mHpCodeRate;
     }
     /**
      * Gets Code Rate for Low Priority level.
      */
     @CodeRate
-    public int getLpCodeRate() {
+    public int getLowPriorityCodeRate() {
         return mLpCodeRate;
     }
     /**
@@ -560,7 +560,7 @@
          * Sets Code Rate for High Priority level.
          */
         @NonNull
-        public Builder setHpCodeRate(@CodeRate int hpCodeRate) {
+        public Builder setHighPriorityCodeRate(@CodeRate int hpCodeRate) {
             mHpCodeRate = hpCodeRate;
             return this;
         }
@@ -568,7 +568,7 @@
          * Sets Code Rate for Low Priority level.
          */
         @NonNull
-        public Builder setLpCodeRate(@CodeRate int lpCodeRate) {
+        public Builder setLowPriorityCodeRate(@CodeRate int lpCodeRate) {
             mLpCodeRate = lpCodeRate;
             return this;
         }
diff --git a/media/java/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl b/media/java/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl
index 20efaa1..77cac6e 100644
--- a/media/java/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl
+++ b/media/java/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl
@@ -19,6 +19,8 @@
 import android.media.tv.tunerresourcemanager.CasSessionRequest;
 import android.media.tv.tunerresourcemanager.IResourcesReclaimListener;
 import android.media.tv.tunerresourcemanager.ResourceClientProfile;
+import android.media.tv.tunerresourcemanager.TunerDemuxRequest;
+import android.media.tv.tunerresourcemanager.TunerDescramblerRequest;
 import android.media.tv.tunerresourcemanager.TunerFrontendInfo;
 import android.media.tv.tunerresourcemanager.TunerFrontendRequest;
 import android.media.tv.tunerresourcemanager.TunerLnbRequest;
@@ -148,6 +150,53 @@
     void shareFrontend(in int selfClientId, in int targetClientId);
 
     /*
+     * This API is used by the Tuner framework to request an available demux from the TunerHAL.
+     *
+     * <p>There are three possible scenarios:
+     * <ul>
+     * <li>If there is demux available, the API would send the handle back.
+     *
+     * <li>If no Demux is available but the current request info can show higher priority than
+     * other uses of demuxes, the API will send
+     * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
+     * handle the resource reclaim on the holder of lower priority and notify the holder of its
+     * resource loss.
+     *
+     * <li>If no demux can be granted, the API would return false.
+     * <ul>
+     *
+     * @param request {@link TunerDemuxRequest} information of the current request.
+     * @param demuxHandle a one-element array to return the granted demux handle.
+     *
+     * @return true if there is demux granted.
+     */
+    boolean requestDemux(in TunerDemuxRequest request, out int[] demuxHandle);
+
+    /*
+     * This API is used by the Tuner framework to request an available descrambler from the
+     * TunerHAL.
+     *
+     * <p>There are three possible scenarios:
+     * <ul>
+     * <li>If there is descrambler available, the API would send the handle back.
+     *
+     * <li>If no Descrambler is available but the current request info can show higher priority than
+     * other uses of Descrambler, the API will send
+     * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
+     * handle the resource reclaim on the holder of lower priority and notify the holder of its
+     * resource loss.
+     *
+     * <li>If no Descrambler can be granted, the API would return false.
+     * <ul>
+     *
+     * @param request {@link TunerDescramblerRequest} information of the current request.
+     * @param descramblerHandle a one-element array to return the granted descrambler handle.
+     *
+     * @return true if there is Descrambler granted.
+     */
+    boolean requestDescrambler(in TunerDescramblerRequest request, out int[] descramblerHandle);
+
+    /*
      * This API is used by the Tuner framework to request an available Cas session. This session
      * needs to be under the CAS system with the id indicated in the {@code request}.
      *
@@ -210,6 +259,24 @@
     void releaseFrontend(in int frontendId);
 
     /*
+     * Notifies the TRM that the Demux with the given handle was released.
+     *
+     * <p>Client must call this whenever it releases a demux.
+     *
+     * @param demuxHandle the handle of the released Tuner Demux.
+     */
+    void releaseDemux(in int demuxHandle);
+
+    /*
+     * Notifies the TRM that the Descrambler with the given handle was released.
+     *
+     * <p>Client must call this whenever it releases a descrambler.
+     *
+     * @param demuxHandle the handle of the released Tuner Descrambler.
+     */
+    void releaseDescrambler(in int descramblerHandle);
+
+    /*
      * Notifies the TRM that the given Cas session has been released.
      *
      * <p>Client must call this whenever it releases a Cas session.
diff --git a/media/java/android/media/tv/tunerresourcemanager/TunerDemuxRequest.aidl b/media/java/android/media/tv/tunerresourcemanager/TunerDemuxRequest.aidl
new file mode 100644
index 0000000..919a215
--- /dev/null
+++ b/media/java/android/media/tv/tunerresourcemanager/TunerDemuxRequest.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.tunerresourcemanager;
+
+/**
+ * Information required to request a Tuner Demux.
+ *
+ * @hide
+ */
+parcelable TunerDemuxRequest;
\ No newline at end of file
diff --git a/media/java/android/media/tv/tunerresourcemanager/TunerDemuxRequest.java b/media/java/android/media/tv/tunerresourcemanager/TunerDemuxRequest.java
new file mode 100644
index 0000000..34a7761
--- /dev/null
+++ b/media/java/android/media/tv/tunerresourcemanager/TunerDemuxRequest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.tunerresourcemanager;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * Information required to request a Tuner Demux.
+ *
+ * @hide
+ */
+public final class TunerDemuxRequest implements Parcelable {
+    static final String TAG = "TunerDemuxRequest";
+
+    public static final
+                @NonNull
+                Parcelable.Creator<TunerDemuxRequest> CREATOR =
+                new Parcelable.Creator<TunerDemuxRequest>() {
+                @Override
+                public TunerDemuxRequest createFromParcel(Parcel source) {
+                    try {
+                        return new TunerDemuxRequest(source);
+                    } catch (Exception e) {
+                        Log.e(TAG, "Exception creating TunerDemuxRequest from parcel", e);
+                        return null;
+                    }
+                }
+
+                @Override
+                public TunerDemuxRequest[] newArray(int size) {
+                    return new TunerDemuxRequest[size];
+                }
+            };
+
+    /**
+     * Client id of the client that sends the request.
+     */
+    private final int mClientId;
+
+    private TunerDemuxRequest(@NonNull Parcel source) {
+        mClientId = source.readInt();
+    }
+
+    /**
+     * Constructs a new {@link TunerDemuxRequest} with the given parameters.
+     *
+     * @param clientId id of the client.
+     */
+    public TunerDemuxRequest(int clientId) {
+        mClientId = clientId;
+    }
+
+    /**
+     * Returns the id of the client.
+     */
+    public int getClientId() {
+        return mClientId;
+    }
+
+    // Parcelable
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder(128);
+        b.append("TunerDemuxRequest {clientId=").append(mClientId);
+        b.append("}");
+        return b.toString();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mClientId);
+    }
+}
diff --git a/media/java/android/media/tv/tunerresourcemanager/TunerDescramblerRequest.aidl b/media/java/android/media/tv/tunerresourcemanager/TunerDescramblerRequest.aidl
new file mode 100644
index 0000000..fbafb3b
--- /dev/null
+++ b/media/java/android/media/tv/tunerresourcemanager/TunerDescramblerRequest.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.tunerresourcemanager;
+
+/**
+ * Information required to request a Tuner Descrambler.
+ *
+ * @hide
+ */
+parcelable TunerDescramblerRequest;
\ No newline at end of file
diff --git a/media/java/android/media/tv/tunerresourcemanager/TunerDescramblerRequest.java b/media/java/android/media/tv/tunerresourcemanager/TunerDescramblerRequest.java
new file mode 100644
index 0000000..5816287
--- /dev/null
+++ b/media/java/android/media/tv/tunerresourcemanager/TunerDescramblerRequest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.tunerresourcemanager;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * Information required to request a Tuner Descrambler.
+ *
+ * @hide
+ */
+public final class TunerDescramblerRequest implements Parcelable {
+    static final String TAG = "TunerDescramblerRequest";
+
+    public static final
+                @NonNull
+                Parcelable.Creator<TunerDescramblerRequest> CREATOR =
+                new Parcelable.Creator<TunerDescramblerRequest>() {
+                @Override
+                public TunerDescramblerRequest createFromParcel(Parcel source) {
+                    try {
+                        return new TunerDescramblerRequest(source);
+                    } catch (Exception e) {
+                        Log.e(TAG, "Exception creating TunerDescramblerRequest from parcel", e);
+                        return null;
+                    }
+                }
+
+                @Override
+                public TunerDescramblerRequest[] newArray(int size) {
+                    return new TunerDescramblerRequest[size];
+                }
+            };
+
+    /**
+     * Client id of the client that sends the request.
+     */
+    private final int mClientId;
+
+    private TunerDescramblerRequest(@NonNull Parcel source) {
+        mClientId = source.readInt();
+    }
+
+    /**
+     * Constructs a new {@link TunerDescramblerRequest} with the given parameters.
+     *
+     * @param clientId id of the client.
+     */
+    public TunerDescramblerRequest(int clientId) {
+        mClientId = clientId;
+    }
+
+    /**
+     * Returns the id of the client.
+     */
+    public int getClientId() {
+        return mClientId;
+    }
+
+    // Parcelable
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder(128);
+        b.append("TunerDescramblerRequest {clientId=").append(mClientId);
+        b.append("}");
+        return b.toString();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mClientId);
+    }
+}
diff --git a/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java b/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
index 7c11ed4..524b6c2 100644
--- a/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
+++ b/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
@@ -65,6 +65,7 @@
     public static final int INVALID_LNB_ID = -1;
     public static final int INVALID_TV_INPUT_DEVICE_ID = -1;
     public static final int INVALID_TV_INPUT_PORT_ID = -1;
+    public static final int INVALID_RESOURCE_HANDLE = -1;
 
     private final ITunerResourceManager mService;
     private final int mUserId;
@@ -260,6 +261,71 @@
     }
 
     /**
+     * Requests a Tuner Demux resource.
+     *
+     * <p>There are three possible scenarios:
+     * <ul>
+     * <li>If there is Demux available, the API would send the handle back.
+     *
+     * <li>If no Demux is available but the current request has a higher priority than other uses of
+     * demuxes, the API will send {@link IResourcesReclaimListener#onReclaimResources()} to the
+     * {@link Tuner}. Tuner would handle the resource reclaim on the holder of lower priority and
+     * notify the holder of its resource loss.
+     *
+     * <li>If no Demux system can be granted, the API would return false.
+     * <ul>
+     *
+     * @param request {@link TunerDemuxRequest} information of the current request.
+     * @param demuxHandle a one-element array to return the granted Demux handle.
+     *                    If no Demux granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
+     *
+     * @return true if there is Demux granted.
+     */
+    public boolean requestDemux(@NonNull TunerDemuxRequest request, @NonNull int[] demuxHandle) {
+        boolean result = false;
+        try {
+            result = mService.requestDemux(request, demuxHandle);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return result;
+    }
+
+    /**
+     * Requests a Tuner Descrambler resource.
+     *
+     * <p>There are three possible scenarios:
+     * <ul>
+     * <li>If there is Descrambler available, the API would send the handle back.
+     *
+     * <li>If no Descrambler is available but the current request has a higher priority than other
+     * uses of descramblers, the API will send
+     * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
+     * handle the resource reclaim on the holder of lower priority and notify the holder of its
+     * resource loss.
+     *
+     * <li>If no Descrambler system can be granted, the API would return false.
+     * <ul>
+     *
+     * @param request {@link TunerDescramblerRequest} information of the current request.
+     * @param descramblerHandle a one-element array to return the granted Descrambler handle.
+     *                          If no Descrambler granted, this will return
+     *                          {@link #INVALID_RESOURCE_HANDLE}.
+     *
+     * @return true if there is Descrambler granted.
+     */
+    public boolean requestDescrambler(@NonNull TunerDescramblerRequest request,
+                @NonNull int[] descramblerHandle) {
+        boolean result = false;
+        try {
+            result = mService.requestDescrambler(request, descramblerHandle);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return result;
+    }
+
+    /**
      * Requests a CAS session resource.
      *
      * <p>There are three possible scenarios:
@@ -345,6 +411,36 @@
     }
 
     /**
+     * Notifies the TRM that the Demux with the given handle has been released.
+     *
+     * <p>Client must call this whenever it releases an Demux.
+     *
+     * @param demuxHandle the handle of the released Tuner Demux.
+     */
+    public void releaseDemux(int demuxHandle) {
+        try {
+            mService.releaseDemux(demuxHandle);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Notifies the TRM that the Descrambler with the given handle has been released.
+     *
+     * <p>Client must call this whenever it releases an Descrambler.
+     *
+     * @param descramblerHandle the handle of the released Tuner Descrambler.
+     */
+    public void releaseDescrambler(int descramblerHandle) {
+        try {
+            mService.releaseDescrambler(descramblerHandle);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Notifies the TRM that the given Cas session has been released.
      *
      * <p>Client must call this whenever it releases a Cas session.
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index e8e1d0b..00f6bcb 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1039,7 +1039,7 @@
     <!-- Title for the accessibility preference to configure display color space correction. [CHAR LIMIT=NONE] -->
     <string name="accessibility_display_daltonizer_preference_title">Color correction</string>
     <!-- Subtitle for the accessibility preference to configure display color space correction. [CHAR LIMIT=NONE] -->
-    <string name="accessibility_display_daltonizer_preference_subtitle">Color correction helps people with colorblindness see more accurate colors</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle">Color correction helps the device display more accurate colors. Color correction may be helpful for people with colorblindness.</string>
     <!-- Summary shown for color space correction preference when its value is overridden by another preference [CHAR LIMIT=35] -->
     <string name="daltonizer_type_overridden">Overridden by <xliff:g id="title" example="Simulate color space">%1$s</xliff:g></string>
 
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 8fa98c8..d350d9d 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -141,6 +141,8 @@
         Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL,
         Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK,
         Settings.Secure.UI_NIGHT_MODE,
+        Settings.Secure.DARK_THEME_CUSTOM_START_TIME,
+        Settings.Secure.DARK_THEME_CUSTOM_END_TIME,
         Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST,
         Settings.Secure.SKIP_DIRECTION,
         Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 75c5f95..4d33b62 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -28,6 +28,7 @@
 import static android.provider.settings.validators.SettingsValidators.NON_NEGATIVE_INTEGER_VALIDATOR;
 import static android.provider.settings.validators.SettingsValidators.NULLABLE_COMPONENT_NAME_VALIDATOR;
 import static android.provider.settings.validators.SettingsValidators.PACKAGE_NAME_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.NONE_NEGATIVE_LONG_VALIDATOR;
 import static android.provider.settings.validators.SettingsValidators.TILE_LIST_VALIDATOR;
 import static android.provider.settings.validators.SettingsValidators.TTS_LIST_VALIDATOR;
 
@@ -235,7 +236,9 @@
         VALIDATORS.put(Secure.AWARE_TAP_PAUSE_TOUCH_COUNT, NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(Secure.ODI_CAPTIONS_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.DARK_MODE_DIALOG_SEEN, BOOLEAN_VALIDATOR);
-        VALIDATORS.put(Secure.UI_NIGHT_MODE, new InclusiveIntegerRangeValidator(0, 2));
+        VALIDATORS.put(Secure.UI_NIGHT_MODE, NON_NEGATIVE_INTEGER_VALIDATOR);
+        VALIDATORS.put(Secure.DARK_THEME_CUSTOM_START_TIME, NONE_NEGATIVE_LONG_VALIDATOR);
+        VALIDATORS.put(Secure.DARK_THEME_CUSTOM_END_TIME, NONE_NEGATIVE_LONG_VALIDATOR);
         VALIDATORS.put(Secure.GLOBAL_ACTIONS_PANEL_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.AWARE_LOCK_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.DISPLAY_DENSITY_FORCED, NON_NEGATIVE_INTEGER_VALIDATOR);
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SettingsValidators.java
index 71c7544..8d5c6e6 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SettingsValidators.java
@@ -207,4 +207,15 @@
 
     static final Validator ACCESSIBILITY_SHORTCUT_TARGET_LIST_VALIDATOR =
             new AccessibilityShortcutTargetListValidator();
+
+    static final Validator NONE_NEGATIVE_LONG_VALIDATOR = new Validator() {
+        @Override
+        public boolean validate(String value) {
+            try {
+                return Long.parseLong(value) >= 0;
+            } catch (NumberFormatException e) {
+                return false;
+            }
+        }
+    };
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 36bb8ef..b6e31d2 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -75,6 +75,9 @@
         sBroadcastOnRestore.add(Settings.Secure.ENABLED_VR_LISTENERS);
         sBroadcastOnRestore.add(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
         sBroadcastOnRestore.add(Settings.Global.BLUETOOTH_ON);
+        sBroadcastOnRestore.add(Settings.Secure.UI_NIGHT_MODE);
+        sBroadcastOnRestore.add(Settings.Secure.DARK_THEME_CUSTOM_START_TIME);
+        sBroadcastOnRestore.add(Settings.Secure.DARK_THEME_CUSTOM_END_TIME);
     }
 
     private interface SettingsLookup {
diff --git a/packages/SettingsProvider/test/src/android/provider/settings/validators/SettingsValidatorsTest.java b/packages/SettingsProvider/test/src/android/provider/settings/validators/SettingsValidatorsTest.java
index bb9e6f6..9134d87 100644
--- a/packages/SettingsProvider/test/src/android/provider/settings/validators/SettingsValidatorsTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/settings/validators/SettingsValidatorsTest.java
@@ -277,6 +277,27 @@
     }
 
     @Test
+    public void testPositiveLongValidator_zero() {
+        assertTrue(SettingsValidators.NONE_NEGATIVE_LONG_VALIDATOR.validate("0"));
+    }
+
+    @Test
+    public void testPositiveLongValidator_negative() {
+        assertFalse(SettingsValidators.NONE_NEGATIVE_LONG_VALIDATOR.validate("-5"));
+    }
+
+
+    @Test
+    public void testPositiveLongValidator_positive() {
+        assertTrue(SettingsValidators.NONE_NEGATIVE_LONG_VALIDATOR.validate("5"));
+    }
+
+    @Test
+    public void testPositiveLongValidator_floatFormat() {
+        assertFalse(SettingsValidators.NONE_NEGATIVE_LONG_VALIDATOR.validate("4.4756"));
+    }
+
+    @Test
     public void testTTSListValidator_withNullInput_returnsFalse() {
         assertFalse(SettingsValidators.TTS_LIST_VALIDATOR.validate(null));
     }
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 18fec29..3543073 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2631,10 +2631,7 @@
     <string name="controls_favorite_default_title">Controls</string>
     <!-- Controls management controls screen subtitle [CHAR LIMIT=NONE] -->
     <string name="controls_favorite_subtitle">Choose controls for quick access</string>
-    <!-- Controls management controls screen favorites header [CHAR LIMIT=50] -->
-    <string name="controls_favorite_header_favorites">Favorites</string>
-    <!-- Controls management controls screen all header [CHAR LIMIT=50] -->
-    <string name="controls_favorite_header_all">All</string>
+
     <!-- Controls management controls screen error on load message [CHAR LIMIT=60] -->
     <string name="controls_favorite_load_error">The list of all controls could not be loaded.</string>
     <!-- Controls management controls screen header for Other zone [CHAR LIMIT=60] -->
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java
index b813e21..7570c2c 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java
@@ -18,7 +18,11 @@
 
 import android.app.WallpaperManager;
 import android.content.Context;
+import android.os.IBinder;
 
+/**
+ * @see WallpaperManager
+ */
 public class WallpaperManagerCompat {
     private final WallpaperManager mWallpaperManager;
 
@@ -26,7 +30,10 @@
         mWallpaperManager = context.getSystemService(WallpaperManager.class);
     }
 
-    public void setWallpaperZoomOut(float zoom) {
-        mWallpaperManager.setWallpaperZoomOut(zoom);
+    /**
+     * @see WallpaperManager#setWallpaperZoomOut(IBinder, float)
+     */
+    public void setWallpaperZoomOut(IBinder windowToken, float zoom) {
+        mWallpaperManager.setWallpaperZoomOut(windowToken, zoom);
     }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index dbcdead..23fa645 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -203,6 +203,11 @@
             }
         }
 
+        @Override
+        public boolean shouldZoomOutWallpaper() {
+            return true;
+        }
+
         private void waitForBackgroundRendering() {
             synchronized (mMonitor) {
                 try {
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index cab9f18..537a812 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -48,6 +48,7 @@
 import android.graphics.Path;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.graphics.RectF;
 import android.graphics.Region;
 import android.hardware.display.DisplayManager;
 import android.os.Handler;
@@ -725,7 +726,8 @@
         private final Rect mBoundingRect = new Rect();
         private final Path mBoundingPath = new Path();
         // Don't initialize these yet because they may never exist
-        private Rect mProtectionRect;
+        private RectF mProtectionRect;
+        private RectF mProtectionRectOrig;
         private Path mProtectionPath;
         private Path mProtectionPathOrig;
         private Rect mTotalBounds = new Rect();
@@ -818,7 +820,11 @@
                 mProtectionPath = new Path();
             }
             mProtectionPathOrig.set(protectionPath);
-            mProtectionRect = pathBounds;
+            if (mProtectionRectOrig == null) {
+                mProtectionRectOrig = new RectF();
+                mProtectionRect = new RectF();
+            }
+            mProtectionRectOrig.set(pathBounds);
         }
 
         void setShowProtection(boolean shouldShow) {
@@ -898,6 +904,7 @@
                 // Reset the protection path so we don't aggregate rotations
                 mProtectionPath.set(mProtectionPathOrig);
                 mProtectionPath.transform(m);
+                m.mapRect(mProtectionRect, mProtectionRectOrig);
             }
         }
 
@@ -964,7 +971,8 @@
             if (mShowProtection) {
                 // Make sure that our measured height encompases the protection
                 mTotalBounds.union(mBoundingRect);
-                mTotalBounds.union(mProtectionRect);
+                mTotalBounds.union((int) mProtectionRect.left, (int) mProtectionRect.top,
+                        (int) mProtectionRect.right, (int) mProtectionRect.bottom);
                 setMeasuredDimension(
                         resolveSizeAndState(mTotalBounds.width(), widthMeasureSpec, 0),
                         resolveSizeAndState(mTotalBounds.height(), heightMeasureSpec, 0));
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
index d109d4a..f8d4a39 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
@@ -255,12 +255,14 @@
         override fun onError(token: IBinder, s: String) {
             hasError = true
             _loadCancelInternal = {}
+            currentProvider?.cancelLoadTimeout()
             backgroundExecutor.execute(OnLoadErrorRunnable(token, s, callback))
         }
 
         override fun onComplete(token: IBinder) {
             _loadCancelInternal = {}
             if (!hasError) {
+                currentProvider?.cancelLoadTimeout()
                 backgroundExecutor.execute(OnLoadRunnable(token, loadedControls, callback))
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
index 50f7d76..4918bd7 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
@@ -228,6 +228,11 @@
         invokeOrQueue({ load(subscriber) }, Message.Load(subscriber))
     }
 
+    fun cancelLoadTimeout() {
+        onLoadCanceller?.run()
+        onLoadCanceller = null
+    }
+
     /**
      * Request a subscription to the [Publisher] returned by [ControlsProviderService.publisherFor]
      *
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 513580f..2e9ce12 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -19,7 +19,6 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.pm.PackageManager;
-import android.view.Choreographer;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.BootCompleteCache;
@@ -31,22 +30,16 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.stackdivider.Divider;
-import com.android.systemui.statusbar.BlurUtils;
 import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.NotificationShadeWindowBlurController;
-import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
 import com.android.systemui.statusbar.notification.people.PeopleHubModule;
 import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
 import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
-import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.KeyguardLiftController;
-import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.concurrency.ConcurrencyModule;
 import com.android.systemui.util.sensors.AsyncSensorManager;
 import com.android.systemui.util.time.SystemClock;
@@ -98,21 +91,6 @@
                 keyguardUpdateMonitor, dumpManager);
     }
 
-    @Singleton
-    @Provides
-    @Nullable
-    static NotificationShadeWindowBlurController providesBlurController(BlurUtils blurUtils,
-            SysuiStatusBarStateController statusBarStateController,
-            DumpManager dumpManager, BiometricUnlockController biometricUnlockController,
-            KeyguardStateController keyguardStateController,
-            NotificationShadeWindowController notificationShadeWindowController,
-            Choreographer choreographer) {
-        return blurUtils.supportsBlursOnWindows() ? new NotificationShadeWindowBlurController(
-                statusBarStateController, blurUtils, biometricUnlockController,
-                keyguardStateController, notificationShadeWindowController, choreographer,
-                dumpManager) : null;
-    }
-
     /** */
     @Binds
     public abstract NotificationRowBinder bindNotificationRowBinder(
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
index c45063a..f6fccc0 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -161,15 +161,8 @@
             }
 
             int scrimOpacity = -1;
-            if (mPaused || mScreenOff) {
-                // If AOD is paused, force the screen black until the
-                // sensor reports a new brightness. This ensures that when the screen comes on
-                // again, it will only show after the brightness sensor has stabilized,
-                // avoiding a potential flicker.
-                scrimOpacity = 255;
-            } else if (!mScreenOff && mLightSensor == null) {
-                // No light sensor but previous state turned the screen black. Make the scrim
-                // transparent and below views visible.
+            if (mLightSensor == null) {
+                // No light sensor, scrims are always transparent.
                 scrimOpacity = 0;
             } else if (brightnessReady) {
                 // Only unblank scrim once brightness is ready.
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 786ad2c..27c81ce 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -1793,7 +1793,7 @@
                         int alpha = (int) (animatedValue * mScrimAlpha * 255);
                         mBackgroundDrawable.setAlpha(alpha);
                         mBlurUtils.applyBlur(mGlobalActionsLayout.getViewRootImpl(),
-                                mBlurUtils.radiusForRatio(animatedValue));
+                                mBlurUtils.blurRadiusOfRatio(animatedValue));
                     })
                     .start();
             if (mControlsUiController != null) {
@@ -1823,7 +1823,7 @@
                         int alpha = (int) (animatedValue * mScrimAlpha * 255);
                         mBackgroundDrawable.setAlpha(alpha);
                         mBlurUtils.applyBlur(mGlobalActionsLayout.getViewRootImpl(),
-                                mBlurUtils.radiusForRatio(animatedValue));
+                                mBlurUtils.blurRadiusOfRatio(animatedValue));
                     })
                     .start();
             dismissPanel();
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index 280a248..bbb57bd 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -151,7 +151,7 @@
         if (mBlurUtils.supportsBlursOnWindows()) {
             background.setAlpha((int) (ScrimController.BUSY_SCRIM_ALPHA * 255));
             mBlurUtils.applyBlur(d.getWindow().getDecorView().getViewRootImpl(),
-                        mBlurUtils.radiusForRatio(1));
+                        mBlurUtils.blurRadiusOfRatio(1));
         } else {
             background.setAlpha((int) (SHUTDOWN_SCRIM_ALPHA * 255));
         }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index 00b977e..51113ac 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -415,11 +415,16 @@
         }
         mLastReportedBounds.set(destinationBounds);
         try {
+            // If we are animating to fullscreen, then we need to reset the override bounds on the
+            // task to ensure that the task "matches" the parent's bounds
+            Rect taskBounds = direction == TRANSITION_DIRECTION_TO_FULLSCREEN
+                    ? null
+                    : destinationBounds;
             final WindowContainerTransaction wct = new WindowContainerTransaction();
             if (direction == TRANSITION_DIRECTION_TO_PIP) {
-                wct.scheduleFinishEnterPip(mToken, destinationBounds);
+                wct.scheduleFinishEnterPip(mToken, taskBounds);
             } else {
-                wct.setBounds(mToken, destinationBounds);
+                wct.setBounds(mToken, taskBounds);
             }
             wct.setBoundsChangeTransaction(mToken, tx);
             mTaskOrganizerController.applyContainerTransaction(wct, null /* ITaskOrganizer */);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAppOpsListener.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAppOpsListener.java
index b09d6e1..7dfd99c 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAppOpsListener.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAppOpsListener.java
@@ -44,7 +44,7 @@
             try {
                 // Dismiss the PiP once the user disables the app ops setting for that package
                 final Pair<ComponentName, Integer> topPipActivityInfo =
-                        PipUtils.getTopPinnedActivity(mContext, mActivityManager);
+                        PipUtils.getTopPipActivity(mContext, mActivityManager);
                 if (topPipActivityInfo.first != null) {
                     final ApplicationInfo appInfo = mContext.getPackageManager()
                             .getApplicationInfoAsUser(packageName, 0, topPipActivityInfo.second);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 1fdf92e..32e9a03 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -115,7 +115,7 @@
 
         @Override
         public void onActivityUnpinned() {
-            final Pair<ComponentName, Integer> topPipActivityInfo = PipUtils.getTopPinnedActivity(
+            final Pair<ComponentName, Integer> topPipActivityInfo = PipUtils.getTopPipActivity(
                     mContext, mActivityManager);
             final ComponentName topActivity = topPipActivityInfo.first;
             mMenuController.onActivityUnpinned();
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
index e57b416..849a62a 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
@@ -231,7 +231,7 @@
      */
     private void resolveActiveMediaController(List<MediaController> controllers) {
         if (controllers != null) {
-            final ComponentName topActivity = PipUtils.getTopPinnedActivity(mContext,
+            final ComponentName topActivity = PipUtils.getTopPipActivity(mContext,
                     mActivityManager).first;
             if (topActivity != null) {
                 for (int i = 0; i < controllers.size(); i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index fc04f79..2b9b171 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -569,7 +569,7 @@
 
     private void showSettings() {
         final Pair<ComponentName, Integer> topPipActivityInfo =
-                PipUtils.getTopPinnedActivity(this, ActivityManager.getService());
+                PipUtils.getTopPipActivity(this, ActivityManager.getService());
         if (topPipActivityInfo.first != null) {
             final UserHandle user = UserHandle.of(topPipActivityInfo.second);
             final Intent settingsIntent = new Intent(ACTION_PICTURE_IN_PICTURE_SETTINGS,
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 90db91a..b5fb1a9 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -31,6 +31,7 @@
 import android.os.Handler;
 import android.os.RemoteException;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Size;
 import android.view.IPinnedStackController;
 import android.view.InputEvent;
@@ -148,8 +149,11 @@
 
         @Override
         public void onPipDismiss() {
-            MetricsLoggerWrapper.logPictureInPictureDismissByTap(mContext,
-                    PipUtils.getTopPinnedActivity(mContext, mActivityManager));
+            Pair<ComponentName, Integer> topPipActivity = PipUtils.getTopPipActivity(mContext,
+                    mActivityManager);
+            if (topPipActivity.first != null) {
+                MetricsLoggerWrapper.logPictureInPictureDismissByTap(mContext, topPipActivity);
+            }
             mMotionHelper.dismissPip();
         }
 
@@ -653,7 +657,7 @@
                 // Check if the user dragged or flung the PiP offscreen to dismiss it
                 if (mMotionHelper.shouldDismissPip() || isFlingToBot) {
                     MetricsLoggerWrapper.logPictureInPictureDismissByDrag(mContext,
-                            PipUtils.getTopPinnedActivity(mContext, mActivityManager));
+                            PipUtils.getTopPipActivity(mContext, mActivityManager));
                     mMotionHelper.animateDismiss(
                             vel.x, vel.y,
                             PipTouchHandler.this::updateDismissFraction /* updateAction */);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java
index 1ed1904..4cfec01 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java
@@ -36,7 +36,7 @@
      * @return the ComponentName and user id of the top non-SystemUI activity in the pinned stack.
      *         The component name may be null if no such activity exists.
      */
-    public static Pair<ComponentName, Integer> getTopPinnedActivity(Context context,
+    public static Pair<ComponentName, Integer> getTopPipActivity(Context context,
             IActivityManager activityManager) {
         try {
             final String sysUiPackageName = context.getPackageName();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
index 34c0860..c523b7b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
@@ -50,7 +50,7 @@
     /**
      * Translates a ratio from 0 to 1 to a blur radius in pixels.
      */
-    fun radiusForRatio(ratio: Float): Int {
+    fun blurRadiusOfRatio(ratio: Float): Int {
         if (ratio == 0f) {
             return 0
         }
@@ -58,6 +58,17 @@
     }
 
     /**
+     * Translates a blur radius in pixels to a ratio between 0 to 1.
+     */
+    fun ratioOfBlurRadius(blur: Int): Float {
+        if (blur == 0) {
+            return 0f
+        }
+        return MathUtils.map(minBlurRadius.toFloat(), maxBlurRadius.toFloat(),
+                0f /* maxStart */, 1f /* maxStop */, blur.toFloat())
+    }
+
+    /**
      * Applies background blurs to a {@link ViewRootImpl}.
      *
      * @param viewRootImpl The window root.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowBlurController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
similarity index 83%
rename from packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowBlurController.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 6e905a3..901ed3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowBlurController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -19,6 +19,7 @@
 import android.animation.Animator
 import android.animation.AnimatorListenerAdapter
 import android.animation.ValueAnimator
+import android.app.WallpaperManager
 import android.view.Choreographer
 import android.view.View
 import androidx.dynamicanimation.animation.FloatPropertyCompat
@@ -30,7 +31,6 @@
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.statusbar.phone.BiometricUnlockController
 import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK
-import com.android.systemui.statusbar.phone.NotificationShadeWindowController
 import com.android.systemui.statusbar.phone.PanelExpansionListener
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import java.io.FileDescriptor
@@ -43,13 +43,13 @@
  * Controller responsible for statusbar window blur.
  */
 @Singleton
-class NotificationShadeWindowBlurController @Inject constructor(
+class NotificationShadeDepthController @Inject constructor(
     private val statusBarStateController: SysuiStatusBarStateController,
     private val blurUtils: BlurUtils,
     private val biometricUnlockController: BiometricUnlockController,
     private val keyguardStateController: KeyguardStateController,
-    private val notificationShadeWindowController: NotificationShadeWindowController,
     private val choreographer: Choreographer,
+    private val wallpaperManager: WallpaperManager,
     dumpManager: DumpManager
 ) : PanelExpansionListener, Dumpable {
     companion object {
@@ -63,12 +63,12 @@
     private var updateScheduled: Boolean = false
     private var shadeExpansion = 1.0f
     private val shadeSpring = SpringAnimation(this, object :
-            FloatPropertyCompat<NotificationShadeWindowBlurController>("shadeBlurRadius") {
-        override fun setValue(rect: NotificationShadeWindowBlurController?, value: Float) {
+            FloatPropertyCompat<NotificationShadeDepthController>("shadeBlurRadius") {
+        override fun setValue(rect: NotificationShadeDepthController?, value: Float) {
             shadeBlurRadius = value.toInt()
         }
 
-        override fun getValue(rect: NotificationShadeWindowBlurController?): Float {
+        override fun getValue(rect: NotificationShadeDepthController?): Float {
             return shadeBlurRadius.toFloat()
         }
     })
@@ -84,12 +84,6 @@
             field = value
             scheduleUpdate()
         }
-    private var incomingNotificationBlurRadius = 0
-        set(value) {
-            if (field == value) return
-            field = value
-            scheduleUpdate()
-        }
 
     /**
      * Callback that updates the window blur value and is called only once per frame.
@@ -97,13 +91,9 @@
     private val updateBlurCallback = Choreographer.FrameCallback {
         updateScheduled = false
 
-        var notificationBlur = 0
-        if (statusBarStateController.state == StatusBarState.KEYGUARD) {
-            notificationBlur = (incomingNotificationBlurRadius * shadeExpansion).toInt()
-        }
-
-        val blur = max(max(shadeBlurRadius, wakeAndUnlockBlurRadius), notificationBlur)
+        val blur = max(shadeBlurRadius, wakeAndUnlockBlurRadius)
         blurUtils.applyBlur(root.viewRootImpl, blur)
+        wallpaperManager.setWallpaperZoomOut(root.windowToken, blurUtils.ratioOfBlurRadius(blur))
     }
 
     /**
@@ -123,7 +113,7 @@
                 interpolator = Interpolators.DECELERATE_QUINT
                 addUpdateListener { animation: ValueAnimator ->
                     wakeAndUnlockBlurRadius =
-                            blurUtils.radiusForRatio(animation.animatedValue as Float)
+                            blurUtils.blurRadiusOfRatio(animation.animatedValue as Float)
                 }
                 addListener(object : AnimatorListenerAdapter() {
                     override fun onAnimationEnd(animation: Animator?) {
@@ -163,7 +153,7 @@
 
         var newBlur = 0
         if (statusBarStateController.state == StatusBarState.SHADE) {
-            newBlur = blurUtils.radiusForRatio(expansion)
+            newBlur = blurUtils.blurRadiusOfRatio(expansion)
         }
 
         if (shadeBlurRadius == newBlur) {
@@ -181,11 +171,11 @@
     }
 
     override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
-        IndentingPrintWriter(pw, "  ").use {
+        IndentingPrintWriter(pw, "  ").let {
             it.println("StatusBarWindowBlurController:")
             it.increaseIndent()
             it.println("shadeBlurRadius: $shadeBlurRadius")
             it.println("wakeAndUnlockBlur: $wakeAndUnlockBlurRadius")
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
index c5c3fff..c54fa29 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
@@ -27,6 +27,8 @@
  */
 public class KeyguardIndicationTextView extends TextView {
 
+    private CharSequence mText = "";
+
     public KeyguardIndicationTextView(Context context) {
         super(context);
     }
@@ -53,10 +55,12 @@
 
         // TODO: Animation, make sure that we will show one indication long enough.
         if (TextUtils.isEmpty(text)) {
+            mText = "";
             setVisibility(View.INVISIBLE);
-        } else {
+        } else if (!TextUtils.equals(text, mText)) {
+            mText = text;
             setVisibility(View.VISIBLE);
-            setText(text);
+            setText(mText);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
index f38d416..596a607 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
@@ -18,7 +18,6 @@
 
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 
-import android.annotation.Nullable;
 import android.app.StatusBarManager;
 import android.graphics.RectF;
 import android.hardware.display.AmbientDisplayConfiguration;
@@ -44,7 +43,7 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DragDownHelper;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.NotificationShadeWindowBlurController;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
 import com.android.systemui.statusbar.PulseExpansionHandler;
 import com.android.systemui.statusbar.SuperStatusBarViewFactory;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
@@ -82,7 +81,7 @@
     private final CommandQueue mCommandQueue;
     private final NotificationShadeWindowView mView;
     private final ShadeController mShadeController;
-    private final NotificationShadeWindowBlurController mBlurController;
+    private final NotificationShadeDepthController mDepthController;
 
     private GestureDetector mGestureDetector;
     private View mBrightnessMirror;
@@ -126,7 +125,7 @@
             CommandQueue commandQueue,
             ShadeController shadeController,
             DockManager dockManager,
-            @Nullable NotificationShadeWindowBlurController blurController,
+            NotificationShadeDepthController depthController,
             NotificationShadeWindowView notificationShadeWindowView,
             NotificationPanelViewController notificationPanelViewController,
             SuperStatusBarViewFactory statusBarViewFactory) {
@@ -149,7 +148,7 @@
         mShadeController = shadeController;
         mDockManager = dockManager;
         mNotificationPanelViewController = notificationPanelViewController;
-        mBlurController = blurController;
+        mDepthController = depthController;
         mStatusBarViewFactory = statusBarViewFactory;
 
         // This view is not part of the newly inflated expanded status bar.
@@ -394,10 +393,8 @@
                         mView.getContext(), mView, expandHelperCallback,
                         dragDownCallback, mFalsingManager));
 
-        if (mBlurController != null) {
-            mBlurController.setRoot(mView);
-            mNotificationPanelViewController.addExpansionListener(mBlurController);
-        }
+        mDepthController.setRoot(mView);
+        mNotificationPanelViewController.addExpansionListener(mDepthController);
     }
 
     public NotificationShadeWindowView getView() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/AudioRecordingDisclosureBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/AudioRecordingDisclosureBar.java
index 73ffe42..e70e30a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/AudioRecordingDisclosureBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/AudioRecordingDisclosureBar.java
@@ -24,6 +24,7 @@
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.annotation.IntDef;
+import android.annotation.UiThread;
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -133,6 +134,7 @@
                 new OnActiveRecordingListener());
     }
 
+    @UiThread
     private void onStartedRecording(String packageName) {
         if (!mActiveAudioRecordingPackages.add(packageName)) {
             // This app is already known to perform recording
@@ -164,6 +166,7 @@
         }
     }
 
+    @UiThread
     private void onDoneRecording(String packageName) {
         if (!mActiveAudioRecordingPackages.remove(packageName)) {
             // Was not marked as an active recorder, do nothing
@@ -179,6 +182,7 @@
         }
     }
 
+    @UiThread
     private void show(String packageName) {
         // Inflate the indicator view
         mIndicatorView = LayoutInflater.from(mContext).inflate(
@@ -253,6 +257,7 @@
         mState = STATE_APPEARING;
     }
 
+    @UiThread
     private void expand(String packageName) {
         final String label = getApplicationLabel(packageName);
         mTextView.setText(mContext.getString(R.string.app_accessed_mic, label));
@@ -276,6 +281,7 @@
         mState = STATE_MAXIMIZING;
     }
 
+    @UiThread
     private void minimize() {
         final int targetOffset = mTextsContainers.getWidth();
         final AnimatorSet set = new AnimatorSet();
@@ -297,6 +303,7 @@
         mState = STATE_MINIMIZING;
     }
 
+    @UiThread
     private void hide() {
         final int targetOffset =
                 mIndicatorView.getWidth() - (int) mIconTextsContainer.getTranslationX();
@@ -317,12 +324,14 @@
         mState = STATE_DISAPPEARING;
     }
 
+    @UiThread
     private void onExpanded() {
         mState = STATE_SHOWN;
 
         mIndicatorView.postDelayed(this::minimize, MAXIMIZED_DURATION);
     }
 
+    @UiThread
     private void onMinimized() {
         mState = STATE_MINIMIZED;
 
@@ -336,6 +345,7 @@
         }
     }
 
+    @UiThread
     private void onHidden() {
         final WindowManager windowManager = (WindowManager) mContext.getSystemService(
                 Context.WINDOW_SERVICE);
@@ -358,6 +368,7 @@
         }
     }
 
+    @UiThread
     private void startPulsatingAnimation() {
         final View pulsatingView = mIconTextsContainer.findViewById(R.id.pulsating_circle);
         final ObjectAnimator animator =
diff --git a/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java b/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java
index 23df991..ccb8699 100644
--- a/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java
+++ b/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java
@@ -324,7 +324,7 @@
 
         @Override
         public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
-                boolean sync) {}
+                float zoom, boolean sync) {}
 
         @Override
         public void dispatchWallpaperCommand(String action, int x, int y,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
index f5ad40b..c25d4e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
@@ -63,7 +63,7 @@
     private lateinit var mockControlsController: ControlsController
 
     @Captor
-    private lateinit var subscriberCaptor: ArgumentCaptor<IControlsSubscriber>
+    private lateinit var subscriberCaptor: ArgumentCaptor<IControlsSubscriber.Stub>
 
     @Captor
     private lateinit var loadSubscriberCaptor: ArgumentCaptor<IControlsSubscriber.Stub>
@@ -149,6 +149,44 @@
     }
 
     @Test
+    fun testLoad_onCompleteRemovesTimeout() {
+        val callback = object : ControlsBindingController.LoadCallback {
+            override fun error(message: String) {}
+
+            override fun accept(t: List<Control>) {}
+        }
+        val subscription = mock(IControlsSubscription::class.java)
+
+        val canceller = controller.bindAndLoad(TEST_COMPONENT_NAME_1, callback)
+
+        verify(providers[0]).maybeBindAndLoad(capture(subscriberCaptor))
+        val b = Binder()
+        subscriberCaptor.value.onSubscribe(b, subscription)
+
+        subscriberCaptor.value.onComplete(b)
+        verify(providers[0]).cancelLoadTimeout()
+    }
+
+    @Test
+    fun testLoad_onErrorRemovesTimeout() {
+        val callback = object : ControlsBindingController.LoadCallback {
+            override fun error(message: String) {}
+
+            override fun accept(t: List<Control>) {}
+        }
+        val subscription = mock(IControlsSubscription::class.java)
+
+        val canceller = controller.bindAndLoad(TEST_COMPONENT_NAME_1, callback)
+
+        verify(providers[0]).maybeBindAndLoad(capture(subscriberCaptor))
+        val b = Binder()
+        subscriberCaptor.value.onSubscribe(b, subscription)
+
+        subscriberCaptor.value.onError(b, "")
+        verify(providers[0]).cancelLoadTimeout()
+    }
+
+    @Test
     fun testBindAndLoad_noCancelAfterOnError() {
         val callback = object : ControlsBindingController.LoadCallback {
             override fun error(message: String) {}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
index 64a9615..2d3757c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
@@ -43,6 +43,7 @@
 import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito.`when`
+import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
@@ -143,6 +144,19 @@
     }
 
     @Test
+    fun testMaybeBindAndLoad_timeoutCancelled() {
+        manager.maybeBindAndLoad(subscriberService)
+        executor.runAllReady()
+
+        manager.cancelLoadTimeout()
+
+        executor.advanceClockToLast()
+        executor.runAllReady()
+
+        verify(subscriberService, never()).onError(any(), anyString())
+    }
+
+    @Test
     fun testMaybeBindAndSubscribe() {
         val list = listOf("TEST_ID")
         manager.maybeBindAndSubscribe(list, subscriberService)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
index 9117ea8..f535351 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
@@ -248,31 +248,6 @@
     }
 
     @Test
-    public void pausingAod_softBlanks_withSpuriousSensorDuringPause() throws Exception {
-        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
-        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
-        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSING);
-        mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);
-
-        reset(mDozeHost);
-        mSensor.sendSensorEvent(1);
-        verify(mDozeHost).setAodDimmingScrim(eq(1f));
-    }
-
-    @Test
-    public void screenOff_softBlanks() throws Exception {
-        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
-        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
-        mScreen.transitionTo(DOZE_AOD, DOZE);
-        verify(mDozeHost).setAodDimmingScrim(eq(1f));
-
-        reset(mDozeHost);
-        mScreen.transitionTo(DOZE, DOZE_AOD);
-        mSensor.sendSensorEvent(2);
-        verify(mDozeHost).setAodDimmingScrim(eq(0f));
-    }
-
-    @Test
     public void pausingAod_unblanksAfterSensor() throws Exception {
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
         mScreen.transitionTo(INITIALIZED, DOZE_AOD);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java
new file mode 100644
index 0000000..291c039
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.View;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class KeyguardIndicationTextViewTest extends SysuiTestCase {
+
+    private KeyguardIndicationTextView mKeyguardIndicationTextView;
+
+    @Before
+    public void setup() {
+        mKeyguardIndicationTextView = new KeyguardIndicationTextView(mContext);
+    }
+
+    @Test
+    public void switchIndication_null_hideIndication() {
+        mKeyguardIndicationTextView.switchIndication(null /* text */);
+
+        assertThat(mKeyguardIndicationTextView.getVisibility()).isEqualTo(View.INVISIBLE);
+        assertThat(mKeyguardIndicationTextView.getText()).isEqualTo("");
+    }
+
+    @Test
+    public void switchIndication_emptyText_hideIndication() {
+        mKeyguardIndicationTextView.switchIndication("" /* text */);
+
+        assertThat(mKeyguardIndicationTextView.getVisibility()).isEqualTo(View.INVISIBLE);
+        assertThat(mKeyguardIndicationTextView.getText()).isEqualTo("");
+    }
+
+    @Test
+    public void switchIndication_newText_updateProperly() {
+        mKeyguardIndicationTextView.switchIndication("test_indication" /* text */);
+
+        assertThat(mKeyguardIndicationTextView.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mKeyguardIndicationTextView.getText()).isEqualTo("test_indication");
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
index c5b6969..cc2d1c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
@@ -37,7 +37,7 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DragDownHelper;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.NotificationShadeWindowBlurController;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
 import com.android.systemui.statusbar.PulseExpansionHandler;
 import com.android.systemui.statusbar.SuperStatusBarViewFactory;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
@@ -81,7 +81,7 @@
     @Mock private DockManager mDockManager;
     @Mock private NotificationPanelViewController mNotificationPanelViewController;
     @Mock private NotificationStackScrollLayout mNotificationStackScrollLayout;
-    @Mock private NotificationShadeWindowBlurController mNotificationShadeWindowBlurController;
+    @Mock private NotificationShadeDepthController mNotificationShadeDepthController;
     @Mock private SuperStatusBarViewFactory mStatusBarViewFactory;
 
     @Before
@@ -116,7 +116,7 @@
                 new CommandQueue(mContext),
                 mShadeController,
                 mDockManager,
-                mNotificationShadeWindowBlurController,
+                mNotificationShadeDepthController,
                 mView,
                 mNotificationPanelViewController,
                 mStatusBarViewFactory);
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index 2cfe404..b464422 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -161,9 +161,6 @@
     private final Runnable mSaveToFile = this::saveToFile;
     private final SystemClock mSystemClock;
     private final BootThreshold mBootThreshold;
-    // The set of packages that have been synced with the ExplicitHealthCheckController
-    @GuardedBy("mLock")
-    private Set<String> mRequestedHealthCheckPackages = new ArraySet<>();
     @GuardedBy("mLock")
     private boolean mIsPackagesReady;
     // Flag to control whether explicit health checks are supported or not
@@ -627,22 +624,17 @@
      * @see #syncRequestsAsync
      */
     private void syncRequests() {
-        boolean syncRequired = false;
+        Set<String> packages = null;
         synchronized (mLock) {
             if (mIsPackagesReady) {
-                Set<String> packages = getPackagesPendingHealthChecksLocked();
-                if (!packages.equals(mRequestedHealthCheckPackages)) {
-                    syncRequired = true;
-                    mRequestedHealthCheckPackages = packages;
-                }
+                packages = getPackagesPendingHealthChecksLocked();
             } // else, we will sync requests when packages become ready
         }
 
         // Call outside lock to avoid holding lock when calling into the controller.
-        if (syncRequired) {
-            Slog.i(TAG, "Syncing health check requests for packages: "
-                    + mRequestedHealthCheckPackages);
-            mHealthCheckController.syncRequests(mRequestedHealthCheckPackages);
+        if (packages != null) {
+            Slog.i(TAG, "Syncing health check requests for packages: " + packages);
+            mHealthCheckController.syncRequests(packages);
         }
     }
 
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 7c833fa..eace86b 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -75,7 +75,9 @@
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.ZoneId;
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -293,7 +295,7 @@
         public void onChange(boolean selfChange, Uri uri) {
             synchronized (mLock) {
                 // setup wizard is done now so we can unblock
-                if (setupWizardCompleteForCurrentUser()) {
+                if (setupWizardCompleteForCurrentUser() && !selfChange) {
                     mSetupWizardComplete = true;
                     getContext().getContentResolver()
                             .unregisterContentObserver(mSetupWizardObserver);
@@ -348,6 +350,9 @@
         IntentFilter batteryFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
         context.registerReceiver(mBatteryReceiver, batteryFilter);
 
+        context.registerReceiver(mSettingsRestored,
+                new IntentFilter(Intent.ACTION_SETTING_RESTORED), null, mHandler);
+
         mLocalPowerManager =
                 LocalServices.getService(PowerManagerInternal.class);
         initPowerSave();
@@ -395,6 +400,22 @@
         mHandler.post(() -> updateSystemProperties());
     }
 
+    private final BroadcastReceiver mSettingsRestored = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            List<String> settings = Arrays.asList(
+                    Secure.UI_NIGHT_MODE, Secure.DARK_THEME_CUSTOM_START_TIME,
+                    Secure.DARK_THEME_CUSTOM_END_TIME);
+            if (settings.contains(intent.getExtras().getCharSequence(Intent.EXTRA_SETTING_NAME))) {
+                synchronized (mLock) {
+                    updateNightModeFromSettingsLocked(context, context.getResources(),
+                            UserHandle.getCallingUserId());
+                    updateConfigurationLocked();
+                }
+            }
+        }
+    };
+
     private void initPowerSave() {
         mPowerSave =
                 mLocalPowerManager.getLowPowerState(ServiceType.NIGHT_MODE)
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 6b16513..0e9970e 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -61,6 +61,7 @@
 import android.app.IApplicationThread;
 import android.app.IUidObserver;
 import android.compat.annotation.ChangeId;
+import android.compat.annotation.Disabled;
 import android.compat.annotation.EnabledAfter;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -70,6 +71,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManagerInternal;
+import android.content.pm.ProcessInfo;
 import android.content.res.Resources;
 import android.graphics.Point;
 import android.net.LocalSocket;
@@ -345,6 +347,14 @@
     private static final long NATIVE_HEAP_POINTER_TAGGING = 135754954; // This is a bug id.
 
     /**
+     * Enable sampled memory bug detection in the app.
+     * @see <a href="https://source.android.com/devices/tech/debug/gwp-asan">GWP-ASan</a>.
+     */
+    @ChangeId
+    @Disabled
+    private static final long GWP_ASAN = 135634846; // This is a bug id.
+
+    /**
      * Apps have no access to the private data directories of any other app, even if the other
      * app has made them world-readable.
      */
@@ -1634,6 +1644,28 @@
         return gidArray;
     }
 
+    private int decideGwpAsanLevel(ProcessRecord app) {
+        // Look at the process attribute first.
+        if (app.processInfo != null && app.processInfo.enableGwpAsan != null) {
+            return app.processInfo.enableGwpAsan ? Zygote.GWP_ASAN_LEVEL_ALWAYS
+                                                 : Zygote.GWP_ASAN_LEVEL_NEVER;
+        }
+        // Then at the applicaton attribute.
+        if (app.info.isGwpAsanEnabled() != null) {
+            return app.info.isGwpAsanEnabled() ? Zygote.GWP_ASAN_LEVEL_ALWAYS
+                                               : Zygote.GWP_ASAN_LEVEL_NEVER;
+        }
+        // If the app does not specify enableGwpAsan, the default behavior is lottery among the
+        // system apps, and disabled for user apps, unless overwritten by the compat feature.
+        if (mPlatformCompat.isChangeEnabled(GWP_ASAN, app.info)) {
+            return Zygote.GWP_ASAN_LEVEL_ALWAYS;
+        }
+        if ((app.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+            return Zygote.GWP_ASAN_LEVEL_LOTTERY;
+        }
+        return Zygote.GWP_ASAN_LEVEL_NEVER;
+    }
+
     /**
      * @return {@code true} if process start is successful, false otherwise.
      */
@@ -1803,6 +1835,8 @@
                 runtimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI;
             }
 
+            runtimeFlags |= decideGwpAsanLevel(app);
+
             String invokeWith = null;
             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
                 // Debuggable apps may include a wrapper script with their library directory.
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index c029811..a78caac 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -384,6 +384,9 @@
                     pw.println(processInfo.deniedPermissions.valueAt(i));
                 }
             }
+            if (processInfo.enableGwpAsan != null) {
+                pw.print(prefix); pw.println("  enableGwpAsan=" + processInfo.enableGwpAsan);
+            }
         }
         pw.print(prefix); pw.print("mRequiredAbi="); pw.print(mRequiredAbi);
                 pw.print(" instructionSet="); pw.println(instructionSet);
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 471c97b..87e1dbc 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -19,7 +19,7 @@
 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
-import static android.app.AppOpsManager.CALL_BACK_ON_CHANGED_LISTENER_WITH_SWITCHED_OP_CHANGE;
+import static android.app.AppOpsManager.CALL_BACK_ON_SWITCHED_OP;
 import static android.app.AppOpsManager.FILTER_BY_FEATURE_ID;
 import static android.app.AppOpsManager.FILTER_BY_OP_NAMES;
 import static android.app.AppOpsManager.FILTER_BY_PACKAGE_NAME;
@@ -87,7 +87,6 @@
 import android.app.AsyncNotedAppOp;
 import android.app.RuntimeAppOpAccessMessage;
 import android.app.SyncNotedAppOp;
-import android.compat.Compatibility;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -2679,10 +2678,8 @@
         synchronized (this) {
             int switchOp = (op != AppOpsManager.OP_NONE) ? AppOpsManager.opToSwitch(op) : op;
 
-            // See CALL_BACK_ON_CHANGED_LISTENER_WITH_SWITCHED_OP_CHANGE
             int notifiedOps;
-            if (Compatibility.isChangeEnabled(
-                    CALL_BACK_ON_CHANGED_LISTENER_WITH_SWITCHED_OP_CHANGE)) {
+            if ((flags & CALL_BACK_ON_SWITCHED_OP) == 0) {
                 if (op == OP_NONE) {
                     notifiedOps = ALL_OPS;
                 } else {
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
index ec9b37d..83da381 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
@@ -45,6 +45,7 @@
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -183,7 +184,8 @@
             String callingFeatureId,
             Intent intent,
             @UserIdInt int userId,
-            IBinder callingActivity) throws RemoteException {
+            IBinder callingActivity,
+            Bundle options) throws RemoteException {
         Objects.requireNonNull(callingPackage);
         Objects.requireNonNull(intent);
         Objects.requireNonNull(intent.getComponent(), "The intent must have a Component set");
@@ -226,7 +228,7 @@
                         launchIntent,
                         callingActivity,
                         /* startFlags= */ 0,
-                        /* options= */ null,
+                        options,
                         userId);
         logStartActivityByIntent(callingPackage);
     }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 33ef2d4..cdc3736 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -805,26 +805,30 @@
     public SessionInfo getSessionInfo(int sessionId) {
         synchronized (mSessions) {
             final PackageInstallerSession session = mSessions.get(sessionId);
-            return session != null ? session.generateInfo() : null;
+
+            return session != null
+                    ? session.generateInfoForCaller(true /*withIcon*/, Binder.getCallingUid())
+                    : null;
         }
     }
 
     @Override
     public ParceledListSlice<SessionInfo> getStagedSessions() {
-        return mStagingManager.getSessions();
+        return mStagingManager.getSessions(Binder.getCallingUid());
     }
 
     @Override
     public ParceledListSlice<SessionInfo> getAllSessions(int userId) {
+        final int callingUid = Binder.getCallingUid();
         mPermissionManager.enforceCrossUserPermission(
-                Binder.getCallingUid(), userId, true, false, "getAllSessions");
+                callingUid, userId, true, false, "getAllSessions");
 
         final List<SessionInfo> result = new ArrayList<>();
         synchronized (mSessions) {
             for (int i = 0; i < mSessions.size(); i++) {
                 final PackageInstallerSession session = mSessions.valueAt(i);
                 if (session.userId == userId && !session.hasParentSessionId()) {
-                    result.add(session.generateInfo(false));
+                    result.add(session.generateInfoForCaller(false, callingUid));
                 }
             }
         }
@@ -842,7 +846,8 @@
             for (int i = 0; i < mSessions.size(); i++) {
                 final PackageInstallerSession session = mSessions.valueAt(i);
 
-                SessionInfo info = session.generateInfo(false);
+                SessionInfo info =
+                        session.generateInfoForCaller(false /*withIcon*/, Process.SYSTEM_UID);
                 if (Objects.equals(info.getInstallerPackageName(), installerPackageName)
                         && session.userId == userId && !session.hasParentSessionId()) {
                     result.add(info);
@@ -1302,7 +1307,10 @@
             session.markUpdated();
             writeSessionsAsync();
             if (mOkToSendBroadcasts) {
-                mPm.sendSessionUpdatedBroadcast(session.generateInfo(false),
+                // we don't scrub the data here as this is sent only to the installer several
+                // privileged system packages
+                mPm.sendSessionUpdatedBroadcast(
+                        session.generateInfoForCaller(false/*icon*/, Process.SYSTEM_UID),
                         session.userId);
             }
         }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 97aa79d..483f83e 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -557,11 +557,41 @@
         }
     }
 
-    public SessionInfo generateInfo() {
-        return generateInfo(true);
+    /**
+     * Returns {@code true} if the {@link SessionInfo} object should be produced with potentially
+     * sensitive data scrubbed from its fields.
+     *
+     * @param callingUid the uid of the caller; the recipient of the {@link SessionInfo} that may
+     *                   need to be scrubbed
+     */
+    private boolean shouldScrubData(int callingUid) {
+        return !(callingUid < Process.FIRST_APPLICATION_UID || getInstallerUid() == callingUid);
     }
 
-    public SessionInfo generateInfo(boolean includeIcon) {
+    /**
+     * Generates a {@link SessionInfo} object for the provided uid. This may result in some fields
+     * that may contain sensitive info being filtered.
+     *
+     * @param includeIcon true if the icon should be included in the object
+     * @param callingUid the uid of the caller; the recipient of the {@link SessionInfo} that may
+     *                   need to be scrubbed
+     * @see #shouldScrubData(int)
+     */
+    public SessionInfo generateInfoForCaller(boolean includeIcon, int callingUid) {
+        return generateInfoInternal(includeIcon, shouldScrubData(callingUid));
+    }
+
+    /**
+     * Generates a {@link SessionInfo} object to ensure proper hiding of sensitive fields.
+     *
+     * @param includeIcon true if the icon should be included in the object
+     * @see #generateInfoForCaller(boolean, int)
+     */
+    public SessionInfo generateInfoScrubbed(boolean includeIcon) {
+        return generateInfoInternal(includeIcon, true /*scrubData*/);
+    }
+
+    private SessionInfo generateInfoInternal(boolean includeIcon, boolean scrubData) {
         final SessionInfo info = new SessionInfo();
         synchronized (mLock) {
             info.sessionId = sessionId;
@@ -584,9 +614,13 @@
             info.appLabel = params.appLabel;
 
             info.installLocation = params.installLocation;
-            info.originatingUri = params.originatingUri;
+            if (!scrubData) {
+                info.originatingUri = params.originatingUri;
+            }
             info.originatingUid = params.originatingUid;
-            info.referrerUri = params.referrerUri;
+            if (!scrubData) {
+                info.referrerUri = params.referrerUri;
+            }
             info.grantedRuntimePermissions = params.grantedRuntimePermissions;
             info.whitelistedRestrictedPermissions = params.whitelistedRestrictedPermissions;
             info.installFlags = params.installFlags;
@@ -2664,7 +2698,7 @@
         final boolean isNewInstall = extras == null || !extras.getBoolean(Intent.EXTRA_REPLACING);
         if (success && isNewInstall && mPm.mInstallerService.okToSendBroadcasts()
                 && (params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) {
-            mPm.sendSessionCommitBroadcast(generateInfo(), userId);
+            mPm.sendSessionCommitBroadcast(generateInfoScrubbed(true /*icon*/), userId);
         }
 
         mCallback.onSessionFinished(this, success);
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 83fe556..342c907 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -128,11 +128,12 @@
         }
     }
 
-    ParceledListSlice<PackageInstaller.SessionInfo> getSessions() {
+    ParceledListSlice<PackageInstaller.SessionInfo> getSessions(int callingUid) {
         final List<PackageInstaller.SessionInfo> result = new ArrayList<>();
         synchronized (mStagedSessions) {
             for (int i = 0; i < mStagedSessions.size(); i++) {
-                result.add(mStagedSessions.valueAt(i).generateInfo(false));
+                final PackageInstallerSession stagedSession = mStagedSessions.valueAt(i);
+                result.add(stagedSession.generateInfoForCaller(false /*icon*/, callingUid));
             }
         }
         return new ParceledListSlice<>(result);
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index d3f668c..0e294f70 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -391,8 +391,9 @@
         ArrayMap<String, ProcessInfo> retProcs = new ArrayMap<>(numProcs);
         for (String key : procs.keySet()) {
             ParsedProcess proc = procs.get(key);
-            retProcs.put(proc.getName(), new ProcessInfo(proc.getName(),
-                    new ArraySet<>(proc.getDeniedPermissions())));
+            retProcs.put(proc.getName(),
+                    new ProcessInfo(proc.getName(), new ArraySet<>(proc.getDeniedPermissions()),
+                            proc.getEnableGwpAsan()));
         }
         return retProcs;
     }
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
index 04d551d..b43d8b7 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
@@ -24,6 +24,8 @@
 import android.media.tv.tunerresourcemanager.IResourcesReclaimListener;
 import android.media.tv.tunerresourcemanager.ITunerResourceManager;
 import android.media.tv.tunerresourcemanager.ResourceClientProfile;
+import android.media.tv.tunerresourcemanager.TunerDemuxRequest;
+import android.media.tv.tunerresourcemanager.TunerDescramblerRequest;
 import android.media.tv.tunerresourcemanager.TunerFrontendInfo;
 import android.media.tv.tunerresourcemanager.TunerFrontendRequest;
 import android.media.tv.tunerresourcemanager.TunerLnbRequest;
@@ -189,6 +191,24 @@
         }
 
         @Override
+        public boolean requestDemux(@NonNull TunerDemuxRequest request,
+                    @NonNull int[] demuxHandle) {
+            if (DEBUG) {
+                Slog.d(TAG, "requestDemux(request=" + request + ")");
+            }
+            return true;
+        }
+
+        @Override
+        public boolean requestDescrambler(@NonNull TunerDescramblerRequest request,
+                    @NonNull int[] descrambleHandle) {
+            if (DEBUG) {
+                Slog.d(TAG, "requestDescrambler(request=" + request + ")");
+            }
+            return true;
+        }
+
+        @Override
         public boolean requestCasSession(
                 @NonNull CasSessionRequest request, @NonNull int[] sessionResourceId) {
             if (DEBUG) {
@@ -214,6 +234,20 @@
         }
 
         @Override
+        public void releaseDemux(int demuxHandle) {
+            if (DEBUG) {
+                Slog.d(TAG, "releaseDemux(demuxHandle=" + demuxHandle + ")");
+            }
+        }
+
+        @Override
+        public void releaseDescrambler(int descramblerHandle) {
+            if (DEBUG) {
+                Slog.d(TAG, "releaseDescrambler(descramblerHandle=" + descramblerHandle + ")");
+            }
+        }
+
+        @Override
         public void releaseCasSession(int sessionResourceId) {
             if (DEBUG) {
                 Slog.d(TAG, "releaseCasSession(sessionResourceId=" + sessionResourceId + ")");
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 6eb3c0f..a298b89 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -2184,47 +2184,6 @@
         }
     }
 
-    /**
-     * Called when the wallpaper needs to zoom out.
-     *
-     * @param zoom from 0 to 1 (inclusive) where 1 means fully zoomed out, 0 means fully zoomed in.
-     * @param callingPackage package name calling this API.
-     * @param displayId id of the display whose zoom is updating.
-     */
-    public void setWallpaperZoomOut(float zoom, String callingPackage, int displayId) {
-        if (!isWallpaperSupported(callingPackage)) {
-            return;
-        }
-        synchronized (mLock) {
-            if (!isValidDisplay(displayId)) {
-                throw new IllegalArgumentException("Cannot find display with id=" + displayId);
-            }
-            int userId = UserHandle.getCallingUserId();
-            if (mCurrentUserId != userId) {
-                return; // Don't change the properties now
-            }
-            WallpaperData wallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
-            if (zoom < 0 || zoom > 1f) {
-                throw new IllegalArgumentException("zoom must be between 0 and one: " + zoom);
-            }
-
-            if (wallpaper.connection != null) {
-                final WallpaperConnection.DisplayConnector connector = wallpaper.connection
-                        .getDisplayConnectorOrCreate(displayId);
-                final IWallpaperEngine engine = connector != null ? connector.mEngine : null;
-                if (engine != null) {
-                    try {
-                        engine.setZoomOut(zoom);
-                    } catch (RemoteException e) {
-                        if (DEBUG) {
-                            Slog.w(TAG, "Couldn't set wallpaper zoom", e);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
     @Deprecated
     @Override
     public ParcelFileDescriptor getWallpaper(String callingPkg, IWallpaperManagerCallback cb,
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 36fdb2d..98e3d07 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2224,9 +2224,7 @@
                             .addTaggedData(MetricsEvent.FIELD_DISPLAY_ID, getDisplayId()));
         }
 
-        // If there was no pinned stack, we still need to notify the controller of the display info
-        // update as a result of the config change.
-        if (mPinnedStackControllerLocked != null && !hasPinnedTask()) {
+        if (mPinnedStackControllerLocked != null) {
             mPinnedStackControllerLocked.onDisplayInfoChanged(getDisplayInfo());
         }
     }
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index a094c81..ba61667 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -440,10 +440,12 @@
                     updateDreamingSleepToken(msg.arg1 != 0);
                     break;
                 case MSG_REQUEST_TRANSIENT_BARS:
-                    WindowState targetBar = (msg.arg1 == MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS)
-                            ? mStatusBar : mNavigationBar;
-                    if (targetBar != null) {
-                        requestTransientBars(targetBar);
+                    synchronized (mLock) {
+                        WindowState targetBar = (msg.arg1 == MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS)
+                                ? mStatusBar : mNavigationBar;
+                        if (targetBar != null) {
+                            requestTransientBars(targetBar);
+                        }
                     }
                     break;
                 case MSG_DISPOSE_INPUT_CONSUMER:
@@ -499,15 +501,20 @@
                 new SystemGesturesPointerEventListener.Callbacks() {
                     @Override
                     public void onSwipeFromTop() {
-                        if (mStatusBar != null) {
-                            requestTransientBars(mStatusBar);
+                        synchronized (mLock) {
+                            if (mStatusBar != null) {
+                                requestTransientBars(mStatusBar);
+                            }
                         }
                     }
 
                     @Override
                     public void onSwipeFromBottom() {
-                        if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) {
-                            requestTransientBars(mNavigationBar);
+                        synchronized (mLock) {
+                            if (mNavigationBar != null
+                                    && mNavigationBarPosition == NAV_BAR_BOTTOM) {
+                                requestTransientBars(mNavigationBar);
+                            }
                         }
                     }
 
@@ -517,12 +524,13 @@
                         synchronized (mLock) {
                             mDisplayContent.calculateSystemGestureExclusion(
                                     excludedRegion, null /* outUnrestricted */);
-                        }
-                        final boolean sideAllowed = mNavigationBarAlwaysShowOnSideGesture
-                                || mNavigationBarPosition == NAV_BAR_RIGHT;
-                        if (mNavigationBar != null && sideAllowed
-                                && !mSystemGestures.currentGestureStartedInRegion(excludedRegion)) {
-                            requestTransientBars(mNavigationBar);
+                            final boolean sideAllowed = mNavigationBarAlwaysShowOnSideGesture
+                                    || mNavigationBarPosition == NAV_BAR_RIGHT;
+                            if (mNavigationBar != null && sideAllowed
+                                    && !mSystemGestures.currentGestureStartedInRegion(
+                                            excludedRegion)) {
+                                requestTransientBars(mNavigationBar);
+                            }
                         }
                         excludedRegion.recycle();
                     }
@@ -533,12 +541,13 @@
                         synchronized (mLock) {
                             mDisplayContent.calculateSystemGestureExclusion(
                                     excludedRegion, null /* outUnrestricted */);
-                        }
-                        final boolean sideAllowed = mNavigationBarAlwaysShowOnSideGesture
-                                || mNavigationBarPosition == NAV_BAR_LEFT;
-                        if (mNavigationBar != null && sideAllowed
-                                && !mSystemGestures.currentGestureStartedInRegion(excludedRegion)) {
-                            requestTransientBars(mNavigationBar);
+                            final boolean sideAllowed = mNavigationBarAlwaysShowOnSideGesture
+                                    || mNavigationBarPosition == NAV_BAR_LEFT;
+                            if (mNavigationBar != null && sideAllowed
+                                    && !mSystemGestures.currentGestureStartedInRegion(
+                                            excludedRegion)) {
+                                requestTransientBars(mNavigationBar);
+                            }
                         }
                         excludedRegion.recycle();
                     }
@@ -3156,47 +3165,46 @@
     }
 
     private void requestTransientBars(WindowState swipeTarget) {
-        synchronized (mLock) {
-            if (!mService.mPolicy.isUserSetupComplete()) {
-                // Swipe-up for navigation bar is disabled during setup
+        if (!mService.mPolicy.isUserSetupComplete()) {
+            // Swipe-up for navigation bar is disabled during setup
+            return;
+        }
+        if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL) {
+            if (swipeTarget == mNavigationBar
+                    && !getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)) {
+                // Don't show status bar when swiping on already visible navigation bar
                 return;
             }
-            if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL) {
-                if (swipeTarget == mNavigationBar
-                        && !getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)) {
-                    // Don't show status bar when swiping on already visible navigation bar
-                    return;
-                }
-                final InsetsControlTarget controlTarget =
-                        swipeTarget.getControllableInsetProvider().getControlTarget();
+            final InsetsSourceProvider provider = swipeTarget.getControllableInsetProvider();
+            final InsetsControlTarget controlTarget = provider != null
+                    ? provider.getControlTarget() : null;
 
-                // No transient mode on lockscreen (in notification shade window).
-                if (controlTarget == null || controlTarget == getNotificationShade()) {
+            // No transient mode on lockscreen (in notification shade window).
+            if (controlTarget == null || controlTarget == getNotificationShade()) {
+                return;
+            }
+            if (controlTarget.canShowTransient()) {
+                mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap(
+                        new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
+            } else {
+                controlTarget.showInsets(Type.systemBars(), false);
+            }
+        } else {
+            boolean sb = mStatusBarController.checkShowTransientBarLw();
+            boolean nb = mNavigationBarController.checkShowTransientBarLw()
+                    && !isNavBarEmpty(mLastSystemUiFlags);
+            if (sb || nb) {
+                // Don't show status bar when swiping on already visible navigation bar
+                if (!nb && swipeTarget == mNavigationBar) {
+                    if (DEBUG) Slog.d(TAG, "Not showing transient bar, wrong swipe target");
                     return;
                 }
-                if (controlTarget.canShowTransient()) {
-                    mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap(
-                            new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
-                } else {
-                    controlTarget.showInsets(Type.systemBars(), false);
-                }
-            } else {
-                boolean sb = mStatusBarController.checkShowTransientBarLw();
-                boolean nb = mNavigationBarController.checkShowTransientBarLw()
-                        && !isNavBarEmpty(mLastSystemUiFlags);
-                if (sb || nb) {
-                    // Don't show status bar when swiping on already visible navigation bar
-                    if (!nb && swipeTarget == mNavigationBar) {
-                        if (DEBUG) Slog.d(TAG, "Not showing transient bar, wrong swipe target");
-                        return;
-                    }
-                    if (sb) mStatusBarController.showTransient();
-                    if (nb) mNavigationBarController.showTransient();
-                    updateSystemUiVisibilityLw();
-                }
+                if (sb) mStatusBarController.showTransient();
+                if (nb) mNavigationBarController.showTransient();
+                updateSystemUiVisibilityLw();
             }
-            mImmersiveModeConfirmation.confirmCurrentPrompt();
         }
+        mImmersiveModeConfirmation.confirmCurrentPrompt();
     }
 
     private void disposeInputConsumer(InputConsumer inputConsumer) {
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 01f9888..958c8af 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -36,6 +36,7 @@
 import android.util.SparseArray;
 import android.view.InsetsAnimationControlCallbacks;
 import android.view.InsetsAnimationControlImpl;
+import android.view.InsetsAnimationControlRunner;
 import android.view.InsetsController;
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
@@ -44,6 +45,7 @@
 import android.view.SyncRtSurfaceTransactionApplier;
 import android.view.ViewRootImpl;
 import android.view.WindowInsetsAnimation;
+import android.view.WindowInsetsAnimation.Bounds;
 import android.view.WindowInsetsAnimationControlListener;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -327,7 +329,7 @@
         InsetsPolicyAnimationControlCallbacks mControlCallbacks;
 
         InsetsPolicyAnimationControlListener(boolean show, Runnable finishCallback) {
-            super(show);
+            super(show, true /* useSfVsync */);
             mFinishCallback = finishCallback;
             mControlCallbacks = new InsetsPolicyAnimationControlCallbacks(this);
         }
@@ -360,8 +362,6 @@
                         mFocusedWin.getDisplayContent().getBounds(), getState(),
                         mListener, typesReady, this, mListener.getDurationMs(),
                         InsetsController.INTERPOLATOR, true,
-                        show ? LAYOUT_INSETS_DURING_ANIMATION_SHOWN
-                                : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN,
                         show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE);
                 SurfaceAnimationThread.getHandler().post(
                         () -> mListener.onReady(mAnimationControl, typesReady));
@@ -377,7 +377,7 @@
             }
 
             @Override
-            public void notifyFinished(InsetsAnimationControlImpl controller, boolean shown) {
+            public void notifyFinished(InsetsAnimationControlRunner runner, boolean shown) {
                 // Nothing's needed here. Finish steps is handled in the listener
                 // onAnimationFinished callback.
             }
@@ -406,14 +406,14 @@
                     applyParams(t, surfaceParams, mTmpFloat9);
                 }
                 t.apply();
+                t.close();
             }
 
             @Override
             public void startAnimation(InsetsAnimationControlImpl controller,
                     WindowInsetsAnimationControlListener listener, int types,
                     WindowInsetsAnimation animation,
-                    WindowInsetsAnimation.Bounds bounds,
-                    int layoutDuringAnimation) {
+                    Bounds bounds) {
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 6ff029b..ee36db9 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.view.InsetsState.ITYPE_CAPTION_BAR;
 import static android.view.InsetsState.ITYPE_IME;
 import static android.view.InsetsState.ITYPE_INVALID;
@@ -29,6 +30,8 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.WindowConfiguration;
+import android.app.WindowConfiguration.WindowingMode;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.SparseArray;
@@ -74,30 +77,28 @@
 
     /**
      * When dispatching window state to the client, we'll need to exclude the source that represents
-     * the window that is being dispatched.
+     * the window that is being dispatched. We also need to exclude certain types of insets source
+     * for client within specific windowing modes.
      *
      * @param target The client we dispatch the state to.
      * @return The state stripped of the necessary information.
      */
     InsetsState getInsetsForDispatch(@NonNull WindowState target) {
         final InsetsSourceProvider provider = target.getControllableInsetProvider();
-        if (provider == null) {
-            return mState;
-        }
-        final @InternalInsetsType int type = provider.getSource().getType();
-        return getInsetsForType(type);
+        final @InternalInsetsType int type = provider != null
+                ? provider.getSource().getType() : ITYPE_INVALID;
+        return getInsetsForTypeAndWindowingMode(type, target.getWindowingMode());
     }
 
     InsetsState getInsetsForWindowMetrics(@NonNull WindowManager.LayoutParams attrs) {
         final @InternalInsetsType int type = getInsetsTypeForWindowType(attrs.type);
-        if (type == ITYPE_INVALID) {
-            return mState;
-        }
-        return getInsetsForType(type);
+        final WindowToken token = mDisplayContent.getWindowToken(attrs.token);
+        final @WindowingMode int windowingMode = token != null
+                ? token.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
+        return getInsetsForTypeAndWindowingMode(type, windowingMode);
     }
 
-    @InternalInsetsType
-    private static int getInsetsTypeForWindowType(int type) {
+    private static @InternalInsetsType int getInsetsTypeForWindowType(int type) {
         switch(type) {
             case TYPE_STATUS_BAR:
                 return ITYPE_STATUS_BAR;
@@ -110,36 +111,48 @@
         }
     }
 
-    private InsetsState getInsetsForType(@InternalInsetsType int type) {
-        final InsetsState state = new InsetsState();
-        state.set(mState);
-        state.removeSource(type);
+    /** @see #getInsetsForDispatch */
+    private InsetsState getInsetsForTypeAndWindowingMode(@InternalInsetsType int type,
+            @WindowingMode int windowingMode) {
+        InsetsState state = mState;
 
-        // Navigation bar doesn't get influenced by anything else
-        if (type == ITYPE_NAVIGATION_BAR) {
-            state.removeSource(ITYPE_IME);
-            state.removeSource(ITYPE_STATUS_BAR);
-            state.removeSource(ITYPE_CAPTION_BAR);
-        }
+        if (type != ITYPE_INVALID) {
+            state = new InsetsState(state);
+            state.removeSource(type);
 
-        // Status bar doesn't get influenced by caption bar
-        if (type == ITYPE_STATUS_BAR) {
-            state.removeSource(ITYPE_CAPTION_BAR);
-        }
+            // Navigation bar doesn't get influenced by anything else
+            if (type == ITYPE_NAVIGATION_BAR) {
+                state.removeSource(ITYPE_IME);
+                state.removeSource(ITYPE_STATUS_BAR);
+                state.removeSource(ITYPE_CAPTION_BAR);
+            }
 
-        // IME needs different frames for certain cases (e.g. navigation bar in gesture nav).
-        if (type == ITYPE_IME) {
-            for (int i = mProviders.size() - 1; i >= 0; i--) {
-                InsetsSourceProvider otherProvider = mProviders.valueAt(i);
-                if (otherProvider.overridesImeFrame()) {
-                    InsetsSource override =
-                            new InsetsSource(state.getSource(otherProvider.getSource().getType()));
-                    override.setFrame(otherProvider.getImeOverrideFrame());
-                    state.addSource(override);
+            // Status bar doesn't get influenced by caption bar
+            if (type == ITYPE_STATUS_BAR) {
+                state.removeSource(ITYPE_CAPTION_BAR);
+            }
+
+            // IME needs different frames for certain cases (e.g. navigation bar in gesture nav).
+            if (type == ITYPE_IME) {
+                for (int i = mProviders.size() - 1; i >= 0; i--) {
+                    InsetsSourceProvider otherProvider = mProviders.valueAt(i);
+                    if (otherProvider.overridesImeFrame()) {
+                        InsetsSource override =
+                                new InsetsSource(
+                                        state.getSource(otherProvider.getSource().getType()));
+                        override.setFrame(otherProvider.getImeOverrideFrame());
+                        state.addSource(override);
+                    }
                 }
             }
         }
 
+        if (WindowConfiguration.isFloating(windowingMode)) {
+            state = new InsetsState(state);
+            state.removeSource(ITYPE_STATUS_BAR);
+            state.removeSource(ITYPE_NAVIGATION_BAR);
+        }
+
         return state;
     }
 
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 9df4248..5f3732a 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -356,6 +356,31 @@
     }
 
     @Override
+    public void setWallpaperZoomOut(IBinder window, float zoom) {
+        if (Float.compare(0f, zoom) > 0 || Float.compare(1f, zoom) < 0 || Float.isNaN(zoom)) {
+            throw new IllegalArgumentException("Zoom must be a valid float between 0 and 1: "
+                    + zoom);
+        }
+        synchronized (mService.mGlobalLock) {
+            long ident = Binder.clearCallingIdentity();
+            try {
+                actionOnWallpaper(window, (wpController, windowState) ->
+                        wpController.setWallpaperZoomOut(windowState, zoom));
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
+    @Override
+    public void setShouldZoomOutWallpaper(IBinder window, boolean shouldZoom) {
+        synchronized (mService.mGlobalLock) {
+            actionOnWallpaper(window, (wpController, windowState) ->
+                    wpController.setShouldZoomOutWallpaper(windowState, shouldZoom));
+        }
+    }
+
+    @Override
     public void wallpaperOffsetsComplete(IBinder window) {
         synchronized (mService.mGlobalLock) {
             actionOnWallpaper(window, (wpController, windowState) ->
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index b2db99b..5ed903e 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -4123,8 +4123,16 @@
         return mMainWindowSizeChangeTransaction;
     }
 
+    void setActivityWindowingMode(int windowingMode) {
+        PooledConsumer c = PooledLambda.obtainConsumer(ActivityRecord::setWindowingMode,
+            PooledLambda.__(ActivityRecord.class), windowingMode);
+        forAllActivities(c);
+        c.recycle();
+    }
+
     @Override
     long getProtoFieldId() {
         return TASK;
     }
+
 }
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 4093fe5..cfb5706 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -553,18 +553,28 @@
             WindowContainerTransaction.Change c) {
         int effects = sanitizeAndApplyChange(wc, c);
 
+        final Task tr = wc.asTask();
+
         final SurfaceControl.Transaction t = c.getBoundsChangeTransaction();
         if (t != null) {
-            Task tr = (Task) wc;
             tr.setMainWindowSizeChangeTransaction(t);
         }
 
         Rect enterPipBounds = c.getEnterPipBounds();
         if (enterPipBounds != null) {
-            Task tr = (Task) wc;
             mService.mStackSupervisor.updatePictureInPictureMode(tr,
                     enterPipBounds, true);
         }
+
+        final int windowingMode = c.getWindowingMode();
+        if (windowingMode > -1) {
+            tr.setWindowingMode(windowingMode);
+        }
+        final int childWindowingMode = c.getActivityWindowingMode();
+        if (childWindowingMode > -1) {
+            tr.setActivityWindowingMode(childWindowingMode);
+        }
+
         return effects;
     }
 
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 669eb78..57d0a33 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -41,6 +41,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.ArraySet;
+import android.util.MathUtils;
 import android.util.Slog;
 import android.view.DisplayInfo;
 import android.view.SurfaceControl;
@@ -52,6 +53,7 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.function.Consumer;
 
 /**
  * Controls wallpaper windows visibility, ordering, and so on.
@@ -75,8 +77,10 @@
     private float mLastWallpaperY = -1;
     private float mLastWallpaperXStep = -1;
     private float mLastWallpaperYStep = -1;
+    private float mLastWallpaperZoomOut = 0;
     private int mLastWallpaperDisplayOffsetX = Integer.MIN_VALUE;
     private int mLastWallpaperDisplayOffsetY = Integer.MIN_VALUE;
+    private final float mMaxWallpaperScale;
 
     // This is set when we are waiting for a wallpaper to tell us it is done
     // changing its scroll position.
@@ -191,9 +195,21 @@
         return false;
     };
 
+    /**
+     * @see #computeLastWallpaperZoomOut()
+     */
+    private Consumer<WindowState>  mComputeMaxZoomOutFunction = windowState -> {
+        if (!windowState.mIsWallpaper
+                && Float.compare(windowState.mWallpaperZoomOut, mLastWallpaperZoomOut) > 0) {
+            mLastWallpaperZoomOut = windowState.mWallpaperZoomOut;
+        }
+    };
+
     WallpaperController(WindowManagerService service, DisplayContent displayContent) {
         mService = service;
         mDisplayContent = displayContent;
+        mMaxWallpaperScale = service.mContext.getResources()
+                .getFloat(com.android.internal.R.dimen.config_wallpaperMaxScale);
     }
 
     WindowState getWallpaperTarget() {
@@ -325,20 +341,30 @@
             rawChanged = true;
         }
 
-        boolean changed = wallpaperWin.mWinAnimator.setWallpaperOffset(xOffset, yOffset);
+        if (Float.compare(wallpaperWin.mWallpaperZoomOut, mLastWallpaperZoomOut) != 0) {
+            wallpaperWin.mWallpaperZoomOut = mLastWallpaperZoomOut;
+            rawChanged = true;
+        }
+
+        boolean changed = wallpaperWin.mWinAnimator.setWallpaperOffset(xOffset, yOffset,
+                wallpaperWin.mShouldScaleWallpaper
+                        ? zoomOutToScale(wallpaperWin.mWallpaperZoomOut) : 1);
 
         if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
                 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
             try {
                 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
                         + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
-                        + " y=" + wallpaperWin.mWallpaperY);
+                        + " y=" + wallpaperWin.mWallpaperY
+                        + " zoom=" + wallpaperWin.mWallpaperZoomOut);
                 if (sync) {
                     mWaitingOnWallpaper = wallpaperWin;
                 }
                 wallpaperWin.mClient.dispatchWallpaperOffsets(
                         wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
-                        wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
+                        wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep,
+                        wallpaperWin.mWallpaperZoomOut, sync);
+
                 if (sync) {
                     if (mWaitingOnWallpaper != null) {
                         long start = SystemClock.uptimeMillis();
@@ -378,6 +404,20 @@
         }
     }
 
+    void setWallpaperZoomOut(WindowState window, float zoom) {
+        if (Float.compare(window.mWallpaperZoomOut, zoom) != 0) {
+            window.mWallpaperZoomOut = zoom;
+            updateWallpaperOffsetLocked(window, false);
+        }
+    }
+
+    void setShouldZoomOutWallpaper(WindowState window, boolean shouldZoom) {
+        if (shouldZoom != window.mShouldScaleWallpaper) {
+            window.mShouldScaleWallpaper = shouldZoom;
+            updateWallpaperOffsetLocked(window, false);
+        }
+    }
+
     void setWindowWallpaperDisplayOffset(WindowState window, int x, int y) {
         if (window.mWallpaperDisplayOffsetX != x || window.mWallpaperDisplayOffsetY != y)  {
             window.mWallpaperDisplayOffsetX = x;
@@ -420,6 +460,7 @@
             } else if (changingTarget.mWallpaperY >= 0) {
                 mLastWallpaperY = changingTarget.mWallpaperY;
             }
+            computeLastWallpaperZoomOut();
             if (target.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
                 mLastWallpaperDisplayOffsetX = target.mWallpaperDisplayOffsetX;
             } else if (changingTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
@@ -593,6 +634,9 @@
                 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
                 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
             }
+            if (mWallpaperTarget.mWallpaperZoomOut >= 0) {
+                mLastWallpaperZoomOut = mWallpaperTarget.mWallpaperZoomOut;
+            }
             if (mWallpaperTarget.mWallpaperY >= 0) {
                 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
                 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
@@ -762,6 +806,23 @@
         return mTmpTopWallpaper;
     }
 
+    /**
+     * Each window can request a zoom, example:
+     * - User is in overview, zoomed out.
+     * - User also pulls down the shade.
+     *
+     * This means that we always have to choose the largest zoom out that we have, otherwise
+     * we'll have conflicts and break the "depth system" mental model.
+     */
+    private void computeLastWallpaperZoomOut() {
+        mLastWallpaperZoomOut = 0;
+        mDisplayContent.forAllWindows(mComputeMaxZoomOutFunction, true);
+    }
+
+    private float zoomOutToScale(float zoom) {
+        return MathUtils.lerp(1, mMaxWallpaperScale, 1 - zoom);
+    }
+
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix); pw.print("displayId="); pw.println(mDisplayContent.getDisplayId());
         pw.print(prefix); pw.print("mWallpaperTarget="); pw.println(mWallpaperTarget);
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index e8897e1..ec90097 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -275,7 +275,7 @@
     RemoteToken mRemoteToken = null;
 
     BLASTSyncEngine mBLASTSyncEngine = new BLASTSyncEngine();
-    SurfaceControl.Transaction mBLASTSyncTransaction = new SurfaceControl.Transaction();
+    SurfaceControl.Transaction mBLASTSyncTransaction;
     boolean mUsingBLASTSyncTransaction = false;
     BLASTSyncEngine.TransactionReadyListener mWaitingListener;
     int mWaitingSyncId;
@@ -283,6 +283,7 @@
     WindowContainer(WindowManagerService wms) {
         mWmService = wms;
         mPendingTransaction = wms.mTransactionFactory.get();
+        mBLASTSyncTransaction = wms.mTransactionFactory.get();
         mSurfaceAnimator = new SurfaceAnimator(this, this::onAnimationFinished, wms);
         mSurfaceFreezer = new SurfaceFreezer(this, wms);
     }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index fc28cd5..c44be4d 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -415,6 +415,7 @@
     float mHScale=1, mVScale=1;
     float mLastHScale=1, mLastVScale=1;
     final Matrix mTmpMatrix = new Matrix();
+    final float[] mTmpMatrixArray = new float[9];
 
     private final WindowFrames mWindowFrames = new WindowFrames();
 
@@ -446,6 +447,14 @@
     float mWallpaperX = -1;
     float mWallpaperY = -1;
 
+    // If a window showing a wallpaper: the requested zoom out for the
+    // wallpaper; if a wallpaper window: the currently applied zoom.
+    float mWallpaperZoomOut = -1;
+
+    // If a wallpaper window: whether the wallpaper should be scaled when zoomed, if set
+    // to false, mWallpaperZoom will be ignored here and just passed to the WallpaperService.
+    boolean mShouldScaleWallpaper;
+
     // If a window showing a wallpaper: what fraction of the offset
     // range corresponds to a full virtual screen.
     float mWallpaperXStep = -1;
@@ -3923,6 +3932,9 @@
             pw.println(prefix + "mWallpaperXStep=" + mWallpaperXStep
                     + " mWallpaperYStep=" + mWallpaperYStep);
         }
+        if (mWallpaperZoomOut != -1) {
+            pw.println(prefix + "mWallpaperZoomOut=" + mWallpaperZoomOut);
+        }
         if (mWallpaperDisplayOffsetX != Integer.MIN_VALUE
                 || mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
             pw.println(prefix + "mWallpaperDisplayOffsetX=" + mWallpaperDisplayOffsetX
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 79dc536..563710b 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -16,6 +16,12 @@
 
 package com.android.server.wm;
 
+import static android.graphics.Matrix.MSCALE_X;
+import static android.graphics.Matrix.MSCALE_Y;
+import static android.graphics.Matrix.MSKEW_X;
+import static android.graphics.Matrix.MSKEW_Y;
+import static android.graphics.Matrix.MTRANS_X;
+import static android.graphics.Matrix.MTRANS_Y;
 import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
 import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
@@ -217,6 +223,10 @@
     int mXOffset = 0;
     int mYOffset = 0;
 
+    // A scale factor for the surface contents, that will be applied from the center of the visible
+    // region.
+    float mWallpaperScale = 1f;
+
     /**
      * A flag to determine if the WSA needs to offset its position to compensate for the stack's
      * position update before the WSA surface has resized.
@@ -1034,7 +1044,12 @@
                         }
                     }
                 }
-                mSurfaceController.setPositionInTransaction(xOffset, yOffset, recoveringMemory);
+                if (!mIsWallpaper) {
+                    mSurfaceController.setPositionInTransaction(xOffset, yOffset, recoveringMemory);
+                } else {
+                    setWallpaperPositionAndScale(
+                            xOffset, yOffset, mWallpaperScale, recoveringMemory);
+                }
             }
         }
 
@@ -1051,11 +1066,15 @@
 
 
         if (!w.mSeamlesslyRotated) {
-            applyCrop(clipRect, recoveringMemory);
-            mSurfaceController.setMatrixInTransaction(mDsDx * w.mHScale * mExtraHScale,
-                    mDtDx * w.mVScale * mExtraVScale,
-                    mDtDy * w.mHScale * mExtraHScale,
-                    mDsDy * w.mVScale * mExtraVScale, recoveringMemory);
+            if (!mIsWallpaper) {
+                applyCrop(clipRect, recoveringMemory);
+                mSurfaceController.setMatrixInTransaction(mDsDx * w.mHScale * mExtraHScale,
+                        mDtDx * w.mVScale * mExtraVScale,
+                        mDtDy * w.mHScale * mExtraHScale,
+                        mDsDy * w.mVScale * mExtraVScale, recoveringMemory);
+            } else {
+                setWallpaperPositionAndScale(mXOffset, mYOffset, mWallpaperScale, recoveringMemory);
+            }
         }
 
         if (mSurfaceResized) {
@@ -1202,18 +1221,18 @@
         mSurfaceController.setTransparentRegionHint(region);
     }
 
-    boolean setWallpaperOffset(int dx, int dy) {
-        if (mXOffset == dx && mYOffset == dy) {
+    boolean setWallpaperOffset(int dx, int dy, float scale) {
+        if (mXOffset == dx && mYOffset == dy && Float.compare(mWallpaperScale, scale) == 0) {
             return false;
         }
         mXOffset = dx;
         mYOffset = dy;
+        mWallpaperScale = scale;
 
         try {
             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
             mService.openSurfaceTransaction();
-            mSurfaceController.setPositionInTransaction(dx, dy, false);
-            applyCrop(null, false);
+            setWallpaperPositionAndScale(dx, dy, scale, false);
         } catch (RuntimeException e) {
             Slog.w(TAG, "Error positioning surface of " + mWin
                     + " pos=(" + dx + "," + dy + ")", e);
@@ -1225,6 +1244,27 @@
         }
     }
 
+    private void setWallpaperPositionAndScale(int dx, int dy, float scale,
+            boolean recoveringMemory) {
+        DisplayInfo displayInfo = mWin.getDisplayInfo();
+        Matrix matrix = mWin.mTmpMatrix;
+        matrix.setTranslate(dx, dy);
+        matrix.postScale(scale, scale, displayInfo.logicalWidth / 2f,
+                displayInfo.logicalHeight / 2f);
+        matrix.getValues(mWin.mTmpMatrixArray);
+        matrix.reset();
+
+        mSurfaceController.setPositionInTransaction(mWin.mTmpMatrixArray[MTRANS_X],
+                mWin.mTmpMatrixArray[MTRANS_Y], recoveringMemory);
+        mSurfaceController.setMatrixInTransaction(
+                mDsDx * mWin.mTmpMatrixArray[MSCALE_X] * mWin.mHScale * mExtraHScale,
+                mDtDx * mWin.mTmpMatrixArray[MSKEW_Y] * mWin.mVScale * mExtraVScale,
+                mDtDy * mWin.mTmpMatrixArray[MSKEW_X] * mWin.mHScale * mExtraHScale,
+                mDsDy * mWin.mTmpMatrixArray[MSCALE_Y] * mWin.mVScale * mExtraVScale,
+                recoveringMemory);
+        applyCrop(null, recoveringMemory);
+    }
+
     /**
      * Try to change the pixel format without recreating the surface. This
      * will be common in the case of changing from PixelFormat.OPAQUE to
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index 9c9fe8c..cccd0133 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -28,6 +28,7 @@
 #include <androidfw/ZipFileRO.h>
 #include <androidfw/ZipUtils.h>
 #include <binder/BinderService.h>
+#include <binder/Nullable.h>
 #include <binder/ParcelFileDescriptor.h>
 #include <binder/Status.h>
 #include <sys/stat.h>
@@ -1083,7 +1084,7 @@
         return false;
     }
     FileSystemControlParcel fsControlParcel;
-    fsControlParcel.incremental = std::make_unique<IncrementalFileSystemControlParcel>();
+    fsControlParcel.incremental = aidl::make_nullable<IncrementalFileSystemControlParcel>();
     fsControlParcel.incremental->cmd.reset(base::unique_fd(::dup(ifs.control.cmd)));
     fsControlParcel.incremental->pendingReads.reset(
             base::unique_fd(::dup(ifs.control.pendingReads)));
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index fe42dc9..053a798 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -151,6 +151,8 @@
 
         sService.mConstants = new ActivityManagerConstants(sContext, sService,
                 sContext.getMainThreadHandler());
+        setFieldValue(ActivityManagerService.class, sService, "mContext",
+                sContext);
         ProcessList pr = new ProcessList();
         pr.init(sService, new ActiveUids(sService, false), null);
         setFieldValue(ActivityManagerService.class, sService, "mProcessList",
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 5cf1fbb..a380ece 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.view.InsetsState.ITYPE_IME;
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
@@ -69,7 +71,7 @@
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
         getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null);
         statusBar.setControllableInsetProvider(getController().getSourceProvider(ITYPE_STATUS_BAR));
-        assertNotNull(getController().getInsetsForDispatch(app).getSource(ITYPE_STATUS_BAR));
+        assertNotNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_STATUS_BAR));
     }
 
     @Test
@@ -101,6 +103,34 @@
     }
 
     @Test
+    public void testStripForDispatch_pip() {
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+        final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+
+        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null);
+        getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null, null);
+        app.setWindowingMode(WINDOWING_MODE_PINNED);
+
+        assertNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_STATUS_BAR));
+        assertNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_NAVIGATION_BAR));
+    }
+
+    @Test
+    public void testStripForDispatch_freeform() {
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+        final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+
+        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null);
+        getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null, null);
+        app.setWindowingMode(WINDOWING_MODE_FREEFORM);
+
+        assertNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_STATUS_BAR));
+        assertNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_NAVIGATION_BAR));
+    }
+
+    @Test
     public void testImeForDispatch() {
         final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
         final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java
index 53a3682..251886a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java
@@ -241,6 +241,32 @@
     }
 
     @Test
+    public void testSetWindowingMode() {
+        final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
+            .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
+        final WindowContainerTransaction t = new WindowContainerTransaction();
+
+        t.setWindowingMode(stack.mRemoteToken, WINDOWING_MODE_FULLSCREEN);
+        mWm.mAtmService.mTaskOrganizerController.applyContainerTransaction(t, null);
+
+        assertEquals(WINDOWING_MODE_FULLSCREEN, stack.getWindowingMode());
+    }
+
+    @Test
+    public void testSetActivityWindowingMode() {
+        final ActivityRecord record = makePipableActivity();
+        final ActivityStack stack = record.getStack();
+        final WindowContainerTransaction t = new WindowContainerTransaction();
+
+        t.setWindowingMode(stack.mRemoteToken, WINDOWING_MODE_PINNED);
+        t.setActivityWindowingMode(stack.mRemoteToken, WINDOWING_MODE_FULLSCREEN);
+        mWm.mAtmService.mTaskOrganizerController.applyContainerTransaction(t, null);
+
+        assertEquals(WINDOWING_MODE_FULLSCREEN, record.getWindowingMode());
+        assertEquals(WINDOWING_MODE_PINNED, stack.getWindowingMode());
+    }
+
+    @Test
     public void testContainerChanges() {
         removeGlobalMinSizeRestriction();
         final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
index e1475a4..91c3c27 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
@@ -77,7 +77,8 @@
     }
 
     @Override
-    public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep, boolean sync)
+    public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep, float zoom,
+            boolean sync)
             throws RemoteException {
     }
 
@@ -85,7 +86,6 @@
     public void dispatchWallpaperCommand(String action, int x, int y, int z, Bundle extras,
             boolean sync) throws RemoteException {
     }
-
     @Override
     public void dispatchDragEvent(DragEvent event) throws RemoteException {
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index aa66524..900f014 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -17,19 +17,29 @@
 package com.android.server.wm;
 
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
 
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.IBinder;
+import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 import android.view.DisplayInfo;
 import android.view.Gravity;
@@ -139,4 +149,124 @@
         assertEquals(Configuration.ORIENTATION_LANDSCAPE, dc.getConfiguration().orientation);
         assertEquals(portraitFrame, wallpaperWindow.getFrameLw());
     }
+
+    @Test
+    public void testWallpaperZoom() throws RemoteException {
+        final DisplayContent dc = mWm.mRoot.getDefaultDisplay();
+        final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
+                mock(IBinder.class), true,  dc, true /* ownerCanManageAppTokens */);
+        final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, wallpaperWindowToken,
+                "wallpaperWindow");
+        wallpaperWindow.getAttrs().privateFlags |=
+                WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
+
+        final WindowState homeWindow = createWallpaperTargetWindow(dc);
+
+        spyOn(dc.mWallpaperController);
+        doReturn(true).when(dc.mWallpaperController).isWallpaperVisible();
+
+        dc.mWallpaperController.adjustWallpaperWindows();
+
+        spyOn(wallpaperWindow.mClient);
+
+        float zoom = .5f;
+        dc.mWallpaperController.setWallpaperZoomOut(homeWindow, zoom);
+        assertEquals(zoom, wallpaperWindow.mWallpaperZoomOut, .01f);
+        verify(wallpaperWindow.mClient).dispatchWallpaperOffsets(anyFloat(), anyFloat(), anyFloat(),
+                anyFloat(), eq(zoom), anyBoolean());
+    }
+
+    @Test
+    public void testWallpaperZoom_shouldNotScaleWallpaper() throws RemoteException {
+        final DisplayContent dc = mWm.mRoot.getDefaultDisplay();
+        final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
+                mock(IBinder.class), true,  dc, true /* ownerCanManageAppTokens */);
+        final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, wallpaperWindowToken,
+                "wallpaperWindow");
+        wallpaperWindow.getAttrs().privateFlags |=
+                WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
+
+        final WindowState homeWindow = createWallpaperTargetWindow(dc);
+
+        spyOn(dc.mWallpaperController);
+        doReturn(true).when(dc.mWallpaperController).isWallpaperVisible();
+
+        dc.mWallpaperController.adjustWallpaperWindows();
+
+        spyOn(wallpaperWindow.mClient);
+
+        float newZoom = .5f;
+        wallpaperWindow.mShouldScaleWallpaper = false;
+        // Set zoom, and make sure the window animator scale didn't actually change, but the zoom
+        // value did, and we do dispatch the zoom to the wallpaper service
+        dc.mWallpaperController.setWallpaperZoomOut(homeWindow, newZoom);
+        assertEquals(newZoom, wallpaperWindow.mWallpaperZoomOut, .01f);
+        assertEquals(1f, wallpaperWindow.mWinAnimator.mWallpaperScale, .01f);
+        verify(wallpaperWindow.mClient).dispatchWallpaperOffsets(anyFloat(), anyFloat(), anyFloat(),
+                anyFloat(), eq(newZoom), anyBoolean());
+    }
+
+    @Test
+    public void testWallpaperZoom_multipleCallers() {
+        final DisplayContent dc = mWm.mRoot.getDefaultDisplay();
+        final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
+                mock(IBinder.class), true,  dc,
+                true /* ownerCanManageAppTokens */);
+        final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, wallpaperWindowToken,
+                "wallpaperWindow");
+        wallpaperWindow.getAttrs().privateFlags |=
+                WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
+
+
+        spyOn(dc.mWallpaperController);
+        doReturn(true).when(dc.mWallpaperController).isWallpaperVisible();
+
+        final WindowState homeWindow = createWallpaperTargetWindow(dc);
+
+        WindowState otherWindow = createWindow(null /* parent */, TYPE_APPLICATION, dc,
+                "otherWindow");
+
+        dc.mWallpaperController.adjustWallpaperWindows();
+
+        spyOn(wallpaperWindow.mClient);
+
+        // Set zoom from 2 windows
+        float homeWindowInitialZoom = .5f;
+        float otherWindowInitialZoom = .7f;
+        dc.mWallpaperController.setWallpaperZoomOut(homeWindow, homeWindowInitialZoom);
+        dc.mWallpaperController.setWallpaperZoomOut(otherWindow, otherWindowInitialZoom);
+        // Make sure the largest one wins
+        assertEquals(otherWindowInitialZoom, wallpaperWindow.mWallpaperZoomOut, .01f);
+
+        // Change zoom to a larger zoom from homeWindow
+        float homeWindowZoom2 = .8f;
+        dc.mWallpaperController.setWallpaperZoomOut(homeWindow, homeWindowZoom2);
+        // New zoom should be current
+        assertEquals(homeWindowZoom2, wallpaperWindow.mWallpaperZoomOut, .01f);
+
+        // Set homeWindow zoom to a lower zoom, but keep the one from otherWindow
+        dc.mWallpaperController.setWallpaperZoomOut(homeWindow, homeWindowInitialZoom);
+
+        // Zoom from otherWindow should be the current.
+        assertEquals(otherWindowInitialZoom, wallpaperWindow.mWallpaperZoomOut, .01f);
+    }
+
+
+    private WindowState createWallpaperTargetWindow(DisplayContent dc) {
+        final ActivityRecord homeActivity = new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
+                .setStack(dc.getRootHomeTask())
+                .setCreateTask(true)
+                .build();
+        homeActivity.setVisibility(true);
+
+        WindowState appWindow = createWindow(null /* parent */, TYPE_BASE_APPLICATION,
+                homeActivity, "wallpaperTargetWindow");
+        appWindow.getAttrs().flags |= FLAG_SHOW_WALLPAPER;
+        appWindow.mHasSurface = true;
+        spyOn(appWindow);
+        doReturn(true).when(appWindow).isDrawFinishedLw();
+
+        homeActivity.addWindow(appWindow);
+        return appWindow;
+    }
 }
diff --git a/telecomm/java/android/telecom/CallRedirectionService.java b/telecomm/java/android/telecom/CallRedirectionService.java
index 36c6377..c832f53 100644
--- a/telecomm/java/android/telecom/CallRedirectionService.java
+++ b/telecomm/java/android/telecom/CallRedirectionService.java
@@ -38,16 +38,14 @@
  *
  * <p>
  * Below is an example manifest registration for a {@code CallRedirectionService}.
- * <pre>
  * {@code
  * <service android:name="your.package.YourCallRedirectionServiceImplementation"
- *          android:permission="android.permission.BIND_REDIRECTION_SERVICE">
+ *          android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE">
  *      <intent-filter>
  *          <action android:name="android.telecom.CallRedirectionService"/>
  *      </intent-filter>
  * </service>
  * }
- * </pre>
  */
 public abstract class CallRedirectionService extends Service {
     /**
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 45cba51..dd20d06 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -580,7 +580,6 @@
      *
      * @hide
      */
-    @SystemApi
     public @RegState int getDataRegistrationState() {
         return getDataRegState();
     }
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 819fc02..8cc8cf4 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -1063,52 +1063,6 @@
         assertThat(bootObserver2.mitigatedBootLoop()).isFalse();
     }
 
-    /**
-     * Test to verify that Package Watchdog syncs health check requests with the controller
-     * correctly, and that the requests are only synced when the set of observed packages
-     * changes.
-     */
-    @Test
-    public void testSyncHealthCheckRequests() {
-        TestController testController = spy(TestController.class);
-        testController.setSupportedPackages(List.of(APP_A, APP_B, APP_C));
-        PackageWatchdog watchdog = createWatchdog(testController, true);
-
-        TestObserver testObserver1 = new TestObserver(OBSERVER_NAME_1);
-        watchdog.registerHealthObserver(testObserver1);
-        watchdog.startObservingHealth(testObserver1, List.of(APP_A), LONG_DURATION);
-        mTestLooper.dispatchAll();
-
-        TestObserver testObserver2 = new TestObserver(OBSERVER_NAME_2);
-        watchdog.registerHealthObserver(testObserver2);
-        watchdog.startObservingHealth(testObserver2, List.of(APP_B), LONG_DURATION);
-        mTestLooper.dispatchAll();
-
-        TestObserver testObserver3 = new TestObserver(OBSERVER_NAME_3);
-        watchdog.registerHealthObserver(testObserver3);
-        watchdog.startObservingHealth(testObserver3, List.of(APP_C), LONG_DURATION);
-        mTestLooper.dispatchAll();
-
-        watchdog.unregisterHealthObserver(testObserver1);
-        mTestLooper.dispatchAll();
-
-        watchdog.unregisterHealthObserver(testObserver2);
-        mTestLooper.dispatchAll();
-
-        watchdog.unregisterHealthObserver(testObserver3);
-        mTestLooper.dispatchAll();
-
-        List<Set> expectedSyncRequests = List.of(
-                Set.of(APP_A),
-                Set.of(APP_A, APP_B),
-                Set.of(APP_A, APP_B, APP_C),
-                Set.of(APP_B, APP_C),
-                Set.of(APP_C),
-                Set.of()
-        );
-        assertThat(testController.getSyncRequests()).isEqualTo(expectedSyncRequests);
-    }
-
     private void adoptShellPermissions(String... permissions) {
         InstrumentationRegistry
                 .getInstrumentation()
@@ -1265,7 +1219,6 @@
         private Consumer<String> mPassedConsumer;
         private Consumer<List<PackageConfig>> mSupportedConsumer;
         private Runnable mNotifySyncRunnable;
-        private List<Set> mSyncRequests = new ArrayList<>();
 
         @Override
         public void setEnabled(boolean enabled) {
@@ -1285,7 +1238,6 @@
 
         @Override
         public void syncRequests(Set<String> packages) {
-            mSyncRequests.add(packages);
             mRequestedPackages.clear();
             if (mIsEnabled) {
                 packages.retainAll(mSupportedPackages);
@@ -1316,10 +1268,6 @@
                 return Collections.emptyList();
             }
         }
-
-        public List<Set> getSyncRequests() {
-            return mSyncRequests;
-        }
     }
 
     private static class TestClock implements PackageWatchdog.SystemClock {
diff --git a/tests/net/common/java/android/net/util/SocketUtilsTest.kt b/tests/net/common/java/android/net/util/SocketUtilsTest.kt
index 9c7cfb0..aaf97f3 100644
--- a/tests/net/common/java/android/net/util/SocketUtilsTest.kt
+++ b/tests/net/common/java/android/net/util/SocketUtilsTest.kt
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package android.net.util;
+package android.net.util
 
+import android.os.Build
 import android.system.NetlinkSocketAddress
 import android.system.Os
 import android.system.OsConstants.AF_INET
@@ -26,18 +27,26 @@
 import android.system.PacketSocketAddress
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.Assert.fail
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 
 private const val TEST_INDEX = 123
 private const val TEST_PORT = 555
+private const val FF_BYTE = 0xff.toByte()
+
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class SocketUtilsTest {
+    @Rule @JvmField
+    val ignoreRule = DevSdkIgnoreRule()
+
     @Test
     fun testMakeNetlinkSocketAddress() {
         val nlAddress = SocketUtils.makeNetlinkSocketAddress(TEST_PORT, RTMGRP_NEIGH)
@@ -50,16 +59,21 @@
     }
 
     @Test
-    fun testMakePacketSocketAddress() {
+    fun testMakePacketSocketAddress_Q() {
         val pkAddress = SocketUtils.makePacketSocketAddress(ETH_P_ALL, TEST_INDEX)
         assertTrue("Not PacketSocketAddress object", pkAddress is PacketSocketAddress)
 
-        val ff = 0xff.toByte()
-        val pkAddress2 = SocketUtils.makePacketSocketAddress(TEST_INDEX,
-                byteArrayOf(ff, ff, ff, ff, ff, ff))
+        val pkAddress2 = SocketUtils.makePacketSocketAddress(TEST_INDEX, ByteArray(6) { FF_BYTE })
         assertTrue("Not PacketSocketAddress object", pkAddress2 is PacketSocketAddress)
     }
 
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    fun testMakePacketSocketAddress() {
+        val pkAddress = SocketUtils.makePacketSocketAddress(
+                ETH_P_ALL, TEST_INDEX, ByteArray(6) { FF_BYTE })
+        assertTrue("Not PacketSocketAddress object", pkAddress is PacketSocketAddress)
+    }
+
     @Test
     fun testCloseSocket() {
         // Expect no exception happening with null object.
diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java
index 2b47623..a269e17 100644
--- a/wifi/java/android/net/wifi/SoftApConfiguration.java
+++ b/wifi/java/android/net/wifi/SoftApConfiguration.java
@@ -35,7 +35,6 @@
 import java.nio.charset.CharsetEncoder;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
 
@@ -211,7 +210,7 @@
      * Delay in milliseconds before shutting down soft AP when
      * there are no connected devices.
      */
-    private final int mShutdownTimeoutMillis;
+    private final long mShutdownTimeoutMillis;
 
     /**
      * THe definition of security type OPEN.
@@ -247,7 +246,7 @@
     private SoftApConfiguration(@Nullable String ssid, @Nullable MacAddress bssid,
             @Nullable String passphrase, boolean hiddenSsid, @BandType int band, int channel,
             @SecurityType int securityType, int maxNumberOfClients, boolean shutdownTimeoutEnabled,
-            int shutdownTimeoutMillis, boolean clientControlByUser,
+            long shutdownTimeoutMillis, boolean clientControlByUser,
             @NonNull List<MacAddress> blockedList, @NonNull List<MacAddress> allowedList) {
         mSsid = ssid;
         mBssid = bssid;
@@ -327,7 +326,7 @@
         dest.writeInt(mSecurityType);
         dest.writeInt(mMaxNumberOfClients);
         dest.writeBoolean(mAutoShutdownEnabled);
-        dest.writeInt(mShutdownTimeoutMillis);
+        dest.writeLong(mShutdownTimeoutMillis);
         dest.writeBoolean(mClientControlByUser);
         dest.writeTypedList(mBlockedClientList);
         dest.writeTypedList(mAllowedClientList);
@@ -346,7 +345,7 @@
                     in.readString(),
                     in.readParcelable(MacAddress.class.getClassLoader()),
                     in.readString(), in.readBoolean(), in.readInt(), in.readInt(), in.readInt(),
-                    in.readInt(), in.readBoolean(), in.readInt(), in.readBoolean(),
+                    in.readInt(), in.readBoolean(), in.readLong(), in.readBoolean(),
                     in.createTypedArrayList(MacAddress.CREATOR),
                     in.createTypedArrayList(MacAddress.CREATOR));
         }
@@ -454,19 +453,19 @@
     /**
      * Returns the shutdown timeout in milliseconds.
      * The Soft AP will shutdown when there are no devices associated to it for
-     * the timeout duration. See {@link Builder#setShutdownTimeoutMillis(int)}.
+     * the timeout duration. See {@link Builder#setShutdownTimeoutMillis(long)}.
      *
      * @hide
      */
     @SystemApi
-    public int getShutdownTimeoutMillis() {
+    public long getShutdownTimeoutMillis() {
         return mShutdownTimeoutMillis;
     }
 
     /**
      * Returns a flag indicating whether clients need to be pre-approved by the user.
      * (true: authorization required) or not (false: not required).
-     * {@link Builder#enableClientControlByUser(Boolean)}.
+     * {@link Builder#setClientControlByUserEnabled(Boolean)}.
      *
      * @hide
      */
@@ -478,7 +477,7 @@
     /**
      * Returns List of clients which aren't allowed to associate to the AP.
      *
-     * Clients are configured using {@link Builder#setClientList(List, List)}
+     * Clients are configured using {@link Builder#setBlockedClientList(List)}
      *
      * @hide
      */
@@ -490,7 +489,7 @@
 
     /**
      * List of clients which are allowed to associate to the AP.
-     * Clients are configured using {@link Builder#setClientList(List, List)}
+     * Clients are configured using {@link Builder#setAllowedClientList(List)}
      *
      * @hide
      */
@@ -575,7 +574,7 @@
         private int mMaxNumberOfClients;
         private int mSecurityType;
         private boolean mAutoShutdownEnabled;
-        private int mShutdownTimeoutMillis;
+        private long mShutdownTimeoutMillis;
         private boolean mClientControlByUser;
         private List<MacAddress> mBlockedClientList;
         private List<MacAddress> mAllowedClientList;
@@ -627,6 +626,11 @@
          */
         @NonNull
         public SoftApConfiguration build() {
+            for (MacAddress client : mAllowedClientList) {
+                if (mBlockedClientList.contains(client)) {
+                    throw new IllegalArgumentException("A MacAddress exist in both client list");
+                }
+            }
             return new SoftApConfiguration(mSsid, mBssid, mPassphrase,
                     mHiddenSsid, mBand, mChannel, mSecurityType, mMaxNumberOfClients,
                     mAutoShutdownEnabled, mShutdownTimeoutMillis, mClientControlByUser,
@@ -835,7 +839,7 @@
          * @param enable true to enable, false to disable.
          * @return Builder for chaining.
          *
-         * @see #setShutdownTimeoutMillis(int)
+         * @see #setShutdownTimeoutMillis(long)
          */
         @NonNull
         public Builder setAutoShutdownEnabled(boolean enable) {
@@ -862,7 +866,7 @@
          * @see #setAutoShutdownEnabled(boolean)
          */
         @NonNull
-        public Builder setShutdownTimeoutMillis(@IntRange(from = 0) int timeoutMillis) {
+        public Builder setShutdownTimeoutMillis(@IntRange(from = 0) long timeoutMillis) {
             if (timeoutMillis < 0) {
                 throw new IllegalArgumentException("Invalid timeout value");
             }
@@ -878,7 +882,7 @@
          *
          * If manual user control is enabled then clients will be accepted, rejected, or require
          * a user approval based on the configuration provided by
-         * {@link #setClientList(List, List)}.
+         * {@link #setBlockedClientList(List)} and {@link #setAllowedClientList(List)}.
          *
          * <p>
          * This method requires hardware support. Hardware support can be determined using
@@ -898,26 +902,48 @@
          * @return Builder for chaining.
          */
         @NonNull
-        public Builder enableClientControlByUser(boolean enabled) {
+        public Builder setClientControlByUserEnabled(boolean enabled) {
             mClientControlByUser = enabled;
             return this;
         }
 
 
         /**
-         * This method together with {@link enableClientControlByUser(boolean)} control client
-         * connections to the AP. If {@link enableClientControlByUser(false)} is configured than
+         * This method together with {@link setClientControlByUserEnabled(boolean)} control client
+         * connections to the AP. If client control by user is disabled using the above method then
          * this API has no effect and clients are allowed to associate to the AP (within limit of
          * max number of clients).
          *
-         * If {@link enableClientControlByUser(true)} is configured then this API configures
-         * 2 lists:
+         * If client control by user is enabled then this API configures the list of clients
+         * which are explicitly allowed. These are auto-accepted.
+         *
+         * All other clients which attempt to associate, whose MAC addresses are on neither list,
+         * are:
          * <ul>
-         * <li>List of clients which are blocked. These are rejected.</li>
-         * <li>List of clients which are explicitly allowed. These are auto-accepted.</li>
+         * <li>Rejected</li>
+         * <li>A callback {@link WifiManager.SoftApCallback#onBlockedClientConnecting(WifiClient)}
+         * is issued (which allows the user to add them to the allowed client list if desired).<li>
          * </ul>
          *
-         * <p>
+         * @param allowedClientList list of clients which are allowed to associate to the AP
+         *                          without user pre-approval.
+         * @return Builder for chaining.
+         */
+        @NonNull
+        public Builder setAllowedClientList(@NonNull List<MacAddress> allowedClientList) {
+            mAllowedClientList = new ArrayList<>(allowedClientList);
+            return this;
+        }
+
+        /**
+         * This method together with {@link setClientControlByUserEnabled(boolean)} control client
+         * connections to the AP. If client control by user is disabled using the above method then
+         * this API has no effect and clients are allowed to associate to the AP (within limit of
+         * max number of clients).
+         *
+         * If client control by user is enabled then this API this API configures the list of
+         * clients which are blocked. These are rejected.
+         *
          * All other clients which attempt to associate, whose MAC addresses are on neither list,
          * are:
          * <ul>
@@ -927,23 +953,11 @@
          * </ul>
          *
          * @param blockedClientList list of clients which are not allowed to associate to the AP.
-         * @param allowedClientList list of clients which are allowed to associate to the AP
-         *                          without user pre-approval.
          * @return Builder for chaining.
          */
         @NonNull
-        public Builder setClientList(@NonNull List<MacAddress> blockedClientList,
-                @NonNull List<MacAddress> allowedClientList) {
+        public Builder setBlockedClientList(@NonNull List<MacAddress> blockedClientList) {
             mBlockedClientList = new ArrayList<>(blockedClientList);
-            mAllowedClientList = new ArrayList<>(allowedClientList);
-            Iterator<MacAddress> iterator = mAllowedClientList.iterator();
-            while (iterator.hasNext()) {
-                MacAddress client = iterator.next();
-                int index = mBlockedClientList.indexOf(client);
-                if (index != -1) {
-                    throw new IllegalArgumentException("A MacAddress exist in both list");
-                }
-            }
             return this;
         }
     }
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 96beacd..5e60b26 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -727,8 +727,9 @@
 
     /**
      *  If Soft Ap client is blocked, this reason code means that client doesn't exist in the
-     *  specified configuration {@link SoftApConfiguration.Builder#setClientList(List, List)}
-     *  and the {@link SoftApConfiguration.Builder#enableClientControlByUser(true)}
+     *  specified configuration {@link SoftApConfiguration.Builder#setBlockedClientList(List)}
+     *  and {@link SoftApConfiguration.Builder#setAllowedClientList(List)}
+     *  and the {@link SoftApConfiguration.Builder#setClientControlByUserEnabled(boolean)}
      *  is configured as well.
      *  @hide
      */
@@ -3409,9 +3410,10 @@
      * If the API is called while the tethered soft AP is enabled, the configuration will apply to
      * the current soft AP if the new configuration only includes
      * {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)}
-     * or {@link SoftApConfiguration.Builder#setShutdownTimeoutMillis(int)}
-     * or {@link SoftApConfiguration.Builder#enableClientControlByUser(boolean)}
-     * or {@link SoftApConfiguration.Builder#setClientList(List, List)}.
+     * or {@link SoftApConfiguration.Builder#setShutdownTimeoutMillis(long)}
+     * or {@link SoftApConfiguration.Builder#setClientControlByUserEnabled(boolean)}
+     * or {@link SoftApConfiguration.Builder#setBlockedClientList(List)}
+     * or {@link SoftApConfiguration.Builder#setAllowedClientList(List)}
      *
      * Otherwise, the configuration changes will be applied when the Soft AP is next started
      * (the framework will not stop/start the AP).
diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
index 060ddf0..1a44270 100644
--- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
@@ -127,8 +127,9 @@
                 .setMaxNumberOfClients(10)
                 .setAutoShutdownEnabled(true)
                 .setShutdownTimeoutMillis(500000)
-                .enableClientControlByUser(true)
-                .setClientList(testBlockedClientList, testAllowedClientList)
+                .setClientControlByUserEnabled(true)
+                .setBlockedClientList(testBlockedClientList)
+                .setAllowedClientList(testAllowedClientList)
                 .build();
         assertThat(original.getPassphrase()).isEqualTo("secretsecret");
         assertThat(original.getSecurityType()).isEqualTo(
@@ -264,7 +265,9 @@
         ArrayList<MacAddress> testBlockedClientList = new ArrayList<>();
         testBlockedClientList.add(testMacAddress_1);
         SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder();
-        configBuilder.setClientList(testBlockedClientList, testAllowedClientList);
+        configBuilder.setBlockedClientList(testBlockedClientList)
+                .setAllowedClientList(testAllowedClientList)
+                .build();
     }
 
     @Test