summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoboErik <epastern@google.com>2014-08-28 21:51:49 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-08-28 21:51:50 +0000
commit350be2e1c2e4ad8b1a1386a55b40c123f148e94e (patch)
tree5ed9e9cfaa4e6af7d64e7a4c7adf7443ce81c411
parent2f2ea058db85393774e9a73144d7c60dc9bdb6aa (diff)
parent3625bf72cb8bcf3c7f8f8cd8d708d7206824cc62 (diff)
downloadframeworks_base-350be2e1c2e4ad8b1a1386a55b40c123f148e94e.zip
frameworks_base-350be2e1c2e4ad8b1a1386a55b40c123f148e94e.tar.gz
frameworks_base-350be2e1c2e4ad8b1a1386a55b40c123f148e94e.tar.bz2
Merge "Update to MediaBrowser APIs per council feedback" into lmp-dev
-rw-r--r--Android.mk4
-rw-r--r--api/current.txt159
-rw-r--r--media/java/android/media/MediaDescription.aidl18
-rw-r--r--media/java/android/media/MediaDescription.java276
-rw-r--r--media/java/android/media/MediaMetadata.java139
-rw-r--r--media/java/android/media/browse/MediaBrowser.java307
-rw-r--r--media/java/android/media/browse/MediaBrowserItem.java313
-rw-r--r--media/java/android/media/session/ISessionCallback.aidl2
-rw-r--r--media/java/android/media/session/ISessionController.aidl4
-rw-r--r--media/java/android/media/session/MediaController.java27
-rw-r--r--media/java/android/media/session/MediaSession.aidl2
-rw-r--r--media/java/android/media/session/MediaSession.java161
-rw-r--r--media/java/android/media/session/PlaybackState.java56
-rw-r--r--media/java/android/service/media/IMediaBrowserService.aidl (renamed from media/java/android/media/browse/IMediaBrowserService.aidl)6
-rw-r--r--media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl (renamed from media/java/android/media/browse/IMediaBrowserServiceCallbacks.aidl)3
-rw-r--r--media/java/android/service/media/MediaBrowserService.java (renamed from media/java/android/media/browse/MediaBrowserService.java)89
-rw-r--r--services/core/java/com/android/server/media/MediaSessionRecord.java13
-rw-r--r--tests/OneMedia/src/com/android/onemedia/NotificationHelper.java5
18 files changed, 674 insertions, 910 deletions
diff --git a/Android.mk b/Android.mk
index 3edaefc..35bb66c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -325,8 +325,6 @@ LOCAL_SRC_FILES += \
media/java/android/media/IRemoteVolumeObserver.aidl \
media/java/android/media/IRingtonePlayer.aidl \
media/java/android/media/IVolumeController.aidl \
- media/java/android/media/browse/IMediaBrowserService.aidl \
- media/java/android/media/browse/IMediaBrowserServiceCallbacks.aidl \
media/java/android/media/projection/IMediaProjection.aidl \
media/java/android/media/projection/IMediaProjectionCallback.aidl \
media/java/android/media/projection/IMediaProjectionManager.aidl \
@@ -346,6 +344,8 @@ LOCAL_SRC_FILES += \
media/java/android/media/tv/ITvInputServiceCallback.aidl \
media/java/android/media/tv/ITvInputSession.aidl \
media/java/android/media/tv/ITvInputSessionCallback.aidl \
+ media/java/android/service/media/IMediaBrowserService.aidl \
+ media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl \
telecomm/java/com/android/internal/telecomm/IVideoCallback.aidl \
telecomm/java/com/android/internal/telecomm/IVideoProvider.aidl \
telecomm/java/com/android/internal/telecomm/IConnectionService.aidl \
diff --git a/api/current.txt b/api/current.txt
index d6f91f2..7392b97 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -14919,6 +14919,31 @@ package android.media {
ctor public MediaCryptoException(java.lang.String);
}
+ public class MediaDescription implements android.os.Parcelable {
+ method public int describeContents();
+ method public java.lang.CharSequence getDescription();
+ method public android.os.Bundle getExtras();
+ method public android.graphics.Bitmap getIconBitmap();
+ method public android.net.Uri getIconUri();
+ method public java.lang.String getMediaId();
+ method public java.lang.CharSequence getSubtitle();
+ method public java.lang.CharSequence getTitle();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
+ }
+
+ public static class MediaDescription.Builder {
+ ctor public MediaDescription.Builder();
+ method public android.media.MediaDescription build();
+ method public android.media.MediaDescription.Builder setDescription(java.lang.CharSequence);
+ method public android.media.MediaDescription.Builder setExtras(android.os.Bundle);
+ method public android.media.MediaDescription.Builder setIconBitmap(android.graphics.Bitmap);
+ method public android.media.MediaDescription.Builder setIconUri(android.net.Uri);
+ method public android.media.MediaDescription.Builder setMediaId(java.lang.String);
+ method public android.media.MediaDescription.Builder setSubtitle(java.lang.CharSequence);
+ method public android.media.MediaDescription.Builder setTitle(java.lang.CharSequence);
+ }
+
public final class MediaDrm {
ctor public MediaDrm(java.util.UUID) throws android.media.UnsupportedSchemeException;
method public void closeSession(byte[]);
@@ -15097,7 +15122,7 @@ package android.media {
method public boolean containsKey(java.lang.String);
method public int describeContents();
method public android.graphics.Bitmap getBitmap(java.lang.String);
- method public android.media.MediaMetadata.Description getDescription();
+ method public android.media.MediaDescription getDescription();
method public long getLong(java.lang.String);
method public android.media.Rating getRating(java.lang.String);
method public java.lang.String getString(java.lang.String);
@@ -15125,6 +15150,7 @@ package android.media {
field public static final java.lang.String METADATA_KEY_DISPLAY_TITLE = "android.media.metadata.DISPLAY_TITLE";
field public static final java.lang.String METADATA_KEY_DURATION = "android.media.metadata.DURATION";
field public static final java.lang.String METADATA_KEY_GENRE = "android.media.metadata.GENRE";
+ field public static final java.lang.String METADATA_KEY_MEDIA_ID = "android.media.metadata.MEDIA_ID";
field public static final java.lang.String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS";
field public static final java.lang.String METADATA_KEY_RATING = "android.media.metadata.RATING";
field public static final java.lang.String METADATA_KEY_TITLE = "android.media.metadata.TITLE";
@@ -15145,14 +15171,6 @@ package android.media {
method public android.media.MediaMetadata.Builder putText(java.lang.String, java.lang.CharSequence);
}
- public final class MediaMetadata.Description {
- method public java.lang.CharSequence getDescription();
- method public android.graphics.Bitmap getIcon();
- method public android.net.Uri getIconUri();
- method public java.lang.CharSequence getSubtitle();
- method public java.lang.CharSequence getTitle();
- }
-
public abstract deprecated class MediaMetadataEditor {
method public synchronized void addEditableKey(int);
method public abstract void apply();
@@ -16238,7 +16256,6 @@ package android.media.browse {
method public android.content.ComponentName getServiceComponent();
method public android.media.session.MediaSession.Token getSessionToken();
method public boolean isConnected();
- method public void loadIcon(android.net.Uri, int, int, android.media.browse.MediaBrowser.IconCallback);
method public void subscribe(android.net.Uri, android.media.browse.MediaBrowser.SubscriptionCallback);
method public void unsubscribe(android.net.Uri);
}
@@ -16250,27 +16267,12 @@ package android.media.browse {
method public void onConnectionSuspended();
}
- public static abstract class MediaBrowser.IconCallback {
- ctor public MediaBrowser.IconCallback();
- method public void onError(android.net.Uri);
- method public void onIconLoaded(android.net.Uri, android.graphics.Bitmap);
- }
-
- public static abstract class MediaBrowser.SubscriptionCallback {
- ctor public MediaBrowser.SubscriptionCallback();
- method public void onChildrenLoaded(android.net.Uri, java.util.List<android.media.browse.MediaBrowserItem>);
- method public void onError(android.net.Uri);
- }
-
- public final class MediaBrowserItem implements android.os.Parcelable {
+ public static class MediaBrowser.MediaItem implements android.os.Parcelable {
+ ctor public MediaBrowser.MediaItem(int, android.media.MediaDescription);
method public int describeContents();
- method public android.os.Bundle getExtras();
+ method public android.media.MediaDescription getDescription();
method public int getFlags();
- method public int getIconResourceId();
- method public android.net.Uri getIconUri();
- method public java.lang.CharSequence getSummary();
- method public java.lang.CharSequence getTitle();
- method public android.net.Uri getUri();
+ method public java.lang.String getMediaId();
method public boolean isBrowsable();
method public boolean isPlayable();
method public void writeToParcel(android.os.Parcel, int);
@@ -16279,37 +16281,10 @@ package android.media.browse {
field public static final int FLAG_PLAYABLE = 2; // 0x2
}
- public static final class MediaBrowserItem.Builder {
- 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 setIconResourceId(int);
- method public android.media.browse.MediaBrowserItem.Builder setIconUri(android.net.Uri);
- method public android.media.browse.MediaBrowserItem.Builder setSummary(java.lang.CharSequence);
- }
-
- 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 android.media.session.MediaSession.Token getSessionToken();
- method public void notifyChildrenChanged(android.net.Uri);
- method public android.os.IBinder onBind(android.content.Intent);
- method public abstract android.media.browse.MediaBrowserService.BrowserRoot onGetRoot(java.lang.String, int, android.os.Bundle);
- method public abstract void onLoadChildren(android.net.Uri, android.media.browse.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowserItem>>);
- method public abstract void onLoadIcon(android.net.Uri, int, int, android.media.browse.MediaBrowserService.Result<android.graphics.Bitmap>);
- method public void setSessionToken(android.media.session.MediaSession.Token);
- field public static final java.lang.String SERVICE_ACTION = "android.media.browse.MediaBrowserService";
- }
-
- public static final class MediaBrowserService.BrowserRoot {
- ctor public MediaBrowserService.BrowserRoot(android.net.Uri, android.os.Bundle);
- method public android.os.Bundle getExtras();
- method public android.net.Uri getRootUri();
- }
-
- public class MediaBrowserService.Result {
- method public void detach();
- method public void sendResult(T);
+ public static abstract class MediaBrowser.SubscriptionCallback {
+ ctor public MediaBrowser.SubscriptionCallback();
+ method public void onChildrenLoaded(android.net.Uri, java.util.List<android.media.browse.MediaBrowser.MediaItem>);
+ method public void onError(android.net.Uri);
}
}
@@ -16404,7 +16379,7 @@ package android.media.session {
method public java.lang.String getPackageName();
method public android.media.session.MediaController.PlaybackInfo getPlaybackInfo();
method public android.media.session.PlaybackState getPlaybackState();
- method public java.util.List<android.media.session.MediaSession.Item> getQueue();
+ method public java.util.List<android.media.session.MediaSession.QueueItem> getQueue();
method public java.lang.CharSequence getQueueTitle();
method public int getRatingType();
method public android.app.PendingIntent getSessionActivity();
@@ -16421,7 +16396,7 @@ package android.media.session {
method public void onExtrasChanged(android.os.Bundle);
method public void onMetadataChanged(android.media.MediaMetadata);
method public void onPlaybackStateChanged(android.media.session.PlaybackState);
- method public void onQueueChanged(java.util.List<android.media.session.MediaSession.Item>);
+ method public void onQueueChanged(java.util.List<android.media.session.MediaSession.QueueItem>);
method public void onQueueTitleChanged(java.lang.CharSequence);
method public void onSessionDestroyed();
method public void onSessionEvent(java.lang.String, android.os.Bundle);
@@ -16441,16 +16416,16 @@ package android.media.session {
method public void fastForward();
method public void pause();
method public void play();
+ method public void playFromMediaId(java.lang.String, android.os.Bundle);
method public void playFromSearch(java.lang.String, android.os.Bundle);
- method public void playUri(android.net.Uri, android.os.Bundle);
method public void rewind();
method public void seekTo(long);
method public void sendCustomAction(android.media.session.PlaybackState.CustomAction, android.os.Bundle);
method public void sendCustomAction(java.lang.String, android.os.Bundle);
method public void setRating(android.media.Rating);
- method public void skipToItem(long);
method public void skipToNext();
method public void skipToPrevious();
+ method public void skipToQueueItem(long);
method public void stop();
}
@@ -16471,7 +16446,7 @@ package android.media.session {
method public void setPlaybackState(android.media.session.PlaybackState);
method public void setPlaybackToLocal(android.media.AudioAttributes);
method public void setPlaybackToRemote(android.media.VolumeProvider);
- method public void setQueue(java.util.List<android.media.session.MediaSession.Item>);
+ method public void setQueue(java.util.List<android.media.session.MediaSession.QueueItem>);
method public void setQueueTitle(java.lang.CharSequence);
method public void setSessionActivity(android.app.PendingIntent);
field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
@@ -16486,34 +16461,27 @@ package android.media.session {
method public boolean onMediaButtonEvent(android.content.Intent);
method public void onPause();
method public void onPlay();
+ method public void onPlayFromMediaId(java.lang.String, android.os.Bundle);
method public void onPlayFromSearch(java.lang.String, android.os.Bundle);
- method public void onPlayUri(android.net.Uri, android.os.Bundle);
method public void onRewind();
method public void onSeekTo(long);
method public void onSetRating(android.media.Rating);
- method public void onSkipToItem(long);
method public void onSkipToNext();
method public void onSkipToPrevious();
+ method public void onSkipToQueueItem(long);
method public void onStop();
}
- public static final class MediaSession.Item implements android.os.Parcelable {
+ public static final class MediaSession.QueueItem implements android.os.Parcelable {
+ ctor public MediaSession.QueueItem(android.media.MediaDescription, long);
method public int describeContents();
- method public android.os.Bundle getExtras();
- method public long getId();
- method public android.media.MediaMetadata getMetadata();
- method public android.net.Uri getUri();
+ method public android.media.MediaDescription getDescription();
+ method public long getQueueId();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
field public static final int UNKNOWN_ID = -1; // 0xffffffff
}
- public static final class MediaSession.Item.Builder {
- ctor public MediaSession.Item.Builder(android.media.MediaMetadata, long, android.net.Uri);
- method public android.media.session.MediaSession.Item build();
- method public android.media.session.MediaSession.Item.Builder setExtras(android.os.Bundle);
- }
-
public static final class MediaSession.Token implements android.os.Parcelable {
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
@@ -16534,6 +16502,7 @@ package android.media.session {
public final class PlaybackState implements android.os.Parcelable {
method public int describeContents();
method public long getActions();
+ method public long getActiveQueueItemId();
method public long getBufferedPosition();
method public java.util.List<android.media.session.PlaybackState.CustomAction> getCustomActions();
method public java.lang.CharSequence getErrorMessage();
@@ -16545,15 +16514,15 @@ package android.media.session {
field public static final long ACTION_FAST_FORWARD = 64L; // 0x40L
field public static final long ACTION_PAUSE = 2L; // 0x2L
field public static final long ACTION_PLAY = 4L; // 0x4L
+ field public static final long ACTION_PLAY_FROM_MEDIA_ID = 1024L; // 0x400L
field public static final long ACTION_PLAY_FROM_SEARCH = 2048L; // 0x800L
field public static final long ACTION_PLAY_PAUSE = 512L; // 0x200L
- field public static final long ACTION_PLAY_URI = 1024L; // 0x400L
field public static final long ACTION_REWIND = 8L; // 0x8L
field public static final long ACTION_SEEK_TO = 256L; // 0x100L
field public static final long ACTION_SET_RATING = 128L; // 0x80L
- field public static final long ACTION_SKIP_TO_ITEM = 4096L; // 0x1000L
field public static final long ACTION_SKIP_TO_NEXT = 32L; // 0x20L
field public static final long ACTION_SKIP_TO_PREVIOUS = 16L; // 0x10L
+ field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
field public static final long ACTION_STOP = 1L; // 0x1L
field public static final android.os.Parcelable.Creator CREATOR;
field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL
@@ -16567,6 +16536,7 @@ package android.media.session {
field public static final int STATE_REWINDING = 5; // 0x5
field public static final int STATE_SKIPPING_TO_NEXT = 10; // 0xa
field public static final int STATE_SKIPPING_TO_PREVIOUS = 9; // 0x9
+ field public static final int STATE_SKIPPING_TO_QUEUE_ITEM = 11; // 0xb
field public static final int STATE_STOPPED = 1; // 0x1
}
@@ -16577,7 +16547,7 @@ package android.media.session {
method public android.media.session.PlaybackState.Builder addCustomAction(android.media.session.PlaybackState.CustomAction);
method public android.media.session.PlaybackState build();
method public android.media.session.PlaybackState.Builder setActions(long);
- method public android.media.session.PlaybackState.Builder setActiveItem(long);
+ method public android.media.session.PlaybackState.Builder setActiveQueueItemId(long);
method public android.media.session.PlaybackState.Builder setBufferedPosition(long);
method public android.media.session.PlaybackState.Builder setErrorMessage(java.lang.CharSequence);
method public android.media.session.PlaybackState.Builder setState(int, long, float, long);
@@ -27093,6 +27063,33 @@ package android.service.dreams {
}
+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 android.media.session.MediaSession.Token getSessionToken();
+ method public void notifyChildrenChanged(android.net.Uri);
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract android.service.media.MediaBrowserService.BrowserRoot onGetRoot(java.lang.String, int, android.os.Bundle);
+ method public abstract void onLoadChildren(android.net.Uri, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>);
+ method public void setSessionToken(android.media.session.MediaSession.Token);
+ field public static final java.lang.String SERVICE_ACTION = "android.media.browse.MediaBrowserService";
+ }
+
+ public static final class MediaBrowserService.BrowserRoot {
+ ctor public MediaBrowserService.BrowserRoot(android.net.Uri, android.os.Bundle);
+ method public android.os.Bundle getExtras();
+ method public android.net.Uri getRootUri();
+ }
+
+ public class MediaBrowserService.Result {
+ method public void detach();
+ method public void sendResult(T);
+ }
+
+}
+
package android.service.notification {
public abstract class NotificationListenerService extends android.app.Service {
diff --git a/media/java/android/media/MediaDescription.aidl b/media/java/android/media/MediaDescription.aidl
new file mode 100644
index 0000000..6f934f7
--- /dev/null
+++ b/media/java/android/media/MediaDescription.aidl
@@ -0,0 +1,18 @@
+/* Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.media;
+
+parcelable MediaDescription;
diff --git a/media/java/android/media/MediaDescription.java b/media/java/android/media/MediaDescription.java
new file mode 100644
index 0000000..4399c0d
--- /dev/null
+++ b/media/java/android/media/MediaDescription.java
@@ -0,0 +1,276 @@
+package android.media;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ContentResolver;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.RectF;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Size;
+
+/**
+ * A simple set of metadata for a media item suitable for display. This can be
+ * created using the Builder or retrieved from existing metadata using
+ * {@link MediaMetadata#getDescription()}.
+ */
+public class MediaDescription implements Parcelable {
+ /**
+ * A unique persistent id for the content or null.
+ */
+ private final String mMediaId;
+ /**
+ * A primary title suitable for display or null.
+ */
+ private final CharSequence mTitle;
+ /**
+ * A subtitle suitable for display or null.
+ */
+ private final CharSequence mSubtitle;
+ /**
+ * A description suitable for display or null.
+ */
+ private final CharSequence mDescription;
+ /**
+ * A bitmap icon suitable for display or null.
+ */
+ private final Bitmap mIcon;
+ /**
+ * A Uri for an icon suitable for display or null.
+ */
+ private final Uri mIconUri;
+ /**
+ * Extras for opaque use by apps/system.
+ */
+ private final Bundle mExtras;
+
+ private MediaDescription(String mediaId, CharSequence title, CharSequence subtitle,
+ CharSequence description, Bitmap icon, Uri iconUri, Bundle extras) {
+ mMediaId = mediaId;
+ mTitle = title;
+ mSubtitle = subtitle;
+ mDescription = description;
+ mIcon = icon;
+ mIconUri = iconUri;
+ mExtras = extras;
+ }
+
+ private MediaDescription(Parcel in) {
+ mMediaId = in.readString();
+ mTitle = in.readCharSequence();
+ mSubtitle = in.readCharSequence();
+ mDescription = in.readCharSequence();
+ mIcon = in.readParcelable(null);
+ mIconUri = in.readParcelable(null);
+ mExtras = in.readBundle();
+ }
+
+ /**
+ * Returns the media id or null. See
+ * {@link MediaMetadata#METADATA_KEY_MEDIA_ID}.
+ */
+ public @Nullable String getMediaId() {
+ return mMediaId;
+ }
+
+ /**
+ * Returns a title suitable for display or null.
+ *
+ * @return A title or null.
+ */
+ public @Nullable CharSequence getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * Returns a subtitle suitable for display or null.
+ *
+ * @return A subtitle or null.
+ */
+ public @Nullable CharSequence getSubtitle() {
+ return mSubtitle;
+ }
+
+ /**
+ * Returns a description suitable for display or null.
+ *
+ * @return A description or null.
+ */
+ public @Nullable CharSequence getDescription() {
+ return mDescription;
+ }
+
+ /**
+ * Returns a bitmap icon suitable for display or null.
+ *
+ * @return An icon or null.
+ */
+ public @Nullable Bitmap getIconBitmap() {
+ return mIcon;
+ }
+
+ /**
+ * Returns a Uri for an icon suitable for display or null.
+ *
+ * @return An icon uri or null.
+ */
+ public @Nullable Uri getIconUri() {
+ return mIconUri;
+ }
+
+ /**
+ * Returns any extras that were added to the description.
+ *
+ * @return A bundle of extras or null.
+ */
+ public @Nullable Bundle getExtras() {
+ return mExtras;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mMediaId);
+ dest.writeCharSequence(mTitle);
+ dest.writeCharSequence(mSubtitle);
+ dest.writeCharSequence(mDescription);
+ dest.writeParcelable(mIcon, flags);
+ dest.writeParcelable(mIconUri, flags);
+ dest.writeBundle(mExtras);
+ }
+
+ @Override
+ public String toString() {
+ return mTitle + ", " + mSubtitle + ", " + mDescription;
+ }
+
+ public static final Parcelable.Creator<MediaDescription> CREATOR =
+ new Parcelable.Creator<MediaDescription>() {
+ @Override
+ public MediaDescription createFromParcel(Parcel in) {
+ return new MediaDescription(in);
+ }
+
+ @Override
+ public MediaDescription[] newArray(int size) {
+ return new MediaDescription[size];
+ }
+ };
+
+ /**
+ * Builder for {@link MediaDescription} objects.
+ */
+ public static class Builder {
+ private String mMediaId;
+ private CharSequence mTitle;
+ private CharSequence mSubtitle;
+ private CharSequence mDescription;
+ private Bitmap mIcon;
+ private Uri mIconUri;
+ private Bundle mExtras;
+
+ /**
+ * Creates an initially empty builder.
+ */
+ public Builder() {
+ }
+
+ /**
+ * Sets the media id.
+ *
+ * @param mediaId The unique id for the item or null.
+ * @return this
+ */
+ public Builder setMediaId(@Nullable String mediaId) {
+ mMediaId = mediaId;
+ return this;
+ }
+
+ /**
+ * Sets the title.
+ *
+ * @param title A title suitable for display to the user or null.
+ * @return this
+ */
+ public Builder setTitle(@Nullable CharSequence title) {
+ mTitle = title;
+ return this;
+ }
+
+ /**
+ * Sets the subtitle.
+ *
+ * @param subtitle A subtitle suitable for display to the user or null.
+ * @return this
+ */
+ public Builder setSubtitle(@Nullable CharSequence subtitle) {
+ mSubtitle = subtitle;
+ return this;
+ }
+
+ /**
+ * Sets the description.
+ *
+ * @param description A description suitable for display to the user or
+ * null.
+ * @return this
+ */
+ public Builder setDescription(@Nullable CharSequence description) {
+ mDescription = description;
+ return this;
+ }
+
+ /**
+ * Sets the icon.
+ *
+ * @param icon A {@link Bitmap} icon suitable for display to the user or
+ * null.
+ * @return this
+ */
+ public Builder setIconBitmap(@Nullable Bitmap icon) {
+ mIcon = icon;
+ return this;
+ }
+
+ /**
+ * Sets the icon uri.
+ *
+ * @param iconUri A {@link Uri} for an icon suitable for display to the
+ * user or null.
+ * @return this
+ */
+ public Builder setIconUri(@Nullable Uri iconUri) {
+ mIconUri = iconUri;
+ return this;
+ }
+
+ /**
+ * Sets a bundle of extras.
+ *
+ * @param extras The extras to include with this description or null.
+ * @return this
+ */
+ public Builder setExtras(@Nullable Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ public MediaDescription build() {
+ return new MediaDescription(mMediaId, mTitle, mSubtitle, mDescription, mIcon, mIconUri,
+ mExtras);
+ }
+ }
+}
diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java
index 74f7a96..b4e6033 100644
--- a/media/java/android/media/MediaMetadata.java
+++ b/media/java/android/media/MediaMetadata.java
@@ -17,15 +17,22 @@ package android.media;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.browse.MediaBrowser;
+import android.media.session.MediaController;
import android.net.Uri;
import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.OperationCanceledException;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
-import android.text.format.Time;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.Size;
import android.util.SparseArray;
import java.util.Set;
@@ -119,7 +126,9 @@ public final class MediaMetadata implements Parcelable {
public static final String METADATA_KEY_ART = "android.media.metadata.ART";
/**
- * The artwork for the media as a Uri.
+ * The artwork for the media as a Uri formatted String. The artwork can be
+ * loaded using a combination of {@link ContentResolver#openInputStream} and
+ * {@link BitmapFactory#decodeStream}.
*/
public static final String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI";
@@ -130,7 +139,10 @@ public final class MediaMetadata implements Parcelable {
public static final String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART";
/**
- * The artwork for the album of the media's original source as a Uri.
+ * The artwork for the album of the media's original source as a Uri
+ * formatted String. The artwork can be loaded using a combination of
+ * {@link ContentResolver#openInputStream} and
+ * {@link BitmapFactory#decodeStream}.
*/
public static final String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI";
@@ -181,13 +193,26 @@ public final class MediaMetadata implements Parcelable {
= "android.media.metadata.DISPLAY_ICON";
/**
- * An icon or thumbnail that is suitable for display to the user. When
- * displaying more information for media described by this metadata the
- * display description should be preferred to other fields when present.
+ * A Uri formatted String for an icon or thumbnail that is suitable for
+ * display to the user. When displaying more information for media described
+ * by this metadata the display description should be preferred to other
+ * fields when present. The icon can be loaded using a combination of
+ * {@link ContentResolver#openInputStream} and
+ * {@link BitmapFactory#decodeStream}.
*/
public static final String METADATA_KEY_DISPLAY_ICON_URI
= "android.media.metadata.DISPLAY_ICON_URI";
+ /**
+ * A String key for identifying the content. This value is specific to the
+ * service providing the content. If used, this should be a persistent
+ * unique key for the underlying content. It may be used with
+ * {@link MediaController.TransportControls#playFromMediaId(String, Bundle)}
+ * to initiate playback when provided by a {@link MediaBrowser} connected to
+ * the same app.
+ */
+ public static final String METADATA_KEY_MEDIA_ID = "android.media.metadata.MEDIA_ID";
+
private static final String[] PREFERRED_DESCRIPTION_ORDER = {
METADATA_KEY_TITLE,
METADATA_KEY_ARTIST,
@@ -277,7 +302,7 @@ public final class MediaMetadata implements Parcelable {
}
private final Bundle mBundle;
- private Description mDescription;
+ private MediaDescription mDescription;
private MediaMetadata(Bundle bundle) {
mBundle = new Bundle(bundle);
@@ -406,11 +431,13 @@ public final class MediaMetadata implements Parcelable {
*
* @return A simple description of this metadata.
*/
- public @NonNull Description getDescription() {
+ public @NonNull MediaDescription getDescription() {
if (mDescription != null) {
return mDescription;
}
+ String mediaId = getString(METADATA_KEY_MEDIA_ID);
+
CharSequence[] text = new CharSequence[3];
Bitmap icon = null;
Uri iconUri = null;
@@ -454,7 +481,15 @@ public final class MediaMetadata implements Parcelable {
}
}
- mDescription = new Description(text[0], text[1], text[2], icon, iconUri);
+ MediaDescription.Builder bob = new MediaDescription.Builder();
+ bob.setMediaId(mediaId);
+ bob.setTitle(text[0]);
+ bob.setSubtitle(text[1]);
+ bob.setDescription(text[2]);
+ bob.setIconBitmap(icon);
+ bob.setIconUri(iconUri);
+ mDescription = bob.build();
+
return mDescription;
}
@@ -668,90 +703,4 @@ public final class MediaMetadata implements Parcelable {
return new MediaMetadata(mBundle);
}
}
-
- /**
- * A simple form of the metadata that can be used for display.
- */
- public final class Description {
- /**
- * A primary title suitable for display or null.
- */
- private final CharSequence mTitle;
- /**
- * A subtitle suitable for display or null.
- */
- private final CharSequence mSubtitle;
- /**
- * A description suitable for display or null.
- */
- private final CharSequence mDescription;
- /**
- * A bitmap icon suitable for display or null.
- */
- private final Bitmap mIcon;
- /**
- * A Uri for an icon suitable for display or null.
- */
- private final Uri mIconUri;
-
- /**
- * Returns the best available title or null.
- *
- * @return A title or null.
- */
- public @Nullable CharSequence getTitle() {
- return mTitle;
- }
-
- /**
- * Returns the best available subtitle or null.
- *
- * @return A subtitle or null.
- */
- public @Nullable CharSequence getSubtitle() {
- return mSubtitle;
- }
-
- /**
- * Returns the best available description or null.
- *
- * @return A description or null.
- */
- public @Nullable CharSequence getDescription() {
- return mDescription;
- }
-
- /**
- * Returns the best available icon or null.
- *
- * @return An icon or null.
- */
- public @Nullable Bitmap getIcon() {
- return mIcon;
- }
-
- /**
- * Returns the best available icon Uri or null.
- *
- * @return An icon uri or null.
- */
- public @Nullable Uri getIconUri() {
- return mIconUri;
- }
-
- private Description(CharSequence title, CharSequence subtitle, CharSequence description,
- Bitmap icon, Uri iconUri) {
- mTitle = title;
- mSubtitle = subtitle;
- mDescription = description;
- mIcon = icon;
- mIconUri = iconUri;
- }
-
- @Override
- public String toString() {
- return mTitle + ", " + mSubtitle + ", " + mDescription;
- }
- }
-
}
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index 1c6d81f..debaf45 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -16,6 +16,7 @@
package android.media.browse;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
@@ -23,26 +24,27 @@ 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.MediaDescription;
import android.media.session.MediaSession;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.os.RemoteException;
+import android.service.media.MediaBrowserService;
+import android.service.media.IMediaBrowserService;
+import android.service.media.IMediaBrowserServiceCallbacks;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
-import android.util.SparseArray;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
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.Objects;
-import java.util.Set;
/**
* Browses media content offered by a link MediaBrowserService.
@@ -67,8 +69,6 @@ public final class MediaBrowser {
private final Handler mHandler = new Handler();
private final ArrayMap<Uri,Subscription> mSubscriptions =
new ArrayMap<Uri, MediaBrowser.Subscription>();
- private final SparseArray<IconRequest> mIconRequests =
- new SparseArray<IconRequest>();
private int mState = CONNECT_STATE_DISCONNECTED;
private MediaServiceConnection mServiceConnection;
@@ -77,7 +77,6 @@ public final class MediaBrowser {
private Uri mRootUri;
private MediaSession.Token mMediaSessionToken;
private Bundle mExtras;
- private int mNextSeq;
/**
* Creates a media browser for the specified media browse service.
@@ -363,49 +362,6 @@ public final class MediaBrowser {
}
/**
- * Loads the icon of a media item.
- *
- * @param uri The uri of the Icon.
- * @param width The preferred width of the icon in dp.
- * @param height The preferred width of the icon in dp.
- * @param callback The callback to receive the icon.
- */
- public void loadIcon(final @NonNull Uri uri, final int width, final int height,
- final @NonNull IconCallback callback) {
- if (uri == null) {
- throw new IllegalArgumentException("Icon uri cannot be null");
- }
- if (callback == null) {
- throw new IllegalArgumentException("Icon callback cannot be null");
- }
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- for (int i = 0; i < mIconRequests.size(); i++) {
- IconRequest existingRequest = mIconRequests.valueAt(i);
- if (existingRequest.isSameRequest(uri, width, height)) {
- existingRequest.addCallback(callback);
- return;
- }
- }
- final int seq = mNextSeq++;
- IconRequest request = new IconRequest(seq, uri, width, height);
- request.addCallback(callback);
- mIconRequests.put(seq, request);
- if (mState == CONNECT_STATE_CONNECTED) {
- try {
- mServiceBinder.loadIcon(seq, uri, width, height, mServiceCallbacks);
- } catch (RemoteException e) {
- // Process is crashing. We will disconnect, and upon reconnect we will
- // automatically reload the icons. So nothing to do here.
- Log.d(TAG, "loadIcon failed with RemoteException uri=" + uri);
- }
- }
- }
- });
- }
-
- /**
* For debugging.
*/
private static String getStateLabel(int state) {
@@ -461,18 +417,6 @@ public final class MediaBrowser {
Log.d(TAG, "addSubscription failed with RemoteException parentUri=" + uri);
}
}
-
- for (int i = 0; i < mIconRequests.size(); i++) {
- IconRequest request = mIconRequests.valueAt(i);
- try {
- mServiceBinder.loadIcon(request.mSeq, request.mUri,
- request.mWidth, request.mHeight, 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, "loadIcon failed with RemoteException request=" + request);
- }
- }
}
});
}
@@ -515,7 +459,7 @@ public final class MediaBrowser {
return;
}
- List<MediaBrowserItem> data = list.getList();
+ List<MediaItem> data = list.getList();
if (DBG) {
Log.d(TAG, "onLoadChildren for " + mServiceComponent + " uri=" + uri);
}
@@ -539,32 +483,6 @@ public final class MediaBrowser {
});
}
- private final void onLoadIcon(final IMediaBrowserServiceCallbacks callback,
- final int seqNum, 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, "onLoadIcon")) {
- return;
- }
-
- IconRequest request = mIconRequests.get(seqNum);
- if (request == null) {
- Log.d(TAG, "onLoadIcon called for seqNum=" + seqNum + " request="
- + request + " but the request is not registered");
- return;
- }
- mIconRequests.delete(seqNum);
- for (IconCallback IconCallback : request.getCallbacks()) {
- IconCallback.onIconLoaded(request.mUri, bitmap);
- }
- }
- });
- }
-
-
/**
* Return true if {@code callback} is the current ServiceCallbacks. Also logs if it's not.
*/
@@ -600,130 +518,169 @@ public final class MediaBrowser {
Log.d(TAG, " mMediaSessionToken=" + mMediaSessionToken);
}
+ public static class MediaItem implements Parcelable {
+ private final int mFlags;
+ private final MediaDescription mDescription;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag=true, value = { FLAG_BROWSABLE, FLAG_PLAYABLE })
+ public @interface Flags { }
- /**
- * Callbacks for connection related events.
- */
- public static class ConnectionCallback {
/**
- * Invoked after {@link MediaBrowser#connect()} when the request has successfully completed.
+ * Flag: Indicates that the item has children of its own.
*/
- public void onConnected() {
+ public static final int FLAG_BROWSABLE = 1 << 0;
+
+ /**
+ * Flag: Indicates that the item is playable.
+ * <p>
+ * The Uri of this item may be passed to link android.media.session.MediaController#play(Uri)
+ * to start playing it.
+ * </p>
+ */
+ public static final int FLAG_PLAYABLE = 1 << 1;
+
+ /**
+ * Create a new MediaItem for use in browsing media.
+ *
+ * @param flags The flags for this item.
+ * @param description The description of the media, which must include a
+ * media id.
+ */
+ public MediaItem(@Flags int flags, @NonNull MediaDescription description) {
+ if (description == null) {
+ throw new IllegalArgumentException("description cannot be null");
+ }
+ if (TextUtils.isEmpty(description.getMediaId())) {
+ throw new IllegalArgumentException("description must have a non-empty media id");
+ }
+ mFlags = flags;
+ mDescription = description;
}
/**
- * Invoked when the client is disconnected from the media browser.
+ * Private constructor.
*/
- public void onConnectionSuspended() {
+ private MediaItem(Parcel in) {
+ mFlags = in.readInt();
+ mDescription = MediaDescription.CREATOR.createFromParcel(in);
}
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(mFlags);
+ mDescription.writeToParcel(out, flags);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("MediaItem{");
+ sb.append("mFlags=").append(mFlags);
+ sb.append(", mDescription=").append(mDescription);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ public static final Parcelable.Creator<MediaItem> CREATOR =
+ new Parcelable.Creator<MediaItem>() {
+ @Override
+ public MediaItem createFromParcel(Parcel in) {
+ return new MediaItem(in);
+ }
+
+ @Override
+ public MediaItem[] newArray(int size) {
+ return new MediaItem[size];
+ }
+ };
+
/**
- * Invoked when the connection to the media browser failed.
+ * Gets the flags of the item.
*/
- public void onConnectionFailed() {
+ public @Flags int getFlags() {
+ return mFlags;
}
- }
- /**
- * Callbacks for subscription related events.
- */
- public static abstract class SubscriptionCallback {
/**
- * Called when the list of children is loaded or updated.
+ * Returns whether this item is browsable.
+ * @see #FLAG_BROWSABLE
*/
- public void onChildrenLoaded(@NonNull Uri parentUri,
- @NonNull List<MediaBrowserItem> children) {
+ public boolean isBrowsable() {
+ return (mFlags & FLAG_BROWSABLE) != 0;
}
/**
- * Called when the Uri doesn't exist or other errors in subscribing.
- * <p>
- * If this is called, the subscription remains until {@link MediaBrowser#unsubscribe}
- * called, because some errors may heal themselves.
- * </p>
+ * Returns whether this item is playable.
+ * @see #FLAG_PLAYABLE
*/
- public void onError(@NonNull Uri uri) {
+ public boolean isPlayable() {
+ return (mFlags & FLAG_PLAYABLE) != 0;
}
- }
- /**
- * Callbacks for icon loading.
- */
- public static abstract class IconCallback {
/**
- * Called when the icon is loaded.
+ * Returns the description of the media.
*/
- public void onIconLoaded(@NonNull Uri uri, @NonNull Bitmap bitmap) {
+ public @NonNull MediaDescription getDescription() {
+ return mDescription;
}
/**
- * Called when the Uri doesn’t exist or the bitmap cannot be loaded.
+ * Returns the media id for this item.
*/
- public void onError(@NonNull Uri uri) {
+ public @NonNull String getMediaId() {
+ return mDescription.getMediaId();
}
}
- private static class IconRequest {
- final int mSeq;
- final Uri mUri;
- final int mWidth;
- final int mHeight;
- final List<IconCallback> mCallbacks;
+ /**
+ * Callbacks for connection related events.
+ */
+ public static class ConnectionCallback {
/**
- * Constructs an icon request.
- * @param seq The unique sequence number assigned to the request by the media browser.
- * @param uri The Uri for the icon.
- * @param width The width for the icon.
- * @param height The height for the icon.
+ * Invoked after {@link MediaBrowser#connect()} when the request has successfully completed.
*/
- IconRequest(int seq, @NonNull Uri uri, int width, int height) {
- if (uri == null) {
- throw new IllegalArgumentException("Icon uri cannot be null");
- }
- this.mSeq = seq;
- this.mUri = uri;
- this.mWidth = width;
- this.mHeight = height;
- mCallbacks = new ArrayList<IconCallback>();
+ public void onConnected() {
}
/**
- * Adds a callback to the icon request.
- * If the callback already exists, it will not be added again.
+ * Invoked when the client is disconnected from the media browser.
*/
- public void addCallback(@NonNull IconCallback callback) {
- if (callback == null) {
- throw new IllegalArgumentException("callback cannot be null in IconRequest");
- }
- if (!mCallbacks.contains(callback)) {
- mCallbacks.add(callback);
- }
+ public void onConnectionSuspended() {
}
/**
- * Checks if the icon request has the same uri, width, and height as the given values.
+ * Invoked when the connection to the media browser failed.
*/
- public boolean isSameRequest(@Nullable Uri uri, int width, int height) {
- return Objects.equals(mUri, uri) && mWidth == width && mHeight == height;
+ public void onConnectionFailed() {
}
+ }
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder("IconRequest{");
- sb.append("uri=").append(mUri);
- sb.append(", width=").append(mWidth);
- sb.append(", height=").append(mHeight);
- sb.append(", seq=").append(mSeq);
- sb.append('}');
- return sb.toString();
+ /**
+ * Callbacks for subscription related events.
+ */
+ public static abstract class SubscriptionCallback {
+ /**
+ * Called when the list of children is loaded or updated.
+ */
+ public void onChildrenLoaded(@NonNull Uri parentUri,
+ @NonNull List<MediaItem> children) {
}
/**
- * Gets an unmodifiable view of the list of callbacks associated with the request.
+ * Called when the Uri doesn't exist or other errors in subscribing.
+ * <p>
+ * If this is called, the subscription remains until {@link MediaBrowser#unsubscribe}
+ * called, because some errors may heal themselves.
+ * </p>
*/
- public List<IconCallback> getCallbacks() {
- return Collections.unmodifiableList(mCallbacks);
+ public void onError(@NonNull Uri uri) {
}
}
@@ -809,7 +766,7 @@ public final class MediaBrowser {
}
return true;
}
- };
+ }
/**
* Callbacks from the service.
@@ -852,14 +809,6 @@ public final class MediaBrowser {
mediaBrowser.onLoadChildren(this, uri, list);
}
}
-
- @Override
- public void onLoadIcon(final int seqNum, final Bitmap bitmap) {
- MediaBrowser mediaBrowser = mMediaBrowser.get();
- if (mediaBrowser != null) {
- mediaBrowser.onLoadIcon(this, seqNum, bitmap);
- }
- }
}
private static class Subscription {
diff --git a/media/java/android/media/browse/MediaBrowserItem.java b/media/java/android/media/browse/MediaBrowserItem.java
deleted file mode 100644
index 47ec46b..0000000
--- a/media/java/android/media/browse/MediaBrowserItem.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.browse;
-
-import android.annotation.DrawableRes;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.net.Uri;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Describes a media item in the list of items offered by a {@link MediaBrowserService}.
- */
-public final class MediaBrowserItem implements Parcelable {
- private final Uri mUri;
- private final int mFlags;
- private final CharSequence mTitle;
- private final CharSequence mSummary;
- private final Uri mIconUri;
- private final int mIconResourceId;
- private final Bundle mExtras;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag=true, value = { FLAG_BROWSABLE, FLAG_PLAYABLE })
- public @interface Flags { }
-
- /**
- * Flag: Indicates that the item has children of its own.
- */
- public static final int FLAG_BROWSABLE = 1 << 0;
-
- /**
- * Flag: Indicates that the item is playable.
- * <p>
- * The Uri of this item may be passed to link android.media.session.MediaController#play(Uri)
- * to start playing it.
- * </p>
- */
- public static final int FLAG_PLAYABLE = 1 << 1;
-
- /**
- * Initialize a MediaBrowserItem object.
- */
- private MediaBrowserItem(@NonNull Uri uri, int flags, @NonNull CharSequence title,
- CharSequence summary, @Nullable Uri iconUri, int iconResourceId, Bundle extras) {
- if (uri == null) {
- throw new IllegalArgumentException("uri can not be null");
- }
- if (title == null) {
- throw new IllegalArgumentException("title can not be null");
- }
- mUri = uri;
- mFlags = flags;
- mTitle = title;
- mSummary = summary;
- mIconUri = iconUri;
- mIconResourceId = iconResourceId;
- mExtras = extras;
- }
-
- /**
- * Private constructor.
- */
- private MediaBrowserItem(Parcel in) {
- mUri = Uri.CREATOR.createFromParcel(in);
- mFlags = in.readInt();
- mTitle = in.readCharSequence();
- if (in.readInt() != 0) {
- mSummary = in.readCharSequence();
- } else {
- mSummary = null;
- }
- if (in.readInt() != 0) {
- mIconUri = Uri.CREATOR.createFromParcel(in);
- } else {
- mIconUri = null;
- }
- mIconResourceId = in.readInt();
- if (in.readInt() != 0) {
- mExtras = Bundle.CREATOR.createFromParcel(in);
- } else {
- mExtras = null;
- }
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- mUri.writeToParcel(out, flags);
- out.writeInt(mFlags);
- out.writeCharSequence(mTitle);
- if (mSummary != null) {
- out.writeInt(1);
- out.writeCharSequence(mSummary);
- } else {
- out.writeInt(0);
- }
- if (mIconUri != null) {
- out.writeInt(1);
- mIconUri.writeToParcel(out, flags);
- } else {
- out.writeInt(0);
- }
- out.writeInt(mIconResourceId);
- if (mExtras != null) {
- out.writeInt(1);
- mExtras.writeToParcel(out, flags);
- } else {
- out.writeInt(0);
- }
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder("MediaBrowserItem{");
- sb.append("mUri=").append(mUri);
- sb.append(", mFlags=").append(mFlags);
- sb.append(", mTitle=").append(mTitle);
- sb.append(", mSummary=").append(mSummary);
- sb.append(", mIconUri=").append(mIconUri);
- sb.append(", mIconResourceId=").append(mIconResourceId);
- sb.append('}');
- return sb.toString();
- }
-
- public static final Parcelable.Creator<MediaBrowserItem> CREATOR =
- new Parcelable.Creator<MediaBrowserItem>() {
- @Override
- public MediaBrowserItem createFromParcel(Parcel in) {
- return new MediaBrowserItem(in);
- }
-
- @Override
- public MediaBrowserItem[] newArray(int size) {
- return new MediaBrowserItem[size];
- }
- };
-
- /**
- * Gets the Uri of the item.
- */
- public @NonNull Uri getUri() {
- return mUri;
- }
-
- /**
- * Gets the flags of the item.
- */
- public @Flags int getFlags() {
- return mFlags;
- }
-
- /**
- * Returns whether this item is browsable.
- * @see #FLAG_BROWSABLE
- */
- public boolean isBrowsable() {
- return (mFlags & FLAG_BROWSABLE) != 0;
- }
-
- /**
- * Returns whether this item is playable.
- * @see #FLAG_PLAYABLE
- */
- public boolean isPlayable() {
- return (mFlags & FLAG_PLAYABLE) != 0;
- }
-
- /**
- * Gets the title of the item.
- * @more
- * The title will be shown as the first line of text when
- * describing each item to the user.
- */
- public @NonNull CharSequence getTitle() {
- return mTitle;
- }
-
- /**
- * Gets summary of the item, or null if none.
- * @more
- * The summary will be shown as the second line of text when
- * describing each item to the user.
- */
- public @Nullable CharSequence getSummary() {
- return mSummary;
- }
-
- /**
- * Gets the Uri of the icon.
- */
- public @Nullable Uri getIconUri() {
- return mIconUri;
- }
-
- /**
- * Gets the resource id of the icon.
- */
- public @DrawableRes int getIconResourceId() {
- return mIconResourceId;
- }
-
- /**
- * Gets additional service-specified extras about the
- * item or its content, or null if none.
- */
- public @Nullable Bundle getExtras() {
- return mExtras;
- }
-
- /**
- * Builder for {@link MediaBrowserItem} objects.
- */
- public static final class Builder {
- private final Uri mUri;
- private final int mFlags;
- private final CharSequence mTitle;
- private CharSequence mSummary;
- private Uri mIconUri;
- private int mIconResourceId;
- private Bundle mExtras;
-
- /**
- * Creates an item builder.
- */
- public Builder(@NonNull Uri uri, @Flags int flags, @NonNull CharSequence title) {
- if (uri == null) {
- throw new IllegalArgumentException("uri can not be null");
- }
- if (title == null) {
- throw new IllegalArgumentException("title can not be null");
- }
- mUri = uri;
- mFlags = flags;
- mTitle = title;
- }
-
- /**
- * Sets summary of the item, or null if none.
- */
- public @NonNull Builder setSummary(@Nullable CharSequence summary) {
- mSummary = summary;
- return this;
- }
-
- /**
- * Sets the uri of the icon.
- * <p>
- * Either {@link #setIconUri(Uri)} or {@link #setIconResourceId(int)} should be called.
- * If both are specified, 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.
- * <p>
- * Either {@link #setIconUri(Uri)} or {@link #setIconResourceId(int)} should be specified.
- * If both are specified, the resource id will be used to load the icon.
- * </p>
- */
- public @NonNull Builder setIconResourceId(@DrawableRes int ResourceId) {
- mIconResourceId = ResourceId;
- return this;
- }
-
- /**
- * Sets additional service-specified extras about the
- * item or its content.
- */
- public @NonNull Builder setExtras(@Nullable Bundle extras) {
- mExtras = extras;
- return this;
- }
-
- /**
- * Builds the item.
- */
- public @NonNull MediaBrowserItem build() {
- return new MediaBrowserItem(mUri, mFlags, mTitle, mSummary, mIconUri,
- mIconResourceId, mExtras);
- }
- }
-}
-
diff --git a/media/java/android/media/session/ISessionCallback.aidl b/media/java/android/media/session/ISessionCallback.aidl
index 9911129..49087b0 100644
--- a/media/java/android/media/session/ISessionCallback.aidl
+++ b/media/java/android/media/session/ISessionCallback.aidl
@@ -30,7 +30,7 @@ oneway interface ISessionCallback {
// These callbacks are for the TransportPerformer
void onPlay();
- void onPlayUri(in Uri uri, in Bundle extras);
+ void onPlayFromMediaId(String uri, in Bundle extras);
void onPlayFromSearch(String query, in Bundle extras);
void onSkipToTrack(long id);
void onPause();
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index 6b80477..d684688 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -51,9 +51,9 @@ interface ISessionController {
// These commands are for the TransportControls
void play();
- void playUri(in Uri uri, in Bundle extras);
+ void playFromMediaId(String uri, in Bundle extras);
void playFromSearch(String string, in Bundle extras);
- void skipToTrack(long id);
+ void skipToQueueItem(long id);
void pause();
void stop();
void next();
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index d7baaa9..9641f83 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -173,7 +173,7 @@ public final class MediaController {
*
* @return The current play queue or null.
*/
- public @Nullable List<MediaSession.Item> getQueue() {
+ public @Nullable List<MediaSession.QueueItem> getQueue() {
try {
ParceledListSlice queue = mSessionBinder.getQueue();
if (queue != null) {
@@ -538,9 +538,9 @@ public final class MediaController {
* @param queue A list of items in the current play queue. It should
* include the currently playing item as well as previous and
* upcoming items if applicable.
- * @see MediaSession.Item
+ * @see MediaSession.QueueItem
*/
- public void onQueueChanged(@Nullable List<MediaSession.Item> queue) {
+ public void onQueueChanged(@Nullable List<MediaSession.QueueItem> queue) {
}
/**
@@ -594,18 +594,19 @@ public final class MediaController {
/**
* Request that the player start playback for a specific {@link Uri}.
*
- * @param uri The uri of the requested media.
+ * @param mediaId The uri of the requested media.
* @param extras Optional extras that can include extra information about the media item
* to be played.
*/
- public void playUri(Uri uri, Bundle extras) {
- if (uri == null) {
- throw new IllegalArgumentException("You must specify a non-null Uri for playUri.");
+ public void playFromMediaId(String mediaId, Bundle extras) {
+ if (TextUtils.isEmpty(mediaId)) {
+ throw new IllegalArgumentException(
+ "You must specify a non-empty String for playFromMediaId.");
}
try {
- mSessionBinder.playUri(uri, extras);
+ mSessionBinder.playFromMediaId(mediaId, extras);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling play(" + uri + ").", e);
+ Log.wtf(TAG, "Error calling play(" + mediaId + ").", e);
}
}
@@ -631,9 +632,9 @@ public final class MediaController {
* Play an item with a specific id in the play queue. If you specify an
* id that is not in the play queue, the behavior is undefined.
*/
- public void skipToItem(long id) {
+ public void skipToQueueItem(long id) {
try {
- mSessionBinder.skipToTrack(id);
+ mSessionBinder.skipToQueueItem(id);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling skipToItem(" + id + ").", e);
}
@@ -904,7 +905,7 @@ public final class MediaController {
@Override
public void onQueueChanged(ParceledListSlice parceledQueue) {
- List<MediaSession.Item> queue = parceledQueue.getList();
+ List<MediaSession.QueueItem> queue = parceledQueue.getList();
MediaController controller = mController.get();
if (controller != null) {
controller.postMessage(MSG_UPDATE_QUEUE, queue, null);
@@ -960,7 +961,7 @@ public final class MediaController {
mCallback.onMetadataChanged((MediaMetadata) msg.obj);
break;
case MSG_UPDATE_QUEUE:
- mCallback.onQueueChanged((List<MediaSession.Item>) msg.obj);
+ mCallback.onQueueChanged((List<MediaSession.QueueItem>) msg.obj);
break;
case MSG_UPDATE_QUEUE_TITLE:
mCallback.onQueueTitleChanged((CharSequence) msg.obj);
diff --git a/media/java/android/media/session/MediaSession.aidl b/media/java/android/media/session/MediaSession.aidl
index 0ad58c4..f657cef 100644
--- a/media/java/android/media/session/MediaSession.aidl
+++ b/media/java/android/media/session/MediaSession.aidl
@@ -16,4 +16,4 @@
package android.media.session;
parcelable MediaSession.Token;
-parcelable MediaSession.Track; \ No newline at end of file
+parcelable MediaSession.QueueItem; \ No newline at end of file
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 0bbdc59..711831b 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -25,6 +25,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes;
+import android.media.MediaDescription;
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.VolumeProvider;
@@ -38,6 +39,7 @@ import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.UserHandle;
+import android.service.media.MediaBrowserService;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
@@ -426,9 +428,9 @@ public final class MediaSession {
*
* @param queue A list of items in the play queue.
*/
- public void setQueue(@Nullable List<Item> queue) {
+ public void setQueue(@Nullable List<QueueItem> queue) {
try {
- mBinder.setQueue(new ParceledListSlice<Item>(queue));
+ mBinder.setQueue(new ParceledListSlice<QueueItem>(queue));
} catch (RemoteException e) {
Log.wtf("Dead object in setQueue.", e);
}
@@ -486,8 +488,8 @@ public final class MediaSession {
postToCallback(CallbackMessageHandler.MSG_PLAY);
}
- private void dispatchPlayUri(Uri uri, Bundle extras) {
- postToCallback(CallbackMessageHandler.MSG_PLAY_URI, uri, extras);
+ private void dispatchPlayFromMediaId(String mediaId, Bundle extras) {
+ postToCallback(CallbackMessageHandler.MSG_PLAY_MEDIA_ID, mediaId, extras);
}
private void dispatchPlayFromSearch(String query, Bundle extras) {
@@ -752,9 +754,10 @@ public final class MediaSession {
}
/**
- * Override to handle requests to play a specific {@link Uri}.
+ * Override to handle requests to play a specific mediaId that was
+ * provided by your app's {@link MediaBrowserService}.
*/
- public void onPlayUri(Uri uri, Bundle extras) {
+ public void onPlayFromMediaId(String mediaId, Bundle extras) {
}
/**
@@ -767,7 +770,7 @@ public final class MediaSession {
* Override to handle requests to play an item with a given id from the
* play queue.
*/
- public void onSkipToItem(long id) {
+ public void onSkipToQueueItem(long id) {
}
/**
@@ -876,10 +879,10 @@ public final class MediaSession {
}
@Override
- public void onPlayUri(Uri uri, Bundle extras) {
+ public void onPlayFromMediaId(String mediaId, Bundle extras) {
MediaSession session = mMediaSession.get();
if (session != null) {
- session.dispatchPlayUri(uri, extras);
+ session.dispatchPlayFromMediaId(mediaId, extras);
}
}
@@ -994,125 +997,59 @@ public final class MediaSession {
}
/**
- * A single item that is part of the play queue. It contains information
- * necessary to display a single item in the queue.
+ * A single item that is part of the play queue. It contains a description
+ * of the item and its id in the queue.
*/
- public static final class Item implements Parcelable {
+ public static final class QueueItem implements Parcelable {
/**
* This id is reserved. No items can be explicitly asigned this id.
*/
public static final int UNKNOWN_ID = -1;
- private final MediaMetadata mMetadata;
+ private final MediaDescription mDescription;
private final long mId;
- private final Uri mUri;
- private final Bundle mExtras;
/**
- * Create a new {@link MediaSession.Item}.
+ * Create a new {@link MediaSession.QueueItem}.
*
- * @param metadata The metadata for this item.
+ * @param description The {@link MediaDescription} for this item.
* @param id An identifier for this item. It must be unique within the
- * play queue.
- * @param uri The uri for this item.
- * @param extras A bundle of extras that can be used to add extra
- * information about this item.
+ * play queue and cannot be {@link #UNKNOWN_ID}.
*/
- private Item(MediaMetadata metadata, long id, Uri uri, Bundle extras) {
- mMetadata = metadata;
+ public QueueItem(MediaDescription description, long id) {
+ if (description == null) {
+ throw new IllegalArgumentException("Description cannot be null.");
+ }
+ if (id == UNKNOWN_ID) {
+ throw new IllegalArgumentException("Id cannot be QueueItem.UNKNOWN_ID");
+ }
+ mDescription = description;
mId = id;
- mUri = uri;
- mExtras = extras;
}
- private Item(Parcel in) {
- mMetadata = MediaMetadata.CREATOR.createFromParcel(in);
+ private QueueItem(Parcel in) {
+ mDescription = MediaDescription.CREATOR.createFromParcel(in);
mId = in.readLong();
- mUri = Uri.CREATOR.createFromParcel(in);
- mExtras = in.readBundle();
}
/**
- * Get the metadata for this item.
+ * Get the description for this item.
*/
- public MediaMetadata getMetadata() {
- return mMetadata;
+ public MediaDescription getDescription() {
+ return mDescription;
}
/**
- * Get the id for this item.
+ * Get the queue id for this item.
*/
- public long getId() {
+ public long getQueueId() {
return mId;
}
- /**
- * Get the Uri for this item.
- */
- public Uri getUri() {
- return mUri;
- }
-
- /**
- * Get the extras for this item.
- */
- public Bundle getExtras() {
- return mExtras;
- }
-
- /**
- * Builder for {@link MediaSession.Item} objects.
- */
- public static final class Builder {
- private final MediaMetadata mMetadata;
- private final long mId;
- private final Uri mUri;
-
- private Bundle mExtras;
-
- /**
- * Create a builder with the metadata, id, and uri already set.
- */
- public Builder(MediaMetadata metadata, long id, Uri uri) {
- if (metadata == null) {
- throw new IllegalArgumentException(
- "You must specify a non-null MediaMetadata to build an Item.");
- }
- if (uri == null) {
- throw new IllegalArgumentException(
- "You must specify a non-null Uri to build an Item.");
- }
- if (id == UNKNOWN_ID) {
- throw new IllegalArgumentException(
- "You must specify an id other than UNKNOWN_ID to build an Item.");
- }
- mMetadata = metadata;
- mId = id;
- mUri = uri;
- }
-
- /**
- * Set optional extras for the item.
- */
- public MediaSession.Item.Builder setExtras(Bundle extras) {
- mExtras = extras;
- return this;
- }
-
- /**
- * Create the {@link Item}.
- */
- public MediaSession.Item build() {
- return new MediaSession.Item(mMetadata, mId, mUri, mExtras);
- }
- }
-
@Override
public void writeToParcel(Parcel dest, int flags) {
- mMetadata.writeToParcel(dest, flags);
+ mDescription.writeToParcel(dest, flags);
dest.writeLong(mId);
- mUri.writeToParcel(dest, flags);
- dest.writeBundle(mExtras);
}
@Override
@@ -1120,28 +1057,24 @@ public final class MediaSession {
return 0;
}
- public static final Creator<MediaSession.Item> CREATOR
- = new Creator<MediaSession.Item>() {
+ public static final Creator<MediaSession.QueueItem> CREATOR = new Creator<MediaSession.QueueItem>() {
@Override
- public MediaSession.Item createFromParcel(Parcel p) {
- return new MediaSession.Item(p);
+ public MediaSession.QueueItem createFromParcel(Parcel p) {
+ return new MediaSession.QueueItem(p);
}
@Override
- public MediaSession.Item[] newArray(int size) {
- return new MediaSession.Item[size];
+ public MediaSession.QueueItem[] newArray(int size) {
+ return new MediaSession.QueueItem[size];
}
};
@Override
public String toString() {
- return "MediaSession.Item {" +
- "Metadata=" + mMetadata +
- ", Id=" + mId +
- ", Uri=" + mUri +
- ", Extras=" + mExtras +
- " }";
+ return "MediaSession.QueueItem {" +
+ "Description=" + mDescription +
+ ", Id=" + mId + " }";
}
}
@@ -1160,7 +1093,7 @@ public final class MediaSession {
private class CallbackMessageHandler extends Handler {
private static final int MSG_PLAY = 1;
- private static final int MSG_PLAY_URI = 2;
+ private static final int MSG_PLAY_MEDIA_ID = 2;
private static final int MSG_PLAY_SEARCH = 3;
private static final int MSG_SKIP_TO_ITEM = 4;
private static final int MSG_PAUSE = 5;
@@ -1206,14 +1139,14 @@ public final class MediaSession {
case MSG_PLAY:
mCallback.onPlay();
break;
- case MSG_PLAY_URI:
- mCallback.onPlayUri((Uri) msg.obj, msg.getData());
+ case MSG_PLAY_MEDIA_ID:
+ mCallback.onPlayFromMediaId((String) msg.obj, msg.getData());
break;
case MSG_PLAY_SEARCH:
mCallback.onPlayFromSearch((String) msg.obj, msg.getData());
break;
case MSG_SKIP_TO_ITEM:
- mCallback.onSkipToItem((Long) msg.obj);
+ mCallback.onSkipToQueueItem((Long) msg.obj);
case MSG_PAUSE:
mCallback.onPause();
break;
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index 2ca97dd..267d1ff 100644
--- a/media/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
@@ -36,95 +36,95 @@ public final class PlaybackState implements Parcelable {
private static final String TAG = "PlaybackState";
/**
- * Indicates this performer supports the stop command.
+ * Indicates this session supports the stop command.
*
* @see Builder#setActions(long)
*/
public static final long ACTION_STOP = 1 << 0;
/**
- * Indicates this performer supports the pause command.
+ * Indicates this session supports the pause command.
*
* @see Builder#setActions(long)
*/
public static final long ACTION_PAUSE = 1 << 1;
/**
- * Indicates this performer supports the play command.
+ * Indicates this session supports the play command.
*
* @see Builder#setActions(long)
*/
public static final long ACTION_PLAY = 1 << 2;
/**
- * Indicates this performer supports the rewind command.
+ * Indicates this session supports the rewind command.
*
* @see Builder#setActions(long)
*/
public static final long ACTION_REWIND = 1 << 3;
/**
- * Indicates this performer supports the previous command.
+ * Indicates this session supports the previous command.
*
* @see Builder#setActions(long)
*/
public static final long ACTION_SKIP_TO_PREVIOUS = 1 << 4;
/**
- * Indicates this performer supports the next command.
+ * Indicates this session supports the next command.
*
* @see Builder#setActions(long)
*/
public static final long ACTION_SKIP_TO_NEXT = 1 << 5;
/**
- * Indicates this performer supports the fast forward command.
+ * Indicates this session supports the fast forward command.
*
* @see Builder#setActions(long)
*/
public static final long ACTION_FAST_FORWARD = 1 << 6;
/**
- * Indicates this performer supports the set rating command.
+ * Indicates this session supports the set rating command.
*
* @see Builder#setActions(long)
*/
public static final long ACTION_SET_RATING = 1 << 7;
/**
- * Indicates this performer supports the seek to command.
+ * Indicates this session supports the seek to command.
*
* @see Builder#setActions(long)
*/
public static final long ACTION_SEEK_TO = 1 << 8;
/**
- * Indicates this performer supports the play/pause toggle command.
+ * Indicates this session supports the play/pause toggle command.
*
* @see Builder#setActions(long)
*/
public static final long ACTION_PLAY_PAUSE = 1 << 9;
/**
- * Indicates this performer supports the play from uri command.
+ * Indicates this session supports the play from media id command.
*
* @see Builder#setActions(long)
*/
- public static final long ACTION_PLAY_URI = 1 << 10;
+ public static final long ACTION_PLAY_FROM_MEDIA_ID = 1 << 10;
/**
- * Indicates this performer supports the play from search command.
+ * Indicates this session supports the play from search command.
*
* @see Builder#setActions(long)
*/
public static final long ACTION_PLAY_FROM_SEARCH = 1 << 11;
/**
- * Indicates this performer supports the skip to item command.
+ * Indicates this session supports the skip to queue item command.
*
* @see Builder#setActions(long)
*/
- public static final long ACTION_SKIP_TO_ITEM = 1 << 12;
+ public static final long ACTION_SKIP_TO_QUEUE_ITEM = 1 << 12;
/**
* This is the default playback state and indicates that no media has been
@@ -211,6 +211,14 @@ public final class PlaybackState implements Parcelable {
public final static int STATE_SKIPPING_TO_NEXT = 10;
/**
+ * State indicating the player is currently skipping to a specific item in
+ * the queue.
+ *
+ * @see Builder#setState
+ */
+ public final static int STATE_SKIPPING_TO_QUEUE_ITEM = 11;
+
+ /**
* Use this value for the position to indicate the position is not known.
*/
public final static long PLAYBACK_POSITION_UNKNOWN = -1;
@@ -374,6 +382,18 @@ public final class PlaybackState implements Parcelable {
}
/**
+ * Get the id of the currently active item in the queue. If there is no
+ * queue or a queue is not supported by the session this will be
+ * {@link MediaSession.QueueItem#UNKNOWN_ID}.
+ *
+ * @return The id of the currently active item in the queue or
+ * {@link MediaSession.QueueItem#UNKNOWN_ID}.
+ */
+ public long getActiveQueueItemId() {
+ return mActiveItemId;
+ }
+
+ /**
* Get the {@link PlaybackState} state for the given
* {@link RemoteControlClient} state.
*
@@ -716,7 +736,7 @@ public final class PlaybackState implements Parcelable {
private long mActions;
private CharSequence mErrorMessage;
private long mUpdateTime;
- private long mActiveItemId = MediaSession.Item.UNKNOWN_ID;
+ private long mActiveItemId = MediaSession.QueueItem.UNKNOWN_ID;
/**
* Creates an initially empty state builder.
@@ -904,12 +924,12 @@ public final class PlaybackState implements Parcelable {
/**
* Set the active item in the play queue by specifying its id. The
- * default value is {@link MediaSession.Item#UNKNOWN_ID}
+ * default value is {@link MediaSession.QueueItem#UNKNOWN_ID}
*
* @param id The id of the active item.
* @return this
*/
- public Builder setActiveItem(long id) {
+ public Builder setActiveQueueItemId(long id) {
mActiveItemId = id;
return this;
}
diff --git a/media/java/android/media/browse/IMediaBrowserService.aidl b/media/java/android/service/media/IMediaBrowserService.aidl
index 8acd724..2631ddd 100644
--- a/media/java/android/media/browse/IMediaBrowserService.aidl
+++ b/media/java/android/service/media/IMediaBrowserService.aidl
@@ -1,9 +1,9 @@
// Copyright 2014 Google Inc. All Rights Reserved.
-package android.media.browse;
+package android.service.media;
import android.content.res.Configuration;
-import android.media.browse.IMediaBrowserServiceCallbacks;
+import android.service.media.IMediaBrowserServiceCallbacks;
import android.net.Uri;
import android.os.Bundle;
@@ -18,6 +18,4 @@ oneway interface IMediaBrowserService {
void addSubscription(in Uri uri, IMediaBrowserServiceCallbacks callbacks);
void removeSubscription(in Uri uri, IMediaBrowserServiceCallbacks callbacks);
- void loadIcon(in int seqNum, in Uri uri, int width, int height,
- IMediaBrowserServiceCallbacks callbacks);
} \ No newline at end of file
diff --git a/media/java/android/media/browse/IMediaBrowserServiceCallbacks.aidl b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
index 06fabcc..7702a50 100644
--- a/media/java/android/media/browse/IMediaBrowserServiceCallbacks.aidl
+++ b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
@@ -1,6 +1,6 @@
// Copyright 2014 Google Inc. All Rights Reserved.
-package android.media.browse;
+package android.service.media;
import android.content.pm.ParceledListSlice;
import android.graphics.Bitmap;
@@ -24,5 +24,4 @@ oneway interface IMediaBrowserServiceCallbacks {
void onConnect(in Uri root, in MediaSession.Token session, in Bundle extras);
void onConnectFailed();
void onLoadChildren(in Uri uri, in ParceledListSlice list);
- void onLoadIcon(int seqNum, in Bitmap bitmap);
}
diff --git a/media/java/android/media/browse/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java
index 99126c9..4d6fd7b 100644
--- a/media/java/android/media/browse/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.media.browse;
+package android.service.media;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -27,6 +27,8 @@ import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.res.Configuration;
import android.graphics.Bitmap;
+import android.media.browse.MediaBrowser;
+import android.media.browse.MediaBrowser.MediaItem;
import android.media.session.MediaSession;
import android.net.Uri;
import android.os.Binder;
@@ -34,6 +36,9 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.Handler;
import android.os.RemoteException;
+import android.service.media.IMediaBrowserService;
+import android.service.media.IMediaBrowserServiceCallbacks;
+import android.service.media.IMediaBrowserService.Stub;
import android.util.ArrayMap;
import android.util.Log;
@@ -264,59 +269,6 @@ public abstract class MediaBrowserService extends Service {
}
});
}
-
- @Override
- public void loadIcon(final int seq, final Uri uri, final int width, final int height,
- final IMediaBrowserServiceCallbacks callbacks) {
- if (uri == null) {
- throw new IllegalStateException("loadIcon sent null list for uri " + uri);
- }
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- // In theory we could return a result to a new connection, but in practice
- // the other side in MediaBrowser uses a new IMediaBrowserServiceCallbacks
- // object every time it calls connect(), so as long as it does that we won't
- // see results sent for the wrong connection.
- final ConnectionRecord connection = mConnections.get(callbacks.asBinder());
- if (connection == null) {
- if (DBG) {
- Log.d(TAG, "Not loading bitmap for invalid connection. uri=" + uri);
- }
- return;
- }
-
- final Result<Bitmap> result = new Result<Bitmap>(uri) {
- @Override
- void onResultSent(Bitmap bitmap) {
- if (mConnections.get(connection.callbacks.asBinder()) != connection) {
- if (DBG) {
- Log.d(TAG, "Not sending onLoadIcon result for connection"
- + " that has been disconnected. pkg=" + connection.pkg
- + " uri=" + uri);
- }
- return;
- }
-
- try {
- callbacks.onLoadIcon(seq, bitmap);
- } catch (RemoteException e) {
- // The other side is in the process of crashing.
- Log.w(TAG, "RemoteException in calling onLoadIcon", e);
- }
- }
- };
-
- onLoadIcon(uri, width, height, result);
-
- if (!result.isDone()) {
- throw new IllegalStateException("onLoadIcon must call detach() or"
- + " sendResult() before returning for package=" + connection.pkg
- + " uri=" + uri);
- }
- }
- });
- }
}
@Override
@@ -372,26 +324,7 @@ public abstract class MediaBrowserService extends Service {
* @return The list of children, or null if the uri is invalid.
*/
public abstract void onLoadChildren(@NonNull Uri parentUri,
- @NonNull Result<List<MediaBrowserItem>> result);
-
- /**
- * Called to get the icon of a particular media item.
- * <p>
- * Implementations must call result.{@link Result#sendResult result.sendResult} with the bitmap.
- * If loading the bitmap 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.
- *
- * @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.
- *
- * @return The file descriptor of the icon, which may then be loaded
- * using a bitmap factory, or null if the item does not have an icon.
- */
- public abstract void onLoadIcon(@NonNull Uri uri, int width, int height,
- @NonNull Result<Bitmap> result);
+ @NonNull Result<List<MediaBrowser.MediaItem>> result);
/**
* Call to set the media session.
@@ -478,9 +411,11 @@ public abstract class MediaBrowserService extends Service {
* Callers must make sure that this connection is still connected.
*/
private void performLoadChildren(final Uri uri, final ConnectionRecord connection) {
- final Result<List<MediaBrowserItem>> result = new Result<List<MediaBrowserItem>>(uri) {
+ final Result<List<MediaBrowser.MediaItem>> result
+ = new Result<List<MediaBrowser.MediaItem>>(
+ uri) {
@Override
- void onResultSent(List<MediaBrowserItem> list) {
+ void onResultSent(List<MediaBrowser.MediaItem> list) {
if (list == null) {
throw new IllegalStateException("onLoadChildren sent null list for uri " + uri);
}
@@ -492,7 +427,7 @@ public abstract class MediaBrowserService extends Service {
return;
}
- final ParceledListSlice<MediaBrowserItem> pls = new ParceledListSlice(list);
+ final ParceledListSlice<MediaBrowser.MediaItem> pls = new ParceledListSlice(list);
try {
connection.callbacks.onLoadChildren(uri, pls);
} catch (RemoteException ex) {
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 978a9f4..0da2cfa 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -23,6 +23,7 @@ import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.media.AudioManager;
import android.media.AudioManagerInternal;
+import android.media.MediaDescription;
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.VolumeProvider;
@@ -441,7 +442,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
private String getShortMetadataString() {
int fields = mMetadata == null ? 0 : mMetadata.size();
- MediaMetadata.Description description = mMetadata == null ? null : mMetadata
+ MediaDescription description = mMetadata == null ? null : mMetadata
.getDescription();
return "size=" + fields + ", description=" + description;
}
@@ -820,9 +821,9 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
}
}
- public void playUri(Uri uri, Bundle extras) {
+ public void playFromMediaId(String mediaId, Bundle extras) {
try {
- mCb.onPlayUri(uri, extras);
+ mCb.onPlayFromMediaId(mediaId, extras);
} catch (RemoteException e) {
Slog.e(TAG, "Remote failure in playUri.", e);
}
@@ -1042,8 +1043,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
}
@Override
- public void playUri(Uri uri, Bundle extras) throws RemoteException {
- mSessionCb.playUri(uri, extras);
+ public void playFromMediaId(String mediaId, Bundle extras) throws RemoteException {
+ mSessionCb.playFromMediaId(mediaId, extras);
}
@Override
@@ -1052,7 +1053,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
}
@Override
- public void skipToTrack(long id) {
+ public void skipToQueueItem(long id) {
mSessionCb.skipToTrack(id);
}
diff --git a/tests/OneMedia/src/com/android/onemedia/NotificationHelper.java b/tests/OneMedia/src/com/android/onemedia/NotificationHelper.java
index a5bcda5..d1172ac 100644
--- a/tests/OneMedia/src/com/android/onemedia/NotificationHelper.java
+++ b/tests/OneMedia/src/com/android/onemedia/NotificationHelper.java
@@ -12,6 +12,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
+import android.media.MediaDescription;
import android.media.MediaMetadata;
import android.media.session.MediaController;
import android.media.session.MediaSession;
@@ -185,10 +186,10 @@ public class NotificationHelper extends BroadcastReceiver {
text = "Empty metadata!";
art = null;
} else {
- MediaMetadata.Description description = mMetadata.getDescription();
+ MediaDescription description = mMetadata.getDescription();
title = description.getTitle();
text = description.getSubtitle();
- art = description.getIcon();
+ art = description.getIconBitmap();
}
String playPauseLabel = "";