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);