diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 69f07d5c5f7bab7c1c1d257cd02114d354399cdc..fc75bf47ed96067b2aed027469c73195edc9c5d4 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -81,6 +81,8 @@ import android.util.Log; import android.util.Slog; import android.view.KeyEvent; +import com.android.internal.annotations.GuardedBy; +import com.android.media.flags.Flags; import com.android.server.LocalServices; import com.android.server.uri.UriGrantsManagerInternal; @@ -229,6 +231,14 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde private int mPolicies; + private final Runnable mUserEngagementTimeoutExpirationRunnable = + () -> { + synchronized (mLock) { + updateUserEngagedStateIfNeededLocked(/* isTimeoutExpired= */ true); + } + }; + + @GuardedBy("mLock") private @UserEngagementState int mUserEngagementState = USER_DISENGAGED; @IntDef({USER_PERMANENTLY_ENGAGED, USER_TEMPORARY_ENGAGED, USER_DISENGAGED}) @@ -238,26 +248,26 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde /** * Indicates that the session is active and in one of the user engaged states. * - * @see #updateUserEngagedStateIfNeededLocked(boolean) () + * @see #updateUserEngagedStateIfNeededLocked(boolean) */ private static final int USER_PERMANENTLY_ENGAGED = 0; /** * Indicates that the session is active and in {@link PlaybackState#STATE_PAUSED} state. * - * @see #updateUserEngagedStateIfNeededLocked(boolean) () + * @see #updateUserEngagedStateIfNeededLocked(boolean) */ private static final int USER_TEMPORARY_ENGAGED = 1; /** * Indicates that the session is either not active or in one of the user disengaged states * - * @see #updateUserEngagedStateIfNeededLocked(boolean) () + * @see #updateUserEngagedStateIfNeededLocked(boolean) */ private static final int USER_DISENGAGED = 2; /** - * Indicates the duration of the temporary engaged states. + * Indicates the duration of the temporary engaged states, in milliseconds. * * <p>Some {@link MediaSession} states like {@link PlaybackState#STATE_PAUSED} are temporarily * engaged, meaning the corresponding session is only considered in an engaged state for the @@ -270,7 +280,7 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde * user-engaged state is not considered user-engaged when transitioning from a non-user engaged * state {@link PlaybackState#STATE_STOPPED}. */ - private static final int TEMP_USER_ENGAGED_TIMEOUT = 600000; + private static final int TEMP_USER_ENGAGED_TIMEOUT_MS = 600000; public MediaSessionRecord( int ownerPid, @@ -609,8 +619,7 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde @Override public void expireTempEngaged() { - mHandler.removeCallbacks(mHandleTempEngagedSessionTimeout); - updateUserEngagedStateIfNeededLocked(/* isTimeoutExpired= */ true); + mHandler.post(mUserEngagementTimeoutExpirationRunnable); } /** @@ -1086,11 +1095,6 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde } }; - private final Runnable mHandleTempEngagedSessionTimeout = - () -> { - updateUserEngagedStateIfNeededLocked(/* isTimeoutExpired= */ true); - }; - @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS) private static boolean componentNameExists( @NonNull ComponentName componentName, @NonNull Context context, int userId) { @@ -1107,10 +1111,14 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde return !resolveInfos.isEmpty(); } + @GuardedBy("mLock") private void updateUserEngagedStateIfNeededLocked(boolean isTimeoutExpired) { + if (!Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange()) { + return; + } int oldUserEngagedState = mUserEngagementState; int newUserEngagedState; - if (!isActive() || mPlaybackState == null) { + if (!isActive() || mPlaybackState == null || mDestroyed) { newUserEngagedState = USER_DISENGAGED; } else if (isActive() && mPlaybackState.isActive()) { newUserEngagedState = USER_PERMANENTLY_ENGAGED; @@ -1126,18 +1134,22 @@ public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinde return; } + mUserEngagementState = newUserEngagedState; if (newUserEngagedState == USER_TEMPORARY_ENGAGED) { - mHandler.postDelayed(mHandleTempEngagedSessionTimeout, TEMP_USER_ENGAGED_TIMEOUT); - } else if (oldUserEngagedState == USER_TEMPORARY_ENGAGED) { - mHandler.removeCallbacks(mHandleTempEngagedSessionTimeout); + mHandler.postDelayed( + mUserEngagementTimeoutExpirationRunnable, TEMP_USER_ENGAGED_TIMEOUT_MS); + } else { + mHandler.removeCallbacks(mUserEngagementTimeoutExpirationRunnable); } boolean wasUserEngaged = oldUserEngagedState != USER_DISENGAGED; boolean isNowUserEngaged = newUserEngagedState != USER_DISENGAGED; - mUserEngagementState = newUserEngagedState; if (wasUserEngaged != isNowUserEngaged) { - mService.onSessionUserEngagementStateChange( - /* mediaSessionRecord= */ this, /* isUserEngaged= */ isNowUserEngaged); + mHandler.post( + () -> + mService.onSessionUserEngagementStateChange( + /* mediaSessionRecord= */ this, + /* isUserEngaged= */ isNowUserEngaged)); } } diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 399866728770f6c105dcaa656893ad67e600970d..f02a3fff12f5e2bb46598a1952db51a75ec996ba 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -715,6 +715,12 @@ public class MediaSessionService extends SystemService implements Monitor { ForegroundServiceDelegationOptions foregroundServiceDelegationOptions) { final long token = Binder.clearCallingIdentity(); try { + Log.i( + TAG, + TextUtils.formatSimple( + "startFgsDelegate: pkg=%s uid=%d", + foregroundServiceDelegationOptions.mClientPackageName, + foregroundServiceDelegationOptions.mClientUid)); mActivityManagerInternal.startForegroundServiceDelegate( foregroundServiceDelegationOptions, /* connection= */ null); } finally { @@ -756,6 +762,12 @@ public class MediaSessionService extends SystemService implements Monitor { ForegroundServiceDelegationOptions foregroundServiceDelegationOptions) { final long token = Binder.clearCallingIdentity(); try { + Log.i( + TAG, + TextUtils.formatSimple( + "stopFgsDelegate: pkg=%s uid=%d", + foregroundServiceDelegationOptions.mClientPackageName, + foregroundServiceDelegationOptions.mClientUid)); mActivityManagerInternal.stopForegroundServiceDelegate( foregroundServiceDelegationOptions); } finally { @@ -2679,6 +2691,9 @@ public class MediaSessionService extends SystemService implements Monitor { @Override public void expireTempEngagedSessions() { + if (!Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange()) { + return; + } synchronized (mLock) { for (Set<MediaSessionRecordImpl> uidSessions : mUserEngagedSessionsForFgs.values()) {