Merge "Restore the selected route when an app starts to make sound" into oc-dr1-dev
diff --git a/media/java/android/media/IMediaRouterClient.aidl b/media/java/android/media/IMediaRouterClient.aidl
index 9640dcb..08344f1 100644
--- a/media/java/android/media/IMediaRouterClient.aidl
+++ b/media/java/android/media/IMediaRouterClient.aidl
@@ -21,4 +21,5 @@
*/
oneway interface IMediaRouterClient {
void onStateChanged();
+ void onRestoreRoute();
}
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index f8f5fdf..3308fc9 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -27,6 +27,7 @@
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 8caba81..80a0315 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -88,6 +88,7 @@
RouteInfo mBluetoothA2dpRoute;
RouteInfo mSelectedRoute;
+ RouteInfo mSystemAudioRoute;
final boolean mCanConfigureWifiDisplays;
boolean mActivelyScanningWifiDisplays;
@@ -149,6 +150,7 @@
}
addRouteStatic(mDefaultAudioVideo);
+ mSystemAudioRoute = mDefaultAudioVideo;
// This will select the active wifi display route if there is one.
updateWifiDisplayStatus(mDisplayService.getWifiDisplayStatus());
@@ -197,8 +199,8 @@
} 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 @@
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 @@
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 @@
}
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 @@
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 @@
}
});
}
+
+ @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);
+ }
+ }
}
}
@@ -909,7 +943,12 @@
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 " +
@@ -918,8 +957,8 @@
}
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);
// TODO: Remove the following logging when no longer needed.
diff --git a/services/core/java/com/android/server/media/AudioPlaybackMonitor.java b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java
index c6dc11c..f6f7676 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 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 @@
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 @@
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 @@
// 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 @@
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 @@
}
/**
+ * 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 @@
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 @@
}
}
}
+
+ 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 d1fa5ef..5ba8f48 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 @@
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.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.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 @@
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 @@
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 @@
// 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 @@
}
}
+ 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 @@
}
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 @@
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 @@
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 @@
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 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 @@
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 38c6157..adb50f0 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -138,19 +138,20 @@
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();