1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.onemedia;
17 
18 import android.app.Service;
19 import android.content.Intent;
20 import android.graphics.Bitmap;
21 import android.media.session.MediaSession;
22 import android.media.session.PlaybackState;
23 import android.os.Bundle;
24 import android.os.IBinder;
25 import android.os.RemoteException;
26 import android.util.Log;
27 
28 import com.android.onemedia.playback.IRequestCallback;
29 import com.android.onemedia.playback.RequestUtils;
30 
31 import java.util.ArrayList;
32 
33 public class PlayerService extends Service {
34     private static final String TAG = "PlayerService";
35 
36     private PlayerBinder mBinder;
37     private PlayerSession mSession;
38     private NotificationHelper mNotifyHelper;
39     private Intent mIntent;
40     private boolean mStarted = false;
41 
42     private ArrayList<IPlayerCallback> mCbs = new ArrayList<IPlayerCallback>();
43 
44     @Override
onCreate()45     public void onCreate() {
46         Log.d(TAG, "onCreate");
47         mIntent = onCreateServiceIntent();
48         if (mSession == null) {
49             mSession = onCreatePlayerController();
50             mSession.createSession();
51             mSession.setListener(mPlayerListener);
52             mNotifyHelper = new NotificationHelper(this, mSession.mSession);
53         }
54     }
55 
56     @Override
onBind(Intent intent)57     public IBinder onBind(Intent intent) {
58         if (mBinder == null) {
59             mBinder = new PlayerBinder();
60         }
61         return mBinder;
62     }
63 
64     @Override
onStartCommand(Intent intent, int flags, int startId)65     public int onStartCommand(Intent intent, int flags, int startId) {
66         Log.d(TAG, "onStartCommand");
67         return START_STICKY;
68     }
69 
70     @Override
onDestroy()71     public void onDestroy() {
72         Log.d(TAG, "onDestroy");
73         mSession.onDestroy();
74         mSession = null;
75     }
76 
onPlaybackStarted()77     public void onPlaybackStarted() {
78         if (!mStarted) {
79             Log.d(TAG, "Starting self");
80             startService(onCreateServiceIntent());
81             mNotifyHelper.onStart();
82             mStarted = true;
83         }
84     }
85 
onPlaybackEnded()86     public void onPlaybackEnded() {
87         if (mStarted) {
88             Log.d(TAG, "Stopping self");
89             mNotifyHelper.onStop();
90             stopSelf();
91             mStarted = false;
92         }
93     }
94 
onCreateServiceIntent()95     protected Intent onCreateServiceIntent() {
96         return new Intent(this, PlayerService.class).setPackage(getBasePackageName());
97     }
98 
onCreatePlayerController()99     protected PlayerSession onCreatePlayerController() {
100         return new PlayerSession(this);
101     }
102 
getAllowedPackages()103     protected ArrayList<String> getAllowedPackages() {
104         return null;
105     }
106 
107     private final PlayerSession.Listener mPlayerListener = new PlayerSession.Listener() {
108         @Override
109         public void onPlayStateChanged(PlaybackState state) {
110             switch (state.getState()) {
111                 case PlaybackState.STATE_PLAYING:
112                     onPlaybackStarted();
113                     break;
114                 case PlaybackState.STATE_STOPPED:
115                 case PlaybackState.STATE_ERROR:
116                     onPlaybackEnded();
117                     break;
118             }
119         }
120     };
121 
122     public class PlayerBinder extends IPlayerService.Stub {
123         @Override
sendRequest(String action, Bundle params, IRequestCallback cb)124         public void sendRequest(String action, Bundle params, IRequestCallback cb) {
125             if (RequestUtils.ACTION_SET_CONTENT.equals(action)) {
126                 mSession.setContent(params);
127             } else if (RequestUtils.ACTION_SET_NEXT_CONTENT.equals(action)) {
128                 mSession.setNextContent(params);
129             }
130         }
131 
132         @Override
registerCallback(final IPlayerCallback cb)133         public void registerCallback(final IPlayerCallback cb) throws RemoteException {
134             if (!mCbs.contains(cb)) {
135                 mCbs.add(cb);
136                 cb.asBinder().linkToDeath(new IBinder.DeathRecipient() {
137                     @Override
138                     public void binderDied() {
139                         mCbs.remove(cb);
140                     }
141                 }, 0);
142             }
143             try {
144                 cb.onSessionChanged(getSessionToken());
145             } catch (RemoteException e) {
146                 mCbs.remove(cb);
147                 throw e;
148             }
149         }
150 
151         @Override
unregisterCallback(IPlayerCallback cb)152         public void unregisterCallback(IPlayerCallback cb) throws RemoteException {
153             mCbs.remove(cb);
154         }
155 
156         @Override
getSessionToken()157         public MediaSession.Token getSessionToken() throws RemoteException {
158             if (mSession == null) {
159                 Log.e(TAG, "Error in PlayerService: mSession=null in getSessionToken()");
160                 return null;
161             }
162             return mSession.getSessionToken();
163         }
164 
165         @Override
setIcon(Bitmap icon)166         public void setIcon(Bitmap icon) {
167             mSession.setIcon(icon);
168         }
169     }
170 
171 }
172