diff options
author | Jeff Brown <jeffbrown@google.com> | 2014-07-14 04:05:08 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2014-07-14 04:38:15 -0700 |
commit | ff0215dd64e5fd4ff366930747e7943fcc40c4ab (patch) | |
tree | cedfda78070d778f79127503211e0d1215ecd904 /tests/OneMedia/src/com/android/onemedia | |
parent | 1a937b04e63539cb1fab1bde601031d415c7156f (diff) | |
download | frameworks_base-ff0215dd64e5fd4ff366930747e7943fcc40c4ab.zip frameworks_base-ff0215dd64e5fd4ff366930747e7943fcc40c4ab.tar.gz frameworks_base-ff0215dd64e5fd4ff366930747e7943fcc40c4ab.tar.bz2 |
Update media session test application for new media router.
Change-Id: I3c19e008d211099b4d7320e3f195850cfb4dd927
Diffstat (limited to 'tests/OneMedia/src/com/android/onemedia')
7 files changed, 224 insertions, 147 deletions
diff --git a/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java b/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java index ee407ad..894377b 100644 --- a/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java +++ b/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java @@ -28,8 +28,6 @@ import android.widget.CheckBox; import android.widget.EditText; import android.widget.TextView; -import com.android.onemedia.playback.Renderer; - public class OnePlayerActivity extends Activity { private static final String TAG = "OnePlayerActivity"; diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerController.java b/tests/OneMedia/src/com/android/onemedia/PlayerController.java index 145b389..802f473 100644 --- a/tests/OneMedia/src/com/android/onemedia/PlayerController.java +++ b/tests/OneMedia/src/com/android/onemedia/PlayerController.java @@ -18,7 +18,6 @@ package com.android.onemedia; import android.media.MediaMetadata; import android.media.session.MediaController; -import android.media.session.RouteInfo; import android.media.session.MediaSessionManager; import android.media.session.PlaybackState; import android.os.Bundle; @@ -121,7 +120,7 @@ public class PlayerController { } public void showRoutePicker() { - mController.showRoutePicker(); + // TODO } private void unbindFromService() { @@ -173,11 +172,6 @@ public class PlayerController { private class SessionCallback extends MediaController.Callback { @Override - public void onRouteChanged(RouteInfo route) { - // TODO - } - - @Override public void onPlaybackStateChanged(PlaybackState state) { if (state == null) { return; diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java index a220107..7c0eabe 100644 --- a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java +++ b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java @@ -17,14 +17,17 @@ package com.android.onemedia; import android.content.Context; import android.content.Intent; -import android.media.session.Route; -import android.media.session.RouteInfo; -import android.media.session.RouteOptions; -import android.media.session.RoutePlaybackControls; +import android.media.routing.MediaRouteSelector; +import android.media.routing.MediaRouter; +import android.media.routing.MediaRouter.ConnectionRequest; +import android.media.routing.MediaRouter.DestinationInfo; +import android.media.routing.MediaRouter.RouteInfo; import android.media.session.MediaSession; import android.media.session.MediaSessionManager; import android.media.session.PlaybackState; import android.os.Bundle; +import android.support.media.protocols.MediaPlayerProtocol; +import android.support.media.protocols.MediaPlayerProtocol.MediaStatus; import android.util.Log; import android.view.KeyEvent; @@ -34,11 +37,13 @@ import com.android.onemedia.playback.Renderer; import com.android.onemedia.playback.RequestUtils; import java.util.ArrayList; +import java.util.List; public class PlayerSession { private static final String TAG = "PlayerSession"; protected MediaSession mSession; + protected MediaRouter mRouter; protected Context mContext; protected Renderer mRenderer; protected MediaSession.Callback mCallback; @@ -46,10 +51,6 @@ public class PlayerSession { protected PlaybackState mPlaybackState; protected Listener mListener; - protected ArrayList<RouteOptions> mRouteOptions; - protected Route mRoute; - protected RoutePlaybackControls mRouteControls; - protected RouteListener mRouteListener; private String mContent; @@ -63,41 +64,53 @@ public class PlayerSession { | PlaybackState.ACTION_PLAY); mRenderer.registerListener(mRenderListener); - - // TODO need an easier way to build route options - mRouteOptions = new ArrayList<RouteOptions>(); - RouteOptions.Builder bob = new RouteOptions.Builder(); - bob.addInterface(RoutePlaybackControls.NAME); - mRouteOptions.add(bob.build()); - mRouteListener = new RouteListener(); } public void createSession() { - if (mSession != null) { - mSession.release(); - } + releaseSession(); + MediaSessionManager man = (MediaSessionManager) mContext .getSystemService(Context.MEDIA_SESSION_SERVICE); Log.d(TAG, "Creating session for package " + mContext.getBasePackageName()); + + mRouter = new MediaRouter(mContext); + mRouter.addSelector(new MediaRouteSelector.Builder() + .addRequiredProtocol(MediaPlayerProtocol.class) + .build()); + mRouter.addSelector(new MediaRouteSelector.Builder() + .setRequiredFeatures(MediaRouter.ROUTE_FEATURE_LIVE_AUDIO) + .setOptionalFeatures(MediaRouter.ROUTE_FEATURE_LIVE_VIDEO) + .build()); + mRouter.setRoutingCallback(new RoutingCallback(), null); + mSession = man.createSession("OneMedia"); mSession.addCallback(mCallback); mSession.addTransportControlsCallback(new TransportCallback()); mSession.setPlaybackState(mPlaybackState); mSession.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); - mSession.setRouteOptions(mRouteOptions); + mSession.setMediaRouter(mRouter); mSession.setActive(true); } public void onDestroy() { - if (mSession != null) { - mSession.release(); - } + releaseSession(); if (mRenderer != null) { mRenderer.unregisterListener(mRenderListener); mRenderer.onDestroy(); } } + private void releaseSession() { + if (mSession != null) { + mSession.release(); + mSession = null; + } + if (mRouter != null) { + mRouter.release(); + mRouter = null; + } + } + public void setListener(Listener listener) { mListener = listener; } @@ -218,40 +231,6 @@ public class PlayerSession { } } } - - @Override - public void onRequestRouteChange(RouteInfo route) { - if (mRenderer != null) { - mRenderer.onStop(); - } - if (route == null) { - // Use local route - mRoute = null; - mRenderer = new LocalRenderer(mContext, null); - mRenderer.registerListener(mRenderListener); - updateState(PlaybackState.STATE_NONE); - } else { - // Use remote route - mSession.connect(route, mRouteOptions.get(0)); - mRenderer = null; - updateState(PlaybackState.STATE_CONNECTING); - } - } - - @Override - public void onRouteConnected(Route route) { - mRoute = route; - mRouteControls = RoutePlaybackControls.from(route); - mRouteControls.addListener(mRouteListener); - Log.d(TAG, "Connected to route, registering listener"); - mRenderer = new OneMRPRenderer(mRouteControls); - updateState(PlaybackState.STATE_NONE); - } - - @Override - public void onRouteDisconnected(Route route, int reason) { - - } } private class TransportCallback extends MediaSession.TransportControlsCallback { @@ -266,12 +245,62 @@ public class PlayerSession { } } - private class RouteListener extends RoutePlaybackControls.Listener { + private class RoutingCallback extends MediaRouter.RoutingCallback { @Override - public void onPlaybackStateChange(int state) { - Log.d(TAG, "Updating state to " + state); - updateState(state); + public void onConnectionStateChanged(int state) { + if (state == MediaRouter.CONNECTION_STATE_CONNECTING) { + if (mRenderer != null) { + mRenderer.onStop(); + } + mRenderer = null; + updateState(PlaybackState.STATE_CONNECTING); + return; + } + + MediaRouter.ConnectionInfo connection = mRouter.getConnection(); + if (connection != null) { + MediaPlayerProtocol protocol = + connection.getProtocolObject(MediaPlayerProtocol.class); + if (protocol != null) { + Log.d(TAG, "Connected to route using media player protocol"); + + protocol.setCallback(new PlayerCallback(), null); + mRenderer = new OneMRPRenderer(protocol); + updateState(PlaybackState.STATE_NONE); + return; + } + } + + // Use local route + mRenderer = new LocalRenderer(mContext, null); + mRenderer.registerListener(mRenderListener); + updateState(PlaybackState.STATE_NONE); } } + private class PlayerCallback extends MediaPlayerProtocol.Callback { + @Override + public void onStatusUpdated(MediaStatus status, Bundle extras) { + if (status != null) { + Log.d(TAG, "Received status update: " + status.toBundle()); + switch (status.getPlayerState()) { + case MediaStatus.PLAYER_STATE_BUFFERING: + updateState(PlaybackState.STATE_BUFFERING); + break; + case MediaStatus.PLAYER_STATE_IDLE: + updateState(PlaybackState.STATE_STOPPED); + break; + case MediaStatus.PLAYER_STATE_PAUSED: + updateState(PlaybackState.STATE_PAUSED); + break; + case MediaStatus.PLAYER_STATE_PLAYING: + updateState(PlaybackState.STATE_PLAYING); + break; + case MediaStatus.PLAYER_STATE_UNKNOWN: + updateState(PlaybackState.STATE_NONE); + break; + } + } + } + } } diff --git a/tests/OneMedia/src/com/android/onemedia/playback/MediaItem.java b/tests/OneMedia/src/com/android/onemedia/playback/MediaItem.java index 05516d2..c133325 100644 --- a/tests/OneMedia/src/com/android/onemedia/playback/MediaItem.java +++ b/tests/OneMedia/src/com/android/onemedia/playback/MediaItem.java @@ -15,10 +15,10 @@ */ package com.android.onemedia.playback; +import android.media.MediaMetadata; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; -import android.support.v7.media.MediaItemMetadata; /** * TODO: Insert description here. (generated by epastern) @@ -35,11 +35,11 @@ public class MediaItem implements Parcelable { } public String getTitle() { - return mBundle.getString(MediaItemMetadata.KEY_TITLE); + return mBundle.getString(MediaMetadata.METADATA_KEY_TITLE); } public String getArtist() { - return mBundle.getString(MediaItemMetadata.KEY_ALBUM_ARTIST); + return mBundle.getString(MediaMetadata.METADATA_KEY_ALBUM_ARTIST); } /* (non-Javadoc) diff --git a/tests/OneMedia/src/com/android/onemedia/playback/OneMRPRenderer.java b/tests/OneMedia/src/com/android/onemedia/playback/OneMRPRenderer.java index 9b0a2b2..55eb92c 100644 --- a/tests/OneMedia/src/com/android/onemedia/playback/OneMRPRenderer.java +++ b/tests/OneMedia/src/com/android/onemedia/playback/OneMRPRenderer.java @@ -1,39 +1,42 @@ package com.android.onemedia.playback; -import android.media.session.RoutePlaybackControls; import android.os.Bundle; +import android.support.media.protocols.MediaPlayerProtocol; +import android.support.media.protocols.MediaPlayerProtocol.MediaInfo; /** * Renderer for communicating with the OneMRP route */ public class OneMRPRenderer extends Renderer { - private final RoutePlaybackControls mControls; + private final MediaPlayerProtocol mProtocol; - public OneMRPRenderer(RoutePlaybackControls controls) { + public OneMRPRenderer(MediaPlayerProtocol protocol) { super(null, null); - mControls = controls; + mProtocol = protocol; } @Override public void setContent(Bundle request) { - mControls.playNow(request.getString(RequestUtils.EXTRA_KEY_SOURCE)); + MediaInfo mediaInfo = new MediaInfo(request.getString(RequestUtils.EXTRA_KEY_SOURCE), + MediaInfo.STREAM_TYPE_BUFFERED, "audio/mp3"); + mProtocol.load(mediaInfo, true, 0, null); } @Override public boolean onStop() { - mControls.pause(); + mProtocol.stop(null); return true; } @Override public boolean onPlay() { - mControls.resume(); + mProtocol.play(null); return true; } @Override public boolean onPause() { - mControls.pause(); + mProtocol.pause(null); return true; } diff --git a/tests/OneMedia/src/com/android/onemedia/playback/RequestUtils.java b/tests/OneMedia/src/com/android/onemedia/playback/RequestUtils.java index dd0d982..3778c5f 100644 --- a/tests/OneMedia/src/com/android/onemedia/playback/RequestUtils.java +++ b/tests/OneMedia/src/com/android/onemedia/playback/RequestUtils.java @@ -16,7 +16,6 @@ package com.android.onemedia.playback; import android.os.Bundle; -import android.support.v7.media.MediaItemMetadata; import java.util.HashMap; import java.util.Map; diff --git a/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java b/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java index f2d691c..2e1478b 100644 --- a/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java +++ b/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java @@ -15,19 +15,20 @@ */ package com.android.onemedia.provider; -import android.media.routeprovider.RouteConnection; -import android.media.routeprovider.RouteInterfaceHandler; -import android.media.routeprovider.RoutePlaybackControlsHandler; -import android.media.routeprovider.RouteProviderService; -import android.media.routeprovider.RouteRequest; -import android.media.session.RouteInfo; -import android.media.session.RoutePlaybackControls; -import android.media.session.RouteInterface; +import android.media.routing.MediaRouteSelector; +import android.media.routing.MediaRouteService; +import android.media.routing.MediaRouter.ConnectionInfo; +import android.media.routing.MediaRouter.ConnectionRequest; +import android.media.routing.MediaRouter.DestinationInfo; +import android.media.routing.MediaRouter.DiscoveryRequest; +import android.media.routing.MediaRouter.RouteInfo; import android.media.session.PlaybackState; import android.os.Bundle; import android.os.Handler; -import android.os.Looper; -import android.os.ResultReceiver; +import android.os.Process; +import android.support.media.protocols.MediaPlayerProtocol; +import android.support.media.protocols.MediaPlayerProtocol.MediaInfo; +import android.support.media.protocols.MediaPlayerProtocol.MediaStatus; import android.util.Log; import com.android.onemedia.playback.LocalRenderer; @@ -35,29 +36,28 @@ import com.android.onemedia.playback.Renderer; import com.android.onemedia.playback.RequestUtils; import java.util.ArrayList; -import java.util.List; -import java.util.UUID; /** * Test of MediaRouteProvider. Show a dummy provider with a simple interface for * playing music. */ -public class OneMediaRouteProvider extends RouteProviderService { +public class OneMediaRouteProvider extends MediaRouteService { private static final String TAG = "OneMRP"; private static final boolean DEBUG = true; + private static final String TEST_DESTINATION_ID = "testDestination"; + private static final String TEST_ROUTE_ID = "testRoute"; + private Renderer mRenderer; private RenderListener mRenderListener; private PlaybackState mPlaybackState; - private RouteConnection mConnection; - private RoutePlaybackControlsHandler mControls; - private String mRouteId; private Handler mHandler; + private OneStub mStub; + @Override public void onCreate() { mHandler = new Handler(); - mRouteId = UUID.randomUUID().toString(); mRenderer = new LocalRenderer(this, null); mRenderListener = new RenderListener(); mPlaybackState = new PlaybackState(); @@ -65,81 +65,106 @@ public class OneMediaRouteProvider extends RouteProviderService { | PlaybackState.ACTION_PLAY); mRenderer.registerListener(mRenderListener); + } - if (DEBUG) { - Log.d(TAG, "onCreate, routeId is " + mRouteId); + @Override + public ClientSession onCreateClientSession(ClientInfo client) { + if (client.getUid() != Process.myUid()) { + // for testing purposes, only allow connections from this application + // since this provider is not fully featured + return null; } + return new OneSession(client); } - @Override - public List<RouteInfo> getMatchingRoutes(List<RouteRequest> requests) { - RouteInfo.Builder bob = new RouteInfo.Builder(); - bob.setName("OneMedia").setId(mRouteId); - // TODO add a helper library for generating route info with the correct - // options - Log.d(TAG, "Requests:"); - for (RouteRequest request : requests) { - List<String> ifaces = request.getConnectionOptions().getInterfaceNames(); - Log.d(TAG, " request ifaces:" + ifaces.toString()); - if (ifaces != null && ifaces.size() == 1 - && RoutePlaybackControls.NAME.equals(ifaces.get(0))) { - bob.addRouteOptions(request.getConnectionOptions()); + private final class OneSession extends ClientSession { + private final ClientInfo mClient; + + public OneSession(ClientInfo client) { + mClient = client; + } + + @Override + public boolean onStartDiscovery(DiscoveryRequest req, DiscoveryCallback callback) { + for (MediaRouteSelector selector : req.getSelectors()) { + if (isMatch(selector)) { + DestinationInfo destination = new DestinationInfo.Builder( + TEST_DESTINATION_ID, getServiceMetadata(), "OneMedia") + .setDescription("Test route from OneMedia app.") + .build(); + ArrayList<RouteInfo> routes = new ArrayList<RouteInfo>(); + routes.add(new RouteInfo.Builder( + TEST_ROUTE_ID, destination, selector).build()); + callback.onDestinationFound(destination, routes); + return true; + } } + return false; } - ArrayList<RouteInfo> result = new ArrayList<RouteInfo>(); - if (bob.getOptionsSize() > 0) { - RouteInfo info = bob.build(); - result.add(info); + + @Override + public void onStopDiscovery() { } - if (DEBUG) { - Log.d(TAG, "getRoutes returning " + result.toString()); + + @Override + public boolean onConnect(ConnectionRequest req, ConnectionCallback callback) { + if (req.getRoute().getId().equals(TEST_ROUTE_ID)) { + mStub = new OneStub(); + ConnectionInfo connection = new ConnectionInfo.Builder(req.getRoute()) + .setProtocolStub(MediaPlayerProtocol.class, mStub) + .build(); + callback.onConnected(connection); + return true; + } + return false; } - return result; - } - @Override - public RouteConnection connect(RouteInfo route, RouteRequest request) { - if (mConnection != null) { - disconnect(mConnection); + @Override + public void onDisconnect() { + mStub = null; } - RouteConnection connection = new RouteConnection(this, route); - mControls = RoutePlaybackControlsHandler.addTo(connection); - mControls.addListener(new PlayHandler(mRouteId), mHandler); - if (DEBUG) { - Log.d(TAG, "Connected to route"); + + private boolean isMatch(MediaRouteSelector selector) { + if (!selector.containsProtocol(MediaPlayerProtocol.class)) { + return false; + } + for (String protocol : selector.getRequiredProtocols()) { + if (!protocol.equals(MediaPlayerProtocol.class.getName())) { + return false; + } + } + return true; } - return connection; } - private class PlayHandler extends RoutePlaybackControlsHandler.Listener { - private final String mRouteId; + private final class OneStub extends MediaPlayerProtocol.Stub { + MediaInfo mMediaInfo; - public PlayHandler(String routeId) { - mRouteId = routeId; + public OneStub() { + super(mHandler); } @Override - public void playNow(String content, ResultReceiver cb) { + public void onLoad(MediaInfo mediaInfo, boolean autoplay, long playPosition, + Bundle extras) { if (DEBUG) { - Log.d(TAG, "Attempting to play " + content); + Log.d(TAG, "Attempting to play " + mediaInfo.getContentId()); } // look up the route and send a play command to it + mMediaInfo = mediaInfo; Bundle bundle = new Bundle(); - bundle.putString(RequestUtils.EXTRA_KEY_SOURCE, content); + bundle.putString(RequestUtils.EXTRA_KEY_SOURCE, mediaInfo.getContentId()); mRenderer.setContent(bundle); - RouteInterfaceHandler.sendResult(cb, RouteInterface.RESULT_SUCCESS, null); } @Override - public boolean resume() { + public void onPlay(Bundle extras) { mRenderer.onPlay(); - return true; } @Override - public boolean pause() { + public void onPause(Bundle extras) { mRenderer.onPause(); - return true; } } @@ -148,9 +173,7 @@ public class OneMediaRouteProvider extends RouteProviderService { @Override public void onError(int type, int extra, Bundle extras, Throwable error) { Log.d(TAG, "Sending onError with type " + type + " and extra " + extra); - if (mControls != null) { - mControls.sendPlaybackChangeEvent(PlaybackState.STATE_ERROR); - } + sendStatusUpdate(PlaybackState.STATE_ERROR); } @Override @@ -186,7 +209,7 @@ public class OneMediaRouteProvider extends RouteProviderService { break; } - mControls.sendPlaybackChangeEvent(mPlaybackState.getState()); + sendStatusUpdate(mPlaybackState.getState()); } @Override @@ -203,5 +226,36 @@ public class OneMediaRouteProvider extends RouteProviderService { @Override public void onNextStarted() { } + + private void sendStatusUpdate(int state) { + if (mStub != null) { + MediaStatus status = new MediaStatus(1, mStub.mMediaInfo); + switch (state) { + case PlaybackState.STATE_BUFFERING: + case PlaybackState.STATE_FAST_FORWARDING: + case PlaybackState.STATE_REWINDING: + case PlaybackState.STATE_SKIPPING_TO_NEXT: + case PlaybackState.STATE_SKIPPING_TO_PREVIOUS: + status.setPlayerState(MediaStatus.PLAYER_STATE_BUFFERING); + break; + case PlaybackState.STATE_CONNECTING: + case PlaybackState.STATE_STOPPED: + status.setPlayerState(MediaStatus.PLAYER_STATE_IDLE); + break; + case PlaybackState.STATE_PAUSED: + status.setPlayerState(MediaStatus.PLAYER_STATE_PAUSED); + break; + case PlaybackState.STATE_PLAYING: + status.setPlayerState(MediaStatus.PLAYER_STATE_PLAYING); + break; + case PlaybackState.STATE_NONE: + case PlaybackState.STATE_ERROR: + default: + status.setPlayerState(MediaStatus.PLAYER_STATE_UNKNOWN); + break; + } + mStub.sendStatusUpdatedEvent(status, null); + } + } } } |