Methods Summary |
---|
private MediaSessionRecord | createSessionInternal(int callerPid, int callerUid, int userId, java.lang.String callerPackageName, android.media.session.ISessionCallback cb, java.lang.String tag)
synchronized (mLock) {
return createSessionLocked(callerPid, callerUid, userId, callerPackageName, cb, tag);
}
|
private MediaSessionRecord | createSessionLocked(int callerPid, int callerUid, int userId, java.lang.String callerPackageName, android.media.session.ISessionCallback cb, java.lang.String tag)
final MediaSessionRecord session = new MediaSessionRecord(callerPid, callerUid, userId,
callerPackageName, cb, tag, this, mHandler);
try {
cb.asBinder().linkToDeath(session, 0);
} catch (RemoteException e) {
throw new RuntimeException("Media Session owner died prematurely.", e);
}
mAllSessions.add(session);
mPriorityStack.addSession(session);
UserRecord user = getOrCreateUser(userId);
user.addSessionLocked(session);
mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, userId, 0);
if (DEBUG) {
Log.d(TAG, "Created session for package " + callerPackageName + " with tag " + tag);
}
return session;
|
void | destroySession(MediaSessionRecord session)
synchronized (mLock) {
destroySessionLocked(session);
}
|
private void | destroySessionLocked(MediaSessionRecord session)
int userId = session.getUserId();
UserRecord user = mUserRecords.get(userId);
if (user != null) {
user.removeSessionLocked(session);
}
mPriorityStack.removeSession(session);
mAllSessions.remove(session);
try {
session.getCallback().asBinder().unlinkToDeath(session, 0);
} catch (Exception e) {
// ignore exceptions while destroying a session.
}
session.onDestroy();
mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, session.getUserId(), 0);
|
private void | destroyUserLocked(com.android.server.media.MediaSessionService$UserRecord user)Stop the user and unbind from everything.
user.stopLocked();
user.destroyLocked();
mUserRecords.remove(user.mUserId);
|
private void | enforceMediaPermissions(android.content.ComponentName compName, int pid, int uid, int resolvedUserId)Checks a caller's authorization to register an IRemoteControlDisplay.
Authorization is granted if one of the following is true:
- the caller has android.Manifest.permission.MEDIA_CONTENT_CONTROL
permission
- the caller's listener is one of the enabled notification listeners
for the caller's user
if (getContext()
.checkPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL, pid, uid)
!= PackageManager.PERMISSION_GRANTED
&& !isEnabledNotificationListener(compName, UserHandle.getUserId(uid),
resolvedUserId)) {
throw new SecurityException("Missing permission to control media.");
}
|
private void | enforcePackageName(java.lang.String packageName, int uid)
if (TextUtils.isEmpty(packageName)) {
throw new IllegalArgumentException("packageName may not be empty");
}
String[] packages = getContext().getPackageManager().getPackagesForUid(uid);
final int packageCount = packages.length;
for (int i = 0; i < packageCount; i++) {
if (packageName.equals(packages[i])) {
return;
}
}
throw new IllegalArgumentException("packageName is not owned by the calling process");
|
protected void | enforcePhoneStatePermission(int pid, int uid)
if (getContext().checkPermission(android.Manifest.permission.MODIFY_PHONE_STATE, pid, uid)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Must hold the MODIFY_PHONE_STATE permission.");
}
|
private void | enforceStatusBarPermission(java.lang.String action, int pid, int uid)
if (getContext().checkPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
pid, uid) != PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Only system ui may " + action);
}
|
private int | findIndexOfSessionsListenerLocked(android.media.session.IActiveSessionsListener listener)
for (int i = mSessionsListeners.size() - 1; i >= 0; i--) {
if (mSessionsListeners.get(i).mListener.asBinder() == listener.asBinder()) {
return i;
}
}
return -1;
|
private android.media.IAudioService | getAudioService()
IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
return IAudioService.Stub.asInterface(b);
|
private com.android.server.media.MediaSessionService$UserRecord | getOrCreateUser(int userId)
UserRecord user = mUserRecords.get(userId);
if (user == null) {
user = new UserRecord(getContext(), userId);
mUserRecords.put(userId, user);
}
return user;
|
private boolean | isEnabledNotificationListener(android.content.ComponentName compName, int userId, int forUserId)This checks if the component is an enabled notification listener for the
specified user. Enabled components may only operate on behalf of the user
they're running as.
if (userId != forUserId) {
// You may not access another user's content as an enabled listener.
return false;
}
if (DEBUG) {
Log.d(TAG, "Checking if enabled notification listener " + compName);
}
if (compName != null) {
final String enabledNotifListeners = Settings.Secure.getStringForUser(mContentResolver,
Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
userId);
if (enabledNotifListeners != null) {
final String[] components = enabledNotifListeners.split(":");
for (int i = 0; i < components.length; i++) {
final ComponentName component =
ComponentName.unflattenFromString(components[i]);
if (component != null) {
if (compName.equals(component)) {
if (DEBUG) {
Log.d(TAG, "ok to get sessions: " + component +
" is authorized notification listener");
}
return true;
}
}
}
}
if (DEBUG) {
Log.d(TAG, "not ok to get sessions, " + compName +
" is not in list of ENABLED_NOTIFICATION_LISTENERS for user " + userId);
}
}
return false;
|
private boolean | isSessionDiscoverable(MediaSessionRecord record)
// TODO probably want to check more than if it's active.
return record.isActive();
|
public void | monitor()
synchronized (mLock) {
// Check for deadlock
}
|
public void | notifyRemoteVolumeChanged(int flags, MediaSessionRecord session)Tells the system UI that volume has changed on a remote session.
if (mRvc == null) {
return;
}
try {
mRvc.remoteVolumeChanged(session.getControllerBinder(), flags);
} catch (Exception e) {
Log.wtf(TAG, "Error sending volume change to system UI.", e);
}
|
public void | onSessionPlaybackTypeChanged(MediaSessionRecord record)
synchronized (mLock) {
if (!mAllSessions.contains(record)) {
Log.d(TAG, "Unknown session changed playback type. Ignoring.");
return;
}
pushRemoteVolumeUpdateLocked(record.getUserId());
}
|
public void | onSessionPlaystateChange(MediaSessionRecord record, int oldState, int newState)
boolean updateSessions = false;
synchronized (mLock) {
if (!mAllSessions.contains(record)) {
Log.d(TAG, "Unknown session changed playback state. Ignoring.");
return;
}
updateSessions = mPriorityStack.onPlaystateChange(record, oldState, newState);
}
if (updateSessions) {
mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, record.getUserId(), 0);
}
|
public void | onStart()
publishBinderService(Context.MEDIA_SESSION_SERVICE, mSessionManagerImpl);
Watchdog.getInstance().addMonitor(this);
updateUser();
mKeyguardManager =
(KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
mAudioService = getAudioService();
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
mContentResolver = getContext().getContentResolver();
mSettingsObserver = new SettingsObserver();
mSettingsObserver.observe();
|
public void | onStartUser(int userHandle)
updateUser();
|
public void | onStopUser(int userHandle)
synchronized (mLock) {
UserRecord user = mUserRecords.get(userHandle);
if (user != null) {
destroyUserLocked(user);
}
}
|
public void | onSwitchUser(int userHandle)
updateUser();
|
private void | pushRemoteVolumeUpdateLocked(int userId)
if (mRvc != null) {
try {
MediaSessionRecord record = mPriorityStack.getDefaultRemoteSession(userId);
mRvc.updateRemoteController(record == null ? null : record.getControllerBinder());
} catch (RemoteException e) {
Log.wtf(TAG, "Error sending default remote volume to sys ui.", e);
}
}
|
private void | pushSessionsChanged(int userId)
synchronized (mLock) {
List<MediaSessionRecord> records = mPriorityStack.getActiveSessions(userId);
int size = records.size();
if (size > 0 && records.get(0).isPlaybackActive(false)) {
rememberMediaButtonReceiverLocked(records.get(0));
}
ArrayList<MediaSession.Token> tokens = new ArrayList<MediaSession.Token>();
for (int i = 0; i < size; i++) {
tokens.add(new MediaSession.Token(records.get(i).getControllerBinder()));
}
pushRemoteVolumeUpdateLocked(userId);
for (int i = mSessionsListeners.size() - 1; i >= 0; i--) {
SessionsListenerRecord record = mSessionsListeners.get(i);
if (record.mUserId == UserHandle.USER_ALL || record.mUserId == userId) {
try {
record.mListener.onActiveSessionsChanged(tokens);
} catch (RemoteException e) {
Log.w(TAG, "Dead ActiveSessionsListener in pushSessionsChanged, removing",
e);
mSessionsListeners.remove(i);
}
}
}
}
|
private void | rememberMediaButtonReceiverLocked(MediaSessionRecord record)
PendingIntent receiver = record.getMediaButtonReceiver();
UserRecord user = mUserRecords.get(record.getUserId());
if (receiver != null && user != null) {
user.mLastMediaButtonReceiver = receiver;
}
|
void | sessionDied(MediaSessionRecord session)
synchronized (mLock) {
destroySessionLocked(session);
}
|
private void | updateActiveSessionListeners()
synchronized (mLock) {
for (int i = mSessionsListeners.size() - 1; i >= 0; i--) {
SessionsListenerRecord listener = mSessionsListeners.get(i);
try {
enforceMediaPermissions(listener.mComponentName, listener.mPid, listener.mUid,
listener.mUserId);
} catch (SecurityException e) {
Log.i(TAG, "ActiveSessionsListener " + listener.mComponentName
+ " is no longer authorized. Disconnecting.");
mSessionsListeners.remove(i);
try {
listener.mListener
.onActiveSessionsChanged(new ArrayList<MediaSession.Token>());
} catch (Exception e1) {
// ignore
}
}
}
}
|
public void | updateSession(MediaSessionRecord record)
synchronized (mLock) {
if (!mAllSessions.contains(record)) {
Log.d(TAG, "Unknown session updated. Ignoring.");
return;
}
mPriorityStack.onSessionStateChange(record);
}
mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, record.getUserId(), 0);
|
private void | updateUser()
synchronized (mLock) {
int userId = ActivityManager.getCurrentUser();
if (mCurrentUserId != userId) {
final int oldUserId = mCurrentUserId;
mCurrentUserId = userId; // do this first
UserRecord oldUser = mUserRecords.get(oldUserId);
if (oldUser != null) {
oldUser.stopLocked();
}
UserRecord newUser = getOrCreateUser(userId);
newUser.startLocked();
}
}
|