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

Commit 258fca37 authored by Jin Seok Park's avatar Jin Seok Park
Browse files

Add setMediaButtonBroadcastReceiver API

This API will replace the existing
setMediaButtonReceiver(PendingIntent) API to address the issue that
PendingIntent obejcts should not be persisted over reboots.

See go/replace-setmediabuttonreceiver for more details.

Bug: 161334442
Test: atest CtsMediaTestCases:android.media.cts.MediaSessionTest
Change-Id: I4ece6b8595b5f572426b96fbf06edb34c93eeb50
parent 09454b27
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -24225,7 +24225,8 @@ package android.media.session {
    method public void setCallback(@Nullable android.media.session.MediaSession.Callback, @Nullable android.os.Handler);
    method public void setExtras(@Nullable android.os.Bundle);
    method public void setFlags(int);
    method public void setMediaButtonReceiver(@Nullable android.app.PendingIntent);
    method public void setMediaButtonBroadcastReceiver(@Nullable android.content.ComponentName);
    method @Deprecated public void setMediaButtonReceiver(@Nullable android.app.PendingIntent);
    method public void setMetadata(@Nullable android.media.MediaMetadata);
    method public void setPlaybackState(@Nullable android.media.session.PlaybackState);
    method public void setPlaybackToLocal(android.media.AudioAttributes);
+2 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package android.media.session;

import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes;
import android.media.MediaMetadata;
@@ -35,6 +36,7 @@ interface ISession {
    void setFlags(int flags);
    void setActive(boolean active);
    void setMediaButtonReceiver(in PendingIntent mbr);
    void setMediaButtonBroadcastReceiver(in ComponentName broadcastReceiver);
    void setLaunchPendingIntent(in PendingIntent pi);
    void destroySession();

+32 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.annotation.SystemApi;
import android.app.Activity;
import android.app.PendingIntent;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.media.AudioAttributes;
@@ -131,6 +132,7 @@ public final class MediaSession {
    public @interface SessionFlags { }

    private final Object mLock = new Object();
    private Context mContext;
    private final int mMaxBitmapSize;

    private final Token mSessionToken;
@@ -194,6 +196,7 @@ public final class MediaSession {
                    + "parcelables");
        }

        mContext = context;
        mMaxBitmapSize = context.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.config_mediaMetadataBitmapMaxSize);
        mCbStub = new CallbackStub(this);
@@ -277,7 +280,10 @@ public final class MediaSession {
     *
     * @param mbr The {@link PendingIntent} to send the media button event to.
     * @see PendingIntent#getActivity
     *
     * @deprecated Use {@link #setMediaButtonBroadcastReceiver(ComponentName)} instead.
     */
    @Deprecated
    public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
        try {
            mBinder.setMediaButtonReceiver(mbr);
@@ -286,6 +292,32 @@ public final class MediaSession {
        }
    }

    /**
     * Set the component name of the manifest-declared {@link android.content.BroadcastReceiver}
     * class that should receive media buttons. This allows restarting playback after the session
     * has been stopped. If your app is started in this way an {@link Intent#ACTION_MEDIA_BUTTON}
     * intent will be sent to the broadcast receiver.
     * <p>
     * Note: The given {@link android.content.BroadcastReceiver} should belong to the same package
     * as the context that was given when creating {@link MediaSession}.
     *
     * @param broadcastReceiver the component name of the BroadcastReceiver class
     */
    public void setMediaButtonBroadcastReceiver(@Nullable ComponentName broadcastReceiver) {
        try {
            if (broadcastReceiver != null) {
                if (!TextUtils.equals(broadcastReceiver.getPackageName(),
                        mContext.getPackageName())) {
                    throw new IllegalArgumentException("broadcastReceiver should belong to the same"
                            + " package as the context given when creating MediaSession.");
                }
            }
            mBinder.setMediaButtonBroadcastReceiver(broadcastReceiver);
        } catch (RemoteException e) {
            Log.wtf(TAG, "Failure in setMediaButtonBroadcastReceiver.", e);
        }
    }

    /**
     * Set any flags for the session.
     *
+5 −0
Original line number Diff line number Diff line
@@ -141,6 +141,11 @@ final class MediaButtonReceiverHolder {
                packageName != null ? packageName : "");
    }

    public static MediaButtonReceiverHolder create(int userId, ComponentName broadcastReceiver) {
        return new MediaButtonReceiverHolder(userId, null, broadcastReceiver,
                COMPONENT_TYPE_BROADCAST);
    }

    private MediaButtonReceiverHolder(int userId, PendingIntent pendingIntent,
            ComponentName componentName, @ComponentType int componentType) {
        mUserId = userId;
+16 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.media;

import android.annotation.Nullable;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ParceledListSlice;
@@ -857,6 +858,21 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
            }
        }

        @Override
        public void setMediaButtonBroadcastReceiver(ComponentName receiver) throws RemoteException {
            final long token = Binder.clearCallingIdentity();
            try {
                if ((mPolicies & SessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER)
                        != 0) {
                    return;
                }
                mMediaButtonReceiverHolder = MediaButtonReceiverHolder.create(mUserId, receiver);
                mService.onMediaButtonReceiverChanged(MediaSessionRecord.this);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

        @Override
        public void setLaunchPendingIntent(PendingIntent pi) throws RemoteException {
            mLaunchIntent = pi;