Remove sessions listeners that are disabled
Removes sessions listeners when their notification listener is
disabled. Also updates the dump for media sessions.
bug:15549450
Change-Id: Ibe51a4a42ef333e75a09f0fffa0f2b9b8939b85c
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 92644ce..277344e 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -29,6 +29,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.database.ContentObserver;
import android.media.AudioManager;
import android.media.IAudioService;
import android.media.IRemoteVolumeController;
@@ -37,6 +38,7 @@
import android.media.session.ISessionCallback;
import android.media.session.ISessionManager;
import android.media.session.MediaSession;
+import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -86,6 +88,7 @@
private KeyguardManager mKeyguardManager;
private IAudioService mAudioService;
private ContentResolver mContentResolver;
+ private SettingsObserver mSettingsObserver;
private MediaSessionRecord mPrioritySession;
private int mCurrentUserId = -1;
@@ -111,6 +114,8 @@
(KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
mAudioService = getAudioService();
mContentResolver = getContext().getContentResolver();
+ mSettingsObserver = new SettingsObserver();
+ mSettingsObserver.observe();
}
private IAudioService getAudioService() {
@@ -229,6 +234,28 @@
}
}
+ 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
+ }
+ }
+ }
+ }
+ }
+
/**
* Stop the user and unbind from everything.
*
@@ -525,11 +552,19 @@
final class SessionsListenerRecord implements IBinder.DeathRecipient {
private final IActiveSessionsListener mListener;
+ private final ComponentName mComponentName;
private final int mUserId;
+ private final int mPid;
+ private final int mUid;
- public SessionsListenerRecord(IActiveSessionsListener listener, int userId) {
+ public SessionsListenerRecord(IActiveSessionsListener listener,
+ ComponentName componentName,
+ int userId, int pid, int uid) {
mListener = listener;
+ mComponentName = componentName;
mUserId = userId;
+ mPid = pid;
+ mUid = uid;
}
@Override
@@ -540,6 +575,25 @@
}
}
+ final class SettingsObserver extends ContentObserver {
+ private final Uri mSecureSettingsUri = Settings.Secure.getUriFor(
+ Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
+
+ private SettingsObserver() {
+ super(null);
+ }
+
+ private void observe() {
+ mContentResolver.registerContentObserver(mSecureSettingsUri,
+ false, this, UserHandle.USER_ALL);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ updateActiveSessionListeners();
+ }
+ }
+
class SessionManagerImpl extends ISessionManager.Stub {
private static final String EXTRA_WAKELOCK_ACQUIRED =
"android.media.AudioService.WAKELOCK_ACQUIRED";
@@ -607,7 +661,7 @@
return;
}
SessionsListenerRecord record = new SessionsListenerRecord(listener,
- resolvedUserId);
+ componentName, resolvedUserId, pid, uid);
try {
listener.asBinder().linkToDeath(record, 0);
} catch (RemoteException e) {