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

Commit 7b406c2d authored by Bishoy Gendy's avatar Bishoy Gendy Committed by Android (Google) Code Review
Browse files

Merge "Notify ActivityManager with changes in MediaSession playback state." into main

parents c0da30c6 d00edd06
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