From 1ea56832178b40ce5a54ee77e6a01108496dc6e9 Mon Sep 17 00:00:00 2001 From: Donghyun Cho Date: Tue, 23 Feb 2016 16:30:07 +0900 Subject: [PATCH] MediaSession: Add a way to get a calling package Introduced a new method, MediaSession#getCallingPackage(), which returns the name of the package that sent the last media button, transport control, or command from controllers and the system. Bug: 25208121 Change-Id: I90bc1fe3e5e432f6c95b4adfbef6ea6cea9244ff --- .../java/android/media/session/ISession.aidl | 2 + .../android/media/session/MediaSession.java | 16 +++++ .../server/media/MediaSessionRecord.java | 64 ++++++++++++++++++- .../server/media/MediaSessionService.java | 3 +- 4 files changed, 82 insertions(+), 3 deletions(-) diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl index bd0019f0f1d84..3affee5c0aa79 100644 --- a/media/java/android/media/session/ISession.aidl +++ b/media/java/android/media/session/ISession.aidl @@ -50,4 +50,6 @@ interface ISession { void setPlaybackToLocal(in AudioAttributes attributes); void setPlaybackToRemote(int control, int max); void setCurrentVolume(int currentVolume); + + String getCallingPackage(); } diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index 3b1b6c86ffcb0..9073077721fa5 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -512,6 +512,22 @@ public final class MediaSession { } } + /** + * Returns the name of the package that sent the last media button, transport control, or + * command from controllers and the system. This is only valid while in a request callback, such + * as {@link Callback#onPlay}. + * + * @hide + */ + public String getCallingPackage() { + try { + return mBinder.getCallingPackage(); + } catch (RemoteException e) { + Log.wtf(TAG, "Dead object in getCallingPackage.", e); + } + return null; + } + private void dispatchPrepare() { postToCallback(CallbackMessageHandler.MSG_PREPARE); } diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 862c061c6b9c5..29c54e9bf78ce 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -77,6 +77,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { */ private static final int OPTIMISTIC_VOLUME_TIMEOUT = 1000; + private static final int UID_NOT_SET = -1; + private final MessageHandler mHandler; private final int mOwnerPid; @@ -122,6 +124,9 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { private boolean mIsActive = false; private boolean mDestroyed = false; + private int mCallingUid = UID_NOT_SET; + private String mCallingPackage; + public MediaSessionRecord(int ownerPid, int ownerUid, int userId, String ownerPackageName, ISessionCallback cb, String tag, MediaSessionService service, Handler handler) { mOwnerPid = ownerPid; @@ -419,7 +424,9 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { return mSessionCb.mCb; } - public void sendMediaButton(KeyEvent ke, int sequenceId, ResultReceiver cb) { + public void sendMediaButton(KeyEvent ke, int sequenceId, + ResultReceiver cb, int uid, String packageName) { + updateCallingPackage(uid, packageName); mSessionCb.sendMediaButton(ke, sequenceId, cb); } @@ -680,6 +687,33 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { return -1; } + private void updateCallingPackage() { + updateCallingPackage(UID_NOT_SET, null); + } + + private void updateCallingPackage(int uid, String packageName) { + if (uid == UID_NOT_SET) { + uid = Binder.getCallingUid(); + } + synchronized (mLock) { + if (mCallingUid == UID_NOT_SET || mCallingUid != uid) { + mCallingUid = uid; + mCallingPackage = packageName; + if (mCallingPackage != null) { + return; + } + Context context = mService.getContext(); + if (context == null) { + return; + } + String[] packages = context.getPackageManager().getPackagesForUid(uid); + if (packages != null && packages.length > 0) { + mCallingPackage = packages[0]; + } + } + } + } + private final Runnable mClearOptimisticVolumeRunnable = new Runnable() { @Override public void run() { @@ -831,6 +865,11 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { mHandler.post(MessageHandler.MSG_UPDATE_VOLUME); } } + + @Override + public String getCallingPackage() { + return mCallingPackage; + } } class SessionCb { @@ -1025,11 +1064,13 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public void sendCommand(String command, Bundle args, ResultReceiver cb) throws RemoteException { + updateCallingPackage(); mSessionCb.sendCommand(command, args, cb); } @Override public boolean sendMediaButton(KeyEvent mediaButtonIntent) { + updateCallingPackage(); return mSessionCb.sendMediaButton(mediaButtonIntent, 0, null); } @@ -1111,6 +1152,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public void adjustVolume(int direction, int flags, String packageName) { + updateCallingPackage(); int uid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { @@ -1122,6 +1164,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public void setVolumeTo(int value, int flags, String packageName) { + updateCallingPackage(); int uid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { @@ -1133,94 +1176,111 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public void prepare() throws RemoteException { + updateCallingPackage(); mSessionCb.prepare(); } @Override public void prepareFromMediaId(String mediaId, Bundle extras) throws RemoteException { + updateCallingPackage(); mSessionCb.prepareFromMediaId(mediaId, extras); } @Override public void prepareFromSearch(String query, Bundle extras) throws RemoteException { + updateCallingPackage(); mSessionCb.prepareFromSearch(query, extras); } @Override public void prepareFromUri(Uri uri, Bundle extras) throws RemoteException { + updateCallingPackage(); mSessionCb.prepareFromUri(uri, extras); } @Override public void play() throws RemoteException { + updateCallingPackage(); mSessionCb.play(); } @Override public void playFromMediaId(String mediaId, Bundle extras) throws RemoteException { + updateCallingPackage(); mSessionCb.playFromMediaId(mediaId, extras); } @Override public void playFromSearch(String query, Bundle extras) throws RemoteException { + updateCallingPackage(); mSessionCb.playFromSearch(query, extras); } @Override public void playFromUri(Uri uri, Bundle extras) throws RemoteException { + updateCallingPackage(); mSessionCb.playFromUri(uri, extras); } @Override public void skipToQueueItem(long id) { + updateCallingPackage(); mSessionCb.skipToTrack(id); } - @Override public void pause() throws RemoteException { + updateCallingPackage(); mSessionCb.pause(); } @Override public void stop() throws RemoteException { + updateCallingPackage(); mSessionCb.stop(); } @Override public void next() throws RemoteException { + updateCallingPackage(); mSessionCb.next(); } @Override public void previous() throws RemoteException { + updateCallingPackage(); mSessionCb.previous(); } @Override public void fastForward() throws RemoteException { + updateCallingPackage(); mSessionCb.fastForward(); } @Override public void rewind() throws RemoteException { + updateCallingPackage(); mSessionCb.rewind(); } @Override public void seekTo(long pos) throws RemoteException { + updateCallingPackage(); mSessionCb.seekTo(pos); } @Override public void rate(Rating rating) throws RemoteException { + updateCallingPackage(); mSessionCb.rate(rating); } @Override public void sendCustomAction(String action, Bundle args) throws RemoteException { + updateCallingPackage(); mSessionCb.sendCustomAction(action, args); } diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 745f4763c1ea4..e3c540a54eb27 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -946,7 +946,8 @@ public class MediaSessionService extends SystemService implements Monitor { // won't release it later session.sendMediaButton(keyEvent, needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1, - mKeyEventReceiver); + mKeyEventReceiver, getContext().getApplicationInfo().uid, + getContext().getPackageName()); } else { // Launch the last PendingIntent we had with priority UserRecord user = mUserRecords.get(mCurrentUserId);