PlayerSession.java revision dba34ba35cd2042d9a8fecfda56e2abe7a680bad
18ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik/* 28ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * Copyright (C) 2014 The Android Open Source Project 38ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * 48ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * Licensed under the Apache License, Version 2.0 (the "License"); 58ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * you may not use this file except in compliance with the License. 68ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * You may obtain a copy of the License at 78ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * 88ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * http://www.apache.org/licenses/LICENSE-2.0 98ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * 108ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * Unless required by applicable law or agreed to in writing, software 118ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * distributed under the License is distributed on an "AS IS" BASIS, 128ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * See the License for the specific language governing permissions and 148ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * limitations under the License. 158ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik */ 16bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikpackage com.android.onemedia; 17bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 18bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.content.Context; 19bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.content.Intent; 2007c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErikimport android.media.session.Route; 2107c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErikimport android.media.session.RouteInfo; 2207c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErikimport android.media.session.RouteOptions; 2307c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErikimport android.media.session.RoutePlaybackControls; 2442ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErikimport android.media.session.MediaSession; 2542ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErikimport android.media.session.MediaSessionManager; 268ae0f34db936a649ddaf9cdd086c224f6514efebRoboErikimport android.media.session.PlaybackState; 27bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.os.Bundle; 28bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.util.Log; 29bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.view.KeyEvent; 30bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 31bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport com.android.onemedia.playback.LocalRenderer; 3207c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErikimport com.android.onemedia.playback.OneMRPRenderer; 33bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport com.android.onemedia.playback.Renderer; 3407c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErikimport com.android.onemedia.playback.RequestUtils; 3507c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik 3607c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErikimport java.util.ArrayList; 37bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 38bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikpublic class PlayerSession { 398ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik private static final String TAG = "PlayerSession"; 40bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 4142ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik protected MediaSession mSession; 42bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik protected Context mContext; 4307c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik protected Renderer mRenderer; 4442ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik protected MediaSession.Callback mCallback; 458ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik protected Renderer.Listener mRenderListener; 468ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 478ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik protected PlaybackState mPlaybackState; 488ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik protected Listener mListener; 4907c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik protected ArrayList<RouteOptions> mRouteOptions; 5007c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik protected Route mRoute; 5107c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik protected RoutePlaybackControls mRouteControls; 5207c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik protected RouteListener mRouteListener; 5307c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik 5407c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik private String mContent; 55bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 56bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public PlayerSession(Context context) { 57bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mContext = context; 58bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mRenderer = new LocalRenderer(context, null); 5907c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mCallback = new SessionCb(); 60bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mRenderListener = new RenderListener(); 618ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mPlaybackState = new PlaybackState(); 628ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mPlaybackState.setActions(PlaybackState.ACTION_PAUSE 638ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik | PlaybackState.ACTION_PLAY); 64bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 65bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mRenderer.registerListener(mRenderListener); 6607c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik 6707c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik // TODO need an easier way to build route options 6807c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mRouteOptions = new ArrayList<RouteOptions>(); 6907c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik RouteOptions.Builder bob = new RouteOptions.Builder(); 7007c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik bob.addInterface(RoutePlaybackControls.NAME); 7107c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mRouteOptions.add(bob.build()); 7207c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mRouteListener = new RouteListener(); 73bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 74bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 75bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void createSession() { 76bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik if (mSession != null) { 77bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mSession.release(); 78bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 7942ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik MediaSessionManager man = (MediaSessionManager) mContext 80bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik .getSystemService(Context.MEDIA_SESSION_SERVICE); 81bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik Log.d(TAG, "Creating session for package " + mContext.getBasePackageName()); 82bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mSession = man.createSession("OneMedia"); 83bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mSession.addCallback(mCallback); 84b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik mSession.addTransportControlsCallback(new TransportCallback()); 85c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mSession.setPlaybackState(mPlaybackState); 8642ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik mSession.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); 8707c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mSession.setRouteOptions(mRouteOptions); 88a8f951462791a16f47e8c07e552232f31dcefac5RoboErik mSession.setActive(true); 89bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 90bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 91bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void onDestroy() { 92bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik if (mSession != null) { 93bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mSession.release(); 94bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 95bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik if (mRenderer != null) { 96bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mRenderer.unregisterListener(mRenderListener); 97bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mRenderer.onDestroy(); 98bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 99bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 100bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 1018ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public void setListener(Listener listener) { 1028ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mListener = listener; 1038ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 1048ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 105dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown public MediaSession.Token getSessionToken() { 106bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik return mSession.getSessionToken(); 107bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 108bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 109bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void setContent(Bundle request) { 110bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mRenderer.setContent(request); 11107c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mContent = request.getString(RequestUtils.EXTRA_KEY_SOURCE); 112bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 113bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 114bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void setNextContent(Bundle request) { 115bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mRenderer.setNextContent(request); 116bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 117bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 11807c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik private void updateState(int newState) { 11979fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik float rate = newState == PlaybackState.STATE_PLAYING ? 1 : 0; 120f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik long position = mRenderer == null ? -1 : mRenderer.getSeekPosition(); 121f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik mPlaybackState.setState(newState, position, rate); 122c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mSession.setPlaybackState(mPlaybackState); 12307c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik } 12407c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik 1258ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public interface Listener { 1268ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public void onPlayStateChanged(PlaybackState state); 1278ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 1288ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 1298ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik private class RenderListener implements Renderer.Listener { 130bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 131bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 132bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void onError(int type, int extra, Bundle extras, Throwable error) { 1338ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik Log.d(TAG, "Sending onError with type " + type + " and extra " + extra); 13479fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik mPlaybackState.setState(PlaybackState.STATE_ERROR, -1, 0); 1358ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (error != null) { 1368ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mPlaybackState.setErrorMessage(error.getLocalizedMessage()); 1378ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 138c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mSession.setPlaybackState(mPlaybackState); 1398ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (mListener != null) { 1408ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mListener.onPlayStateChanged(mPlaybackState); 1418ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 142bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 143bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 144bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 145bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void onStateChanged(int newState) { 1468ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (newState != Renderer.STATE_ERROR) { 1478ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mPlaybackState.setErrorMessage(null); 1488ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 149f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik long position = -1; 150f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (mRenderer != null) { 151f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik position = mRenderer.getSeekPosition(); 152f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 1538ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik switch (newState) { 1548ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik case Renderer.STATE_ENDED: 1558ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik case Renderer.STATE_STOPPED: 15679fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik mPlaybackState.setState(PlaybackState.STATE_STOPPED, position, 0); 1578ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik break; 1588ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik case Renderer.STATE_INIT: 1598ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik case Renderer.STATE_PREPARING: 16079fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik mPlaybackState.setState(PlaybackState.STATE_BUFFERING, position, 0); 1618ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik break; 1628ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik case Renderer.STATE_ERROR: 16379fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik mPlaybackState.setState(PlaybackState.STATE_ERROR, position, 0); 1648ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik break; 1658ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik case Renderer.STATE_PAUSED: 16679fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik mPlaybackState.setState(PlaybackState.STATE_PAUSED, position, 0); 1678ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik break; 1688ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik case Renderer.STATE_PLAYING: 16979fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik mPlaybackState.setState(PlaybackState.STATE_PLAYING, position, 1); 1708ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik break; 1718ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik default: 17279fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik mPlaybackState.setState(PlaybackState.STATE_ERROR, position, 0); 1738ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mPlaybackState.setErrorMessage("unkown state"); 1748ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik break; 1758ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 176c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mSession.setPlaybackState(mPlaybackState); 1778ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (mListener != null) { 1788ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mListener.onPlayStateChanged(mPlaybackState); 1798ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 180bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 181bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 182bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 183bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void onBufferingUpdate(int percent) { 184bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 185bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 186bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 187bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void onFocusLost() { 1888ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik Log.d(TAG, "Focus lost, changing state to " + Renderer.STATE_PAUSED); 189f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik long position = mRenderer == null ? -1 : mRenderer.getSeekPosition(); 19079fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik mPlaybackState.setState(PlaybackState.STATE_PAUSED, position, 0); 191c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mSession.setPlaybackState(mPlaybackState); 1928ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (mListener != null) { 1938ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mListener.onPlayStateChanged(mPlaybackState); 1948ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 195bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 196bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 197bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 198bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void onNextStarted() { 199bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 200bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 201bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 202bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 20342ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik private class SessionCb extends MediaSession.Callback { 204bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 20579fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik public void onMediaButtonEvent(Intent mediaRequestIntent) { 206bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik if (Intent.ACTION_MEDIA_BUTTON.equals(mediaRequestIntent.getAction())) { 207bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik KeyEvent event = (KeyEvent) mediaRequestIntent 208bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik .getParcelableExtra(Intent.EXTRA_KEY_EVENT); 209bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik switch (event.getKeyCode()) { 210bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik case KeyEvent.KEYCODE_MEDIA_PLAY: 211bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik Log.d(TAG, "play button received"); 212bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mRenderer.onPlay(); 213bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik break; 214bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik case KeyEvent.KEYCODE_MEDIA_PAUSE: 215bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik Log.d(TAG, "pause button received"); 216bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mRenderer.onPause(); 217bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik break; 218bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 219bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 220bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 22107c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik 22207c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik @Override 22307c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik public void onRequestRouteChange(RouteInfo route) { 22407c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik if (mRenderer != null) { 22507c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mRenderer.onStop(); 22607c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik } 22707c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik if (route == null) { 22807c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik // Use local route 22907c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mRoute = null; 23007c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mRenderer = new LocalRenderer(mContext, null); 23107c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mRenderer.registerListener(mRenderListener); 23279fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik updateState(PlaybackState.STATE_NONE); 23307c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik } else { 23407c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik // Use remote route 23507c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mSession.connect(route, mRouteOptions.get(0)); 23607c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mRenderer = null; 23779fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik updateState(PlaybackState.STATE_CONNECTING); 23807c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik } 23907c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik } 24007c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik 24107c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik @Override 24207c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik public void onRouteConnected(Route route) { 24307c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mRoute = route; 24407c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mRouteControls = RoutePlaybackControls.from(route); 24507c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mRouteControls.addListener(mRouteListener); 24607c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik Log.d(TAG, "Connected to route, registering listener"); 24707c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik mRenderer = new OneMRPRenderer(mRouteControls); 24879fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik updateState(PlaybackState.STATE_NONE); 24907c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik } 25007c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik 25107c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik @Override 25207c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik public void onRouteDisconnected(Route route, int reason) { 25307c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik 25407c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik } 255bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 256bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 257b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik private class TransportCallback extends MediaSession.TransportControlsCallback { 2588ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik @Override 2598ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public void onPlay() { 2608ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mRenderer.onPlay(); 2618ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 2628ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 2638ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik @Override 2648ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public void onPause() { 2658ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mRenderer.onPause(); 2668ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 2678ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 2688ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 26907c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik private class RouteListener extends RoutePlaybackControls.Listener { 27007c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik @Override 27107c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik public void onPlaybackStateChange(int state) { 27207c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik Log.d(TAG, "Updating state to " + state); 27307c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik updateState(state); 27407c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik } 27507c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik } 27607c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik 277bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik} 278