am bc43b4c2
: RemoteControlClient can report current position, speed
* commit 'bc43b4c2f24fd03c0d0546895c97918c1736d9fb': RemoteControlClient can report current position, speed
This commit is contained in:
@ -143,7 +143,8 @@ public class TransportControlView extends FrameLayout implements OnClickListener
|
||||
mLocalHandler = new WeakReference<Handler>(handler);
|
||||
}
|
||||
|
||||
public void setPlaybackState(int generationId, int state, long stateChangeTimeMs) {
|
||||
public void setPlaybackState(int generationId, int state, long stateChangeTimeMs,
|
||||
long currentPosMs, float speed) {
|
||||
Handler handler = mLocalHandler.get();
|
||||
if (handler != null) {
|
||||
handler.obtainMessage(MSG_UPDATE_STATE, generationId, state).sendToTarget();
|
||||
|
@ -166,6 +166,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
|
||||
private static final int MSG_PROMOTE_RCC = 29;
|
||||
private static final int MSG_BROADCAST_BT_CONNECTION_STATE = 30;
|
||||
private static final int MSG_UNLOAD_SOUND_EFFECTS = 31;
|
||||
private static final int MSG_RCC_NEW_PLAYBACK_STATE = 32;
|
||||
|
||||
|
||||
// flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
|
||||
@ -3741,6 +3742,10 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
|
||||
onRegisterVolumeObserverForRcc(msg.arg1 /* rccId */,
|
||||
(IRemoteVolumeObserver)msg.obj /* rvo */);
|
||||
break;
|
||||
case MSG_RCC_NEW_PLAYBACK_STATE:
|
||||
onNewPlaybackStateForRcc(msg.arg1 /* rccId */, msg.arg2 /* state */,
|
||||
(RccPlaybackState)msg.obj /* newState */);
|
||||
break;
|
||||
|
||||
case MSG_SET_RSX_CONNECTION_STATE:
|
||||
onSetRsxConnectionState(msg.arg1/*available*/, msg.arg2/*address*/);
|
||||
@ -5001,6 +5006,59 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
|
||||
*/
|
||||
private boolean mHasRemotePlayback;
|
||||
|
||||
private static class RccPlaybackState {
|
||||
public int mState;
|
||||
public long mPositionMs;
|
||||
public float mSpeed;
|
||||
|
||||
public RccPlaybackState(int state, long positionMs, float speed) {
|
||||
mState = state;
|
||||
mPositionMs = positionMs;
|
||||
mSpeed = speed;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
mState = RemoteControlClient.PLAYSTATE_STOPPED;
|
||||
mPositionMs = RemoteControlClient.PLAYBACK_POSITION_INVALID;
|
||||
mSpeed = RemoteControlClient.PLAYBACK_SPEED_1X;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return stateToString() + ", "
|
||||
+ ((mPositionMs == RemoteControlClient.PLAYBACK_POSITION_INVALID) ?
|
||||
"PLAYBACK_POSITION_INVALID ," : String.valueOf(mPositionMs)) + "ms ,"
|
||||
+ mSpeed + "X";
|
||||
}
|
||||
|
||||
private String stateToString() {
|
||||
switch (mState) {
|
||||
case RemoteControlClient.PLAYSTATE_NONE:
|
||||
return "PLAYSTATE_NONE";
|
||||
case RemoteControlClient.PLAYSTATE_STOPPED:
|
||||
return "PLAYSTATE_STOPPED";
|
||||
case RemoteControlClient.PLAYSTATE_PAUSED:
|
||||
return "PLAYSTATE_PAUSED";
|
||||
case RemoteControlClient.PLAYSTATE_PLAYING:
|
||||
return "PLAYSTATE_PLAYING";
|
||||
case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
|
||||
return "PLAYSTATE_FAST_FORWARDING";
|
||||
case RemoteControlClient.PLAYSTATE_REWINDING:
|
||||
return "PLAYSTATE_REWINDING";
|
||||
case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
|
||||
return "PLAYSTATE_SKIPPING_FORWARDS";
|
||||
case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
|
||||
return "PLAYSTATE_SKIPPING_BACKWARDS";
|
||||
case RemoteControlClient.PLAYSTATE_BUFFERING:
|
||||
return "PLAYSTATE_BUFFERING";
|
||||
case RemoteControlClient.PLAYSTATE_ERROR:
|
||||
return "PLAYSTATE_ERROR";
|
||||
default:
|
||||
return "[invalid playstate]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class RemoteControlStackEntry {
|
||||
public int mRccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
|
||||
/**
|
||||
@ -5029,7 +5087,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
|
||||
public int mPlaybackVolumeMax;
|
||||
public int mPlaybackVolumeHandling;
|
||||
public int mPlaybackStream;
|
||||
public int mPlaybackState;
|
||||
public RccPlaybackState mPlaybackState;
|
||||
public IRemoteVolumeObserver mRemoteVolumeObs;
|
||||
|
||||
public void resetPlaybackInfo() {
|
||||
@ -5038,7 +5096,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
|
||||
mPlaybackVolumeMax = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
|
||||
mPlaybackVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
|
||||
mPlaybackStream = AudioManager.STREAM_MUSIC;
|
||||
mPlaybackState = RemoteControlClient.PLAYSTATE_STOPPED;
|
||||
mPlaybackState.reset();
|
||||
mRemoteVolumeObs = null;
|
||||
}
|
||||
|
||||
@ -6007,21 +6065,6 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
|
||||
case RemoteControlClient.PLAYBACKINFO_USES_STREAM:
|
||||
rcse.mPlaybackStream = value;
|
||||
break;
|
||||
case RemoteControlClient.PLAYBACKINFO_PLAYSTATE:
|
||||
rcse.mPlaybackState = value;
|
||||
synchronized (mMainRemote) {
|
||||
if (rccId == mMainRemote.mRccId) {
|
||||
mMainRemoteIsActive = isPlaystateActive(value);
|
||||
postReevaluateRemote();
|
||||
}
|
||||
}
|
||||
// an RCC moving to a "playing" state should become the media button
|
||||
// event receiver so it can be controlled, without requiring the
|
||||
// app to re-register its receiver
|
||||
if (isPlaystateActive(value)) {
|
||||
postPromoteRcc(rccId);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log.e(TAG, "unhandled key " + key + " for RCC " + rccId);
|
||||
break;
|
||||
@ -6031,7 +6074,45 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
|
||||
}//for
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
// not expected to happen, indicates improper concurrent modification
|
||||
Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
|
||||
Log.e(TAG, "Wrong index mRCStack on onNewPlaybackInfoForRcc, lock error? ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setPlaybackStateForRcc(int rccId, int state, long timeMs, float speed) {
|
||||
sendMsg(mAudioHandler, MSG_RCC_NEW_PLAYBACK_STATE, SENDMSG_QUEUE,
|
||||
rccId /* arg1 */, state /* arg2 */,
|
||||
new RccPlaybackState(state, timeMs, speed) /* obj */, 0 /* delay */);
|
||||
}
|
||||
|
||||
public void onNewPlaybackStateForRcc(int rccId, int state, RccPlaybackState newState) {
|
||||
if(DEBUG_RC) Log.d(TAG, "onNewPlaybackStateForRcc(id=" + rccId + ", state=" + state
|
||||
+ ", time=" + newState.mPositionMs + ", speed=" + newState.mSpeed + ")");
|
||||
synchronized(mRCStack) {
|
||||
// iterating from top of stack as playback information changes are more likely
|
||||
// on entries at the top of the remote control stack
|
||||
try {
|
||||
for (int index = mRCStack.size()-1; index >= 0; index--) {
|
||||
final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
|
||||
if (rcse.mRccId == rccId) {
|
||||
rcse.mPlaybackState = newState;
|
||||
synchronized (mMainRemote) {
|
||||
if (rccId == mMainRemote.mRccId) {
|
||||
mMainRemoteIsActive = isPlaystateActive(state);
|
||||
postReevaluateRemote();
|
||||
}
|
||||
}
|
||||
// an RCC moving to a "playing" state should become the media button
|
||||
// event receiver so it can be controlled, without requiring the
|
||||
// app to re-register its receiver
|
||||
if (isPlaystateActive(state)) {
|
||||
postPromoteRcc(rccId);
|
||||
}
|
||||
}
|
||||
}//for
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
// not expected to happen, indicates improper concurrent modification
|
||||
Log.e(TAG, "Wrong index on mRCStack in onNewPlaybackStateForRcc, lock error? ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6075,7 +6156,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
|
||||
for (int index = mRCStack.size()-1; index >= 0; index--) {
|
||||
final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
|
||||
if ((rcse.mPlaybackType == RemoteControlClient.PLAYBACK_TYPE_REMOTE)
|
||||
&& isPlaystateActive(rcse.mPlaybackState)
|
||||
&& isPlaystateActive(rcse.mPlaybackState.mState)
|
||||
&& (rcse.mPlaybackStream == streamType)) {
|
||||
if (DEBUG_RC) Log.d(TAG, "remote playback active on stream " + streamType
|
||||
+ ", vol =" + rcse.mPlaybackVolume);
|
||||
|
@ -159,6 +159,7 @@ interface IAudioService {
|
||||
oneway void remoteControlDisplayUsesBitmapSize(in IRemoteControlDisplay rcd, int w, int h);
|
||||
|
||||
oneway void setPlaybackInfoForRcc(int rccId, int what, int value);
|
||||
void setPlaybackStateForRcc(int rccId, int state, long timeMs, float speed);
|
||||
int getRemoteStreamMaxVolume();
|
||||
int getRemoteStreamVolume();
|
||||
oneway void registerRemoteVolumeObserverForRcc(int rccId, in IRemoteVolumeObserver rvo);
|
||||
|
@ -40,7 +40,8 @@ oneway interface IRemoteControlDisplay
|
||||
void setCurrentClientId(int clientGeneration, in PendingIntent clientMediaIntent,
|
||||
boolean clearing);
|
||||
|
||||
void setPlaybackState(int generationId, int state, long stateChangeTimeMs);
|
||||
void setPlaybackState(int generationId, int state, long stateChangeTimeMs, long currentPosMs,
|
||||
float speed);
|
||||
|
||||
void setTransportControlFlags(int generationId, int transportControlFlags);
|
||||
|
||||
|
@ -172,6 +172,17 @@ public class RemoteControlClient
|
||||
*/
|
||||
public final static int PLAYBACKINFO_INVALID_VALUE = Integer.MIN_VALUE;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* An unknown or invalid playback position value.
|
||||
*/
|
||||
public final static long PLAYBACK_POSITION_INVALID = -1;
|
||||
/**
|
||||
* @hide
|
||||
* The default playback speed, 1x.
|
||||
*/
|
||||
public final static float PLAYBACK_SPEED_1X = 1.0f;
|
||||
|
||||
//==========================================
|
||||
// Public keys for playback information
|
||||
/**
|
||||
@ -208,15 +219,7 @@ public class RemoteControlClient
|
||||
public final static int PLAYBACKINFO_USES_STREAM = 5;
|
||||
|
||||
//==========================================
|
||||
// Private keys for playback information
|
||||
/**
|
||||
* @hide
|
||||
* Used internally to relay playback state (set by the application with
|
||||
* {@link #setPlaybackState(int)}) to AudioService
|
||||
*/
|
||||
public final static int PLAYBACKINFO_PLAYSTATE = 255;
|
||||
|
||||
|
||||
// Public flags for the supported transport control capabililities
|
||||
/**
|
||||
* Flag indicating a RemoteControlClient makes use of the "previous" media key.
|
||||
*
|
||||
@ -273,6 +276,15 @@ public class RemoteControlClient
|
||||
* @see android.view.KeyEvent#KEYCODE_MEDIA_NEXT
|
||||
*/
|
||||
public final static int FLAG_KEY_MEDIA_NEXT = 1 << 7;
|
||||
/**
|
||||
* @hide
|
||||
* (to be un-hidden and added in javadoc of setTransportControlFlags(int))
|
||||
* Flag indicating a RemoteControlClient can receive changes in the media playback position
|
||||
* through the {@link #OnPlaybackPositionUpdateListener} interface.
|
||||
*
|
||||
* @see #setTransportControlFlags(int)
|
||||
*/
|
||||
public final static int FLAG_KEY_MEDIA_POSITION_UPDATE = 1 << 8;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
@ -588,17 +600,54 @@ public class RemoteControlClient
|
||||
* {@link #PLAYSTATE_ERROR}.
|
||||
*/
|
||||
public void setPlaybackState(int state) {
|
||||
setPlaybackState(state, PLAYBACK_POSITION_INVALID, PLAYBACK_SPEED_1X);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* (to be un-hidden)
|
||||
* Sets the current playback state and the matching media position for the current playback
|
||||
* speed.
|
||||
* @param state The current playback state, 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}.
|
||||
* @param timeInMs a 0 or positive value for the current media position expressed in ms
|
||||
* (same unit as for when sending the media duration, if applicable, with
|
||||
* {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} in the
|
||||
* {@link RemoteControlClient.MetadataEditor}). Negative values imply that position is not
|
||||
* known (e.g. listening to a live stream of a radio) or not applicable (e.g. when state
|
||||
* is {@link #PLAYSTATE_BUFFERING} and nothing had played yet).
|
||||
* @param playbackSpeed a value expressed as a ratio of 1x playback: 1.0f is normal playback,
|
||||
* 2.0f is 2x, 0.5f is half-speed, -2.0f is rewind at 2x speed. 0.0f means nothing is
|
||||
* playing (e.g. when state is {@link #PLAYSTATE_ERROR}).
|
||||
*/
|
||||
public void setPlaybackState(int state, long timeInMs, float playbackSpeed) {
|
||||
synchronized(mCacheLock) {
|
||||
if (mPlaybackState != state) {
|
||||
if (timeInMs != PLAYBACK_POSITION_INVALID) {
|
||||
mPlaybackPositionCapabilities |= MEDIA_POSITION_READABLE;
|
||||
} else {
|
||||
mPlaybackPositionCapabilities &= ~MEDIA_POSITION_READABLE;
|
||||
}
|
||||
if ((mPlaybackState != state) || (mPlaybackPositionMs != timeInMs)
|
||||
|| (mPlaybackSpeed != playbackSpeed)) {
|
||||
// store locally
|
||||
mPlaybackState = state;
|
||||
mPlaybackPositionMs = timeInMs;
|
||||
mPlaybackSpeed = playbackSpeed;
|
||||
// keep track of when the state change occurred
|
||||
mPlaybackStateChangeTimeMs = SystemClock.elapsedRealtime();
|
||||
|
||||
// send to remote control display if conditions are met
|
||||
sendPlaybackState_syncCacheLock();
|
||||
// update AudioService
|
||||
sendAudioServiceNewPlaybackInfo_syncCacheLock(PLAYBACKINFO_PLAYSTATE, state);
|
||||
sendAudioServiceNewPlaybackState_syncCacheLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -625,6 +674,65 @@ public class RemoteControlClient
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* (to be un-hidden)
|
||||
* Interface definition for a callback to be invoked when the media playback position is
|
||||
* requested to be updated.
|
||||
*/
|
||||
public interface OnPlaybackPositionUpdateListener {
|
||||
/**
|
||||
* Called on the listener to notify it that the playback head should be set at the given
|
||||
* position. If the position can be changed from its current value, the implementor of
|
||||
* the interface should also update the playback position using
|
||||
* {@link RemoteControlClient#setPlaybackState(int, long, int)} to reflect the actual new
|
||||
* position being used, regardless of whether it differs from the requested position.
|
||||
* @param newPositionMs the new requested position in the current media, expressed in ms.
|
||||
*/
|
||||
void onPlaybackPositionUpdate(long newPositionMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* (to be un-hidden)
|
||||
* Sets the listener RemoteControlClient calls whenever the media playback position is requested
|
||||
* to be updated.
|
||||
* Notifications will be received in the same thread as the one in which RemoteControlClient
|
||||
* was created.
|
||||
* @param l
|
||||
*/
|
||||
public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener l) {
|
||||
synchronized(mCacheLock) {
|
||||
if ((mPositionUpdateListener == null) && (l != null)) {
|
||||
mPlaybackPositionCapabilities |= MEDIA_POSITION_WRITABLE;
|
||||
// tell RCDs and AudioService this RCC accepts position updates
|
||||
// TODO implement
|
||||
} else if ((mPositionUpdateListener != null) && (l == null)) {
|
||||
mPlaybackPositionCapabilities &= ~MEDIA_POSITION_WRITABLE;
|
||||
// tell RCDs and AudioService this RCC doesn't handle position updates
|
||||
// TODO implement
|
||||
}
|
||||
mPositionUpdateListener = l;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Flag to reflect that the application controlling this RemoteControlClient sends playback
|
||||
* position updates. The playback position being "readable" is considered from the application's
|
||||
* point of view.
|
||||
*/
|
||||
public static int MEDIA_POSITION_READABLE = 1 << 0;
|
||||
/**
|
||||
* @hide
|
||||
* Flag to reflect that the application controlling this RemoteControlClient can receive
|
||||
* playback position updates. The playback position being "writable"
|
||||
* is considered from the application's point of view.
|
||||
*/
|
||||
public static int MEDIA_POSITION_WRITABLE = 1 << 1;
|
||||
|
||||
private int mPlaybackPositionCapabilities = 0;
|
||||
|
||||
/** @hide */
|
||||
public final static int DEFAULT_PLAYBACK_VOLUME_HANDLING = PLAYBACK_VOLUME_VARIABLE;
|
||||
/** @hide */
|
||||
@ -755,6 +863,14 @@ public class RemoteControlClient
|
||||
* Access synchronized on mCacheLock
|
||||
*/
|
||||
private long mPlaybackStateChangeTimeMs = 0;
|
||||
/**
|
||||
* Last playback position in ms reported by the user
|
||||
*/
|
||||
private long mPlaybackPositionMs = PLAYBACK_POSITION_INVALID;
|
||||
/**
|
||||
* Last playback speed reported by the user
|
||||
*/
|
||||
private float mPlaybackSpeed = PLAYBACK_SPEED_1X;
|
||||
/**
|
||||
* Cache for the artwork bitmap.
|
||||
* Access synchronized on mCacheLock
|
||||
@ -774,9 +890,13 @@ public class RemoteControlClient
|
||||
* This is re-initialized in apply() and so cannot be final.
|
||||
*/
|
||||
private Bundle mMetadata = new Bundle();
|
||||
|
||||
/**
|
||||
* The current remote control client generation ID across the system
|
||||
* Listener registered by user of RemoteControlClient to receive requests for playback position
|
||||
* update requests.
|
||||
*/
|
||||
private OnPlaybackPositionUpdateListener mPositionUpdateListener;
|
||||
/**
|
||||
* The current remote control client generation ID across the system, as known by this object
|
||||
*/
|
||||
private int mCurrentClientGenId = -1;
|
||||
/**
|
||||
@ -789,7 +909,8 @@ public class RemoteControlClient
|
||||
|
||||
/**
|
||||
* The media button intent description associated with this remote control client
|
||||
* (can / should include target component for intent handling)
|
||||
* (can / should include target component for intent handling, used when persisting media
|
||||
* button event receiver across reboots).
|
||||
*/
|
||||
private final PendingIntent mRcMediaIntent;
|
||||
|
||||
@ -990,7 +1111,8 @@ public class RemoteControlClient
|
||||
final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next();
|
||||
try {
|
||||
di.mRcDisplay.setPlaybackState(mInternalClientGenId,
|
||||
mPlaybackState, mPlaybackStateChangeTimeMs);
|
||||
mPlaybackState, mPlaybackStateChangeTimeMs, mPlaybackPositionMs,
|
||||
mPlaybackSpeed);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error in setPlaybackState(), dead display " + di.mRcDisplay, e);
|
||||
displayIterator.remove();
|
||||
@ -1109,7 +1231,20 @@ public class RemoteControlClient
|
||||
try {
|
||||
service.setPlaybackInfoForRcc(mRcseId, what, value);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Dead object in sendAudioServiceNewPlaybackInfo_syncCacheLock", e);
|
||||
Log.e(TAG, "Dead object in setPlaybackInfoForRcc", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendAudioServiceNewPlaybackState_syncCacheLock() {
|
||||
if (mRcseId == RCSE_ID_UNREGISTERED) {
|
||||
return;
|
||||
}
|
||||
IAudioService service = getService();
|
||||
try {
|
||||
service.setPlaybackStateForRcc(mRcseId,
|
||||
mPlaybackState, mPlaybackPositionMs, mPlaybackSpeed);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Dead object in setPlaybackStateForRcc", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,8 @@ public class KeyguardTransportControlView extends FrameLayout implements OnClick
|
||||
mLocalHandler = new WeakReference<Handler>(handler);
|
||||
}
|
||||
|
||||
public void setPlaybackState(int generationId, int state, long stateChangeTimeMs) {
|
||||
public void setPlaybackState(int generationId, int state, long stateChangeTimeMs,
|
||||
long currentPosMs, float speed) {
|
||||
Handler handler = mLocalHandler.get();
|
||||
if (handler != null) {
|
||||
handler.obtainMessage(MSG_UPDATE_STATE, generationId, state).sendToTarget();
|
||||
|
@ -200,7 +200,8 @@ public class KeyguardUpdateMonitor {
|
||||
private final IRemoteControlDisplay.Stub mRemoteControlDisplay =
|
||||
new IRemoteControlDisplay.Stub() {
|
||||
|
||||
public void setPlaybackState(int generationId, int state, long stateChangeTimeMs) {
|
||||
public void setPlaybackState(int generationId, int state, long stateChangeTimeMs,
|
||||
long currentPosMs, float speed) {
|
||||
Message msg = mHandler.obtainMessage(MSG_SET_PLAYBACK_STATE,
|
||||
generationId, state, stateChangeTimeMs);
|
||||
mHandler.sendMessage(msg);
|
||||
|
Reference in New Issue
Block a user