Loading services/core/java/com/android/server/media/MediaSessionRecord.java +1 −1 Original line number Diff line number Diff line Loading @@ -454,7 +454,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public String toString() { return mPackageName + "/" + mTag; return mPackageName + "/" + mTag + " (uid=" + mUserId + ")"; } private void postAdjustLocalVolume(final int stream, final int direction, final int flags, Loading services/core/java/com/android/server/media/MediaSessionService.java +77 −67 Original line number Diff line number Diff line Loading @@ -47,10 +47,12 @@ import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.speech.RecognizerIntent; import android.text.TextUtils; Loading @@ -67,6 +69,7 @@ import com.android.server.Watchdog.Monitor; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** Loading Loading @@ -97,7 +100,9 @@ public class MediaSessionService extends SystemService implements Monitor { private ContentResolver mContentResolver; private SettingsObserver mSettingsObserver; private int mCurrentUserId = -1; // List of user IDs running in the foreground. // Multiple users can be in the foreground if the work profile is on. private final List<Integer> mCurrentUserIdList = new ArrayList<>(); // Used to notify system UI when remote volume was changed. TODO find a // better way to handle this. Loading Loading @@ -181,22 +186,26 @@ public class MediaSessionService extends SystemService implements Monitor { } @Override public void onStartUser(int userHandle) { public void onStartUser(int userId) { if (DEBUG) Log.d(TAG, "onStartUser: " + userId); updateUser(); } @Override public void onSwitchUser(int userHandle) { public void onSwitchUser(int userId) { if (DEBUG) Log.d(TAG, "onSwitchUser: " + userId); updateUser(); } @Override public void onStopUser(int userHandle) { public void onStopUser(int userId) { if (DEBUG) Log.d(TAG, "onStopUser: " + userId); synchronized (mLock) { UserRecord user = mUserRecords.get(userHandle); UserRecord user = mUserRecords.get(userId); if (user != null) { destroyUserLocked(user); } updateUser(); } } Loading Loading @@ -229,17 +238,23 @@ public class MediaSessionService extends SystemService implements Monitor { private void updateUser() { int userId = ActivityManager.getCurrentUser(); synchronized (mLock) { if (mCurrentUserId != userId) { final int oldUserId = mCurrentUserId; mCurrentUserId = userId; // do this first UserRecord oldUser = mUserRecords.get(oldUserId); if (oldUser != null) { oldUser.stopLocked(); UserManager manager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); int currentUser = ActivityManager.getCurrentUser(); int[] userIds = manager.getEnabledProfileIds(currentUser); mCurrentUserIdList.clear(); if (userIds != null && userIds.length > 0) { for (int userId : userIds) { mCurrentUserIdList.add(userId); } } else { // This shouldn't happen. Log.w(TAG, "Failed to get enabled profiles."); mCurrentUserIdList.add(currentUser); } for (int userId : mCurrentUserIdList) { if (mUserRecords.get(userId) == null) { mUserRecords.put(userId, new UserRecord(getContext(), userId)); } UserRecord newUser = getOrCreateUser(userId); newUser.startLocked(); } } } Loading Loading @@ -272,7 +287,6 @@ public class MediaSessionService extends SystemService implements Monitor { * @param user The user to dispose of */ private void destroyUserLocked(UserRecord user) { user.stopLocked(); user.destroyLocked(); mUserRecords.remove(user.mUserId); } Loading Loading @@ -436,9 +450,9 @@ public class MediaSessionService extends SystemService implements Monitor { } mAllSessions.add(session); mPriorityStack.addSession(session); mPriorityStack.addSession(session, mCurrentUserIdList.contains(userId)); UserRecord user = getOrCreateUser(userId); UserRecord user = mUserRecords.get(userId); user.addSessionLocked(session); mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, userId, 0); Loading @@ -449,15 +463,6 @@ public class MediaSessionService extends SystemService implements Monitor { return session; } private UserRecord getOrCreateUser(int userId) { UserRecord user = mUserRecords.get(userId); if (user == null) { user = new UserRecord(getContext(), userId); mUserRecords.put(userId, user); } return user; } private int findIndexOfSessionsListenerLocked(IActiveSessionsListener listener) { for (int i = mSessionsListeners.size() - 1; i >= 0; i--) { if (mSessionsListeners.get(i).mListener.asBinder() == listener.asBinder()) { Loading Loading @@ -536,13 +541,6 @@ public class MediaSessionService extends SystemService implements Monitor { restoreMediaButtonReceiver(); } public void startLocked() { } public void stopLocked() { // nothing for now } public void destroyLocked() { for (int i = mSessions.size() - 1; i >= 0; i--) { MediaSessionRecord session = mSessions.get(i); Loading Loading @@ -578,7 +576,7 @@ public class MediaSessionService extends SystemService implements Monitor { private void restoreMediaButtonReceiver() { String receiverName = Settings.Secure.getStringForUser(mContentResolver, Settings.System.MEDIA_BUTTON_RECEIVER, UserHandle.USER_CURRENT); Settings.System.MEDIA_BUTTON_RECEIVER, mUserId); if (!TextUtils.isEmpty(receiverName)) { ComponentName eventReceiver = ComponentName.unflattenFromString(receiverName); if (eventReceiver == null) { Loading Loading @@ -767,12 +765,22 @@ public class MediaSessionService extends SystemService implements Monitor { synchronized (mLock) { // If we don't have a media button receiver to fall back on // include non-playing sessions for dispatching UserRecord ur = mUserRecords.get(mCurrentUserId); boolean useNotPlayingSessions = (ur == null) || (ur.mLastMediaButtonReceiver == null && ur.mRestoredMediaButtonReceiver == null); MediaSessionRecord session = mPriorityStack .getDefaultMediaButtonSession(mCurrentUserId, useNotPlayingSessions); boolean useNotPlayingSessions = true; for (int userId : mCurrentUserIdList) { UserRecord ur = mUserRecords.get(userId); if (ur.mLastMediaButtonReceiver != null || ur.mRestoredMediaButtonReceiver != null) { useNotPlayingSessions = false; break; } } if (DEBUG) { Log.d(TAG, "dispatchMediaKeyEvent, useNotPlayingSessions=" + useNotPlayingSessions); } MediaSessionRecord session = mPriorityStack.getDefaultMediaButtonSession( mCurrentUserIdList, useNotPlayingSessions); if (isVoiceKey(keyEvent.getKeyCode())) { handleVoiceKeyEventLocked(keyEvent, needWakeLock, session); } else { Loading @@ -786,13 +794,11 @@ public class MediaSessionService extends SystemService implements Monitor { @Override public void dispatchAdjustVolume(int suggestedStream, int delta, int flags) { final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { synchronized (mLock) { MediaSessionRecord session = mPriorityStack .getDefaultVolumeSession(mCurrentUserId); .getDefaultVolumeSession(mCurrentUserIdList); dispatchAdjustVolumeLocked(suggestedStream, delta, flags, session); } } finally { Loading Loading @@ -910,7 +916,7 @@ public class MediaSessionService extends SystemService implements Monitor { }); } else { session.adjustVolume(direction, flags, getContext().getPackageName(), UserHandle.myUserId(), true); Process.SYSTEM_UID, true); } } Loading Loading @@ -957,13 +963,16 @@ public class MediaSessionService extends SystemService implements Monitor { // won't release it later session.sendMediaButton(keyEvent, needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1, mKeyEventReceiver, getContext().getApplicationInfo().uid, mKeyEventReceiver, Process.SYSTEM_UID, getContext().getPackageName()); } else { // Launch the last PendingIntent we had with priority UserRecord user = mUserRecords.get(mCurrentUserId); if (user != null && (user.mLastMediaButtonReceiver != null || user.mRestoredMediaButtonReceiver != null)) { for (int userId : mCurrentUserIdList) { UserRecord user = mUserRecords.get(userId); if (user.mLastMediaButtonReceiver == null && user.mRestoredMediaButtonReceiver == null) { continue; } if (DEBUG) { Log.d(TAG, "Sending media key to last known PendingIntent " + user.mLastMediaButtonReceiver + " or restored Intent " Loading @@ -983,13 +992,14 @@ public class MediaSessionService extends SystemService implements Monitor { } else { mediaButtonIntent.setComponent(user.mRestoredMediaButtonReceiver); getContext().sendBroadcastAsUser(mediaButtonIntent, new UserHandle(mCurrentUserId)); UserHandle.of(userId)); } } catch (CanceledException e) { Log.i(TAG, "Error sending key event to media button receiver " + user.mLastMediaButtonReceiver, e); } } else { return; } if (DEBUG) { Log.d(TAG, "Sending media key ordered broadcast"); } Loading @@ -1001,14 +1011,13 @@ public class MediaSessionService extends SystemService implements Monitor { keyIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent); if (needWakeLock) { keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED, WAKELOCK_RELEASE_ON_FINISHED); keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED, WAKELOCK_RELEASE_ON_FINISHED); } // Send broadcast only to the full user. getContext().sendOrderedBroadcastAsUser(keyIntent, UserHandle.CURRENT, null, mKeyEventDone, mHandler, Activity.RESULT_OK, null, null); } } } private void startVoiceInput(boolean needWakeLock) { Intent voiceIntent = null; Loading Loading @@ -1036,6 +1045,7 @@ public class MediaSessionService extends SystemService implements Monitor { if (voiceIntent != null) { voiceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); if (DEBUG) Log.d(TAG, "voiceIntent: " + voiceIntent); getContext().startActivityAsUser(voiceIntent, UserHandle.CURRENT); } } catch (ActivityNotFoundException e) { Loading services/core/java/com/android/server/media/MediaSessionStack.java +25 −17 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ import java.util.List; * Keeps track of media sessions and their priority for notifications, media * button dispatch, etc. */ public class MediaSessionStack { class MediaSessionStack { /** * These are states that usually indicate the user took an action and should * bump priority regardless of the old state. Loading Loading @@ -68,13 +68,10 @@ public class MediaSessionStack { * Checks if a media session is created from the most recent app. * * @param record A media session record to be examined. * @return true if the media session's package name equals to the most recent app, false * @return {@code true} if the media session's package name equals to the most recent app, false * otherwise. */ private static boolean isFromMostRecentApp(MediaSessionRecord record) { if (ActivityManager.getCurrentUser() != record.getUserId()) { return false; } try { List<ActivityManager.RecentTaskInfo> tasks = ActivityManagerNative.getDefault().getRecentTasks(1, Loading @@ -84,10 +81,11 @@ public class MediaSessionStack { ActivityManager.RECENT_WITH_EXCLUDED, record.getUserId()).getList(); if (tasks != null && !tasks.isEmpty()) { ActivityManager.RecentTaskInfo recentTask = tasks.get(0); if (recentTask.baseIntent != null) if (recentTask.userId == record.getUserId() && recentTask.baseIntent != null) { return recentTask.baseIntent.getComponent().getPackageName() .equals(record.getPackageName()); } } } catch (RemoteException e) { return false; } Loading @@ -98,11 +96,12 @@ public class MediaSessionStack { * Add a record to the priority tracker. * * @param record The record to add. * @param fromForegroundUser {@code true} if the session is created by the foreground user. */ public void addSession(MediaSessionRecord record) { public void addSession(MediaSessionRecord record, boolean fromForegroundUser) { mSessions.add(record); clearCache(); if (isFromMostRecentApp(record)) { if (fromForegroundUser && isFromMostRecentApp(record)) { mLastInterestingRecord = record; } } Loading Loading @@ -210,12 +209,13 @@ public class MediaSessionStack { /** * Get the highest priority session that can handle media buttons. * * @param userId The user to check. * @param userIdList The user lists to check. * @param includeNotPlaying Return a non-playing session if nothing else is * available * @return The default media button session or null. */ public MediaSessionRecord getDefaultMediaButtonSession(int userId, boolean includeNotPlaying) { public MediaSessionRecord getDefaultMediaButtonSession( List<Integer> userIdList, boolean includeNotPlaying) { if (mGlobalPrioritySession != null && mGlobalPrioritySession.isActive()) { return mGlobalPrioritySession; } Loading @@ -223,7 +223,7 @@ public class MediaSessionStack { return mCachedButtonReceiver; } ArrayList<MediaSessionRecord> records = getPriorityListLocked(true, MediaSession.FLAG_HANDLES_MEDIA_BUTTONS, userId); MediaSession.FLAG_HANDLES_MEDIA_BUTTONS, userIdList); if (records.size() > 0) { MediaSessionRecord record = records.get(0); if (record.isPlaybackActive(false)) { Loading @@ -248,14 +248,14 @@ public class MediaSessionStack { return mCachedButtonReceiver; } public MediaSessionRecord getDefaultVolumeSession(int userId) { public MediaSessionRecord getDefaultVolumeSession(List<Integer> userIdList) { if (mGlobalPrioritySession != null && mGlobalPrioritySession.isActive()) { return mGlobalPrioritySession; } if (mCachedVolumeDefault != null) { return mCachedVolumeDefault; } ArrayList<MediaSessionRecord> records = getPriorityListLocked(true, 0, userId); ArrayList<MediaSessionRecord> records = getPriorityListLocked(true, 0, userIdList); int size = records.size(); for (int i = 0; i < size; i++) { MediaSessionRecord record = records.get(i); Loading Loading @@ -298,6 +298,13 @@ public class MediaSessionStack { } } private ArrayList<MediaSessionRecord> getPriorityListLocked(boolean activeOnly, int withFlags, int userId) { List<Integer> userIdList = new ArrayList<>(); userIdList.add(userId); return getPriorityListLocked(activeOnly, withFlags, userIdList); } /** * Get a priority sorted list of sessions. Can filter to only return active * sessions or sessions with specific flags. Loading @@ -306,22 +313,23 @@ public class MediaSessionStack { * all sessions. * @param withFlags Only return sessions with all the specified flags set. 0 * returns all sessions. * @param userId The user to get sessions for. {@link UserHandle#USER_ALL} * @param userIdList The user to get sessions for. {@link UserHandle#USER_ALL} * will return sessions for all users. * @return The priority sorted list of sessions. */ private ArrayList<MediaSessionRecord> getPriorityListLocked(boolean activeOnly, int withFlags, int userId) { List<Integer> userIdList) { ArrayList<MediaSessionRecord> result = new ArrayList<MediaSessionRecord>(); int lastLocalIndex = 0; int lastActiveIndex = 0; int lastPublishedIndex = 0; boolean filterUser = !userIdList.contains(UserHandle.USER_ALL); int size = mSessions.size(); for (int i = 0; i < size; i++) { final MediaSessionRecord session = mSessions.get(i); if (userId != UserHandle.USER_ALL && userId != session.getUserId()) { if (filterUser && !userIdList.contains(session.getUserId())) { // Filter out sessions for the wrong user continue; } Loading Loading
services/core/java/com/android/server/media/MediaSessionRecord.java +1 −1 Original line number Diff line number Diff line Loading @@ -454,7 +454,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public String toString() { return mPackageName + "/" + mTag; return mPackageName + "/" + mTag + " (uid=" + mUserId + ")"; } private void postAdjustLocalVolume(final int stream, final int direction, final int flags, Loading
services/core/java/com/android/server/media/MediaSessionService.java +77 −67 Original line number Diff line number Diff line Loading @@ -47,10 +47,12 @@ import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.speech.RecognizerIntent; import android.text.TextUtils; Loading @@ -67,6 +69,7 @@ import com.android.server.Watchdog.Monitor; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** Loading Loading @@ -97,7 +100,9 @@ public class MediaSessionService extends SystemService implements Monitor { private ContentResolver mContentResolver; private SettingsObserver mSettingsObserver; private int mCurrentUserId = -1; // List of user IDs running in the foreground. // Multiple users can be in the foreground if the work profile is on. private final List<Integer> mCurrentUserIdList = new ArrayList<>(); // Used to notify system UI when remote volume was changed. TODO find a // better way to handle this. Loading Loading @@ -181,22 +186,26 @@ public class MediaSessionService extends SystemService implements Monitor { } @Override public void onStartUser(int userHandle) { public void onStartUser(int userId) { if (DEBUG) Log.d(TAG, "onStartUser: " + userId); updateUser(); } @Override public void onSwitchUser(int userHandle) { public void onSwitchUser(int userId) { if (DEBUG) Log.d(TAG, "onSwitchUser: " + userId); updateUser(); } @Override public void onStopUser(int userHandle) { public void onStopUser(int userId) { if (DEBUG) Log.d(TAG, "onStopUser: " + userId); synchronized (mLock) { UserRecord user = mUserRecords.get(userHandle); UserRecord user = mUserRecords.get(userId); if (user != null) { destroyUserLocked(user); } updateUser(); } } Loading Loading @@ -229,17 +238,23 @@ public class MediaSessionService extends SystemService implements Monitor { private void updateUser() { int userId = ActivityManager.getCurrentUser(); synchronized (mLock) { if (mCurrentUserId != userId) { final int oldUserId = mCurrentUserId; mCurrentUserId = userId; // do this first UserRecord oldUser = mUserRecords.get(oldUserId); if (oldUser != null) { oldUser.stopLocked(); UserManager manager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); int currentUser = ActivityManager.getCurrentUser(); int[] userIds = manager.getEnabledProfileIds(currentUser); mCurrentUserIdList.clear(); if (userIds != null && userIds.length > 0) { for (int userId : userIds) { mCurrentUserIdList.add(userId); } } else { // This shouldn't happen. Log.w(TAG, "Failed to get enabled profiles."); mCurrentUserIdList.add(currentUser); } for (int userId : mCurrentUserIdList) { if (mUserRecords.get(userId) == null) { mUserRecords.put(userId, new UserRecord(getContext(), userId)); } UserRecord newUser = getOrCreateUser(userId); newUser.startLocked(); } } } Loading Loading @@ -272,7 +287,6 @@ public class MediaSessionService extends SystemService implements Monitor { * @param user The user to dispose of */ private void destroyUserLocked(UserRecord user) { user.stopLocked(); user.destroyLocked(); mUserRecords.remove(user.mUserId); } Loading Loading @@ -436,9 +450,9 @@ public class MediaSessionService extends SystemService implements Monitor { } mAllSessions.add(session); mPriorityStack.addSession(session); mPriorityStack.addSession(session, mCurrentUserIdList.contains(userId)); UserRecord user = getOrCreateUser(userId); UserRecord user = mUserRecords.get(userId); user.addSessionLocked(session); mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, userId, 0); Loading @@ -449,15 +463,6 @@ public class MediaSessionService extends SystemService implements Monitor { return session; } private UserRecord getOrCreateUser(int userId) { UserRecord user = mUserRecords.get(userId); if (user == null) { user = new UserRecord(getContext(), userId); mUserRecords.put(userId, user); } return user; } private int findIndexOfSessionsListenerLocked(IActiveSessionsListener listener) { for (int i = mSessionsListeners.size() - 1; i >= 0; i--) { if (mSessionsListeners.get(i).mListener.asBinder() == listener.asBinder()) { Loading Loading @@ -536,13 +541,6 @@ public class MediaSessionService extends SystemService implements Monitor { restoreMediaButtonReceiver(); } public void startLocked() { } public void stopLocked() { // nothing for now } public void destroyLocked() { for (int i = mSessions.size() - 1; i >= 0; i--) { MediaSessionRecord session = mSessions.get(i); Loading Loading @@ -578,7 +576,7 @@ public class MediaSessionService extends SystemService implements Monitor { private void restoreMediaButtonReceiver() { String receiverName = Settings.Secure.getStringForUser(mContentResolver, Settings.System.MEDIA_BUTTON_RECEIVER, UserHandle.USER_CURRENT); Settings.System.MEDIA_BUTTON_RECEIVER, mUserId); if (!TextUtils.isEmpty(receiverName)) { ComponentName eventReceiver = ComponentName.unflattenFromString(receiverName); if (eventReceiver == null) { Loading Loading @@ -767,12 +765,22 @@ public class MediaSessionService extends SystemService implements Monitor { synchronized (mLock) { // If we don't have a media button receiver to fall back on // include non-playing sessions for dispatching UserRecord ur = mUserRecords.get(mCurrentUserId); boolean useNotPlayingSessions = (ur == null) || (ur.mLastMediaButtonReceiver == null && ur.mRestoredMediaButtonReceiver == null); MediaSessionRecord session = mPriorityStack .getDefaultMediaButtonSession(mCurrentUserId, useNotPlayingSessions); boolean useNotPlayingSessions = true; for (int userId : mCurrentUserIdList) { UserRecord ur = mUserRecords.get(userId); if (ur.mLastMediaButtonReceiver != null || ur.mRestoredMediaButtonReceiver != null) { useNotPlayingSessions = false; break; } } if (DEBUG) { Log.d(TAG, "dispatchMediaKeyEvent, useNotPlayingSessions=" + useNotPlayingSessions); } MediaSessionRecord session = mPriorityStack.getDefaultMediaButtonSession( mCurrentUserIdList, useNotPlayingSessions); if (isVoiceKey(keyEvent.getKeyCode())) { handleVoiceKeyEventLocked(keyEvent, needWakeLock, session); } else { Loading @@ -786,13 +794,11 @@ public class MediaSessionService extends SystemService implements Monitor { @Override public void dispatchAdjustVolume(int suggestedStream, int delta, int flags) { final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { synchronized (mLock) { MediaSessionRecord session = mPriorityStack .getDefaultVolumeSession(mCurrentUserId); .getDefaultVolumeSession(mCurrentUserIdList); dispatchAdjustVolumeLocked(suggestedStream, delta, flags, session); } } finally { Loading Loading @@ -910,7 +916,7 @@ public class MediaSessionService extends SystemService implements Monitor { }); } else { session.adjustVolume(direction, flags, getContext().getPackageName(), UserHandle.myUserId(), true); Process.SYSTEM_UID, true); } } Loading Loading @@ -957,13 +963,16 @@ public class MediaSessionService extends SystemService implements Monitor { // won't release it later session.sendMediaButton(keyEvent, needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1, mKeyEventReceiver, getContext().getApplicationInfo().uid, mKeyEventReceiver, Process.SYSTEM_UID, getContext().getPackageName()); } else { // Launch the last PendingIntent we had with priority UserRecord user = mUserRecords.get(mCurrentUserId); if (user != null && (user.mLastMediaButtonReceiver != null || user.mRestoredMediaButtonReceiver != null)) { for (int userId : mCurrentUserIdList) { UserRecord user = mUserRecords.get(userId); if (user.mLastMediaButtonReceiver == null && user.mRestoredMediaButtonReceiver == null) { continue; } if (DEBUG) { Log.d(TAG, "Sending media key to last known PendingIntent " + user.mLastMediaButtonReceiver + " or restored Intent " Loading @@ -983,13 +992,14 @@ public class MediaSessionService extends SystemService implements Monitor { } else { mediaButtonIntent.setComponent(user.mRestoredMediaButtonReceiver); getContext().sendBroadcastAsUser(mediaButtonIntent, new UserHandle(mCurrentUserId)); UserHandle.of(userId)); } } catch (CanceledException e) { Log.i(TAG, "Error sending key event to media button receiver " + user.mLastMediaButtonReceiver, e); } } else { return; } if (DEBUG) { Log.d(TAG, "Sending media key ordered broadcast"); } Loading @@ -1001,14 +1011,13 @@ public class MediaSessionService extends SystemService implements Monitor { keyIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent); if (needWakeLock) { keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED, WAKELOCK_RELEASE_ON_FINISHED); keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED, WAKELOCK_RELEASE_ON_FINISHED); } // Send broadcast only to the full user. getContext().sendOrderedBroadcastAsUser(keyIntent, UserHandle.CURRENT, null, mKeyEventDone, mHandler, Activity.RESULT_OK, null, null); } } } private void startVoiceInput(boolean needWakeLock) { Intent voiceIntent = null; Loading Loading @@ -1036,6 +1045,7 @@ public class MediaSessionService extends SystemService implements Monitor { if (voiceIntent != null) { voiceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); if (DEBUG) Log.d(TAG, "voiceIntent: " + voiceIntent); getContext().startActivityAsUser(voiceIntent, UserHandle.CURRENT); } } catch (ActivityNotFoundException e) { Loading
services/core/java/com/android/server/media/MediaSessionStack.java +25 −17 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ import java.util.List; * Keeps track of media sessions and their priority for notifications, media * button dispatch, etc. */ public class MediaSessionStack { class MediaSessionStack { /** * These are states that usually indicate the user took an action and should * bump priority regardless of the old state. Loading Loading @@ -68,13 +68,10 @@ public class MediaSessionStack { * Checks if a media session is created from the most recent app. * * @param record A media session record to be examined. * @return true if the media session's package name equals to the most recent app, false * @return {@code true} if the media session's package name equals to the most recent app, false * otherwise. */ private static boolean isFromMostRecentApp(MediaSessionRecord record) { if (ActivityManager.getCurrentUser() != record.getUserId()) { return false; } try { List<ActivityManager.RecentTaskInfo> tasks = ActivityManagerNative.getDefault().getRecentTasks(1, Loading @@ -84,10 +81,11 @@ public class MediaSessionStack { ActivityManager.RECENT_WITH_EXCLUDED, record.getUserId()).getList(); if (tasks != null && !tasks.isEmpty()) { ActivityManager.RecentTaskInfo recentTask = tasks.get(0); if (recentTask.baseIntent != null) if (recentTask.userId == record.getUserId() && recentTask.baseIntent != null) { return recentTask.baseIntent.getComponent().getPackageName() .equals(record.getPackageName()); } } } catch (RemoteException e) { return false; } Loading @@ -98,11 +96,12 @@ public class MediaSessionStack { * Add a record to the priority tracker. * * @param record The record to add. * @param fromForegroundUser {@code true} if the session is created by the foreground user. */ public void addSession(MediaSessionRecord record) { public void addSession(MediaSessionRecord record, boolean fromForegroundUser) { mSessions.add(record); clearCache(); if (isFromMostRecentApp(record)) { if (fromForegroundUser && isFromMostRecentApp(record)) { mLastInterestingRecord = record; } } Loading Loading @@ -210,12 +209,13 @@ public class MediaSessionStack { /** * Get the highest priority session that can handle media buttons. * * @param userId The user to check. * @param userIdList The user lists to check. * @param includeNotPlaying Return a non-playing session if nothing else is * available * @return The default media button session or null. */ public MediaSessionRecord getDefaultMediaButtonSession(int userId, boolean includeNotPlaying) { public MediaSessionRecord getDefaultMediaButtonSession( List<Integer> userIdList, boolean includeNotPlaying) { if (mGlobalPrioritySession != null && mGlobalPrioritySession.isActive()) { return mGlobalPrioritySession; } Loading @@ -223,7 +223,7 @@ public class MediaSessionStack { return mCachedButtonReceiver; } ArrayList<MediaSessionRecord> records = getPriorityListLocked(true, MediaSession.FLAG_HANDLES_MEDIA_BUTTONS, userId); MediaSession.FLAG_HANDLES_MEDIA_BUTTONS, userIdList); if (records.size() > 0) { MediaSessionRecord record = records.get(0); if (record.isPlaybackActive(false)) { Loading @@ -248,14 +248,14 @@ public class MediaSessionStack { return mCachedButtonReceiver; } public MediaSessionRecord getDefaultVolumeSession(int userId) { public MediaSessionRecord getDefaultVolumeSession(List<Integer> userIdList) { if (mGlobalPrioritySession != null && mGlobalPrioritySession.isActive()) { return mGlobalPrioritySession; } if (mCachedVolumeDefault != null) { return mCachedVolumeDefault; } ArrayList<MediaSessionRecord> records = getPriorityListLocked(true, 0, userId); ArrayList<MediaSessionRecord> records = getPriorityListLocked(true, 0, userIdList); int size = records.size(); for (int i = 0; i < size; i++) { MediaSessionRecord record = records.get(i); Loading Loading @@ -298,6 +298,13 @@ public class MediaSessionStack { } } private ArrayList<MediaSessionRecord> getPriorityListLocked(boolean activeOnly, int withFlags, int userId) { List<Integer> userIdList = new ArrayList<>(); userIdList.add(userId); return getPriorityListLocked(activeOnly, withFlags, userIdList); } /** * Get a priority sorted list of sessions. Can filter to only return active * sessions or sessions with specific flags. Loading @@ -306,22 +313,23 @@ public class MediaSessionStack { * all sessions. * @param withFlags Only return sessions with all the specified flags set. 0 * returns all sessions. * @param userId The user to get sessions for. {@link UserHandle#USER_ALL} * @param userIdList The user to get sessions for. {@link UserHandle#USER_ALL} * will return sessions for all users. * @return The priority sorted list of sessions. */ private ArrayList<MediaSessionRecord> getPriorityListLocked(boolean activeOnly, int withFlags, int userId) { List<Integer> userIdList) { ArrayList<MediaSessionRecord> result = new ArrayList<MediaSessionRecord>(); int lastLocalIndex = 0; int lastActiveIndex = 0; int lastPublishedIndex = 0; boolean filterUser = !userIdList.contains(UserHandle.USER_ALL); int size = mSessions.size(); for (int i = 0; i < size; i++) { final MediaSessionRecord session = mSessions.get(i); if (userId != UserHandle.USER_ALL && userId != session.getUserId()) { if (filterUser && !userIdList.contains(session.getUserId())) { // Filter out sessions for the wrong user continue; } Loading