Merge "Add getMediaItem API to MediaBrowser"
This commit is contained in:
@@ -16217,6 +16217,7 @@ package android.media.browse {
|
||||
method public void connect();
|
||||
method public void disconnect();
|
||||
method public android.os.Bundle getExtras();
|
||||
method public void getMediaItem(java.lang.String, android.media.browse.MediaBrowser.MediaItemCallback);
|
||||
method public java.lang.String getRoot();
|
||||
method public android.content.ComponentName getServiceComponent();
|
||||
method public android.media.session.MediaSession.Token getSessionToken();
|
||||
@@ -16246,6 +16247,12 @@ package android.media.browse {
|
||||
field public static final int FLAG_PLAYABLE = 2; // 0x2
|
||||
}
|
||||
|
||||
public static abstract class MediaBrowser.MediaItemCallback {
|
||||
ctor public MediaBrowser.MediaItemCallback();
|
||||
method public void onError();
|
||||
method public void onMediaItemLoaded(android.media.browse.MediaBrowser.MediaItem);
|
||||
}
|
||||
|
||||
public static abstract class MediaBrowser.SubscriptionCallback {
|
||||
ctor public MediaBrowser.SubscriptionCallback();
|
||||
method public void onChildrenLoaded(java.lang.String, java.util.List<android.media.browse.MediaBrowser.MediaItem>);
|
||||
@@ -27360,6 +27367,7 @@ package android.service.media {
|
||||
public abstract class MediaBrowserService extends android.app.Service {
|
||||
ctor public MediaBrowserService();
|
||||
method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
|
||||
method public void getMediaItem(java.lang.String, android.service.media.MediaBrowserService.Result<android.media.browse.MediaBrowser.MediaItem>) throws java.lang.UnsupportedOperationException;
|
||||
method public android.media.session.MediaSession.Token getSessionToken();
|
||||
method public void notifyChildrenChanged(java.lang.String);
|
||||
method public android.os.IBinder onBind(android.content.Intent);
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ResultReceiver;
|
||||
import android.service.media.MediaBrowserService;
|
||||
import android.service.media.IMediaBrowserService;
|
||||
import android.service.media.IMediaBrowserServiceCallbacks;
|
||||
@@ -347,8 +348,8 @@ public final class MediaBrowser {
|
||||
*/
|
||||
public void unsubscribe(@NonNull String parentId) {
|
||||
// Check arguments.
|
||||
if (parentId == null) {
|
||||
throw new IllegalArgumentException("parentId is null");
|
||||
if (TextUtils.isEmpty(parentId)) {
|
||||
throw new IllegalArgumentException("parentId is empty.");
|
||||
}
|
||||
|
||||
// Remove from our list.
|
||||
@@ -366,6 +367,60 @@ public final class MediaBrowser {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a specific {@link MediaItem} from the connected service. Not
|
||||
* all services may support this, so falling back to subscribing to the
|
||||
* parent's id should be used when unavailable.
|
||||
*
|
||||
* @param mediaId The id of the item to retrieve.
|
||||
* @param cb The callback to receive the result on.
|
||||
*/
|
||||
public void getMediaItem(@NonNull String mediaId, @NonNull final MediaItemCallback cb) {
|
||||
if (TextUtils.isEmpty(mediaId)) {
|
||||
throw new IllegalArgumentException("mediaId is empty.");
|
||||
}
|
||||
if (cb == null) {
|
||||
throw new IllegalArgumentException("cb is null.");
|
||||
}
|
||||
if (mState != CONNECT_STATE_CONNECTED) {
|
||||
Log.i(TAG, "Not connected, unable to retrieve the MediaItem.");
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
cb.onError();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
ResultReceiver receiver = new ResultReceiver(mHandler) {
|
||||
@Override
|
||||
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
||||
if (resultCode != 0 || resultData == null
|
||||
|| !resultData.containsKey(MediaBrowserService.KEY_MEDIA_ITEM)) {
|
||||
cb.onError();
|
||||
return;
|
||||
}
|
||||
Parcelable item = resultData.getParcelable(MediaBrowserService.KEY_MEDIA_ITEM);
|
||||
if (!(item instanceof MediaItem)) {
|
||||
cb.onError();
|
||||
}
|
||||
cb.onMediaItemLoaded((MediaItem) resultData.getParcelable(
|
||||
MediaBrowserService.KEY_MEDIA_ITEM));
|
||||
}
|
||||
};
|
||||
try {
|
||||
mServiceBinder.getMediaItem(mediaId, receiver);
|
||||
} catch (RemoteException e) {
|
||||
Log.i(TAG, "Remote error getting media item.");
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
cb.onError();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For debugging.
|
||||
*/
|
||||
@@ -689,6 +744,27 @@ public final class MediaBrowser {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for receiving the result of {@link #getMediaItem}.
|
||||
*/
|
||||
public static abstract class MediaItemCallback {
|
||||
|
||||
/**
|
||||
* Called when the item has been returned by the browser service.
|
||||
*
|
||||
* @param item The item that was returned or null if it doesn't exist.
|
||||
*/
|
||||
public void onMediaItemLoaded(MediaItem item) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the id doesn't exist or there was an error retrieving the
|
||||
* item.
|
||||
*/
|
||||
public void onError() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ServiceConnection to the other app.
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.content.res.Configuration;
|
||||
import android.service.media.IMediaBrowserServiceCallbacks;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.ResultReceiver;
|
||||
|
||||
/**
|
||||
* Media API allows clients to browse through hierarchy of a user’s media collection,
|
||||
@@ -18,4 +19,5 @@ oneway interface IMediaBrowserService {
|
||||
|
||||
void addSubscription(String uri, IMediaBrowserServiceCallbacks callbacks);
|
||||
void removeSubscription(String uri, IMediaBrowserServiceCallbacks callbacks);
|
||||
void getMediaItem(String uri, in ResultReceiver cb);
|
||||
}
|
||||
@@ -32,8 +32,10 @@ import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ResultReceiver;
|
||||
import android.service.media.IMediaBrowserService;
|
||||
import android.service.media.IMediaBrowserServiceCallbacks;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -74,6 +76,13 @@ public abstract class MediaBrowserService extends Service {
|
||||
@SdkConstant(SdkConstantType.SERVICE_ACTION)
|
||||
public static final String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService";
|
||||
|
||||
/**
|
||||
* A key for passing the MediaItem to the ResultReceiver in getMediaItem.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String KEY_MEDIA_ITEM = "media_item";
|
||||
|
||||
private final ArrayMap<IBinder, ConnectionRecord> mConnections = new ArrayMap();
|
||||
private final Handler mHandler = new Handler();
|
||||
private ServiceBinder mBinder;
|
||||
@@ -261,6 +270,33 @@ public abstract class MediaBrowserService extends Service {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getMediaItem(final String mediaId, final ResultReceiver receiver) {
|
||||
if (TextUtils.isEmpty(mediaId) || receiver == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Result<MediaBrowser.MediaItem> result
|
||||
= new Result<MediaBrowser.MediaItem>(mediaId) {
|
||||
@Override
|
||||
void onResultSent(MediaBrowser.MediaItem item) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(KEY_MEDIA_ITEM, item);
|
||||
receiver.send(0, bundle);
|
||||
}
|
||||
};
|
||||
try {
|
||||
MediaBrowserService.this.getMediaItem(mediaId, result);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
receiver.send(-1, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -284,20 +320,21 @@ public abstract class MediaBrowserService extends Service {
|
||||
/**
|
||||
* 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.
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* @param clientPackageName The package name of the application
|
||||
* which is requesting access to browse media.
|
||||
* @param clientUid The uid of the application which is requesting
|
||||
* access to browse media.
|
||||
* @param clientPackageName The package name of the application which is
|
||||
* requesting access to browse media.
|
||||
* @param clientUid The uid of the application which is requesting access to
|
||||
* browse media.
|
||||
* @param rootHints An optional bundle of service-specific arguments to send
|
||||
* to the media browse 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.
|
||||
* to the media browse 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.
|
||||
*/
|
||||
public abstract @Nullable BrowserRoot onGetRoot(@NonNull String clientPackageName,
|
||||
int clientUid, @Nullable Bundle rootHints);
|
||||
@@ -305,24 +342,51 @@ public abstract class MediaBrowserService extends Service {
|
||||
/**
|
||||
* Called to get information about the children of a media item.
|
||||
* <p>
|
||||
* Implementations must call result.{@link Result#sendResult result.sendResult} with the list
|
||||
* of children. If loading the children will be an expensive operation that should be performed
|
||||
* on another thread, result.{@link Result#detach result.detach} may be called before returning
|
||||
* from this function, and then {@link Result#sendResult result.sendResult} called when
|
||||
* the loading is complete.
|
||||
* Implementations must call {@link Result#sendResult result.sendResult}
|
||||
* with the list of children. If loading the children will be an expensive
|
||||
* operation that should be performed on another thread,
|
||||
* {@link Result#detach result.detach} may be called before returning from
|
||||
* this function, and then {@link Result#sendResult result.sendResult}
|
||||
* called when the loading is complete.
|
||||
*
|
||||
* @param parentId The id of the parent media item whose
|
||||
* children are to be queried.
|
||||
* @return The list of children, or null if the id is invalid.
|
||||
* @param parentId The id of the parent media item whose children are to be
|
||||
* queried.
|
||||
* @param result The Result to send the list of children to, or null if the
|
||||
* id is invalid.
|
||||
*/
|
||||
public abstract void onLoadChildren(@NonNull String parentId,
|
||||
@NonNull Result<List<MediaBrowser.MediaItem>> result);
|
||||
|
||||
/**
|
||||
* Called to get a specific media item. The mediaId should be the same id
|
||||
* that would be returned for this item when it is in a list of child items.
|
||||
* <p>
|
||||
* Implementations must call {@link Result#sendResult result.sendResult}. If
|
||||
* loading the item will be an expensive operation {@link Result#detach
|
||||
* result.detach} may be called before returning from this function, and
|
||||
* then {@link Result#sendResult result.sendResult} called when the item has
|
||||
* been loaded.
|
||||
* <p>
|
||||
* The default implementation throws an exception.
|
||||
*
|
||||
* @param mediaId The id for the specific
|
||||
* {@link android.media.browse.MediaBrowser.MediaItem}.
|
||||
* @param result The Result to send the item to, or null if the id is
|
||||
* invalid.
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public void getMediaItem(String mediaId, Result<MediaBrowser.MediaItem> result)
|
||||
throws UnsupportedOperationException {
|
||||
throw new UnsupportedOperationException("getMediaItem is not supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to set the media session.
|
||||
* <p>
|
||||
* This should be called as soon as possible during the service's startup.
|
||||
* It may only be called once.
|
||||
*
|
||||
* @param token The token for the service's {@link MediaSession}.
|
||||
*/
|
||||
public void setSessionToken(final MediaSession.Token token) {
|
||||
if (token == null) {
|
||||
|
||||
Reference in New Issue
Block a user