Index: chrome/android/java/src/org/chromium/chrome/browser/media/remote/ExpandedControllerActivity.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/ExpandedControllerActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/ExpandedControllerActivity.java |
index 1d7416f28b6a85c8c53ff47ececdf635a3995555..017c3c657b71b98e91e6d6167e72a68b9a752c9d 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/ExpandedControllerActivity.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/ExpandedControllerActivity.java |
@@ -11,6 +11,7 @@ import android.graphics.Color; |
import android.os.Bundle; |
import android.os.Handler; |
import android.support.v4.app.FragmentActivity; |
+import android.support.v4.media.session.PlaybackStateCompat; |
import android.text.TextUtils; |
import android.view.KeyEvent; |
import android.view.View; |
@@ -18,8 +19,6 @@ import android.view.ViewGroup; |
import android.view.Window; |
import android.view.WindowManager; |
import android.widget.ImageView; |
-import android.widget.MediaController; |
-import android.widget.MediaController.MediaPlayerControl; |
import android.widget.TextView; |
import com.google.android.gms.cast.CastMediaControlIntent; |
@@ -27,6 +26,7 @@ import com.google.android.gms.cast.CastMediaControlIntent; |
import org.chromium.chrome.R; |
import org.chromium.chrome.browser.media.remote.RemoteVideoInfo.PlayerState; |
import org.chromium.chrome.browser.metrics.MediaNotificationUma; |
+import org.chromium.third_party.android.media.MediaController; |
/** |
* The activity that's opened by clicking the video flinging (casting) notification. |
@@ -39,48 +39,10 @@ public class ExpandedControllerActivity |
// The alpha value for the poster/placeholder image, an integer between 0 and 256 (opaque). |
private static final int POSTER_IMAGE_ALPHA = 200; |
- // Subclass of {@link android.widget.MediaController} that never hides itself. |
- class AlwaysShownMediaController extends MediaController { |
- public AlwaysShownMediaController(Context context) { |
- super(context); |
- } |
- |
- @Override |
- public void show(int timeout) { |
- // Never auto-hide the controls. |
- super.show(0); |
- } |
- |
- @Override |
- public boolean dispatchKeyEvent(KeyEvent event) { |
- int keyCode = event.getKeyCode(); |
- // MediaController hides the controls when back or menu are pressed. |
- // Close the activity on back and ignore menu. |
- if (keyCode == KeyEvent.KEYCODE_BACK) { |
- finish(); |
- return true; |
- } else if (keyCode == KeyEvent.KEYCODE_MENU) { |
- return true; |
- } |
- return super.dispatchKeyEvent(event); |
- } |
- |
- @Override |
- public void hide() { |
- // Don't allow the controls to hide until explicitly asked to do so from the host |
- // activity. |
- } |
- |
- /** |
- * Actually hides the controls which prevents some window leaks. |
- */ |
- public void cleanup() { |
- super.hide(); |
- } |
- }; |
- |
private Handler mHandler; |
- private AlwaysShownMediaController mMediaController; |
+ // We don't use the standard android.media.MediaController, but a custom one. |
+ // See the class itself for details. |
+ private MediaController mMediaController; |
private FullscreenMediaRouteButton mMediaRouteButton; |
private MediaRouteController mMediaRouteController; |
private RemoteVideoInfo mVideoInfo; |
@@ -89,85 +51,74 @@ public class ExpandedControllerActivity |
/** |
* Handle actions from on-screen media controls. |
*/ |
- private MediaPlayerControl mMediaPlayerControl = new MediaPlayerControl() { |
- @Override |
- public boolean canPause() { |
- return true; |
- } |
- |
- @Override |
- public boolean canSeekBackward() { |
- return getDuration() > 0 && getCurrentPosition() > 0; |
- } |
- |
+ private MediaController.Delegate mControllerDelegate = new MediaController.Delegate() { |
@Override |
- public boolean canSeekForward() { |
- return getDuration() > 0 && getCurrentPosition() < getDuration(); |
- } |
- |
- @Override |
- public int getAudioSessionId() { |
- // TODO(avayvod): not sure 0 is a valid value to return. |
- return 0; |
+ public void play() { |
+ if (mMediaRouteController == null) return; |
+ mMediaRouteController.resume(); |
+ RecordCastAction.recordFullscreenControlsAction( |
+ RecordCastAction.FULLSCREEN_CONTROLS_RESUME, |
+ mMediaRouteController.getMediaStateListener() != null); |
} |
@Override |
- public int getBufferPercentage() { |
- int duration = getDuration(); |
- if (duration == 0) return 0; |
- return (getCurrentPosition() * 100) / duration; |
+ public void pause() { |
+ if (mMediaRouteController == null) return; |
+ mMediaRouteController.pause(); |
+ RecordCastAction.recordFullscreenControlsAction( |
+ RecordCastAction.FULLSCREEN_CONTROLS_PAUSE, |
+ mMediaRouteController.getMediaStateListener() != null); |
} |
@Override |
- public int getCurrentPosition() { |
+ public long getDuration() { |
if (mMediaRouteController == null) return 0; |
- return (int) mMediaRouteController.getPosition(); |
+ return mMediaRouteController.getDuration(); |
} |
@Override |
- public int getDuration() { |
+ public long getPosition() { |
if (mMediaRouteController == null) return 0; |
- return (int) mMediaRouteController.getDuration(); |
+ return mMediaRouteController.getPosition(); |
} |
@Override |
- public boolean isPlaying() { |
- if (mMediaRouteController == null) return false; |
- return mMediaRouteController.isPlaying(); |
- } |
- |
- @Override |
- public void pause() { |
+ public void seekTo(long pos) { |
if (mMediaRouteController == null) return; |
- mMediaRouteController.pause(); |
+ mMediaRouteController.seekTo(pos); |
RecordCastAction.recordFullscreenControlsAction( |
- RecordCastAction.FULLSCREEN_CONTROLS_PAUSE, |
+ RecordCastAction.FULLSCREEN_CONTROLS_SEEK, |
mMediaRouteController.getMediaStateListener() != null); |
} |
@Override |
- public void start() { |
- if (mMediaRouteController == null) return; |
- mMediaRouteController.resume(); |
- RecordCastAction.recordFullscreenControlsAction( |
- RecordCastAction.FULLSCREEN_CONTROLS_RESUME, |
- mMediaRouteController.getMediaStateListener() != null); |
+ public boolean isPlaying() { |
+ if (mMediaRouteController == null) return false; |
+ return mMediaRouteController.isPlaying(); |
} |
@Override |
- public void seekTo(int pos) { |
- if (mMediaRouteController == null) return; |
- mMediaRouteController.seekTo(pos); |
- RecordCastAction.recordFullscreenControlsAction( |
- RecordCastAction.FULLSCREEN_CONTROLS_SEEK, |
- mMediaRouteController.getMediaStateListener() != null); |
+ public long getActionFlags() { |
+ long flags = |
+ PlaybackStateCompat.ACTION_REWIND | PlaybackStateCompat.ACTION_FAST_FORWARD; |
+ if (mMediaRouteController != null && mMediaRouteController.isPlaying()) { |
+ flags |= PlaybackStateCompat.ACTION_PAUSE; |
+ } else { |
+ flags |= PlaybackStateCompat.ACTION_PLAY; |
+ } |
+ return flags; |
} |
}; |
- private Runnable mControlsUpdater = new Runnable() { |
+ private Runnable mProgressUpdater = new Runnable() { |
@Override |
public void run() { |
- mMediaController.show(); |
+ if (mMediaRouteController.isPlaying()) { |
+ mMediaController.updateProgress(); |
+ mHandler.postDelayed(this, PROGRESS_UPDATE_PERIOD_IN_MS); |
+ } else { |
+ mHandler.removeCallbacks(this); |
+ } |
} |
}; |
@@ -201,10 +152,8 @@ public class ExpandedControllerActivity |
mMediaRouteController.addUiListener(this); |
// Create and initialize the media control UI. |
- mMediaController = new AlwaysShownMediaController(this); |
- mMediaController.setEnabled(true); |
- mMediaController.setMediaPlayer(mMediaPlayerControl); |
- mMediaController.setAnchorView(rootView); |
+ mMediaController = (MediaController) findViewById(R.id.cast_media_controller); |
+ mMediaController.setDelegate(mControllerDelegate); |
View button = getLayoutInflater().inflate(R.layout.cast_controller_media_route_button, |
rootView, false); |
@@ -219,13 +168,16 @@ public class ExpandedControllerActivity |
} |
// Initialize the video info. |
- mVideoInfo = new RemoteVideoInfo(null, 0, RemoteVideoInfo.PlayerState.STOPPED, 0, null); |
+ setVideoInfo(new RemoteVideoInfo(null, 0, RemoteVideoInfo.PlayerState.STOPPED, 0, null)); |
+ |
+ mMediaController.refresh(); |
+ |
+ scheduleProgressUpdate(); |
} |
@Override |
protected void onResume() { |
super.onResume(); |
- |
if (mVideoInfo.state == PlayerState.FINISHED) finish(); |
if (mMediaRouteController == null) return; |
@@ -241,9 +193,6 @@ public class ExpandedControllerActivity |
Bitmap posterBitmap = mMediaRouteController.getPoster(); |
if (posterBitmap != null) iv.setImageBitmap(posterBitmap); |
iv.setImageAlpha(POSTER_IMAGE_ALPHA); |
- |
- // Can't show the media controller until attached to window. |
- scheduleControlsUpdate(); |
} |
@Override |
@@ -264,12 +213,10 @@ public class ExpandedControllerActivity |
} |
private void cleanup() { |
- if (mHandler != null) mHandler.removeCallbacks(mControlsUpdater); |
+ if (mHandler != null) mHandler.removeCallbacks(mProgressUpdater); |
if (mMediaRouteController != null) mMediaRouteController.removeUiListener(this); |
mMediaRouteController = null; |
- mControlsUpdater = null; |
- mMediaController.cleanup(); |
- mMediaController = null; |
+ mProgressUpdater = null; |
} |
/** |
@@ -279,12 +226,14 @@ public class ExpandedControllerActivity |
if ((mVideoInfo == null) ? (videoInfo == null) : mVideoInfo.equals(videoInfo)) return; |
mVideoInfo = videoInfo; |
- updateUi(); |
+ onVideoInfoChanged(); |
} |
- private void scheduleControlsUpdate() { |
- mHandler.removeCallbacks(mControlsUpdater); |
- mHandler.post(mControlsUpdater); |
+ private void scheduleProgressUpdate() { |
+ mHandler.removeCallbacks(mProgressUpdater); |
+ if (mMediaRouteController.isPlaying()) { |
+ mHandler.post(mProgressUpdater); |
+ } |
} |
/** |
@@ -294,6 +243,14 @@ public class ExpandedControllerActivity |
if (TextUtils.equals(mScreenName, screenName)) return; |
mScreenName = screenName; |
+ onScreenNameChanged(); |
+ } |
+ |
+ private void onVideoInfoChanged() { |
+ updateUi(); |
+ } |
+ |
+ private void onScreenNameChanged() { |
updateUi(); |
} |
@@ -308,7 +265,7 @@ public class ExpandedControllerActivity |
TextView castTextView = (TextView) findViewById(R.id.cast_screen_title); |
castTextView.setText(castText); |
- scheduleControlsUpdate(); |
+ mMediaController.refresh(); |
} |
@Override |
@@ -337,7 +294,7 @@ public class ExpandedControllerActivity |
videoInfo.state = newState; |
setVideoInfo(videoInfo); |
- scheduleControlsUpdate(); |
+ scheduleProgressUpdate(); |
if (newState == PlayerState.FINISHED || newState == PlayerState.INVALIDATED) { |
// If we are switching to a finished state, stop the notifications. |