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

Commit 4099b6e6 authored by Jaewan Kim's avatar Jaewan Kim
Browse files

MediaSession2: Public APIs for MediaBrowser2 and MediaLibraryService2

Test: Run MediaComponents test once
Change-Id: Icea9f7db7f13ed8354c7ce36b069f45ad7ddbfa8
parent 17b19b73
Loading
Loading
Loading
Loading
+110 −3
Original line number Diff line number Diff line
@@ -16,12 +16,14 @@

package android.media;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.media.update.ApiLoader;
import android.media.update.MediaBrowser2Provider;
import android.os.Bundle;

import java.util.List;
import java.util.concurrent.Executor;

/**
@@ -35,7 +37,7 @@ public class MediaBrowser2 extends MediaController2 {
    /**
     * Callback to listen events from {@link MediaLibraryService2}.
     */
    public abstract static class BrowserCallback extends MediaController2.ControllerCallback {
    public static class BrowserCallback extends MediaController2.ControllerCallback {
        /**
         * Called with the result of {@link #getBrowserRoot(Bundle)}.
         * <p>
@@ -46,8 +48,55 @@ public class MediaBrowser2 extends MediaController2 {
         * @param rootMediaId media id of the browser root. Can be {@code null}
         * @param rootExtra extra of the browser root. Can be {@code null}
         */
        public abstract void onGetRootResult(Bundle rootHints, @Nullable String rootMediaId,
                @Nullable Bundle rootExtra);
        public void onGetRootResult(Bundle rootHints, @Nullable String rootMediaId,
                @Nullable Bundle rootExtra) { }

        /**
         * Called when the item has been returned by the library service for the previous
         * {@link MediaBrowser2#getItem} call.
         * <p>
         * Result can be null if there had been error.
         *
         * @param mediaId media id
         * @param result result. Can be {@code null}
         */
        public void onItemLoaded(@NonNull String mediaId, @Nullable MediaItem2 result) { }

        /**
         * Called when the list of items has been returned by the library service for the previous
         * {@link MediaBrowser2#getChildren(String, int, int, Bundle)}.
         *
         * @param parentId parent id
         * @param page page number that you've specified
         * @param pageSize page size that you've specified
         * @param options optional bundle that you've specified
         * @param result result. Can be {@code null}
         */
        public void onChildrenLoaded(@NonNull String parentId, int page, int pageSize,
                @Nullable Bundle options, @Nullable List<MediaItem2> result) { }

        /**
         * Called when there's change in the parent's children.
         *
         * @param parentId parent id that you've specified with subscribe
         * @param options optional bundle that you've specified with subscribe
         */
        public void onChildrenChanged(@NonNull String parentId, @Nullable Bundle options) { }

        /**
         * Called when the search result has been returned by the library service for the previous
         * {@link MediaBrowser2#search(String, int, int, Bundle)}.
         * <p>
         * Result can be null if there had been error.
         *
         * @param query query string that you've specified
         * @param page page number that you've specified
         * @param pageSize page size that you've specified
         * @param options optional bundle that you've specified
         * @param result result. Can be {@code null}
         */
        public void onSearchResult(@NonNull String query, int page, int pageSize,
                @Nullable Bundle options, @Nullable List<MediaItem2> result) { }
    }

    public MediaBrowser2(Context context, SessionToken token, BrowserCallback callback,
@@ -66,4 +115,62 @@ public class MediaBrowser2 extends MediaController2 {
    public void getBrowserRoot(Bundle rootHints) {
        mProvider.getBrowserRoot_impl(rootHints);
    }

    /**
     * Subscribe to a parent id for the change in its children. When there's a change,
     * {@link BrowserCallback#onChildrenChanged(String, Bundle)} will be called with the bundle
     * that you've specified. You should call {@link #getChildren(String, int, int, Bundle)} to get
     * the actual contents for the parent.
     *
     * @param parentId parent id
     * @param options optional bundle
     */
    public void subscribe(String parentId, @Nullable Bundle options) {
        mProvider.subscribe_impl(parentId, options);
    }

    /**
     * Unsubscribe for changes to the children of the parent, which was previously subscribed with
     * {@link #subscribe(String, Bundle)}.
     *
     * @param parentId parent id
     * @param options optional bundle
     */
    public void unsubscribe(String parentId, @Nullable Bundle options) {
        mProvider.unsubscribe_impl(parentId, options);
    }

    /**
     * Get the media item with the given media id. Result would be sent back asynchronously with the
     * {@link BrowserCallback#onItemLoaded(String, MediaItem2)}.
     *
     * @param mediaId media id
     */
    public void getItem(String mediaId) {
        mProvider.getItem_impl(mediaId);
    }

    /**
     * Get list of children under the parent. Result would be sent back asynchronously with the
     * {@link BrowserCallback#onChildrenLoaded(String, int, int, Bundle, List)}.
     *
     * @param parentId
     * @param page
     * @param pageSize
     * @param options
     */
    public void getChildren(String parentId, int page, int pageSize, @Nullable Bundle options) {
        mProvider.getChildren_impl(parentId, page, pageSize, options);
    }

    /**
     *
     * @param query search query deliminated by string
     * @param page page number to get search result. Starts from {@code 1}
     * @param pageSize page size. Should be greater or equal to {@code 1}
     * @param extras extra bundle
     */
    public void search(String query, int page, int pageSize, Bundle extras) {
        mProvider.search_impl(query, page, pageSize, extras);
    }
}
+201 −4
Original line number Diff line number Diff line
@@ -23,10 +23,14 @@ import android.content.Context;
import android.media.MediaSession2.BuilderBase;
import android.media.MediaSession2.ControllerInfo;
import android.media.update.ApiLoader;
import android.media.update.MediaLibraryService2Provider.MediaLibrarySessionProvider;
import android.media.update.MediaSession2Provider;
import android.media.update.MediaSessionService2Provider;
import android.os.Bundle;
import android.service.media.MediaBrowserService.BrowserRoot;

import java.util.List;

/**
 * Base class for media library services.
 * <p>
@@ -60,16 +64,50 @@ public abstract class MediaLibraryService2 extends MediaSessionService2 {
     * Session for the media library service.
     */
    public class MediaLibrarySession extends MediaSession2 {
        private final MediaLibrarySessionProvider mProvider;

        MediaLibrarySession(Context context, MediaPlayerBase player, String id,
                SessionCallback callback, VolumeProvider volumeProvider,
                int ratingType, PendingIntent sessionActivity) {
            super(context, player, id, callback, volumeProvider, ratingType, sessionActivity);
            mProvider = (MediaLibrarySessionProvider) getProvider();
        }

        @Override
        MediaSession2Provider createProvider(Context context, MediaPlayerBase player, String id,
                SessionCallback callback, VolumeProvider volumeProvider, int ratingType,
                PendingIntent sessionActivity) {
            return ApiLoader.getProvider(context)
                    .createMediaLibraryService2MediaLibrarySession(this, context, player, id,
                            (MediaLibrarySessionCallback) callback, volumeProvider, ratingType,
                            sessionActivity);
        }

        /**
         * Notify subscribed controller about change in a parent's children.
         *
         * @param controller controller to notify
         * @param parentId
         * @param options
         */
        public void notifyChildrenChanged(@NonNull ControllerInfo controller,
                @NonNull String parentId, @NonNull Bundle options) {
            mProvider.notifyChildrenChanged_impl(controller, parentId, options);
        }

        /**
         * Notify subscribed controller about change in a parent's children.
         *
         * @param parentId parent id
         * @param options optional bundle
         */
        // This is for the backward compatibility.
        public void notifyChildrenChanged(@NonNull String parentId, @Nullable Bundle options) {
            mProvider.notifyChildrenChanged_impl(parentId, options);
        }
        // TODO(jaewan): Place public methods here.
    }

    public static abstract class MediaLibrarySessionCallback extends MediaSession2.SessionCallback {
    public static class MediaLibrarySessionCallback extends MediaSession2.SessionCallback {
        /**
         * Called to get the root information for browsing by a particular client.
         * <p>
@@ -88,8 +126,76 @@ public abstract class MediaLibraryService2 extends MediaSessionService2 {
         * @see BrowserRoot#EXTRA_OFFLINE
         * @see BrowserRoot#EXTRA_SUGGESTED
         */
        public abstract @Nullable BrowserRoot onGetRoot(
                @NonNull ControllerInfo controllerInfo, @Nullable Bundle rootHints);
        public @Nullable BrowserRoot onGetRoot(@NonNull ControllerInfo controllerInfo,
                @Nullable Bundle rootHints) {
            return null;
        }

        /**
         * Called to get the search result. Return search result here for the browser.
         * <p>
         * Return an empty list for no search result, and return {@code null} for the error.
         *
         * @param query The search query sent from the media browser. It contains keywords separated
         *            by space.
         * @param extras The bundle of service-specific arguments sent from the media browser.
         * @return search result. {@code null} for error.
         */
        public @Nullable List<MediaItem2> onSearch(@NonNull ControllerInfo controllerInfo,
                @NonNull String query, @Nullable Bundle extras) {
            return null;
        }

        /**
         * Called to get the search result . Return result here for the browser.
         * <p>
         * Return an empty list for no search result, and return {@code null} for the error.
         *
         * @param itemId item id to get media item.
         * @return media item2. {@code null} for error.
         */
        public @Nullable MediaItem2 onLoadItem(@NonNull ControllerInfo controllerInfo,
                @NonNull String itemId) {
            return null;
        }

        /**
         * Called to get the search result. Return search result here for the browser.
         * <p>
         * Return an empty list for no search result, and return {@code null} for the error.
         *
         * @param parentId parent id to get children
         * @param page number of page
         * @param pageSize size of the page
         * @param options
         * @return list of children. Can be {@code null}.
         */
        public @Nullable List<MediaItem2> onLoadChildren(@NonNull ControllerInfo controller,
                @NonNull String parentId, int page, int pageSize, @Nullable Bundle options) {
            return null;
        }

        /**
         * Called when a controller subscribes to the parent.
         *
         * @param controller controller
         * @param parentId parent id
         * @param options optional bundle
         */
        public void onSubscribed(@NonNull ControllerInfo controller,
                String parentId, @Nullable Bundle options) {
        }

        /**
         * Called when a controller unsubscribes to the parent.
         *
         * @param controller controller
         * @param parentId parent id
         * @param options optional bundle
         */
        public void onUnsubscribed(@NonNull ControllerInfo controller,
                String parentId, @Nullable Bundle options) {
        }
    }

    /**
@@ -145,4 +251,95 @@ public abstract class MediaLibraryService2 extends MediaSessionService2 {
     */
    @Override
    public @NonNull abstract MediaLibrarySession onCreateSession(String sessionId);

    /**
     * Contains information that the browser service needs to send to the client
     * when first connected.
     */
    public static final class BrowserRoot {
        /**
         * The lookup key for a boolean that indicates whether the browser service should return a
         * browser root for recently played media items.
         *
         * <p>When creating a media browser for a given media browser service, this key can be
         * supplied as a root hint for retrieving media items that are recently played.
         * If the media browser service can provide such media items, the implementation must return
         * the key in the root hint when
         * {@link MediaLibrarySessionCallback#onGetRoot(ControllerInfo, Bundle)} is called back.
         *
         * <p>The root hint may contain multiple keys.
         *
         * @see #EXTRA_OFFLINE
         * @see #EXTRA_SUGGESTED
         */
        public static final String EXTRA_RECENT = "android.service.media.extra.RECENT";

        /**
         * The lookup key for a boolean that indicates whether the browser service should return a
         * browser root for offline media items.
         *
         * <p>When creating a media browser for a given media browser service, this key can be
         * supplied as a root hint for retrieving media items that are can be played without an
         * internet connection.
         * If the media browser service can provide such media items, the implementation must return
         * the key in the root hint when
         * {@link MediaLibrarySessionCallback#onGetRoot(ControllerInfo, Bundle)} is called back.
         *
         * <p>The root hint may contain multiple keys.
         *
         * @see #EXTRA_RECENT
         * @see #EXTRA_SUGGESTED
         */
        public static final String EXTRA_OFFLINE = "android.service.media.extra.OFFLINE";

        /**
         * The lookup key for a boolean that indicates whether the browser service should return a
         * browser root for suggested media items.
         *
         * <p>When creating a media browser for a given media browser service, this key can be
         * supplied as a root hint for retrieving the media items suggested by the media browser
         * service. The list of media items passed in {@link android.media.browse.MediaBrowser.SubscriptionCallback#onChildrenLoaded(String, List)}
         * is considered ordered by relevance, first being the top suggestion.
         * If the media browser service can provide such media items, the implementation must return
         * the key in the root hint when
         * {@link MediaLibrarySessionCallback#onGetRoot(ControllerInfo, Bundle)} is called back.
         *
         * <p>The root hint may contain multiple keys.
         *
         * @see #EXTRA_RECENT
         * @see #EXTRA_OFFLINE
         */
        public static final String EXTRA_SUGGESTED = "android.service.media.extra.SUGGESTED";

        final private String mRootId;
        final private Bundle mExtras;

        /**
         * Constructs a browser root.
         * @param rootId The root id for browsing.
         * @param extras Any extras about the browser service.
         */
        public BrowserRoot(@NonNull String rootId, @Nullable Bundle extras) {
            if (rootId == null) {
                throw new IllegalArgumentException("The root id in BrowserRoot cannot be null. " +
                        "Use null for BrowserRoot instead.");
            }
            mRootId = rootId;
            mExtras = extras;
        }

        /**
         * Gets the root id for browsing.
         */
        public String getRootId() {
            return mRootId;
        }

        /**
         * Gets any extras about the browser service.
         */
        public Bundle getExtras() {
            return mExtras;
        }
    }
}
+8 −1
Original line number Diff line number Diff line
@@ -889,7 +889,14 @@ public class MediaSession2 implements AutoCloseable {
            SessionCallback callback, VolumeProvider volumeProvider, int ratingType,
            PendingIntent sessionActivity) {
        super();
        mProvider = ApiLoader.getProvider(context)
        mProvider = createProvider(context, player, id, callback,
                volumeProvider, ratingType, sessionActivity);
    }

    MediaSession2Provider createProvider(Context context, MediaPlayerBase player, String id,
            SessionCallback callback, VolumeProvider volumeProvider, int ratingType,
            PendingIntent sessionActivity) {
        return ApiLoader.getProvider(context)
                .createMediaSession2(this, context, player, id, callback,
                        volumeProvider, ratingType, sessionActivity);
    }
+7 −0
Original line number Diff line number Diff line
@@ -23,4 +23,11 @@ import android.os.Bundle;
 */
public interface MediaBrowser2Provider extends MediaController2Provider {
    void getBrowserRoot_impl(Bundle rootHints);

    void subscribe_impl(String parentId, Bundle options);
    void unsubscribe_impl(String parentId, Bundle options);

    void getItem_impl(String mediaId);
    void getChildren_impl(String parentId, int page, int pageSize, Bundle options);
    void search_impl(String query, int page, int pageSize, Bundle extras);
}
+7 −1
Original line number Diff line number Diff line
@@ -16,9 +16,15 @@

package android.media.update;

/**
import android.media.MediaSession2.ControllerInfo;
import android.os.Bundle; /**
 * @hide
 */
public interface MediaLibraryService2Provider extends MediaSessionService2Provider {
    // Nothing new for now

    interface MediaLibrarySessionProvider extends MediaSession2Provider {
        void notifyChildrenChanged_impl(ControllerInfo controller, String parentId, Bundle options);
        void notifyChildrenChanged_impl(String parentId, Bundle options);
    }
}
Loading