summaryrefslogtreecommitdiff
path: root/android/media/MediaLibraryService2.java
diff options
context:
space:
mode:
Diffstat (limited to 'android/media/MediaLibraryService2.java')
-rw-r--r--android/media/MediaLibraryService2.java438
1 files changed, 255 insertions, 183 deletions
diff --git a/android/media/MediaLibraryService2.java b/android/media/MediaLibraryService2.java
index d7e43ec9..f29d386c 100644
--- a/android/media/MediaLibraryService2.java
+++ b/android/media/MediaLibraryService2.java
@@ -20,27 +20,27 @@ import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.PendingIntent;
-import android.content.Context;
-import android.media.MediaSession2.BuilderBase;
+import android.media.MediaLibraryService2.MediaLibrarySession.Builder;
+import android.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback;
import android.media.MediaSession2.ControllerInfo;
import android.media.update.ApiLoader;
+import android.media.update.MediaLibraryService2Provider.LibraryRootProvider;
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;
import java.util.concurrent.Executor;
/**
+ * @hide
* Base class for media library services.
* <p>
* Media library services enable applications to browse media content provided by an application
* and ask the application to start playing it. They may also be used to control content that
* is already playing by way of a {@link MediaSession2}.
* <p>
- * To extend this class, adding followings directly to your {@code AndroidManifest.xml}.
+ * When extending this class, also add the following to your {@code AndroidManifest.xml}.
* <pre>
* &lt;service android:name="component_name_of_your_implementation" &gt;
* &lt;intent-filter&gt;
@@ -48,13 +48,13 @@ import java.util.concurrent.Executor;
* &lt;/intent-filter&gt;
* &lt;/service&gt;</pre>
* <p>
- * A {@link MediaLibraryService2} is extension of {@link MediaSessionService2}. IDs shouldn't
+ * The {@link MediaLibraryService2} class derives from {@link MediaSessionService2}. IDs shouldn't
* be shared between the {@link MediaSessionService2} and {@link MediaSession2}. By
* default, an empty string will be used for ID of the service. If you want to specify an ID,
* declare metadata in the manifest as follows.
- * @hide
+ *
+ * @see MediaSessionService2
*/
-// TODO(jaewan): Unhide
public abstract class MediaLibraryService2 extends MediaSessionService2 {
/**
* This is the interface name that a service implementing a session service should say that it
@@ -63,178 +63,252 @@ public abstract class MediaLibraryService2 extends MediaSessionService2 {
public static final String SERVICE_INTERFACE = "android.media.MediaLibraryService2";
/**
- * Session for the media library service.
+ * Session for the {@link MediaLibraryService2}. Build this object with
+ * {@link Builder} and return in {@link #onCreateSession(String)}.
*/
- public class MediaLibrarySession extends MediaSession2 {
+ public static final class MediaLibrarySession extends MediaSession2 {
private final MediaLibrarySessionProvider mProvider;
- MediaLibrarySession(Context context, MediaPlayerBase player, String id,
- Executor callbackExecutor, SessionCallback callback, VolumeProvider volumeProvider,
- int ratingType, PendingIntent sessionActivity) {
- super(context, player, id, callbackExecutor, callback, volumeProvider, ratingType,
- sessionActivity);
- mProvider = (MediaLibrarySessionProvider) getProvider();
- }
-
- @Override
- MediaSession2Provider createProvider(Context context, MediaPlayerBase player, String id,
- Executor callbackExecutor, SessionCallback callback, VolumeProvider volumeProvider,
- int ratingType, PendingIntent sessionActivity) {
- return ApiLoader.getProvider(context)
- .createMediaLibraryService2MediaLibrarySession(this, context, player, id,
- callbackExecutor, (MediaLibrarySessionCallback) callback,
- volumeProvider, ratingType, sessionActivity);
- }
-
/**
- * Notify subscribed controller about change in a parent's children.
- *
- * @param controller controller to notify
- * @param parentId
- * @param options
+ * Callback for the {@link MediaLibrarySession}.
*/
- public void notifyChildrenChanged(@NonNull ControllerInfo controller,
- @NonNull String parentId, @NonNull Bundle options) {
- mProvider.notifyChildrenChanged_impl(controller, parentId, options);
- }
+ public static class MediaLibrarySessionCallback extends MediaSession2.SessionCallback {
+ public MediaLibrarySessionCallback() {
+ super();
+ }
- /**
- * 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);
- }
- }
+ /**
+ * Called to get the root information for browsing by a particular client.
+ * <p>
+ * The implementation should verify that the client package has permission
+ * to access browse media information before returning the root id; it
+ * should return null if the client is not allowed to access this
+ * information.
+ *
+ * @param session the session for this event
+ * @param controllerInfo information of the controller requesting access to browse media.
+ * @param rootHints An optional bundle of service-specific arguments to send
+ * to the media library service when connecting and retrieving the
+ * root id for browsing, or null if none. The contents of this
+ * bundle may affect the information returned when browsing.
+ * @return The {@link LibraryRoot} for accessing this app's content or null.
+ * @see LibraryRoot#EXTRA_RECENT
+ * @see LibraryRoot#EXTRA_OFFLINE
+ * @see LibraryRoot#EXTRA_SUGGESTED
+ */
+ public @Nullable LibraryRoot onGetLibraryRoot(@NonNull MediaLibrarySession session,
+ @NonNull ControllerInfo controllerInfo, @Nullable Bundle rootHints) {
+ return null;
+ }
- public static class MediaLibrarySessionCallback extends MediaSession2.SessionCallback {
- /**
- * Called to get the root information for browsing by a particular client.
- * <p>
- * The implementation should verify that the client package has permission
- * to access browse media information before returning the root id; it
- * should return null if the client is not allowed to access this
- * information.
- *
- * @param controllerInfo information of the controller requesting access to browse media.
- * @param rootHints An optional bundle of service-specific arguments to send
- * to the media browser service when connecting and retrieving the
- * root id for browsing, or null if none. The contents of this
- * bundle may affect the information returned when browsing.
- * @return The {@link BrowserRoot} for accessing this app's content or null.
- * @see BrowserRoot#EXTRA_RECENT
- * @see BrowserRoot#EXTRA_OFFLINE
- * @see BrowserRoot#EXTRA_SUGGESTED
- */
- public @Nullable BrowserRoot onGetRoot(@NonNull ControllerInfo controllerInfo,
- @Nullable Bundle rootHints) {
- return null;
+ /**
+ * Called to get an item. Return result here for the browser.
+ * <p>
+ * Return {@code null} for no result or error.
+ *
+ * @param session the session for this event
+ * @param mediaId item id to get media item.
+ * @return a media item. {@code null} for no result or error.
+ */
+ public @Nullable MediaItem2 onGetItem(@NonNull MediaLibrarySession session,
+ @NonNull ControllerInfo controllerInfo, @NonNull String mediaId) {
+ return null;
+ }
+
+ /**
+ * Called to get children of given parent id. Return the children here for the browser.
+ * <p>
+ * Return an empty list for no children, and return {@code null} for the error.
+ *
+ * @param session the session for this event
+ * @param parentId parent id to get children
+ * @param page number of page
+ * @param pageSize size of the page
+ * @param extras extra bundle
+ * @return list of children. Can be {@code null}.
+ */
+ public @Nullable List<MediaItem2> onGetChildren(@NonNull MediaLibrarySession session,
+ @NonNull ControllerInfo controller, @NonNull String parentId, int page,
+ int pageSize, @Nullable Bundle extras) {
+ return null;
+ }
+
+ /**
+ * Called when a controller subscribes to the parent.
+ * <p>
+ * It's your responsibility to keep subscriptions by your own and call
+ * {@link MediaLibrarySession#notifyChildrenChanged(ControllerInfo, String, int, Bundle)}
+ * when the parent is changed.
+ *
+ * @param session the session for this event
+ * @param controller controller
+ * @param parentId parent id
+ * @param extras extra bundle
+ */
+ public void onSubscribe(@NonNull MediaLibrarySession session,
+ @NonNull ControllerInfo controller, @NonNull String parentId,
+ @Nullable Bundle extras) {
+ }
+
+ /**
+ * Called when a controller unsubscribes to the parent.
+ *
+ * @param session the session for this event
+ * @param controller controller
+ * @param parentId parent id
+ */
+ public void onUnsubscribe(@NonNull MediaLibrarySession session,
+ @NonNull ControllerInfo controller, @NonNull String parentId) {
+ }
+
+ /**
+ * Called when a controller requests search.
+ *
+ * @param session the session for this event
+ * @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.
+ */
+ public void onSearch(@NonNull MediaLibrarySession session,
+ @NonNull ControllerInfo controllerInfo, @NonNull String query,
+ @Nullable Bundle extras) {
+ }
+
+ /**
+ * Called to get the search result. Return search result here for the browser which has
+ * requested search previously.
+ * <p>
+ * Return an empty list for no search result, and return {@code null} for the error.
+ *
+ * @param session the session for this event
+ * @param controllerInfo Information of the controller requesting the search result.
+ * @param query The search query which was previously sent through
+ * {@link #onSearch(MediaLibrarySession, ControllerInfo, String, Bundle)}.
+ * @param page page number. Starts from {@code 1}.
+ * @param pageSize page size. Should be greater or equal to {@code 1}.
+ * @param extras The bundle of service-specific arguments sent from the media browser.
+ * @return search result. {@code null} for error.
+ */
+ public @Nullable List<MediaItem2> onGetSearchResult(
+ @NonNull MediaLibrarySession session, @NonNull ControllerInfo controllerInfo,
+ @NonNull String query, int page, int pageSize, @Nullable Bundle extras) {
+ 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.
+ * Builder for {@link MediaLibrarySession}.
*/
- public @Nullable List<MediaItem2> onSearch(@NonNull ControllerInfo controllerInfo,
- @NonNull String query, @Nullable Bundle extras) {
- return null;
+ // Override all methods just to show them with the type instead of generics in Javadoc.
+ // This workarounds javadoc issue described in the MediaSession2.BuilderBase.
+ public static final class Builder extends BuilderBase<MediaLibrarySession, Builder,
+ MediaLibrarySessionCallback> {
+ // Builder requires MediaLibraryService2 instead of Context just to ensure that the
+ // builder can be only instantiated within the MediaLibraryService2.
+ // Ideally it's better to make it inner class of service to enforce, it violates API
+ // guideline that Builders should be the inner class of the building target.
+ public Builder(@NonNull MediaLibraryService2 service,
+ @NonNull @CallbackExecutor Executor callbackExecutor,
+ @NonNull MediaLibrarySessionCallback callback) {
+ super((instance) -> ApiLoader.getProvider().createMediaLibraryService2Builder(
+ service, (Builder) instance, callbackExecutor, callback));
+ }
+
+ @Override
+ public Builder setPlayer(@NonNull MediaPlayerBase player) {
+ return super.setPlayer(player);
+ }
+
+ @Override
+ public Builder setPlaylistAgent(@NonNull MediaPlaylistAgent playlistAgent) {
+ return super.setPlaylistAgent(playlistAgent);
+ }
+
+ @Override
+ public Builder setVolumeProvider(@Nullable VolumeProvider2 volumeProvider) {
+ return super.setVolumeProvider(volumeProvider);
+ }
+
+ @Override
+ public Builder setSessionActivity(@Nullable PendingIntent pi) {
+ return super.setSessionActivity(pi);
+ }
+
+ @Override
+ public Builder setId(@NonNull String id) {
+ return super.setId(id);
+ }
+
+ @Override
+ public Builder setSessionCallback(@NonNull @CallbackExecutor Executor executor,
+ @NonNull MediaLibrarySessionCallback callback) {
+ return super.setSessionCallback(executor, callback);
+ }
+
+ @Override
+ public MediaLibrarySession build() {
+ return super.build();
+ }
}
/**
- * 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.
+ * @hide
*/
- public @Nullable MediaItem2 onLoadItem(@NonNull ControllerInfo controllerInfo,
- @NonNull String itemId) {
- return null;
+ public MediaLibrarySession(MediaLibrarySessionProvider provider) {
+ super(provider);
+ mProvider = provider;
}
/**
- * Called to get the search result. Return search result here for the browser.
+ * Notify the controller of the change in a parent's children.
* <p>
- * Return an empty list for no search result, and return {@code null} for the error.
+ * If the controller hasn't subscribed to the parent, the API will do nothing.
+ * <p>
+ * Controllers will use {@link MediaBrowser2#getChildren(String, int, int, Bundle)} to get
+ * the list of children.
*
- * @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}.
+ * @param controller controller to notify
+ * @param parentId parent id with changes in its children
+ * @param itemCount number of children.
+ * @param extras extra information from session to controller
*/
- public @Nullable List<MediaItem2> onLoadChildren(@NonNull ControllerInfo controller,
- @NonNull String parentId, int page, int pageSize, @Nullable Bundle options) {
- return null;
+ public void notifyChildrenChanged(@NonNull ControllerInfo controller,
+ @NonNull String parentId, int itemCount, @Nullable Bundle extras) {
+ mProvider.notifyChildrenChanged_impl(controller, parentId, itemCount, extras);
}
/**
- * Called when a controller subscribes to the parent.
+ * Notify all controllers that subscribed to the parent about change in the parent's
+ * children, regardless of the extra bundle supplied by
+ * {@link MediaBrowser2#subscribe(String, Bundle)}.
*
- * @param controller controller
* @param parentId parent id
- * @param options optional bundle
+ * @param itemCount number of children
+ * @param extras extra information from session to controller
*/
- public void onSubscribed(@NonNull ControllerInfo controller,
- String parentId, @Nullable Bundle options) {
+ // This is for the backward compatibility.
+ public void notifyChildrenChanged(@NonNull String parentId, int itemCount,
+ @Nullable Bundle extras) {
+ mProvider.notifyChildrenChanged_impl(parentId, itemCount, extras);
}
/**
- * Called when a controller unsubscribes to the parent.
+ * Notify controller about change in the search result.
*
- * @param controller controller
- * @param parentId parent id
- * @param options optional bundle
+ * @param controller controller to notify
+ * @param query previously sent search query from the controller.
+ * @param itemCount the number of items that have been found in the search.
+ * @param extras extra bundle
*/
- public void onUnsubscribed(@NonNull ControllerInfo controller,
- String parentId, @Nullable Bundle options) {
- }
- }
-
- /**
- * Builder for {@link MediaLibrarySession}.
- */
- // TODO(jaewan): Move this to updatable.
- public class MediaLibrarySessionBuilder
- extends BuilderBase<MediaLibrarySessionBuilder, MediaLibrarySessionCallback> {
- public MediaLibrarySessionBuilder(
- @NonNull Context context, @NonNull MediaPlayerBase player,
- @NonNull @CallbackExecutor Executor callbackExecutor,
- @NonNull MediaLibrarySessionCallback callback) {
- super(context, player);
- setSessionCallback(callbackExecutor, callback);
- }
-
- @Override
- public MediaLibrarySessionBuilder setSessionCallback(
- @NonNull @CallbackExecutor Executor callbackExecutor,
- @NonNull MediaLibrarySessionCallback callback) {
- if (callback == null) {
- throw new IllegalArgumentException("MediaLibrarySessionCallback cannot be null");
- }
- return super.setSessionCallback(callbackExecutor, callback);
- }
-
- @Override
- public MediaLibrarySession build() throws IllegalStateException {
- return new MediaLibrarySession(mContext, mPlayer, mId, mCallbackExecutor, mCallback,
- mVolumeProvider, mRatingType, mSessionActivity);
+ public void notifySearchResultChanged(@NonNull ControllerInfo controller,
+ @NonNull String query, int itemCount, @NonNull Bundle extras) {
+ mProvider.notifySearchResultChanged_impl(controller, query, itemCount, extras);
}
}
@Override
MediaSessionService2Provider createProvider() {
- return ApiLoader.getProvider(this).createMediaLibraryService2(this);
+ return ApiLoader.getProvider().createMediaLibraryService2(this);
}
/**
@@ -249,8 +323,8 @@ public abstract class MediaLibraryService2 extends MediaSessionService2 {
* This method will be called on the main thread.
*
* @param sessionId session id written in the AndroidManifest.xml.
- * @return a new browser session
- * @see MediaLibrarySessionBuilder
+ * @return a new library session
+ * @see Builder
* @see #getSession()
* @throws RuntimeException if returned session is invalid
*/
@@ -258,93 +332,91 @@ public abstract class MediaLibraryService2 extends MediaSessionService2 {
public @NonNull abstract MediaLibrarySession onCreateSession(String sessionId);
/**
- * Contains information that the browser service needs to send to the client
- * when first connected.
+ * Contains information that the library service needs to send to the client when
+ * {@link MediaBrowser2#getLibraryRoot(Bundle)} is called.
*/
- public static final class BrowserRoot {
+ public static final class LibraryRoot {
/**
- * The lookup key for a boolean that indicates whether the browser service should return a
- * browser root for recently played media items.
+ * The lookup key for a boolean that indicates whether the library service should return a
+ * librar root for recently played media items.
*
- * <p>When creating a media browser for a given media browser service, this key can be
+ * <p>When creating a media browser for a given media library 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
+ * If the media library 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.
+ * {@link MediaLibrarySessionCallback#onGetLibraryRoot(MediaLibrarySession, 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";
+ public static final String EXTRA_RECENT = "android.media.extra.RECENT";
/**
- * The lookup key for a boolean that indicates whether the browser service should return a
- * browser root for offline media items.
+ * The lookup key for a boolean that indicates whether the library service should return a
+ * library root for offline media items.
*
- * <p>When creating a media browser for a given media browser service, this key can be
+ * <p>When creating a media browser for a given media library 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
+ * If the media library 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.
+ * {@link MediaLibrarySessionCallback#onGetLibraryRoot(MediaLibrarySession, 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";
+ public static final String EXTRA_OFFLINE = "android.media.extra.OFFLINE";
/**
- * The lookup key for a boolean that indicates whether the browser service should return a
- * browser root for suggested media items.
+ * The lookup key for a boolean that indicates whether the library service should return a
+ * library 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
+ * <p>When creating a media browser for a given media library service, this key can be
+ * supplied as a root hint for retrieving the media items suggested by the media library
+ * service. The list of media items is considered ordered by relevance, first being the top
+ * suggestion.
+ * If the media library 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.
+ * {@link MediaLibrarySessionCallback#onGetLibraryRoot(MediaLibrarySession, 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";
+ public static final String EXTRA_SUGGESTED = "android.media.extra.SUGGESTED";
- final private String mRootId;
- final private Bundle mExtras;
+ private final LibraryRootProvider mProvider;
/**
- * Constructs a browser root.
+ * Constructs a library root.
* @param rootId The root id for browsing.
- * @param extras Any extras about the browser service.
+ * @param extras Any extras about the library 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;
+ public LibraryRoot(@NonNull String rootId, @Nullable Bundle extras) {
+ mProvider = ApiLoader.getProvider().createMediaLibraryService2LibraryRoot(
+ this, rootId, extras);
}
/**
* Gets the root id for browsing.
*/
public String getRootId() {
- return mRootId;
+ return mProvider.getRootId_impl();
}
/**
- * Gets any extras about the browser service.
+ * Gets any extras about the library service.
*/
public Bundle getExtras() {
- return mExtras;
+ return mProvider.getExtras_impl();
}
}
}