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.app.Service; 19bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.content.Intent; 2045f7ee8201efbda59b57b1fe637a1b9ffef25bb6Daniel Sandlerimport android.graphics.Bitmap; 21dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brownimport android.media.session.MediaSession; 228ae0f34db936a649ddaf9cdd086c224f6514efebRoboErikimport android.media.session.PlaybackState; 23bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.os.Bundle; 24bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.os.IBinder; 25bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport android.os.RemoteException; 268ae0f34db936a649ddaf9cdd086c224f6514efebRoboErikimport android.util.Log; 27bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 28bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport com.android.onemedia.playback.IRequestCallback; 29bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport com.android.onemedia.playback.RequestUtils; 30bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 31bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikimport java.util.ArrayList; 32bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 33bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErikpublic class PlayerService extends Service { 34bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik private static final String TAG = "PlayerService"; 35bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 36bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik private PlayerBinder mBinder; 37bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik private PlayerSession mSession; 3845f7ee8201efbda59b57b1fe637a1b9ffef25bb6Daniel Sandler private NotificationHelper mNotifyHelper; 39bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik private Intent mIntent; 408ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik private boolean mStarted = false; 41bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 42bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik private ArrayList<IPlayerCallback> mCbs = new ArrayList<IPlayerCallback>(); 43bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 44bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 45bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void onCreate() { 468ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik Log.d(TAG, "onCreate"); 47bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mIntent = onCreateServiceIntent(); 488ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (mSession == null) { 498ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mSession = onCreatePlayerController(); 508ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mSession.createSession(); 518ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mSession.setListener(mPlayerListener); 5245f7ee8201efbda59b57b1fe637a1b9ffef25bb6Daniel Sandler mNotifyHelper = new NotificationHelper(this, mSession.mSession); 538ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 54bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 55bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 56bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 57bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public IBinder onBind(Intent intent) { 58bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik if (mBinder == null) { 59bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mBinder = new PlayerBinder(); 60bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 61bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik return mBinder; 62bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 63bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 64bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 65bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public int onStartCommand(Intent intent, int flags, int startId) { 668ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik Log.d(TAG, "onStartCommand"); 67bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik return START_STICKY; 68bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 69bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 70bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 71bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void onDestroy() { 728ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik Log.d(TAG, "onDestroy"); 73bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mSession.onDestroy(); 748ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mSession = null; 758ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 768ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 778ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public void onPlaybackStarted() { 788ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (!mStarted) { 798ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik Log.d(TAG, "Starting self"); 808ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik startService(onCreateServiceIntent()); 8145f7ee8201efbda59b57b1fe637a1b9ffef25bb6Daniel Sandler mNotifyHelper.onStart(); 828ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mStarted = true; 838ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 848ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 858ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 868ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public void onPlaybackEnded() { 878ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik if (mStarted) { 888ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik Log.d(TAG, "Stopping self"); 8945f7ee8201efbda59b57b1fe637a1b9ffef25bb6Daniel Sandler mNotifyHelper.onStop(); 908ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik stopSelf(); 918ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik mStarted = false; 928ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 93bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 94bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 95bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik protected Intent onCreateServiceIntent() { 96bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik return new Intent(this, PlayerService.class).setPackage(getBasePackageName()); 97bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 98bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 99bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik protected PlayerSession onCreatePlayerController() { 100bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik return new PlayerSession(this); 101bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 102bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 103bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik protected ArrayList<String> getAllowedPackages() { 104bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik return null; 105bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 106bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 1078ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik private final PlayerSession.Listener mPlayerListener = new PlayerSession.Listener() { 1088ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik @Override 1098ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik public void onPlayStateChanged(PlaybackState state) { 1108ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik switch (state.getState()) { 11179fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik case PlaybackState.STATE_PLAYING: 1128ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik onPlaybackStarted(); 1138ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik break; 11479fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik case PlaybackState.STATE_STOPPED: 11579fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik case PlaybackState.STATE_ERROR: 1168ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik onPlaybackEnded(); 1178ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik break; 1188ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 1198ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik } 1208ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik }; 1218ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik 122bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public class PlayerBinder extends IPlayerService.Stub { 123bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 124bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void sendRequest(String action, Bundle params, IRequestCallback cb) { 125bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik if (RequestUtils.ACTION_SET_CONTENT.equals(action)) { 126bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mSession.setContent(params); 127bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } else if (RequestUtils.ACTION_SET_NEXT_CONTENT.equals(action)) { 128bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mSession.setNextContent(params); 129bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 130bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 131bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 132bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 133bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void registerCallback(final IPlayerCallback cb) throws RemoteException { 134bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik if (!mCbs.contains(cb)) { 135bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mCbs.add(cb); 136bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik cb.asBinder().linkToDeath(new IBinder.DeathRecipient() { 137bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 138bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void binderDied() { 139bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mCbs.remove(cb); 140bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 141bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik }, 0); 142bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 143bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik try { 144bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik cb.onSessionChanged(getSessionToken()); 145bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } catch (RemoteException e) { 146bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mCbs.remove(cb); 147bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik throw e; 148bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 149bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 150bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 151bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 152bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik public void unregisterCallback(IPlayerCallback cb) throws RemoteException { 153bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik mCbs.remove(cb); 154bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 155bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 156bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik @Override 157dba34ba35cd2042d9a8fecfda56e2abe7a680badJeff Brown public MediaSession.Token getSessionToken() throws RemoteException { 15845f7ee8201efbda59b57b1fe637a1b9ffef25bb6Daniel Sandler if (mSession == null) { 15945f7ee8201efbda59b57b1fe637a1b9ffef25bb6Daniel Sandler Log.e(TAG, "Error in PlayerService: mSession=null in getSessionToken()"); 16045f7ee8201efbda59b57b1fe637a1b9ffef25bb6Daniel Sandler return null; 16145f7ee8201efbda59b57b1fe637a1b9ffef25bb6Daniel Sandler } 162bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik return mSession.getSessionToken(); 163bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 16445f7ee8201efbda59b57b1fe637a1b9ffef25bb6Daniel Sandler 16545f7ee8201efbda59b57b1fe637a1b9ffef25bb6Daniel Sandler @Override 16645f7ee8201efbda59b57b1fe637a1b9ffef25bb6Daniel Sandler public void setIcon(Bitmap icon) { 16745f7ee8201efbda59b57b1fe637a1b9ffef25bb6Daniel Sandler mSession.setIcon(icon); 16845f7ee8201efbda59b57b1fe637a1b9ffef25bb6Daniel Sandler } 169bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik } 170bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik 171bfa153b64b4e8c2faa39a15e87fc9f0300335f20RoboErik} 172