Merge "MediaSession2: Complete transport control commands"
diff --git a/packages/MediaComponents/res/layout/media_controller.xml b/packages/MediaComponents/res/layout/media_controller.xml
index 4d05546..74a8306 100644
--- a/packages/MediaComponents/res/layout/media_controller.xml
+++ b/packages/MediaComponents/res/layout/media_controller.xml
@@ -136,7 +136,13 @@
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:visibility="gone"
- android:orientation="horizontal" >
+ android:orientation="horizontal"
+ android:gravity="center">
+
+ <LinearLayout
+ android:id="@+id/custom_buttons"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
<ImageButton
android:id="@+id/mute"
diff --git a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
index bc370d8..f96ff70 100644
--- a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
@@ -24,11 +24,11 @@
import android.media.update.ViewProvider;
import android.os.Bundle;
import android.util.Log;
-import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
+import android.widget.Button;
import android.widget.ImageButton;
import android.widget.MediaControlView2;
import android.widget.ProgressBar;
@@ -40,6 +40,7 @@
import com.android.media.update.R;
import java.util.Formatter;
+import java.util.List;
import java.util.Locale;
public class MediaControlView2Impl implements MediaControlView2Provider {
@@ -97,6 +98,7 @@
private ImageButton mOverflowButtonRight;
private ViewGroup mExtraControls;
+ private ViewGroup mCustomButtons;
private ImageButton mOverflowButtonLeft;
private ImageButton mMuteButton;
private ImageButton mAspectRationButton;
@@ -305,62 +307,11 @@
}
@Override
- public boolean onKeyDown_impl(int keyCode, KeyEvent event) {
- return mSuperProvider.onKeyDown_impl(keyCode, event);
- }
-
- @Override
public void onFinishInflate_impl() {
mSuperProvider.onFinishInflate_impl();
}
@Override
- public boolean dispatchKeyEvent_impl(KeyEvent event) {
- int keyCode = event.getKeyCode();
- final boolean uniqueDown = event.getRepeatCount() == 0
- && event.getAction() == KeyEvent.ACTION_DOWN;
- if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK
- || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
- || keyCode == KeyEvent.KEYCODE_SPACE) {
- if (uniqueDown) {
- togglePausePlayState();
- mInstance.show(DEFAULT_TIMEOUT_MS);
- if (mPlayPauseButton != null) {
- mPlayPauseButton.requestFocus();
- }
- }
- return true;
- } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) {
- if (uniqueDown && !isPlaying()) {
- togglePausePlayState();
- mInstance.show(DEFAULT_TIMEOUT_MS);
- }
- return true;
- } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP
- || keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) {
- if (uniqueDown && isPlaying()) {
- togglePausePlayState();
- mInstance.show(DEFAULT_TIMEOUT_MS);
- }
- return true;
- } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
- || keyCode == KeyEvent.KEYCODE_VOLUME_UP
- || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE
- || keyCode == KeyEvent.KEYCODE_CAMERA) {
- // don't show the controls for volume adjustment
- return mSuperProvider.dispatchKeyEvent_impl(event);
- } else if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) {
- if (uniqueDown) {
- mInstance.hide();
- }
- return true;
- }
-
- mInstance.show(DEFAULT_TIMEOUT_MS);
- return mSuperProvider.dispatchKeyEvent_impl(event);
- }
-
- @Override
public void setEnabled_impl(boolean enabled) {
if (mPlayPauseButton != null) {
mPlayPauseButton.setEnabled(enabled);
@@ -501,6 +452,7 @@
// TODO: should these buttons be shown as default?
mExtraControls = v.findViewById(R.id.extra_controls);
+ mCustomButtons = v.findViewById(R.id.custom_buttons);
mOverflowButtonLeft = v.findViewById(R.id.overflow_left);
if (mOverflowButtonLeft != null) {
mOverflowButtonLeft.setOnClickListener(mOverflowLeftListener);
@@ -875,6 +827,31 @@
}
mPlaybackActions = newActions;
}
+
+ // Add buttons if custom actions are present.
+ List<PlaybackState.CustomAction> customActions = mPlaybackState.getCustomActions();
+ mCustomButtons.removeAllViews();
+ if (customActions.size() > 0) {
+ for (PlaybackState.CustomAction action : customActions) {
+ ImageButton button = new ImageButton(mInstance.getContext(),
+ null /* AttributeSet */, 0 /* Style */);
+ // TODO: Apply R.style.BottomBarButton to this button using library context.
+ // Refer Constructor with argument (int defStyleRes) of View.java
+ button.setImageResource(action.getIcon());
+ button.setTooltipText(action.getName());
+ final String actionString = action.getAction().toString();
+ button.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // TODO: Currently, we are just sending extras that came from session.
+ // Is it the right behavior?
+ mControls.sendCustomAction(actionString, action.getExtras());
+ mInstance.show(DEFAULT_TIMEOUT_MS);
+ }
+ });
+ mCustomButtons.addView(button);
+ }
+ }
}
@Override
diff --git a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
index 6a75c1a..8cd932d 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
@@ -45,7 +45,6 @@
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
-import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout.LayoutParams;
@@ -78,8 +77,8 @@
private final AudioManager mAudioManager;
private AudioAttributes mAudioAttributes;
private int mAudioFocusType = AudioManager.AUDIOFOCUS_GAIN; // legacy focus gain
- private int mAudioSession;
+ private VideoView2.OnCustomActionListener mOnCustomActionListener;
private VideoView2.OnPreparedListener mOnPreparedListener;
private VideoView2.OnCompletionListener mOnCompletionListener;
private VideoView2.OnErrorListener mOnErrorListener;
@@ -99,6 +98,7 @@
private String mTitle;
private PlaybackState.Builder mStateBuilder;
+ private List<PlaybackState.CustomAction> mCustomActionList;
private int mTargetState = STATE_IDLE;
private int mCurrentState = STATE_IDLE;
private int mCurrentBufferPercentage;
@@ -192,16 +192,6 @@
}
@Override
- public int getAudioSessionId_impl() {
- if (mAudioSession == 0) {
- MediaPlayer foo = new MediaPlayer();
- mAudioSession = foo.getAudioSessionId();
- foo.release();
- }
- return mAudioSession;
- }
-
- @Override
public void showSubtitle_impl() {
// Retrieve all tracks that belong to the current video.
MediaPlayer.TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo();
@@ -232,7 +222,7 @@
@Override
public void setFullScreen_impl(boolean fullScreen) {
if (mOnFullScreenChangedListener != null) {
- mOnFullScreenChangedListener.onFullScreenChanged(fullScreen);
+ mOnFullScreenChangedListener.onFullScreenChanged(mInstance, fullScreen);
}
}
@@ -277,16 +267,16 @@
@Override
public void setVideoPath_impl(String path) {
- mInstance.setVideoURI(Uri.parse(path));
+ mInstance.setVideoUri(Uri.parse(path));
}
@Override
- public void setVideoURI_impl(Uri uri) {
- mInstance.setVideoURI(uri, null);
+ public void setVideoUri_impl(Uri uri) {
+ mInstance.setVideoUri(uri, null);
}
@Override
- public void setVideoURI_impl(Uri uri, Map<String, String> headers) {
+ public void setVideoUri_impl(Uri uri, Map<String, String> headers) {
mSeekWhenPrepared = 0;
openVideo(uri, headers);
}
@@ -317,6 +307,17 @@
}
@Override
+ public void setCustomActions_impl(List<PlaybackState.CustomAction> actionList,
+ VideoView2.OnCustomActionListener listener) {
+ mCustomActionList = actionList;
+ mOnCustomActionListener = listener;
+
+ // Create a new playback builder in order to clear existing the custom actions.
+ mStateBuilder = null;
+ updatePlaybackState();
+ }
+
+ @Override
public void setOnPreparedListener_impl(VideoView2.OnPreparedListener l) {
mOnPreparedListener = l;
}
@@ -363,6 +364,7 @@
mSuperProvider.onDetachedFromWindow_impl();
mMediaSession.release();
mMediaSession = null;
+ mMediaController = null;
}
@Override
@@ -393,58 +395,11 @@
}
@Override
- public boolean onKeyDown_impl(int keyCode, KeyEvent event) {
- Log.v(TAG, "onKeyDown_impl: " + keyCode);
- boolean isKeyCodeSupported = keyCode != KeyEvent.KEYCODE_BACK
- && keyCode != KeyEvent.KEYCODE_VOLUME_UP
- && keyCode != KeyEvent.KEYCODE_VOLUME_DOWN
- && keyCode != KeyEvent.KEYCODE_VOLUME_MUTE
- && keyCode != KeyEvent.KEYCODE_MENU
- && keyCode != KeyEvent.KEYCODE_CALL
- && keyCode != KeyEvent.KEYCODE_ENDCALL;
- if (isInPlaybackState() && isKeyCodeSupported && mMediaControlView != null) {
- if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK
- || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) {
- if (mMediaPlayer.isPlaying()) {
- mMediaController.getTransportControls().pause();
- mMediaControlView.show();
- } else {
- mMediaController.getTransportControls().play();
- mMediaControlView.hide();
- }
- return true;
- } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) {
- if (!mMediaPlayer.isPlaying()) {
- mMediaController.getTransportControls().play();
- mMediaControlView.hide();
- }
- return true;
- } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP
- || keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) {
- if (mMediaPlayer.isPlaying()) {
- mMediaController.getTransportControls().pause();
- mMediaControlView.show();
- }
- return true;
- } else {
- toggleMediaControlViewVisibility();
- }
- }
-
- return mSuperProvider.onKeyDown_impl(keyCode, event);
- }
-
- @Override
public void onFinishInflate_impl() {
mSuperProvider.onFinishInflate_impl();
}
@Override
- public boolean dispatchKeyEvent_impl(KeyEvent event) {
- return mSuperProvider.dispatchKeyEvent_impl(event);
- }
-
- @Override
public void setEnabled_impl(boolean enabled) {
mSuperProvider.setEnabled_impl(enabled);
}
@@ -492,7 +447,7 @@
}
mCurrentView = view;
if (mOnViewTypeChangedListener != null) {
- mOnViewTypeChangedListener.onViewTypeChanged(view.getViewType());
+ mOnViewTypeChangedListener.onViewTypeChanged(mInstance, view.getViewType());
}
if (needToStart()) {
mMediaController.getTransportControls().play();
@@ -554,12 +509,6 @@
controller.registerRenderer(new Cea708CaptionRenderer(context));
controller.registerRenderer(new ClosedCaptionRenderer(context));
mMediaPlayer.setSubtitleAnchor(controller, (SubtitleController.Anchor) mSubtitleView);
-
- if (mAudioSession != 0) {
- mMediaPlayer.setAudioSessionId(mAudioSession);
- } else {
- mAudioSession = mMediaPlayer.getAudioSessionId();
- }
mMediaPlayer.setOnPreparedListener(mPreparedListener);
mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
mMediaPlayer.setOnCompletionListener(mCompletionListener);
@@ -658,8 +607,12 @@
}
mStateBuilder = new PlaybackState.Builder();
mStateBuilder.setActions(playbackActions);
- mStateBuilder.addCustomAction(MediaControlView2Impl.COMMAND_SHOW_SUBTITLE, null, -1);
- mStateBuilder.addCustomAction(MediaControlView2Impl.COMMAND_HIDE_SUBTITLE, null, -1);
+
+ if (mCustomActionList != null) {
+ for (PlaybackState.CustomAction action : mCustomActionList) {
+ mStateBuilder.addCustomAction(action);
+ }
+ }
}
mStateBuilder.setState(getCorrespondingPlaybackState(),
mMediaPlayer.getCurrentPosition(), mSpeed);
@@ -752,7 +705,7 @@
}
mCurrentState = STATE_PREPARED;
if (mOnPreparedListener != null) {
- mOnPreparedListener.onPrepared();
+ mOnPreparedListener.onPrepared(mInstance);
}
if (mMediaControlView != null) {
mMediaControlView.setEnabled(true);
@@ -827,7 +780,7 @@
updatePlaybackState();
if (mOnCompletionListener != null) {
- mOnCompletionListener.onCompletion();
+ mOnCompletionListener.onCompletion(mInstance);
}
if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
mAudioManager.abandonAudioFocus(null);
@@ -839,7 +792,7 @@
new MediaPlayer.OnInfoListener() {
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (mOnInfoListener != null) {
- mOnInfoListener.onInfo(what, extra);
+ mOnInfoListener.onInfo(mInstance, what, extra);
}
return true;
}
@@ -861,7 +814,7 @@
/* If an error handler has been supplied, use it and finish. */
if (mOnErrorListener != null) {
- if (mOnErrorListener.onError(frameworkErr, implErr)) {
+ if (mOnErrorListener.onError(mInstance, frameworkErr, implErr)) {
return true;
}
}
@@ -892,7 +845,7 @@
* at least inform them that the video is over.
*/
if (mOnCompletionListener != null) {
- mOnCompletionListener.onCompletion();
+ mOnCompletionListener.onCompletion(mInstance);
}
}
})
@@ -929,6 +882,11 @@
}
@Override
+ public void onCustomAction(String action, Bundle extras) {
+ mOnCustomActionListener.onCustomAction(action, extras);
+ }
+
+ @Override
public void onPlay() {
if (isInPlaybackState() && mCurrentView.hasAvailableSurface()) {
applySpeed();