Merge "Add thumbnail related api." into lmp-dev
This commit is contained in:
@@ -16164,10 +16164,11 @@ package android.media.browse {
|
||||
ctor public MediaBrowser(android.content.Context, android.content.ComponentName, android.media.browse.MediaBrowser.ConnectionCallback, android.os.Bundle);
|
||||
method public void connect();
|
||||
method public void disconnect();
|
||||
method public android.os.Bundle getExtras();
|
||||
method public android.net.Uri getRoot();
|
||||
method public android.media.session.MediaSession.Token getSessionToken();
|
||||
method public boolean isConnected();
|
||||
method public void loadThumbnail(android.net.Uri, int, int, int, android.media.browse.MediaBrowser.ThumbnailCallback);
|
||||
method public void loadThumbnail(android.net.Uri, int, int, android.media.browse.MediaBrowser.ThumbnailCallback);
|
||||
method public void subscribe(android.net.Uri, android.media.browse.MediaBrowser.SubscriptionCallback);
|
||||
method public void unsubscribe(android.net.Uri);
|
||||
}
|
||||
@@ -16195,6 +16196,8 @@ package android.media.browse {
|
||||
method public int describeContents();
|
||||
method public android.os.Bundle getExtras();
|
||||
method public int getFlags();
|
||||
method public int getIconResId();
|
||||
method public android.net.Uri getIconUri();
|
||||
method public java.lang.CharSequence getSummary();
|
||||
method public java.lang.CharSequence getTitle();
|
||||
method public android.net.Uri getUri();
|
||||
@@ -16210,6 +16213,8 @@ package android.media.browse {
|
||||
ctor public MediaBrowserItem.Builder(android.net.Uri, int, java.lang.CharSequence);
|
||||
method public android.media.browse.MediaBrowserItem build();
|
||||
method public android.media.browse.MediaBrowserItem.Builder setExtras(android.os.Bundle);
|
||||
method public android.media.browse.MediaBrowserItem.Builder setIconResId(int);
|
||||
method public android.media.browse.MediaBrowserItem.Builder setIconUri(android.net.Uri);
|
||||
method public android.media.browse.MediaBrowserItem.Builder setSummary(java.lang.CharSequence);
|
||||
}
|
||||
|
||||
@@ -16217,16 +16222,19 @@ package android.media.browse {
|
||||
ctor public MediaBrowserService();
|
||||
method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
|
||||
method public android.media.session.MediaSession.Token getSessionToken();
|
||||
method public void notifyChange();
|
||||
method public void notifyChildrenChanged(android.net.Uri);
|
||||
method public android.os.IBinder onBind(android.content.Intent);
|
||||
method public abstract android.net.Uri onGetRoot(java.lang.String, int, android.os.Bundle);
|
||||
method public abstract android.graphics.Bitmap onGetThumbnail(android.net.Uri, int, int, int);
|
||||
method public abstract java.util.List<android.media.browse.MediaBrowserItem> onLoadChildren(android.net.Uri);
|
||||
method protected abstract android.media.browse.MediaBrowserService.BrowserRoot onGetRoot(java.lang.String, int, android.os.Bundle);
|
||||
method protected abstract android.graphics.Bitmap onGetThumbnail(android.net.Uri, int, int);
|
||||
method protected abstract java.util.List<android.media.browse.MediaBrowserItem> onLoadChildren(android.net.Uri);
|
||||
method public void setSessionToken(android.media.session.MediaSession.Token);
|
||||
field public static final java.lang.String SERVICE_ACTION = "android.media.browse.MediaBrowserService";
|
||||
}
|
||||
|
||||
public static class MediaBrowserService.BrowserRoot {
|
||||
ctor public MediaBrowserService.BrowserRoot(android.net.Uri, android.os.Bundle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.media.effect {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
package android.media.browse;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.media.browse.IMediaBrowserServiceCallbacks;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
@@ -17,4 +18,5 @@ oneway interface IMediaBrowserService {
|
||||
|
||||
void addSubscription(in Uri uri, IMediaBrowserServiceCallbacks callbacks);
|
||||
void removeSubscription(in Uri uri, IMediaBrowserServiceCallbacks callbacks);
|
||||
void loadThumbnail(in Uri uri, int width, int height, IMediaBrowserServiceCallbacks callbacks);
|
||||
}
|
||||
@@ -3,8 +3,10 @@
|
||||
package android.media.browse;
|
||||
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.graphics.Bitmap;
|
||||
import android.media.session.MediaSession;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* Media API allows clients to browse through hierarchy of a user’s media collection,
|
||||
@@ -16,9 +18,11 @@ oneway interface IMediaBrowserServiceCallbacks {
|
||||
* Invoked when the connected has been established.
|
||||
* @param root The root Uri for browsing.
|
||||
* @param session The {@link MediaSession.Token media session token} that can be used to control
|
||||
* the playback of the media app.
|
||||
* the playback of the media app.
|
||||
* @param extra Extras returned by the media service.
|
||||
*/
|
||||
void onConnect(in Uri root, in MediaSession.Token session);
|
||||
void onConnect(in Uri root, in MediaSession.Token session, in Bundle extras);
|
||||
void onConnectFailed();
|
||||
void onLoadChildren(in Uri uri, in ParceledListSlice list);
|
||||
void onLoadThumbnail(in Uri uri, int width, int height, in Bitmap bitmap);
|
||||
}
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
package android.media.browse;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.media.session.MediaSession;
|
||||
import android.net.Uri;
|
||||
@@ -36,7 +38,9 @@ import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Browses media content offered by a link MediaBrowserService.
|
||||
@@ -61,6 +65,8 @@ public final class MediaBrowser {
|
||||
private final Handler mHandler = new Handler();
|
||||
private final ArrayMap<Uri,Subscription> mSubscriptions =
|
||||
new ArrayMap<Uri, MediaBrowser.Subscription>();
|
||||
private final ArrayMap<ThumbnailRequest, HashSet<ThumbnailCallback>> mThumbnailCallbacks =
|
||||
new ArrayMap<ThumbnailRequest, HashSet<ThumbnailCallback>>();
|
||||
|
||||
private int mState = CONNECT_STATE_DISCONNECTED;
|
||||
private MediaServiceConnection mServiceConnection;
|
||||
@@ -68,6 +74,7 @@ public final class MediaBrowser {
|
||||
private IMediaBrowserServiceCallbacks mServiceCallbacks;
|
||||
private Uri mRootUri;
|
||||
private MediaSession.Token mMediaSessionToken;
|
||||
private Bundle mExtras;
|
||||
|
||||
/**
|
||||
* Creates a media browser for the specified media browse service.
|
||||
@@ -162,7 +169,6 @@ public final class MediaBrowser {
|
||||
|
||||
/**
|
||||
* Disconnects from the media browse service.
|
||||
* @more
|
||||
* After this, no more callbacks will be received.
|
||||
*/
|
||||
public void disconnect() {
|
||||
@@ -223,7 +229,7 @@ public final class MediaBrowser {
|
||||
* </p>
|
||||
*
|
||||
* @throws IllegalStateException if not connected.
|
||||
*/
|
||||
*/
|
||||
public @NonNull Uri getRoot() {
|
||||
if (mState != CONNECT_STATE_CONNECTED) {
|
||||
throw new IllegalStateException("getSessionToken() called while not connected (state="
|
||||
@@ -232,6 +238,19 @@ public final class MediaBrowser {
|
||||
return mRootUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets any extras for the media service.
|
||||
*
|
||||
* @throws IllegalStateException if not connected.
|
||||
*/
|
||||
public @Nullable Bundle getExtras() {
|
||||
if (mState != CONNECT_STATE_CONNECTED) {
|
||||
throw new IllegalStateException("getExtras() called while not connected (state="
|
||||
+ getStateLabel(mState) + ")");
|
||||
}
|
||||
return mExtras;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the media session token associated with the media browser.
|
||||
* <p>
|
||||
@@ -332,18 +351,45 @@ public final class MediaBrowser {
|
||||
/**
|
||||
* Loads the thumbnail of a media item.
|
||||
*
|
||||
* @param uri The uri of the media item.
|
||||
* @param uri The uri of the thumbnail.
|
||||
* @param width The preferred width of the icon in dp.
|
||||
* @param height The preferred width of the icon in dp.
|
||||
* @param density The preferred density of the icon. Must be one of the android
|
||||
* density buckets.
|
||||
* @param callback The callback to receive the thumbnail.
|
||||
*
|
||||
* @throws IllegalStateException if not connected. TODO: Is this restriction necessary?
|
||||
*/
|
||||
public void loadThumbnail(@NonNull Uri uri, int width, int height, int density,
|
||||
@NonNull ThumbnailCallback callback) {
|
||||
throw new RuntimeException("implement me");
|
||||
public void loadThumbnail(final @NonNull Uri uri, final int width, final int height,
|
||||
final @NonNull ThumbnailCallback callback) {
|
||||
if (uri == null) {
|
||||
throw new IllegalArgumentException("thumbnail uri cannot be null");
|
||||
}
|
||||
if (callback == null) {
|
||||
throw new IllegalArgumentException("thumbnail callback cannot be null");
|
||||
}
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
HashSet<ThumbnailCallback> callbackSet;
|
||||
ThumbnailRequest request = new ThumbnailRequest(uri, width, height);
|
||||
callbackSet = mThumbnailCallbacks.get(request);
|
||||
if (callbackSet != null) {
|
||||
callbackSet.add(callback);
|
||||
mThumbnailCallbacks.put(request, callbackSet);
|
||||
// same request has been sent. we will wait for the callback.
|
||||
return;
|
||||
}
|
||||
callbackSet = new HashSet<ThumbnailCallback>();
|
||||
callbackSet.add(callback);
|
||||
mThumbnailCallbacks.put(request, callbackSet);
|
||||
if (mState == CONNECT_STATE_CONNECTED) {
|
||||
try {
|
||||
mServiceBinder.loadThumbnail(uri, width, height, mServiceCallbacks);
|
||||
} catch (RemoteException e) {
|
||||
// Process is crashing. We will disconnect, and upon reconnect we will
|
||||
// automatically reload the thumbnails. So nothing to do here.
|
||||
Log.d(TAG, "loadThumbnail failed with RemoteException uri=" + uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -365,7 +411,7 @@ public final class MediaBrowser {
|
||||
}
|
||||
|
||||
private final void onServiceConnected(final IMediaBrowserServiceCallbacks callback,
|
||||
final Uri root, final MediaSession.Token session) {
|
||||
final Uri root, final MediaSession.Token session, final Bundle extra) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -382,6 +428,7 @@ public final class MediaBrowser {
|
||||
}
|
||||
mRootUri = root;
|
||||
mMediaSessionToken = session;
|
||||
mExtras = extra;
|
||||
mState = CONNECT_STATE_CONNECTED;
|
||||
|
||||
if (DBG) {
|
||||
@@ -402,6 +449,17 @@ public final class MediaBrowser {
|
||||
}
|
||||
}
|
||||
|
||||
for (ThumbnailRequest request : mThumbnailCallbacks.keySet()) {
|
||||
try {
|
||||
mServiceBinder.loadThumbnail(request.uri, request.width, request.height,
|
||||
mServiceCallbacks);
|
||||
} catch (RemoteException e) {
|
||||
// Process is crashing. We will disconnect, and upon reconnect we will
|
||||
// automatically reload. So nothing to do here.
|
||||
Log.d(TAG, "loadThumbnail failed with RemoteException uri=" + request.uri);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -468,6 +526,31 @@ public final class MediaBrowser {
|
||||
});
|
||||
}
|
||||
|
||||
private final void onLoadThumbnail(final IMediaBrowserServiceCallbacks callback,
|
||||
final ThumbnailRequest request, final Bitmap bitmap) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Check that there hasn't been a disconnect or a different
|
||||
// ServiceConnection.
|
||||
if (!isCurrent(callback, "onLoadThumbnail")) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<ThumbnailCallback> callbackSet = mThumbnailCallbacks.get(request);
|
||||
if (callbackSet == null) {
|
||||
Log.d(TAG, "onLoadThumbnail called for request=" + request +
|
||||
" but the callback is not registered");
|
||||
return;
|
||||
}
|
||||
for (ThumbnailCallback thumbnailCallback : callbackSet) {
|
||||
thumbnailCallback.onThumbnailLoaded(request.uri, bitmap);
|
||||
}
|
||||
mThumbnailCallbacks.remove(request);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if {@code callback} is the current ServiceCallbacks. Also logs if it's not.
|
||||
@@ -567,6 +650,51 @@ public final class MediaBrowser {
|
||||
}
|
||||
}
|
||||
|
||||
private static class ThumbnailRequest {
|
||||
Uri uri;
|
||||
int width;
|
||||
int height;
|
||||
ThumbnailRequest(@NonNull Uri uri, int width, int height) {
|
||||
if (uri == null) {
|
||||
throw new IllegalArgumentException("thumbnail uri cannot be null");
|
||||
}
|
||||
this.uri = uri;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ThumbnailRequest)) return false;
|
||||
|
||||
ThumbnailRequest that = (ThumbnailRequest) o;
|
||||
|
||||
if (height != that.height) return false;
|
||||
if (width != that.width) return false;
|
||||
if (!uri.equals(that.uri)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = uri.hashCode();
|
||||
result = 31 * result + width;
|
||||
result = 31 * result + height;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ThumbnailRequest{" +
|
||||
"uri=" + uri +
|
||||
", width=" + width +
|
||||
", height=" + height +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ServiceConnection to the other app.
|
||||
*/
|
||||
@@ -666,10 +794,11 @@ public final class MediaBrowser {
|
||||
* are the initial data as requested.
|
||||
*/
|
||||
@Override
|
||||
public void onConnect(final Uri root, final MediaSession.Token session) {
|
||||
public void onConnect(final Uri root, final MediaSession.Token session,
|
||||
final Bundle extras) {
|
||||
MediaBrowser mediaBrowser = mMediaBrowser.get();
|
||||
if (mediaBrowser != null) {
|
||||
mediaBrowser.onServiceConnected(this, root, session);
|
||||
mediaBrowser.onServiceConnected(this, root, session, extras);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -691,6 +820,15 @@ public final class MediaBrowser {
|
||||
mediaBrowser.onLoadChildren(this, uri, list);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadThumbnail(final Uri uri, int width, int height, final Bitmap bitmap) {
|
||||
MediaBrowser mediaBrowser = mMediaBrowser.get();
|
||||
if (mediaBrowser != null) {
|
||||
ThumbnailRequest request = new ThumbnailRequest(uri, width, height);
|
||||
mediaBrowser.onLoadThumbnail(this, request, bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class Subscription {
|
||||
|
||||
@@ -32,6 +32,8 @@ import java.lang.annotation.RetentionPolicy;
|
||||
*/
|
||||
public final class MediaBrowserItem implements Parcelable {
|
||||
private final Uri mUri;
|
||||
private final Uri mIconUri;
|
||||
private final int mIconResId;
|
||||
private final int mFlags;
|
||||
private final CharSequence mTitle;
|
||||
private final CharSequence mSummary;
|
||||
@@ -59,8 +61,8 @@ public final class MediaBrowserItem implements Parcelable {
|
||||
/**
|
||||
* Initialize a MediaBrowserItem object.
|
||||
*/
|
||||
private MediaBrowserItem(@NonNull Uri uri, int flags, @NonNull CharSequence title,
|
||||
CharSequence summary, Bundle extras) {
|
||||
private MediaBrowserItem(@NonNull Uri uri, @Nullable Uri iconUri, int iconResId, int flags,
|
||||
@NonNull CharSequence title, CharSequence summary, Bundle extras) {
|
||||
if (uri == null) {
|
||||
throw new IllegalArgumentException("uri can not be null");
|
||||
}
|
||||
@@ -68,6 +70,8 @@ public final class MediaBrowserItem implements Parcelable {
|
||||
throw new IllegalArgumentException("title can not be null");
|
||||
}
|
||||
mUri = uri;
|
||||
mIconUri = iconUri;
|
||||
mIconResId = iconResId;
|
||||
mFlags = flags;
|
||||
mTitle = title;
|
||||
mSummary = summary;
|
||||
@@ -79,6 +83,8 @@ public final class MediaBrowserItem implements Parcelable {
|
||||
*/
|
||||
private MediaBrowserItem(Parcel in) {
|
||||
mUri = Uri.CREATOR.createFromParcel(in);
|
||||
mIconUri = Uri.CREATOR.createFromParcel(in);
|
||||
mIconResId = in.readInt();
|
||||
mFlags = in.readInt();
|
||||
mTitle = in.readCharSequence();
|
||||
if (in.readInt() != 0) {
|
||||
@@ -101,6 +107,8 @@ public final class MediaBrowserItem implements Parcelable {
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
mUri.writeToParcel(out, flags);
|
||||
mIconUri.writeToParcel(out, flags);
|
||||
out.writeInt(mIconResId);
|
||||
out.writeInt(mFlags);
|
||||
out.writeCharSequence(mTitle);
|
||||
if (mSummary != null) {
|
||||
@@ -137,6 +145,20 @@ public final class MediaBrowserItem implements Parcelable {
|
||||
return mUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Uri of the icon.
|
||||
*/
|
||||
public @Nullable Uri getIconUri() {
|
||||
return mIconUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the resource id of the icon.
|
||||
*/
|
||||
public int getIconResId() {
|
||||
return mIconResId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the flags of the item.
|
||||
*/
|
||||
@@ -195,6 +217,8 @@ public final class MediaBrowserItem implements Parcelable {
|
||||
private final Uri mUri;
|
||||
private final int mFlags;
|
||||
private final CharSequence mTitle;
|
||||
private Uri mIconUri;
|
||||
private int mIconResId;
|
||||
private CharSequence mSummary;
|
||||
private Bundle mExtras;
|
||||
|
||||
@@ -213,6 +237,26 @@ public final class MediaBrowserItem implements Parcelable {
|
||||
mTitle = title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the uri of the icon.
|
||||
* <p>
|
||||
* If both {@link #setIconUri(Uri)} and {@link #setIconResId(int)} are called,
|
||||
* the resource id will be used to load the icon.
|
||||
* </p>
|
||||
*/
|
||||
public @NonNull Builder setIconUri(@Nullable Uri iconUri) {
|
||||
mIconUri = iconUri;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the resource id of the icon.
|
||||
*/
|
||||
public @NonNull Builder setIconResId(int resId) {
|
||||
mIconResId = resId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets summary of the item, or null if none.
|
||||
*/
|
||||
@@ -234,7 +278,8 @@ public final class MediaBrowserItem implements Parcelable {
|
||||
* Builds the item.
|
||||
*/
|
||||
public @NonNull MediaBrowserItem build() {
|
||||
return new MediaBrowserItem(mUri, mFlags, mTitle, mSummary, mExtras);
|
||||
return new MediaBrowserItem(mUri, mIconUri, mIconResId,
|
||||
mFlags, mTitle, mSummary, mExtras);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.media.session.MediaSession;
|
||||
import android.net.Uri;
|
||||
@@ -43,6 +44,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Base class for media browse services.
|
||||
@@ -81,7 +83,7 @@ public abstract class MediaBrowserService extends Service {
|
||||
String pkg;
|
||||
Bundle rootHints;
|
||||
IMediaBrowserServiceCallbacks callbacks;
|
||||
Uri root;
|
||||
BrowserRoot root;
|
||||
HashSet<Uri> subscriptions = new HashSet();
|
||||
}
|
||||
|
||||
@@ -130,7 +132,8 @@ public abstract class MediaBrowserService extends Service {
|
||||
} else {
|
||||
try {
|
||||
mConnections.put(b, connection);
|
||||
callbacks.onConnect(connection.root, mSession);
|
||||
callbacks.onConnect(connection.root.getRootUri(),
|
||||
mSession, connection.root.getExtras());
|
||||
} catch (RemoteException ex) {
|
||||
Log.w(TAG, "Calling onConnect() failed. Dropping client. "
|
||||
+ "pkg=" + pkg);
|
||||
@@ -199,6 +202,22 @@ public abstract class MediaBrowserService extends Service {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadThumbnail(final Uri uri, final int width, final int height,
|
||||
final IMediaBrowserServiceCallbacks callbacks) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Bitmap bitmap = onGetThumbnail(uri, width, height);
|
||||
try {
|
||||
callbacks.onLoadThumbnail(uri, width, height, bitmap);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException in calling onLoadThumbnail", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -220,7 +239,7 @@ public abstract class MediaBrowserService extends Service {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to get the root uri for browsing by a particular client.
|
||||
* 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
|
||||
@@ -237,8 +256,8 @@ public abstract class MediaBrowserService extends Service {
|
||||
* for browsing, or null if none. The contents of this bundle may affect
|
||||
* the information returned when browsing.
|
||||
*/
|
||||
public abstract @Nullable Uri onGetRoot(@NonNull String clientPackageName, int clientUid,
|
||||
@Nullable Bundle rootHints);
|
||||
protected abstract @Nullable BrowserRoot onGetRoot(@NonNull String clientPackageName,
|
||||
int clientUid, @Nullable Bundle rootHints);
|
||||
|
||||
/**
|
||||
* Called to get information about the children of a media item.
|
||||
@@ -247,7 +266,7 @@ public abstract class MediaBrowserService extends Service {
|
||||
* children are to be queried.
|
||||
* @return The list of children, or null if the uri is invalid.
|
||||
*/
|
||||
public abstract @Nullable List<MediaBrowserItem> onLoadChildren(@NonNull Uri parentUri);
|
||||
protected abstract @Nullable List<MediaBrowserItem> onLoadChildren(@NonNull Uri parentUri);
|
||||
|
||||
/**
|
||||
* Called to get the thumbnail of a particular media item.
|
||||
@@ -255,14 +274,11 @@ public abstract class MediaBrowserService extends Service {
|
||||
* @param uri The uri of the media item.
|
||||
* @param width The requested width of the icon in dp.
|
||||
* @param height The requested height of the icon in dp.
|
||||
* @param density The requested density of the icon. This is the approximate density of the
|
||||
* screen on which the icon will be displayed. This density will be one of
|
||||
* the android density buckets.
|
||||
*
|
||||
* @return The file descriptor of the thumbnail, which may then be loaded
|
||||
* using a bitmap factory, or null if the item does not have a thumbnail.
|
||||
*/
|
||||
public abstract @Nullable Bitmap onGetThumbnail(@NonNull Uri uri,
|
||||
int width, int height, int density);
|
||||
protected abstract @Nullable Bitmap onGetThumbnail(@NonNull Uri uri, int width, int height);
|
||||
|
||||
/**
|
||||
* Call to set the media session.
|
||||
@@ -287,15 +303,6 @@ public abstract class MediaBrowserService extends Service {
|
||||
return mSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all connected media browsers that the content of
|
||||
* the browse service has changed in some way.
|
||||
* This will cause browsers to fetch subscribed content again.
|
||||
*/
|
||||
public void notifyChange() {
|
||||
throw new RuntimeException("implement me");
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all connected media browsers that the children of
|
||||
* the specified Uri have changed in some way.
|
||||
@@ -305,7 +312,19 @@ public abstract class MediaBrowserService extends Service {
|
||||
* children changed.
|
||||
*/
|
||||
public void notifyChildrenChanged(@NonNull Uri parentUri) {
|
||||
throw new RuntimeException("implement me");
|
||||
if (parentUri == null) {
|
||||
throw new IllegalArgumentException("parentUri cannot be null in notifyChildrenChanged");
|
||||
}
|
||||
for (IBinder binder : mConnections.keySet()) {
|
||||
ConnectionRecord connection = mConnections.get(binder);
|
||||
Set<Uri> uris = connection.subscriptions;
|
||||
for (Uri uri : uris) {
|
||||
if (uri.equals(parentUri)) {
|
||||
performLoadChildren(uri, connection);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -360,4 +379,25 @@ public abstract class MediaBrowserService extends Service {
|
||||
+ " package=" + connection.pkg);
|
||||
}
|
||||
}
|
||||
|
||||
public static class BrowserRoot {
|
||||
final private Uri mUri;
|
||||
final private Bundle mExtras;
|
||||
public BrowserRoot(@NonNull Uri uri, @Nullable Bundle extras) {
|
||||
if (uri == null) {
|
||||
throw new IllegalArgumentException("The root uri in BrowserRoot cannot be null. " +
|
||||
"Use null for BrowserRoot instead.");
|
||||
}
|
||||
mUri = uri;
|
||||
mExtras = extras;
|
||||
}
|
||||
|
||||
Uri getRootUri() {
|
||||
return mUri;
|
||||
}
|
||||
|
||||
Bundle getExtras() {
|
||||
return mExtras;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.media.MediaPlayer.OnErrorListener;
|
||||
import android.media.MediaPlayer.OnPreparedListener;
|
||||
import android.media.browse.MediaBrowserItem;
|
||||
import android.media.browse.MediaBrowserService;
|
||||
import android.media.browse.MediaBrowserService.BrowserRoot;
|
||||
import android.media.session.MediaSession;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
@@ -115,24 +116,27 @@ public class BrowserService extends MediaBrowserService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
|
||||
return BROWSE_URI;
|
||||
protected BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
|
||||
return new BrowserRoot(BROWSE_URI, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MediaBrowserItem> onLoadChildren(Uri parentUri) {
|
||||
protected List<MediaBrowserItem> onLoadChildren(Uri parentUri) {
|
||||
final ArrayList<MediaBrowserItem> results = new ArrayList();
|
||||
|
||||
for (int i=0; i<10; i++) {
|
||||
results.add(new MediaBrowserItem.Builder(Uri.withAppendedPath(BASE_URI, Integer.toString(i)),
|
||||
MediaBrowserItem.FLAG_BROWSABLE, "Title " + i).setSummary("Summary " + i).build());
|
||||
results.add(new MediaBrowserItem.Builder(
|
||||
Uri.withAppendedPath(BASE_URI, Integer.toString(i)),
|
||||
MediaBrowserItem.FLAG_BROWSABLE, "Title " + i)
|
||||
.setSummary("Summary " + i)
|
||||
.build());
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap onGetThumbnail(Uri uri, int width, int height, int density) {
|
||||
protected Bitmap onGetThumbnail(Uri uri, int width, int height) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user