diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/java/android/media/AudioManager.java | 62 | ||||
-rw-r--r-- | media/java/android/media/AudioService.java | 160 | ||||
-rw-r--r-- | media/java/android/media/IAudioService.aidl | 12 | ||||
-rw-r--r-- | media/java/android/media/IRemoteControlDisplay.aidl | 9 | ||||
-rw-r--r-- | media/java/android/media/RemoteControlClient.java | 62 |
5 files changed, 166 insertions, 139 deletions
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index cd8bb1d..a0881a7 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -18,8 +18,10 @@ package android.media; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; +import android.content.Intent; import android.database.ContentObserver; import android.graphics.Bitmap; import android.os.Binder; @@ -1684,17 +1686,42 @@ public class AudioManager { * Register a component to be the sole receiver of MEDIA_BUTTON intents. * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver} * that will receive the media button intent. This broadcast receiver must be declared - * in the application manifest. + * in the application manifest. The package of the component must match that of + * the context you're registering from. */ public void registerMediaButtonEventReceiver(ComponentName eventReceiver) { if (eventReceiver == null) { return; } + if (!eventReceiver.getPackageName().equals(mContext.getPackageName())) { + Log.e(TAG, "registerMediaButtonEventReceiver() error: " + + "receiver and context package names don't match"); + return; + } + // construct a PendingIntent for the media button and register it + Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); + // the associated intent will be handled by the component being registered + mediaButtonIntent.setComponent(eventReceiver); + PendingIntent pi = PendingIntent.getBroadcast(mContext, + 0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/); + registerMediaButtonIntent(pi, eventReceiver); + } + + /** + * @hide + * no-op if (pi == null) or (eventReceiver == null) + */ + public void registerMediaButtonIntent(PendingIntent pi, ComponentName eventReceiver) { + if ((pi == null) || (eventReceiver == null)) { + Log.e(TAG, "Cannot call registerMediaButtonIntent() with a null parameter"); + return; + } IAudioService service = getService(); try { - service.registerMediaButtonEventReceiver(eventReceiver); + // pi != null + service.registerMediaButtonIntent(pi, eventReceiver); } catch (RemoteException e) { - Log.e(TAG, "Dead object in registerMediaButtonEventReceiver"+e); + Log.e(TAG, "Dead object in registerMediaButtonIntent"+e); } } @@ -1707,15 +1734,27 @@ public class AudioManager { if (eventReceiver == null) { return; } + // construct a PendingIntent for the media button and unregister it + Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); + // the associated intent will be handled by the component being registered + mediaButtonIntent.setComponent(eventReceiver); + PendingIntent pi = PendingIntent.getBroadcast(mContext, + 0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/); + unregisterMediaButtonIntent(pi, eventReceiver); + } + + /** + * @hide + */ + public void unregisterMediaButtonIntent(PendingIntent pi, ComponentName eventReceiver) { IAudioService service = getService(); try { - service.unregisterMediaButtonEventReceiver(eventReceiver); + service.unregisterMediaButtonIntent(pi, eventReceiver); } catch (RemoteException e) { - Log.e(TAG, "Dead object in unregisterMediaButtonEventReceiver"+e); + Log.e(TAG, "Dead object in unregisterMediaButtonIntent"+e); } } - /** * Registers the remote control client for providing information to display on the remote * controls. @@ -1724,14 +1763,13 @@ public class AudioManager { * @see RemoteControlClient */ public void registerRemoteControlClient(RemoteControlClient rcClient) { - if ((rcClient == null) || (rcClient.getRcEventReceiver() == null)) { + if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) { return; } IAudioService service = getService(); try { - service.registerRemoteControlClient(rcClient.getRcEventReceiver(), /* eventReceiver */ + service.registerRemoteControlClient(rcClient.getRcMediaIntent(), /* mediaIntent */ rcClient.getIRemoteControlClient(), /* rcClient */ - rcClient.toString(), /* clientName */ // used to match media button event receiver and audio focus mContext.getPackageName()); /* packageName */ } catch (RemoteException e) { @@ -1746,13 +1784,13 @@ public class AudioManager { * @see #registerRemoteControlClient(RemoteControlClient) */ public void unregisterRemoteControlClient(RemoteControlClient rcClient) { - if ((rcClient == null) || (rcClient.getRcEventReceiver() == null)) { + if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) { return; } IAudioService service = getService(); try { - service.unregisterRemoteControlClient(rcClient.getRcEventReceiver(), /* eventReceiver */ - rcClient.getIRemoteControlClient()); /* rcClient */ + service.unregisterRemoteControlClient(rcClient.getRcMediaIntent(), /* mediaIntent */ + rcClient.getIRemoteControlClient()); /* rcClient */ } catch (RemoteException e) { Log.e(TAG, "Dead object in unregisterRemoteControlClient"+e); } diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index db27cfd..8895c9e 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -18,6 +18,8 @@ package android.media; import android.app.ActivityManagerNative; import android.app.KeyguardManager; +import android.app.PendingIntent; +import android.app.PendingIntent.CanceledException; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothClass; @@ -35,6 +37,7 @@ import android.database.ContentObserver; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnErrorListener; import android.os.Binder; +import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.IBinder; @@ -2084,7 +2087,7 @@ public class AudioService extends IAudioService.Stub { } } - private void persistMediaButtonReceiver(ComponentName receiver) { + private void onHandlePersistMediaButtonReceiver(ComponentName receiver) { Settings.System.putString(mContentResolver, Settings.System.MEDIA_BUTTON_RECEIVER, receiver == null ? "" : receiver.flattenToString()); } @@ -2201,7 +2204,7 @@ public class AudioService extends IAudioService.Stub { break; case MSG_PERSIST_MEDIABUTTONRECEIVER: - persistMediaButtonReceiver( (ComponentName) msg.obj ); + onHandlePersistMediaButtonReceiver( (ComponentName) msg.obj ); break; case MSG_RCDISPLAY_CLEAR: @@ -2894,14 +2897,22 @@ public class AudioService extends IAudioService.Stub { } synchronized(mRCStack) { if (!mRCStack.empty()) { - // create a new intent specifically aimed at the current registered listener + // create a new intent to fill in the extras of the registered PendingIntent Intent targetedIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); - targetedIntent.putExtras(intent.getExtras()); - targetedIntent.setComponent(mRCStack.peek().mReceiverComponent); - // trap the current broadcast - abortBroadcast(); - //Log.v(TAG, " Sending intent" + targetedIntent); - context.sendBroadcast(targetedIntent, null); + Bundle extras = intent.getExtras(); + if (extras != null) { + targetedIntent.putExtras(extras); + // trap the current broadcast + abortBroadcast(); + //Log.v(TAG, " Sending intent" + targetedIntent); + // send the intent that was registered by the client + try { + mRCStack.peek().mMediaIntent.send(context, 0, targetedIntent); + } catch (CanceledException e) { + Log.e(TAG, "Error sending pending intent " + mRCStack.peek()); + e.printStackTrace(); + } + } } } } @@ -2936,18 +2947,18 @@ public class AudioService extends IAudioService.Stub { */ private class RcClientDeathHandler implements IBinder.DeathRecipient { private IBinder mCb; // To be notified of client's death - private ComponentName mRcEventReceiver; + private PendingIntent mMediaIntent; - RcClientDeathHandler(IBinder cb, ComponentName eventReceiver) { + RcClientDeathHandler(IBinder cb, PendingIntent pi) { mCb = cb; - mRcEventReceiver = eventReceiver; + mMediaIntent = pi; } public void binderDied() { Log.w(TAG, " RemoteControlClient died"); // remote control client died, make sure the displays don't use it anymore // by setting its remote control client to null - registerRemoteControlClient(mRcEventReceiver, null, null, null/*ignored*/); + registerRemoteControlClient(mMediaIntent, null, null/*ignored*/); } public IBinder getBinder() { @@ -2956,18 +2967,29 @@ public class AudioService extends IAudioService.Stub { } private static class RemoteControlStackEntry { - /** the target for the ACTION_MEDIA_BUTTON events */ - public ComponentName mReceiverComponent;// always non null + /** + * The target for the ACTION_MEDIA_BUTTON events. + * Always non null. + */ + public PendingIntent mMediaIntent; + /** + * The registered media button event receiver. + * Always non null. + */ + public ComponentName mReceiverComponent; public String mCallingPackageName; - public String mRcClientName; public int mCallingUid; - - /** provides access to the information to display on the remote control */ + /** + * Provides access to the information to display on the remote control. + * May be null (when a media button event receiver is registered, + * but no remote control client has been registered) */ public IRemoteControlClient mRcClient; public RcClientDeathHandler mRcClientDeathHandler; - public RemoteControlStackEntry(ComponentName r) { - mReceiverComponent = r; + /** precondition: mediaIntent != null, eventReceiver != null */ + public RemoteControlStackEntry(PendingIntent mediaIntent, ComponentName eventReceiver) { + mMediaIntent = mediaIntent; + mReceiverComponent = eventReceiver; mCallingUid = -1; mRcClient = null; } @@ -3003,7 +3025,8 @@ public class AudioService extends IAudioService.Stub { Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator(); while(stackIterator.hasNext()) { RemoteControlStackEntry rcse = stackIterator.next(); - pw.println(" receiver: " + rcse.mReceiverComponent + + pw.println(" pi: " + rcse.mMediaIntent + + " -- ercvr: " + rcse.mReceiverComponent + " -- client: " + rcse.mRcClient + " -- uid: " + rcse.mCallingUid); } @@ -3035,7 +3058,6 @@ public class AudioService extends IAudioService.Stub { mAudioHandler.sendMessage( mAudioHandler.obtainMessage(MSG_PERSIST_MEDIABUTTONRECEIVER, 0, 0, null)); - return; } else if (oldTop != mRCStack.peek()) { // the top of the stack has changed, save it in the system settings // by posting a message to persist it @@ -3049,25 +3071,32 @@ public class AudioService extends IAudioService.Stub { /** * Helper function: - * Restore remote control receiver from the system settings + * Restore remote control receiver from the system settings. */ private void restoreMediaButtonReceiver() { String receiverName = Settings.System.getString(mContentResolver, Settings.System.MEDIA_BUTTON_RECEIVER); if ((null != receiverName) && !receiverName.isEmpty()) { - ComponentName receiverComponentName = ComponentName.unflattenFromString(receiverName); - registerMediaButtonEventReceiver(receiverComponentName); + ComponentName eventReceiver = ComponentName.unflattenFromString(receiverName); + // construct a PendingIntent targeted to the restored component name + // for the media button and register it + Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); + // the associated intent will be handled by the component being registered + mediaButtonIntent.setComponent(eventReceiver); + PendingIntent pi = PendingIntent.getBroadcast(mContext, + 0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/); + registerMediaButtonIntent(pi, eventReceiver); } - // upon restoring (e.g. after boot), do we want to refresh all remotes? } /** * Helper function: - * Set the new remote control receiver at the top of the RC focus stack + * Set the new remote control receiver at the top of the RC focus stack. + * precondition: mediaIntent != null, target != null */ - private void pushMediaButtonReceiver(ComponentName newReceiver) { + private void pushMediaButtonReceiver(PendingIntent mediaIntent, ComponentName target) { // already at top of stack? - if (!mRCStack.empty() && mRCStack.peek().mReceiverComponent.equals(newReceiver)) { + if (!mRCStack.empty() && mRCStack.peek().mMediaIntent.equals(mediaIntent)) { return; } Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator(); @@ -3075,31 +3104,32 @@ public class AudioService extends IAudioService.Stub { boolean wasInsideStack = false; while(stackIterator.hasNext()) { rcse = (RemoteControlStackEntry)stackIterator.next(); - if(rcse.mReceiverComponent.equals(newReceiver)) { + if(rcse.mMediaIntent.equals(mediaIntent)) { wasInsideStack = true; stackIterator.remove(); break; } } if (!wasInsideStack) { - rcse = new RemoteControlStackEntry(newReceiver); + rcse = new RemoteControlStackEntry(mediaIntent, target); } mRCStack.push(rcse); // post message to persist the default media button receiver mAudioHandler.sendMessage( mAudioHandler.obtainMessage( - MSG_PERSIST_MEDIABUTTONRECEIVER, 0, 0, newReceiver/*obj*/) ); + MSG_PERSIST_MEDIABUTTONRECEIVER, 0, 0, target/*obj*/) ); } /** * Helper function: - * Remove the remote control receiver from the RC focus stack + * Remove the remote control receiver from the RC focus stack. + * precondition: pi != null */ - private void removeMediaButtonReceiver(ComponentName newReceiver) { + private void removeMediaButtonReceiver(PendingIntent pi) { Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator(); while(stackIterator.hasNext()) { RemoteControlStackEntry rcse = (RemoteControlStackEntry)stackIterator.next(); - if(rcse.mReceiverComponent.equals(newReceiver)) { + if(rcse.mMediaIntent.equals(pi)) { stackIterator.remove(); break; } @@ -3110,8 +3140,8 @@ public class AudioService extends IAudioService.Stub { * Helper function: * Called synchronized on mRCStack */ - private boolean isCurrentRcController(ComponentName eventReceiver) { - if (!mRCStack.empty() && mRCStack.peek().mReceiverComponent.equals(eventReceiver)) { + private boolean isCurrentRcController(PendingIntent pi) { + if (!mRCStack.empty() && mRCStack.peek().mMediaIntent.equals(pi)) { return true; } return false; @@ -3124,12 +3154,12 @@ public class AudioService extends IAudioService.Stub { * Update the remote control displays with the new "focused" client generation */ private void setNewRcClientOnDisplays_syncRcsCurrc(int newClientGeneration, - ComponentName newClientEventReceiver, boolean clearing) { + PendingIntent newMediaIntent, boolean clearing) { // NOTE: Only one IRemoteControlDisplay supported in this implementation if (mRcDisplay != null) { try { mRcDisplay.setCurrentClientId( - newClientGeneration, newClientEventReceiver, clearing); + newClientGeneration, newMediaIntent, clearing); } catch (RemoteException e) { Log.e(TAG, "Dead display in setNewRcClientOnDisplays_syncRcsCurrc() "+e); // if we had a display before, stop monitoring its death @@ -3167,10 +3197,9 @@ public class AudioService extends IAudioService.Stub { * where the display should be cleared. */ private void setNewRcClient_syncRcsCurrc(int newClientGeneration, - ComponentName newClientEventReceiver, boolean clearing) { + PendingIntent newMediaIntent, boolean clearing) { // send the new valid client generation ID to all displays - setNewRcClientOnDisplays_syncRcsCurrc(newClientGeneration, newClientEventReceiver, - clearing); + setNewRcClientOnDisplays_syncRcsCurrc(newClientGeneration, newMediaIntent, clearing); // send the new valid client generation ID to all clients setNewRcClientGenerationOnClients_syncRcsCurrc(newClientGeneration); } @@ -3186,7 +3215,7 @@ public class AudioService extends IAudioService.Stub { mCurrentRcClientGen++; // synchronously update the displays and clients with the new client generation setNewRcClient_syncRcsCurrc(mCurrentRcClientGen, - null /*event receiver*/, true /*clearing*/); + null /*newMediaIntent*/, true /*clearing*/); } } } @@ -3204,7 +3233,7 @@ public class AudioService extends IAudioService.Stub { // synchronously update the displays and clients with // the new client generation setNewRcClient_syncRcsCurrc(mCurrentRcClientGen, - rcse.mReceiverComponent /*event receiver*/, + rcse.mMediaIntent /*newMediaIntent*/, false /*clearing*/); // tell the current client that it needs to send info @@ -3301,27 +3330,34 @@ public class AudioService extends IAudioService.Stub { updateRemoteControlDisplay_syncAfRcs(infoChangedFlags); } - /** see AudioManager.registerMediaButtonEventReceiver(ComponentName eventReceiver) */ - public void registerMediaButtonEventReceiver(ComponentName eventReceiver) { - Log.i(TAG, " Remote Control registerMediaButtonEventReceiver() for " + eventReceiver); + /** + * see AudioManager.registerMediaButtonIntent(PendingIntent pi, ComponentName c) + * precondition: mediaIntent != null, target != null + */ + public void registerMediaButtonIntent(PendingIntent mediaIntent, ComponentName eventReceiver) { + Log.i(TAG, " Remote Control registerMediaButtonIntent() for " + mediaIntent); synchronized(mAudioFocusLock) { synchronized(mRCStack) { - pushMediaButtonReceiver(eventReceiver); + pushMediaButtonReceiver(mediaIntent, eventReceiver); // new RC client, assume every type of information shall be queried checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL); } } } - /** see AudioManager.unregisterMediaButtonEventReceiver(ComponentName eventReceiver) */ - public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver) { - Log.i(TAG, " Remote Control unregisterMediaButtonEventReceiver() for " + eventReceiver); + /** + * see AudioManager.unregisterMediaButtonIntent(PendingIntent mediaIntent) + * precondition: mediaIntent != null, eventReceiver != null + */ + public void unregisterMediaButtonIntent(PendingIntent mediaIntent, ComponentName eventReceiver) + { + Log.i(TAG, " Remote Control unregisterMediaButtonIntent() for " + mediaIntent); synchronized(mAudioFocusLock) { synchronized(mRCStack) { - boolean topOfStackWillChange = isCurrentRcController(eventReceiver); - removeMediaButtonReceiver(eventReceiver); + boolean topOfStackWillChange = isCurrentRcController(mediaIntent); + removeMediaButtonReceiver(mediaIntent); if (topOfStackWillChange) { // current RC client will change, assume every type of info needs to be queried checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL); @@ -3331,8 +3367,8 @@ public class AudioService extends IAudioService.Stub { } /** see AudioManager.registerRemoteControlClient(ComponentName eventReceiver, ...) */ - public void registerRemoteControlClient(ComponentName eventReceiver, - IRemoteControlClient rcClient, String clientName, String callingPackageName) { + public void registerRemoteControlClient(PendingIntent mediaIntent, + IRemoteControlClient rcClient, String callingPackageName) { if (DEBUG_RC) Log.i(TAG, "Register remote control client rcClient="+rcClient); synchronized(mAudioFocusLock) { synchronized(mRCStack) { @@ -3340,7 +3376,7 @@ public class AudioService extends IAudioService.Stub { Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator(); while(stackIterator.hasNext()) { RemoteControlStackEntry rcse = stackIterator.next(); - if(rcse.mReceiverComponent.equals(eventReceiver)) { + if(rcse.mMediaIntent.equals(mediaIntent)) { // already had a remote control client? if (rcse.mRcClientDeathHandler != null) { // stop monitoring the old client's death @@ -3357,7 +3393,6 @@ public class AudioService extends IAudioService.Stub { } } rcse.mCallingPackageName = callingPackageName; - rcse.mRcClientName = clientName; rcse.mCallingUid = Binder.getCallingUid(); if (rcClient == null) { rcse.mRcClientDeathHandler = null; @@ -3366,7 +3401,7 @@ public class AudioService extends IAudioService.Stub { // monitor the new client's death IBinder b = rcClient.asBinder(); RcClientDeathHandler rcdh = - new RcClientDeathHandler(b, rcse.mReceiverComponent); + new RcClientDeathHandler(b, rcse.mMediaIntent); try { b.linkToDeath(rcdh, 0); } catch (RemoteException e) { @@ -3380,7 +3415,7 @@ public class AudioService extends IAudioService.Stub { } // if the eventReceiver is at the top of the stack // then check for potential refresh of the remote controls - if (isCurrentRcController(eventReceiver)) { + if (isCurrentRcController(mediaIntent)) { checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL); } } @@ -3388,24 +3423,23 @@ public class AudioService extends IAudioService.Stub { } /** - * see AudioManager.unregisterRemoteControlClient(ComponentName eventReceiver, ...) + * see AudioManager.unregisterRemoteControlClient(PendingIntent pi, ...) * rcClient is guaranteed non-null */ - public void unregisterRemoteControlClient(ComponentName eventReceiver, + public void unregisterRemoteControlClient(PendingIntent mediaIntent, IRemoteControlClient rcClient) { synchronized(mAudioFocusLock) { synchronized(mRCStack) { Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator(); while(stackIterator.hasNext()) { RemoteControlStackEntry rcse = stackIterator.next(); - if ((rcse.mReceiverComponent.equals(eventReceiver)) + if ((rcse.mMediaIntent.equals(mediaIntent)) && rcClient.equals(rcse.mRcClient)) { // we found the IRemoteControlClient to unregister // stop monitoring its death rcse.unlinkToRcClientDeath(); // reset the client-related fields rcse.mRcClient = null; - rcse.mRcClientName = null; rcse.mRcClientDeathHandler = null; rcse.mCallingPackageName = null; } diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 7bf9814..5294d36 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -16,6 +16,7 @@ package android.media; +import android.app.PendingIntent; import android.content.ComponentName; import android.media.IAudioFocusDispatcher; import android.media.IRemoteControlClient; @@ -85,13 +86,12 @@ interface IAudioService { void unregisterAudioFocusClient(String clientId); - void registerMediaButtonEventReceiver(in ComponentName eventReceiver); + oneway void registerMediaButtonIntent(in PendingIntent pi, in ComponentName c); + oneway void unregisterMediaButtonIntent(in PendingIntent pi, in ComponentName c); - void unregisterMediaButtonEventReceiver(in ComponentName eventReceiver); - - oneway void registerRemoteControlClient(in ComponentName eventReceiver, - in IRemoteControlClient rcClient, in String clientName, in String callingPackageName); - oneway void unregisterRemoteControlClient(in ComponentName eventReceiver, + oneway void registerRemoteControlClient(in PendingIntent mediaIntent, + in IRemoteControlClient rcClient, in String callingPackageName); + oneway void unregisterRemoteControlClient(in PendingIntent mediaIntent, in IRemoteControlClient rcClient); oneway void registerRemoteControlDisplay(in IRemoteControlDisplay rcd); diff --git a/media/java/android/media/IRemoteControlDisplay.aidl b/media/java/android/media/IRemoteControlDisplay.aidl index fd50b7e..e15b07c 100644 --- a/media/java/android/media/IRemoteControlDisplay.aidl +++ b/media/java/android/media/IRemoteControlDisplay.aidl @@ -16,6 +16,7 @@ package android.media; +import android.app.PendingIntent; import android.content.ComponentName; import android.graphics.Bitmap; import android.os.Bundle; @@ -31,14 +32,12 @@ oneway interface IRemoteControlDisplay /** * Sets the generation counter of the current client that is displayed on the remote control. * @param clientGeneration the new RemoteControlClient generation - * @param clientEventReceiver the media button event receiver associated with the client. - * May be null, which implies there is no registered media button event receiver. This - * parameter is supplied as an optimization so a display can directly target media button - * events to the client. + * @param clientMediaIntent the PendingIntent associated with the client. + * May be null, which implies there is no registered media button event receiver. * @param clearing true if the new client generation value maps to a remote control update * where the display should be cleared. */ - void setCurrentClientId(int clientGeneration, in ComponentName clientEventReceiver, + void setCurrentClientId(int clientGeneration, in PendingIntent clientMediaIntent, boolean clearing); void setPlaybackState(int generationId, int state); diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java index cdebba0..5dea87f 100644 --- a/media/java/android/media/RemoteControlClient.java +++ b/media/java/android/media/RemoteControlClient.java @@ -34,6 +34,7 @@ import android.util.Log; import java.lang.IllegalArgumentException; /** + * TODO javadoc update for ComponentName - PendingIntent change * RemoteControlClient enables exposing information meant to be consumed by remote controls * capable of displaying metadata, artwork and media transport control buttons. * A remote control client object is associated with a media button event receiver. This @@ -205,50 +206,6 @@ public class RemoteControlClient public final static int FLAG_INFORMATION_REQUEST_ALBUM_ART = 1 << 3; /** - * @hide - * TODO remove after modifying known (internal) media apps using this API - * Class constructor. - * @param mediaButtonEventReceiver The receiver for the media button events. It needs to have - * been registered with {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)} - * before this new RemoteControlClient can itself be registered with - * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}. - * @see AudioManager#registerMediaButtonEventReceiver(ComponentName) - * @see AudioManager#registerRemoteControlClient(RemoteControlClient) - */ - public RemoteControlClient(ComponentName mediaButtonEventReceiver) { - mRcEventReceiver = mediaButtonEventReceiver; - - Looper looper; - if ((looper = Looper.myLooper()) != null) { - mEventHandler = new EventHandler(this, looper); - } else if ((looper = Looper.getMainLooper()) != null) { - mEventHandler = new EventHandler(this, looper); - } else { - mEventHandler = null; - Log.e(TAG, "RemoteControlClient() couldn't find main application thread"); - } - } - - /** - * @hide - * TODO remove after modifying known (internal) media apps using this API - * Class constructor for a remote control client whose internal event handling - * happens on a user-provided Looper. - * @param mediaButtonEventReceiver The receiver for the media button events. It needs to have - * been registered with {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)} - * before this new RemoteControlClient can itself be registered with - * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}. - * @param looper The Looper running the event loop. - * @see AudioManager#registerMediaButtonEventReceiver(ComponentName) - * @see AudioManager#registerRemoteControlClient(RemoteControlClient) - */ - public RemoteControlClient(ComponentName mediaButtonEventReceiver, Looper looper) { - mRcEventReceiver = mediaButtonEventReceiver; - - mEventHandler = new EventHandler(this, looper); - } - - /** * Class constructor. * @param mediaButtonIntent The intent that will be sent for the media button events sent * by remote controls. @@ -262,8 +219,7 @@ public class RemoteControlClient * @see AudioManager#registerRemoteControlClient(RemoteControlClient) */ public RemoteControlClient(PendingIntent mediaButtonIntent) { - // TODO implement using PendingIntent instead of ComponentName - mRcEventReceiver = null; + mRcMediaIntent = mediaButtonIntent; Looper looper; if ((looper = Looper.myLooper()) != null) { @@ -292,8 +248,7 @@ public class RemoteControlClient * @see AudioManager#registerRemoteControlClient(RemoteControlClient) */ public RemoteControlClient(PendingIntent mediaButtonIntent, Looper looper) { - // TODO implement using PendingIntent instead of ComponentName - mRcEventReceiver = null; + mRcMediaIntent = mediaButtonIntent; mEventHandler = new EventHandler(this, looper); } @@ -614,9 +569,10 @@ public class RemoteControlClient private int mInternalClientGenId = -2; /** - * The media button event receiver associated with this remote control client + * The media button intent description associated with this remote control client + * (can / should include target component for intent handling) */ - private final ComponentName mRcEventReceiver; + private final PendingIntent mRcMediaIntent; /** * The remote control display to which this client will send information. @@ -626,10 +582,10 @@ public class RemoteControlClient /** * @hide - * Accessor to media button event receiver + * Accessor to media button intent description (includes target component) */ - public ComponentName getRcEventReceiver() { - return mRcEventReceiver; + public PendingIntent getRcMediaIntent() { + return mRcMediaIntent; } /** * @hide |