• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 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 
17 package com.android.media;
18 
19 import static android.content.Context.NOTIFICATION_SERVICE;
20 
21 import android.app.Notification;
22 import android.app.NotificationManager;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.media.MediaPlayerBase;
26 import android.media.MediaPlayerBase.PlayerEventCallback;
27 import android.media.MediaSession2;
28 import android.media.MediaSessionService2;
29 import android.media.MediaSessionService2.MediaNotification;
30 import android.media.SessionToken2;
31 import android.media.SessionToken2.TokenType;
32 import android.media.update.MediaSessionService2Provider;
33 import android.os.IBinder;
34 import android.support.annotation.GuardedBy;
35 import android.util.Log;
36 
37 // TODO(jaewan): Need a test for session service itself.
38 public class MediaSessionService2Impl implements MediaSessionService2Provider {
39 
40     private static final String TAG = "MPSessionService"; // to meet 23 char limit in Log tag
41     private static final boolean DEBUG = true; // TODO(jaewan): Change this. (b/74094611)
42 
43     private final MediaSessionService2 mInstance;
44     private final PlayerEventCallback mCallback = new SessionServiceEventCallback();
45 
46     private final Object mLock = new Object();
47     @GuardedBy("mLock")
48     private NotificationManager mNotificationManager;
49     @GuardedBy("mLock")
50     private Intent mStartSelfIntent;
51 
52     private boolean mIsRunningForeground;
53     private MediaSession2 mSession;
54 
MediaSessionService2Impl(MediaSessionService2 instance)55     public MediaSessionService2Impl(MediaSessionService2 instance) {
56         if (DEBUG) {
57             Log.d(TAG, "MediaSessionService2Impl(" + instance + ")");
58         }
59         mInstance = instance;
60     }
61 
62     @Override
getSession_impl()63     public MediaSession2 getSession_impl() {
64         return getSession();
65     }
66 
getSession()67     MediaSession2 getSession() {
68         synchronized (mLock) {
69             return mSession;
70         }
71     }
72 
73     @Override
onUpdateNotification_impl()74     public MediaNotification onUpdateNotification_impl() {
75         // Provide default notification UI later.
76         return null;
77     }
78 
79     @Override
onCreate_impl()80     public void onCreate_impl() {
81         mNotificationManager = (NotificationManager) mInstance.getSystemService(
82                 NOTIFICATION_SERVICE);
83         mStartSelfIntent = new Intent(mInstance, mInstance.getClass());
84 
85         SessionToken2 token = new SessionToken2(mInstance, mInstance.getPackageName(),
86                 mInstance.getClass().getName());
87         if (token.getType() != getSessionType()) {
88             throw new RuntimeException("Expected session service, but was " + token.getType());
89         }
90         mSession = mInstance.onCreateSession(token.getId());
91         if (mSession == null || !token.getId().equals(mSession.getToken().getId())) {
92             throw new RuntimeException("Expected session with id " + token.getId()
93                     + ", but got " + mSession);
94         }
95         // TODO(jaewan): Uncomment here.
96         // mSession.registerPlayerEventCallback(mCallback, mSession.getExecutor());
97     }
98 
getSessionType()99     @TokenType int getSessionType() {
100         return SessionToken2.TYPE_SESSION_SERVICE;
101     }
102 
onBind_impl(Intent intent)103     public IBinder onBind_impl(Intent intent) {
104         if (MediaSessionService2.SERVICE_INTERFACE.equals(intent.getAction())) {
105             return ((MediaSession2Impl) mSession.getProvider()).getSessionStub().asBinder();
106         }
107         return null;
108     }
109 
updateNotification(int playerState)110     private void updateNotification(int playerState) {
111         MediaNotification mediaNotification = mInstance.onUpdateNotification();
112         if (mediaNotification == null) {
113             return;
114         }
115         switch(playerState) {
116             case MediaPlayerBase.PLAYER_STATE_PLAYING:
117                 if (!mIsRunningForeground) {
118                     mIsRunningForeground = true;
119                     mInstance.startForegroundService(mStartSelfIntent);
120                     mInstance.startForeground(mediaNotification.getNotificationId(),
121                             mediaNotification.getNotification());
122                     return;
123                 }
124                 break;
125             case MediaPlayerBase.PLAYER_STATE_IDLE:
126             case MediaPlayerBase.PLAYER_STATE_ERROR:
127                 if (mIsRunningForeground) {
128                     mIsRunningForeground = false;
129                     mInstance.stopForeground(true);
130                     return;
131                 }
132                 break;
133         }
134         mNotificationManager.notify(mediaNotification.getNotificationId(),
135                 mediaNotification.getNotification());
136     }
137 
138     private class SessionServiceEventCallback extends PlayerEventCallback {
139         @Override
onPlayerStateChanged(MediaPlayerBase player, int state)140         public void onPlayerStateChanged(MediaPlayerBase player, int state) {
141             // TODO: Implement this
142             return;
143         }
144     }
145 
146     public static class MediaNotificationImpl implements MediaNotificationProvider {
147         private int mNotificationId;
148         private Notification mNotification;
149 
MediaNotificationImpl(MediaNotification instance, int notificationId, Notification notification)150         public MediaNotificationImpl(MediaNotification instance, int notificationId,
151                 Notification notification) {
152             if (notification == null) {
153                 throw new IllegalArgumentException("notification shouldn't be null");
154             }
155             mNotificationId = notificationId;
156             mNotification = notification;
157         }
158 
159         @Override
getNotificationId_impl()160         public int getNotificationId_impl() {
161             return mNotificationId;
162         }
163 
164         @Override
getNotification_impl()165         public Notification getNotification_impl() {
166             return mNotification;
167         }
168     }
169 }
170