MediaSessionManager.java revision b69ffd4dc2c8fa85e0064151141ebeee90de471e
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 android.media.session; 18 19import android.content.ComponentName; 20import android.content.Context; 21import android.media.session.ISessionManager; 22import android.os.IBinder; 23import android.os.RemoteException; 24import android.os.ServiceManager; 25import android.os.UserHandle; 26import android.service.notification.NotificationListenerService; 27import android.util.Log; 28import android.view.KeyEvent; 29 30import java.util.ArrayList; 31import java.util.List; 32 33/** 34 * MediaSessionManager allows the creation and control of MediaSessions in the 35 * system. A MediaSession enables publishing information about ongoing media and 36 * interacting with MediaControllers and MediaRoutes. 37 * <p> 38 * Use <code>Context.getSystemService(Context.MEDIA_SESSION_SERVICE)</code> to 39 * get an instance of this class. 40 * <p> 41 * 42 * @see MediaSession 43 * @see MediaController 44 */ 45public final class MediaSessionManager { 46 private static final String TAG = "SessionManager"; 47 48 private final ISessionManager mService; 49 50 private Context mContext; 51 52 /** 53 * @hide 54 */ 55 public MediaSessionManager(Context context) { 56 // Consider rewriting like DisplayManagerGlobal 57 // Decide if we need context 58 mContext = context; 59 IBinder b = ServiceManager.getService(Context.MEDIA_SESSION_SERVICE); 60 mService = ISessionManager.Stub.asInterface(b); 61 } 62 63 /** 64 * Creates a new session. 65 * 66 * @param tag A short name for debugging purposes 67 * @return a {@link MediaSession} for the new session 68 */ 69 public MediaSession createSession(String tag) { 70 return createSessionAsUser(tag, UserHandle.myUserId()); 71 } 72 73 /** 74 * Creates a new session as the specified user. To create a session as a 75 * user other than your own you must hold the 76 * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} 77 * permission. 78 * 79 * @param tag A short name for debugging purposes 80 * @param userId The user id to create the session as. 81 * @return a {@link MediaSession} for the new session 82 * @hide 83 */ 84 public MediaSession createSessionAsUser(String tag, int userId) { 85 try { 86 MediaSession.CallbackStub cbStub = new MediaSession.CallbackStub(); 87 MediaSession session = new MediaSession(mService 88 .createSession(mContext.getPackageName(), cbStub, tag, userId), cbStub); 89 cbStub.setMediaSession(session); 90 91 return session; 92 } catch (RemoteException e) { 93 Log.e(TAG, "Failed to create session: ", e); 94 return null; 95 } 96 } 97 98 /** 99 * Get a list of controllers for all ongoing sessions. This requires the 100 * android.Manifest.permission.MEDIA_CONTENT_CONTROL permission be held by 101 * the calling app. You may also retrieve this list if your app is an 102 * enabled notification listener using the 103 * {@link NotificationListenerService} APIs, in which case you must pass the 104 * {@link ComponentName} of your enabled listener. 105 * 106 * @param notificationListener The enabled notification listener component. 107 * May be null. 108 * @return A list of controllers for ongoing sessions 109 * @hide 110 */ 111 public List<MediaController> getActiveSessions(ComponentName notificationListener) { 112 return getActiveSessionsForUser(notificationListener, UserHandle.myUserId()); 113 } 114 115 /** 116 * Get active sessions for a specific user. To retrieve actions for a user 117 * other than your own you must hold the 118 * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission 119 * in addition to any other requirements. If you are an enabled notification 120 * listener you may only get sessions for the users you are enabled for. 121 * 122 * @param notificationListener The enabled notification listener component. 123 * May be null. 124 * @param userId The user id to fetch sessions for. 125 * @return A list of controllers for ongoing sessions. 126 * @hide 127 */ 128 public List<MediaController> getActiveSessionsForUser(ComponentName notificationListener, 129 int userId) { 130 ArrayList<MediaController> controllers = new ArrayList<MediaController>(); 131 try { 132 List<IBinder> binders = mService.getSessions(notificationListener, userId); 133 for (int i = binders.size() - 1; i >= 0; i--) { 134 MediaController controller = MediaController.fromBinder(ISessionController.Stub 135 .asInterface(binders.get(i))); 136 controllers.add(controller); 137 } 138 } catch (RemoteException e) { 139 Log.e(TAG, "Failed to get active sessions: ", e); 140 } 141 return controllers; 142 } 143 144 /** 145 * Send a media key event. The receiver will be selected automatically. 146 * 147 * @param keyEvent The KeyEvent to send. 148 * @hide 149 */ 150 public void dispatchMediaKeyEvent(KeyEvent keyEvent) { 151 dispatchMediaKeyEvent(keyEvent, false); 152 } 153 154 /** 155 * Send a media key event. The receiver will be selected automatically. 156 * 157 * @param keyEvent The KeyEvent to send 158 * @param needWakeLock true if a wake lock should be held while sending the 159 * key 160 * @hide 161 */ 162 public void dispatchMediaKeyEvent(KeyEvent keyEvent, boolean needWakeLock) { 163 try { 164 mService.dispatchMediaKeyEvent(keyEvent, needWakeLock); 165 } catch (RemoteException e) { 166 Log.e(TAG, "Failed to send key event.", e); 167 } 168 } 169 170 /** 171 * Dispatch an adjust volume request to the system. It will be routed to the 172 * most relevant stream/session. 173 * 174 * @param suggestedStream The stream to fall back to if there isn't a 175 * relevant stream 176 * @param delta The amount to adjust the volume by. 177 * @param flags Any flags to include with the volume change. 178 * @hide 179 */ 180 public void dispatchAdjustVolumeBy(int suggestedStream, int delta, int flags) { 181 try { 182 mService.dispatchAdjustVolumeBy(suggestedStream, delta, flags); 183 } catch (RemoteException e) { 184 Log.e(TAG, "Failed to send adjust volume.", e); 185 } 186 } 187} 188