Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d00edd06 authored by Bishoy Gendy's avatar Bishoy Gendy
Browse files

Notify ActivityManager with changes in MediaSession playback state.

Bug: 295518668
Test: InProgress
Change-Id: I5df00218b4053291c357c7c758f9c34cac0eba69
parent db77f881
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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"
}
+22 −0
Original line number Diff line number Diff line
@@ -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
+9 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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);
        }
    }
}
+31 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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<>();
@@ -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}.
     *
@@ -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,
@@ -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);
            }
+11 −0
Original line number Diff line number Diff line
@@ -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;

@@ -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