MediaSessionRecord.java revision 01fe661ae5da3739215d93922412df4b24c859a2
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 17package com.android.server.media; 18 19import android.content.Intent; 20import android.media.IMediaController; 21import android.media.IMediaControllerCallback; 22import android.media.IMediaSession; 23import android.media.IMediaSessionCallback; 24import android.media.RemoteControlClient; 25import android.os.Bundle; 26import android.os.IBinder; 27import android.os.RemoteException; 28import android.util.Log; 29import android.view.KeyEvent; 30 31import java.util.ArrayList; 32 33/** 34 * This is the system implementation of a Session. Apps will interact with the 35 * MediaSession wrapper class instead. 36 */ 37public class MediaSessionRecord implements IBinder.DeathRecipient { 38 private static final String TAG = "MediaSessionImpl"; 39 40 private final int mPid; 41 private final String mPackageName; 42 private final String mTag; 43 private final ControllerStub mController; 44 private final SessionStub mSession; 45 private final SessionCb mSessionCb; 46 private final MediaSessionService mService; 47 48 private final ArrayList<IMediaControllerCallback> mSessionCallbacks = 49 new ArrayList<IMediaControllerCallback>(); 50 51 private int mPlaybackState = RemoteControlClient.PLAYSTATE_NONE; 52 53 public MediaSessionRecord(int pid, String packageName, IMediaSessionCallback cb, String tag, 54 MediaSessionService service) { 55 mPid = pid; 56 mPackageName = packageName; 57 mTag = tag; 58 mController = new ControllerStub(); 59 mSession = new SessionStub(); 60 mSessionCb = new SessionCb(cb); 61 mService = service; 62 } 63 64 public IMediaSession getSessionBinder() { 65 return mSession; 66 } 67 68 public IMediaController getControllerBinder() { 69 return mController; 70 } 71 72 public void setPlaybackStateInternal(int state) { 73 mPlaybackState = state; 74 for (int i = mSessionCallbacks.size() - 1; i >= 0; i--) { 75 IMediaControllerCallback cb = mSessionCallbacks.get(i); 76 try { 77 cb.onPlaybackUpdate(state); 78 } catch (RemoteException e) { 79 Log.d(TAG, "SessionCallback object dead in setPlaybackState.", e); 80 mSessionCallbacks.remove(i); 81 } 82 } 83 } 84 85 @Override 86 public void binderDied() { 87 mService.sessionDied(this); 88 } 89 90 private void onDestroy() { 91 mService.destroySession(this); 92 } 93 94 private final class SessionStub extends IMediaSession.Stub { 95 96 @Override 97 public void setPlaybackState(int state) throws RemoteException { 98 setPlaybackStateInternal(state); 99 } 100 101 @Override 102 public void destroy() throws RemoteException { 103 onDestroy(); 104 } 105 106 @Override 107 public void sendEvent(Bundle data) throws RemoteException { 108 } 109 110 @Override 111 public IMediaController getMediaSessionToken() throws RemoteException { 112 return mController; 113 } 114 115 @Override 116 public void setMetadata(Bundle metadata) throws RemoteException { 117 } 118 119 @Override 120 public void setRouteState(Bundle routeState) throws RemoteException { 121 } 122 123 @Override 124 public void setRoute(Bundle medaiRouteDescriptor) throws RemoteException { 125 } 126 127 } 128 129 class SessionCb { 130 private final IMediaSessionCallback mCb; 131 132 public SessionCb(IMediaSessionCallback cb) { 133 mCb = cb; 134 } 135 136 public void sendMediaButton(KeyEvent keyEvent) { 137 Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 138 mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent); 139 try { 140 mCb.onMediaButton(mediaButtonIntent); 141 } catch (RemoteException e) { 142 Log.d(TAG, "Controller object dead in sendMediaRequest.", e); 143 onDestroy(); 144 } 145 } 146 147 public void sendCommand(String command, Bundle extras) { 148 try { 149 mCb.onCommand(command, extras); 150 } catch (RemoteException e) { 151 Log.d(TAG, "Controller object dead in sendCommand.", e); 152 onDestroy(); 153 } 154 } 155 156 public void registerCallbackListener(IMediaSessionCallback cb) { 157 158 } 159 160 } 161 162 class ControllerStub extends IMediaController.Stub { 163 /* 164 */ 165 @Override 166 public void sendCommand(String command, Bundle extras) throws RemoteException { 167 mSessionCb.sendCommand(command, extras); 168 } 169 170 @Override 171 public void sendMediaButton(KeyEvent mediaButtonIntent) { 172 mSessionCb.sendMediaButton(mediaButtonIntent); 173 } 174 175 /* 176 */ 177 @Override 178 public void registerCallbackListener(IMediaControllerCallback cb) throws RemoteException { 179 if (!mSessionCallbacks.contains(cb)) { 180 mSessionCallbacks.add(cb); 181 } 182 } 183 184 /* 185 */ 186 @Override 187 public void unregisterCallbackListener(IMediaControllerCallback cb) 188 throws RemoteException { 189 mSessionCallbacks.remove(cb); 190 } 191 192 /* 193 */ 194 @Override 195 public int getPlaybackState() throws RemoteException { 196 return mPlaybackState; 197 } 198 } 199 200} 201