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

Commit 2a28269a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topics "sessionplayer2", "mediasession2_audio_api",...

Merge changes from topics "sessionplayer2", "mediasession2_audio_api", "session2_playbacklistener", "session2_timing"

* changes:
  MediaSession2: Initial commit of SessionPlayer2
  MediaSession2 API set for audio focus handling
  MediaSession2: Add/remove playback listeners
  MediaSession2: Fix timing issue
parents 98c8ad92 6a13e1b4
Loading
Loading
Loading
Loading
+6 −27
Original line number Diff line number Diff line
@@ -24,9 +24,7 @@ import android.os.Bundle;
 *
 * @hide
 */
// TODO(jaewan): Make this oneway interface.
//               Malicious app can fake session binder and holds commands from controller.
interface IMediaSession2 {
oneway interface IMediaSession2 {
    // TODO(jaewan): add onCommand() to send private command
    // TODO(jaewan): Due to the nature of oneway calls, APIs can be called in out of order
    //               Add id for individual calls to address this.
@@ -35,37 +33,18 @@ interface IMediaSession2 {
    //               not to expose other methods to the controller whose connection wasn't accepted.
    //               But this would be enough for now because it's the same as existing
    //               MediaBrowser and MediaBrowserService.
    oneway void connect(String callingPackage, IMediaSession2Callback callback);
    oneway void release(IMediaSession2Callback caller);
    void connect(String callingPackage, IMediaSession2Callback callback);
    void release(IMediaSession2Callback caller);

    //////////////////////////////////////////////////////////////////////////////////////////////
    // send command
    //////////////////////////////////////////////////////////////////////////////////////////////
    oneway void sendCommand(IMediaSession2Callback caller, in Bundle command, in Bundle args);
    oneway void sendTransportControlCommand(IMediaSession2Callback caller,
    void sendCommand(IMediaSession2Callback caller, in Bundle command, in Bundle args);
    void sendTransportControlCommand(IMediaSession2Callback caller,
            int commandCode, long arg);

    Bundle getPlaybackState();

    //////////////////////////////////////////////////////////////////////////////////////////////
    // Get library service specific
    //////////////////////////////////////////////////////////////////////////////////////////////
    oneway void getBrowserRoot(IMediaSession2Callback callback, in Bundle rootHints);

    //////////////////////////////////////////////////////////////////////////////////////////////
    // Callbacks -- remove them
    //////////////////////////////////////////////////////////////////////////////////////////////
    /**
     * @param callbackBinder binder to be used to notify changes.
     * @param callbackFlag one of {@link MediaController2#FLAG_CALLBACK_PLAYBACK} or
     *     {@link MediaController2#FLAG_CALLBACK_SESSION_ACTIVENESS}
     * @param requestCode If >= 0, this code will be called back by the callback after the callback
     *     is registered.
     */
    // TODO(jaewan): Due to the nature of the binder, calls can be called out of order.
    //               Need a way to ensure calling of unregisterCallback unregisters later
    //               registerCallback.
    oneway void registerCallback(IMediaSession2Callback callbackBinder,
            int callbackFlag, int requestCode);
    oneway void unregisterCallback(IMediaSession2Callback callbackBinder, int callbackFlag);
    void getBrowserRoot(IMediaSession2Callback callback, in Bundle rootHints);
}
+11 −6
Original line number Diff line number Diff line
@@ -133,9 +133,9 @@ public class MediaController2 implements AutoCloseable {
                @NonNull List<MediaItem2> list, @NonNull PlaylistParams param) { }

        /**
         * Called when the playback state is changed.
         * Called when the playback state is changed, or connection success.
         *
         * @param state
         * @param state latest playback state
         */
        public void onPlaybackStateChanged(@NonNull PlaybackState2 state) { }

@@ -254,12 +254,13 @@ public class MediaController2 implements AutoCloseable {
            @NonNull @CallbackExecutor Executor executor, @NonNull ControllerCallback callback) {
        super();

        mProvider = createProvider(context, token, executor, callback);
        // This also connects to the token.
        // Explicit connect() isn't added on purpose because retrying connect() is impossible with
        // session whose session binder is only valid while it's active.
        // prevent a controller from reusable after the
        // session is released and recreated.
        mProvider = createProvider(context, token, executor, callback);
        mProvider.initialize();
    }

    MediaController2Provider createProvider(@NonNull Context context,
@@ -545,11 +546,15 @@ public class MediaController2 implements AutoCloseable {
    }

    /**
     * Get the latest {@link PlaybackState2} from the session.
     * Get the lastly cached {@link PlaybackState2} from
     * {@link ControllerCallback#onPlaybackStateChanged(PlaybackState2)}.
     * <p>
     * It may return {@code null} before the first callback or session has sent {@code null}
     * playback state.
     *
     * @return a playback state
     * @return a playback state. Can be {@code null}
     */
    public PlaybackState2 getPlaybackState() {
    public @Nullable PlaybackState2 getPlaybackState() {
        return mProvider.getPlaybackState_impl();
    }

+8 −2
Original line number Diff line number Diff line
@@ -36,9 +36,9 @@ import java.lang.annotation.RetentionPolicy;
 * @hide
 */
public class MediaItem2 {
    // TODO(jaewan): Keep DataSourceDesc.
    private final int mFlags;
    private MediaMetadata2 mMetadata;
    private DataSourceDesc mDataSourceDesc;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
@@ -64,8 +64,10 @@ public class MediaItem2 {
     * @param metadata metadata with the media id.
     * @param flags The flags for this item.
     */
    public MediaItem2(@NonNull MediaMetadata2 metadata, @Flags int flags) {
    public MediaItem2(@Nullable MediaMetadata2 metadata,
            @Nullable DataSourceDesc data, @Flags int flags) {
        mFlags = flags;
        mDataSourceDesc = data;
        setMetadata(metadata);
    }

@@ -139,4 +141,8 @@ public class MediaItem2 {
    public @Nullable String getMediaId() {
        return mMetadata.getMediaId();
    }

    public @Nullable DataSourceDesc getDataSourceDesc() {
        return mDataSourceDesc;
    }
}
+17 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.media;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.media.MediaSession2.PlaylistParams;

import java.util.List;
@@ -48,9 +50,23 @@ public interface MediaPlayerInterface {
    void rewind();

    PlaybackState2 getPlaybackState();

    /**
     * Sets the {@link AudioAttributes} to be used during the playback of the media.
     *
     * @param attributes non-null <code>AudioAttributes</code>.
     */
    void setAudioAttributes(@NonNull AudioAttributes attributes);

    /**
     * Returns AudioAttributes that media player has.
     */
    @Nullable
    AudioAttributes getAudioAttributes();

    void setPlaylist(List<MediaItem2> item, PlaylistParams param);
    void setPlaylist(List<MediaItem2> list, PlaylistParams param);
    List<MediaItem2> getPlaylist();

    void setCurrentPlaylistItem(int index);
    void setPlaylistParams(PlaylistParams params);
    PlaylistParams getPlaylistParams();
+43 −13
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ public class MediaSession2 implements AutoCloseable {

    // Note: Do not define IntDef because subclass can add more command code on top of these.
    // TODO(jaewan): Shouldn't we pull out?
    // TODO(jaewan): Should we also protect getPlaybackState()?
    public static final int COMMAND_CODE_CUSTOM = 0;
    public static final int COMMAND_CODE_PLAYBACK_START = 1;
    public static final int COMMAND_CODE_PLAYBACK_PAUSE = 2;
@@ -199,7 +200,8 @@ public class MediaSession2 implements AutoCloseable {
        @Override
        public int hashCode() {
            final int prime = 31;
            return ((mCustomCommand != null) ? mCustomCommand.hashCode() : 0) * prime + mCommandCode;
            return ((mCustomCommand != null)
                    ? mCustomCommand.hashCode() : 0) * prime + mCommandCode;
        }
    }

@@ -999,14 +1001,13 @@ public class MediaSession2 implements AutoCloseable {
     *       framework had to add heuristics to figure out if an app is
     * @hide
     */

    MediaSession2(Context context, MediaPlayerInterface player, String id,
            VolumeProvider volumeProvider, int ratingType, PendingIntent sessionActivity,
            Executor callbackExecutor, SessionCallback callback) {
        super();
        mProvider = createProvider(context, player, id, volumeProvider, ratingType, sessionActivity,
                callbackExecutor, callback
        );
                callbackExecutor, callback);
        mProvider.initialize();
    }

    MediaSession2Provider createProvider(Context context, MediaPlayerInterface player, String id,
@@ -1078,15 +1079,6 @@ public class MediaSession2 implements AutoCloseable {
        return mProvider.getConnectedControllers_impl();
    }

    /**
     * Sets the {@link AudioAttributes} to be used during the playback of the video.
     *
     * @param attributes non-null <code>AudioAttributes</code>.
     */
    public void setAudioAttributes(@NonNull AudioAttributes attributes) {
        mProvider.setAudioAttributes_impl(attributes);
    }

    /**
     * Sets which type of audio focus will be requested during the playback, or configures playback
     * to not request audio focus. Valid values for focus requests are
@@ -1270,6 +1262,10 @@ public class MediaSession2 implements AutoCloseable {
        mProvider.setPlaylist_impl(playlist, param);
    }

    public List<MediaItem2> getPlaylist() {
        return mProvider.getPlaylist_impl();
    }

    /**
     * Sets the {@link PlaylistParams} for the current play list. Repeat/shuffle mode and metadata
     * for the list can be set by calling this method.
@@ -1288,4 +1284,38 @@ public class MediaSession2 implements AutoCloseable {
    public PlaylistParams getPlaylistParams() {
        return mProvider.getPlaylistParams_impl();
    }

    /*
     * Add a {@link PlaybackListener} to listen changes in the underlying
     * {@link MediaPlayerInterface}. Listener will be called immediately to tell the current value.
     * <p>
     * Added listeners will be also called when the underlying player is changed.
     *
     * @param executor the call listener
     * @param listener the listener that will be run
     * @throws IllegalArgumentException when either the listener or handler is {@code null}.
     */
    public void addPlaybackListener(@NonNull @CallbackExecutor Executor executor,
            @NonNull PlaybackListener listener) {
        mProvider.addPlaybackListener_impl(executor, listener);
    }

    /**
     * Remove previously added {@link PlaybackListener}.
     *
     * @param listener the listener to be removed
     * @throws IllegalArgumentException if the listener is {@code null}.
     */
    public void removePlaybackListener(@NonNull PlaybackListener listener) {
        mProvider.removePlaybackListener_impl(listener);
    }

    /**
     * Return the {@link PlaybackState2} from the player.
     *
     * @return playback state
     */
    public PlaybackState2 getPlaybackState() {
        return mProvider.getPlaybackState_impl();
    }
}
Loading