Loading media/java/android/service/media/MediaBrowserService.java +85 −41 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; Loading Loading @@ -112,21 +113,34 @@ public abstract class MediaBrowserService extends Service { /** * All the info about a connection. */ private class ConnectionRecord implements IBinder.DeathRecipient { String pkg; int uid; int pid; Bundle rootHints; IMediaBrowserServiceCallbacks callbacks; BrowserRoot root; HashMap<String, List<Pair<IBinder, Bundle>>> subscriptions = new HashMap<>(); private static class ConnectionRecord implements IBinder.DeathRecipient { public final MediaBrowserService service; public final String pkg; public final int pid; public final int uid; public final Bundle rootHints; public final IMediaBrowserServiceCallbacks callbacks; public final BrowserRoot root; public final HashMap<String, List<Pair<IBinder, Bundle>>> subscriptions = new HashMap<>(); ConnectionRecord( MediaBrowserService service, String pkg, int pid, int uid, Bundle rootHints, IMediaBrowserServiceCallbacks callbacks, BrowserRoot root) { this.service = service; this.pkg = pkg; this.pid = pid; this.uid = uid; this.rootHints = rootHints; this.callbacks = callbacks; this.root = root; } @Override public void binderDied() { mHandler.post(new Runnable() { service.mHandler.post(new Runnable() { @Override public void run() { mConnections.remove(callbacks.asBinder()); service.mConnections.remove(callbacks.asBinder()); } }); } Loading Loading @@ -199,39 +213,46 @@ public abstract class MediaBrowserService extends Service { } } private class ServiceBinder extends IMediaBrowserService.Stub { private static class ServiceBinder extends IMediaBrowserService.Stub { private WeakReference<MediaBrowserService> mService; private ServiceBinder(MediaBrowserService service) { mService = new WeakReference(service); } @Override public void connect(final String pkg, final Bundle rootHints, final IMediaBrowserServiceCallbacks callbacks) { MediaBrowserService service = mService.get(); if (service == null) { return; } final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); if (!isValidPackage(pkg, uid)) { if (!service.isValidPackage(pkg, uid)) { throw new IllegalArgumentException("Package/uid mismatch: uid=" + uid + " package=" + pkg); } mHandler.post(new Runnable() { service.mHandler.post(new Runnable() { @Override public void run() { final IBinder b = callbacks.asBinder(); // Clear out the old subscriptions. We are getting new ones. mConnections.remove(b); final ConnectionRecord connection = new ConnectionRecord(); connection.pkg = pkg; connection.pid = pid; connection.uid = uid; connection.rootHints = rootHints; connection.callbacks = callbacks; service.mConnections.remove(b); mCurConnection = connection; connection.root = MediaBrowserService.this.onGetRoot(pkg, uid, rootHints); mCurConnection = null; // Temporarily sets a placeholder ConnectionRecord to make // getCurrentBrowserInfo() work in onGetRoot(). service.mCurConnection = new ConnectionRecord( service, pkg, pid, uid, rootHints, callbacks, null); BrowserRoot root = service.onGetRoot(pkg, uid, rootHints); service.mCurConnection = null; // If they didn't return something, don't allow this client. if (connection.root == null) { if (root == null) { Log.i(TAG, "No root for client " + pkg + " from service " + getClass().getName()); try { Loading @@ -242,16 +263,19 @@ public abstract class MediaBrowserService extends Service { } } else { try { mConnections.put(b, connection); ConnectionRecord connection = new ConnectionRecord( service, pkg, pid, uid, rootHints, callbacks, root); service.mConnections.put(b, connection); b.linkToDeath(connection, 0); if (mSession != null) { if (service.mSession != null) { callbacks.onConnect(connection.root.getRootId(), mSession, connection.root.getExtras()); service.mSession, connection.root.getExtras()); } } catch (RemoteException ex) { Log.w(TAG, "Calling onConnect() failed. Dropping client. " + "pkg=" + pkg); mConnections.remove(b); service.mConnections.remove(b); } } } Loading @@ -260,13 +284,18 @@ public abstract class MediaBrowserService extends Service { @Override public void disconnect(final IMediaBrowserServiceCallbacks callbacks) { mHandler.post(new Runnable() { MediaBrowserService service = mService.get(); if (service == null) { return; } service.mHandler.post(new Runnable() { @Override public void run() { final IBinder b = callbacks.asBinder(); // Clear out the old subscriptions. We are getting new ones. final ConnectionRecord old = mConnections.remove(b); final ConnectionRecord old = service.mConnections.remove(b); if (old != null) { // TODO old.callbacks.asBinder().unlinkToDeath(old, 0); Loading @@ -283,20 +312,25 @@ public abstract class MediaBrowserService extends Service { @Override public void addSubscription(final String id, final IBinder token, final Bundle options, final IMediaBrowserServiceCallbacks callbacks) { mHandler.post(new Runnable() { MediaBrowserService service = mService.get(); if (service == null) { return; } service.mHandler.post(new Runnable() { @Override public void run() { final IBinder b = callbacks.asBinder(); // Get the record for the connection final ConnectionRecord connection = mConnections.get(b); final ConnectionRecord connection = service.mConnections.get(b); if (connection == null) { Log.w(TAG, "addSubscription for callback that isn't registered id=" + id); return; } MediaBrowserService.this.addSubscription(id, connection, token, options); service.addSubscription(id, connection, token, options); } }); } Loading @@ -310,18 +344,23 @@ public abstract class MediaBrowserService extends Service { @Override public void removeSubscription(final String id, final IBinder token, final IMediaBrowserServiceCallbacks callbacks) { mHandler.post(new Runnable() { MediaBrowserService service = mService.get(); if (service == null) { return; } service.mHandler.post(new Runnable() { @Override public void run() { final IBinder b = callbacks.asBinder(); ConnectionRecord connection = mConnections.get(b); ConnectionRecord connection = service.mConnections.get(b); if (connection == null) { Log.w(TAG, "removeSubscription for callback that isn't registered id=" + id); return; } if (!MediaBrowserService.this.removeSubscription(id, connection, token)) { if (!service.removeSubscription(id, connection, token)) { Log.w(TAG, "removeSubscription called for " + id + " which is not subscribed"); } Loading @@ -332,16 +371,21 @@ public abstract class MediaBrowserService extends Service { @Override public void getMediaItem(final String mediaId, final ResultReceiver receiver, final IMediaBrowserServiceCallbacks callbacks) { mHandler.post(new Runnable() { MediaBrowserService service = mService.get(); if (service == null) { return; } service.mHandler.post(new Runnable() { @Override public void run() { final IBinder b = callbacks.asBinder(); ConnectionRecord connection = mConnections.get(b); ConnectionRecord connection = service.mConnections.get(b); if (connection == null) { Log.w(TAG, "getMediaItem for callback that isn't registered id=" + mediaId); return; } performLoadItem(mediaId, connection, receiver); service.performLoadItem(mediaId, connection, receiver); } }); } Loading @@ -350,7 +394,7 @@ public abstract class MediaBrowserService extends Service { @Override public void onCreate() { super.onCreate(); mBinder = new ServiceBinder(); mBinder = new ServiceBinder(this); } @Override Loading Loading
media/java/android/service/media/MediaBrowserService.java +85 −41 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; Loading Loading @@ -112,21 +113,34 @@ public abstract class MediaBrowserService extends Service { /** * All the info about a connection. */ private class ConnectionRecord implements IBinder.DeathRecipient { String pkg; int uid; int pid; Bundle rootHints; IMediaBrowserServiceCallbacks callbacks; BrowserRoot root; HashMap<String, List<Pair<IBinder, Bundle>>> subscriptions = new HashMap<>(); private static class ConnectionRecord implements IBinder.DeathRecipient { public final MediaBrowserService service; public final String pkg; public final int pid; public final int uid; public final Bundle rootHints; public final IMediaBrowserServiceCallbacks callbacks; public final BrowserRoot root; public final HashMap<String, List<Pair<IBinder, Bundle>>> subscriptions = new HashMap<>(); ConnectionRecord( MediaBrowserService service, String pkg, int pid, int uid, Bundle rootHints, IMediaBrowserServiceCallbacks callbacks, BrowserRoot root) { this.service = service; this.pkg = pkg; this.pid = pid; this.uid = uid; this.rootHints = rootHints; this.callbacks = callbacks; this.root = root; } @Override public void binderDied() { mHandler.post(new Runnable() { service.mHandler.post(new Runnable() { @Override public void run() { mConnections.remove(callbacks.asBinder()); service.mConnections.remove(callbacks.asBinder()); } }); } Loading Loading @@ -199,39 +213,46 @@ public abstract class MediaBrowserService extends Service { } } private class ServiceBinder extends IMediaBrowserService.Stub { private static class ServiceBinder extends IMediaBrowserService.Stub { private WeakReference<MediaBrowserService> mService; private ServiceBinder(MediaBrowserService service) { mService = new WeakReference(service); } @Override public void connect(final String pkg, final Bundle rootHints, final IMediaBrowserServiceCallbacks callbacks) { MediaBrowserService service = mService.get(); if (service == null) { return; } final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); if (!isValidPackage(pkg, uid)) { if (!service.isValidPackage(pkg, uid)) { throw new IllegalArgumentException("Package/uid mismatch: uid=" + uid + " package=" + pkg); } mHandler.post(new Runnable() { service.mHandler.post(new Runnable() { @Override public void run() { final IBinder b = callbacks.asBinder(); // Clear out the old subscriptions. We are getting new ones. mConnections.remove(b); final ConnectionRecord connection = new ConnectionRecord(); connection.pkg = pkg; connection.pid = pid; connection.uid = uid; connection.rootHints = rootHints; connection.callbacks = callbacks; service.mConnections.remove(b); mCurConnection = connection; connection.root = MediaBrowserService.this.onGetRoot(pkg, uid, rootHints); mCurConnection = null; // Temporarily sets a placeholder ConnectionRecord to make // getCurrentBrowserInfo() work in onGetRoot(). service.mCurConnection = new ConnectionRecord( service, pkg, pid, uid, rootHints, callbacks, null); BrowserRoot root = service.onGetRoot(pkg, uid, rootHints); service.mCurConnection = null; // If they didn't return something, don't allow this client. if (connection.root == null) { if (root == null) { Log.i(TAG, "No root for client " + pkg + " from service " + getClass().getName()); try { Loading @@ -242,16 +263,19 @@ public abstract class MediaBrowserService extends Service { } } else { try { mConnections.put(b, connection); ConnectionRecord connection = new ConnectionRecord( service, pkg, pid, uid, rootHints, callbacks, root); service.mConnections.put(b, connection); b.linkToDeath(connection, 0); if (mSession != null) { if (service.mSession != null) { callbacks.onConnect(connection.root.getRootId(), mSession, connection.root.getExtras()); service.mSession, connection.root.getExtras()); } } catch (RemoteException ex) { Log.w(TAG, "Calling onConnect() failed. Dropping client. " + "pkg=" + pkg); mConnections.remove(b); service.mConnections.remove(b); } } } Loading @@ -260,13 +284,18 @@ public abstract class MediaBrowserService extends Service { @Override public void disconnect(final IMediaBrowserServiceCallbacks callbacks) { mHandler.post(new Runnable() { MediaBrowserService service = mService.get(); if (service == null) { return; } service.mHandler.post(new Runnable() { @Override public void run() { final IBinder b = callbacks.asBinder(); // Clear out the old subscriptions. We are getting new ones. final ConnectionRecord old = mConnections.remove(b); final ConnectionRecord old = service.mConnections.remove(b); if (old != null) { // TODO old.callbacks.asBinder().unlinkToDeath(old, 0); Loading @@ -283,20 +312,25 @@ public abstract class MediaBrowserService extends Service { @Override public void addSubscription(final String id, final IBinder token, final Bundle options, final IMediaBrowserServiceCallbacks callbacks) { mHandler.post(new Runnable() { MediaBrowserService service = mService.get(); if (service == null) { return; } service.mHandler.post(new Runnable() { @Override public void run() { final IBinder b = callbacks.asBinder(); // Get the record for the connection final ConnectionRecord connection = mConnections.get(b); final ConnectionRecord connection = service.mConnections.get(b); if (connection == null) { Log.w(TAG, "addSubscription for callback that isn't registered id=" + id); return; } MediaBrowserService.this.addSubscription(id, connection, token, options); service.addSubscription(id, connection, token, options); } }); } Loading @@ -310,18 +344,23 @@ public abstract class MediaBrowserService extends Service { @Override public void removeSubscription(final String id, final IBinder token, final IMediaBrowserServiceCallbacks callbacks) { mHandler.post(new Runnable() { MediaBrowserService service = mService.get(); if (service == null) { return; } service.mHandler.post(new Runnable() { @Override public void run() { final IBinder b = callbacks.asBinder(); ConnectionRecord connection = mConnections.get(b); ConnectionRecord connection = service.mConnections.get(b); if (connection == null) { Log.w(TAG, "removeSubscription for callback that isn't registered id=" + id); return; } if (!MediaBrowserService.this.removeSubscription(id, connection, token)) { if (!service.removeSubscription(id, connection, token)) { Log.w(TAG, "removeSubscription called for " + id + " which is not subscribed"); } Loading @@ -332,16 +371,21 @@ public abstract class MediaBrowserService extends Service { @Override public void getMediaItem(final String mediaId, final ResultReceiver receiver, final IMediaBrowserServiceCallbacks callbacks) { mHandler.post(new Runnable() { MediaBrowserService service = mService.get(); if (service == null) { return; } service.mHandler.post(new Runnable() { @Override public void run() { final IBinder b = callbacks.asBinder(); ConnectionRecord connection = mConnections.get(b); ConnectionRecord connection = service.mConnections.get(b); if (connection == null) { Log.w(TAG, "getMediaItem for callback that isn't registered id=" + mediaId); return; } performLoadItem(mediaId, connection, receiver); service.performLoadItem(mediaId, connection, receiver); } }); } Loading @@ -350,7 +394,7 @@ public abstract class MediaBrowserService extends Service { @Override public void onCreate() { super.onCreate(); mBinder = new ServiceBinder(); mBinder = new ServiceBinder(this); } @Override Loading