Loading services/core/java/com/android/server/media/MediaSession2Record.java +2 −6 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.server.media; import android.app.ForegroundServiceDelegationOptions; import android.app.Notification; import android.media.MediaController2; import android.media.Session2CommandGroup; Loading Loading @@ -98,11 +97,8 @@ public class MediaSession2Record extends MediaSessionRecordImpl { } @Override public ForegroundServiceDelegationOptions getForegroundServiceDelegationOptions() { // For an app to be eligible for FGS delegation, it needs a media session liked to a media // notification. Currently, notifications cannot be linked to MediaSession2 so it is not // supported. return null; public boolean hasLinkedNotificationSupport() { return false; } @Override Loading services/core/java/com/android/server/media/MediaSessionRecord.java +5 −30 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ForegroundServiceDelegationOptions; import android.app.Notification; import android.app.PendingIntent; import android.app.compat.CompatChanges; Loading Loading @@ -184,8 +183,6 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde private final UriGrantsManagerInternal mUgmInternal; private final Context mContext; private final ForegroundServiceDelegationOptions mForegroundServiceDelegationOptions; private final Object mLock = new Object(); // This field is partially guarded by mLock. Writes and non-atomic iterations (for example: // index-based-iterations) must be guarded by mLock. But it is safe to acquire an iterator Loading Loading @@ -306,32 +303,10 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde mPolicies = policies; mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class); mForegroundServiceDelegationOptions = createForegroundServiceDelegationOptions(); // May throw RemoteException if the session app is killed. mSessionCb.mCb.asBinder().linkToDeath(this, 0); } private ForegroundServiceDelegationOptions createForegroundServiceDelegationOptions() { return new ForegroundServiceDelegationOptions.Builder() .setClientPid(mOwnerPid) .setClientUid(getUid()) .setClientPackageName(getPackageName()) .setClientAppThread(null) .setSticky(false) .setClientInstanceName( "MediaSessionFgsDelegate_" + getUid() + "_" + mOwnerPid + "_" + getPackageName()) .setForegroundServiceTypes(0) .setDelegationService( ForegroundServiceDelegationOptions.DELEGATION_SERVICE_MEDIA_PLAYBACK) .build(); } /** * Get the session binder for the {@link MediaSession}. * Loading Loading @@ -389,6 +364,11 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde return mUserId; } @Override public boolean hasLinkedNotificationSupport() { return true; } /** * Check if this session has system priorty and should receive media buttons * before any other sessions. Loading Loading @@ -752,11 +732,6 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde return mPackageName + "/" + mTag + "/" + getUniqueId() + " (userId=" + mUserId + ")"; } @Override public ForegroundServiceDelegationOptions getForegroundServiceDelegationOptions() { return mForegroundServiceDelegationOptions; } private void postAdjustLocalVolume(final int stream, final int direction, final int flags, final String callingOpPackageName, final int callingPid, final int callingUid, final boolean asSystemService, final boolean useSuggested, Loading services/core/java/com/android/server/media/MediaSessionRecordImpl.java +6 −7 Original line number Diff line number Diff line Loading @@ -16,10 +16,8 @@ package com.android.server.media; import android.app.ForegroundServiceDelegationOptions; import android.app.Notification; import android.media.AudioManager; import android.media.session.PlaybackState; import android.os.ResultReceiver; import android.view.KeyEvent; Loading Loading @@ -63,13 +61,14 @@ public abstract class MediaSessionRecordImpl { public abstract int getUserId(); /** * Get the {@link ForegroundServiceDelegationOptions} needed for notifying activity manager * service with changes in the {@link PlaybackState} for this session. * Returns whether this session supports linked notifications. * * @return the {@link ForegroundServiceDelegationOptions} needed for notifying the activity * manager service with changes in the {@link PlaybackState} for this session. * <p>A notification is linked to a media session if it contains * {@link android.app.Notification#EXTRA_MEDIA_SESSION}. * * @return {@code true} if this session supports linked notifications, {@code false} otherwise. */ public abstract ForegroundServiceDelegationOptions getForegroundServiceDelegationOptions(); public abstract boolean hasLinkedNotificationSupport(); /** * Check if this session has system priority and should receive media buttons before any other Loading services/core/java/com/android/server/media/MediaSessionService.java +68 −56 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ForegroundServiceDelegationOptions; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationManager; Loading Loading @@ -185,9 +184,9 @@ public class MediaSessionService extends SystemService implements Monitor { /** * Maps uid with all user engaged session records associated to it. It's used for calling * ActivityManagerInternal startFGS and stopFGS. This collection doesn't contain * MediaSession2Record(s). When the media session is paused, There exists a timeout before * calling stopFGS unlike usage logging which considers it disengaged immediately. * ActivityManagerInternal internal api to set fgs active/inactive. This collection doesn't * contain MediaSession2Record(s). When the media session is paused, There exists a timeout * before setting FGS inactive unlike usage logging which considers it disengaged immediately. */ @GuardedBy("mLock") private final Map<Integer, Set<MediaSessionRecordImpl>> mUserEngagedSessionsForFgs = Loading @@ -195,7 +194,7 @@ public class MediaSessionService extends SystemService implements Monitor { /* Maps uid with all media notifications associated to it */ @GuardedBy("mLock") private final Map<Integer, Set<Notification>> mMediaNotifications = new HashMap<>(); private final Map<Integer, Set<StatusBarNotification>> mMediaNotifications = new HashMap<>(); /** * Holds all {@link MediaSessionRecordImpl} which we've reported as being {@link Loading Loading @@ -700,10 +699,10 @@ public class MediaSessionService extends SystemService implements Monitor { MediaSessionRecordImpl mediaSessionRecord, boolean isUserEngaged) { if (isUserEngaged) { addUserEngagedSession(mediaSessionRecord); startFgsIfSessionIsLinkedToNotification(mediaSessionRecord); setFgsActiveIfSessionIsLinkedToNotification(mediaSessionRecord); } else { removeUserEngagedSession(mediaSessionRecord); stopFgsIfNoSessionIsLinkedToNotification(mediaSessionRecord); setFgsInactiveIfNoSessionIsLinkedToNotification(mediaSessionRecord); } } Loading Loading @@ -737,17 +736,20 @@ public class MediaSessionService extends SystemService implements Monitor { } } private void startFgsIfSessionIsLinkedToNotification( private void setFgsActiveIfSessionIsLinkedToNotification( MediaSessionRecordImpl mediaSessionRecord) { Log.d(TAG, "startFgsIfSessionIsLinkedToNotification: record=" + mediaSessionRecord); Log.d(TAG, "setFgsIfSessionIsLinkedToNotification: record=" + mediaSessionRecord); if (!Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange()) { return; } if (!mediaSessionRecord.hasLinkedNotificationSupport()) { return; } synchronized (mLock) { int uid = mediaSessionRecord.getUid(); for (Notification mediaNotification : mMediaNotifications.getOrDefault(uid, Set.of())) { if (mediaSessionRecord.isLinkedToNotification(mediaNotification)) { startFgsDelegateLocked(mediaSessionRecord); for (StatusBarNotification sbn : mMediaNotifications.getOrDefault(uid, Set.of())) { if (mediaSessionRecord.isLinkedToNotification(sbn.getNotification())) { setFgsActiveLocked(mediaSessionRecord, sbn); return; } } Loading @@ -755,81 +757,92 @@ public class MediaSessionService extends SystemService implements Monitor { } @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. } private void setFgsActiveLocked(MediaSessionRecordImpl mediaSessionRecord, StatusBarNotification sbn) { if (!mFgsAllowedMediaSessionRecords.add(mediaSessionRecord)) { return; // This record is already FGS-started. return; // This record already is FGS-activated. } final long token = Binder.clearCallingIdentity(); try { final String packageName = sbn.getPackageName(); final int uid = sbn.getUid(); final int notificationId = sbn.getId(); Log.i( TAG, TextUtils.formatSimple( "startFgsDelegate: pkg=%s uid=%d", foregroundServiceDelegationOptions.mClientPackageName, foregroundServiceDelegationOptions.mClientUid)); mActivityManagerInternal.startForegroundServiceDelegate( foregroundServiceDelegationOptions, /* connection= */ null); "setFgsActiveLocked: pkg=%s uid=%d notification=%d", packageName, uid, notificationId)); mActivityManagerInternal.notifyActiveMediaForegroundService(packageName, sbn.getUser().getIdentifier(), notificationId); } finally { Binder.restoreCallingIdentity(token); } } private void stopFgsIfNoSessionIsLinkedToNotification( @Nullable private StatusBarNotification getLinkedNotification( int uid, MediaSessionRecordImpl record) { synchronized (mLock) { for (StatusBarNotification sbn : mMediaNotifications.getOrDefault(uid, Set.of())) { if (record.isLinkedToNotification(sbn.getNotification())) { return sbn; } } } return null; } private void setFgsInactiveIfNoSessionIsLinkedToNotification( MediaSessionRecordImpl mediaSessionRecord) { Log.d(TAG, "stopFgsIfNoSessionIsLinkedToNotification: record=" + mediaSessionRecord); Log.d(TAG, "setFgsIfNoSessionIsLinkedToNotification: record=" + mediaSessionRecord); if (!Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange()) { return; } synchronized (mLock) { int uid = mediaSessionRecord.getUid(); ForegroundServiceDelegationOptions foregroundServiceDelegationOptions = mediaSessionRecord.getForegroundServiceDelegationOptions(); if (foregroundServiceDelegationOptions == null) { if (!mediaSessionRecord.hasLinkedNotificationSupport()) { return; } synchronized (mLock) { final int uid = mediaSessionRecord.getUid(); for (MediaSessionRecordImpl record : mUserEngagedSessionsForFgs.getOrDefault(uid, Set.of())) { for (Notification mediaNotification : for (StatusBarNotification sbn : mMediaNotifications.getOrDefault(uid, Set.of())) { if (record.isLinkedToNotification(mediaNotification)) { if (record.isLinkedToNotification(sbn.getNotification())) { // A user engaged session linked with a media notification is found. // We shouldn't call stop FGS in this case. return; } } } stopFgsDelegateLocked(mediaSessionRecord); final StatusBarNotification linkedNotification = getLinkedNotification(uid, mediaSessionRecord); if (linkedNotification != null) { setFgsInactiveLocked(mediaSessionRecord, linkedNotification); } } } @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. } private void setFgsInactiveLocked(MediaSessionRecordImpl mediaSessionRecord, StatusBarNotification sbn) { if (!mFgsAllowedMediaSessionRecords.remove(mediaSessionRecord)) { return; // This record is not FGS-started. No need to stop it. return; // This record is not FGS-active. No need to set inactive. } final long token = Binder.clearCallingIdentity(); try { final String packageName = sbn.getPackageName(); final int userId = sbn.getUser().getIdentifier(); final int uid = sbn.getUid(); final int notificationId = sbn.getId(); Log.i( TAG, TextUtils.formatSimple( "stopFgsDelegate: pkg=%s uid=%d", foregroundServiceDelegationOptions.mClientPackageName, foregroundServiceDelegationOptions.mClientUid)); mActivityManagerInternal.stopForegroundServiceDelegate( foregroundServiceDelegationOptions); "setFgsInactiveLocked: pkg=%s uid=%d notification=%d", packageName, uid, notificationId)); mActivityManagerInternal.notifyInactiveMediaForegroundService(packageName, userId, notificationId); } finally { Binder.restoreCallingIdentity(token); } Loading Loading @@ -3259,18 +3272,18 @@ public class MediaSessionService extends SystemService implements Monitor { @Override public void onNotificationPosted(StatusBarNotification sbn) { super.onNotificationPosted(sbn); Notification postedNotification = sbn.getNotification(); int uid = sbn.getUid(); final Notification postedNotification = sbn.getNotification(); if (!postedNotification.isMediaNotification()) { return; } synchronized (mLock) { mMediaNotifications.putIfAbsent(uid, new HashSet<>()); mMediaNotifications.get(uid).add(postedNotification); mMediaNotifications.get(uid).add(sbn); for (MediaSessionRecordImpl mediaSessionRecord : mUserEngagedSessionsForFgs.getOrDefault(uid, Set.of())) { if (mediaSessionRecord.isLinkedToNotification(postedNotification)) { startFgsDelegateLocked(mediaSessionRecord); setFgsActiveLocked(mediaSessionRecord, sbn); return; } } Loading @@ -3286,9 +3299,9 @@ public class MediaSessionService extends SystemService implements Monitor { return; } synchronized (mLock) { Set<Notification> uidMediaNotifications = mMediaNotifications.get(uid); Set<StatusBarNotification> uidMediaNotifications = mMediaNotifications.get(uid); if (uidMediaNotifications != null) { uidMediaNotifications.remove(removedNotification); uidMediaNotifications.remove(sbn); if (uidMediaNotifications.isEmpty()) { mMediaNotifications.remove(uid); } Loading @@ -3300,8 +3313,7 @@ public class MediaSessionService extends SystemService implements Monitor { if (notificationRecord == null) { return; } stopFgsIfNoSessionIsLinkedToNotification(notificationRecord); setFgsInactiveIfNoSessionIsLinkedToNotification(notificationRecord); } } Loading Loading
services/core/java/com/android/server/media/MediaSession2Record.java +2 −6 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.server.media; import android.app.ForegroundServiceDelegationOptions; import android.app.Notification; import android.media.MediaController2; import android.media.Session2CommandGroup; Loading Loading @@ -98,11 +97,8 @@ public class MediaSession2Record extends MediaSessionRecordImpl { } @Override public ForegroundServiceDelegationOptions getForegroundServiceDelegationOptions() { // For an app to be eligible for FGS delegation, it needs a media session liked to a media // notification. Currently, notifications cannot be linked to MediaSession2 so it is not // supported. return null; public boolean hasLinkedNotificationSupport() { return false; } @Override Loading
services/core/java/com/android/server/media/MediaSessionRecord.java +5 −30 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ForegroundServiceDelegationOptions; import android.app.Notification; import android.app.PendingIntent; import android.app.compat.CompatChanges; Loading Loading @@ -184,8 +183,6 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde private final UriGrantsManagerInternal mUgmInternal; private final Context mContext; private final ForegroundServiceDelegationOptions mForegroundServiceDelegationOptions; private final Object mLock = new Object(); // This field is partially guarded by mLock. Writes and non-atomic iterations (for example: // index-based-iterations) must be guarded by mLock. But it is safe to acquire an iterator Loading Loading @@ -306,32 +303,10 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde mPolicies = policies; mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class); mForegroundServiceDelegationOptions = createForegroundServiceDelegationOptions(); // May throw RemoteException if the session app is killed. mSessionCb.mCb.asBinder().linkToDeath(this, 0); } private ForegroundServiceDelegationOptions createForegroundServiceDelegationOptions() { return new ForegroundServiceDelegationOptions.Builder() .setClientPid(mOwnerPid) .setClientUid(getUid()) .setClientPackageName(getPackageName()) .setClientAppThread(null) .setSticky(false) .setClientInstanceName( "MediaSessionFgsDelegate_" + getUid() + "_" + mOwnerPid + "_" + getPackageName()) .setForegroundServiceTypes(0) .setDelegationService( ForegroundServiceDelegationOptions.DELEGATION_SERVICE_MEDIA_PLAYBACK) .build(); } /** * Get the session binder for the {@link MediaSession}. * Loading Loading @@ -389,6 +364,11 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde return mUserId; } @Override public boolean hasLinkedNotificationSupport() { return true; } /** * Check if this session has system priorty and should receive media buttons * before any other sessions. Loading Loading @@ -752,11 +732,6 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde return mPackageName + "/" + mTag + "/" + getUniqueId() + " (userId=" + mUserId + ")"; } @Override public ForegroundServiceDelegationOptions getForegroundServiceDelegationOptions() { return mForegroundServiceDelegationOptions; } private void postAdjustLocalVolume(final int stream, final int direction, final int flags, final String callingOpPackageName, final int callingPid, final int callingUid, final boolean asSystemService, final boolean useSuggested, Loading
services/core/java/com/android/server/media/MediaSessionRecordImpl.java +6 −7 Original line number Diff line number Diff line Loading @@ -16,10 +16,8 @@ package com.android.server.media; import android.app.ForegroundServiceDelegationOptions; import android.app.Notification; import android.media.AudioManager; import android.media.session.PlaybackState; import android.os.ResultReceiver; import android.view.KeyEvent; Loading Loading @@ -63,13 +61,14 @@ public abstract class MediaSessionRecordImpl { public abstract int getUserId(); /** * Get the {@link ForegroundServiceDelegationOptions} needed for notifying activity manager * service with changes in the {@link PlaybackState} for this session. * Returns whether this session supports linked notifications. * * @return the {@link ForegroundServiceDelegationOptions} needed for notifying the activity * manager service with changes in the {@link PlaybackState} for this session. * <p>A notification is linked to a media session if it contains * {@link android.app.Notification#EXTRA_MEDIA_SESSION}. * * @return {@code true} if this session supports linked notifications, {@code false} otherwise. */ public abstract ForegroundServiceDelegationOptions getForegroundServiceDelegationOptions(); public abstract boolean hasLinkedNotificationSupport(); /** * Check if this session has system priority and should receive media buttons before any other Loading
services/core/java/com/android/server/media/MediaSessionService.java +68 −56 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ForegroundServiceDelegationOptions; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationManager; Loading Loading @@ -185,9 +184,9 @@ public class MediaSessionService extends SystemService implements Monitor { /** * Maps uid with all user engaged session records associated to it. It's used for calling * ActivityManagerInternal startFGS and stopFGS. This collection doesn't contain * MediaSession2Record(s). When the media session is paused, There exists a timeout before * calling stopFGS unlike usage logging which considers it disengaged immediately. * ActivityManagerInternal internal api to set fgs active/inactive. This collection doesn't * contain MediaSession2Record(s). When the media session is paused, There exists a timeout * before setting FGS inactive unlike usage logging which considers it disengaged immediately. */ @GuardedBy("mLock") private final Map<Integer, Set<MediaSessionRecordImpl>> mUserEngagedSessionsForFgs = Loading @@ -195,7 +194,7 @@ public class MediaSessionService extends SystemService implements Monitor { /* Maps uid with all media notifications associated to it */ @GuardedBy("mLock") private final Map<Integer, Set<Notification>> mMediaNotifications = new HashMap<>(); private final Map<Integer, Set<StatusBarNotification>> mMediaNotifications = new HashMap<>(); /** * Holds all {@link MediaSessionRecordImpl} which we've reported as being {@link Loading Loading @@ -700,10 +699,10 @@ public class MediaSessionService extends SystemService implements Monitor { MediaSessionRecordImpl mediaSessionRecord, boolean isUserEngaged) { if (isUserEngaged) { addUserEngagedSession(mediaSessionRecord); startFgsIfSessionIsLinkedToNotification(mediaSessionRecord); setFgsActiveIfSessionIsLinkedToNotification(mediaSessionRecord); } else { removeUserEngagedSession(mediaSessionRecord); stopFgsIfNoSessionIsLinkedToNotification(mediaSessionRecord); setFgsInactiveIfNoSessionIsLinkedToNotification(mediaSessionRecord); } } Loading Loading @@ -737,17 +736,20 @@ public class MediaSessionService extends SystemService implements Monitor { } } private void startFgsIfSessionIsLinkedToNotification( private void setFgsActiveIfSessionIsLinkedToNotification( MediaSessionRecordImpl mediaSessionRecord) { Log.d(TAG, "startFgsIfSessionIsLinkedToNotification: record=" + mediaSessionRecord); Log.d(TAG, "setFgsIfSessionIsLinkedToNotification: record=" + mediaSessionRecord); if (!Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange()) { return; } if (!mediaSessionRecord.hasLinkedNotificationSupport()) { return; } synchronized (mLock) { int uid = mediaSessionRecord.getUid(); for (Notification mediaNotification : mMediaNotifications.getOrDefault(uid, Set.of())) { if (mediaSessionRecord.isLinkedToNotification(mediaNotification)) { startFgsDelegateLocked(mediaSessionRecord); for (StatusBarNotification sbn : mMediaNotifications.getOrDefault(uid, Set.of())) { if (mediaSessionRecord.isLinkedToNotification(sbn.getNotification())) { setFgsActiveLocked(mediaSessionRecord, sbn); return; } } Loading @@ -755,81 +757,92 @@ public class MediaSessionService extends SystemService implements Monitor { } @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. } private void setFgsActiveLocked(MediaSessionRecordImpl mediaSessionRecord, StatusBarNotification sbn) { if (!mFgsAllowedMediaSessionRecords.add(mediaSessionRecord)) { return; // This record is already FGS-started. return; // This record already is FGS-activated. } final long token = Binder.clearCallingIdentity(); try { final String packageName = sbn.getPackageName(); final int uid = sbn.getUid(); final int notificationId = sbn.getId(); Log.i( TAG, TextUtils.formatSimple( "startFgsDelegate: pkg=%s uid=%d", foregroundServiceDelegationOptions.mClientPackageName, foregroundServiceDelegationOptions.mClientUid)); mActivityManagerInternal.startForegroundServiceDelegate( foregroundServiceDelegationOptions, /* connection= */ null); "setFgsActiveLocked: pkg=%s uid=%d notification=%d", packageName, uid, notificationId)); mActivityManagerInternal.notifyActiveMediaForegroundService(packageName, sbn.getUser().getIdentifier(), notificationId); } finally { Binder.restoreCallingIdentity(token); } } private void stopFgsIfNoSessionIsLinkedToNotification( @Nullable private StatusBarNotification getLinkedNotification( int uid, MediaSessionRecordImpl record) { synchronized (mLock) { for (StatusBarNotification sbn : mMediaNotifications.getOrDefault(uid, Set.of())) { if (record.isLinkedToNotification(sbn.getNotification())) { return sbn; } } } return null; } private void setFgsInactiveIfNoSessionIsLinkedToNotification( MediaSessionRecordImpl mediaSessionRecord) { Log.d(TAG, "stopFgsIfNoSessionIsLinkedToNotification: record=" + mediaSessionRecord); Log.d(TAG, "setFgsIfNoSessionIsLinkedToNotification: record=" + mediaSessionRecord); if (!Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange()) { return; } synchronized (mLock) { int uid = mediaSessionRecord.getUid(); ForegroundServiceDelegationOptions foregroundServiceDelegationOptions = mediaSessionRecord.getForegroundServiceDelegationOptions(); if (foregroundServiceDelegationOptions == null) { if (!mediaSessionRecord.hasLinkedNotificationSupport()) { return; } synchronized (mLock) { final int uid = mediaSessionRecord.getUid(); for (MediaSessionRecordImpl record : mUserEngagedSessionsForFgs.getOrDefault(uid, Set.of())) { for (Notification mediaNotification : for (StatusBarNotification sbn : mMediaNotifications.getOrDefault(uid, Set.of())) { if (record.isLinkedToNotification(mediaNotification)) { if (record.isLinkedToNotification(sbn.getNotification())) { // A user engaged session linked with a media notification is found. // We shouldn't call stop FGS in this case. return; } } } stopFgsDelegateLocked(mediaSessionRecord); final StatusBarNotification linkedNotification = getLinkedNotification(uid, mediaSessionRecord); if (linkedNotification != null) { setFgsInactiveLocked(mediaSessionRecord, linkedNotification); } } } @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. } private void setFgsInactiveLocked(MediaSessionRecordImpl mediaSessionRecord, StatusBarNotification sbn) { if (!mFgsAllowedMediaSessionRecords.remove(mediaSessionRecord)) { return; // This record is not FGS-started. No need to stop it. return; // This record is not FGS-active. No need to set inactive. } final long token = Binder.clearCallingIdentity(); try { final String packageName = sbn.getPackageName(); final int userId = sbn.getUser().getIdentifier(); final int uid = sbn.getUid(); final int notificationId = sbn.getId(); Log.i( TAG, TextUtils.formatSimple( "stopFgsDelegate: pkg=%s uid=%d", foregroundServiceDelegationOptions.mClientPackageName, foregroundServiceDelegationOptions.mClientUid)); mActivityManagerInternal.stopForegroundServiceDelegate( foregroundServiceDelegationOptions); "setFgsInactiveLocked: pkg=%s uid=%d notification=%d", packageName, uid, notificationId)); mActivityManagerInternal.notifyInactiveMediaForegroundService(packageName, userId, notificationId); } finally { Binder.restoreCallingIdentity(token); } Loading Loading @@ -3259,18 +3272,18 @@ public class MediaSessionService extends SystemService implements Monitor { @Override public void onNotificationPosted(StatusBarNotification sbn) { super.onNotificationPosted(sbn); Notification postedNotification = sbn.getNotification(); int uid = sbn.getUid(); final Notification postedNotification = sbn.getNotification(); if (!postedNotification.isMediaNotification()) { return; } synchronized (mLock) { mMediaNotifications.putIfAbsent(uid, new HashSet<>()); mMediaNotifications.get(uid).add(postedNotification); mMediaNotifications.get(uid).add(sbn); for (MediaSessionRecordImpl mediaSessionRecord : mUserEngagedSessionsForFgs.getOrDefault(uid, Set.of())) { if (mediaSessionRecord.isLinkedToNotification(postedNotification)) { startFgsDelegateLocked(mediaSessionRecord); setFgsActiveLocked(mediaSessionRecord, sbn); return; } } Loading @@ -3286,9 +3299,9 @@ public class MediaSessionService extends SystemService implements Monitor { return; } synchronized (mLock) { Set<Notification> uidMediaNotifications = mMediaNotifications.get(uid); Set<StatusBarNotification> uidMediaNotifications = mMediaNotifications.get(uid); if (uidMediaNotifications != null) { uidMediaNotifications.remove(removedNotification); uidMediaNotifications.remove(sbn); if (uidMediaNotifications.isEmpty()) { mMediaNotifications.remove(uid); } Loading @@ -3300,8 +3313,7 @@ public class MediaSessionService extends SystemService implements Monitor { if (notificationRecord == null) { return; } stopFgsIfNoSessionIsLinkedToNotification(notificationRecord); setFgsInactiveIfNoSessionIsLinkedToNotification(notificationRecord); } } Loading