Bug 5045498 RemoteControlClient interface
Define a RemoteControlClient interface that applications must
implement and register to be displayed on the lockscreen.
Change-Id: I67276ae653f203e76727432231f1d76535c31942
diff --git a/Android.mk b/Android.mk
index 752a5f8..a0b80e4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -183,7 +183,7 @@
media/java/android/media/IAudioFocusDispatcher.aidl \
media/java/android/media/IMediaScannerListener.aidl \
media/java/android/media/IMediaScannerService.aidl \
- media/java/android/media/IRemoteControlClient.aidl \
+ media/java/android/media/IRemoteControlClientDispatcher.aidl \
telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \
telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
telephony/java/com/android/internal/telephony/ITelephony.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index bf47314..2593065 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -104,6 +104,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/SystemUI_intermediates)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/R/com/android/systemui/R.java)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java/android/media/IAudioService.P)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 7a92b35..f9efd3c 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -21,6 +21,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.database.ContentObserver;
+import android.graphics.Bitmap;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -1715,29 +1716,103 @@
}
/**
+ * Acts as a proxy between AudioService and the RemoteControlClient
+ */
+ private IRemoteControlClientDispatcher mRcClientDispatcher =
+ new IRemoteControlClientDispatcher.Stub() {
+
+ public String getMetadataStringForClient(String clientName, int field) {
+ RemoteControlClient realClient;
+ synchronized(mRcClientMap) {
+ realClient = mRcClientMap.get(clientName);
+ }
+ if (realClient != null) {
+ return realClient.getMetadataString(field);
+ } else {
+ return null;
+ }
+ }
+
+ public int getPlaybackStateForClient(String clientName) {
+ RemoteControlClient realClient;
+ synchronized(mRcClientMap) {
+ realClient = mRcClientMap.get(clientName);
+ }
+ if (realClient != null) {
+ return realClient.getPlaybackState();
+ } else {
+ return 0;
+ }
+ }
+
+ public int getTransportControlFlagsForClient(String clientName) {
+ RemoteControlClient realClient;
+ synchronized(mRcClientMap) {
+ realClient = mRcClientMap.get(clientName);
+ }
+ if (realClient != null) {
+ return realClient.getTransportControlFlags();
+ } else {
+ return 0;
+ }
+ }
+
+ public Bitmap getAlbumArtForClient(String clientName, int maxWidth, int maxHeight) {
+ RemoteControlClient realClient;
+ synchronized(mRcClientMap) {
+ realClient = mRcClientMap.get(clientName);
+ }
+ if (realClient != null) {
+ return realClient.getAlbumArt(maxWidth, maxHeight);
+ } else {
+ return null;
+ }
+ }
+ };
+
+ private HashMap<String, RemoteControlClient> mRcClientMap =
+ new HashMap<String, RemoteControlClient>();
+
+ private String getIdForRcClient(RemoteControlClient client) {
+ // client is guaranteed to be non-null
+ return client.toString();
+ }
+
+ /**
* @hide
- * Registers the remote control client for providing information to display on the remotes.
+ * Registers the remote control client for providing information to display on the remote
+ * controls.
* @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 rcClient the client associated with the event receiver, responsible for providing
- * the information to display on the remote control.
+ * @param rcClient the remote control client associated with the event receiver, responsible
+ * for providing the information to display on the remote control.
*/
public void registerRemoteControlClient(ComponentName eventReceiver,
- IRemoteControlClient rcClient) {
- if (eventReceiver == null) {
+ RemoteControlClient rcClient) {
+ if ((eventReceiver == null) || (rcClient == null)) {
return;
}
+ String clientKey = getIdForRcClient(rcClient);
+ synchronized(mRcClientMap) {
+ if (mRcClientMap.containsKey(clientKey)) {
+ return;
+ }
+ mRcClientMap.put(clientKey, rcClient);
+ }
IAudioService service = getService();
try {
- service.registerRemoteControlClient(eventReceiver, rcClient,
+ service.registerRemoteControlClient(eventReceiver, mRcClientDispatcher, clientKey,
// used to match media button event receiver and audio focus
mContext.getPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Dead object in registerRemoteControlClient"+e);
+ synchronized(mRcClientMap) {
+ mRcClientMap.remove(clientKey);
+ }
}
}
@@ -1748,17 +1823,28 @@
* @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}
* that receives the media button intent, and associated with the remote control
* client.
- * @see #registerRemoteControlClient(ComponentName)
-
+ * @param rcClient the remote control client to unregister
+ * @see #registerRemoteControlClient(ComponentName, RemoteControlClient)
*/
- public void unregisterRemoteControlClient(ComponentName eventReceiver) {
- if (eventReceiver == null) {
+ public void unregisterRemoteControlClient(ComponentName eventReceiver,
+ RemoteControlClient rcClient) {
+ if ((eventReceiver == null) || (rcClient == null)) {
return;
}
IAudioService service = getService();
try {
- // unregistering a IRemoteControlClient is equivalent to setting it to null
- service.registerRemoteControlClient(eventReceiver, null, mContext.getPackageName());
+ // remove locally
+ boolean unregister = true;
+ synchronized(mRcClientMap) {
+ if (mRcClientMap.remove(getIdForRcClient(rcClient)) == null) {
+ unregister = false;
+ }
+ }
+ if (unregister) {
+ // unregistering a RemoteControlClient is equivalent to setting it to null
+ service.registerRemoteControlClient(eventReceiver, null, null,
+ mContext.getPackageName());
+ }
} catch (RemoteException e) {
Log.e(TAG, "Dead object in unregisterRemoteControlClient"+e);
}
@@ -1767,17 +1853,17 @@
/**
* @hide
* Returns the current remote control client.
- * @param rcClientId the counter value that matches the extra
- * {@link AudioManager#EXTRA_REMOTE_CONTROL_CLIENT} in the
+ * @param rcClientId the generation counter that matches the extra
+ * {@link AudioManager#EXTRA_REMOTE_CONTROL_CLIENT_GENERATION} in the
* {@link AudioManager#REMOTE_CONTROL_CLIENT_CHANGED} event
- * @return the current IRemoteControlClient from which information to display on the remote
+ * @return the current RemoteControlClient from which information to display on the remote
* control can be retrieved, or null if rcClientId doesn't match the current generation
* counter.
*/
- public IRemoteControlClient getRemoteControlClient(int rcClientId) {
+ public IRemoteControlClientDispatcher getRemoteControlClientDispatcher(int rcClientId) {
IAudioService service = getService();
try {
- return service.getRemoteControlClient(rcClientId);
+ return service.getRemoteControlClientDispatcher(rcClientId);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in getRemoteControlClient "+e);
return null;
@@ -1786,160 +1872,6 @@
/**
* @hide
- * Definitions of constants to be used in {@link android.media.IRemoteControlClient}.
- */
- public final class RemoteControlParameters {
- /**
- * Playback state of an IRemoteControlClient which is stopped.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_STOPPED = 1;
- /**
- * Playback state of an IRemoteControlClient which is paused.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_PAUSED = 2;
- /**
- * Playback state of an IRemoteControlClient which is playing media.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_PLAYING = 3;
- /**
- * Playback state of an IRemoteControlClient which is fast forwarding in the media
- * it is currently playing.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_FAST_FORWARDING = 4;
- /**
- * Playback state of an IRemoteControlClient which is fast rewinding in the media
- * it is currently playing.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_REWINDING = 5;
- /**
- * Playback state of an IRemoteControlClient which is skipping to the next
- * logical chapter (such as a song in a playlist) in the media it is currently playing.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_SKIPPING_FORWARDS = 6;
- /**
- * Playback state of an IRemoteControlClient which is skipping back to the previous
- * logical chapter (such as a song in a playlist) in the media it is currently playing.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_SKIPPING_BACKWARDS = 7;
- /**
- * Playback state of an IRemoteControlClient which is buffering data to play before it can
- * start or resume playback.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_BUFFERING = 8;
- /**
- * Playback state of an IRemoteControlClient which cannot perform any playback related
- * operation because of an internal error. Examples of such situations are no network
- * connectivity when attempting to stream data from a server, or expired user credentials
- * when trying to play subscription-based content.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_ERROR = 9;
-
- /**
- * Flag indicating an IRemoteControlClient makes use of the "previous" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_PREVIOUS
- */
- public final static int FLAG_KEY_MEDIA_PREVIOUS = 1 << 0;
- /**
- * Flag indicating an IRemoteControlClient makes use of the "rewing" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_REWIND
- */
- public final static int FLAG_KEY_MEDIA_REWIND = 1 << 1;
- /**
- * Flag indicating an IRemoteControlClient makes use of the "play" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY
- */
- public final static int FLAG_KEY_MEDIA_PLAY = 1 << 2;
- /**
- * Flag indicating an IRemoteControlClient makes use of the "play/pause" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE
- */
- public final static int FLAG_KEY_MEDIA_PLAY_PAUSE = 1 << 3;
- /**
- * Flag indicating an IRemoteControlClient makes use of the "pause" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_PAUSE
- */
- public final static int FLAG_KEY_MEDIA_PAUSE = 1 << 4;
- /**
- * Flag indicating an IRemoteControlClient makes use of the "stop" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_STOP
- */
- public final static int FLAG_KEY_MEDIA_STOP = 1 << 5;
- /**
- * Flag indicating an IRemoteControlClient makes use of the "fast forward" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_FAST_FORWARD
- */
- public final static int FLAG_KEY_MEDIA_FAST_FORWARD = 1 << 6;
- /**
- * Flag indicating an IRemoteControlClient makes use of the "next" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_NEXT
- */
- public final static int FLAG_KEY_MEDIA_NEXT = 1 << 7;
-
- /**
- * Flag used to signal that the metadata exposed by the IRemoteControlClient has changed.
- *
- * @see #notifyRemoteControlInformationChanged(ComponentName, int)
- */
- public final static int FLAG_INFORMATION_CHANGED_METADATA = 1 << 0;
- /**
- * Flag used to signal that the transport control buttons supported by the
- * IRemoteControlClient have changed.
- * This can for instance happen when playback is at the end of a playlist, and the "next"
- * operation is not supported anymore.
- *
- * @see #notifyRemoteControlInformationChanged(ComponentName, int)
- */
- public final static int FLAG_INFORMATION_CHANGED_KEY_MEDIA = 1 << 1;
- /**
- * Flag used to signal that the playback state of the IRemoteControlClient has changed.
- *
- * @see #notifyRemoteControlInformationChanged(ComponentName, int)
- */
- public final static int FLAG_INFORMATION_CHANGED_PLAYSTATE = 1 << 2;
- /**
- * Flag used to signal that the album art for the IRemoteControlClient has changed.
- *
- * @see #notifyRemoteControlInformationChanged(ComponentName, int)
- */
- public final static int FLAG_INFORMATION_CHANGED_ALBUM_ART = 1 << 3;
- }
-
- /**
- * @hide
* Broadcast intent action indicating that the displays on the remote controls
* should be updated because a new remote control client is now active. If there is no
* {@link #EXTRA_REMOTE_CONTROL_CLIENT}, the remote control display should be cleared
@@ -1952,16 +1884,27 @@
/**
* @hide
- * The IRemoteControlClient monotonically increasing generation counter.
+ * The IRemoteControlClientDispatcher monotonically increasing generation counter.
*
* @see #REMOTE_CONTROL_CLIENT_CHANGED_ACTION
*/
- public static final String EXTRA_REMOTE_CONTROL_CLIENT =
- "android.media.EXTRA_REMOTE_CONTROL_CLIENT";
+ public static final String EXTRA_REMOTE_CONTROL_CLIENT_GENERATION =
+ "android.media.EXTRA_REMOTE_CONTROL_CLIENT_GENERATION";
/**
* @hide
- * The media button event receiver associated with the IRemoteControlClient.
+ * The name of the RemoteControlClient.
+ * This String is passed as the client name when calling methods from the
+ * IRemoteControlClientDispatcher interface.
+ *
+ * @see #REMOTE_CONTROL_CLIENT_CHANGED_ACTION
+ */
+ public static final String EXTRA_REMOTE_CONTROL_CLIENT_NAME =
+ "android.media.EXTRA_REMOTE_CONTROL_CLIENT_NAME";
+
+ /**
+ * @hide
+ * The media button event receiver associated with the RemoteControlClient.
* The {@link android.content.ComponentName} value of the event receiver can be retrieved with
* {@link android.content.ComponentName#unflattenFromString(String)}
*
@@ -1992,10 +1935,10 @@
* @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}.
+ * {@link RemoteControlClient#FLAG_INFORMATION_CHANGED_METADATA},
+ * {@link RemoteControlClient#FLAG_INFORMATION_CHANGED_KEY_MEDIA},
+ * {@link RemoteControlClient#FLAG_INFORMATION_CHANGED_PLAYSTATE},
+ * {@link RemoteControlClient#FLAG_INFORMATION_CHANGED_ALBUM_ART}.
*/
public void notifyRemoteControlInformationChanged(ComponentName eventReceiver, int infoFlag) {
IAudioService service = getService();
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index ff2e66b..92829ca 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -34,6 +34,7 @@
import android.database.ContentObserver;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
+import android.media.IRemoteControlClientDispatcher;
import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
@@ -2165,7 +2166,7 @@
// TODO remove log before release
Log.i(TAG, "Clear remote control display");
Intent clearIntent = new Intent(AudioManager.REMOTE_CONTROL_CLIENT_CHANGED);
- // no extra means no IRemoteControlClient, which is a request to clear
+ // no extra means no IRemoteControlClientDispatcher, which is a request to clear
clearIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mContext.sendBroadcast(clearIntent);
break;
@@ -2185,7 +2186,8 @@
Log.i(TAG, "Display/update remote control ");
Intent rcClientIntent = new Intent(
AudioManager.REMOTE_CONTROL_CLIENT_CHANGED);
- rcClientIntent.putExtra(AudioManager.EXTRA_REMOTE_CONTROL_CLIENT,
+ rcClientIntent.putExtra(
+ AudioManager.EXTRA_REMOTE_CONTROL_CLIENT_GENERATION,
mCurrentRcClientGen);
rcClientIntent.putExtra(
AudioManager.EXTRA_REMOTE_CONTROL_CLIENT_INFO_CHANGED,
@@ -2193,6 +2195,9 @@
rcClientIntent.putExtra(
AudioManager.EXTRA_REMOTE_CONTROL_EVENT_RECEIVER,
rcse.mReceiverComponent.flattenToString());
+ rcClientIntent.putExtra(
+ AudioManager.EXTRA_REMOTE_CONTROL_CLIENT_NAME,
+ rcse.mRcClientName);
rcClientIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mContext.sendBroadcast(rcClientIntent);
}
@@ -2888,14 +2893,14 @@
* This object may be null.
* Access protected by mCurrentRcLock.
*/
- private IRemoteControlClient mCurrentRcClient = null;
+ private IRemoteControlClientDispatcher mCurrentRcClient = 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;
+ RemoteControlClient.FLAG_INFORMATION_CHANGED_ALBUM_ART |
+ RemoteControlClient.FLAG_INFORMATION_CHANGED_KEY_MEDIA |
+ RemoteControlClient.FLAG_INFORMATION_CHANGED_METADATA |
+ RemoteControlClient.FLAG_INFORMATION_CHANGED_PLAYSTATE;
/**
* A monotonically increasing generation counter for mCurrentRcClient.
@@ -2907,13 +2912,13 @@
/**
* Returns the current remote control client.
* @param rcClientId the counter value that matches the extra
- * {@link AudioManager#EXTRA_REMOTE_CONTROL_CLIENT} in the
+ * {@link AudioManager#EXTRA_REMOTE_CONTROL_CLIENT_GENERATION} in the
* {@link AudioManager#REMOTE_CONTROL_CLIENT_CHANGED} event
- * @return the current IRemoteControlClient from which information to display on the remote
- * control can be retrieved, or null if rcClientId doesn't match the current generation
- * counter.
+ * @return the current IRemoteControlClientDispatcher from which information to display on the
+ * remote control can be retrieved, or null if rcClientId doesn't match the current
+ * generation counter.
*/
- public IRemoteControlClient getRemoteControlClient(int rcClientId) {
+ public IRemoteControlClientDispatcher getRemoteControlClientDispatcher(int rcClientId) {
synchronized(mCurrentRcLock) {
if (rcClientId == mCurrentRcClientGen) {
return mCurrentRcClient;
@@ -2940,7 +2945,7 @@
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/*ignored*/);
+ registerRemoteControlClient(mRcEventReceiver, null, null, null/*ignored*/);
}
public IBinder getBinder() {
@@ -2952,10 +2957,11 @@
/** the target for the ACTION_MEDIA_BUTTON events */
public ComponentName mReceiverComponent;// always non null
public String mCallingPackageName;
+ public String mRcClientName;
public int mCallingUid;
/** provides access to the information to display on the remote control */
- public IRemoteControlClient mRcClient;
+ public IRemoteControlClientDispatcher mRcClient;
public RcClientDeathHandler mRcClientDeathHandler;
public RemoteControlStackEntry(ComponentName r) {
@@ -3210,7 +3216,7 @@
/** see AudioManager.registerRemoteControlClient(ComponentName eventReceiver, ...) */
public void registerRemoteControlClient(ComponentName eventReceiver,
- IRemoteControlClient rcClient, String callingPackageName) {
+ IRemoteControlClientDispatcher rcClient, String clientName, String callingPackageName) {
synchronized(mAudioFocusLock) {
synchronized(mRCStack) {
// store the new display information
@@ -3226,8 +3232,10 @@
// save the new remote control client
rcse.mRcClient = rcClient;
rcse.mCallingPackageName = callingPackageName;
+ rcse.mRcClientName = clientName;
rcse.mCallingUid = Binder.getCallingUid();
if (rcClient == null) {
+ rcse.mRcClientDeathHandler = null;
break;
}
// monitor the new client's death
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index c259aa3..7f9ced9 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -18,9 +18,7 @@
import android.content.ComponentName;
import android.media.IAudioFocusDispatcher;
-import android.media.IRemoteControlClient;
-import android.net.Uri;
-import android.os.Bundle;
+import android.media.IRemoteControlClientDispatcher;
/**
* {@hide}
@@ -91,9 +89,10 @@
void unregisterMediaButtonEventReceiver(in ComponentName eventReceiver);
void registerRemoteControlClient(in ComponentName eventReceiver,
- in IRemoteControlClient rcClient, in String callingPackageName);
+ in IRemoteControlClientDispatcher rcClient, in String clientName,
+ in String callingPackageName);
- IRemoteControlClient getRemoteControlClient(in int rcClientId);
+ IRemoteControlClientDispatcher getRemoteControlClientDispatcher(in int rcClientId);
void notifyRemoteControlInformationChanged(in ComponentName eventReceiver, int infoFlag);
diff --git a/media/java/android/media/IRemoteControlClient.aidl b/media/java/android/media/IRemoteControlClientDispatcher.aidl
similarity index 88%
rename from media/java/android/media/IRemoteControlClient.aidl
rename to media/java/android/media/IRemoteControlClientDispatcher.aidl
index 76d178c..98142cc 100644
--- a/media/java/android/media/IRemoteControlClient.aidl
+++ b/media/java/android/media/IRemoteControlClientDispatcher.aidl
@@ -20,13 +20,11 @@
/**
* @hide
- * Interface for an object that exposes information meant to be consumed by remote controls
- * capable of displaying metadata, album art and media transport control buttons.
- * Such a remote control client object is associated with a media button event receiver
- * when registered through
- * {@link AudioManager#registerRemoteControlClient(ComponentName, IRemoteControlClient)}.
+ * Interface registered by AudioManager to dispatch remote control information requests
+ * to the RemoteControlClient implementation. This is used by AudioService.
+ * {@see AudioManager#registerRemoteControlClient(ComponentName, RemoteControlClient)}.
*/
-interface IRemoteControlClient
+interface IRemoteControlClientDispatcher
{
/**
* Called by a remote control to retrieve a String of information to display.
@@ -49,7 +47,7 @@
* @return null if the requested field is not supported, or the String matching the
* metadata field.
*/
- String getMetadataString(int field);
+ String getMetadataStringForClient(String clientName, int field);
/**
* Called by a remote control to retrieve the current playback state.
@@ -64,7 +62,7 @@
* {@link android.media.AudioManager.RemoteControlParameters#PLAYSTATE_BUFFERING},
* {@link android.media.AudioManager.RemoteControlParameters#PLAYSTATE_ERROR}.
*/
- int getPlaybackState();
+ int getPlaybackStateForClient(String clientName);
/**
* Called by a remote control to retrieve the flags for the media transport control buttons
@@ -78,7 +76,7 @@
* {@link android.media.AudioManager.RemoteControlParameters#FLAG_KEY_MEDIA_FAST_FORWARD},
* {@link android.media.AudioManager.RemoteControlParameters#FLAG_KEY_MEDIA_NEXT}
*/
- int getTransportControlFlags();
+ int getTransportControlFlagsForClient(String clientName);
/**
* Called by a remote control to retrieve the album art picture at the requested size.
@@ -90,5 +88,5 @@
* @return the bitmap for the album art, or null if there isn't any.
* @see android.graphics.Bitmap
*/
- Bitmap getAlbumArt(int maxWidth, int maxHeight);
+ Bitmap getAlbumArtForClient(String clientName, int maxWidth, int maxHeight);
}
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
new file mode 100644
index 0000000..c384636
--- /dev/null
+++ b/media/java/android/media/RemoteControlClient.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.content.ComponentName;
+import android.graphics.Bitmap;
+
+/**
+ * @hide
+ * Interface for an object that exposes information meant to be consumed by remote controls
+ * capable of displaying metadata, album art and media transport control buttons.
+ * Such a remote control client object is associated with a media button event receiver
+ * when registered through
+ * {@link AudioManager#registerRemoteControlClient(ComponentName, RemoteControlClient)}.
+ */
+public interface RemoteControlClient
+{
+ /**
+ * Playback state of a RemoteControlClient which is stopped.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_STOPPED = 1;
+ /**
+ * Playback state of a RemoteControlClient which is paused.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_PAUSED = 2;
+ /**
+ * Playback state of a RemoteControlClient which is playing media.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_PLAYING = 3;
+ /**
+ * Playback state of a RemoteControlClient which is fast forwarding in the media
+ * it is currently playing.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_FAST_FORWARDING = 4;
+ /**
+ * Playback state of a RemoteControlClient which is fast rewinding in the media
+ * it is currently playing.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_REWINDING = 5;
+ /**
+ * Playback state of a RemoteControlClient which is skipping to the next
+ * logical chapter (such as a song in a playlist) in the media it is currently playing.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_SKIPPING_FORWARDS = 6;
+ /**
+ * Playback state of a RemoteControlClient which is skipping back to the previous
+ * logical chapter (such as a song in a playlist) in the media it is currently playing.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_SKIPPING_BACKWARDS = 7;
+ /**
+ * Playback state of a RemoteControlClient which is buffering data to play before it can
+ * start or resume playback.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_BUFFERING = 8;
+ /**
+ * Playback state of a RemoteControlClient which cannot perform any playback related
+ * operation because of an internal error. Examples of such situations are no network
+ * connectivity when attempting to stream data from a server, or expired user credentials
+ * when trying to play subscription-based content.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_ERROR = 9;
+
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "previous" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_PREVIOUS
+ */
+ public final static int FLAG_KEY_MEDIA_PREVIOUS = 1 << 0;
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "rewing" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_REWIND
+ */
+ public final static int FLAG_KEY_MEDIA_REWIND = 1 << 1;
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "play" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY
+ */
+ public final static int FLAG_KEY_MEDIA_PLAY = 1 << 2;
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "play/pause" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE
+ */
+ public final static int FLAG_KEY_MEDIA_PLAY_PAUSE = 1 << 3;
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "pause" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_PAUSE
+ */
+ public final static int FLAG_KEY_MEDIA_PAUSE = 1 << 4;
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "stop" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_STOP
+ */
+ public final static int FLAG_KEY_MEDIA_STOP = 1 << 5;
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "fast forward" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_FAST_FORWARD
+ */
+ public final static int FLAG_KEY_MEDIA_FAST_FORWARD = 1 << 6;
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "next" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_NEXT
+ */
+ public final static int FLAG_KEY_MEDIA_NEXT = 1 << 7;
+
+ /**
+ * Flag used to signal that the metadata exposed by the RemoteControlClient has changed.
+ *
+ * @see #notifyRemoteControlInformationChanged(ComponentName, int)
+ */
+ public final static int FLAG_INFORMATION_CHANGED_METADATA = 1 << 0;
+ /**
+ * Flag used to signal that the transport control buttons supported by the
+ * RemoteControlClient have changed.
+ * This can for instance happen when playback is at the end of a playlist, and the "next"
+ * operation is not supported anymore.
+ *
+ * @see #notifyRemoteControlInformationChanged(ComponentName, int)
+ */
+ public final static int FLAG_INFORMATION_CHANGED_KEY_MEDIA = 1 << 1;
+ /**
+ * Flag used to signal that the playback state of the RemoteControlClient has changed.
+ *
+ * @see #notifyRemoteControlInformationChanged(ComponentName, int)
+ */
+ public final static int FLAG_INFORMATION_CHANGED_PLAYSTATE = 1 << 2;
+ /**
+ * Flag used to signal that the album art for the RemoteControlClient has changed.
+ *
+ * @see #notifyRemoteControlInformationChanged(ComponentName, int)
+ */
+ public final static int FLAG_INFORMATION_CHANGED_ALBUM_ART = 1 << 3;
+
+ /**
+ * Called by a remote control to retrieve a String of information to display.
+ * @param field the identifier for a metadata field to retrieve. Valid values are
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUM},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ARTIST},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_AUTHOR},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPILATION},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPOSER},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DATE},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_GENRE},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}.
+ * @return null if the requested field is not supported, or the String matching the
+ * metadata field.
+ */
+ String getMetadataString(int field);
+
+ /**
+ * Called by a remote control to retrieve the current playback state.
+ * @return one of the following values:
+ * {@link #PLAYSTATE_STOPPED},
+ * {@link #PLAYSTATE_PAUSED},
+ * {@link #PLAYSTATE_PLAYING},
+ * {@link #PLAYSTATE_FAST_FORWARDING},
+ * {@link #PLAYSTATE_REWINDING},
+ * {@link #PLAYSTATE_SKIPPING_FORWARDS},
+ * {@link #PLAYSTATE_SKIPPING_BACKWARDS},
+ * {@link #PLAYSTATE_BUFFERING},
+ * {@link #PLAYSTATE_ERROR}.
+ */
+ int getPlaybackState();
+
+ /**
+ * Called by a remote control to retrieve the flags for the media transport control buttons
+ * that this client supports.
+ * @see {@link #FLAG_KEY_MEDIA_PREVIOUS},
+ * {@link #FLAG_KEY_MEDIA_REWIND},
+ * {@link #FLAG_KEY_MEDIA_PLAY},
+ * {@link #FLAG_KEY_MEDIA_PLAY_PAUSE},
+ * {@link #FLAG_KEY_MEDIA_PAUSE},
+ * {@link #FLAG_KEY_MEDIA_STOP},
+ * {@link #FLAG_KEY_MEDIA_FAST_FORWARD},
+ * {@link #FLAG_KEY_MEDIA_NEXT}
+ */
+ int getTransportControlFlags();
+
+ /**
+ * Called by a remote control to retrieve the album art picture at the requested size.
+ * Note that returning a bitmap smaller than the maximum requested dimension is accepted
+ * and it will be scaled as needed, but exceeding the maximum dimensions may produce
+ * unspecified results, such as the image being cropped or simply not being displayed.
+ * @param maxWidth the maximum width of the requested bitmap expressed in pixels.
+ * @param maxHeight the maximum height of the requested bitmap expressed in pixels.
+ * @return the bitmap for the album art, or null if there isn't any.
+ * @see android.graphics.Bitmap
+ */
+ Bitmap getAlbumArt(int maxWidth, int maxHeight);
+}