Loading media/java/android/media/flags/media_better_together.aconfig +6 −0 Original line number Diff line number Diff line Loading @@ -77,3 +77,9 @@ flag { bug: "279555229" } flag { name: "enable_notifying_activity_manager_with_media_session_status_change" namespace: "media_solutions" description: "Notify ActivityManager with the changes in playback state of the media session." bug: "295518668" } media/java/android/media/session/PlaybackState.java +22 −0 Original line number Diff line number Diff line Loading @@ -524,6 +524,28 @@ public final class PlaybackState implements Parcelable { return false; } /** * Returns whether the service holding the media session should run in the foreground when the * media session has this playback state or not. * * @hide */ public boolean shouldAllowServiceToRunInForeground() { switch (mState) { case PlaybackState.STATE_PLAYING: case PlaybackState.STATE_FAST_FORWARDING: case PlaybackState.STATE_REWINDING: case PlaybackState.STATE_BUFFERING: case PlaybackState.STATE_CONNECTING: case PlaybackState.STATE_SKIPPING_TO_PREVIOUS: case PlaybackState.STATE_SKIPPING_TO_NEXT: case PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM: return true; default: return false; } } public static final @android.annotation.NonNull Parcelable.Creator<PlaybackState> CREATOR = new Parcelable.Creator<PlaybackState>() { @Override Loading services/core/java/com/android/server/media/MediaSession2Record.java +9 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.media; import android.app.ForegroundServiceDelegationOptions; import android.media.MediaController2; import android.media.Session2CommandGroup; import android.media.Session2Token; Loading Loading @@ -88,6 +89,12 @@ public class MediaSession2Record implements MediaSessionRecordImpl { return UserHandle.getUserHandleForUid(mSessionToken.getUid()).getIdentifier(); } @Override public ForegroundServiceDelegationOptions getForegroundServiceDelegationOptions() { // TODO: Implement when MediaSession2 knows about its owner pid. return null; } @Override public boolean isSystemPriority() { // System priority session is currently only allowed for telephony, so it's OK to stick to Loading Loading @@ -217,7 +224,8 @@ public class MediaSession2Record implements MediaSessionRecordImpl { synchronized (mLock) { service = mService; } service.onSessionPlaybackStateChanged(MediaSession2Record.this, playbackActive); service.onSessionPlaybackStateChanged( MediaSession2Record.this, playbackActive, /* playbackState= */ null); } } } services/core/java/com/android/server/media/MediaSessionRecord.java +31 −1 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ForegroundServiceDelegationOptions; import android.app.PendingIntent; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; Loading Loading @@ -182,6 +183,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR private final Context mContext; private final boolean mVolumeAdjustmentForRemoteGroupSessions; private final ForegroundServiceDelegationOptions mForegroundServiceDelegationOptions; private final Object mLock = new Object(); private final CopyOnWriteArrayList<ISessionControllerCallbackHolder> mControllerCallbackHolders = new CopyOnWriteArrayList<>(); Loading Loading @@ -244,10 +247,32 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR mVolumeAdjustmentForRemoteGroupSessions = mContext.getResources().getBoolean( com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions); 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 @@ -681,6 +706,11 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR return mPackageName + "/" + mTag + " (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 Loading @@ -1273,7 +1303,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR final long token = Binder.clearCallingIdentity(); try { mService.onSessionPlaybackStateChanged( MediaSessionRecord.this, shouldUpdatePriority); MediaSessionRecord.this, shouldUpdatePriority, mPlaybackState); } finally { Binder.restoreCallingIdentity(token); } Loading services/core/java/com/android/server/media/MediaSessionRecordImpl.java +11 −0 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package com.android.server.media; import android.app.ForegroundServiceDelegationOptions; import android.media.AudioManager; import android.media.session.PlaybackState; import android.os.ResultReceiver; import android.view.KeyEvent; Loading Loading @@ -50,6 +52,15 @@ public interface MediaSessionRecordImpl extends AutoCloseable { */ int getUserId(); /** * Get the {@link ForegroundServiceDelegationOptions} needed for notifying activity manager * service with changes in the {@link PlaybackState} for this session. * * @return the {@link ForegroundServiceDelegationOptions} needed for notifying the activity * manager service with changes in the {@link PlaybackState} for this session. */ ForegroundServiceDelegationOptions getForegroundServiceDelegationOptions(); /** * Check if this session has system priority and should receive media buttons before any other * sessions. Loading Loading
media/java/android/media/flags/media_better_together.aconfig +6 −0 Original line number Diff line number Diff line Loading @@ -77,3 +77,9 @@ flag { bug: "279555229" } flag { name: "enable_notifying_activity_manager_with_media_session_status_change" namespace: "media_solutions" description: "Notify ActivityManager with the changes in playback state of the media session." bug: "295518668" }
media/java/android/media/session/PlaybackState.java +22 −0 Original line number Diff line number Diff line Loading @@ -524,6 +524,28 @@ public final class PlaybackState implements Parcelable { return false; } /** * Returns whether the service holding the media session should run in the foreground when the * media session has this playback state or not. * * @hide */ public boolean shouldAllowServiceToRunInForeground() { switch (mState) { case PlaybackState.STATE_PLAYING: case PlaybackState.STATE_FAST_FORWARDING: case PlaybackState.STATE_REWINDING: case PlaybackState.STATE_BUFFERING: case PlaybackState.STATE_CONNECTING: case PlaybackState.STATE_SKIPPING_TO_PREVIOUS: case PlaybackState.STATE_SKIPPING_TO_NEXT: case PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM: return true; default: return false; } } public static final @android.annotation.NonNull Parcelable.Creator<PlaybackState> CREATOR = new Parcelable.Creator<PlaybackState>() { @Override Loading
services/core/java/com/android/server/media/MediaSession2Record.java +9 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.media; import android.app.ForegroundServiceDelegationOptions; import android.media.MediaController2; import android.media.Session2CommandGroup; import android.media.Session2Token; Loading Loading @@ -88,6 +89,12 @@ public class MediaSession2Record implements MediaSessionRecordImpl { return UserHandle.getUserHandleForUid(mSessionToken.getUid()).getIdentifier(); } @Override public ForegroundServiceDelegationOptions getForegroundServiceDelegationOptions() { // TODO: Implement when MediaSession2 knows about its owner pid. return null; } @Override public boolean isSystemPriority() { // System priority session is currently only allowed for telephony, so it's OK to stick to Loading Loading @@ -217,7 +224,8 @@ public class MediaSession2Record implements MediaSessionRecordImpl { synchronized (mLock) { service = mService; } service.onSessionPlaybackStateChanged(MediaSession2Record.this, playbackActive); service.onSessionPlaybackStateChanged( MediaSession2Record.this, playbackActive, /* playbackState= */ null); } } }
services/core/java/com/android/server/media/MediaSessionRecord.java +31 −1 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ForegroundServiceDelegationOptions; import android.app.PendingIntent; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; Loading Loading @@ -182,6 +183,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR private final Context mContext; private final boolean mVolumeAdjustmentForRemoteGroupSessions; private final ForegroundServiceDelegationOptions mForegroundServiceDelegationOptions; private final Object mLock = new Object(); private final CopyOnWriteArrayList<ISessionControllerCallbackHolder> mControllerCallbackHolders = new CopyOnWriteArrayList<>(); Loading Loading @@ -244,10 +247,32 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR mVolumeAdjustmentForRemoteGroupSessions = mContext.getResources().getBoolean( com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions); 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 @@ -681,6 +706,11 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR return mPackageName + "/" + mTag + " (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 Loading @@ -1273,7 +1303,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR final long token = Binder.clearCallingIdentity(); try { mService.onSessionPlaybackStateChanged( MediaSessionRecord.this, shouldUpdatePriority); MediaSessionRecord.this, shouldUpdatePriority, mPlaybackState); } finally { Binder.restoreCallingIdentity(token); } Loading
services/core/java/com/android/server/media/MediaSessionRecordImpl.java +11 −0 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package com.android.server.media; import android.app.ForegroundServiceDelegationOptions; import android.media.AudioManager; import android.media.session.PlaybackState; import android.os.ResultReceiver; import android.view.KeyEvent; Loading Loading @@ -50,6 +52,15 @@ public interface MediaSessionRecordImpl extends AutoCloseable { */ int getUserId(); /** * Get the {@link ForegroundServiceDelegationOptions} needed for notifying activity manager * service with changes in the {@link PlaybackState} for this session. * * @return the {@link ForegroundServiceDelegationOptions} needed for notifying the activity * manager service with changes in the {@link PlaybackState} for this session. */ ForegroundServiceDelegationOptions getForegroundServiceDelegationOptions(); /** * Check if this session has system priority and should receive media buttons before any other * sessions. Loading