TransportMediator: handle playback position.
Update interaction with media controller to report playback
position and handle requests to set the position. Also
update api to use longs for position everywhere.
Change-Id: Ia960cc0443b07b70503d2e08d4943fd5102b809d
diff --git a/v4/java/android/support/v4/media/TransportController.java b/v4/java/android/support/v4/media/TransportController.java
index fdbb3f8..b92a4a1 100644
--- a/v4/java/android/support/v4/media/TransportController.java
+++ b/v4/java/android/support/v4/media/TransportController.java
@@ -52,18 +52,18 @@
/**
* Retrieve the total duration of the media stream, in milliseconds.
*/
- public abstract int getDuration();
+ public abstract long getDuration();
/**
* Retrieve the current playback location in the media stream, in milliseconds.
*/
- public abstract int getCurrentPosition();
+ public abstract long getCurrentPosition();
/**
* Move to a new location in the media stream.
* @param pos Position to move to, in milliseconds.
*/
- public abstract void seekTo(int pos);
+ public abstract void seekTo(long pos);
/**
* Return whether the player is currently playing its stream.
diff --git a/v4/java/android/support/v4/media/TransportMediator.java b/v4/java/android/support/v4/media/TransportMediator.java
index 8ea16a9..93706b9 100644
--- a/v4/java/android/support/v4/media/TransportMediator.java
+++ b/v4/java/android/support/v4/media/TransportMediator.java
@@ -51,11 +51,11 @@
final AudioManager mAudioManager;
final View mView;
final Object mDispatcherState;
- final TransportControllerJellybeanMR2 mController;
+ final TransportMediatorJellybeanMR2 mController;
final ArrayList<TransportStateListener> mListeners
= new ArrayList<TransportStateListener>();
- final TransportControllerJellybeanMR2.TransportCallback mTransportKeyCallback
- = new TransportControllerJellybeanMR2.TransportCallback() {
+ final TransportMediatorCallback mTransportKeyCallback
+ = new TransportMediatorCallback() {
@Override
public void handleKey(KeyEvent key) {
key.dispatch(mKeyEventCallback);
@@ -64,6 +64,16 @@
public void handleAudioFocusChange(int focusChange) {
mCallbacks.onAudioFocusChange(focusChange);
}
+
+ @Override
+ public long getPlaybackPosition() {
+ return mCallbacks.onGetCurrentPosition();
+ }
+
+ @Override
+ public void playbackPositionUpdate(long newPositionMs) {
+ mCallbacks.onSeekTo(newPositionMs);
+ }
};
/** Synonym for {@link KeyEvent#KEYCODE_MEDIA_PLAY KeyEvent.KEYCODE_MEDIA_PLAY} */
@@ -153,7 +163,7 @@
mView = activity != null ? activity.getWindow().getDecorView() : view;
mDispatcherState = KeyEventCompat.getKeyDispatcherState(mView);
if (Build.VERSION.SDK_INT >= 18 || Build.VERSION.CODENAME.equals("JellyBeanMR2")) {
- mController = new TransportControllerJellybeanMR2(mContext, mAudioManager,
+ mController = new TransportMediatorJellybeanMR2(mContext, mAudioManager,
mView, mTransportKeyCallback);
} else {
mController = null;
@@ -168,6 +178,13 @@
* {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}. You should always check for
* null here and not do anything with the RemoteControlClient if none is given; this
* way you don't need to worry about the current platform API version.
+ *
+ * <p>Note that this class takes possession of the
+ * {@link android.media.RemoteControlClient.OnGetPlaybackPositionListener} and
+ * {@link android.media.RemoteControlClient.OnPlaybackPositionUpdateListener} callbacks;
+ * you will interact with these through
+ * {@link TransportPerformer#onGetCurrentPosition() TransportPerformer.onGetCurrentPosition} and
+ * {@link TransportPerformer#onSeekTo TransportPerformer.onSeekTo}, respectively.</p>
*/
public Object getRemoteControlClient() {
return mController != null ? mController.getRemoteControlClient() : null;
@@ -221,6 +238,7 @@
private void pushControllerState() {
if (mController != null) {
mController.refreshState(mCallbacks.onIsPlaying(),
+ mCallbacks.onGetCurrentPosition(),
mCallbacks.onGetTransportControlFlags());
}
}
@@ -274,17 +292,17 @@
}
@Override
- public int getDuration() {
+ public long getDuration() {
return mCallbacks.onGetDuration();
}
@Override
- public int getCurrentPosition() {
+ public long getCurrentPosition() {
return mCallbacks.onGetCurrentPosition();
}
@Override
- public void seekTo(int pos) {
+ public void seekTo(long pos) {
mCallbacks.onSeekTo(pos);
}
diff --git a/v4/java/android/support/v4/media/TransportPerformer.java b/v4/java/android/support/v4/media/TransportPerformer.java
index 98bbbaa..2d3afc9 100644
--- a/v4/java/android/support/v4/media/TransportPerformer.java
+++ b/v4/java/android/support/v4/media/TransportPerformer.java
@@ -48,18 +48,18 @@
/**
* Request to return the duration of the current media, in milliseconds.
*/
- public abstract int onGetDuration();
+ public abstract long onGetDuration();
/**
* Request to return the current playback position, in milliseconds.
*/
- public abstract int onGetCurrentPosition();
+ public abstract long onGetCurrentPosition();
/**
* Request to move the current playback position.
* @param pos New position to move to, in milliseconds.
*/
- public abstract void onSeekTo(int pos);
+ public abstract void onSeekTo(long pos);
/**
* Request to find out whether the player is currently playing its media.
diff --git a/v4/jellybean-mr2/android/support/v4/media/TransportMediatorCallback.java b/v4/jellybean-mr2/android/support/v4/media/TransportMediatorCallback.java
new file mode 100644
index 0000000..aaed620
--- /dev/null
+++ b/v4/jellybean-mr2/android/support/v4/media/TransportMediatorCallback.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 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.support.v4.media;
+
+import android.view.KeyEvent;
+
+public interface TransportMediatorCallback {
+ public void handleKey(KeyEvent key);
+ public void handleAudioFocusChange(int focusChange);
+ public long getPlaybackPosition();
+ public void playbackPositionUpdate(long newPositionMs);
+}
diff --git a/v4/jellybean-mr2/android/support/v4/media/TransportControllerJellybeanMR2.java b/v4/jellybean-mr2/android/support/v4/media/TransportMediatorJellybeanMR2.java
similarity index 87%
rename from v4/jellybean-mr2/android/support/v4/media/TransportControllerJellybeanMR2.java
rename to v4/jellybean-mr2/android/support/v4/media/TransportMediatorJellybeanMR2.java
index fa63005..89bed33 100644
--- a/v4/jellybean-mr2/android/support/v4/media/TransportControllerJellybeanMR2.java
+++ b/v4/jellybean-mr2/android/support/v4/media/TransportMediatorJellybeanMR2.java
@@ -23,19 +23,18 @@
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.RemoteControlClient;
-import android.os.SystemClock;
import android.util.Log;
-import android.view.InputDevice;
-import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewTreeObserver;
-public class TransportControllerJellybeanMR2 {
+public class TransportMediatorJellybeanMR2
+ implements RemoteControlClient.OnGetPlaybackPositionListener,
+ RemoteControlClient.OnPlaybackPositionUpdateListener {
final Context mContext;
final AudioManager mAudioManager;
final View mTargetView;
- final TransportCallback mTransportCallback;
+ final TransportMediatorCallback mTransportCallback;
final String mReceiverAction;
final IntentFilter mReceiverFilter;
final Intent mIntent;
@@ -83,13 +82,8 @@
int mPlayState = 0;
boolean mAudioFocused;
- public interface TransportCallback {
- public void handleKey(KeyEvent key);
- public void handleAudioFocusChange(int focusChange);
- }
-
- public TransportControllerJellybeanMR2(Context context, AudioManager audioManager,
- View view, TransportCallback transportCallback) {
+ public TransportMediatorJellybeanMR2(Context context, AudioManager audioManager,
+ View view, TransportMediatorCallback transportCallback) {
mContext = context;
mAudioManager = audioManager;
mTargetView = view;
@@ -118,6 +112,8 @@
mPendingIntent = PendingIntent.getBroadcast(mContext, 0, mIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
mRemoteControl = new RemoteControlClient(mPendingIntent);
+ mRemoteControl.setOnGetPlaybackPositionListener(this);
+ mRemoteControl.setPlaybackPositionUpdateListener(this);
}
void gainFocus() {
@@ -149,10 +145,20 @@
}
}
- public void refreshState(boolean playing, int transportControls) {
+ @Override
+ public long onGetPlaybackPosition() {
+ return mTransportCallback.getPlaybackPosition();
+ }
+
+ @Override
+ public void onPlaybackPositionUpdate(long newPositionMs) {
+ mTransportCallback.playbackPositionUpdate(newPositionMs);
+ }
+
+ public void refreshState(boolean playing, long position, int transportControls) {
if (mRemoteControl != null) {
mRemoteControl.setPlaybackState(playing ? RemoteControlClient.PLAYSTATE_PLAYING
- : RemoteControlClient.PLAYSTATE_STOPPED);
+ : RemoteControlClient.PLAYSTATE_STOPPED, position, playing ? 1 : 0);
mRemoteControl.setTransportControlFlags(transportControls);
}
}