Merge "Remove incomplete media router API." into mnc-dev
This commit is contained in:
@@ -9,9 +9,6 @@ LOCAL_SRC_FILES := $(call all-subdir-java-files) \
|
||||
LOCAL_PACKAGE_NAME := OneMedia
|
||||
LOCAL_CERTIFICATE := platform
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
android-support-media-protocols
|
||||
|
||||
LOCAL_JAVA_LIBRARIES += org.apache.http.legacy
|
||||
|
||||
LOCAL_PROGUARD_ENABLED := disabled
|
||||
|
||||
@@ -27,15 +27,6 @@
|
||||
android:name="com.android.onemedia.OnePlayerService"
|
||||
android:exported="true"
|
||||
android:process="com.android.onemedia.service" />
|
||||
<service
|
||||
android:name=".provider.OneMediaRouteProvider"
|
||||
android:permission="android.permission.BIND_MEDIA_ROUTE_SERVICE"
|
||||
android:exported="true"
|
||||
android:process="com.android.onemedia.provider">
|
||||
<intent-filter>
|
||||
<action android:name="android.media.routing.MediaRouteService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -19,25 +19,17 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.media.MediaMetadata;
|
||||
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.MediaSession.QueueItem;
|
||||
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.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.android.onemedia.playback.LocalRenderer;
|
||||
import com.android.onemedia.playback.OneMRPRenderer;
|
||||
import com.android.onemedia.playback.Renderer;
|
||||
import com.android.onemedia.playback.RequestUtils;
|
||||
|
||||
@@ -48,7 +40,6 @@ 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;
|
||||
@@ -84,22 +75,11 @@ public class PlayerSession {
|
||||
.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 = new MediaSession(mContext, "OneMedia");
|
||||
mSession.setCallback(mCallback);
|
||||
mSession.setPlaybackState(mPlaybackState);
|
||||
mSession.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS
|
||||
| MediaSession.FLAG_HANDLES_MEDIA_BUTTONS);
|
||||
mSession.setMediaRouter(mRouter);
|
||||
mSession.setActive(true);
|
||||
updateMetadata();
|
||||
}
|
||||
@@ -117,10 +97,6 @@ public class PlayerSession {
|
||||
mSession.release();
|
||||
mSession = null;
|
||||
}
|
||||
if (mRouter != null) {
|
||||
mRouter.release();
|
||||
mRouter = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setListener(Listener listener) {
|
||||
@@ -278,63 +254,4 @@ public class PlayerSession {
|
||||
mRenderer.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
private class RoutingCallback extends MediaRouter.RoutingCallback {
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
package com.android.onemedia.playback;
|
||||
|
||||
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 MediaPlayerProtocol mProtocol;
|
||||
|
||||
public OneMRPRenderer(MediaPlayerProtocol protocol) {
|
||||
super(null, null);
|
||||
mProtocol = protocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContent(Bundle request) {
|
||||
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() {
|
||||
mProtocol.stop(null);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPlay() {
|
||||
mProtocol.play(null);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPause() {
|
||||
mProtocol.pause(null);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSeekPosition() {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1,270 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.onemedia.provider;
|
||||
|
||||
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.Process;
|
||||
import android.support.media.protocols.MediaPlayerProtocol;
|
||||
import android.support.media.protocols.MediaPlayerProtocol.MediaInfo;
|
||||
import android.support.media.protocols.MediaPlayerProtocol.MediaStatus;
|
||||
import android.os.Looper;
|
||||
import android.os.ResultReceiver;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.onemedia.playback.LocalRenderer;
|
||||
import com.android.onemedia.playback.Renderer;
|
||||
import com.android.onemedia.playback.RequestUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Test of MediaRouteProvider. Show a dummy provider with a simple interface for
|
||||
* playing music.
|
||||
*/
|
||||
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 Handler mHandler;
|
||||
|
||||
private OneStub mStub;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
mHandler = new Handler();
|
||||
mRenderer = new LocalRenderer(this, null);
|
||||
mRenderListener = new RenderListener();
|
||||
PlaybackState.Builder bob = new PlaybackState.Builder();
|
||||
bob.setActions(PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY);
|
||||
mPlaybackState = bob.build();
|
||||
|
||||
mRenderer.registerListener(mRenderListener);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopDiscovery() {
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect() {
|
||||
mStub = null;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
private final class OneStub extends MediaPlayerProtocol.Stub {
|
||||
MediaInfo mMediaInfo;
|
||||
|
||||
public OneStub() {
|
||||
super(mHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad(MediaInfo mediaInfo, boolean autoplay, long playPosition,
|
||||
Bundle extras) {
|
||||
if (DEBUG) {
|
||||
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, mediaInfo.getContentId());
|
||||
mRenderer.setContent(bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlay(Bundle extras) {
|
||||
mRenderer.onPlay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause(Bundle extras) {
|
||||
mRenderer.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
private class RenderListener implements Renderer.Listener {
|
||||
|
||||
@Override
|
||||
public void onError(int type, int extra, Bundle extras, Throwable error) {
|
||||
Log.d(TAG, "Sending onError with type " + type + " and extra " + extra);
|
||||
sendStatusUpdate(PlaybackState.STATE_ERROR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateChanged(int newState) {
|
||||
long position = -1;
|
||||
if (mRenderer != null) {
|
||||
position = mRenderer.getSeekPosition();
|
||||
}
|
||||
int pbState;
|
||||
float rate = 0;
|
||||
String errorMsg = null;
|
||||
switch (newState) {
|
||||
case Renderer.STATE_ENDED:
|
||||
case Renderer.STATE_STOPPED:
|
||||
pbState = PlaybackState.STATE_STOPPED;
|
||||
break;
|
||||
case Renderer.STATE_INIT:
|
||||
case Renderer.STATE_PREPARING:
|
||||
pbState = PlaybackState.STATE_BUFFERING;
|
||||
break;
|
||||
case Renderer.STATE_ERROR:
|
||||
pbState = PlaybackState.STATE_ERROR;
|
||||
break;
|
||||
case Renderer.STATE_PAUSED:
|
||||
pbState = PlaybackState.STATE_PAUSED;
|
||||
break;
|
||||
case Renderer.STATE_PLAYING:
|
||||
pbState = PlaybackState.STATE_PLAYING;
|
||||
rate = 1;
|
||||
break;
|
||||
default:
|
||||
pbState = PlaybackState.STATE_ERROR;
|
||||
errorMsg = "unknown state";
|
||||
break;
|
||||
}
|
||||
PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState);
|
||||
bob.setState(pbState, position, rate, SystemClock.elapsedRealtime());
|
||||
bob.setErrorMessage(errorMsg);
|
||||
mPlaybackState = bob.build();
|
||||
|
||||
sendStatusUpdate(mPlaybackState.getState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBufferingUpdate(int percent) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFocusLost() {
|
||||
Log.d(TAG, "Focus lost, pausing");
|
||||
// Don't update state here, we'll get a separate call to
|
||||
// onStateChanged when it pauses
|
||||
mRenderer.onPause();
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user