MediaCompat migration
Gets MediaControllerCompat from Token obtained via MediaSessionManager
Bug: 4985903
Test: Manual, Robolectric tests
Change-Id: I21847f3ed3abb8987cbd092c9cbcb8b2ba609a5b
diff --git a/car-media-common/src/com/android/car/media/common/MediaItemMetadata.java b/car-media-common/src/com/android/car/media/common/MediaItemMetadata.java
index 71dd7a2..08867a8 100644
--- a/car-media-common/src/com/android/car/media/common/MediaItemMetadata.java
+++ b/car-media-common/src/com/android/car/media/common/MediaItemMetadata.java
@@ -22,14 +22,14 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
-import android.media.MediaDescription;
-import android.media.MediaMetadata;
-import android.media.browse.MediaBrowser;
-import android.media.session.MediaSession;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.support.v4.media.MediaBrowserCompat;
+import android.support.v4.media.MediaDescriptionCompat;
+import android.support.v4.media.MediaMetadataCompat;
+import android.support.v4.media.session.MediaSessionCompat;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
@@ -48,31 +48,31 @@
public class MediaItemMetadata implements Parcelable {
private static final String TAG = "MediaItemMetadata";
@NonNull
- private final MediaDescription mMediaDescription;
+ private final MediaDescriptionCompat mMediaDescription;
@Nullable
private final Long mQueueId;
private final boolean mIsBrowsable;
private final boolean mIsPlayable;
- /** Creates an instance based on a {@link MediaMetadata} */
- public MediaItemMetadata(@NonNull MediaMetadata metadata) {
+ /** Creates an instance based on a {@link MediaMetadataCompat} */
+ public MediaItemMetadata(@NonNull MediaMetadataCompat metadata) {
this(metadata.getDescription(), null, false, false);
}
- /** Creates an instance based on a {@link MediaSession.QueueItem} */
- public MediaItemMetadata(@NonNull MediaSession.QueueItem queueItem) {
+ /** Creates an instance based on a {@link MediaSessionCompat.QueueItem} */
+ public MediaItemMetadata(@NonNull MediaSessionCompat.QueueItem queueItem) {
this(queueItem.getDescription(), queueItem.getQueueId(), false, true);
}
- /** Creates an instance based on a {@link MediaBrowser.MediaItem} */
- public MediaItemMetadata(@NonNull MediaBrowser.MediaItem item) {
+ /** Creates an instance based on a {@link MediaBrowserCompat.MediaItem} */
+ public MediaItemMetadata(@NonNull MediaBrowserCompat.MediaItem item) {
this(item.getDescription(), null, item.isBrowsable(), item.isPlayable());
}
/** Creates an instance based on a {@link Parcel} */
public MediaItemMetadata(@NonNull Parcel in) {
- mMediaDescription = (MediaDescription) in.readValue(
- MediaDescription.class.getClassLoader());
+ mMediaDescription = (MediaDescriptionCompat) in.readValue(
+ MediaDescriptionCompat.class.getClassLoader());
mQueueId = in.readByte() == 0x00 ? null : in.readLong();
mIsBrowsable = in.readByte() != 0x00;
mIsPlayable = in.readByte() != 0x00;
@@ -91,8 +91,8 @@
mIsPlayable = item.mIsPlayable;
}
- private MediaItemMetadata(MediaDescription description, Long queueId, boolean isBrowsable,
- boolean isPlayable) {
+ private MediaItemMetadata(MediaDescriptionCompat description, Long queueId, boolean isBrowsable,
+ boolean isPlayable) {
mMediaDescription = description;
mQueueId = queueId;
mIsPlayable = isPlayable;
diff --git a/car-media-common/src/com/android/car/media/common/MediaSource.java b/car-media-common/src/com/android/car/media/common/MediaSource.java
index a0e977b..5e65a49 100644
--- a/car-media-common/src/com/android/car/media/common/MediaSource.java
+++ b/car-media-common/src/com/android/car/media/common/MediaSource.java
@@ -33,12 +33,13 @@
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.media.browse.MediaBrowser;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
import android.os.Bundle;
import android.os.Handler;
+import android.os.RemoteException;
import android.service.media.MediaBrowserService;
+import android.support.v4.media.MediaBrowserCompat;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
import android.util.Log;
import java.util.ArrayList;
@@ -70,7 +71,7 @@
@Nullable
private final String mBrowseServiceClassName;
@Nullable
- private final MediaBrowser mBrowser;
+ private final MediaBrowserCompat mBrowser;
private final Context mContext;
private final Handler mHandler = new Handler();
private List<Observer> mObservers = new ArrayList<>();
@@ -119,8 +120,8 @@
@Nullable List<MediaItemMetadata> items);
}
- private final MediaBrowser.ConnectionCallback mConnectionCallback =
- new MediaBrowser.ConnectionCallback() {
+ private final MediaBrowserCompat.ConnectionCallback mConnectionCallback =
+ new MediaBrowserCompat.ConnectionCallback() {
@Override
public void onConnected() {
MediaSource.this.notify(observer -> observer.onBrowseConnected(true));
@@ -145,7 +146,7 @@
mPackageName = packageName;
mBrowseServiceClassName = getBrowseServiceClassName(packageName);
if (mBrowseServiceClassName != null) {
- mBrowser = new MediaBrowser(mContext,
+ mBrowser = new MediaBrowserCompat(mContext,
new ComponentName(mPackageName, mBrowseServiceClassName),
mConnectionCallback,
null);
@@ -291,27 +292,27 @@
}
/**
- * {@link MediaBrowser.SubscriptionCallback} wrapper used to overcome the lack of a reliable
- * method to obtain the initial list of children of a given node.
+ * {@link MediaBrowserCompat.SubscriptionCallback} wrapper used to overcome the lack of a
+ * reliable method to obtain the initial list of children of a given node.
* <p>
* When some 3rd party apps go through configuration changes (i.e., in the case of user-switch),
* they leave subscriptions in an intermediate state where neither
- * {@link MediaBrowser.SubscriptionCallback#onChildrenLoaded(String, List)} nor
- * {@link MediaBrowser.SubscriptionCallback#onError(String)} are invoked.
+ * {@link MediaBrowserCompat.SubscriptionCallback#onChildrenLoaded(String, List)} nor
+ * {@link MediaBrowserCompat.SubscriptionCallback#onError(String)} are invoked.
* <p>
* This wrapper works around this problem by retrying the subscription a given number of times
* if no data is received after a certain amount of time. This process is started by calling
* {@link #start(int, int)}, passing the number of retries and delay between them as
* parameters.
*/
- private class ChildrenSubscription extends MediaBrowser.SubscriptionCallback {
+ private class ChildrenSubscription extends MediaBrowserCompat.SubscriptionCallback {
private List<MediaItemMetadata> mItems;
private boolean mIsDataLoaded;
private List<ItemsSubscription> mSubscriptions = new ArrayList<>();
private String mParentId;
private int mRetries;
private int mRetryDelay;
- private MediaBrowser mMediaBrowser;
+ private MediaBrowserCompat mMediaBrowser;
private Runnable mRetryRunnable = new Runnable() {
@Override
public void run() {
@@ -333,10 +334,10 @@
/**
* Creates a subscription to the list of children of a certain media browse item
*
- * @param mediaBrowser {@link MediaBrowser} used to create the subscription
+ * @param mediaBrowser {@link MediaBrowserCompat} used to create the subscription
* @param parentId identifier of the parent node to subscribe to
*/
- ChildrenSubscription(@NonNull MediaBrowser mediaBrowser, String parentId) {
+ ChildrenSubscription(@NonNull MediaBrowserCompat mediaBrowser, String parentId) {
mParentId = parentId;
mMediaBrowser = mediaBrowser;
}
@@ -394,7 +395,7 @@
@Override
public void onChildrenLoaded(String parentId,
- List<MediaBrowser.MediaItem> children) {
+ List<MediaBrowserCompat.MediaItem> children) {
mHandler.removeCallbacks(mRetryRunnable);
mItems = children.stream()
.map(child -> new MediaItemMetadata(child))
@@ -404,7 +405,7 @@
}
@Override
- public void onChildrenLoaded(String parentId, List<MediaBrowser.MediaItem> children,
+ public void onChildrenLoaded(String parentId, List<MediaBrowserCompat.MediaItem> children,
Bundle options) {
onChildrenLoaded(parentId, children);
}
@@ -491,17 +492,22 @@
}
/**
- * Returns a {@link MediaController} that allows controlling this media source, or NULL
+ * Returns a {@link MediaControllerCompat} that allows controlling this media source, or NULL
* if the media source doesn't support browsing or the browser is not connected.
*/
@Nullable
- public MediaController getMediaController() {
+ public MediaControllerCompat getMediaController() {
if (mBrowser == null || !mBrowser.isConnected()) {
return null;
}
- MediaSession.Token token = mBrowser.getSessionToken();
- return new MediaController(mContext, token);
+ MediaSessionCompat.Token token = mBrowser.getSessionToken();
+ try {
+ return new MediaControllerCompat(mContext, token);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Couldn't get MediaControllerCompat", e);
+ return null;
+ }
}
/**
@@ -584,7 +590,7 @@
}
/** @return the current media browser. This media browser might not be connected yet. */
- public MediaBrowser getMediaBrowser() {
+ public MediaBrowserCompat getMediaBrowser() {
return mBrowser;
}
diff --git a/car-media-common/src/com/android/car/media/common/PlaybackFragment.java b/car-media-common/src/com/android/car/media/common/PlaybackFragment.java
index 6f386b6..b4a8efb 100644
--- a/car-media-common/src/com/android/car/media/common/PlaybackFragment.java
+++ b/car-media-common/src/com/android/car/media/common/PlaybackFragment.java
@@ -22,7 +22,6 @@
import android.car.Car;
import android.content.Intent;
import android.graphics.Bitmap;
-import android.media.session.MediaController;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@@ -36,7 +35,6 @@
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModelProviders;
import com.android.car.media.common.playback.AlbumArtLiveData;
@@ -52,8 +50,6 @@
* application.
*/
public class PlaybackFragment extends Fragment {
- private MutableLiveData<MediaController> mMediaController = new MutableLiveData<>();
-
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
diff --git a/car-media-common/src/com/android/car/media/common/browse/BrowsedMediaItems.java b/car-media-common/src/com/android/car/media/common/browse/BrowsedMediaItems.java
index 1dfb885..d9621cf 100644
--- a/car-media-common/src/com/android/car/media/common/browse/BrowsedMediaItems.java
+++ b/car-media-common/src/com/android/car/media/common/browse/BrowsedMediaItems.java
@@ -18,9 +18,9 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.media.browse.MediaBrowser;
import android.os.Bundle;
import android.os.Handler;
+import android.support.v4.media.MediaBrowserCompat;
import androidx.lifecycle.LiveData;
@@ -44,13 +44,13 @@
*/
private static final int CHILDREN_SUBSCRIPTION_RETRY_TIME_MS = 1000;
- private final MediaBrowser mBrowser;
+ private final MediaBrowserCompat mBrowser;
private final String mParentId;
private final Handler mHandler = new Handler();
private ChildrenSubscription mSubscription;
- BrowsedMediaItems(@NonNull MediaBrowser mediaBrowser, @Nullable String parentId) {
+ BrowsedMediaItems(@NonNull MediaBrowserCompat mediaBrowser, @Nullable String parentId) {
mBrowser = mediaBrowser;
mParentId = parentId;
}
@@ -74,20 +74,20 @@
}
/**
- * {@link MediaBrowser.SubscriptionCallback} wrapper used to overcome the lack of a reliable
- * method to obtain the initial list of children of a given node.
+ * {@link MediaBrowserCompat.SubscriptionCallback} wrapper used to overcome the lack of a
+ * reliable method to obtain the initial list of children of a given node.
* <p>
* When some 3rd party apps go through configuration changes (i.e., in the case of user-switch),
* they leave subscriptions in an intermediate state where neither {@link
- * MediaBrowser.SubscriptionCallback#onChildrenLoaded(String, List)} nor {@link
- * MediaBrowser.SubscriptionCallback#onError(String)} are invoked.
+ * MediaBrowserCompat.SubscriptionCallback#onChildrenLoaded(String, List)} nor {@link
+ * MediaBrowserCompat.SubscriptionCallback#onError(String)} are invoked.
* <p>
* This wrapper works around this problem by retrying the subscription a given number of times
* if no data is received after a certain amount of time. This process is started by calling
* {@link #start(int, int)}, passing the number of retries and delay between them as
* parameters.
*/
- private class ChildrenSubscription extends MediaBrowser.SubscriptionCallback {
+ private class ChildrenSubscription extends MediaBrowserCompat.SubscriptionCallback {
private final String mItemId;
private boolean mIsDataLoaded;
@@ -142,7 +142,7 @@
@Override
public void onChildrenLoaded(@NonNull String parentId,
- @NonNull List<MediaBrowser.MediaItem> children) {
+ @NonNull List<MediaBrowserCompat.MediaItem> children) {
mHandler.removeCallbacks(mRetryRunnable);
mIsDataLoaded = true;
setValue(children.stream()
@@ -152,7 +152,7 @@
@Override
public void onChildrenLoaded(@NonNull String parentId,
- @NonNull List<MediaBrowser.MediaItem> children,
+ @NonNull List<MediaBrowserCompat.MediaItem> children,
@NonNull Bundle options) {
onChildrenLoaded(parentId, children);
}
diff --git a/car-media-common/src/com/android/car/media/common/browse/MediaBrowserViewModel.java b/car-media-common/src/com/android/car/media/common/browse/MediaBrowserViewModel.java
index 24efdd4..2afd45c 100644
--- a/car-media-common/src/com/android/car/media/common/browse/MediaBrowserViewModel.java
+++ b/car-media-common/src/com/android/car/media/common/browse/MediaBrowserViewModel.java
@@ -24,7 +24,7 @@
import android.annotation.Nullable;
import android.annotation.UiThread;
import android.app.Application;
-import android.media.browse.MediaBrowser;
+import android.support.v4.media.MediaBrowserCompat;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
@@ -42,10 +42,10 @@
public class MediaBrowserViewModel extends AndroidViewModel {
- private final SwitchingLiveData<MediaBrowser> mMediaBrowserSwitch =
+ private final SwitchingLiveData<MediaBrowserCompat> mMediaBrowserSwitch =
SwitchingLiveData.newInstance();
- private final LiveData<MediaBrowser> mConnectedMediaBrowser =
+ private final LiveData<MediaBrowserCompat> mConnectedMediaBrowser =
map(mMediaBrowserSwitch.asLiveData(),
MediaBrowserViewModel::requireConnected);
@@ -62,7 +62,7 @@
super(application);
}
- private static MediaBrowser requireConnected(@Nullable MediaBrowser mediaBrowser) {
+ private static MediaBrowserCompat requireConnected(@Nullable MediaBrowserCompat mediaBrowser) {
if (mediaBrowser != null && !mediaBrowser.isConnected()) {
throw new IllegalStateException(
"Only connected MediaBrowsers may be provided to MediaBrowserViewModel.");
@@ -71,10 +71,10 @@
}
/**
- * Set the source {@link MediaBrowser} to use for browsing. If {@code mediaBrowser} emits
+ * Set the source {@link MediaBrowserCompat} to use for browsing. If {@code mediaBrowser} emits
* non-null, the MediaBrowser emitted must already be in a connected state.
*/
- public void setConnectedMediaBrowser(@Nullable LiveData<MediaBrowser> mediaBrowser) {
+ public void setConnectedMediaBrowser(@Nullable LiveData<MediaBrowserCompat> mediaBrowser) {
mMediaBrowserSwitch.setSource(mediaBrowser);
}
diff --git a/car-media-common/src/com/android/car/media/common/playback/MediaMetadataLiveData.java b/car-media-common/src/com/android/car/media/common/playback/MediaMetadataLiveData.java
index 98f1f00..1212dd6 100644
--- a/car-media-common/src/com/android/car/media/common/playback/MediaMetadataLiveData.java
+++ b/car-media-common/src/com/android/car/media/common/playback/MediaMetadataLiveData.java
@@ -18,27 +18,28 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.media.MediaMetadata;
-import android.media.session.MediaController;
+import android.support.v4.media.MediaMetadataCompat;
+import android.support.v4.media.session.MediaControllerCompat;
import androidx.lifecycle.LiveData;
/**
- * Watches the {@link MediaMetadata} for the session controlled by given a {@link MediaController}.
+ * Watches the {@link MediaMetadataCompat} for the session controlled by given a
+ * {@link MediaControllerCompat}.
*
- * @see MediaController#getMetadata()
+ * @see MediaControllerCompat#getMetadata()
*/
-class MediaMetadataLiveData extends LiveData<MediaMetadata> {
+class MediaMetadataLiveData extends LiveData<MediaMetadataCompat> {
- private final MediaController mMediaController;
- private final MediaController.Callback mCallback = new MediaController.Callback() {
+ private final MediaControllerCompat mMediaController;
+ private final MediaControllerCompat.Callback mCallback = new MediaControllerCompat.Callback() {
@Override
- public void onMetadataChanged(@Nullable MediaMetadata metadata) {
+ public void onMetadataChanged(@Nullable MediaMetadataCompat metadata) {
setValue(metadata);
}
};
- MediaMetadataLiveData(@NonNull MediaController mediaController) {
+ MediaMetadataLiveData(@NonNull MediaControllerCompat mediaController) {
mMediaController = mediaController;
}
diff --git a/car-media-common/src/com/android/car/media/common/playback/PlaybackStateLiveData.java b/car-media-common/src/com/android/car/media/common/playback/PlaybackStateLiveData.java
index 41fc685..2d574df 100644
--- a/car-media-common/src/com/android/car/media/common/playback/PlaybackStateLiveData.java
+++ b/car-media-common/src/com/android/car/media/common/playback/PlaybackStateLiveData.java
@@ -17,27 +17,28 @@
package com.android.car.media.common.playback;
import android.annotation.NonNull;
-import android.media.session.MediaController;
-import android.media.session.PlaybackState;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.PlaybackStateCompat;
import androidx.lifecycle.LiveData;
/**
- * Watches the {@link PlaybackState} for the session controlled by given a {@link MediaController}.
+ * Watches the {@link PlaybackStateCompat} for the session controlled by given a
+ * {@link MediaControllerCompat}.
*
- * @see MediaController#getPlaybackState()
+ * @see MediaControllerCompat#getPlaybackState()
*/
-class PlaybackStateLiveData extends LiveData<PlaybackState> {
+class PlaybackStateLiveData extends LiveData<PlaybackStateCompat> {
- private final MediaController mMediaController;
- private final MediaController.Callback mCallback = new MediaController.Callback() {
+ private final MediaControllerCompat mMediaController;
+ private final MediaControllerCompat.Callback mCallback = new MediaControllerCompat.Callback() {
@Override
- public void onPlaybackStateChanged(@NonNull PlaybackState playbackState) {
+ public void onPlaybackStateChanged(@NonNull PlaybackStateCompat playbackState) {
setValue(playbackState);
}
};
- PlaybackStateLiveData(@NonNull MediaController mediaController) {
+ PlaybackStateLiveData(@NonNull MediaControllerCompat mediaController) {
mMediaController = mediaController;
}
diff --git a/car-media-common/src/com/android/car/media/common/playback/PlaybackViewModel.java b/car-media-common/src/com/android/car/media/common/playback/PlaybackViewModel.java
index 0a9a766..d6784ee 100644
--- a/car-media-common/src/com/android/car/media/common/playback/PlaybackViewModel.java
+++ b/car-media-common/src/com/android/car/media/common/playback/PlaybackViewModel.java
@@ -34,12 +34,12 @@
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
-import android.media.MediaMetadata;
-import android.media.Rating;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
-import android.media.session.PlaybackState;
import android.os.Bundle;
+import android.support.v4.media.MediaMetadataCompat;
+import android.support.v4.media.RatingCompat;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.support.v4.media.session.PlaybackStateCompat;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
@@ -100,29 +100,30 @@
*/
public static final int ACTION_PAUSE = 3;
- private final SwitchingLiveData<MediaController>
+ private final SwitchingLiveData<MediaControllerCompat>
mMediaController = SwitchingLiveData.newInstance();
- private final LiveData<MediaController> mMediaControllerData = mMediaController.asLiveData();
+ private final LiveData<MediaControllerCompat> mMediaControllerData =
+ mMediaController.asLiveData();
- private final LiveData<MediaController> mDistinctMediaController =
+ private final LiveData<MediaControllerCompat> mDistinctMediaController =
distinct(mMediaControllerData, this::haveSamePackageName);
private final MediaSourceColors.Factory mColorsFactory;
private final LiveData<MediaSourceColors> mColors;
- private final LiveData<MediaMetadata> mMetadata = switchMap(mMediaControllerData,
+ private final LiveData<MediaMetadataCompat> mMetadata = switchMap(mMediaControllerData,
mediaController -> mediaController == null ? nullLiveData()
: new MediaMetadataLiveData(mediaController));
private final LiveData<MediaItemMetadata> mWrappedMetadata = distinct(map(mMetadata,
metadata -> metadata == null ? null : new MediaItemMetadata(metadata)));
- private final LiveData<PlaybackState> mPlaybackState = switchMap(mMediaControllerData,
+ private final LiveData<PlaybackStateCompat> mPlaybackState = switchMap(mMediaControllerData,
mediaController -> mediaController == null ? nullLiveData()
: new PlaybackStateLiveData(mediaController));
- private final LiveData<List<MediaSession.QueueItem>> mQueue = switchMap(mMediaControllerData,
- mediaController -> mediaController == null ? nullLiveData()
- : new QueueLiveData(mediaController));
+ private final LiveData<List<MediaSessionCompat.QueueItem>> mQueue =
+ switchMap(mMediaControllerData, mediaController ->
+ mediaController == null ? nullLiveData() : new QueueLiveData(mediaController));
// Filters out queue items with no description or title and converts them to MediaItemMetadatas
private final LiveData<List<MediaItemMetadata>> mSanitizedQueue = distinct(map(mQueue,
@@ -148,11 +149,11 @@
);
@Nullable
- private CombinedInfo getCombinedInfo(@Nullable MediaController mediaController) {
+ private CombinedInfo getCombinedInfo(@Nullable MediaControllerCompat mediaController) {
if (mediaController == null) return null;
- MediaMetadata metadata = mediaController.getMetadata();
- PlaybackState playbackState = mediaController.getPlaybackState();
+ MediaMetadataCompat metadata = mediaController.getMetadata();
+ PlaybackStateCompat playbackState = mediaController.getPlaybackState();
CombinedInfo oldInfo = mCombinedInfo.getValue();
// Minimize object churn
if (oldInfo == null
@@ -183,7 +184,7 @@
* LiveDatas returned by other methods in this ViewModel will refer to the latest
* MediaController.
*/
- public void setMediaController(@Nullable LiveData<MediaController> mediaControllerData) {
+ public void setMediaController(@Nullable LiveData<MediaControllerCompat> mediaControllerData) {
mMediaController.setSource(mediaControllerData);
}
@@ -191,7 +192,7 @@
* Returns a LiveData that emits the currently set MediaController (may emit null).
*/
@NonNull
- public LiveData<MediaController> getMediaController() {
+ public LiveData<MediaControllerCompat> getMediaController() {
return mMediaControllerData;
}
@@ -204,14 +205,14 @@
/**
* Returns a LiveData that emits a MediaItemMetadata of the current media item in the session
- * managed by the provided {@link MediaController}.
+ * managed by the provided {@link MediaControllerCompat}.
*/
public LiveData<MediaItemMetadata> getMetadata() {
return mWrappedMetadata;
}
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
- LiveData<PlaybackState> getPlaybackState() {
+ LiveData<PlaybackStateCompat> getPlaybackState() {
return mPlaybackState;
}
@@ -250,7 +251,7 @@
return mCombinedInfo;
}
- private boolean haveSamePackageName(MediaController left, MediaController right) {
+ private boolean haveSamePackageName(MediaControllerCompat left, MediaControllerCompat right) {
if (left == right) {
return true;
}
@@ -270,27 +271,28 @@
@Actions long actions = state.getActions();
@Action int stopAction = ACTION_DISABLED;
- if ((actions & (PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY_PAUSE)) != 0) {
+ if ((actions & (PlaybackStateCompat.ACTION_PAUSE
+ | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0) {
stopAction = ACTION_PAUSE;
- } else if ((actions & PlaybackState.ACTION_STOP) != 0) {
+ } else if ((actions & PlaybackStateCompat.ACTION_STOP) != 0) {
stopAction = ACTION_STOP;
}
switch (state.getState()) {
- case PlaybackState.STATE_PLAYING:
- case PlaybackState.STATE_BUFFERING:
- case PlaybackState.STATE_CONNECTING:
- case PlaybackState.STATE_FAST_FORWARDING:
- case PlaybackState.STATE_REWINDING:
- case PlaybackState.STATE_SKIPPING_TO_NEXT:
- case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
- case PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM:
+ case PlaybackStateCompat.STATE_PLAYING:
+ case PlaybackStateCompat.STATE_BUFFERING:
+ case PlaybackStateCompat.STATE_CONNECTING:
+ case PlaybackStateCompat.STATE_FAST_FORWARDING:
+ case PlaybackStateCompat.STATE_REWINDING:
+ case PlaybackStateCompat.STATE_SKIPPING_TO_NEXT:
+ case PlaybackStateCompat.STATE_SKIPPING_TO_PREVIOUS:
+ case PlaybackStateCompat.STATE_SKIPPING_TO_QUEUE_ITEM:
return stopAction;
- case PlaybackState.STATE_STOPPED:
- case PlaybackState.STATE_PAUSED:
- case PlaybackState.STATE_NONE:
- case PlaybackState.STATE_ERROR:
- return (actions & PlaybackState.ACTION_PLAY) != 0 ? ACTION_PLAY
+ case PlaybackStateCompat.STATE_STOPPED:
+ case PlaybackStateCompat.STATE_PAUSED:
+ case PlaybackStateCompat.STATE_NONE:
+ case PlaybackStateCompat.STATE_ERROR:
+ return (actions & PlaybackStateCompat.ACTION_PLAY) != 0 ? ACTION_PLAY
: ACTION_DISABLED;
default:
Log.w(TAG, String.format("Unknown PlaybackState: %d", state.getState()));
@@ -300,7 +302,7 @@
private final LiveData<Long> mMaxProgress = map(mMetadata,
metadata -> metadata == null ? 0
- : metadata.getLong(MediaMetadata.METADATA_KEY_DURATION));
+ : metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION));
private final LiveData<Long> mProgress =
switchMap(pair(mPlaybackState, mMaxProgress),
@@ -308,15 +310,15 @@
: new ProgressLiveData(pair.first, pair.second));
private final LiveData<Boolean> mIsPlaying = map(mPlaybackState,
- state -> state != null && state.getState() == PlaybackState.STATE_PLAYING);
+ state -> state != null && state.getState() == PlaybackStateCompat.STATE_PLAYING);
private final LiveData<Boolean> mIsSkipNextEnabled = map(mPlaybackState,
state -> state != null
- && (state.getActions() & PlaybackState.ACTION_SKIP_TO_NEXT) != 0);
+ && (state.getActions() & PlaybackStateCompat.ACTION_SKIP_TO_NEXT) != 0);
private final LiveData<Boolean> mIsSkipPreviousEnabled = map(mPlaybackState,
state -> state != null
- && (state.getActions() & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0);
+ && (state.getActions() & PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS) != 0);
// true if the media source is loading (e.g.: buffering, connecting, etc.)
private final LiveData<Boolean> mIsLoading = map(mPlaybackState,
@@ -326,20 +328,20 @@
}
int state = playbackState.getState();
- return state == PlaybackState.STATE_BUFFERING
- || state == PlaybackState.STATE_CONNECTING
- || state == PlaybackState.STATE_FAST_FORWARDING
- || state == PlaybackState.STATE_REWINDING
- || state == PlaybackState.STATE_SKIPPING_TO_NEXT
- || state == PlaybackState.STATE_SKIPPING_TO_PREVIOUS
- || state == PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM;
+ return state == PlaybackStateCompat.STATE_BUFFERING
+ || state == PlaybackStateCompat.STATE_CONNECTING
+ || state == PlaybackStateCompat.STATE_FAST_FORWARDING
+ || state == PlaybackStateCompat.STATE_REWINDING
+ || state == PlaybackStateCompat.STATE_SKIPPING_TO_NEXT
+ || state == PlaybackStateCompat.STATE_SKIPPING_TO_PREVIOUS
+ || state == PlaybackStateCompat.STATE_SKIPPING_TO_QUEUE_ITEM;
});
private final LiveData<CharSequence> mErrorMessage = map(mPlaybackState,
state -> state == null ? null : state.getErrorMessage());
private final LiveData<Long> mActiveQueueItemId = map(mPlaybackState,
- state -> state == null ? MediaSession.QueueItem.UNKNOWN_ID
+ state -> state == null ? MediaSessionCompat.QueueItem.UNKNOWN_ID
: state.getActiveQueueItemId());
private final LiveData<List<RawCustomPlaybackAction>> mCustomActions =
@@ -372,7 +374,7 @@
/**
* Returns a LiveData that emits the current playback progress, in milliseconds. This is a
* value between 0 and {@link #getMaxProgress()} or
- * {@link PlaybackState#PLAYBACK_POSITION_UNKNOWN}
+ * {@link PlaybackStateCompat#PLAYBACK_POSITION_UNKNOWN}
* if the current position is unknown. This value will update on its own periodically (less
* than a second) while active.
*/
@@ -422,7 +424,7 @@
/**
* Returns a LiveData that emits the queue id of the currently playing queue item, or {@link
- * MediaSession.QueueItem#UNKNOWN_ID} if none of the items is currently playing.
+ * MediaSessionCompat.QueueItem#UNKNOWN_ID} if none of the items is currently playing.
*/
public LiveData<Long> getActiveQueueItemId() {
return mActiveQueueItemId;
@@ -432,13 +434,13 @@
@Nullable CombinedInfo info) {
List<RawCustomPlaybackAction> actions = new ArrayList<>();
if (info == null) return actions;
- PlaybackState playbackState = info.mPlaybackState;
+ PlaybackStateCompat playbackState = info.mPlaybackState;
if (playbackState == null) return actions;
RawCustomPlaybackAction ratingAction = getRatingAction(info);
if (ratingAction != null) actions.add(ratingAction);
- for (PlaybackState.CustomAction action : playbackState.getCustomActions()) {
+ for (PlaybackStateCompat.CustomAction action : playbackState.getCustomActions()) {
String packageName = info.mMediaController.getPackageName();
actions.add(
new RawCustomPlaybackAction(action.getIcon(), packageName,
@@ -451,19 +453,20 @@
@Nullable
private RawCustomPlaybackAction getRatingAction(@Nullable CombinedInfo info) {
if (info == null) return null;
- PlaybackState playbackState = info.mPlaybackState;
+ PlaybackStateCompat playbackState = info.mPlaybackState;
if (playbackState == null) return null;
long stdActions = playbackState.getActions();
- if ((stdActions & PlaybackState.ACTION_SET_RATING) == 0) return null;
+ if ((stdActions & PlaybackStateCompat.ACTION_SET_RATING) == 0) return null;
int ratingType = info.mMediaController.getRatingType();
- if (ratingType != Rating.RATING_HEART) return null;
+ if (ratingType != RatingCompat.RATING_HEART) return null;
- MediaMetadata metadata = info.mMetadata;
+ MediaMetadataCompat metadata = info.mMetadata;
boolean hasHeart = false;
if (metadata != null) {
- Rating rating = metadata.getRating(MediaMetadata.METADATA_KEY_USER_RATING);
+ RatingCompat rating =
+ metadata.getRating(MediaMetadataCompat.METADATA_KEY_USER_RATING);
hasHeart = rating != null && rating.hasHeart();
}
@@ -477,12 +480,12 @@
/**
* Wraps the {@link android.media.session.MediaController.TransportControls TransportControls}
- * for a {@link MediaController} to send commands.
+ * for a {@link MediaControllerCompat} to send commands.
*/
public static class PlaybackController {
- private final MediaController mMediaController;
+ private final MediaControllerCompat mMediaController;
- private PlaybackController(@Nullable MediaController mediaController) {
+ private PlaybackController(@Nullable MediaControllerCompat mediaController) {
mMediaController = mediaController;
}
@@ -539,11 +542,11 @@
*/
public void doCustomAction(String action, Bundle extras) {
if (mMediaController == null) return;
- MediaController.TransportControls cntrl = mMediaController.getTransportControls();
+ MediaControllerCompat.TransportControls cntrl = mMediaController.getTransportControls();
if (ACTION_SET_RATING.equals(action)) {
boolean setHeart = extras != null && extras.getBoolean(EXTRA_SET_HEART, false);
- cntrl.setRating(Rating.newHeartRating(setHeart));
+ cntrl.setRating(RatingCompat.newHeartRating(setHeart));
} else {
cntrl.sendCustomAction(action, extras);
}
@@ -686,12 +689,12 @@
}
static class CombinedInfo {
- final MediaController mMediaController;
- final MediaMetadata mMetadata;
- final PlaybackState mPlaybackState;
+ final MediaControllerCompat mMediaController;
+ final MediaMetadataCompat mMetadata;
+ final PlaybackStateCompat mPlaybackState;
- private CombinedInfo(MediaController mediaController,
- MediaMetadata metadata, PlaybackState playbackState) {
+ private CombinedInfo(MediaControllerCompat mediaController,
+ MediaMetadataCompat metadata, PlaybackStateCompat playbackState) {
this.mMediaController = mediaController;
this.mMetadata = metadata;
this.mPlaybackState = playbackState;
diff --git a/car-media-common/src/com/android/car/media/common/playback/ProgressLiveData.java b/car-media-common/src/com/android/car/media/common/playback/ProgressLiveData.java
index 1ae61c8..6a4df83 100644
--- a/car-media-common/src/com/android/car/media/common/playback/ProgressLiveData.java
+++ b/car-media-common/src/com/android/car/media/common/playback/ProgressLiveData.java
@@ -16,10 +16,10 @@
package com.android.car.media.common.playback;
-import android.media.session.PlaybackState;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
+import android.support.v4.media.session.PlaybackStateCompat;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -28,7 +28,7 @@
import java.util.function.Supplier;
/**
- * Updates current progress from a given {@link PlaybackState} while active
+ * Updates current progress from a given {@link PlaybackStateCompat} while active
*/
class ProgressLiveData extends LiveData<Long> {
@@ -36,18 +36,18 @@
@VisibleForTesting
static final long UPDATE_INTERVAL_MS = 500;
- private final PlaybackState mPlaybackState;
+ private final PlaybackStateCompat mPlaybackState;
private final long mMaxProgress;
private final Handler mTimerHandler = new Handler(Looper.getMainLooper());
private final Supplier<Long> mElapsedRealtime;
- ProgressLiveData(@NonNull PlaybackState playbackState, long maxProgress) {
+ ProgressLiveData(@NonNull PlaybackStateCompat playbackState, long maxProgress) {
this(playbackState, maxProgress, SystemClock::elapsedRealtime);
}
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
ProgressLiveData(
- @NonNull PlaybackState playbackState, long maxProgress,
+ @NonNull PlaybackStateCompat playbackState, long maxProgress,
Supplier<Long> elapsedRealtime) {
mPlaybackState = playbackState;
mMaxProgress = maxProgress;
@@ -56,21 +56,21 @@
private void updateProgress() {
setValue(getProgress());
- if (mPlaybackState.getState() != PlaybackState.STATE_PAUSED
- && mPlaybackState.getState() != PlaybackState.STATE_STOPPED
+ if (mPlaybackState.getState() != PlaybackStateCompat.STATE_PAUSED
+ && mPlaybackState.getState() != PlaybackStateCompat.STATE_STOPPED
&& mPlaybackState.getPlaybackSpeed() != 0) {
mTimerHandler.postDelayed(this::updateProgress, UPDATE_INTERVAL_MS);
}
}
private long getProgress() {
- if (mPlaybackState.getPosition() == PlaybackState.PLAYBACK_POSITION_UNKNOWN) {
- return PlaybackState.PLAYBACK_POSITION_UNKNOWN;
+ if (mPlaybackState.getPosition() == PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN) {
+ return PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN;
}
long timeDiff = mElapsedRealtime.get() - mPlaybackState.getLastPositionUpdateTime();
float speed = mPlaybackState.getPlaybackSpeed();
- if (mPlaybackState.getState() == PlaybackState.STATE_PAUSED
- || mPlaybackState.getState() == PlaybackState.STATE_STOPPED) {
+ if (mPlaybackState.getState() == PlaybackStateCompat.STATE_PAUSED
+ || mPlaybackState.getState() == PlaybackStateCompat.STATE_STOPPED) {
// This guards against apps who don't keep their playbackSpeed to spec (b/62375164)
speed = 0f;
}
diff --git a/car-media-common/src/com/android/car/media/common/playback/QueueLiveData.java b/car-media-common/src/com/android/car/media/common/playback/QueueLiveData.java
index ad0d41d..831a50b 100644
--- a/car-media-common/src/com/android/car/media/common/playback/QueueLiveData.java
+++ b/car-media-common/src/com/android/car/media/common/playback/QueueLiveData.java
@@ -18,8 +18,8 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
import androidx.lifecycle.LiveData;
@@ -27,21 +27,21 @@
/**
- * Watches the queue for the session controlled by given a {@link MediaController}.
+ * Watches the queue for the session controlled by given a {@link MediaControllerCompat}.
*
- * @see MediaController#getQueue()
+ * @see MediaControllerCompat#getQueue()
*/
-class QueueLiveData extends LiveData<List<MediaSession.QueueItem>> {
+class QueueLiveData extends LiveData<List<MediaSessionCompat.QueueItem>> {
- private final MediaController mMediaController;
- private final MediaController.Callback mCallback = new MediaController.Callback() {
+ private final MediaControllerCompat mMediaController;
+ private final MediaControllerCompat.Callback mCallback = new MediaControllerCompat.Callback() {
@Override
- public void onQueueChanged(@Nullable List<MediaSession.QueueItem> metadata) {
+ public void onQueueChanged(@Nullable List<MediaSessionCompat.QueueItem> metadata) {
setValue(metadata);
}
};
- QueueLiveData(@NonNull MediaController mediaController) {
+ QueueLiveData(@NonNull MediaControllerCompat mediaController) {
mMediaController = mediaController;
}
diff --git a/car-media-common/src/com/android/car/media/common/source/ActiveMediaControllersLiveData.java b/car-media-common/src/com/android/car/media/common/source/ActiveMediaControllersLiveData.java
index 7929b4c..86af462 100644
--- a/car-media-common/src/com/android/car/media/common/source/ActiveMediaControllersLiveData.java
+++ b/car-media-common/src/com/android/car/media/common/source/ActiveMediaControllersLiveData.java
@@ -20,7 +20,11 @@
import android.content.Context;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
-import android.media.session.PlaybackState;
+import android.os.RemoteException;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.support.v4.media.session.PlaybackStateCompat;
+import android.util.Log;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
@@ -29,6 +33,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.stream.Collectors;
/**
* This is an abstractions over {@link MediaSessionManager} that provides information about the
@@ -37,10 +42,12 @@
* This requires the android.Manifest.permission.MEDIA_CONTENT_CONTROL permission to be held by the
* calling app.
*/
-class ActiveMediaControllersLiveData extends LiveData<List<MediaController>> {
+class ActiveMediaControllersLiveData extends LiveData<List<MediaControllerCompat>> {
+ private static final String TAG = "ActiveMedia";
private final MediaSessionManager mMediaSessionManager;
private final MediaSessionUpdater mMediaSessionUpdater = new MediaSessionUpdater();
+ private Context mContext;
/**
* Temporary work-around to bug b/76017849. MediaSessionManager is not notifying media session
@@ -49,27 +56,29 @@
* selecting the top-most controller is a cheap operation.
*/
private class MediaSessionUpdater {
- private List<MediaController> mControllers = new ArrayList<>();
+ private List<MediaControllerCompat> mControllers = new ArrayList<>();
- private MediaController.Callback mCallback = new MediaController.Callback() {
+ private MediaControllerCompat.Callback mCallback = new MediaControllerCompat.Callback() {
@Override
- public void onPlaybackStateChanged(@Nullable PlaybackState state) {
- List<MediaController> activeSessions = mMediaSessionManager.getActiveSessions(null);
+ public void onPlaybackStateChanged(@Nullable PlaybackStateCompat state) {
+ List<MediaController> activeSessions =
+ mMediaSessionManager.getActiveSessions(null);
update(activeSessions);
}
@Override
public void onSessionDestroyed() {
- List<MediaController> activeSessions = mMediaSessionManager.getActiveSessions(null);
+ List<MediaController> activeSessions =
+ mMediaSessionManager.getActiveSessions(null);
update(activeSessions);
}
};
- private void registerCallbacks(List<MediaController> newControllers) {
- for (MediaController oldController : mControllers) {
+ private void registerCallbacks(List<MediaControllerCompat> newControllers) {
+ for (MediaControllerCompat oldController : mControllers) {
oldController.unregisterCallback(mCallback);
}
- for (MediaController newController : newControllers) {
+ for (MediaControllerCompat newController : newControllers) {
newController.registerCallback(mCallback);
}
mControllers.clear();
@@ -78,10 +87,11 @@
}
private MediaSessionManager.OnActiveSessionsChangedListener mSessionChangeListener =
- this::setValue;
+ controllers -> setValue(convertCompat(controllers));
ActiveMediaControllersLiveData(Context context) {
this(Objects.requireNonNull(context.getSystemService(MediaSessionManager.class)));
+ mContext = context;
}
@VisibleForTesting
@@ -90,8 +100,9 @@
}
private void update(List<MediaController> activeSessions) {
- setValue(activeSessions);
- mMediaSessionUpdater.registerCallbacks(activeSessions);
+ List<MediaControllerCompat> activeSessionsCompat = convertCompat(activeSessions);
+ setValue(activeSessionsCompat);
+ mMediaSessionUpdater.registerCallbacks(activeSessionsCompat);
}
@Override
@@ -106,4 +117,23 @@
mMediaSessionManager.removeOnActiveSessionsChangedListener(mSessionChangeListener);
}
+ private List<MediaControllerCompat> convertCompat(List<MediaController> mediaControllers) {
+ return mediaControllers.stream().map(
+ controller -> fromMediaController(controller))
+ .collect(Collectors.toList());
+ }
+
+ @VisibleForTesting
+ MediaControllerCompat fromMediaController(MediaController mediaController) {
+ // TODO(b/112161702): cache active MediaControllers
+ MediaSessionCompat.Token token =
+ MediaSessionCompat.Token.fromToken(mediaController.getSessionToken());
+ MediaControllerCompat controllerCompat = null;
+ try {
+ controllerCompat = new MediaControllerCompat(mContext, token);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Couldn't get MediaController", e);
+ }
+ return controllerCompat;
+ }
}
diff --git a/car-media-common/src/com/android/car/media/common/source/ActiveMediaSelector.java b/car-media-common/src/com/android/car/media/common/source/ActiveMediaSelector.java
index 3596c57..3fa0bb4 100644
--- a/car-media-common/src/com/android/car/media/common/source/ActiveMediaSelector.java
+++ b/car-media-common/src/com/android/car/media/common/source/ActiveMediaSelector.java
@@ -20,9 +20,9 @@
import android.annotation.Nullable;
import android.content.Context;
import android.content.SharedPreferences;
-import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
-import android.media.session.PlaybackState;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.PlaybackStateCompat;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
@@ -32,7 +32,7 @@
import java.util.List;
/**
- * Provides functions for selecting a {@link MediaController} from a list of controllers.
+ * Provides functions for selecting a {@link MediaControllerCompat} from a list of controllers.
*/
class ActiveMediaSelector {
private static final String TAG = "ActiveSourceManager";
@@ -54,15 +54,16 @@
}
/**
- * Searches through {@code controllers} to find the MediaController with the same package name
- * as {@code mediaSource}.
+ * Searches through {@code controllers} to find the MediaControllerCompat with the same package
+ * name as {@code mediaSource}.
*
* @param controllers The List of MediaControllers to search through.
* @param mediaSource The MediaSource to match.
- * @return The MediaController whose package name matches or {@code null} if no match is found.
+ * @return The MediaControllerCompat whose package name matches or {@code null} if no match is
+ * found.
*/
@Nullable
- MediaController getControllerForSource(@NonNull List<MediaController> controllers,
+ MediaControllerCompat getControllerForSource(@NonNull List<MediaControllerCompat> controllers,
@NonNull SimpleMediaSource mediaSource) {
return getControllerForPackage(controllers, mediaSource.getPackageName());
}
@@ -76,9 +77,9 @@
* @return The MediaController whose package name matches or {@code null} if no match is found.
*/
@Nullable
- MediaController getControllerForPackage(@NonNull List<MediaController> controllers,
+ MediaControllerCompat getControllerForPackage(@NonNull List<MediaControllerCompat> controllers,
@NonNull String packageName) {
- for (MediaController controller : controllers) {
+ for (MediaControllerCompat controller : controllers) {
if (controller != null && packageName.equals(controller.getPackageName())) {
return controller;
}
@@ -90,12 +91,13 @@
* Returns one of the provided controllers as the "currently playing" one. If {@code previous}
* is equivalent, will return that instance.
*/
- MediaController getTopMostMediaController(@NonNull List<MediaController> controllers,
- @Nullable MediaController previous) {
+ MediaControllerCompat getTopMostMediaController(
+ @NonNull List<MediaControllerCompat> controllers,
+ @Nullable MediaControllerCompat previous) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
dump("Selecting a media controller from: ", controllers);
}
- MediaController topMostController = pickTopMostController(controllers);
+ MediaControllerCompat topMostController = pickTopMostController(controllers);
if ((topMostController == null && previous == null)
|| (topMostController != null && previous != null
&& topMostController.getPackageName().equals(previous.getPackageName()))) {
@@ -108,12 +110,12 @@
}
private void dump(@SuppressWarnings("SameParameterValue") String title,
- List<MediaController> controllers) {
+ List<MediaControllerCompat> controllers) {
Log.d(TAG, title + " (total: " + controllers.size() + ")");
- for (MediaController controller : controllers) {
+ for (MediaControllerCompat controller : controllers) {
String stateName = getStateName(controller.getPlaybackState() != null
? controller.getPlaybackState().getState()
- : PlaybackState.STATE_NONE);
+ : PlaybackStateCompat.STATE_NONE);
Log.d(TAG, String.format("\t%s: %s",
controller.getPackageName(),
stateName));
@@ -122,29 +124,29 @@
private String getStateName(@PlaybackStateAnnotations.State int state) {
switch (state) {
- case PlaybackState.STATE_NONE:
+ case PlaybackStateCompat.STATE_NONE:
return "NONE";
- case PlaybackState.STATE_STOPPED:
+ case PlaybackStateCompat.STATE_STOPPED:
return "STOPPED";
- case PlaybackState.STATE_PAUSED:
+ case PlaybackStateCompat.STATE_PAUSED:
return "PAUSED";
- case PlaybackState.STATE_PLAYING:
+ case PlaybackStateCompat.STATE_PLAYING:
return "PLAYING";
- case PlaybackState.STATE_FAST_FORWARDING:
+ case PlaybackStateCompat.STATE_FAST_FORWARDING:
return "FORWARDING";
- case PlaybackState.STATE_REWINDING:
+ case PlaybackStateCompat.STATE_REWINDING:
return "REWINDING";
- case PlaybackState.STATE_BUFFERING:
+ case PlaybackStateCompat.STATE_BUFFERING:
return "BUFFERING";
- case PlaybackState.STATE_ERROR:
+ case PlaybackStateCompat.STATE_ERROR:
return "ERROR";
- case PlaybackState.STATE_CONNECTING:
+ case PlaybackStateCompat.STATE_CONNECTING:
return "CONNECTING";
- case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
+ case PlaybackStateCompat.STATE_SKIPPING_TO_PREVIOUS:
return "SKIPPING_TO_PREVIOUS";
- case PlaybackState.STATE_SKIPPING_TO_NEXT:
+ case PlaybackStateCompat.STATE_SKIPPING_TO_NEXT:
return "SKIPPING_TO_NEXT";
- case PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM:
+ case PlaybackStateCompat.STATE_SKIPPING_TO_QUEUE_ITEM:
return "SKIPPING_TO_QUEUE_ITEM";
default:
return "UNKNOWN";
@@ -155,30 +157,30 @@
* Returns the controller most likely to be the currently active one, out of the list of active
* controllers reported by {@link MediaSessionManager}. It does so by picking the first one (in
* order of priority) with an active state as reported by
- * {@link MediaController#getPlaybackState()}
+ * {@link MediaControllerCompat#getPlaybackState()}
*/
@Nullable
- private MediaController pickTopMostController(List<MediaController> controllers) {
+ private MediaControllerCompat pickTopMostController(List<MediaControllerCompat> controllers) {
if (controllers != null && controllers.size() > 0) {
- for (MediaController candidate : controllers) {
+ for (MediaControllerCompat candidate : controllers) {
@PlaybackStateAnnotations.State int state = candidate.getPlaybackState() != null
? candidate.getPlaybackState().getState()
- : PlaybackState.STATE_NONE;
- if (state == PlaybackState.STATE_BUFFERING
- || state == PlaybackState.STATE_CONNECTING
- || state == PlaybackState.STATE_FAST_FORWARDING
- || state == PlaybackState.STATE_PLAYING
- || state == PlaybackState.STATE_REWINDING
- || state == PlaybackState.STATE_SKIPPING_TO_NEXT
- || state == PlaybackState.STATE_SKIPPING_TO_PREVIOUS
- || state == PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM) {
+ : PlaybackStateCompat.STATE_NONE;
+ if (state == PlaybackStateCompat.STATE_BUFFERING
+ || state == PlaybackStateCompat.STATE_CONNECTING
+ || state == PlaybackStateCompat.STATE_FAST_FORWARDING
+ || state == PlaybackStateCompat.STATE_PLAYING
+ || state == PlaybackStateCompat.STATE_REWINDING
+ || state == PlaybackStateCompat.STATE_SKIPPING_TO_NEXT
+ || state == PlaybackStateCompat.STATE_SKIPPING_TO_PREVIOUS
+ || state == PlaybackStateCompat.STATE_SKIPPING_TO_QUEUE_ITEM) {
return candidate;
}
}
// If no source is active, we go for the last known source
String packageName = getLastKnownActivePackageName();
if (packageName != null) {
- for (MediaController candidate : controllers) {
+ for (MediaControllerCompat candidate : controllers) {
if (candidate.getPackageName().equals(packageName)) {
return candidate;
}
diff --git a/car-media-common/src/com/android/car/media/common/source/MediaBrowserConnector.java b/car-media-common/src/com/android/car/media/common/source/MediaBrowserConnector.java
index 2b93713..acaeae4 100644
--- a/car-media-common/src/com/android/car/media/common/source/MediaBrowserConnector.java
+++ b/car-media-common/src/com/android/car/media/common/source/MediaBrowserConnector.java
@@ -19,7 +19,7 @@
import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
-import android.media.browse.MediaBrowser;
+import android.support.v4.media.MediaBrowserCompat;
import androidx.annotation.IntDef;
import androidx.annotation.VisibleForTesting;
@@ -36,16 +36,16 @@
class MediaBrowserConnector extends LiveData<MediaBrowserConnector.MediaBrowserState> {
/**
- * Contains the {@link MediaBrowser} for a {@link MediaBrowserConnector} and its associated
- * connection status.
+ * Contains the {@link MediaBrowserCompat} for a {@link MediaBrowserConnector} and its
+ * associated connection status.
*/
public static class MediaBrowserState {
- public final MediaBrowser mMediaBrowser;
+ public final MediaBrowserCompat mMediaBrowser;
@ConnectionState
public final int mConnectionState;
- MediaBrowserState(MediaBrowser mediaBrowser, @ConnectionState int connectionState) {
+ MediaBrowserState(MediaBrowserCompat mediaBrowser, @ConnectionState int connectionState) {
mMediaBrowser = mediaBrowser;
mConnectionState = connectionState;
}
@@ -61,20 +61,20 @@
int CONNECTION_FAILED = 3;
}
- private final MediaBrowser mBrowser;
+ private final MediaBrowserCompat mBrowser;
/**
* Create a new MediaBrowserConnector for the specified component.
*
* @param context The Context with which to build the MediaBrowser.
* @param browseService The ComponentName of the media browser service.
- * @see MediaBrowser#MediaBrowser(Context, ComponentName, MediaBrowser.ConnectionCallback,
- * android.os.Bundle)
+ * @see MediaBrowserCompat#MediaBrowserCompat(Context, ComponentName,
+ * MediaBrowserCompat.ConnectionCallback, android.os.Bundle)
*/
MediaBrowserConnector(@NonNull Context context,
@NonNull ComponentName browseService) {
mBrowser = createMediaBrowser(context, browseService,
- new MediaBrowser.ConnectionCallback() {
+ new MediaBrowserCompat.ConnectionCallback() {
@Override
public void onConnected() {
setValue(new MediaBrowserState(mBrowser, ConnectionState.CONNECTED));
@@ -94,13 +94,13 @@
}
/**
- * Instantiate the MediaBrowser this MediaBrowserConnector will connect with.
+ * Instantiate the MediaBrowserCompat this MediaBrowserConnector will connect with.
*/
@VisibleForTesting()
- protected MediaBrowser createMediaBrowser(@NonNull Context context,
+ protected MediaBrowserCompat createMediaBrowser(@NonNull Context context,
@NonNull ComponentName browseService,
- @NonNull MediaBrowser.ConnectionCallback callback) {
- return new MediaBrowser(context, browseService, callback, null);
+ @NonNull MediaBrowserCompat.ConnectionCallback callback) {
+ return new MediaBrowserCompat(context, browseService, callback, null);
}
@Override
diff --git a/car-media-common/src/com/android/car/media/common/source/MediaSourceViewModel.java b/car-media-common/src/com/android/car/media/common/source/MediaSourceViewModel.java
index 5b4f79e..94de3f3 100644
--- a/car-media-common/src/com/android/car/media/common/source/MediaSourceViewModel.java
+++ b/car-media-common/src/com/android/car/media/common/source/MediaSourceViewModel.java
@@ -29,9 +29,12 @@
import android.annotation.UiThread;
import android.app.Application;
import android.content.ComponentName;
-import android.media.browse.MediaBrowser;
import android.media.session.MediaController;
-import android.media.session.MediaSession;
+import android.os.RemoteException;
+import android.support.v4.media.MediaBrowserCompat;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.arch.core.util.Function;
@@ -50,6 +53,7 @@
* Contains observable data needed for displaying playback and browse UI
*/
public class MediaSourceViewModel extends AndroidViewModel {
+ private static final String TAG = "MediaSourceViewModel";
private final LiveData<List<SimpleMediaSource>> mMediaSources;
@@ -57,13 +61,13 @@
private final MutableLiveData<SimpleMediaSource> mSelectedMediaSource = new MutableLiveData<>();
- private final LiveData<MediaBrowser> mConnectedMediaBrowser;
+ private final LiveData<MediaBrowserCompat> mConnectedMediaBrowser;
// Media controller for selected media source.
- private final LiveData<MediaController> mMediaController;
+ private final LiveData<MediaControllerCompat> mMediaController;
// Media controller for active media source, may not be the same as selected media source.
- private final LiveData<MediaController> mTopActiveMediaController;
+ private final LiveData<MediaControllerCompat> mTopActiveMediaController;
private final LiveData<Boolean> mIsCurrentMediaSourcePlaying;
@@ -79,9 +83,9 @@
ActiveMediaSelector createActiveMediaSelector();
- LiveData<List<MediaController>> createActiveMediaControllerData();
+ LiveData<List<MediaControllerCompat>> createActiveMediaControllerData();
- MediaController getControllerForSession(@Nullable MediaSession.Token session);
+ MediaControllerCompat getControllerForSession(@Nullable MediaSessionCompat.Token session);
}
/**
@@ -104,7 +108,7 @@
}
@Override
- public LiveData<List<MediaController>> createActiveMediaControllerData() {
+ public LiveData<List<MediaControllerCompat>> createActiveMediaControllerData() {
return new ActiveMediaControllersLiveData(application);
}
@@ -114,9 +118,15 @@
}
@Override
- public MediaController getControllerForSession(@Nullable MediaSession.Token token) {
+ public MediaControllerCompat getControllerForSession(
+ @Nullable MediaSessionCompat.Token token) {
if (token == null) return null;
- return new MediaController(application, token);
+ try {
+ return new MediaControllerCompat(application, token);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Couldn't get MediaControllerCompat", e);
+ return null;
+ }
}
});
}
@@ -125,7 +135,7 @@
MediaSourceViewModel(@NonNull Application application, @NonNull InputFactory inputFactory) {
super(application);
- LiveData<List<MediaController>> activeMediaControllers =
+ LiveData<List<MediaControllerCompat>> activeMediaControllers =
inputFactory.createActiveMediaControllerData();
ActiveMediaSelector mediaSelector = inputFactory.createActiveMediaSelector();
mTopActiveMediaController = map(activeMediaControllers,
@@ -149,11 +159,12 @@
state -> state != null && (state.mConnectionState == ConnectionState.CONNECTED)
? state.mMediaBrowser : null);
- LiveData<MediaController> controllerFromActiveList =
+ LiveData<MediaControllerCompat> controllerFromActiveList =
combine(activeMediaControllers, mSelectedMediaSource,
mediaSelector::getControllerForSource);
- LiveData<MediaController> controllerFromMediaBrowser = mapNonNull(mConnectedMediaBrowser,
- browser -> inputFactory.getControllerForSession(browser.getSessionToken()));
+ LiveData<MediaControllerCompat> controllerFromMediaBrowser =
+ mapNonNull(mConnectedMediaBrowser,
+ browser -> inputFactory.getControllerForSession(browser.getSessionToken()));
// Prefer fetching MediaController from MediaSessionManager's active controller
// list. Otherwise use controller from MediaBrowser (which requires connecting to it).
mMediaController = coalesceNull(controllerFromActiveList, controllerFromMediaBrowser);
@@ -203,7 +214,7 @@
* not connected. Observing the LiveData will attempt to connect to a media browse session if
* possible.
*/
- public LiveData<MediaBrowser> getConnectedMediaBrowser() {
+ public LiveData<MediaBrowserCompat> getConnectedMediaBrowser() {
return mConnectedMediaBrowser;
}
@@ -212,7 +223,7 @@
* source, or emits {@code null} if the media source doesn't support browsing or the browser is
* not connected.
*/
- public LiveData<MediaController> getMediaController() {
+ public LiveData<MediaControllerCompat> getMediaController() {
return mMediaController;
}
@@ -220,7 +231,7 @@
* Returns a LiveData that emits a {@link MediaController} for the primary active media source.
* Note that this may not be from the selected media source.
*/
- public LiveData<MediaController> getTopActiveMediaController() {
+ public LiveData<MediaControllerCompat> getTopActiveMediaController() {
return mTopActiveMediaController;
}
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/playback/MediaMetadataLiveDataTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/playback/MediaMetadataLiveDataTest.java
index 802aeb9..2bcb980 100644
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/playback/MediaMetadataLiveDataTest.java
+++ b/car-media-common/tests/robotests/src/com/android/car/media/common/playback/MediaMetadataLiveDataTest.java
@@ -22,8 +22,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.media.MediaMetadata;
-import android.media.session.MediaController;
+import android.support.v4.media.MediaMetadataCompat;
+import android.support.v4.media.session.MediaControllerCompat;
import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
import androidx.lifecycle.Lifecycle;
@@ -56,11 +56,11 @@
public final TestLifecycleOwner mLifecycleOwner = new TestLifecycleOwner();
@Mock
- private MediaController mMediaController;
+ private MediaControllerCompat mMediaController;
@Mock
- private MediaMetadata mMetadata;
+ private MediaMetadataCompat mMetadata;
@Captor
- private ArgumentCaptor<MediaController.Callback> mCapturedCallback;
+ private ArgumentCaptor<MediaControllerCompat.Callback> mCapturedCallback;
private MediaMetadataLiveData mMediaMetadataLiveData;
@@ -80,7 +80,7 @@
@Test
public void testGetValueOnActive() {
when(mMediaController.getMetadata()).thenReturn(mMetadata);
- CaptureObserver<MediaMetadata> observer = new CaptureObserver<>();
+ CaptureObserver<MediaMetadataCompat> observer = new CaptureObserver<>();
mMediaMetadataLiveData.observe(mLifecycleOwner, observer);
assertThat(observer.getObservedValue()).isEqualTo(mMetadata);
@@ -88,7 +88,7 @@
@Test
public void testDeliversValueToObserver() {
- CaptureObserver<MediaMetadata> observer = new CaptureObserver<>();
+ CaptureObserver<MediaMetadataCompat> observer = new CaptureObserver<>();
mMediaMetadataLiveData.observe(mLifecycleOwner, observer);
mCapturedCallback.getValue().onMetadataChanged(mMetadata);
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/playback/PlaybackStateLiveDataTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/playback/PlaybackStateLiveDataTest.java
index 9537e56..9d3d1ad 100644
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/playback/PlaybackStateLiveDataTest.java
+++ b/car-media-common/tests/robotests/src/com/android/car/media/common/playback/PlaybackStateLiveDataTest.java
@@ -22,8 +22,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.media.session.MediaController;
-import android.media.session.PlaybackState;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.PlaybackStateCompat;
import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
import androidx.lifecycle.Lifecycle;
@@ -56,11 +56,11 @@
public final TestLifecycleOwner mLifecycleOwner = new TestLifecycleOwner();
@Mock
- private MediaController mMediaController;
+ private MediaControllerCompat mMediaController;
@Mock
- private PlaybackState mPlaybackState;
+ private PlaybackStateCompat mPlaybackState;
@Captor
- private ArgumentCaptor<MediaController.Callback> mCapturedCallback;
+ private ArgumentCaptor<MediaControllerCompat.Callback> mCapturedCallback;
private PlaybackStateLiveData mPlaybackStateLiveData;
@@ -80,7 +80,7 @@
@Test
public void testGetValueOnActive() {
when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
- CaptureObserver<PlaybackState> observer = new CaptureObserver<>();
+ CaptureObserver<PlaybackStateCompat> observer = new CaptureObserver<>();
mPlaybackStateLiveData.observe(mLifecycleOwner, observer);
assertThat(observer.getObservedValue()).isEqualTo(mPlaybackState);
@@ -88,7 +88,7 @@
@Test
public void testDeliversValueToObserver() {
- CaptureObserver<PlaybackState> observer = new CaptureObserver<>();
+ CaptureObserver<PlaybackStateCompat> observer = new CaptureObserver<>();
mPlaybackStateLiveData.observe(mLifecycleOwner, observer);
mCapturedCallback.getValue().onPlaybackStateChanged(mPlaybackState);
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/playback/PlaybackViewModelTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/playback/PlaybackViewModelTest.java
index 1b31468..2e926cc 100644
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/playback/PlaybackViewModelTest.java
+++ b/car-media-common/tests/robotests/src/com/android/car/media/common/playback/PlaybackViewModelTest.java
@@ -26,10 +26,11 @@
import static org.robolectric.RuntimeEnvironment.application;
import android.media.MediaDescription;
-import android.media.MediaMetadata;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
-import android.media.session.PlaybackState;
+import android.support.v4.media.MediaDescriptionCompat;
+import android.support.v4.media.MediaMetadataCompat;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.support.v4.media.session.PlaybackStateCompat;
import androidx.annotation.NonNull;
import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
@@ -66,29 +67,32 @@
public final TestLifecycleOwner mLifecycleOwner = new TestLifecycleOwner();
@Mock
- public MediaController mMediaController;
+ public MediaControllerCompat mMediaController;
@Mock
- public MediaMetadata mMediaMetadata;
+ public MediaMetadataCompat mMediaMetadata;
@Mock
public MediaDescription mMediaDescription;
@Mock
- public PlaybackState mPlaybackState;
+ public MediaDescriptionCompat mMediaDescriptionCompat;
+ @Mock
+ public PlaybackStateCompat mPlaybackState;
@Captor
- private ArgumentCaptor<MediaController.Callback> mCapturedCallback;
+ private ArgumentCaptor<MediaControllerCompat.Callback> mCapturedCallback;
private PlaybackViewModel mPlaybackViewModel;
@Before
public void setUp() {
doNothing().when(mMediaController).registerCallback(mCapturedCallback.capture());
- when(mMediaMetadata.getDescription()).thenReturn(mMediaDescription);
+ when(mMediaDescriptionCompat.getMediaDescription()).thenReturn(mMediaDescription);
+ when(mMediaMetadata.getDescription()).thenReturn(mMediaDescriptionCompat);
mPlaybackViewModel = new PlaybackViewModel(application);
mPlaybackViewModel.setMediaController(dataOf(mMediaController));
}
@Test
public void testGetMediaController() {
- CaptureObserver<MediaController> observer = new CaptureObserver<>();
+ CaptureObserver<MediaControllerCompat> observer = new CaptureObserver<>();
mPlaybackViewModel.getMediaController().observe(mLifecycleOwner, observer);
assertThat(observer.getObservedValue()).isEqualTo(mMediaController);
@@ -111,7 +115,7 @@
@Test
public void testGetPlaybackState() {
- CaptureObserver<PlaybackState> observer = new CaptureObserver<>();
+ CaptureObserver<PlaybackStateCompat> observer = new CaptureObserver<>();
mPlaybackViewModel.getPlaybackState().observe(mLifecycleOwner, observer);
observer.reset();
@@ -126,8 +130,8 @@
public void testGetSanitizedQueue() {
String title = "title";
int queueId = 1;
- MediaSession.QueueItem queueItem = createQueueItem(title, queueId);
- List<MediaSession.QueueItem> queue = Collections.singletonList(queueItem);
+ MediaSessionCompat.QueueItem queueItem = createQueueItem(title, queueId);
+ List<MediaSessionCompat.QueueItem> queue = Collections.singletonList(queueItem);
CaptureObserver<List<MediaItemMetadata>> observer = new CaptureObserver<>();
mPlaybackViewModel.getQueue().observe(mLifecycleOwner, observer);
observer.reset();
@@ -160,7 +164,7 @@
@Test
public void testGetHasQueue_empty() {
- List<MediaSession.QueueItem> queue = Collections.emptyList();
+ List<MediaSessionCompat.QueueItem> queue = Collections.emptyList();
CaptureObserver<Boolean> observer = new CaptureObserver<>();
mPlaybackViewModel.hasQueue().observe(mLifecycleOwner, observer);
mCapturedCallback.getValue().onQueueChanged(
@@ -175,7 +179,8 @@
@Test
public void testGetHasQueue_true() {
- List<MediaSession.QueueItem> queue = Collections.singletonList(createQueueItem("title", 1));
+ List<MediaSessionCompat.QueueItem> queue =
+ Collections.singletonList(createQueueItem("title", 1));
CaptureObserver<Boolean> observer = new CaptureObserver<>();
mPlaybackViewModel.hasQueue().observe(mLifecycleOwner, observer);
observer.reset();
@@ -194,14 +199,14 @@
deliverValuesToCallbacks(mCapturedCallback, mMediaMetadata, mPlaybackState);
// Create new MediaController and associated callback captor
- MediaController newController = mock(MediaController.class);
- ArgumentCaptor<MediaController.Callback> newCallbackCaptor =
- ArgumentCaptor.forClass(MediaController.Callback.class);
+ MediaControllerCompat newController = mock(MediaControllerCompat.class);
+ ArgumentCaptor<MediaControllerCompat.Callback> newCallbackCaptor =
+ ArgumentCaptor.forClass(MediaControllerCompat.Callback.class);
doNothing().when(newController).registerCallback(newCallbackCaptor.capture());
// Wire up new data for new MediaController
- MediaMetadata newMetadata = mock(MediaMetadata.class);
- PlaybackState newPlaybackState = mock(PlaybackState.class);
+ MediaMetadataCompat newMetadata = mock(MediaMetadataCompat.class);
+ PlaybackStateCompat newPlaybackState = mock(PlaybackStateCompat.class);
when(newController.getMetadata()).thenReturn(newMetadata);
when(newController.getPlaybackState()).thenReturn(newPlaybackState);
@@ -223,18 +228,19 @@
}
private void deliverValuesToCallbacks(
- ArgumentCaptor<MediaController.Callback> callbackCaptor,
- MediaMetadata metadata,
- PlaybackState playbackState) {
- for (MediaController.Callback callback : callbackCaptor.getAllValues()) {
+ ArgumentCaptor<MediaControllerCompat.Callback> callbackCaptor,
+ MediaMetadataCompat metadata,
+ PlaybackStateCompat playbackState) {
+ for (MediaControllerCompat.Callback callback : callbackCaptor.getAllValues()) {
callback.onMetadataChanged(metadata);
callback.onPlaybackStateChanged(playbackState);
}
}
@NonNull
- private MediaSession.QueueItem createQueueItem(String title, int queueId) {
- MediaDescription description = new MediaDescription.Builder().setTitle(title).build();
- return new MediaSession.QueueItem(description, queueId);
+ private MediaSessionCompat.QueueItem createQueueItem(String title, int queueId) {
+ MediaDescriptionCompat description =
+ new MediaDescriptionCompat.Builder().setTitle(title).build();
+ return new MediaSessionCompat.QueueItem(description, queueId);
}
}
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/playback/ProgressLiveDataTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/playback/ProgressLiveDataTest.java
index d147f77..955ef92 100644
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/playback/ProgressLiveDataTest.java
+++ b/car-media-common/tests/robotests/src/com/android/car/media/common/playback/ProgressLiveDataTest.java
@@ -16,12 +16,12 @@
package com.android.car.media.common.playback;
+import android.support.v4.media.session.PlaybackStateCompat;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
-import android.media.session.PlaybackState;
-
import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
import androidx.lifecycle.Lifecycle;
@@ -58,7 +58,7 @@
public final TestLifecycleOwner mLifecycleOwner = new TestLifecycleOwner();
@Mock
- private PlaybackState mPlaybackState;
+ private PlaybackStateCompat mPlaybackState;
private long mLastPositionUpdateTime;
private long mCurrentElapsedTime;
@@ -73,7 +73,7 @@
invocation -> mLastPositionUpdateTime);
when(mPlaybackState.getPosition()).thenReturn(START_PROGRESS);
when(mPlaybackState.getPlaybackSpeed()).thenReturn(1F);
- when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING);
+ when(mPlaybackState.getState()).thenReturn(PlaybackStateCompat.STATE_PLAYING);
mProgressLiveData = new ProgressLiveData(mPlaybackState, MAX_PROGRESS,
this::getCurrentElapsedTime);
}
@@ -99,12 +99,13 @@
@Test
public void testUnknownProgress() {
CaptureObserver<Long> progressObserver = new CaptureObserver<>();
- when(mPlaybackState.getPosition()).thenReturn(PlaybackState.PLAYBACK_POSITION_UNKNOWN);
+ when(mPlaybackState.getPosition())
+ .thenReturn(PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN);
mProgressLiveData.observe(mLifecycleOwner, progressObserver);
assertThat(progressObserver.hasBeenNotified()).isTrue();
assertThat(progressObserver.getObservedValue()).isEqualTo(
- PlaybackState.PLAYBACK_POSITION_UNKNOWN);
+ PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN);
}
@Test
@@ -139,7 +140,7 @@
public void testDoesntMoveForwardWhenPaused() {
CaptureObserver<Long> progressObserver = new CaptureObserver<>();
mProgressLiveData.observe(mLifecycleOwner, progressObserver);
- when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PAUSED);
+ when(mPlaybackState.getState()).thenReturn(PlaybackStateCompat.STATE_PAUSED);
progressObserver.reset();
advanceElapsedTime(ProgressLiveData.UPDATE_INTERVAL_MS);
@@ -153,7 +154,7 @@
public void testDoesntMoveForwardWhenStopped() {
CaptureObserver<Long> progressObserver = new CaptureObserver<>();
mProgressLiveData.observe(mLifecycleOwner, progressObserver);
- when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_STOPPED);
+ when(mPlaybackState.getState()).thenReturn(PlaybackStateCompat.STATE_STOPPED);
progressObserver.reset();
advanceElapsedTime(ProgressLiveData.UPDATE_INTERVAL_MS);
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/playback/QueueLiveDataTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/playback/QueueLiveDataTest.java
index bad5073..06f6f64 100644
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/playback/QueueLiveDataTest.java
+++ b/car-media-common/tests/robotests/src/com/android/car/media/common/playback/QueueLiveDataTest.java
@@ -22,8 +22,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
import androidx.lifecycle.Lifecycle;
@@ -59,9 +59,9 @@
public final TestLifecycleOwner mLifecycleOwner = new TestLifecycleOwner();
@Mock
- private MediaController mMediaController;
+ private MediaControllerCompat mMediaController;
@Captor
- private ArgumentCaptor<MediaController.Callback> mCapturedCallback;
+ private ArgumentCaptor<MediaControllerCompat.Callback> mCapturedCallback;
private QueueLiveData mQueueLiveData;
@@ -80,9 +80,9 @@
@Test
public void testGetValueOnActive() {
- List<MediaSession.QueueItem> queue = Collections.emptyList();
+ List<MediaSessionCompat.QueueItem> queue = Collections.emptyList();
when(mMediaController.getQueue()).thenReturn(queue);
- CaptureObserver<List<MediaSession.QueueItem>> observer = new CaptureObserver<>();
+ CaptureObserver<List<MediaSessionCompat.QueueItem>> observer = new CaptureObserver<>();
mQueueLiveData.observe(mLifecycleOwner, observer);
assertThat(observer.getObservedValue()).isEqualTo(queue);
@@ -90,9 +90,9 @@
@Test
public void testDeliversValueToObserver() {
- CaptureObserver<List<MediaSession.QueueItem>> observer = new CaptureObserver<>();
+ CaptureObserver<List<MediaSessionCompat.QueueItem>> observer = new CaptureObserver<>();
mQueueLiveData.observe(mLifecycleOwner, observer);
- List<MediaSession.QueueItem> queue = Collections.emptyList();
+ List<MediaSessionCompat.QueueItem> queue = Collections.emptyList();
mCapturedCallback.getValue().onQueueChanged(queue);
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/source/ActiveMediaControllersLiveDataTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/source/ActiveMediaControllersLiveDataTest.java
index 570f0db..cccae6e 100644
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/source/ActiveMediaControllersLiveDataTest.java
+++ b/car-media-common/tests/robotests/src/com/android/car/media/common/source/ActiveMediaControllersLiveDataTest.java
@@ -27,6 +27,7 @@
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
import android.media.session.MediaSessionManager.OnActiveSessionsChangedListener;
+import android.support.v4.media.session.MediaControllerCompat;
import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
import androidx.lifecycle.Lifecycle;
@@ -67,10 +68,14 @@
public MediaController mFirstMediaController;
@Mock
public MediaController mSecondMediaController;
+ @Mock
+ public MediaControllerCompat mFirstMediaControllerCompat;
+ @Mock
+ public MediaControllerCompat mSecondMediaControllerCompat;
@Captor
public ArgumentCaptor<OnActiveSessionsChangedListener> mSessionChangeListenerCaptor;
@Captor
- public ArgumentCaptor<MediaController.Callback> mFirstControllerCallbackCaptor;
+ public ArgumentCaptor<MediaControllerCompat.Callback> mFirstControllerCallbackCaptor;
private List<MediaController> mMediaControllerList;
@@ -82,7 +87,7 @@
mMediaControllerList.add(mFirstMediaController);
mMediaControllerList.add(mSecondMediaController);
- doNothing().when(mFirstMediaController)
+ doNothing().when(mFirstMediaControllerCompat)
.registerCallback(mFirstControllerCallbackCaptor.capture());
doNothing().when(mMediaSessionManager).addOnActiveSessionsChangedListener(
mSessionChangeListenerCaptor.capture(), any());
@@ -98,35 +103,48 @@
when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllerList);
- mLiveData = new ActiveMediaControllersLiveData(mMediaSessionManager);
+ mLiveData = new ActiveMediaControllersLiveData(mMediaSessionManager) {
+ @Override
+ protected MediaControllerCompat fromMediaController(MediaController mediaController) {
+ if (mediaController == mFirstMediaController) {
+ return mFirstMediaControllerCompat;
+ } else if (mediaController == mSecondMediaController) {
+ return mSecondMediaControllerCompat;
+ }
+ return null;
+ }
+ };
}
@Test
public void testFetchOnActive() {
- CaptureObserver<List<MediaController>> observer = new CaptureObserver<>();
+ CaptureObserver<List<MediaControllerCompat>> observer = new CaptureObserver<>();
mLiveData.observe(mLifecycleOwner, observer);
assertThat(observer.hasBeenNotified()).isTrue();
- assertThat(observer.getObservedValue()).isEqualTo(mMediaControllerList);
+ List<MediaControllerCompat> mediaControllerCompatList = new ArrayList<>();
+ mediaControllerCompatList.add(mFirstMediaControllerCompat);
+ mediaControllerCompatList.add(mSecondMediaControllerCompat);
+ assertThat(observer.getObservedValue()).isEqualTo(mediaControllerCompatList);
}
@Test
public void testPlaybackStateChangedTriggersUpdate() {
- CaptureObserver<List<MediaController>> observer = new CaptureObserver<>();
+ CaptureObserver<List<MediaControllerCompat>> observer = new CaptureObserver<>();
mLiveData.observe(mLifecycleOwner, observer);
observer.reset();
mFirstControllerCallbackCaptor.getValue()
- .onPlaybackStateChanged(mFirstMediaController.getPlaybackState());
+ .onPlaybackStateChanged(mFirstMediaControllerCompat.getPlaybackState());
assertThat(observer.hasBeenNotified()).isTrue();
}
@Test
public void testSessionDestroyedTriggersUpdate() {
- CaptureObserver<List<MediaController>> observer = new CaptureObserver<>();
+ CaptureObserver<List<MediaControllerCompat>> observer = new CaptureObserver<>();
mLiveData.observe(mLifecycleOwner, observer);
observer.reset();
@@ -137,7 +155,7 @@
@Test
public void testUnregisterOnInactive() {
- CaptureObserver<List<MediaController>> observer = new CaptureObserver<>();
+ CaptureObserver<List<MediaControllerCompat>> observer = new CaptureObserver<>();
mLiveData.observe(mLifecycleOwner, observer);
observer.reset();
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/source/ActiveMediaSelectorTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/source/ActiveMediaSelectorTest.java
index 429ace1..a95f9ed 100644
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/source/ActiveMediaSelectorTest.java
+++ b/car-media-common/tests/robotests/src/com/android/car/media/common/source/ActiveMediaSelectorTest.java
@@ -22,9 +22,9 @@
import static org.robolectric.RuntimeEnvironment.application;
import android.content.SharedPreferences;
-import android.media.session.MediaController;
-import android.media.session.PlaybackState;
import android.preference.PreferenceManager;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.PlaybackStateCompat;
import androidx.annotation.Nullable;
import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
@@ -61,11 +61,11 @@
public final TestLifecycleOwner mLifecycleOwner = new TestLifecycleOwner();
@Mock
- public MediaController mFirstMediaController;
+ public MediaControllerCompat mFirstMediaController;
@Mock
- public MediaController mSecondMediaController;
+ public MediaControllerCompat mSecondMediaController;
- private List<MediaController> mMediaControllerList;
+ private List<MediaControllerCompat> mMediaControllerList;
private SharedPreferences mSharedPreferences;
private ActiveMediaSelector mSelector;
@@ -80,9 +80,9 @@
mMediaControllerList.add(mFirstMediaController);
mMediaControllerList.add(mSecondMediaController);
- setControllerState(mFirstMediaController, PlaybackState.STATE_PLAYING);
+ setControllerState(mFirstMediaController, PlaybackStateCompat.STATE_PLAYING);
when(mFirstMediaController.getPackageName()).thenReturn(TEST_PACKAGE_1);
- setControllerState(mSecondMediaController, PlaybackState.STATE_PLAYING);
+ setControllerState(mSecondMediaController, PlaybackStateCompat.STATE_PLAYING);
when(mSecondMediaController.getPackageName()).thenReturn(TEST_PACKAGE_2);
@@ -97,7 +97,7 @@
@Test
public void testPickPlayingController() {
- setControllerState(mFirstMediaController, PlaybackState.STATE_PAUSED);
+ setControllerState(mFirstMediaController, PlaybackStateCompat.STATE_PAUSED);
assertThat(mSelector.getTopMostMediaController(mMediaControllerList, null))
.isSameAs(mSecondMediaController);
@@ -105,8 +105,8 @@
@Test
public void testUsedLastWhenAllPaused() {
- setControllerState(mFirstMediaController, PlaybackState.STATE_PAUSED);
- setControllerState(mSecondMediaController, PlaybackState.STATE_PAUSED);
+ setControllerState(mFirstMediaController, PlaybackStateCompat.STATE_PAUSED);
+ setControllerState(mSecondMediaController, PlaybackStateCompat.STATE_PAUSED);
setLastObservedController(mSecondMediaController);
assertThat(mSelector.getTopMostMediaController(mMediaControllerList, null))
@@ -124,8 +124,8 @@
assertThat(mSelector.getControllerForPackage(mMediaControllerList, "")).isNull();
}
- private void setLastObservedController(@Nullable MediaController mediaController) {
- List<MediaController> mediaControllers =
+ private void setLastObservedController(@Nullable MediaControllerCompat mediaController) {
+ List<MediaControllerCompat> mediaControllers =
mediaController == null ? Collections.emptyList()
: Collections.singletonList(mediaController);
@@ -137,10 +137,10 @@
injectorData.getTopMostMediaController(mediaControllers, null);
}
- private void setControllerState(MediaController mediaController,
+ private void setControllerState(MediaControllerCompat mediaController,
@PlaybackStateAnnotations.State int state) {
when(mediaController.getPlaybackState())
.thenReturn(
- new PlaybackState.Builder().setState(state, 0, 0).build());
+ new PlaybackStateCompat.Builder().setState(state, 0, 0).build());
}
}
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaBrowserConnectorTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaBrowserConnectorTest.java
index d5cbac0..fb1c891 100644
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaBrowserConnectorTest.java
+++ b/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaBrowserConnectorTest.java
@@ -27,7 +27,7 @@
import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
-import android.media.browse.MediaBrowser;
+import android.support.v4.media.MediaBrowserCompat;
import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
@@ -59,18 +59,18 @@
public final TestLifecycleOwner mLifecycleOwner = new TestLifecycleOwner();
@Mock
- public MediaBrowser mMediaBrowser;
+ public MediaBrowserCompat mMediaBrowser;
private MediaBrowserConnector mLiveData;
- private MediaBrowser.ConnectionCallback mConnectionCallback;
+ private MediaBrowserCompat.ConnectionCallback mConnectionCallback;
@Before
public void setUp() {
mLiveData = new MediaBrowserConnector(application, new ComponentName("", "")) {
@Override
- protected MediaBrowser createMediaBrowser(@NonNull Context context,
+ protected MediaBrowserCompat createMediaBrowser(@NonNull Context context,
@NonNull ComponentName browseService,
- @NonNull MediaBrowser.ConnectionCallback callback) {
+ @NonNull MediaBrowserCompat.ConnectionCallback callback) {
mConnectionCallback = callback;
return mMediaBrowser;
}
diff --git a/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourceViewModelTest.java b/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourceViewModelTest.java
index 0575e9e..c283fce 100644
--- a/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourceViewModelTest.java
+++ b/car-media-common/tests/robotests/src/com/android/car/media/common/source/MediaSourceViewModelTest.java
@@ -24,9 +24,9 @@
import android.annotation.NonNull;
import android.content.ComponentName;
-import android.media.browse.MediaBrowser;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
+import android.support.v4.media.MediaBrowserCompat;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
import androidx.annotation.Nullable;
import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
@@ -67,17 +67,17 @@
@Mock
public SimpleMediaSource mMediaSource;
@Mock
- public MediaBrowser mMediaBrowser;
+ public MediaBrowserCompat mMediaBrowser;
@Mock
public ActiveMediaSelector mActiveMediaSelector;
@Mock
- public MediaController mMediaControllerFromBrowser;
+ public MediaControllerCompat mMediaControllerFromBrowser;
@Mock
- public MediaController mMediaControllerFromSessionManager;
+ public MediaControllerCompat mMediaControllerFromSessionManager;
private final MutableLiveData<List<SimpleMediaSource>> mMediaSources = new MutableLiveData<>();
private final MutableLiveData<MediaBrowserState> mMediaBrowserState = new MutableLiveData<>();
- private final MutableLiveData<List<MediaController>> mActiveMediaControllers =
+ private final MutableLiveData<List<MediaControllerCompat>> mActiveMediaControllers =
new MutableLiveData<>();
private MediaSourceViewModel mViewModel;
@@ -117,12 +117,13 @@
}
@Override
- public LiveData<List<MediaController>> createActiveMediaControllerData() {
+ public LiveData<List<MediaControllerCompat>> createActiveMediaControllerData() {
return mActiveMediaControllers;
}
@Override
- public MediaController getControllerForSession(@Nullable MediaSession.Token token) {
+ public MediaControllerCompat getControllerForSession(
+ @Nullable MediaSessionCompat.Token token) {
return mMediaControllerFromBrowser;
}
});
@@ -169,7 +170,7 @@
@Test
public void testGetMediaController_fromSessionManager() {
- CaptureObserver<MediaController> observer = new CaptureObserver<>();
+ CaptureObserver<MediaControllerCompat> observer = new CaptureObserver<>();
when(mActiveMediaSelector.getControllerForSource(any(), any()))
.thenReturn(mMediaControllerFromSessionManager);
@@ -181,7 +182,7 @@
@Test
public void testGetMediaController_noActiveSession() {
- CaptureObserver<MediaController> observer = new CaptureObserver<>();
+ CaptureObserver<MediaControllerCompat> observer = new CaptureObserver<>();
mMediaControllerFromSessionManager = null;
ComponentName testComponent = new ComponentName("test", "test");
when(mMediaSource.getBrowseServiceComponentName()).thenReturn(testComponent);
@@ -196,7 +197,7 @@
@Test
public void testGetMediaController_noActiveSession_noBrowseService() {
- CaptureObserver<MediaController> observer = new CaptureObserver<>();
+ CaptureObserver<MediaControllerCompat> observer = new CaptureObserver<>();
mMediaControllerFromSessionManager = null;
when(mMediaSource.getBrowseServiceComponentName()).thenReturn(null);
mMediaBrowserState.setValue(new MediaBrowserState(mMediaBrowser,
@@ -211,7 +212,7 @@
@Test
public void testGetMediaController_noActiveSession_notConnected() {
- CaptureObserver<MediaController> observer = new CaptureObserver<>();
+ CaptureObserver<MediaControllerCompat> observer = new CaptureObserver<>();
mMediaControllerFromSessionManager = null;
ComponentName testComponent = new ComponentName("test", "test");
when(mMediaSource.getBrowseServiceComponentName()).thenReturn(testComponent);
@@ -229,7 +230,7 @@
public void testGetActiveMediaController() {
when(mActiveMediaSelector.getTopMostMediaController(any(), any()))
.thenReturn(mMediaControllerFromBrowser);
- CaptureObserver<MediaController> observer = new CaptureObserver<>();
+ CaptureObserver<MediaControllerCompat> observer = new CaptureObserver<>();
mViewModel.getTopActiveMediaController().observe(mLifecycleOwner, observer);