Commit 178889ef authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

Bug 5045498 RemoteControlClient interface

Define a RemoteControlClient interface that applications must
 implement and register to be displayed on the lockscreen.

Change-Id: I67276ae653f203e76727432231f1d76535c31942
parent ed2d658a
......@@ -183,7 +183,7 @@ LOCAL_SRC_FILES += \
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 \
......
......@@ -104,6 +104,7 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framew
$(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
# ************************************************
......@@ -21,6 +21,7 @@ import android.annotation.SdkConstant.SdkConstantType;
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;
......@@ -1714,30 +1715,104 @@ public class AudioManager {
}
}
/**
* 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 @@ public class AudioManager {
* @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,177 +1853,23 @@ public class AudioManager {
/**
* @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;
}
}
/**
* @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
......@@ -1952,16 +1884,27 @@ public class AudioManager {
/**
* @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_GENERATION =
"android.media.EXTRA_REMOTE_CONTROL_CLIENT_GENERATION";
/**
* @hide
* 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 =
"android.media.EXTRA_REMOTE_CONTROL_CLIENT";
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 IRemoteControlClient.
* 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 @@ public class AudioManager {
* @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();
......
......@@ -34,6 +34,7 @@ import android.content.pm.PackageManager;
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 @@ public class AudioService extends IAudioService.Stub {
// 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 @@ public class AudioService extends IAudioService.Stub {
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 @@ public class AudioService extends IAudioService.Stub {
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 @@ public class AudioService extends IAudioService.Stub {
* 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 @@ public class AudioService extends IAudioService.Stub {
/**
* 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 @@ public class AudioService extends IAudioService.Stub {
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 @@ public class AudioService extends IAudioService.Stub {
/** 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 @@ public class AudioService extends IAudioService.Stub {
/** 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 @@ public class AudioService extends IAudioService.Stub {
// 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
......
......@@ -18,9 +18,7 @@ package android.media;
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 @@ interface IAudioService {
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);
......
......@@ -20,13 +20,11 @@ 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, 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 @@ interface IRemoteControlClient
* @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 @@ interface IRemoteControlClient
* {@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 @@ interface IRemoteControlClient
* {@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 @@ interface IRemoteControlClient
* @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);
}
/*
* 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);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment