PlayerController.java revision ff0215dd64e5fd4ff366930747e7943fcc40c4ab
1bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 28ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik/* 38ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * Copyright (C) 2014 The Android Open Source Project 48ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * 58ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * Licensed under the Apache License, Version 2.0 (the "License"); 68ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * you may not use this file except in compliance with the License. 78ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * You may obtain a copy of the License at 88ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * 98ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * http://www.apache.org/licenses/LICENSE-2.0 108ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * 118ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * Unless required by applicable law or agreed to in writing, software 128ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * distributed under the License is distributed on an "AS IS" BASIS, 138ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 148ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * See the License for the specific language governing permissions and 158ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * limitations under the License. 168ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik */ 17bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikpackage com.android.onemedia; 18bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 1942ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErikimport android.media.MediaMetadata; 2042ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErikimport android.media.session.MediaController; 2142ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErikimport android.media.session.MediaSessionManager; 228ae0f34db936a649ddaf9cdd086c224f6514efebRoboErikimport android.media.session.PlaybackState; 238ae0f34db936a649ddaf9cdd086c224f6514efebRoboErikimport android.os.Bundle; 24bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.os.Handler; 25bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.os.IBinder; 26bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.os.RemoteException; 27bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.content.ComponentName; 28bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.content.Context; 29bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.content.Intent; 30bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.content.ServiceConnection; 31bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.util.Log; 32bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 33bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport com.android.onemedia.playback.RequestUtils; 34bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 35bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikpublic class PlayerController { 368ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik private static final String TAG = "PlayerController"; 37bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 38bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public static final int STATE_DISCONNECTED = 0; 39bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public static final int STATE_CONNECTED = 1; 40bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 4142ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik protected MediaController mController; 42bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik protected IPlayerService mBinder; 43c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik protected MediaController.TransportControls mTransportControls; 44bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 45bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik private final Intent mServiceIntent; 46bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik private Context mContext; 47bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik private Listener mListener; 48bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik private SessionCallback mControllerCb; 4942ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik private MediaSessionManager mManager; 50bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik private Handler mHandler = new Handler(); 51bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 52bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik private boolean mResumed; 53bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 54bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public PlayerController(Context context, Intent serviceIntent) { 55bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mContext = context; 56bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik if (serviceIntent == null) { 57bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mServiceIntent = new Intent(mContext, PlayerService.class); 58bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } else { 59bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mServiceIntent = serviceIntent; 60bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 61bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mControllerCb = new SessionCallback(); 6242ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik mManager = (MediaSessionManager) context 63bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik .getSystemService(Context.MEDIA_SESSION_SERVICE); 64bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 65bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mResumed = false; 66bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 67bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 68bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void setListener(Listener listener) { 69bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mListener = listener; 70bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik Log.d(TAG, "Listener set to " + listener + " session is " + mController); 71bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik if (mListener != null) { 72bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mHandler = new Handler(); 738ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mListener.onConnectionStateChange( 74bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mController == null ? STATE_DISCONNECTED : STATE_CONNECTED); 75bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 76bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 77bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 78bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void onResume() { 79bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mResumed = true; 80bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik Log.d(TAG, "onResume. Binding to service with intent " + mServiceIntent.toString()); 81bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik bindToService(); 82bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 83bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 84bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void onPause() { 85bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mResumed = false; 86bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik Log.d(TAG, "onPause, unbinding from service"); 87bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik unbindFromService(); 88bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 89bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 90bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void play() { 918ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (mTransportControls != null) { 928ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mTransportControls.play(); 938ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 94bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 95bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 96bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void pause() { 978ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (mTransportControls != null) { 988ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mTransportControls.pause(); 998ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 100bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 101bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 102bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void setContent(String source) { 103bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik RequestUtils.ContentBuilder bob = new RequestUtils.ContentBuilder(); 104bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik bob.setSource(source); 105bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik try { 106bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mBinder.sendRequest(RequestUtils.ACTION_SET_CONTENT, bob.build(), null); 107bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } catch (RemoteException e) { 108bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik Log.d(TAG, "setContent failed, service may have died.", e); 109bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 110bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 111bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 112bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void setNextContent(String source) { 113bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik RequestUtils.ContentBuilder bob = new RequestUtils.ContentBuilder(); 114bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik bob.setSource(source); 115bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik try { 116bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mBinder.sendRequest(RequestUtils.ACTION_SET_NEXT_CONTENT, bob.build(), null); 117bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } catch (RemoteException e) { 118bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik Log.d(TAG, "setNexctContent failed, service may have died.", e); 119bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 120bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 121bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 12207c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik public void showRoutePicker() { 123ff0215dd64e5fd4ff366930747e7943fcc40c4abJeff Brown // TODO 12407c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik } 12507c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik 126bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik private void unbindFromService() { 127bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mContext.unbindService(mServiceConnection); 128bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 129bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 130bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik private void bindToService() { 131bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mContext.bindService(mServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE); 132bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 133bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 134bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik private ServiceConnection mServiceConnection = new ServiceConnection() { 135bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 136bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void onServiceDisconnected(ComponentName name) { 137bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik if (mController != null) { 138bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mController.removeCallback(mControllerCb); 139bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 140bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mBinder = null; 141bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mController = null; 1428ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mTransportControls = null; 143bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik Log.d(TAG, "Disconnected from PlayerService"); 144bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 145bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik if (mListener != null) { 1468ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mListener.onConnectionStateChange(STATE_DISCONNECTED); 147bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 148bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 149bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 150bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 151bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void onServiceConnected(ComponentName name, IBinder service) { 152bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mBinder = IPlayerService.Stub.asInterface(service); 153bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik Log.d(TAG, "service is " + service + " binder is " + mBinder); 154bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik try { 15542ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik mController = MediaController.fromToken(mBinder.getSessionToken()); 156bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } catch (RemoteException e) { 157bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik Log.e(TAG, "Error getting session", e); 158bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik return; 159bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 160bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mController.addCallback(mControllerCb, mHandler); 161c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mTransportControls = mController.getTransportControls(); 162bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik Log.d(TAG, "Ready to use PlayerService"); 163bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 164bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik if (mListener != null) { 1658ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mListener.onConnectionStateChange(STATE_CONNECTED); 1668ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (mTransportControls != null) { 167c47fa84b0a6bda48c38ba8822481ce613bafd019RoboErik mListener.onPlaybackStateChange(mController.getPlaybackState()); 1688ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 169bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 170bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 171bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik }; 172bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 17342ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik private class SessionCallback extends MediaController.Callback { 174bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 1758ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public void onPlaybackStateChanged(PlaybackState state) { 1768ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (state == null) { 1778ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik return; 1788ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 1798ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik Log.d(TAG, "Received playback state change to state " + state.getState()); 180bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik if (mListener != null) { 1818ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mListener.onPlaybackStateChange(state); 182bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 183bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 1848ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 1858ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik @Override 1868ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public void onMetadataChanged(MediaMetadata metadata) { 1878ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (metadata == null) { 1888ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik return; 1898ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 1908ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik Log.d(TAG, "Received metadata change, title is " 1918ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik + metadata.getString(MediaMetadata.METADATA_KEY_TITLE)); 1928ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 193bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 194bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 195bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public interface Listener { 1968ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public void onPlaybackStateChange(PlaybackState state); 1978ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public void onMetadataChange(MediaMetadata metadata); 1988ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public void onConnectionStateChange(int state); 199bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 200bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 201bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik} 202