Merge "Handle the visibility of sdk sandbox uids" into tm-dev
diff --git a/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java
index 517e3ce..31c92ba 100644
--- a/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java
@@ -70,6 +70,9 @@
         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         while (state.keepRunning()) {
             ZipFile zf = new ZipFile(mFile);
+            state.pauseTiming();
+            zf.close();
+            state.resumeTiming();
         }
     }
 
diff --git a/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java b/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java
index 4999245..ca00154 100644
--- a/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java
+++ b/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java
@@ -301,6 +301,7 @@
          * Sets a {@link PersistableBundle} that contains admin-specific extras.
          */
         @NonNull
+        //TODO(b/235783053) The adminExtras parameter is actually @Nullable.
         public Builder setAdminExtras(@NonNull PersistableBundle adminExtras) {
             mAdminExtras = adminExtras != null
                     ? new PersistableBundle(adminExtras)
@@ -333,7 +334,7 @@
                     mLocalTime,
                     mLocale,
                     mDeviceOwnerCanGrantSensorsPermissions,
-                    mAdminExtras,
+                    mAdminExtras != null ? mAdminExtras : new PersistableBundle(),
                     mDemoDevice);
         }
     }
diff --git a/core/java/android/app/admin/ManagedProfileProvisioningParams.java b/core/java/android/app/admin/ManagedProfileProvisioningParams.java
index f91d60a..474f785 100644
--- a/core/java/android/app/admin/ManagedProfileProvisioningParams.java
+++ b/core/java/android/app/admin/ManagedProfileProvisioningParams.java
@@ -252,6 +252,7 @@
          * Sets a {@link Bundle} that contains admin-specific extras.
          */
         @NonNull
+        //TODO(b/235783053) The adminExtras parameter is actually @Nullable.
         public Builder setAdminExtras(@NonNull PersistableBundle adminExtras) {
             mAdminExtras = adminExtras != null
                     ? new PersistableBundle(adminExtras)
@@ -274,7 +275,7 @@
                     mLeaveAllSystemAppsEnabled,
                     mOrganizationOwnedProvisioning,
                     mKeepingAccountOnMigration,
-                    mAdminExtras);
+                    mAdminExtras != null ? mAdminExtras : new PersistableBundle());
         }
     }
 
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 73735ed..0f1b39c 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -892,9 +892,9 @@
      * <tr><th colspan="7">Preview stabilization guaranteed stream configurations</th></tr>
      * <tr><th colspan="2" id="rb">Target 1</th><th colspan="2" id="rb">Target 2</th><th rowspan="2">Sample use case(s)</th> </tr>
      * <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th></tr>
-     * <tr> <td>{@code PRIV / YUV}</td><td id="rb">{@code RECORD}</td><td colspan="4" id="rb"></td> <td>Stabilized preview, GPU video processing, or no-preview stabilized video recording.</td> </tr>
-     * <tr> <td>{@code PRIV / YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code JPEG / YUV}</td><td id="rb">{@code MAXIMUM }</td><td>Standard still imaging with stabilized preview.</td> </tr>
-     * <tr> <td>{@code PRIV / YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV / YUV}</td><td id="rb">{@code RECORD }</td><td>High-resolution recording with stabilized preview and recording stream.</td> </tr>
+     * <tr> <td>{@code PRIV / YUV}</td><td id="rb">{@code s1440p}</td><td colspan="4" id="rb"></td> <td>Stabilized preview, GPU video processing, or no-preview stabilized video recording.</td> </tr>
+     * <tr> <td>{@code PRIV / YUV}</td><td id="rb">{@code s1440p}</td> <td>{@code JPEG / YUV}</td><td id="rb">{@code MAXIMUM }</td><td>Standard still imaging with stabilized preview.</td> </tr>
+     * <tr> <td>{@code PRIV / YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV / YUV}</td><td id="rb">{@code s1440p }</td><td>High-resolution recording with stabilized preview and recording stream.</td> </tr>
      * </table><br>
      * <p>
      * For the maximum size column, PREVIEW refers to the best size match to the device's screen
diff --git a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
index a3bc665..e5b9cdb 100644
--- a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
+++ b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
@@ -1265,43 +1265,43 @@
     private static StreamCombinationTemplate sPreviewStabilizedStreamCombinations[] = {
         // 1 stream combinations
         new StreamCombinationTemplate(new StreamTemplate [] {
-                new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.RECORD)},
+                new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.s1440p)},
                 "Stabilized preview, GPU video processing, or no-preview stabilized recording"),
         new StreamCombinationTemplate(new StreamTemplate [] {
-                new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.RECORD)},
+                new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.s1440p)},
                 "Stabilized preview, GPU video processing, or no-preview stabilized recording"),
         //2 stream combinations
         new StreamCombinationTemplate(new StreamTemplate [] {
                 new StreamTemplate(ImageFormat.JPEG, SizeThreshold.MAXIMUM),
-                new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.PREVIEW)},
+                new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.s1440p)},
                 "Standard JPEG still imaging with stabilized preview"),
         new StreamCombinationTemplate(new StreamTemplate [] {
                 new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.MAXIMUM),
-                new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.PREVIEW)},
+                new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.s1440p)},
                 "Standard YUV still imaging with stabilized preview"),
         new StreamCombinationTemplate(new StreamTemplate [] {
                 new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.MAXIMUM),
-                new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.PREVIEW)},
+                new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.s1440p)},
                 "Standard YUV still imaging with stabilized in-app image processing stream"),
         new StreamCombinationTemplate(new StreamTemplate [] {
                 new StreamTemplate(ImageFormat.JPEG, SizeThreshold.MAXIMUM),
-                new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.PREVIEW)},
+                new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.s1440p)},
                 "Standard JPEG still imaging with stabilized in-app image processing stream"),
 
         new StreamCombinationTemplate(new StreamTemplate [] {
-                new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.RECORD),
+                new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.s1440p),
                 new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.PREVIEW)},
                 "High-resolution video recording with preview both streams stabilized"),
         new StreamCombinationTemplate(new StreamTemplate [] {
-                new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.RECORD),
+                new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.s1440p),
                 new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.PREVIEW)},
                 "High-resolution video recording with preview both streams stabilized"),
         new StreamCombinationTemplate(new StreamTemplate [] {
-                new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.RECORD),
+                new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.s1440p),
                 new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.PREVIEW)},
                 "High-resolution video recording with preview both streams stabilized"),
         new StreamCombinationTemplate(new StreamTemplate [] {
-                new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.RECORD),
+                new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.s1440p),
                 new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.PREVIEW)},
                 "High-resolution video recording with preview both streams stabilized"),
     };
@@ -1430,7 +1430,7 @@
             StreamCombinationTemplate []chosenStreamCombinations =
                     sPreviewStabilizedStreamCombinations;
 
-            if (mIsPreviewStabilizationSupported) {
+            if (!mIsPreviewStabilizationSupported) {
                 Log.v(TAG, "Device does not support preview stabilization");
                  return null;
              }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 6829f3d..98d4c59 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -4503,10 +4503,13 @@
             for (Map.Entry<HistoryTag, Integer> entry: mHistoryTagPool.entrySet()) {
                 entry.setValue(entry.getValue() | TAG_FIRST_OCCURRENCE_FLAG);
             }
+            // Make a copy of mHistoryCur.
+            HistoryItem copy = new HistoryItem();
+            copy.setTo(cur);
+            // startRecordingHistory will reset mHistoryCur.
             startRecordingHistory(elapsedRealtimeMs, uptimeMs, false);
-            HistoryItem newItem = new HistoryItem();
-            newItem.setTo(cur);
-            addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, newItem);
+            // Add the copy into history buffer.
+            addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, copy);
             return;
         }
 
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java
index 3858792..dd0e9ff 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java
@@ -154,19 +154,21 @@
 
         for (int i = 0; i < eventCount; i++) {
             String name = "a" + (i % 10);
-            assertThat(iterator.next(item)).isTrue();
-            // Skip a blank event inserted at the start of every buffer
-            if (item.eventCode == BatteryStats.HistoryItem.EVENT_NONE) {
+            do {
                 assertThat(iterator.next(item)).isTrue();
-            }
+                // Skip a blank event inserted at the start of every buffer
+            } while (item.cmd != BatteryStats.HistoryItem.CMD_UPDATE
+                    || item.eventCode == BatteryStats.HistoryItem.EVENT_NONE);
+
             assertThat(item.eventCode).isEqualTo(BatteryStats.HistoryItem.EVENT_ALARM
                     | BatteryStats.HistoryItem.EVENT_FLAG_START);
             assertThat(item.eventTag.string).isEqualTo(name);
 
-            assertThat(iterator.next(item)).isTrue();
-            if (item.eventCode == BatteryStats.HistoryItem.EVENT_NONE) {
+            do {
                 assertThat(iterator.next(item)).isTrue();
-            }
+            } while (item.cmd != BatteryStats.HistoryItem.CMD_UPDATE
+                    || item.eventCode == BatteryStats.HistoryItem.EVENT_NONE);
+
             assertThat(item.eventCode).isEqualTo(BatteryStats.HistoryItem.EVENT_ALARM
                     | BatteryStats.HistoryItem.EVENT_FLAG_FINISH);
             assertThat(item.eventTag.string).isEqualTo(name);
diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java
index 9976fa1..db5e52a 100644
--- a/media/java/android/media/MediaMetadata.java
+++ b/media/java/android/media/MediaMetadata.java
@@ -429,6 +429,15 @@
     private MediaMetadata(Parcel in) {
         mBundle = in.readBundle();
         mBitmapDimensionLimit = Math.max(in.readInt(), 1);
+
+        // Proactively read bitmaps from known bitmap keys, to ensure that they're unparceled and
+        // added to mBundle's internal map. This ensures that the GC accounts for the underlying
+        // allocations, which it does not do if the bitmaps remain parceled (see b/215820910).
+        // TODO(b/223225532): Remove this workaround once the underlying allocations are properly
+        // tracked in NativeAllocationsRegistry.
+        getBitmap(METADATA_KEY_ART);
+        getBitmap(METADATA_KEY_ALBUM_ART);
+        getBitmap(METADATA_KEY_DISPLAY_ICON);
     }
 
     /**
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 490a3f5..6f22b49 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -723,7 +723,7 @@
                   android:excludeFromRecents="true"
                   android:stateNotNeeded="true"
                   android:resumeWhilePausing="true"
-                  android:theme="@style/Theme.AppCompat.DayNight.NoActionBar">
+                  android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
             <intent-filter>
                 <action android:name="android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER" />
                 <category android:name="android.intent.category.DEFAULT" />
diff --git a/packages/SystemUI/res/layout/auth_biometric_background.xml b/packages/SystemUI/res/layout/auth_biometric_background.xml
index 7ce81ad..995aea1 100644
--- a/packages/SystemUI/res/layout/auth_biometric_background.xml
+++ b/packages/SystemUI/res/layout/auth_biometric_background.xml
@@ -16,6 +16,8 @@
   -->
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:theme="@style/Theme.AppCompat.DayNight"
+    android:background="?android:colorBackground"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:gravity="center"
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 80ad93f..3ad43ac 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -485,6 +485,8 @@
      */
     private IRemoteAnimationRunner mKeyguardExitAnimationRunner;
 
+    private CentralSurfaces mCentralSurfaces;
+
     private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
             new DeviceConfig.OnPropertiesChangedListener() {
             @Override
@@ -845,6 +847,13 @@
                             + mOccluded);
                 }
 
+                @Override
+                public void onLaunchAnimationEnd(boolean launchIsFullScreen) {
+                    if (launchIsFullScreen) {
+                        mCentralSurfaces.instantCollapseNotificationPanel();
+                    }
+                }
+
                 @NonNull
                 @Override
                 public ViewGroup getLaunchContainer() {
@@ -2846,6 +2855,7 @@
             @Nullable PanelExpansionStateManager panelExpansionStateManager,
             BiometricUnlockController biometricUnlockController,
             View notificationContainer, KeyguardBypassController bypassController) {
+        mCentralSurfaces = centralSurfaces;
         mKeyguardViewControllerLazy.get().registerCentralSurfaces(
                 centralSurfaces,
                 panelView,
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
index 360f865..aeeef6b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
@@ -216,4 +216,20 @@
 
     /** Unique id for this device */
     val id: String? = null
-)
+) {
+    /**
+     * Check whether [MediaDeviceData] objects are equal in all fields except the icon. The icon
+     * is ignored because it can change by reference frequently depending on the device type's
+     * implementation, but this is not usually relevant unless other info has changed
+     */
+    fun equalsWithoutIcon(other: MediaDeviceData?): Boolean {
+        if (other == null) {
+            return false
+        }
+
+        return enabled == other.enabled &&
+            name == other.name &&
+            intent == other.intent &&
+            id == other.id
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
index 8558859..baed1c4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
@@ -155,8 +155,8 @@
         private var playbackType = PLAYBACK_TYPE_UNKNOWN
         private var current: MediaDeviceData? = null
             set(value) {
-                val hasSameId = value?.id != null && value.id == field?.id
-                if (!started || (!hasSameId && value != field)) {
+                val sameWithoutIcon = value != null && value.equalsWithoutIcon(field)
+                if (!started || !sameWithoutIcon) {
                     field = value
                     fgExecutor.execute {
                         processDevice(key, oldKey, value)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt
index 3417d49..05038b7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt
@@ -22,6 +22,8 @@
 import android.graphics.drawable.RippleDrawable
 import android.os.UserManager
 import android.util.AttributeSet
+import android.util.Log
+import android.view.MotionEvent
 import android.view.View
 import android.widget.ImageView
 import android.widget.LinearLayout
@@ -101,4 +103,18 @@
         }
         multiUserAvatar.setImageDrawable(pictureToSet)
     }
-}
\ No newline at end of file
+
+    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
+        if (VERBOSE) Log.d(TAG, "FooterActionsView onInterceptTouchEvent ${ev?.string}")
+        return super.onInterceptTouchEvent(ev)
+    }
+
+    override fun onTouchEvent(event: MotionEvent?): Boolean {
+        if (VERBOSE) Log.d(TAG, "FooterActionsView onTouchEvent ${event?.string}")
+        return super.onTouchEvent(event)
+    }
+}
+private const val TAG = "FooterActionsView"
+private val VERBOSE = Log.isLoggable(TAG, Log.VERBOSE)
+private val MotionEvent.string
+    get() = "($id): ($x,$y)"
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 367684f..705de9b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -1596,7 +1596,7 @@
                         }
                     }
                 });
-        mStatusBarKeyguardViewManager.registerCentralSurfaces(
+        mKeyguardViewMediator.registerCentralSurfaces(
                 /* statusBar= */ this,
                 mNotificationPanelViewController,
                 mPanelExpansionStateManager,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 557c995..2cac001 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -4142,6 +4142,11 @@
 
             @Override
             public boolean onInterceptTouchEvent(MotionEvent event) {
+                if (SPEW_LOGCAT) {
+                    Log.v(TAG,
+                            "NPVC onInterceptTouchEvent (" + event.getId() + "): (" + event.getX()
+                                    + "," + event.getY() + ")");
+                }
                 if (mBlockTouches || mQs.disallowPanelTouches()) {
                     return false;
                 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
index 18ee791..187210a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
@@ -47,7 +47,9 @@
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.reset
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
 import org.mockito.junit.MockitoJUnit
 import org.mockito.Mockito.`when` as whenever
 
@@ -55,6 +57,7 @@
 private const val KEY_OLD = "TEST_KEY_OLD"
 private const val PACKAGE = "PKG"
 private const val SESSION_KEY = "SESSION_KEY"
+private const val DEVICE_ID = "DEVICE_ID"
 private const val DEVICE_NAME = "DEVICE_NAME"
 private const val REMOTE_DEVICE_NAME = "REMOTE_DEVICE_NAME"
 
@@ -457,6 +460,89 @@
     }
 
     @Test
+    fun deviceIdChanged_informListener() {
+        // GIVEN a notification is added, with a particular device connected
+        whenever(device.id).thenReturn(DEVICE_ID)
+        manager.onMediaDataLoaded(KEY, null, mediaData)
+        fakeBgExecutor.runAllReady()
+        fakeFgExecutor.runAllReady()
+
+        // and later the manager gets a new device ID
+        val deviceCallback = captureCallback()
+        val updatedId = DEVICE_ID + "_new"
+        whenever(device.id).thenReturn(updatedId)
+        deviceCallback.onDeviceListUpdate(mutableListOf(device))
+
+        // THEN the listener gets the updated info
+        fakeBgExecutor.runAllReady()
+        fakeFgExecutor.runAllReady()
+
+        val dataCaptor = ArgumentCaptor.forClass(MediaDeviceData::class.java)
+        verify(listener, times(2)).onMediaDeviceChanged(eq(KEY), any(), dataCaptor.capture())
+
+        val firstDevice = dataCaptor.allValues.get(0)
+        assertThat(firstDevice.id).isEqualTo(DEVICE_ID)
+
+        val secondDevice = dataCaptor.allValues.get(1)
+        assertThat(secondDevice.id).isEqualTo(updatedId)
+    }
+
+    @Test
+    fun deviceNameChanged_informListener() {
+        // GIVEN a notification is added, with a particular device connected
+        whenever(device.id).thenReturn(DEVICE_ID)
+        whenever(device.name).thenReturn(DEVICE_NAME)
+        manager.onMediaDataLoaded(KEY, null, mediaData)
+        fakeBgExecutor.runAllReady()
+        fakeFgExecutor.runAllReady()
+
+        // and later the manager gets a new device name
+        val deviceCallback = captureCallback()
+        val updatedName = DEVICE_NAME + "_new"
+        whenever(device.name).thenReturn(updatedName)
+        deviceCallback.onDeviceListUpdate(mutableListOf(device))
+
+        // THEN the listener gets the updated info
+        fakeBgExecutor.runAllReady()
+        fakeFgExecutor.runAllReady()
+
+        val dataCaptor = ArgumentCaptor.forClass(MediaDeviceData::class.java)
+        verify(listener, times(2)).onMediaDeviceChanged(eq(KEY), any(), dataCaptor.capture())
+
+        val firstDevice = dataCaptor.allValues.get(0)
+        assertThat(firstDevice.name).isEqualTo(DEVICE_NAME)
+
+        val secondDevice = dataCaptor.allValues.get(1)
+        assertThat(secondDevice.name).isEqualTo(updatedName)
+    }
+
+    @Test
+    fun deviceIconChanged_doesNotCallListener() {
+        // GIVEN a notification is added, with a particular device connected
+        whenever(device.id).thenReturn(DEVICE_ID)
+        whenever(device.name).thenReturn(DEVICE_NAME)
+        val firstIcon = mock(Drawable::class.java)
+        whenever(device.icon).thenReturn(firstIcon)
+        manager.onMediaDataLoaded(KEY, null, mediaData)
+        fakeBgExecutor.runAllReady()
+        fakeFgExecutor.runAllReady()
+
+        val dataCaptor = ArgumentCaptor.forClass(MediaDeviceData::class.java)
+        verify(listener).onMediaDeviceChanged(eq(KEY), any(), dataCaptor.capture())
+
+        // and later the manager gets a callback with only the icon changed
+        val deviceCallback = captureCallback()
+        val secondIcon = mock(Drawable::class.java)
+        whenever(device.icon).thenReturn(secondIcon)
+        deviceCallback.onDeviceListUpdate(mutableListOf(device))
+
+        // THEN the listener is not called again
+        fakeBgExecutor.runAllReady()
+        fakeFgExecutor.runAllReady()
+        verifyNoMoreInteractions(listener)
+    }
+
+    @Test
     fun testRemotePlaybackDeviceOverride() {
         whenever(route.name).thenReturn(DEVICE_NAME)
         val deviceData = MediaDeviceData(false, null, REMOTE_DEVICE_NAME, null)
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index e37d7b0..6076eb1 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -1115,6 +1115,14 @@
                 DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "prompt_fgs_with_noti_on_long_running";
 
         /**
+         * The behavior for an app with a FGS, when the system detects it's running for
+         * a very long time, should we prompt the user.
+         * {@code true} - we'll show the prompt to user, {@code false} - we'll not show it.
+         */
+        static final String KEY_BG_PROMPT_FGS_ON_LONG_RUNNING =
+                DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "prompt_fgs_on_long_running";
+
+        /**
          * The list of packages to be exempted from all these background restrictions.
          */
         static final String KEY_BG_RESTRICTION_EXEMPTED_PACKAGES =
@@ -1154,6 +1162,11 @@
         static final boolean DEFAULT_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING = false;
 
         /**
+         * Default value to {@link #mBgPromptFgsOnLongRunning}.
+         */
+        static final boolean DEFAULT_BG_PROMPT_FGS_ON_LONG_RUNNING = true;
+
+        /**
          * Default value to {@link #mBgPromptFgsWithNotiToBgRestricted}.
          */
         final boolean mDefaultBgPromptFgsWithNotiToBgRestricted;
@@ -1191,6 +1204,11 @@
         volatile boolean mBgPromptFgsWithNotiOnLongRunning;
 
         /**
+         * @see #KEY_BG_PROMPT_FGS_ON_LONG_RUNNING.
+         */
+        volatile boolean mBgPromptFgsOnLongRunning;
+
+        /**
          * @see #KEY_BG_PROMPT_ABUSIVE_APPS_TO_BG_RESTRICTED.
          */
         volatile boolean mBgPromptAbusiveAppsToBgRestricted;
@@ -1228,6 +1246,9 @@
                     case KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING:
                         updateBgPromptFgsWithNotiOnLongRunning();
                         break;
+                    case KEY_BG_PROMPT_FGS_ON_LONG_RUNNING:
+                        updateBgPromptFgsOnLongRunning();
+                        break;
                     case KEY_BG_PROMPT_ABUSIVE_APPS_TO_BG_RESTRICTED:
                         updateBgPromptAbusiveAppToBgRestricted();
                         break;
@@ -1269,6 +1290,7 @@
             updateBgLongFgsNotificationMinimalInterval();
             updateBgPromptFgsWithNotiToBgRestricted();
             updateBgPromptFgsWithNotiOnLongRunning();
+            updateBgPromptFgsOnLongRunning();
             updateBgPromptAbusiveAppToBgRestricted();
             updateBgRestrictionExemptedPackages();
         }
@@ -1319,6 +1341,13 @@
                     DEFAULT_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING);
         }
 
+        private void updateBgPromptFgsOnLongRunning() {
+            mBgPromptFgsOnLongRunning = DeviceConfig.getBoolean(
+                    DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                    KEY_BG_PROMPT_FGS_ON_LONG_RUNNING,
+                    DEFAULT_BG_PROMPT_FGS_ON_LONG_RUNNING);
+        }
+
         private void updateBgPromptAbusiveAppToBgRestricted() {
             mBgPromptAbusiveAppsToBgRestricted = DeviceConfig.getBoolean(
                     DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -1365,6 +1394,14 @@
             pw.print('=');
             pw.println(mBgLongFgsNotificationMinIntervalMs);
             pw.print(prefix);
+            pw.print(KEY_BG_PROMPT_FGS_ON_LONG_RUNNING);
+            pw.print('=');
+            pw.println(mBgPromptFgsOnLongRunning);
+            pw.print(prefix);
+            pw.print(KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING);
+            pw.print('=');
+            pw.println(mBgPromptFgsWithNotiOnLongRunning);
+            pw.print(prefix);
             pw.print(KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_TO_BG_RESTRICTED);
             pw.print('=');
             pw.println(mBgPromptFgsWithNotiToBgRestricted);
@@ -2500,6 +2537,12 @@
                     ActivityManager.isLowRamDeviceStatic(),
                     mBgController.getRestrictionLevel(uid));
             PendingIntent pendingIntent;
+            if (!mBgController.mConstantsObserver.mBgPromptFgsOnLongRunning) {
+                if (DEBUG_BG_RESTRICTION_CONTROLLER) {
+                    Slog.i(TAG, "Long-running FGS prompt is disabled.");
+                }
+                return;
+            }
             if (!mBgController.mConstantsObserver.mBgPromptFgsWithNotiOnLongRunning
                     && mBgController.hasForegroundServiceNotifications(packageName, uid)) {
                 if (DEBUG_BG_RESTRICTION_CONTROLLER) {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index a2048a3..92a8dcd 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2794,15 +2794,6 @@
         }
 
         int N = procs.size();
-        for (int i = 0; i < N; ++i) {
-            final ProcessRecord proc = procs.get(i).first;
-            try {
-                Process.setProcessFrozen(proc.getPid(), proc.uid, true);
-            } catch (Exception e) {
-                Slog.w(TAG, "Unable to freeze " + proc.getPid() + " " + proc.processName);
-            }
-        }
-
         for (int i=0; i<N; i++) {
             final Pair<ProcessRecord, Boolean> proc = procs.get(i);
             removeProcessLocked(proc.first, callerWillRestart, allowRestart || proc.second,
diff --git a/services/core/java/com/android/server/devicestate/DeviceState.java b/services/core/java/com/android/server/devicestate/DeviceState.java
index 78d55b9..f8d4b8f 100644
--- a/services/core/java/com/android/server/devicestate/DeviceState.java
+++ b/services/core/java/com/android/server/devicestate/DeviceState.java
@@ -18,6 +18,7 @@
 
 import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE;
 import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE;
+import static android.view.Display.DEFAULT_DISPLAY;
 
 import android.annotation.IntDef;
 import android.annotation.IntRange;
@@ -48,9 +49,16 @@
      */
     public static final int FLAG_CANCEL_OVERRIDE_REQUESTS = 1 << 0;
 
+    /**
+     * Flag that indicates this device state is inaccessible for applications to be placed in. This
+     * could be a device-state where the {@link DEFAULT_DISPLAY} is not enabled.
+     */
+    public static final int FLAG_APP_INACCESSIBLE = 1 << 1;
+
     /** @hide */
     @IntDef(prefix = {"FLAG_"}, flag = true, value = {
             FLAG_CANCEL_OVERRIDE_REQUESTS,
+            FLAG_APP_INACCESSIBLE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface DeviceStateFlags {}
@@ -97,7 +105,8 @@
 
     @Override
     public String toString() {
-        return "DeviceState{" + "identifier=" + mIdentifier + ", name='" + mName + '\'' + '}';
+        return "DeviceState{" + "identifier=" + mIdentifier + ", name='" + mName + '\''
+                + ", app_accessible=" + !hasFlag(FLAG_APP_INACCESSIBLE) + "}";
     }
 
     @Override
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index cf63b69..6fd8841 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -1057,7 +1057,17 @@
 
     public void recalculateSplines(boolean applyAdjustment, float[] adjustment) {
         mCurrentBrightnessMapper.recalculateSplines(applyAdjustment, adjustment);
-        updateAutoBrightness(true /*sendUpdate*/, false /*isManuallySet*/);
+
+        // If rbc is turned on, off or there is a change in strength, we want to reset the short
+        // term model. Since the nits range at which brightness now operates has changed due to
+        // RBC/strength change, any short term model based on the previous range should be
+        // invalidated.
+        resetShortTermModel();
+
+        // When rbc is turned on, we want to accommodate this change in the short term model.
+        if (applyAdjustment) {
+            setScreenBrightnessByUser(getAutomaticScreenBrightness());
+        }
     }
 
     private final class AutomaticBrightnessHandler extends Handler {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index a5bb716..d05a902 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -657,12 +657,6 @@
         }
         mIsRbcActive = mCdsi.isReduceBrightColorsActivated();
         mAutomaticBrightnessController.recalculateSplines(mIsRbcActive, adjustedNits);
-
-        // If rbc is turned on, off or there is a change in strength, we want to reset the short
-        // term model. Since the nits range at which brightness now operates has changed due to
-        // RBC/strength change, any short term model based on the previous range should be
-        // invalidated.
-        mAutomaticBrightnessController.resetShortTermModel();
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/AppsFilterImpl.java b/services/core/java/com/android/server/pm/AppsFilterImpl.java
index 9fddc76..181c39e 100644
--- a/services/core/java/com/android/server/pm/AppsFilterImpl.java
+++ b/services/core/java/com/android/server/pm/AppsFilterImpl.java
@@ -418,7 +418,9 @@
         } else if (changed) {
             invalidateCache("grantImplicitAccess: " + recipientUid + " -> " + visibleUid);
         }
-        onChanged();
+        if (changed) {
+            onChanged();
+        }
         return changed;
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4f8c792..94e8ec5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2859,12 +2859,15 @@
         mDexOptHelper.performPackageDexOptUpgradeIfNeeded();
     }
 
-
     private void notifyPackageUseInternal(String packageName, int reason) {
         long time = System.currentTimeMillis();
-        commitPackageStateMutation(null, packageName, packageState -> {
-            packageState.setLastPackageUsageTime(reason, time);
-        });
+        synchronized (mLock) {
+            final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
+            if (pkgSetting == null) {
+                return;
+            }
+            pkgSetting.getPkgState().setLastPackageUsageTimeInMills(reason, time);
+        }
     }
 
     /*package*/ DexManager getDexManager() {
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index cc1c943..0ae92b4 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -911,6 +911,11 @@
         grantSystemFixedPermissionsToSystemPackage(pm,
                 MidiManager.BLUETOOTH_MIDI_SERVICE_PACKAGE, userId,
                 NEARBY_DEVICES_PERMISSIONS);
+
+        // Ad Service
+        String commonServiceAction = "android.adservices.AD_SERVICES_COMMON_SERVICE";
+        grantPermissionsToSystemPackage(pm, getDefaultSystemHandlerServicePackage(pm,
+                        commonServiceAction, userId), userId, NOTIFICATION_PERMISSIONS);
     }
 
     private String getDefaultSystemHandlerActivityPackageForCategory(PackageManagerWrapper pm,
diff --git a/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java b/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
index 7bd720a..5251fe0 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
@@ -79,7 +79,10 @@
             return this;
         }
         getLastPackageUsageTimeInMills()[reason] = time;
-        mPackageSetting.onChanged();
+        // TODO(b/236180425): This method does not notify snapshot changes because it's called too
+        //  frequently, causing too many re-takes. This should be moved to a separate data structure
+        //  or merged with the general UsageStats to avoid tracking heavily mutated data in the
+        //  package data snapshot.
         return this;
     }
 
diff --git a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
index 17a5fd0..9b7d19a 100644
--- a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
+++ b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
@@ -95,6 +95,7 @@
     private static final String DATA_CONFIG_FILE_PATH = "system/devicestate/";
     private static final String CONFIG_FILE_NAME = "device_state_configuration.xml";
     private static final String FLAG_CANCEL_OVERRIDE_REQUESTS = "FLAG_CANCEL_OVERRIDE_REQUESTS";
+    private static final String FLAG_APP_INACCESSIBLE = "FLAG_APP_INACCESSIBLE";
 
     /** Interface that allows reading the device state configuration. */
     interface ReadableConfig {
@@ -145,6 +146,9 @@
                                 case FLAG_CANCEL_OVERRIDE_REQUESTS:
                                     flags |= DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS;
                                     break;
+                                case FLAG_APP_INACCESSIBLE:
+                                    flags |= DeviceState.FLAG_APP_INACCESSIBLE;
+                                    break;
                                 default:
                                     Slog.w(TAG, "Parsed unknown flag with name: "
                                             + configFlagString);
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index dd0ec94..43d62aa 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -21,6 +21,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.Signature;
 import android.os.AsyncTask;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.util.Slog;
 import android.webkit.UserPackage;
@@ -265,10 +266,12 @@
                 // Either the current relro creation  isn't done yet, or the new relro creatioin
                 // hasn't kicked off yet (the last relro creation used an out-of-date WebView).
                 webViewStatus = WebViewFactory.LIBLOAD_FAILED_WAITING_FOR_RELRO;
-                Slog.e(TAG, "Timed out waiting for relro creation, relros started "
+                String timeoutError = "Timed out waiting for relro creation, relros started "
                         + mNumRelroCreationsStarted
                         + " relros finished " + mNumRelroCreationsFinished
-                        + " package dirty? " + mWebViewPackageDirty);
+                        + " package dirty? " + mWebViewPackageDirty;
+                Slog.e(TAG, timeoutError);
+                Trace.instant(Trace.TRACE_TAG_ACTIVITY_MANAGER, timeoutError);
             }
         }
         if (!webViewReady) Slog.w(TAG, "creating relro file timed out");
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 3bb40b0..4c32edc 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -884,7 +884,9 @@
      * {@link InsetsStateController#notifyInsetsChanged}.
      */
     boolean isReadyToDispatchInsetsState() {
-        return isVisibleRequested() && mFrozenInsetsState == null;
+        final boolean visible = shouldCheckTokenVisibleRequested()
+                ? isVisibleRequested() : isVisible();
+        return visible && mFrozenInsetsState == null;
     }
 
     void seamlesslyRotateIfAllowed(Transaction transaction, @Rotation int oldRotation,
diff --git a/services/proguard.flags b/services/proguard.flags
index bad02b4..c648f7d 100644
--- a/services/proguard.flags
+++ b/services/proguard.flags
@@ -68,6 +68,9 @@
 # TODO(b/210510433): Revisit and consider generating from frameworks/base/core/res/res/values/config.xml.
 -keep,allowoptimization,allowaccessmodification public class com.android.server.notification.** implements com.android.server.notification.NotificationSignalExtractor
 
+# OEM provided DisplayAreaPolicy.Provider defined in frameworks/base/core/res/res/values/config.xml.
+-keep,allowoptimization,allowaccessmodification class com.android.server.wm.** implements com.android.server.wm.DisplayAreaPolicy$Provider
+
 # JNI keep rules
 # TODO(b/210510433): Revisit and fix with @Keep, or consider auto-generating from
 # frameworks/base/services/core/jni/onload.cpp.
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
index fa8d569..f02571f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
@@ -1141,6 +1141,7 @@
         DeviceConfigSession<Long> longRunningFGSWindow = null;
         DeviceConfigSession<Long> longRunningFGSThreshold = null;
         DeviceConfigSession<Boolean> longRunningFGSWithNotification = null;
+        DeviceConfigSession<Boolean> longRunningFGS = null;
 
         try {
             longRunningFGSMonitor = new DeviceConfigSession<>(
@@ -1171,6 +1172,13 @@
                     ConstantsObserver.DEFAULT_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING);
             longRunningFGSWithNotification.set(true);
 
+            longRunningFGS = new DeviceConfigSession<>(
+                    DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                    ConstantsObserver.KEY_BG_PROMPT_FGS_ON_LONG_RUNNING,
+                    DeviceConfig::getBoolean,
+                    ConstantsObserver.DEFAULT_BG_PROMPT_FGS_ON_LONG_RUNNING);
+            longRunningFGS.set(true);
+
             // Basic case
             mAppFGSTracker.onForegroundServiceStateChanged(testPkgName1, testUid1,
                     testPid1, true);
@@ -1214,6 +1222,23 @@
                     testPid2, false);
             checkNotificationGone(testPkgName2, timeout(windowMs), notificationId);
 
+            // Turn OFF the notification.
+            longRunningFGS.set(false);
+            clearInvocations(mInjector.getNotificationManager());
+            mBgRestrictionController.resetRestrictionSettings();
+            // Start the FGS again.
+            mAppFGSTracker.onForegroundServiceStateChanged(testPkgName2, testUid2,
+                    testPid2, true);
+            // Verify we do NOT have the notification.
+            checkNotificationShown(
+                    new String[] {testPkgName2}, timeout(windowMs * 2).times(0), false);
+            // Stop this FGS
+            mAppFGSTracker.onForegroundServiceStateChanged(testPkgName2, testUid2,
+                    testPid2, false);
+
+            // Turn it back ON.
+            longRunningFGS.set(true);
+
             // Start over with concurrent cases.
             clearInvocations(mInjector.getNotificationManager());
             mBgRestrictionController.resetRestrictionSettings();
@@ -1306,6 +1331,7 @@
             closeIfNotNull(longRunningFGSWindow);
             closeIfNotNull(longRunningFGSThreshold);
             closeIfNotNull(longRunningFGSWithNotification);
+            closeIfNotNull(longRunningFGS);
         }
     }
 
@@ -1332,6 +1358,7 @@
         DeviceConfigSession<Long> mediaPlaybackFGSThreshold = null;
         DeviceConfigSession<Long> locationFGSThreshold = null;
         DeviceConfigSession<Boolean> longRunningFGSWithNotification = null;
+        DeviceConfigSession<Boolean> longRunningFGS = null;
 
         doReturn(testPkgName1).when(mInjector).getPackageName(testPid1);
         doReturn(testPkgName2).when(mInjector).getPackageName(testPid2);
@@ -1379,6 +1406,13 @@
                     ConstantsObserver.DEFAULT_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING);
             longRunningFGSWithNotification.set(true);
 
+            longRunningFGS = new DeviceConfigSession<>(
+                    DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                    ConstantsObserver.KEY_BG_PROMPT_FGS_ON_LONG_RUNNING,
+                    DeviceConfig::getBoolean,
+                    ConstantsObserver.DEFAULT_BG_PROMPT_FGS_ON_LONG_RUNNING);
+            longRunningFGS.set(true);
+
             // Long-running FGS with type "location", but ran for a very short time.
             runTestLongFGSExemptionOnce(testPkgName1, testUid1, testPid1,
                     FOREGROUND_SERVICE_TYPE_LOCATION, 0, null, OP_NONE, null, null,
@@ -1487,6 +1521,7 @@
             closeIfNotNull(mediaPlaybackFGSThreshold);
             closeIfNotNull(locationFGSThreshold);
             closeIfNotNull(longRunningFGSWithNotification);
+            closeIfNotNull(longRunningFGS);
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
index b0c52f1..9d82f1a 100644
--- a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyFloat;
 import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -258,29 +259,36 @@
     @Test
     public void testRecalculateSplines() throws Exception {
         // Enabling the light sensor, and setting the ambient lux to 1000
+        int currentLux = 1000;
         ArgumentCaptor<SensorEventListener> listenerCaptor =
                 ArgumentCaptor.forClass(SensorEventListener.class);
         verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor),
                 eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
         SensorEventListener listener = listenerCaptor.getValue();
-        listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 1000));
+        listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, currentLux));
 
-        //Setting the brightnessFloat to 0.5f
-        float currentBrightnessFloat = 0.5f;
-        when(mBrightnessMappingStrategy.getBrightness(1000,
-                null, ApplicationInfo.CATEGORY_UNDEFINED)).thenReturn(currentBrightnessFloat);
+        // User sets brightness to 0.5f
+        when(mBrightnessMappingStrategy.getBrightness(currentLux,
+                null, ApplicationInfo.CATEGORY_UNDEFINED)).thenReturn(0.5f);
         mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration */,
-                currentBrightnessFloat /* brightness */, false /* userChangedBrightness */,
-                0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT);
+                0.5f /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */,
+                false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT);
 
-        // Adjusting spline, and accordingly remapping the current 0.5f brightnessFloat to 0.3f
-        float updatedBrightnessFloat = 0.3f;
-        when(mBrightnessMappingStrategy.getBrightness(1000,
-                null, ApplicationInfo.CATEGORY_UNDEFINED)).thenReturn(updatedBrightnessFloat);
-        float[] adjustments = new float[]{0.2f, 0.5f};
+        //Recalculating the spline with RBC enabled, verifying that the short term model is reset,
+        //and the interaction is learnt in short term model
+        float[] adjustments = new float[]{0.2f, 0.6f};
         mController.recalculateSplines(true, adjustments);
+        verify(mBrightnessMappingStrategy).clearUserDataPoints();
         verify(mBrightnessMappingStrategy).recalculateSplines(true, adjustments);
-        assertEquals(mController.getAutomaticScreenBrightness(), updatedBrightnessFloat, EPSILON);
+        verify(mBrightnessMappingStrategy, times(2)).addUserDataPoint(currentLux, 0.5f);
+
+        clearInvocations(mBrightnessMappingStrategy);
+
+        // Verify short term model is not learnt when RBC is disabled
+        mController.recalculateSplines(false, adjustments);
+        verify(mBrightnessMappingStrategy).clearUserDataPoints();
+        verify(mBrightnessMappingStrategy).recalculateSplines(false, adjustments);
+        verifyNoMoreInteractions(mBrightnessMappingStrategy);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index e8f343e..20935f1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -927,6 +927,15 @@
         assertTrue(app.isReadyToDispatchInsetsState());
         mDisplayContent.getInsetsStateController().notifyInsetsChanged();
         verify(app).notifyInsetsChanged();
+
+        // Verify that invisible non-activity window won't dispatch insets changed.
+        final WindowState overlay = createWindow(null, TYPE_APPLICATION_OVERLAY, "overlay");
+        makeWindowVisible(overlay);
+        assertTrue(overlay.isReadyToDispatchInsetsState());
+        overlay.mHasSurface = false;
+        assertFalse(overlay.isReadyToDispatchInsetsState());
+        mDisplayContent.getInsetsStateController().notifyInsetsChanged();
+        assertFalse(overlay.getWindowFrames().hasInsetsChanged());
     }
 
     @UseTestDisplay(addWindows = {W_INPUT_METHOD, W_ACTIVITY})