Merge "Avoid multiple calls to start/stop FGS for the same session record" into main
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index f02a3ff..1ebc856 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -197,6 +197,16 @@
@GuardedBy("mLock")
private final Map<Integer, Set<Notification>> mMediaNotifications = new HashMap<>();
+ /**
+ * Holds all {@link MediaSessionRecordImpl} which we've reported as being {@link
+ * ActivityManagerInternal#startForegroundServiceDelegate user engaged}.
+ *
+ * <p>This map simply prevents invoking {@link
+ * ActivityManagerInternal#startForegroundServiceDelegate} more than once per session.
+ */
+ @GuardedBy("mLock")
+ private final Set<MediaSessionRecordImpl> mFgsAllowedMediaSessionRecords = new HashSet<>();
+
// The FullUserRecord of the current users. (i.e. The foreground user that isn't a profile)
// It's always not null after the MediaSessionService is started.
private FullUserRecord mCurrentFullUserRecord;
@@ -704,15 +714,23 @@
int uid = mediaSessionRecord.getUid();
for (Notification mediaNotification : mMediaNotifications.getOrDefault(uid, Set.of())) {
if (mediaSessionRecord.isLinkedToNotification(mediaNotification)) {
- startFgsDelegate(mediaSessionRecord.getForegroundServiceDelegationOptions());
+ startFgsDelegateLocked(mediaSessionRecord);
return;
}
}
}
}
- private void startFgsDelegate(
- ForegroundServiceDelegationOptions foregroundServiceDelegationOptions) {
+ @GuardedBy("mLock")
+ private void startFgsDelegateLocked(MediaSessionRecordImpl mediaSessionRecord) {
+ ForegroundServiceDelegationOptions foregroundServiceDelegationOptions =
+ mediaSessionRecord.getForegroundServiceDelegationOptions();
+ if (foregroundServiceDelegationOptions == null) {
+ return; // This record doesn't support FGS. Typically a MediaSession2 record.
+ }
+ if (!mFgsAllowedMediaSessionRecords.add(mediaSessionRecord)) {
+ return; // This record is already FGS-started.
+ }
final long token = Binder.clearCallingIdentity();
try {
Log.i(
@@ -754,12 +772,21 @@
}
}
- stopFgsDelegate(foregroundServiceDelegationOptions);
+ stopFgsDelegateLocked(mediaSessionRecord);
}
}
- private void stopFgsDelegate(
- ForegroundServiceDelegationOptions foregroundServiceDelegationOptions) {
+ @GuardedBy("mLock")
+ private void stopFgsDelegateLocked(MediaSessionRecordImpl mediaSessionRecord) {
+ ForegroundServiceDelegationOptions foregroundServiceDelegationOptions =
+ mediaSessionRecord.getForegroundServiceDelegationOptions();
+ if (foregroundServiceDelegationOptions == null) {
+ return; // This record doesn't support FGS. Typically a MediaSession2 record.
+ }
+ if (!mFgsAllowedMediaSessionRecords.remove(mediaSessionRecord)) {
+ return; // This record is not FGS-started. No need to stop it.
+ }
+
final long token = Binder.clearCallingIdentity();
try {
Log.i(
@@ -3209,11 +3236,8 @@
mMediaNotifications.get(uid).add(postedNotification);
for (MediaSessionRecordImpl mediaSessionRecord :
mUserEngagedSessionsForFgs.getOrDefault(uid, Set.of())) {
- ForegroundServiceDelegationOptions foregroundServiceDelegationOptions =
- mediaSessionRecord.getForegroundServiceDelegationOptions();
- if (foregroundServiceDelegationOptions != null
- && mediaSessionRecord.isLinkedToNotification(postedNotification)) {
- startFgsDelegate(foregroundServiceDelegationOptions);
+ if (mediaSessionRecord.isLinkedToNotification(postedNotification)) {
+ startFgsDelegateLocked(mediaSessionRecord);
return;
}
}