| /* |
| * Copyright 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.media; |
| |
| import static android.content.Context.NOTIFICATION_SERVICE; |
| |
| import android.app.Notification; |
| import android.app.NotificationManager; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.media.MediaPlayerBase; |
| import android.media.MediaPlayerBase.PlayerEventCallback; |
| import android.media.MediaSession2; |
| import android.media.MediaSessionService2; |
| import android.media.MediaSessionService2.MediaNotification; |
| import android.media.SessionToken2; |
| import android.media.SessionToken2.TokenType; |
| import android.media.update.MediaSessionService2Provider; |
| import android.os.IBinder; |
| import android.support.annotation.GuardedBy; |
| import android.util.Log; |
| |
| // TODO(jaewan): Need a test for session service itself. |
| public class MediaSessionService2Impl implements MediaSessionService2Provider { |
| |
| private static final String TAG = "MPSessionService"; // to meet 23 char limit in Log tag |
| private static final boolean DEBUG = true; // TODO(jaewan): Change this. (b/74094611) |
| |
| private final MediaSessionService2 mInstance; |
| private final PlayerEventCallback mCallback = new SessionServiceEventCallback(); |
| |
| private final Object mLock = new Object(); |
| @GuardedBy("mLock") |
| private NotificationManager mNotificationManager; |
| @GuardedBy("mLock") |
| private Intent mStartSelfIntent; |
| |
| private boolean mIsRunningForeground; |
| private MediaSession2 mSession; |
| |
| public MediaSessionService2Impl(MediaSessionService2 instance) { |
| if (DEBUG) { |
| Log.d(TAG, "MediaSessionService2Impl(" + instance + ")"); |
| } |
| mInstance = instance; |
| } |
| |
| @Override |
| public MediaSession2 getSession_impl() { |
| return getSession(); |
| } |
| |
| MediaSession2 getSession() { |
| synchronized (mLock) { |
| return mSession; |
| } |
| } |
| |
| @Override |
| public MediaNotification onUpdateNotification_impl() { |
| // Provide default notification UI later. |
| return null; |
| } |
| |
| @Override |
| public void onCreate_impl() { |
| mNotificationManager = (NotificationManager) mInstance.getSystemService( |
| NOTIFICATION_SERVICE); |
| mStartSelfIntent = new Intent(mInstance, mInstance.getClass()); |
| |
| SessionToken2 token = new SessionToken2(mInstance, mInstance.getPackageName(), |
| mInstance.getClass().getName()); |
| if (token.getType() != getSessionType()) { |
| throw new RuntimeException("Expected session service, but was " + token.getType()); |
| } |
| mSession = mInstance.onCreateSession(token.getId()); |
| if (mSession == null || !token.getId().equals(mSession.getToken().getId())) { |
| throw new RuntimeException("Expected session with id " + token.getId() |
| + ", but got " + mSession); |
| } |
| // TODO(jaewan): Uncomment here. |
| // mSession.registerPlayerEventCallback(mCallback, mSession.getExecutor()); |
| } |
| |
| @TokenType int getSessionType() { |
| return SessionToken2.TYPE_SESSION_SERVICE; |
| } |
| |
| public IBinder onBind_impl(Intent intent) { |
| if (MediaSessionService2.SERVICE_INTERFACE.equals(intent.getAction())) { |
| return ((MediaSession2Impl) mSession.getProvider()).getSessionStub().asBinder(); |
| } |
| return null; |
| } |
| |
| private void updateNotification(int playerState) { |
| MediaNotification mediaNotification = mInstance.onUpdateNotification(); |
| if (mediaNotification == null) { |
| return; |
| } |
| switch(playerState) { |
| case MediaPlayerBase.PLAYER_STATE_PLAYING: |
| if (!mIsRunningForeground) { |
| mIsRunningForeground = true; |
| mInstance.startForegroundService(mStartSelfIntent); |
| mInstance.startForeground(mediaNotification.getNotificationId(), |
| mediaNotification.getNotification()); |
| return; |
| } |
| break; |
| case MediaPlayerBase.PLAYER_STATE_IDLE: |
| case MediaPlayerBase.PLAYER_STATE_ERROR: |
| if (mIsRunningForeground) { |
| mIsRunningForeground = false; |
| mInstance.stopForeground(true); |
| return; |
| } |
| break; |
| } |
| mNotificationManager.notify(mediaNotification.getNotificationId(), |
| mediaNotification.getNotification()); |
| } |
| |
| private class SessionServiceEventCallback extends PlayerEventCallback { |
| @Override |
| public void onPlayerStateChanged(MediaPlayerBase player, int state) { |
| // TODO: Implement this |
| return; |
| } |
| } |
| |
| public static class MediaNotificationImpl implements MediaNotificationProvider { |
| private int mNotificationId; |
| private Notification mNotification; |
| |
| public MediaNotificationImpl(MediaNotification instance, int notificationId, |
| Notification notification) { |
| if (notification == null) { |
| throw new IllegalArgumentException("notification shouldn't be null"); |
| } |
| mNotificationId = notificationId; |
| mNotification = notification; |
| } |
| |
| @Override |
| public int getNotificationId_impl() { |
| return mNotificationId; |
| } |
| |
| @Override |
| public Notification getNotification_impl() { |
| return mNotification; |
| } |
| } |
| } |