DO NOT MERGE) MediaBrowserCompat: Fix for sending messages to a remote process
- In order to send an object via Message.obj from a process to
a different process, the type of the object should be parcelable.
- When using Messenger, Binder.getCallingUid() in handleMessage does
not return the uid of the calling process.
Bug: 26609825
Change-Id: I1f9ad5b46e8e174600eb432bf91e7541900b6283
diff --git a/v4/java/android/support/v4/media/MediaBrowserCompat.java b/v4/java/android/support/v4/media/MediaBrowserCompat.java
index f60d596..c6bad63 100644
--- a/v4/java/android/support/v4/media/MediaBrowserCompat.java
+++ b/v4/java/android/support/v4/media/MediaBrowserCompat.java
@@ -916,34 +916,40 @@
}
void connect() throws RemoteException {
- sendRequest(CLIENT_MSG_CONNECT, mContext.getPackageName(), mRootHints,
- mCallbacksMessenger);
+ Bundle data = new Bundle();
+ data.putString(DATA_PACKAGE_NAME, mContext.getPackageName());
+ data.putBundle(DATA_ROOT_HINTS, mRootHints);
+ sendRequest(CLIENT_MSG_CONNECT, data, mCallbacksMessenger);
}
void disconnect() throws RemoteException {
- sendRequest(CLIENT_MSG_DISCONNECT, null, null, mCallbacksMessenger);
+ sendRequest(CLIENT_MSG_DISCONNECT, null, mCallbacksMessenger);
}
void addSubscription(String parentId) throws RemoteException {
- sendRequest(CLIENT_MSG_ADD_SUBSCRIPTION, parentId, null, mCallbacksMessenger);
+ Bundle data = new Bundle();
+ data.putString(DATA_MEDIA_ITEM_ID, parentId);
+ sendRequest(CLIENT_MSG_ADD_SUBSCRIPTION, data, mCallbacksMessenger);
}
void removeSubscription(String parentId) throws RemoteException {
- sendRequest(CLIENT_MSG_REMOVE_SUBSCRIPTION, parentId, null, mCallbacksMessenger);
+ Bundle data = new Bundle();
+ data.putString(DATA_MEDIA_ITEM_ID, parentId);
+ sendRequest(CLIENT_MSG_REMOVE_SUBSCRIPTION, data, mCallbacksMessenger);
}
void getMediaItem(String mediaId, ResultReceiver receiver) throws RemoteException {
Bundle data = new Bundle();
- data.putParcelable(SERVICE_DATA_RESULT_RECEIVER, receiver);
- sendRequest(CLIENT_MSG_GET_MEDIA_ITEM, mediaId, data, null);
+ data.putString(DATA_MEDIA_ITEM_ID, mediaId);
+ data.putParcelable(DATA_RESULT_RECEIVER, receiver);
+ sendRequest(CLIENT_MSG_GET_MEDIA_ITEM, data, null);
}
- private void sendRequest(int what, Object obj, Bundle data, Messenger cbMessenger)
+ private void sendRequest(int what, Bundle data, Messenger cbMessenger)
throws RemoteException {
Message msg = Message.obtain();
msg.what = what;
msg.arg1 = CLIENT_VERSION_CURRENT;
- msg.obj = obj;
msg.setData(data);
msg.replyTo = cbMessenger;
mMessenger.send(msg);
@@ -1062,17 +1068,17 @@
Bundle data = msg.getData();
switch (msg.what) {
case SERVICE_MSG_ON_CONNECT:
- onServiceConnected(mCallbacksMessenger, (String) msg.obj,
+ onServiceConnected(mCallbacksMessenger, data.getString(DATA_MEDIA_ITEM_ID),
(MediaSessionCompat.Token) data.getParcelable(
- SERVICE_DATA_MEDIA_SESSION_TOKEN),
- data.getBundle(SERVICE_DATA_EXTRAS));
+ DATA_MEDIA_SESSION_TOKEN),
+ data.getBundle(DATA_ROOT_HINTS));
break;
case SERVICE_MSG_ON_CONNECT_FAILED:
onConnectionFailed(mCallbacksMessenger);
break;
case SERVICE_MSG_ON_LOAD_CHILDREN:
- onLoadChildren(mCallbacksMessenger, (String) msg.obj,
- data.getParcelableArrayList(SERVICE_DATA_MEDIA_ITEM_LIST));
+ onLoadChildren(mCallbacksMessenger, data.getString(DATA_MEDIA_ITEM_ID),
+ data.getParcelableArrayList(DATA_MEDIA_ITEM_LIST));
break;
default:
Log.w(TAG, "Unhandled message: " + msg
@@ -1207,7 +1213,7 @@
};
try {
Bundle data = new Bundle();
- data.putParcelable(SERVICE_DATA_RESULT_RECEIVER, receiver);
+ data.putParcelable(DATA_RESULT_RECEIVER, receiver);
sendRequest(CLIENT_MSG_GET_MEDIA_ITEM, mediaId, data, null);
} catch (RemoteException e) {
Log.i(TAG, "Remote error getting media item.");
diff --git a/v4/java/android/support/v4/media/MediaBrowserProtocol.java b/v4/java/android/support/v4/media/MediaBrowserProtocol.java
index 7c8feb3..6410466 100644
--- a/v4/java/android/support/v4/media/MediaBrowserProtocol.java
+++ b/v4/java/android/support/v4/media/MediaBrowserProtocol.java
@@ -21,6 +21,17 @@
*/
class MediaBrowserProtocol {
+ public static final String DATA_CALLING_UID = "data_calling_uid";
+ public static final String DATA_ROOT_HINTS = "data_root_hints";
+ public static final String DATA_MEDIA_ITEM_ID = "data_media_item_id";
+ public static final String DATA_MEDIA_ITEM_LIST = "data_media_item_list";
+ public static final String DATA_MEDIA_SESSION_TOKEN = "data_media_session_token";
+ public static final String DATA_PACKAGE_NAME = "data_package_name";
+ public static final String DATA_RESULT_RECEIVER = "data_result_receiver";
+
+ public static final String EXTRA_SERVICE_VERSION = "extra_service_version";
+ public static final String EXTRA_MESSENGER_BINDER = "extra_messenger";
+
/**
* MediaBrowserCompat will check the version of the connected MediaBrowserServiceCompat,
* and it will not send messages if they are introduced in the higher version of the
@@ -39,10 +50,10 @@
* Sent after {@link MediaBrowserCompat#connect()} when the request has successfully
* completed.
* - arg1 : The service version
- * - obj : The root media item id
* - data
- * SERVICE_DATA_MEDIA_SESSION_TOKEN : Media session token
- * SERVICE_DATA_EXTRAS : An extras bundle which contains EXTRA_SERVICE_VERSION
+ * DATA_MEDIA_ITEM_ID : A string for the root media item id
+ * DATA_MEDIA_SESSION_TOKEN : Media session token
+ * DATA_ROOT_HINTS : An extras bundle which contains EXTRA_SERVICE_VERSION
*/
public static final int SERVICE_MSG_ON_CONNECT = 1;
@@ -56,20 +67,12 @@
/** (service v1)
* Sent when the list of children is loaded or updated.
* - arg1 : The service version
- * - obj : The parent media item id
* - data
- * SERVICE_DATA_MEDIA_ITEM_LIST : An array list for the media item children
+ * DATA_MEDIA_ITEM_ID : A string for the parent media item id
+ * DATA_MEDIA_ITEM_LIST : An array list for the media item children
*/
public static final int SERVICE_MSG_ON_LOAD_CHILDREN = 3;
- public static final String SERVICE_DATA_MEDIA_SESSION_TOKEN = "data_media_session_token";
- public static final String SERVICE_DATA_EXTRAS = "data_extras";
- public static final String SERVICE_DATA_MEDIA_ITEM_LIST = "data_media_item_list";
- public static final String SERVICE_DATA_RESULT_RECEIVER = "data_result_receiver";
-
- public static final String EXTRA_SERVICE_VERSION = "extra_service_version";
- public static final String EXTRA_MESSENGER_BINDER = "extra_messenger";
-
/**
* MediaBrowserServiceCompat will check the version of the MediaBrowserCompat, and it will not
* send messages if they are introduced in the higher version of the MediaBrowserCompat.
@@ -87,7 +90,9 @@
* Sent to connect to the media browse service compat.
* - arg1 : The client version
* - obj : The package name
- * - data : An optional root hints bundle of service-specific arguments
+ * - data
+ * DATA_PACKAGE_NAME : A string for the package name of MediaBrowserCompat
+ * DATA_ROOT_HINTS : An optional root hints bundle of service-specific arguments
* - replayTo : Client messenger
*/
public static final int CLIENT_MSG_CONNECT = 1;
@@ -102,7 +107,8 @@
/** (client v1)
* Sent to subscribe for changes to the children of the specified media id.
* - arg1 : The client version
- * - obj : The media item id
+ * - data
+ * DATA_MEDIA_ITEM_ID : A string for a media item id
* - replayTo : Client messenger
*/
public static final int CLIENT_MSG_ADD_SUBSCRIPTION = 3;
@@ -110,7 +116,8 @@
/** (client v1)
* Sent to unsubscribe for changes to the children of the specified media id.
* - arg1 : The client version
- * - obj : The media item id
+ * - data
+ * DATA_MEDIA_ITEM_ID : A string for a media item id
* - replayTo : Client messenger
*/
public static final int CLIENT_MSG_REMOVE_SUBSCRIPTION = 4;
@@ -118,9 +125,9 @@
/** (client v1)
* Sent to retrieves a specific media item from the connected service.
* - arg1 : The client version
- * - obj : The media item id
* - data
- * SERVICE_DATA_RESULT_RECEIVER : Result receiver to get the result
+ * DATA_MEDIA_ITEM_ID : A string for a media item id
+ * DATA_RESULT_RECEIVER : Result receiver to get the result
*/
public static final int CLIENT_MSG_GET_MEDIA_ITEM = 5;
}
diff --git a/v4/java/android/support/v4/media/MediaBrowserServiceCompat.java b/v4/java/android/support/v4/media/MediaBrowserServiceCompat.java
index 90a361e..587329d 100644
--- a/v4/java/android/support/v4/media/MediaBrowserServiceCompat.java
+++ b/v4/java/android/support/v4/media/MediaBrowserServiceCompat.java
@@ -145,25 +145,27 @@
@Override
public void handleMessage(Message msg) {
+ Bundle data = msg.getData();
switch (msg.what) {
case CLIENT_MSG_CONNECT:
- mServiceImpl.connect((String) msg.obj, msg.getData(),
+ mServiceImpl.connect(data.getString(DATA_PACKAGE_NAME),
+ data.getInt(DATA_CALLING_UID), data.getBundle(DATA_ROOT_HINTS),
new ServiceCallbacksCompat(msg.replyTo));
break;
case CLIENT_MSG_DISCONNECT:
mServiceImpl.disconnect(new ServiceCallbacksCompat(msg.replyTo));
break;
case CLIENT_MSG_ADD_SUBSCRIPTION:
- mServiceImpl.addSubscription((String) msg.obj,
+ mServiceImpl.addSubscription(data.getString(DATA_MEDIA_ITEM_ID),
new ServiceCallbacksCompat(msg.replyTo));
break;
case CLIENT_MSG_REMOVE_SUBSCRIPTION:
- mServiceImpl.removeSubscription((String) msg.obj,
+ mServiceImpl.removeSubscription(data.getString(DATA_MEDIA_ITEM_ID),
new ServiceCallbacksCompat(msg.replyTo));
break;
case CLIENT_MSG_GET_MEDIA_ITEM:
- mServiceImpl.getMediaItem((String) msg.obj, (ResultReceiver) msg.getData()
- .getParcelable(SERVICE_DATA_RESULT_RECEIVER));
+ mServiceImpl.getMediaItem(data.getString(DATA_MEDIA_ITEM_ID),
+ (ResultReceiver) data.getParcelable(DATA_RESULT_RECEIVER));
break;
default:
Log.w(TAG, "Unhandled message: " + msg
@@ -172,6 +174,15 @@
}
}
+ @Override
+ public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+ // Binder.getCallingUid() in handleMessage will return the uid of this process.
+ // In order to get the right calling uid, Binder.getCallingUid() should be called here.
+ Bundle data = msg.getData();
+ data.putInt(DATA_CALLING_UID, Binder.getCallingUid());
+ return super.sendMessageAtTime(msg, uptimeMillis);
+ }
+
public void postOrRun(Runnable r) {
if (Thread.currentThread() == getLooper().getThread()) {
r.run();
@@ -258,10 +269,9 @@
}
private class ServiceImpl {
- public void connect(final String pkg, final Bundle rootHints,
+ public void connect(final String pkg, final int uid, final Bundle rootHints,
final ServiceCallbacks callbacks) {
- final int uid = Binder.getCallingUid();
if (!isValidPackage(pkg, uid)) {
throw new IllegalArgumentException("Package/uid mismatch: uid=" + uid
+ " package=" + pkg);
@@ -389,7 +399,8 @@
@Override
public void connect(final String pkg, final Bundle rootHints,
final MediaBrowserServiceCompatApi21.ServiceCallbacks callbacks) {
- mServiceImpl.connect(pkg, rootHints, new ServiceCallbacksApi21(callbacks));
+ mServiceImpl.connect(pkg, Binder.getCallingUid(), rootHints,
+ new ServiceCallbacksApi21(callbacks));
}
@Override
@@ -459,32 +470,31 @@
}
extras.putInt(EXTRA_SERVICE_VERSION, SERVICE_VERSION_CURRENT);
Bundle data = new Bundle();
- data.putParcelable(SERVICE_DATA_MEDIA_SESSION_TOKEN, session);
- data.putBundle(SERVICE_DATA_EXTRAS, extras);
- sendRequest(SERVICE_MSG_ON_CONNECT, root, data);
+ data.putString(DATA_MEDIA_ITEM_ID, root);
+ data.putParcelable(DATA_MEDIA_SESSION_TOKEN, session);
+ data.putBundle(DATA_ROOT_HINTS, extras);
+ sendRequest(SERVICE_MSG_ON_CONNECT, data);
}
public void onConnectFailed() throws RemoteException {
- sendRequest(SERVICE_MSG_ON_CONNECT_FAILED, null, null);
+ sendRequest(SERVICE_MSG_ON_CONNECT_FAILED, null);
}
public void onLoadChildren(String mediaId, List<MediaBrowserCompat.MediaItem> list)
throws RemoteException {
- Bundle data = null;
+ Bundle data = new Bundle();
+ data.putString(DATA_MEDIA_ITEM_ID, mediaId);
if (list != null) {
- data = new Bundle();
- data.putParcelableArrayList(SERVICE_DATA_MEDIA_ITEM_LIST,
+ data.putParcelableArrayList(DATA_MEDIA_ITEM_LIST,
list instanceof ArrayList ? (ArrayList) list : new ArrayList<>(list));
}
- sendRequest(SERVICE_MSG_ON_LOAD_CHILDREN, mediaId, data);
+ sendRequest(SERVICE_MSG_ON_LOAD_CHILDREN, data);
}
- private void sendRequest(int what, Object obj, Bundle data)
- throws RemoteException {
+ private void sendRequest(int what, Bundle data) throws RemoteException {
Message msg = Message.obtain();
msg.what = what;
msg.arg1 = SERVICE_VERSION_CURRENT;
- msg.obj = obj;
msg.setData(data);
mCallbacks.send(msg);
}