Merge "Ratings for RemoteControl" into klp-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
198bc229c3
@@ -2359,6 +2359,24 @@ public class AudioManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* Notify the user of a RemoteControlClient that it should update its metadata
|
||||||
|
* @param generationId the RemoteControlClient generation counter for which this request is
|
||||||
|
* issued. Requests for an older generation than current one will be ignored.
|
||||||
|
* @param key the metadata key for which a new value exists
|
||||||
|
* @param value the new metadata value
|
||||||
|
*/
|
||||||
|
public void updateRemoteControlClientMetadata(int generationId, int key, long value) {
|
||||||
|
IAudioService service = getService();
|
||||||
|
try {
|
||||||
|
service.updateRemoteControlClientMetadata(generationId, key, value);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Dead object in updateRemoteControlClientMetadata("+ generationId + ", "
|
||||||
|
+ key +", " + value + ")", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
* Reload audio settings. This method is called by Settings backup
|
* Reload audio settings. This method is called by Settings backup
|
||||||
|
|||||||
@@ -4189,6 +4189,10 @@ public class AudioService extends IAudioService.Stub {
|
|||||||
mMediaFocusControl.setRemoteControlClientPlaybackPosition(generationId, timeMs);
|
mMediaFocusControl.setRemoteControlClientPlaybackPosition(generationId, timeMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateRemoteControlClientMetadata(int generationId, int key, long value) {
|
||||||
|
mMediaFocusControl.updateRemoteControlClientMetadata(generationId, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
public void registerRemoteVolumeObserverForRcc(int rccId, IRemoteVolumeObserver rvo) {
|
public void registerRemoteVolumeObserverForRcc(int rccId, IRemoteVolumeObserver rvo) {
|
||||||
mMediaFocusControl.registerRemoteVolumeObserverForRcc(rccId, rvo);
|
mMediaFocusControl.registerRemoteVolumeObserverForRcc(rccId, rvo);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,6 +179,14 @@ interface IAudioService {
|
|||||||
* @param timeMs the time in ms to seek to, must be positive.
|
* @param timeMs the time in ms to seek to, must be positive.
|
||||||
*/
|
*/
|
||||||
void setRemoteControlClientPlaybackPosition(int generationId, long timeMs);
|
void setRemoteControlClientPlaybackPosition(int generationId, long timeMs);
|
||||||
|
/**
|
||||||
|
* Notify the user of a RemoteControlClient that it should update its metadata
|
||||||
|
* @param generationId the RemoteControlClient generation counter for which this request is
|
||||||
|
* issued. Requests for an older generation than current one will be ignored.
|
||||||
|
* @param key the metadata key for which a new value exists
|
||||||
|
* @param value the new metadata value
|
||||||
|
*/
|
||||||
|
void updateRemoteControlClientMetadata(int generationId, int key, long value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do not use directly, use instead
|
* Do not use directly, use instead
|
||||||
|
|||||||
@@ -49,4 +49,5 @@ oneway interface IRemoteControlClient
|
|||||||
void setBitmapSizeForDisplay(IRemoteControlDisplay rcd, int w, int h);
|
void setBitmapSizeForDisplay(IRemoteControlDisplay rcd, int w, int h);
|
||||||
void setWantsSyncForDisplay(IRemoteControlDisplay rcd, boolean wantsSync);
|
void setWantsSyncForDisplay(IRemoteControlDisplay rcd, boolean wantsSync);
|
||||||
void seekTo(int clientGeneration, long timeMs);
|
void seekTo(int clientGeneration, long timeMs);
|
||||||
|
void updateMetadata(int clientGeneration, int key, long value);
|
||||||
}
|
}
|
||||||
@@ -138,6 +138,7 @@ public class MediaFocusControl implements OnFinished {
|
|||||||
private static final int MSG_PROMOTE_RCC = 6;
|
private static final int MSG_PROMOTE_RCC = 6;
|
||||||
private static final int MSG_RCC_NEW_PLAYBACK_STATE = 7;
|
private static final int MSG_RCC_NEW_PLAYBACK_STATE = 7;
|
||||||
private static final int MSG_RCC_SEEK_REQUEST = 8;
|
private static final int MSG_RCC_SEEK_REQUEST = 8;
|
||||||
|
private static final int MSG_RCC_UPDATE_METADATA_LONG = 9;
|
||||||
|
|
||||||
// sendMsg() flags
|
// sendMsg() flags
|
||||||
/** If the msg is already queued, replace it with this one. */
|
/** If the msg is already queued, replace it with this one. */
|
||||||
@@ -188,18 +189,27 @@ public class MediaFocusControl implements OnFinished {
|
|||||||
onNewPlaybackInfoForRcc(msg.arg1 /* rccId */, msg.arg2 /* key */,
|
onNewPlaybackInfoForRcc(msg.arg1 /* rccId */, msg.arg2 /* key */,
|
||||||
((Integer)msg.obj).intValue() /* value */);
|
((Integer)msg.obj).intValue() /* value */);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSG_RCC_NEW_VOLUME_OBS:
|
case MSG_RCC_NEW_VOLUME_OBS:
|
||||||
onRegisterVolumeObserverForRcc(msg.arg1 /* rccId */,
|
onRegisterVolumeObserverForRcc(msg.arg1 /* rccId */,
|
||||||
(IRemoteVolumeObserver)msg.obj /* rvo */);
|
(IRemoteVolumeObserver)msg.obj /* rvo */);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSG_RCC_NEW_PLAYBACK_STATE:
|
case MSG_RCC_NEW_PLAYBACK_STATE:
|
||||||
onNewPlaybackStateForRcc(msg.arg1 /* rccId */,
|
onNewPlaybackStateForRcc(msg.arg1 /* rccId */,
|
||||||
msg.arg2 /* state */,
|
msg.arg2 /* state */,
|
||||||
(RccPlaybackState)msg.obj /* newState */);
|
(RccPlaybackState)msg.obj /* newState */);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSG_RCC_SEEK_REQUEST:
|
case MSG_RCC_SEEK_REQUEST:
|
||||||
onSetRemoteControlClientPlaybackPosition(
|
onSetRemoteControlClientPlaybackPosition(
|
||||||
msg.arg1 /* generationId */, ((Long)msg.obj).longValue() /* timeMs */);
|
msg.arg1 /* generationId */, ((Long)msg.obj).longValue() /* timeMs */);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSG_RCC_UPDATE_METADATA_LONG:
|
||||||
|
onUpdateRemoteControlClientMetadataLong(msg.arg1 /*genId*/, msg.arg2 /*key*/,
|
||||||
|
((Long)msg.obj).longValue() /* value */);
|
||||||
|
break;
|
||||||
|
|
||||||
case MSG_PROMOTE_RCC:
|
case MSG_PROMOTE_RCC:
|
||||||
onPromoteRcc(msg.arg1);
|
onPromoteRcc(msg.arg1);
|
||||||
@@ -2070,6 +2080,36 @@ public class MediaFocusControl implements OnFinished {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void updateRemoteControlClientMetadata(int genId, int key, long value) {
|
||||||
|
sendMsg(mEventHandler, MSG_RCC_UPDATE_METADATA_LONG, SENDMSG_QUEUE,
|
||||||
|
genId /* arg1 */, key /* arg2 */, Long.valueOf(value) /* obj */, 0 /* delay */);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onUpdateRemoteControlClientMetadataLong(int genId, int key, long value) {
|
||||||
|
if(DEBUG_RC) Log.d(TAG, "onUpdateRemoteControlClientMetadataLong(genId=" + genId +
|
||||||
|
", what=" + key + ",val=" + value + ")");
|
||||||
|
synchronized(mRCStack) {
|
||||||
|
synchronized(mCurrentRcLock) {
|
||||||
|
if ((mCurrentRcClient != null) && (mCurrentRcClientGen == genId)) {
|
||||||
|
try {
|
||||||
|
switch (key) {
|
||||||
|
case RemoteControlClient.MetadataEditor.LONG_KEY_RATING_BY_USER:
|
||||||
|
mCurrentRcClient.updateMetadata(genId, key, value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.e(TAG, "unhandled metadata key " + key + " update for RCC "
|
||||||
|
+ genId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Current valid remote client is dead", e);
|
||||||
|
mCurrentRcClient = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void setPlaybackInfoForRcc(int rccId, int what, int value) {
|
protected void setPlaybackInfoForRcc(int rccId, int what, int value) {
|
||||||
sendMsg(mEventHandler, MSG_RCC_NEW_PLAYBACK_INFO, SENDMSG_QUEUE,
|
sendMsg(mEventHandler, MSG_RCC_NEW_PLAYBACK_INFO, SENDMSG_QUEUE,
|
||||||
rccId /* arg1 */, what /* arg2 */, Integer.valueOf(value) /* obj */, 0 /* delay */);
|
rccId /* arg1 */, what /* arg2 */, Integer.valueOf(value) /* obj */, 0 /* delay */);
|
||||||
|
|||||||
@@ -293,6 +293,18 @@ public class RemoteControlClient
|
|||||||
* @see #setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener)
|
* @see #setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener)
|
||||||
*/
|
*/
|
||||||
public final static int FLAG_KEY_MEDIA_POSITION_UPDATE = 1 << 8;
|
public final static int FLAG_KEY_MEDIA_POSITION_UPDATE = 1 << 8;
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
* Flag indicating a RemoteControlClient supports ratings.
|
||||||
|
* This flag must be set in order for components that display the RemoteControlClient
|
||||||
|
* information, to display ratings information, and, if ratings are declared editable
|
||||||
|
* (by calling {@link MetadataEditor#addEditableKey(int)} with the
|
||||||
|
* {@link MetadataEditor#LONG_KEY_RATING_BY_USER} key), it will enable the user to rate
|
||||||
|
* the media.
|
||||||
|
* @see #setTransportControlFlags(int)
|
||||||
|
*/
|
||||||
|
public final static int FLAG_KEY_MEDIA_RATING = 1 << 9;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
@@ -389,7 +401,10 @@ public class RemoteControlClient
|
|||||||
private static final int[] METADATA_KEYS_TYPE_LONG = {
|
private static final int[] METADATA_KEYS_TYPE_LONG = {
|
||||||
MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER,
|
MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER,
|
||||||
MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER,
|
MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER,
|
||||||
MediaMetadataRetriever.METADATA_KEY_DURATION };
|
MediaMetadataRetriever.METADATA_KEY_DURATION,
|
||||||
|
MetadataEditor.LONG_KEY_RATING_TYPE,
|
||||||
|
MetadataEditor.LONG_KEY_RATING_BY_OTHERS,
|
||||||
|
MetadataEditor.LONG_KEY_RATING_BY_USER};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to modify metadata in a {@link RemoteControlClient} object.
|
* Class used to modify metadata in a {@link RemoteControlClient} object.
|
||||||
@@ -400,6 +415,10 @@ public class RemoteControlClient
|
|||||||
* instance of the MetadataEditor.
|
* instance of the MetadataEditor.
|
||||||
*/
|
*/
|
||||||
public class MetadataEditor {
|
public class MetadataEditor {
|
||||||
|
/**
|
||||||
|
* Mask of editable keys.
|
||||||
|
*/
|
||||||
|
private long mEditableKeys;
|
||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@@ -431,6 +450,78 @@ public class RemoteControlClient
|
|||||||
* The metadata key for the content artwork / album art.
|
* The metadata key for the content artwork / album art.
|
||||||
*/
|
*/
|
||||||
public final static int BITMAP_KEY_ARTWORK = 100;
|
public final static int BITMAP_KEY_ARTWORK = 100;
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
* The metadata key qualifying the content rating.
|
||||||
|
* The value associated with this key may be: {@link #RATING_HEART},
|
||||||
|
* {@link #RATING_THUMB_UP_DOWN}, or a non-null positive integer expressing a maximum
|
||||||
|
* number of "stars" for the rating, for which a typical value is 3 or 5.
|
||||||
|
*/
|
||||||
|
public final static int LONG_KEY_RATING_TYPE = 101;
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
* The metadata key for the content's average rating, not the user's rating.
|
||||||
|
* The value associated with this key may be: an integer value between 0 and 100,
|
||||||
|
* or {@link #RATING_NOT_RATED} to express that no average rating is available.
|
||||||
|
* <p></p>
|
||||||
|
* Note that a rating value up to 100 is not incompatible with a rating type using up
|
||||||
|
* to 5 stars for instance, as the average may be an non-integer number of stars.
|
||||||
|
* <p></p>
|
||||||
|
* When the rating type is:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link #RATING_HEART}, a rating of 50 to 100 means "heart selected",</li>
|
||||||
|
* <li>{@link #RATING_THUMB_UP_DOWN}, a rating of 0 to 49 means "thumb down", 50 means
|
||||||
|
* both "thumb up" and "thumb down" selected, 51 to 100 means "thumb up"</li>
|
||||||
|
* <li>a non-null positive integer, the rating value is mapped to the number of stars, e.g.
|
||||||
|
* with a maximum of 5 stars, a rating of 21 to 40 maps to 2 stars.</li>
|
||||||
|
* </ul>
|
||||||
|
* @see #LONG_KEY_RATING_BY_USER
|
||||||
|
*/
|
||||||
|
public final static int LONG_KEY_RATING_BY_OTHERS = 102;
|
||||||
|
|
||||||
|
// editable keys
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* Editable key mask
|
||||||
|
*/
|
||||||
|
public final static int KEY_EDITABLE_MASK = 0x1FFFFFFF;
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
* The metadata key for the content's rating by the user.
|
||||||
|
* The value associated with this key may be: an integer value between 0 and 100,
|
||||||
|
* or {@link #RATING_NOT_RATED} to express that the user hasn't rated this content.
|
||||||
|
* Rules for the interpretation of the rating value according to the rating style are
|
||||||
|
* the same as for {@link #LONG_KEY_RATING_BY_OTHERS}
|
||||||
|
*/
|
||||||
|
public final static int LONG_KEY_RATING_BY_USER = 0x10000001;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
* A rating style with a single degree of rating, "heart" vs "no heart". Can be used to
|
||||||
|
* indicate the content referred to is a favorite (or not).
|
||||||
|
* @see #LONG_KEY_RATING_TYPE
|
||||||
|
*/
|
||||||
|
public final static long RATING_HEART = -1;
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
* A rating style for "thumb up" vs "thumb down".
|
||||||
|
* @see #LONG_KEY_RATING_TYPE
|
||||||
|
*/
|
||||||
|
public final static long RATING_THUMB_UP_DOWN = -2;
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
* A rating value indicating no rating is available.
|
||||||
|
* @see #LONG_KEY_RATING_BY_OTHERS
|
||||||
|
* @see #LONG_KEY_RATING_BY_USER
|
||||||
|
*/
|
||||||
|
public final static long RATING_NOT_RATED = -101;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
* TODO(jmtrivi) have lockscreen and music move to the new key name
|
* TODO(jmtrivi) have lockscreen and music move to the new key name
|
||||||
@@ -529,6 +620,7 @@ public class RemoteControlClient
|
|||||||
* Clears all the metadata that has been set since the MetadataEditor instance was
|
* Clears all the metadata that has been set since the MetadataEditor instance was
|
||||||
* created with {@link RemoteControlClient#editMetadata(boolean)}.
|
* created with {@link RemoteControlClient#editMetadata(boolean)}.
|
||||||
*/
|
*/
|
||||||
|
// TODO add in javadoc that this doesn't call clearEditableKeys()
|
||||||
public synchronized void clear() {
|
public synchronized void clear() {
|
||||||
if (mApplied) {
|
if (mApplied) {
|
||||||
Log.e(TAG, "Can't clear a previously applied MetadataEditor");
|
Log.e(TAG, "Can't clear a previously applied MetadataEditor");
|
||||||
@@ -538,6 +630,40 @@ public class RemoteControlClient
|
|||||||
mEditorArtwork = null;
|
mEditorArtwork = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
*/
|
||||||
|
public synchronized void addEditableKey(int key) {
|
||||||
|
if (mApplied) {
|
||||||
|
Log.e(TAG, "Can't change editable keys of a previously applied MetadataEditor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// only one editable key at the moment, so we're not wasting memory on an array
|
||||||
|
// of editable keys to check the validity of the key, just hardcode the supported key.
|
||||||
|
if (key == MetadataEditor.LONG_KEY_RATING_BY_USER) {
|
||||||
|
mEditableKeys |= (MetadataEditor.KEY_EDITABLE_MASK & key);
|
||||||
|
mMetadataChanged = true;
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Metadata key " + key + " cannot be edited");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
*/
|
||||||
|
public synchronized void clearEditableKeys() {
|
||||||
|
if (mApplied) {
|
||||||
|
Log.e(TAG, "Can't clear editable keys of a previously applied MetadataEditor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mEditableKeys != 0) {
|
||||||
|
mEditableKeys = 0;
|
||||||
|
mMetadataChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Associates all the metadata that has been set since the MetadataEditor instance was
|
* Associates all the metadata that has been set since the MetadataEditor instance was
|
||||||
* created with {@link RemoteControlClient#editMetadata(boolean)}, or since
|
* created with {@link RemoteControlClient#editMetadata(boolean)}, or since
|
||||||
@@ -552,6 +678,8 @@ public class RemoteControlClient
|
|||||||
synchronized(mCacheLock) {
|
synchronized(mCacheLock) {
|
||||||
// assign the edited data
|
// assign the edited data
|
||||||
mMetadata = new Bundle(mEditorMetadata);
|
mMetadata = new Bundle(mEditorMetadata);
|
||||||
|
// add the information about editable keys
|
||||||
|
mMetadata.putLong(String.valueOf(KEY_EDITABLE_MASK), mEditableKeys);
|
||||||
if ((mOriginalArtwork != null) && (!mOriginalArtwork.equals(mEditorArtwork))) {
|
if ((mOriginalArtwork != null) && (!mOriginalArtwork.equals(mEditorArtwork))) {
|
||||||
mOriginalArtwork.recycle();
|
mOriginalArtwork.recycle();
|
||||||
}
|
}
|
||||||
@@ -585,6 +713,7 @@ public class RemoteControlClient
|
|||||||
editor.mEditorArtwork = null;
|
editor.mEditorArtwork = null;
|
||||||
editor.mMetadataChanged = true;
|
editor.mMetadataChanged = true;
|
||||||
editor.mArtworkChanged = true;
|
editor.mArtworkChanged = true;
|
||||||
|
editor.mEditableKeys = 0;
|
||||||
} else {
|
} else {
|
||||||
editor.mEditorMetadata = new Bundle(mMetadata);
|
editor.mEditorMetadata = new Bundle(mMetadata);
|
||||||
editor.mEditorArtwork = mOriginalArtwork;
|
editor.mEditorArtwork = mOriginalArtwork;
|
||||||
@@ -751,6 +880,45 @@ public class RemoteControlClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
* TODO ADD DESCRIPTION
|
||||||
|
*/
|
||||||
|
public interface OnMetadataUpdateListener {
|
||||||
|
/**
|
||||||
|
* TODO ADD DESCRIPTION
|
||||||
|
* @param key
|
||||||
|
* @param newValue
|
||||||
|
*/
|
||||||
|
void onMetadataUpdateLong(int key, long newValue);
|
||||||
|
/**
|
||||||
|
* TODO ADD DESCRIPTION
|
||||||
|
* @param key
|
||||||
|
* @param newValue
|
||||||
|
*/
|
||||||
|
void onMetadataUpdateString(int key, String newValue);
|
||||||
|
/**
|
||||||
|
* TODO ADD DESCRIPTION
|
||||||
|
* @param key
|
||||||
|
* @param newValue
|
||||||
|
*/
|
||||||
|
void onMetadataUpdateBitmap(int key, Bitmap newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* CANDIDATE FOR PUBLIC API
|
||||||
|
* TODO ADD DESCRIPTION
|
||||||
|
* @param l
|
||||||
|
*/
|
||||||
|
public void setMetadataUpdateListener(OnMetadataUpdateListener l) {
|
||||||
|
synchronized(mCacheLock) {
|
||||||
|
mMetadataUpdateListener = l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface definition for a callback to be invoked when the media playback position is
|
* Interface definition for a callback to be invoked when the media playback position is
|
||||||
* requested to be updated.
|
* requested to be updated.
|
||||||
@@ -1022,6 +1190,11 @@ public class RemoteControlClient
|
|||||||
* Provider registered by user of RemoteControlClient to provide the current playback position.
|
* Provider registered by user of RemoteControlClient to provide the current playback position.
|
||||||
*/
|
*/
|
||||||
private OnGetPlaybackPositionListener mPositionProvider;
|
private OnGetPlaybackPositionListener mPositionProvider;
|
||||||
|
/**
|
||||||
|
* Listener registered by user of RemoteControlClient to receive edit changes to metadata
|
||||||
|
* it exposes.
|
||||||
|
*/
|
||||||
|
private OnMetadataUpdateListener mMetadataUpdateListener;
|
||||||
/**
|
/**
|
||||||
* The current remote control client generation ID across the system, as known by this object
|
* The current remote control client generation ID across the system, as known by this object
|
||||||
*/
|
*/
|
||||||
@@ -1163,6 +1336,15 @@ public class RemoteControlClient
|
|||||||
new Long(timeMs)));
|
new Long(timeMs)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateMetadata(int generationId, int key, long value) {
|
||||||
|
// only post messages, we can't block here
|
||||||
|
if (mEventHandler != null) {
|
||||||
|
mEventHandler.sendMessage(mEventHandler.obtainMessage(
|
||||||
|
MSG_UPDATE_METADATA_LONG, generationId /* arg1 */, key /* arg2*/,
|
||||||
|
new Long(value)));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1206,6 +1388,7 @@ public class RemoteControlClient
|
|||||||
private final static int MSG_SEEK_TO = 10;
|
private final static int MSG_SEEK_TO = 10;
|
||||||
private final static int MSG_POSITION_DRIFT_CHECK = 11;
|
private final static int MSG_POSITION_DRIFT_CHECK = 11;
|
||||||
private final static int MSG_DISPLAY_WANTS_POS_SYNC = 12;
|
private final static int MSG_DISPLAY_WANTS_POS_SYNC = 12;
|
||||||
|
private final static int MSG_UPDATE_METADATA_LONG = 13;
|
||||||
|
|
||||||
private class EventHandler extends Handler {
|
private class EventHandler extends Handler {
|
||||||
public EventHandler(RemoteControlClient rcc, Looper looper) {
|
public EventHandler(RemoteControlClient rcc, Looper looper) {
|
||||||
@@ -1259,6 +1442,9 @@ public class RemoteControlClient
|
|||||||
case MSG_DISPLAY_WANTS_POS_SYNC:
|
case MSG_DISPLAY_WANTS_POS_SYNC:
|
||||||
onDisplayWantsSync((IRemoteControlDisplay)msg.obj, msg.arg1 == 1);
|
onDisplayWantsSync((IRemoteControlDisplay)msg.obj, msg.arg1 == 1);
|
||||||
break;
|
break;
|
||||||
|
case MSG_UPDATE_METADATA_LONG:
|
||||||
|
onUpdateMetadata(msg.arg1, msg.arg2, ((Long)msg.obj).longValue());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Log.e(TAG, "Unknown event " + msg.what + " in RemoteControlClient handler");
|
Log.e(TAG, "Unknown event " + msg.what + " in RemoteControlClient handler");
|
||||||
}
|
}
|
||||||
@@ -1538,6 +1724,14 @@ public class RemoteControlClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onUpdateMetadata(int generationId, int key, long value) {
|
||||||
|
synchronized (mCacheLock) {
|
||||||
|
if ((mCurrentClientGenId == generationId) && (mMetadataUpdateListener != null)) {
|
||||||
|
mMetadataUpdateListener.onMetadataUpdateLong(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================
|
//===========================================================
|
||||||
// Internal utilities
|
// Internal utilities
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user