From 7b6198cacc3e7dd31ef91537d809857d826fb7fa Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Sun, 7 Aug 2011 11:27:50 -0700 Subject: [PATCH] Bug 5045498 API for client to notify remote control info changed Update to API for a client to notify what type of information changed (e.g. playstate, metadata) to optimize small updates without the remote control display having to do expensive queries such as album art. When the remote control display retrieves the flags about what information changed, the flag gets cleared. Change-Id: I7d3d8d3eecd1da44695d84905ed9e7b70fe38b86 --- media/java/android/media/AudioManager.java | 44 ++++++++++++++++-- media/java/android/media/AudioService.java | 49 ++++++++++++++++++++- media/java/android/media/IAudioService.aidl | 4 +- 3 files changed, 91 insertions(+), 6 deletions(-) diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index ed6d87e423f43..e613523a9b6e6 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -1775,6 +1775,27 @@ public class AudioManager { } } + /** + * @hide + * Returns the current remote control client flags describing what information has changed. + * The flags are reset everytime this method is called with a valid rcClientId. + * @param rcClientId the counter value that matches the extra + * {@link AudioManager#EXTRA_REMOTE_CONTROL_CLIENT} in the + * {@link AudioManager#REMOTE_CONTROL_CLIENT_CHANGED} event + * @return the "information changed" flags from the current IRemoteControlClient from + * which information to display on the remote control can be retrieved, + * or 0 if rcClientId doesn't match the current generation counter. + */ + public int getRemoteControlClientInformationChangedFlags(int rcClientId) { + IAudioService service = getService(); + try { + return service.getRemoteControlClientInformationChangedFlags(rcClientId); + } catch (RemoteException e) { + Log.e(TAG, "Dead object in getRemoteControlClientInformationChangedFlags "+e); + return 0; + } + } + /** * @hide * Definitions of constants to be used in {@link android.media.IRemoteControlClient}. @@ -1797,6 +1818,11 @@ public class AudioManager { public final static int FLAG_KEY_MEDIA_STOP = 1 << 5; public final static int FLAG_KEY_MEDIA_FAST_FORWARD = 1 << 6; public final static int FLAG_KEY_MEDIA_NEXT = 1 << 7; + + public final static int FLAG_INFORMATION_CHANGED_METADATA = 1 << 0; + public final static int FLAG_INFORMATION_CHANGED_KEY_MEDIA = 1 << 1; + public final static int FLAG_INFORMATION_CHANGED_PLAYSTATE = 1 << 2; + public final static int FLAG_INFORMATION_CHANGED_ALBUM_ART = 1 << 3; } /** @@ -1824,12 +1850,24 @@ public class AudioManager { * @hide * Notifies the users of the associated remote control client that the information to display * has changed. - * @param eventReceiver + @param eventReceiver identifier of a {@link android.content.BroadcastReceiver} + * that will receive the media button intent, and associated with the remote control + * client. This method has no effect if + * {@link #registerMediaButtonEventReceiver(ComponentName)} hasn't been called + * with the same eventReceiver, or if + * {@link #unregisterMediaButtonEventReceiver(ComponentName)} has been called. + * @param infoFlag the type of information that has changed since this method was last called, + * or the event receiver was registered. Use one or multiple of the following flags to + * describe what changed: + * {@link RemoteControlParameters#FLAG_INFORMATION_CHANGED_METADATA}, + * {@link RemoteControlParameters#FLAG_INFORMATION_CHANGED_KEY_MEDIA}, + * {@link RemoteControlParameters#FLAG_INFORMATION_CHANGED_PLAYSTATE}, + * {@link RemoteControlParameters#FLAG_INFORMATION_CHANGED_ALBUM_ART}. */ - public void notifyRemoteControlInformationChanged(ComponentName eventReceiver) { + public void notifyRemoteControlInformationChanged(ComponentName eventReceiver, int infoFlag) { IAudioService service = getService(); try { - service.notifyRemoteControlInformationChanged(eventReceiver); + service.notifyRemoteControlInformationChanged(eventReceiver, infoFlag); } catch (RemoteException e) { Log.e(TAG, "Dead object in refreshRemoteControlDisplay"+e); } diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index cb56bc6a68cf6..c628be165c758 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -2854,6 +2854,19 @@ public class AudioService extends IAudioService.Stub { private SoftReference mCurrentRcClientRef = new SoftReference(null); + private final static int RC_INFO_NONE = 0; + private final static int RC_INFO_ALL = + AudioManager.RemoteControlParameters.FLAG_INFORMATION_CHANGED_ALBUM_ART | + AudioManager.RemoteControlParameters.FLAG_INFORMATION_CHANGED_KEY_MEDIA | + AudioManager.RemoteControlParameters.FLAG_INFORMATION_CHANGED_METADATA | + AudioManager.RemoteControlParameters.FLAG_INFORMATION_CHANGED_PLAYSTATE; + + /** + * The flags indicating what type of information changed since the last time it was queried. + * Access protected by mCurrentRcLock. + */ + private int mCurrentRcClientInfoFlags = RC_INFO_ALL; + /** * A monotonically increasing generation counter for mCurrentRcClientRef. * Only accessed with a lock on mCurrentRcLock. @@ -2879,6 +2892,27 @@ public class AudioService extends IAudioService.Stub { } } + /** + * Returns the current flags of information that changed on the current remote control client. + * Requesting this information clears it. + * @param rcClientId the counter value that matches the extra + * {@link AudioManager#EXTRA_REMOTE_CONTROL_CLIENT} in the + * {@link AudioManager#REMOTE_CONTROL_CLIENT_CHANGED} event + * @return the flags indicating which type of information changed since the client notified + * that its information had changed. + */ + public int getRemoteControlClientInformationChangedFlags(int rcClientId) { + synchronized(mCurrentRcLock) { + if (rcClientId == mCurrentRcClientGen) { + int flags = mCurrentRcClientInfoFlags; + mCurrentRcClientInfoFlags = RC_INFO_NONE; + return flags; + } else { + return RC_INFO_NONE; + } + } + } + /** * Inner class to monitor remote control client deaths, and remove the client for the * remote control stack if necessary. @@ -3072,6 +3106,7 @@ public class AudioService extends IAudioService.Stub { private void clearRemoteControlDisplay() { synchronized(mCurrentRcLock) { mCurrentRcClientRef.clear(); + mCurrentRcClientInfoFlags = RC_INFO_NONE; } mAudioHandler.sendMessage( mAudioHandler.obtainMessage(MSG_RCDISPLAY_CLEAR) ); } @@ -3092,6 +3127,10 @@ public class AudioService extends IAudioService.Stub { return; } synchronized(mCurrentRcLock) { + if (!mCurrentRcClientRef.get().equals(rcse.mRcClientRef.get())) { + // new RC client, assume every type of information shall be queried + mCurrentRcClientInfoFlags = RC_INFO_ALL; + } mCurrentRcClientRef = rcse.mRcClientRef; } mAudioHandler.sendMessage( mAudioHandler.obtainMessage(MSG_RCDISPLAY_UPDATE, 0, 0, rcse) ); @@ -3200,12 +3239,18 @@ public class AudioService extends IAudioService.Stub { } } - /** see AudioManager.notifyRemoteControlInformationChanged(ComponentName er) */ - public void notifyRemoteControlInformationChanged(ComponentName eventReceiver) { + /** see AudioManager.notifyRemoteControlInformationChanged(ComponentName er, int infoFlag) */ + public void notifyRemoteControlInformationChanged(ComponentName eventReceiver, int infoFlag) { synchronized(mAudioFocusLock) { synchronized(mRCStack) { // only refresh if the eventReceiver is at the top of the stack if (isCurrentRcController(eventReceiver)) { + // there is a refresh request for the current event receiver: it might not be + // displayed on the remote control display, but we can cache what new + // information has changed. + synchronized(mCurrentRcLock) { + mCurrentRcClientInfoFlags |= infoFlag; + } checkUpdateRemoteControlDisplay(); } } diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 25b9a1b352347..1061f13072ab6 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -95,7 +95,9 @@ interface IAudioService { IRemoteControlClient getRemoteControlClient(in int rcClientId); - void notifyRemoteControlInformationChanged(in ComponentName eventReceiver); + int getRemoteControlClientInformationChangedFlags(in int rcClientId); + + void notifyRemoteControlInformationChanged(in ComponentName eventReceiver, int infoFlag); void startBluetoothSco(IBinder cb);