Merge "Fix high traffic PMS lockless methods" 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/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/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/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/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/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})