diff options
| author | 2017-06-22 00:11:47 +0000 | |
|---|---|---|
| committer | 2017-06-22 00:11:54 +0000 | |
| commit | b82b7046ffbf9984dcce80d01e763de874abe4c7 (patch) | |
| tree | 111e3dce9139be787d99a1a8aecc0728408209e4 | |
| parent | 30be8d998ac5bb3bf0e691e9aec7c16f85f958ed (diff) | |
| parent | b3658569e9a87afe1b3168837cc282235fd4d1f8 (diff) | |
Merge "Restore the selected route when an app starts to make sound"
6 files changed, 288 insertions, 54 deletions
diff --git a/media/java/android/media/IMediaRouterClient.aidl b/media/java/android/media/IMediaRouterClient.aidl index 9640dcbd6518..08344f188098 100644 --- a/media/java/android/media/IMediaRouterClient.aidl +++ b/media/java/android/media/IMediaRouterClient.aidl @@ -21,4 +21,5 @@ package android.media; */ oneway interface IMediaRouterClient { void onStateChanged(); + void onRestoreRoute(); } diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl index f8f5fdfd2d62..3308fc929b03 100644 --- a/media/java/android/media/IMediaRouterService.aidl +++ b/media/java/android/media/IMediaRouterService.aidl @@ -27,6 +27,7 @@ interface IMediaRouterService { void unregisterClient(IMediaRouterClient client); MediaRouterClientState getState(IMediaRouterClient client); + boolean isPlaybackActive(IMediaRouterClient client); void setDiscoveryRequest(IMediaRouterClient client, int routeTypes, boolean activeScan); void setSelectedRoute(IMediaRouterClient client, String routeId, boolean explicit); diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java index d5509c14e09b..cff7043f0fa2 100644 --- a/media/java/android/media/MediaRouter.java +++ b/media/java/android/media/MediaRouter.java @@ -88,6 +88,7 @@ public class MediaRouter { RouteInfo mBluetoothA2dpRoute; RouteInfo mSelectedRoute; + RouteInfo mSystemAudioRoute; final boolean mCanConfigureWifiDisplays; boolean mActivelyScanningWifiDisplays; @@ -149,6 +150,7 @@ public class MediaRouter { } addRouteStatic(mDefaultAudioVideo); + mSystemAudioRoute = mDefaultAudioVideo; // This will select the active wifi display route if there is one. updateWifiDisplayStatus(mDisplayService.getWifiDisplayStatus()); @@ -197,8 +199,8 @@ public class MediaRouter { } else { name = com.android.internal.R.string.default_audio_route_name; } - sStatic.mDefaultAudioVideo.mNameResId = name; - dispatchRouteChanged(sStatic.mDefaultAudioVideo); + mDefaultAudioVideo.mNameResId = name; + dispatchRouteChanged(mDefaultAudioVideo); updated = true; } @@ -207,22 +209,28 @@ public class MediaRouter { if (!TextUtils.equals(newRoutes.bluetoothName, mCurAudioRoutesInfo.bluetoothName)) { mCurAudioRoutesInfo.bluetoothName = newRoutes.bluetoothName; if (mCurAudioRoutesInfo.bluetoothName != null) { - if (sStatic.mBluetoothA2dpRoute == null) { - final RouteInfo info = new RouteInfo(sStatic.mSystemCategory); + if (mBluetoothA2dpRoute == null) { + // BT connected + final RouteInfo info = new RouteInfo(mSystemCategory); info.mName = mCurAudioRoutesInfo.bluetoothName; - info.mDescription = sStatic.mResources.getText( + info.mDescription = mResources.getText( com.android.internal.R.string.bluetooth_a2dp_audio_route_name); info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO; info.mDeviceType = RouteInfo.DEVICE_TYPE_BLUETOOTH; - sStatic.mBluetoothA2dpRoute = info; - addRouteStatic(sStatic.mBluetoothA2dpRoute); + mBluetoothA2dpRoute = info; + addRouteStatic(mBluetoothA2dpRoute); + mSystemAudioRoute = mBluetoothA2dpRoute; + selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mSystemAudioRoute, false); } else { - sStatic.mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.bluetoothName; - dispatchRouteChanged(sStatic.mBluetoothA2dpRoute); + mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.bluetoothName; + dispatchRouteChanged(mBluetoothA2dpRoute); } - } else if (sStatic.mBluetoothA2dpRoute != null) { - removeRouteStatic(sStatic.mBluetoothA2dpRoute); - sStatic.mBluetoothA2dpRoute = null; + } else if (mBluetoothA2dpRoute != null) { + // BT disconnected + removeRouteStatic(mBluetoothA2dpRoute); + mBluetoothA2dpRoute = null; + mSystemAudioRoute = mDefaultAudioVideo; + selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mSystemAudioRoute, false); } updated = true; } @@ -230,11 +238,13 @@ public class MediaRouter { if (mBluetoothA2dpRoute != null) { final boolean a2dpEnabled = isBluetoothA2dpOn(); if (mSelectedRoute == mBluetoothA2dpRoute && !a2dpEnabled) { - selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo, false); + // A2DP off + mSystemAudioRoute = mDefaultAudioVideo; updated = true; } else if ((mSelectedRoute == mDefaultAudioVideo || mSelectedRoute == null) && a2dpEnabled) { - selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute, false); + // A2DP on or BT connected + mSystemAudioRoute = mBluetoothA2dpRoute; updated = true; } } @@ -471,7 +481,7 @@ public class MediaRouter { } RouteInfo makeGlobalRoute(MediaRouterClientState.RouteInfo globalRoute) { - RouteInfo route = new RouteInfo(sStatic.mSystemCategory); + RouteInfo route = new RouteInfo(mSystemCategory); route.mGlobalRouteId = globalRoute.id; route.mName = globalRoute.name; route.mDescription = globalRoute.description; @@ -567,6 +577,17 @@ public class MediaRouter { return null; } + boolean isPlaybackActive() { + if (mClient != null) { + try { + return mMediaRouterService.isPlaybackActive(mClient); + } catch (RemoteException ex) { + Log.e(TAG, "Unable to retrieve playback active state.", ex); + } + } + return false; + } + final class Client extends IMediaRouterClient.Stub { @Override public void onStateChanged() { @@ -579,6 +600,19 @@ public class MediaRouter { } }); } + + @Override + public void onRestoreRoute() { + if ((mSelectedRoute != mDefaultAudioVideo && mSelectedRoute != mBluetoothA2dpRoute) + || mSelectedRoute == mSystemAudioRoute) { + return; + } + try { + sStatic.mAudioService.setBluetoothA2dpOn(mSelectedRoute == mBluetoothA2dpRoute); + } catch (RemoteException e) { + Log.e(TAG, "Error changing Bluetooth A2DP state", e); + } + } } } @@ -900,7 +934,12 @@ public class MediaRouter { Log.v(TAG, "Selecting route: " + route); assert(route != null); final RouteInfo oldRoute = sStatic.mSelectedRoute; - if (oldRoute == route) return; + boolean wasDefaultOrBluetoothRoute = (oldRoute == sStatic.mDefaultAudioVideo + || oldRoute == sStatic.mBluetoothA2dpRoute); + if (oldRoute == route + && (!wasDefaultOrBluetoothRoute || oldRoute == sStatic.mSystemAudioRoute)) { + return; + } if (!route.matchesTypes(types)) { Log.w(TAG, "selectRoute ignored; cannot select route with supported types " + typesToString(route.getSupportedTypes()) + " into route types " + @@ -909,8 +948,8 @@ public class MediaRouter { } final RouteInfo btRoute = sStatic.mBluetoothA2dpRoute; - if (btRoute != null && (types & ROUTE_TYPE_LIVE_AUDIO) != 0 && - (route == btRoute || route == sStatic.mDefaultAudioVideo)) { + if (sStatic.isPlaybackActive() && btRoute != null && (types & ROUTE_TYPE_LIVE_AUDIO) != 0 + && (route == btRoute || route == sStatic.mDefaultAudioVideo)) { try { sStatic.mAudioService.setBluetoothA2dpOn(route == btRoute); } catch (RemoteException e) { diff --git a/services/core/java/com/android/server/media/AudioPlaybackMonitor.java b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java index c6dc11c53393..f6f767653c83 100644 --- a/services/core/java/com/android/server/media/AudioPlaybackMonitor.java +++ b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java @@ -31,17 +31,22 @@ import android.util.SparseArray; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashSet; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; /** - * Monitors changes in audio playback and notify the newly started audio playback through the - * {@link OnAudioPlaybackStartedListener}. + * Monitors changes in audio playback, and notify the newly started audio playback through the + * {@link OnAudioPlaybackStartedListener} and the activeness change through the + * {@link OnAudioPlaybackActiveStateListener}. */ class AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub { private static boolean DEBUG = MediaSessionService.DEBUG; private static String TAG = "AudioPlaybackMonitor"; + private static AudioPlaybackMonitor sInstance; + /** * Called when audio playback is started for a given UID. */ @@ -49,22 +54,36 @@ class AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub { void onAudioPlaybackStarted(int uid); } + /** + * Called when audio player state is changed. + */ + interface OnAudioPlayerActiveStateChangedListener { + void onAudioPlayerActiveStateChanged(int uid, boolean active); + } + private final Object mLock = new Object(); private final Context mContext; - private final OnAudioPlaybackStartedListener mListener; - - private Set<Integer> mActiveAudioPlaybackPlayerInterfaceIds = new HashSet<>(); - private Set<Integer> mActiveAudioPlaybackClientUids = new HashSet<>(); + private final List<OnAudioPlaybackStartedListener> mAudioPlaybackStartedListeners + = new ArrayList<>(); + private final List<OnAudioPlayerActiveStateChangedListener> + mAudioPlayerActiveStateChangedListeners = new ArrayList<>(); + private final Map<Integer, Integer> mAudioPlaybackStates = new HashMap<>(); + private final Set<Integer> mActiveAudioPlaybackClientUids = new HashSet<>(); // Sorted array of UIDs that had active audio playback. (i.e. playing an audio/video) // The UID whose audio playback becomes active at the last comes first. // TODO(b/35278867): Find and use unique identifier for apps because apps may share the UID. private final IntArray mSortedAudioPlaybackClientUids = new IntArray(); - AudioPlaybackMonitor(Context context, IAudioService audioService, - OnAudioPlaybackStartedListener listener) { + static AudioPlaybackMonitor getInstance(Context context, IAudioService audioService) { + if (sInstance == null) { + sInstance = new AudioPlaybackMonitor(context, audioService); + } + return sInstance; + } + + private AudioPlaybackMonitor(Context context, IAudioService audioService) { mContext = context; - mListener = listener; try { audioService.registerPlaybackCallback(this); } catch (RemoteException e) { @@ -84,9 +103,12 @@ class AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub { public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) { final long token = Binder.clearCallingIdentity(); try { - Set<Integer> newActiveAudioPlaybackPlayerInterfaceIds = new HashSet<>(); List<Integer> newActiveAudioPlaybackClientUids = new ArrayList<>(); + List<OnAudioPlayerActiveStateChangedListener> audioPlayerActiveStateChangedListeners; + List<OnAudioPlaybackStartedListener> audioPlaybackStartedListeners; synchronized (mLock) { + // Update mActiveAudioPlaybackClientUids and mSortedAudioPlaybackClientUids, + // and find newly activated audio playbacks. mActiveAudioPlaybackClientUids.clear(); for (AudioPlaybackConfiguration config : configs) { // Ignore inactive (i.e. not playing) or PLAYER_TYPE_JAM_SOUNDPOOL @@ -94,16 +116,14 @@ class AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub { // playback. // Note that we shouldn't ignore PLAYER_TYPE_UNKNOWN because it might be OEM // specific audio/video players. - if (!config.isActive() - || config.getPlayerType() + if (!config.isActive() || config.getPlayerType() == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) { continue; } - mActiveAudioPlaybackClientUids.add(config.getClientUid()); - newActiveAudioPlaybackPlayerInterfaceIds.add(config.getPlayerInterfaceId()); - if (!mActiveAudioPlaybackPlayerInterfaceIds.contains( - config.getPlayerInterfaceId())) { + mActiveAudioPlaybackClientUids.add(config.getClientUid()); + Integer oldState = mAudioPlaybackStates.get(config.getPlayerInterfaceId()); + if (!isActiveState(oldState)) { if (DEBUG) { Log.d(TAG, "Found a new active media playback. " + AudioPlaybackConfiguration.toLogFriendlyString(config)); @@ -120,11 +140,32 @@ class AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub { mSortedAudioPlaybackClientUids.add(0, config.getClientUid()); } } - mActiveAudioPlaybackPlayerInterfaceIds.clear(); - mActiveAudioPlaybackPlayerInterfaceIds = newActiveAudioPlaybackPlayerInterfaceIds; + audioPlayerActiveStateChangedListeners = new ArrayList<>( + mAudioPlayerActiveStateChangedListeners); + audioPlaybackStartedListeners = new ArrayList<>(mAudioPlaybackStartedListeners); } + // Notify the change of audio playback states. + for (AudioPlaybackConfiguration config : configs) { + boolean wasActive = isActiveState( + mAudioPlaybackStates.get(config.getPlayerInterfaceId())); + boolean isActive = config.isActive(); + if (wasActive != isActive) { + for (OnAudioPlayerActiveStateChangedListener listener + : audioPlayerActiveStateChangedListeners) { + listener.onAudioPlayerActiveStateChanged(config.getClientUid(), + isActive); + } + } + } + // Notify the start of audio playback for (int uid : newActiveAudioPlaybackClientUids) { - mListener.onAudioPlaybackStarted(uid); + for (OnAudioPlaybackStartedListener listener : audioPlaybackStartedListeners) { + listener.onAudioPlaybackStarted(uid); + } + } + mAudioPlaybackStates.clear(); + for (AudioPlaybackConfiguration config : configs) { + mAudioPlaybackStates.put(config.getPlayerInterfaceId(), config.getPlayerState()); } } finally { Binder.restoreCallingIdentity(token); @@ -132,6 +173,44 @@ class AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub { } /** + * Registers OnAudioPlaybackStartedListener. + */ + public void registerOnAudioPlaybackStartedListener(OnAudioPlaybackStartedListener listener) { + synchronized (mLock) { + mAudioPlaybackStartedListeners.add(listener); + } + } + + /** + * Unregisters OnAudioPlaybackStartedListener. + */ + public void unregisterOnAudioPlaybackStartedListener(OnAudioPlaybackStartedListener listener) { + synchronized (mLock) { + mAudioPlaybackStartedListeners.remove(listener); + } + } + + /** + * Registers OnAudioPlayerActiveStateChangedListener. + */ + public void registerOnAudioPlayerActiveStateChangedListener( + OnAudioPlayerActiveStateChangedListener listener) { + synchronized (mLock) { + mAudioPlayerActiveStateChangedListeners.add(listener); + } + } + + /** + * Unregisters OnAudioPlayerActiveStateChangedListener. + */ + public void unregisterOnAudioPlayerActiveStateChangedListener( + OnAudioPlayerActiveStateChangedListener listener) { + synchronized (mLock) { + mAudioPlayerActiveStateChangedListeners.remove(listener); + } + } + + /** * Returns the sorted list of UIDs that have had active audio playback. (i.e. playing an * audio/video) The UID whose audio playback becomes active at the last comes first. */ @@ -167,7 +246,8 @@ class AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub { if (mSortedAudioPlaybackClientUids.get(i) == mediaButtonSessionUid) { break; } - if (userId == UserHandle.getUserId(mSortedAudioPlaybackClientUids.get(i))) { + int uid = mSortedAudioPlaybackClientUids.get(i); + if (userId == UserHandle.getUserId(uid) && !isPlaybackActive(uid)) { // Clean up unnecessary UIDs. // It doesn't need to be managed profile aware because it's just to prevent // the list from increasing indefinitely. The media button session updating @@ -198,4 +278,8 @@ class AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub { } } } + + private boolean isActiveState(Integer state) { + return state != null && state.equals(AudioPlaybackConfiguration.PLAYER_STATE_STARTED); + } } diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java index d1fa5efe4dc1..5ba8f4853407 100644 --- a/services/core/java/com/android/server/media/MediaRouterService.java +++ b/services/core/java/com/android/server/media/MediaRouterService.java @@ -18,6 +18,7 @@ package com.android.server.media; import com.android.internal.util.DumpUtils; import com.android.server.Watchdog; +import com.android.server.media.AudioPlaybackMonitor.OnAudioPlayerActiveStateChangedListener; import android.Manifest; import android.app.ActivityManager; @@ -26,7 +27,10 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.media.AudioRoutesInfo; import android.media.AudioSystem; +import android.media.IAudioRoutesObserver; +import android.media.IAudioService; import android.media.IMediaRouterClient; import android.media.IMediaRouterService; import android.media.MediaRouter; @@ -39,9 +43,12 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.RemoteException; +import android.os.ServiceManager; import android.os.SystemClock; +import android.os.UserHandle; import android.text.TextUtils; import android.util.ArrayMap; +import android.util.IntArray; import android.util.Log; import android.util.Slog; import android.util.SparseArray; @@ -89,10 +96,54 @@ public final class MediaRouterService extends IMediaRouterService.Stub private final ArrayMap<IBinder, ClientRecord> mAllClientRecords = new ArrayMap<IBinder, ClientRecord>(); private int mCurrentUserId = -1; + private boolean mHasBluetoothRoute = false; + private final IAudioService mAudioService; + private final AudioPlaybackMonitor mAudioPlaybackMonitor; public MediaRouterService(Context context) { mContext = context; Watchdog.getInstance().addMonitor(this); + + mAudioService = IAudioService.Stub.asInterface( + ServiceManager.getService(Context.AUDIO_SERVICE)); + + mAudioPlaybackMonitor = AudioPlaybackMonitor.getInstance(context, mAudioService); + mAudioPlaybackMonitor.registerOnAudioPlayerActiveStateChangedListener( + new AudioPlaybackMonitor.OnAudioPlayerActiveStateChangedListener() { + @Override + public void onAudioPlayerActiveStateChanged(int uid, boolean active) { + if (active) { + restoreRoute(uid); + } else { + IntArray sortedAudioPlaybackClientUids = + mAudioPlaybackMonitor.getSortedAudioPlaybackClientUids(); + boolean restored = false; + for (int i = 0; i < sortedAudioPlaybackClientUids.size(); i++) { + if (mAudioPlaybackMonitor.isPlaybackActive( + sortedAudioPlaybackClientUids.get(i))) { + restoreRoute(sortedAudioPlaybackClientUids.get(i)); + restored = true; + break; + } + } + if (!restored) { + restoreBluetoothA2dp(); + } + } + } + }); + AudioRoutesInfo audioRoutes = null; + try { + audioRoutes = mAudioService.startWatchingRoutes(new IAudioRoutesObserver.Stub() { + @Override + public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) { + mHasBluetoothRoute = newRoutes.bluetoothName != null; + } + }); + } catch (RemoteException e) { + Slog.w(TAG, "RemoteException in the audio service."); + } + mHasBluetoothRoute = (audioRoutes != null && audioRoutes.bluetoothName != null); } public void systemRunning() { @@ -135,7 +186,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub final long token = Binder.clearCallingIdentity(); try { synchronized (mLock) { - registerClientLocked(client, pid, packageName, resolvedUserId, trusted); + registerClientLocked(client, uid, pid, packageName, resolvedUserId, trusted); } } finally { Binder.restoreCallingIdentity(token); @@ -178,6 +229,23 @@ public final class MediaRouterService extends IMediaRouterService.Stub // Binder call @Override + public boolean isPlaybackActive(IMediaRouterClient client) { + if (client == null) { + throw new IllegalArgumentException("client must not be null"); + } + + final long token = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + return isPlaybackActiveLocked(client); + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + + // Binder call + @Override public void setDiscoveryRequest(IMediaRouterClient client, int routeTypes, boolean activeScan) { if (client == null) { @@ -276,6 +344,36 @@ public final class MediaRouterService extends IMediaRouterService.Stub } } + void restoreBluetoothA2dp() { + try { + mAudioService.setBluetoothA2dpOn(mHasBluetoothRoute); + } catch (RemoteException e) { + Slog.w(TAG, "RemoteException while calling setBluetoothA2dpOn."); + } + } + + void restoreRoute(int uid) { + ClientRecord clientRecord = null; + UserRecord userRecord = mUserRecords.get(UserHandle.getUserId(uid)); + if (userRecord.mClientRecords != null) { + for (ClientRecord cr : userRecord.mClientRecords) { + if (validatePackageName(uid, cr.mPackageName)) { + clientRecord = cr; + break; + } + } + } + if (clientRecord != null) { + try { + clientRecord.mClient.onRestoreRoute(); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to call onRestoreRoute. Client probably died."); + } + } else { + restoreBluetoothA2dp(); + } + } + void switchUser() { synchronized (mLock) { int userId = ActivityManager.getCurrentUser(); @@ -304,7 +402,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub } private void registerClientLocked(IMediaRouterClient client, - int pid, String packageName, int userId, boolean trusted) { + int uid, int pid, String packageName, int userId, boolean trusted) { final IBinder binder = client.asBinder(); ClientRecord clientRecord = mAllClientRecords.get(binder); if (clientRecord == null) { @@ -314,7 +412,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub userRecord = new UserRecord(userId); newUser = true; } - clientRecord = new ClientRecord(userRecord, client, pid, packageName, trusted); + clientRecord = new ClientRecord(userRecord, client, uid, pid, packageName, trusted); try { binder.linkToDeath(clientRecord, 0); } catch (RemoteException ex) { @@ -350,6 +448,14 @@ public final class MediaRouterService extends IMediaRouterService.Stub return null; } + private boolean isPlaybackActiveLocked(IMediaRouterClient client) { + ClientRecord clientRecord = mAllClientRecords.get(client.asBinder()); + if (clientRecord != null) { + return mAudioPlaybackMonitor.isPlaybackActive(clientRecord.mUid); + } + return false; + } + private void setDiscoveryRequestLocked(IMediaRouterClient client, int routeTypes, boolean activeScan) { final IBinder binder = client.asBinder(); @@ -489,6 +595,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub final class ClientRecord implements DeathRecipient { public final UserRecord mUserRecord; public final IMediaRouterClient mClient; + public final int mUid; public final int mPid; public final String mPackageName; public final boolean mTrusted; @@ -498,9 +605,10 @@ public final class MediaRouterService extends IMediaRouterService.Stub public String mSelectedRouteId; public ClientRecord(UserRecord userRecord, IMediaRouterClient client, - int pid, String packageName, boolean trusted) { + int uid, int pid, String packageName, boolean trusted) { mUserRecord = userRecord; mClient = client; + mUid = uid; mPid = pid; mPackageName = packageName; mTrusted = trusted; @@ -997,7 +1105,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub try { mTempClients.get(i).onStateChanged(); } catch (RemoteException ex) { - // ignore errors, client probably died + Slog.w(TAG, "Failed to call onStateChanged. Client probably died."); } } } finally { diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 67920edcf56a..a0487f93981b 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -136,19 +136,20 @@ public class MediaSessionService extends SystemService implements Monitor { mKeyguardManager = (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE); mAudioService = getAudioService(); - mAudioPlaybackMonitor = new AudioPlaybackMonitor(getContext(), mAudioService, + mAudioPlaybackMonitor = AudioPlaybackMonitor.getInstance(getContext(), mAudioService); + mAudioPlaybackMonitor.registerOnAudioPlaybackStartedListener( new AudioPlaybackMonitor.OnAudioPlaybackStartedListener() { - @Override - public void onAudioPlaybackStarted(int uid) { - synchronized (mLock) { - FullUserRecord user = - getFullUserRecordLocked(UserHandle.getUserId(uid)); - if (user != null) { - user.mPriorityStack.updateMediaButtonSessionIfNeeded(); - } - } + @Override + public void onAudioPlaybackStarted(int uid) { + synchronized (mLock) { + FullUserRecord user = + getFullUserRecordLocked(UserHandle.getUserId(uid)); + if (user != null) { + user.mPriorityStack.updateMediaButtonSessionIfNeeded(); } - }); + } + } + }); mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class); mContentResolver = getContext().getContentResolver(); mSettingsObserver = new SettingsObserver(); |