Merge "MediaSession2: Change controller's behavior when connected"
diff --git a/packages/MediaComponents/res/values/themes.xml b/packages/MediaComponents/res/values/themes.xml
index 51098e9..d9a754b 100644
--- a/packages/MediaComponents/res/values/themes.xml
+++ b/packages/MediaComponents/res/values/themes.xml
@@ -16,8 +16,8 @@
<resources>
- <style name="Theme.MediaRouter" parent="ThemeOverlay.AppCompat.Dark">
- <item name="windowNoTitle">true</item>
+ <style name="Theme.MediaRouter" parent="android:Theme.Material">
+ <item name="android:windowNoTitle">true</item>
<item name="mediaRouteButtonStyle">@style/Widget.MediaRouter.MediaRouteButton</item>
<item name="mediaRouteCloseDrawable">@drawable/mr_dialog_close_dark</item>
@@ -37,8 +37,8 @@
<item name="mediaRouteControlPanelThemeOverlay">@style/ThemeOverlay.MediaRouter.Light</item>
</style>
- <style name="Theme.MediaRouter.Light" parent="ThemeOverlay.AppCompat.Light">
- <item name="windowNoTitle">true</item>
+ <style name="Theme.MediaRouter.Light" parent="android:Theme.Material.Light">
+ <item name="android:windowNoTitle">true</item>
<item name="mediaRouteButtonStyle">@style/Widget.MediaRouter.Light.MediaRouteButton</item>
<item name="mediaRouteCloseDrawable">@drawable/mr_dialog_close_light</item>
@@ -58,14 +58,14 @@
<item name="mediaRouteControlPanelThemeOverlay">@style/ThemeOverlay.MediaRouter.Dark</item>
</style>
- <style name="ThemeOverlay.MediaRouter.Dark" parent="ThemeOverlay.AppCompat.Dark">
+ <style name="ThemeOverlay.MediaRouter.Dark" parent="android:Theme.Material">
<item name="mediaRoutePlayDrawable">@drawable/mr_media_play_dark</item>
<item name="mediaRoutePauseDrawable">@drawable/mr_media_pause_dark</item>
<item name="mediaRouteStopDrawable">@drawable/mr_media_stop_dark</item>
<item name="mediaRouteAudioTrackDrawable">@drawable/mr_vol_type_audiotrack_dark</item>
</style>
- <style name="ThemeOverlay.MediaRouter.Light" parent="ThemeOverlay.AppCompat.Light">
+ <style name="ThemeOverlay.MediaRouter.Light" parent="android:Theme.Material.Light">
<item name="mediaRoutePlayDrawable">@drawable/mr_media_play_light</item>
<item name="mediaRoutePauseDrawable">@drawable/mr_media_pause_light</item>
<item name="mediaRouteStopDrawable">@drawable/mr_media_stop_light</item>
diff --git a/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl b/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl
index d5bd354..99df372 100644
--- a/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl
+++ b/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl
@@ -40,6 +40,9 @@
void connect(String callingPackage, IMediaSession2Callback callback);
void release(IMediaSession2Callback caller);
+ void setVolumeTo(IMediaSession2Callback caller, int value, int flags);
+ void adjustVolume(IMediaSession2Callback caller, int direction, int flags);
+
//////////////////////////////////////////////////////////////////////////////////////////////
// send command
//////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/packages/MediaComponents/src/com/android/media/MediaController2Impl.java b/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
index 06883f2..3b31d9e 100644
--- a/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
@@ -288,12 +288,32 @@
@Override
public void setVolumeTo_impl(int value, int flags) {
- // TODO(jaewan): Implement
+ // TODO(hdmoon): sanity check
+ final IMediaSession2 binder = mSessionBinder;
+ if (binder != null) {
+ try {
+ binder.setVolumeTo(mSessionCallbackStub, value, flags);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to the service or the session is gone", e);
+ }
+ } else {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ }
}
@Override
public void adjustVolume_impl(int direction, int flags) {
- // TODO(jaewan): Implement
+ // TODO(hdmoon): sanity check
+ final IMediaSession2 binder = mSessionBinder;
+ if (binder != null) {
+ try {
+ binder.adjustVolume(mSessionCallbackStub, direction, flags);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to the service or the session is gone", e);
+ }
+ } else {
+ Log.w(TAG, "Session isn't active", new IllegalStateException());
+ }
}
@Override
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
index cde98d2..0b7c546 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
@@ -559,6 +559,10 @@
return mCallback;
}
+ VolumeProvider2 getVolumeProvider() {
+ return mVolumeProvider;
+ }
+
private static class MyPlaybackListener implements MediaPlayerInterface.PlaybackListener {
private final WeakReference<MediaSession2Impl> mSession;
private final MediaPlayerInterface mPlayer;
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java b/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
index 3909fe2..3391236 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
@@ -29,6 +29,7 @@
import android.media.MediaSession2.ControllerInfo;
import android.media.MediaSession2.PlaylistParams;
import android.media.PlaybackState2;
+import android.media.VolumeProvider2;
import android.media.update.MediaSession2Provider.CommandButtonProvider;
import android.os.Binder;
import android.os.Bundle;
@@ -165,6 +166,82 @@
}
@Override
+ public void setVolumeTo(IMediaSession2Callback caller, int value, int flags)
+ throws RuntimeException {
+ final MediaSession2Impl sessionImpl = getSession();
+ final ControllerInfo controller = getController(caller);
+ if (controller == null) {
+ if (DEBUG) {
+ Log.d(TAG, "Command from a controller that hasn't connected. Ignore");
+ }
+ return;
+ }
+ sessionImpl.getCallbackExecutor().execute(() -> {
+ final MediaSession2Impl session = mSession.get();
+ if (session == null) {
+ return;
+ }
+ // TODO(jaewan): Sanity check.
+ Command command = new Command(
+ session.getContext(), MediaSession2.COMMAND_CODE_SET_VOLUME);
+ boolean accepted = session.getCallback().onCommandRequest(controller, command);
+ if (!accepted) {
+ // Don't run rejected command.
+ if (DEBUG) {
+ Log.d(TAG, "Command " + MediaSession2.COMMAND_CODE_SET_VOLUME + " from "
+ + controller + " was rejected by " + session);
+ }
+ return;
+ }
+
+ VolumeProvider2 volumeProvider = session.getVolumeProvider();
+ if (volumeProvider == null) {
+ // TODO(jaewan): Set local stream volume
+ } else {
+ volumeProvider.onSetVolumeTo(value);
+ }
+ });
+ }
+
+ @Override
+ public void adjustVolume(IMediaSession2Callback caller, int direction, int flags)
+ throws RuntimeException {
+ final MediaSession2Impl sessionImpl = getSession();
+ final ControllerInfo controller = getController(caller);
+ if (controller == null) {
+ if (DEBUG) {
+ Log.d(TAG, "Command from a controller that hasn't connected. Ignore");
+ }
+ return;
+ }
+ sessionImpl.getCallbackExecutor().execute(() -> {
+ final MediaSession2Impl session = mSession.get();
+ if (session == null) {
+ return;
+ }
+ // TODO(jaewan): Sanity check.
+ Command command = new Command(
+ session.getContext(), MediaSession2.COMMAND_CODE_SET_VOLUME);
+ boolean accepted = session.getCallback().onCommandRequest(controller, command);
+ if (!accepted) {
+ // Don't run rejected command.
+ if (DEBUG) {
+ Log.d(TAG, "Command " + MediaSession2.COMMAND_CODE_SET_VOLUME + " from "
+ + controller + " was rejected by " + session);
+ }
+ return;
+ }
+
+ VolumeProvider2 volumeProvider = session.getVolumeProvider();
+ if (volumeProvider == null) {
+ // TODO(jaewan): Adjust local stream volume
+ } else {
+ volumeProvider.onAdjustVolume(direction);
+ }
+ });
+ }
+
+ @Override
public void sendCommand(IMediaSession2Callback caller, Bundle command, Bundle args)
throws RuntimeException {
// TODO(jaewan): Generic command
diff --git a/packages/MediaComponents/src/com/android/media/update/ApiHelper.java b/packages/MediaComponents/src/com/android/media/update/ApiHelper.java
index b0ca1bd..06f463f 100644
--- a/packages/MediaComponents/src/com/android/media/update/ApiHelper.java
+++ b/packages/MediaComponents/src/com/android/media/update/ApiHelper.java
@@ -16,6 +16,7 @@
package com.android.media.update;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
@@ -24,6 +25,7 @@
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
import com.android.support.mediarouter.app.MediaRouteButton;
@@ -51,13 +53,23 @@
return sInstance.mLibResources;
}
- public static Resources.Theme getLibTheme() {
+ public static Theme getLibTheme() {
return sInstance.mLibTheme;
}
+ public static Theme getLibTheme(int themeId) {
+ Theme theme = sInstance.mLibResources.newTheme();
+ theme.applyStyle(themeId, true);
+ return theme;
+ }
+
public static LayoutInflater getLayoutInflater(Context context) {
+ return getLayoutInflater(context, getLibTheme());
+ }
+
+ public static LayoutInflater getLayoutInflater(Context context, Theme theme) {
LayoutInflater layoutInflater = LayoutInflater.from(context).cloneInContext(
- new ContextThemeWrapper(context, getLibTheme()));
+ new ContextThemeWrapper(context, theme));
layoutInflater.setFactory2(new LayoutInflater.Factory2() {
@Override
public View onCreateView(
@@ -77,8 +89,17 @@
}
public static View inflateLibLayout(Context context, int libResId) {
+ return inflateLibLayout(context, getLibTheme(), libResId, null, false);
+ }
+
+ public static View inflateLibLayout(Context context, Theme theme, int libResId) {
+ return inflateLibLayout(context, theme, libResId, null, false);
+ }
+
+ public static View inflateLibLayout(Context context, Theme theme, int libResId,
+ @Nullable ViewGroup root, boolean attachToRoot) {
try (XmlResourceParser parser = getLibResources().getLayout(libResId)) {
- return getLayoutInflater(context).inflate(parser, null);
+ return getLayoutInflater(context, theme).inflate(parser, root, attachToRoot);
}
}
}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteButton.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteButton.java
index 7fdcfe4..fa94a81 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteButton.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteButton.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.app.Activity;
+import android.app.FragmentManager;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.ColorStateList;
@@ -27,8 +28,6 @@
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentManager;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.widget.TooltipCompat;
import android.util.AttributeSet;
@@ -259,7 +258,7 @@
return false;
}
- final FragmentManager fm = getFragmentManager();
+ final FragmentManager fm = getActivity().getFragmentManager();
if (fm == null) {
throw new IllegalStateException("The activity must be a subclass of FragmentActivity");
}
@@ -286,13 +285,6 @@
return true;
}
- private FragmentManager getFragmentManager() {
- Activity activity = getActivity();
- if (activity instanceof FragmentActivity) {
- return ((FragmentActivity)activity).getSupportFragmentManager();
- }
- return null;
- }
private Activity getActivity() {
// Gross way of unwrapping the Activity so we can get the FragmentManager
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialog.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialog.java
index cc7c3d5..aeb4408 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialog.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialog.java
@@ -20,7 +20,9 @@
import static com.android.support.mediarouter.media.MediaRouter.RouteInfo.CONNECTION_STATE_CONNECTING;
import android.annotation.NonNull;
+import android.app.Dialog;
import android.content.Context;
+import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.net.Uri;
@@ -31,6 +33,7 @@
import android.support.v7.app.AppCompatDialog;
import android.text.TextUtils;
import android.util.Log;
+import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@@ -41,6 +44,7 @@
import android.widget.ListView;
import android.widget.TextView;
+import com.android.media.update.ApiHelper;
import com.android.media.update.R;
import com.android.support.mediarouter.media.MediaRouteSelector;
import com.android.support.mediarouter.media.MediaRouter;
@@ -61,7 +65,7 @@
* @see MediaRouteButton
* @see MediaRouteActionProvider
*/
-public class MediaRouteChooserDialog extends AppCompatDialog {
+public class MediaRouteChooserDialog extends Dialog {
static final String TAG = "MediaRouteChooserDialog";
// Do not update the route list immediately to avoid unnatural dialog change.
@@ -94,8 +98,9 @@
}
public MediaRouteChooserDialog(Context context, int theme) {
- super(context = MediaRouterThemeHelper.createThemedDialogContext(context, theme, false),
- MediaRouterThemeHelper.createThemedDialogStyle(context));
+ super(new ContextThemeWrapper(context,
+ ApiHelper.getLibTheme(MediaRouterThemeHelper.getRouterThemeId(context))),
+ theme == 0 ? android.R.style.Animation : theme);
context = getContext();
mRouter = MediaRouter.getInstance(context);
@@ -182,7 +187,9 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.mr_chooser_dialog);
+ setContentView(ApiHelper.inflateLibLayout(getContext(),
+ ApiHelper.getLibTheme(MediaRouterThemeHelper.getRouterThemeId(getContext())),
+ R.layout.mr_chooser_dialog));
mRoutes = new ArrayList<>();
mAdapter = new RouteAdapter(getContext(), mRoutes);
@@ -199,7 +206,7 @@
* Sets the width of the dialog. Also called when configuration changes.
*/
void updateLayout() {
- getWindow().setLayout(MediaRouteDialogHelper.getDialogWidth(getContext()),
+ getWindow().setLayout(MediaRouteDialogHelper.getDialogWidth(),
ViewGroup.LayoutParams.WRAP_CONTENT);
}
@@ -248,7 +255,6 @@
private final class RouteAdapter extends ArrayAdapter<MediaRouter.RouteInfo>
implements ListView.OnItemClickListener {
- private final LayoutInflater mInflater;
private final Drawable mDefaultIcon;
private final Drawable mTvIcon;
private final Drawable mSpeakerIcon;
@@ -256,12 +262,16 @@
public RouteAdapter(Context context, List<MediaRouter.RouteInfo> routes) {
super(context, 0, routes);
- mInflater = LayoutInflater.from(context);
- TypedArray styledAttributes = getContext().obtainStyledAttributes(new int[] {
- R.attr.mediaRouteDefaultIconDrawable,
- R.attr.mediaRouteTvIconDrawable,
- R.attr.mediaRouteSpeakerIconDrawable,
- R.attr.mediaRouteSpeakerGroupIconDrawable});
+
+ TypedArray styledAttributes = ApiHelper.getLibTheme(
+ MediaRouterThemeHelper.getRouterThemeId(context)).obtainStyledAttributes(
+ new int[] {
+ R.attr.mediaRouteDefaultIconDrawable,
+ R.attr.mediaRouteTvIconDrawable,
+ R.attr.mediaRouteSpeakerIconDrawable,
+ R.attr.mediaRouteSpeakerGroupIconDrawable
+ });
+
mDefaultIcon = styledAttributes.getDrawable(0);
mTvIcon = styledAttributes.getDrawable(1);
mSpeakerIcon = styledAttributes.getDrawable(2);
@@ -283,7 +293,10 @@
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
- view = mInflater.inflate(R.layout.mr_chooser_list_item, parent, false);
+ view = ApiHelper.inflateLibLayout(getContext(),
+ ApiHelper.getLibTheme(
+ MediaRouterThemeHelper.getRouterThemeId(getContext())),
+ R.layout.mr_chooser_list_item, parent, false);
}
MediaRouter.RouteInfo route = getItem(position);
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialogFragment.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialogFragment.java
index 2f85fb3..65e6b29 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialogFragment.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialogFragment.java
@@ -17,10 +17,10 @@
package com.android.support.mediarouter.app;
import android.app.Dialog;
+import android.app.DialogFragment;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
import com.android.support.mediarouter.media.MediaRouteSelector;
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialog.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialog.java
index 942797b..123ab21 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialog.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialog.java
@@ -455,7 +455,7 @@
* Sets the width of the dialog. Also called when configuration changes.
*/
void updateLayout() {
- int width = MediaRouteDialogHelper.getDialogWidth(mContext);
+ int width = MediaRouteDialogHelper.getDialogWidth();
getWindow().setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT);
View decorView = getWindow().getDecorView();
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialogFragment.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialogFragment.java
index 9442df7..215d74f 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialogFragment.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialogFragment.java
@@ -17,10 +17,10 @@
package com.android.support.mediarouter.app;
import android.app.Dialog;
+import android.app.DialogFragment;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
/**
* Media route controller dialog fragment.
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDialogHelper.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDialogHelper.java
index 6f75b46..62c050b 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDialogHelper.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDialogHelper.java
@@ -28,6 +28,7 @@
import android.widget.ArrayAdapter;
import android.widget.ListView;
+import com.android.media.update.ApiHelper;
import com.android.media.update.R;
import java.util.HashMap;
@@ -40,12 +41,12 @@
* The framework should set the dialog width properly, but somehow it doesn't work, hence
* duplicating a similar logic here to determine the appropriate dialog width.
*/
- public static int getDialogWidth(Context context) {
- DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+ public static int getDialogWidth() {
+ DisplayMetrics metrics = ApiHelper.getLibResources().getDisplayMetrics();
boolean isPortrait = metrics.widthPixels < metrics.heightPixels;
TypedValue value = new TypedValue();
- context.getResources().getValue(isPortrait ? R.dimen.mr_dialog_fixed_width_minor
+ ApiHelper.getLibResources().getValue(isPortrait ? R.dimen.mr_dialog_fixed_width_minor
: R.dimen.mr_dialog_fixed_width_major, value, true);
if (value.type == TypedValue.TYPE_DIMENSION) {
return (int) value.getDimension(metrics);
diff --git a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
index 9f207b1..dea72e6 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
@@ -81,6 +81,8 @@
private static final int STATE_PAUSED = 4;
private static final int STATE_PLAYBACK_COMPLETED = 5;
+ private static final int INVALID_TRACK_INDEX = -1;
+
private AudioManager mAudioManager;
private AudioAttributes mAudioAttributes;
private int mAudioFocusType = AudioManager.AUDIOFOCUS_GAIN; // legacy focus gain
@@ -117,7 +119,7 @@
private int mVideoWidth;
private int mVideoHeight;
- private boolean mCCEnabled;
+ private boolean mSubtitleEnabled;
private int mSelectedTrackIndex;
private SubtitleView mSubtitleView;
@@ -138,6 +140,7 @@
mVideoHeight = 0;
mSpeed = 1.0f;
mFallbackSpeed = mSpeed;
+ mSelectedTrackIndex = INVALID_TRACK_INDEX;
mAudioManager = (AudioManager) mInstance.getContext()
.getSystemService(Context.AUDIO_SERVICE);
@@ -179,11 +182,11 @@
if (enableControlView) {
mMediaControlView = new MediaControlView2(mInstance.getContext());
}
- boolean showSubtitle = (attrs == null) || attrs.getAttributeBooleanValue(
+ boolean enableSubtitle = (attrs == null) || attrs.getAttributeBooleanValue(
"http://schemas.android.com/apk/res/android",
- "showSubtitle", true);
- if (showSubtitle) {
- Log.d(TAG, "showSubtitle attribute is true.");
+ "enableSubtitle", true);
+ if (enableSubtitle) {
+ Log.d(TAG, "enableSubtitle attribute is true.");
// TODO: implement
}
int viewType = (attrs == null) ? VideoView2.VIEW_TYPE_SURFACEVIEW
@@ -226,8 +229,8 @@
}
@Override
- public void showSubtitle_impl(boolean show) {
- if (show) {
+ public void setSubtitleEnabled_impl(boolean enable) {
+ if (enable) {
// Retrieve all tracks that belong to the current video.
MediaPlayer.TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo();
@@ -240,16 +243,21 @@
}
if (subtitleTrackIndices.size() > 0) {
// Select first subtitle track
- mCCEnabled = true;
mSelectedTrackIndex = subtitleTrackIndices.get(0);
mMediaPlayer.selectTrack(mSelectedTrackIndex);
}
} else {
- if (mCCEnabled) {
+ if (mSelectedTrackIndex != INVALID_TRACK_INDEX) {
mMediaPlayer.deselectTrack(mSelectedTrackIndex);
- mCCEnabled = false;
+ mSelectedTrackIndex = INVALID_TRACK_INDEX;
}
}
+ mSubtitleEnabled = enable;
+ }
+
+ @Override
+ public boolean isSubtitleEnabled_impl() {
+ return mSubtitleEnabled;
}
// TODO: remove setSpeed_impl once MediaController2 is ready.
@@ -661,8 +669,12 @@
}
mStateBuilder.setState(getCorrespondingPlaybackState(),
mMediaPlayer.getCurrentPosition(), mSpeed);
- mStateBuilder.setBufferedPosition(
- (long) (mCurrentBufferPercentage / 100.0) * mMediaPlayer.getDuration());
+ if (mCurrentState != STATE_ERROR
+ && mCurrentState != STATE_IDLE
+ && mCurrentState != STATE_PREPARING) {
+ mStateBuilder.setBufferedPosition(
+ (long) (mCurrentBufferPercentage / 100.0) * mMediaPlayer.getDuration());
+ }
// Set PlaybackState for MediaSession
if (mMediaSession != null) {
@@ -928,10 +940,10 @@
} else {
switch (command) {
case MediaControlView2.COMMAND_SHOW_SUBTITLE:
- mInstance.showSubtitle(true);
+ mInstance.setSubtitleEnabled(true);
break;
case MediaControlView2.COMMAND_HIDE_SUBTITLE:
- mInstance.showSubtitle(false);
+ mInstance.setSubtitleEnabled(false);
break;
case MediaControlView2.COMMAND_SET_FULLSCREEN:
if (mOnFullScreenRequestListener != null) {
diff --git a/packages/MediaComponents/test/src/android/media/MediaController2Test.java b/packages/MediaComponents/test/src/android/media/MediaController2Test.java
index 358beb7..f1fdf2e 100644
--- a/packages/MediaComponents/test/src/android/media/MediaController2Test.java
+++ b/packages/MediaComponents/test/src/android/media/MediaController2Test.java
@@ -16,7 +16,7 @@
package android.media;
-import android.media.MediaController2.ControllerCallback;
+import android.content.Context;
import android.media.MediaPlayerInterface.PlaybackListener;
import android.media.MediaSession2.Command;
import android.media.MediaSession2.ControllerInfo;
@@ -223,6 +223,42 @@
}
@Test
+ public void testSetVolumeTo() throws Exception {
+ final int maxVolume = 100;
+ final int currentVolume = 23;
+ final int volumeControlType = VolumeProvider2.VOLUME_CONTROL_ABSOLUTE;
+ TestVolumeProvider volumeProvider =
+ new TestVolumeProvider(mContext, volumeControlType, maxVolume, currentVolume);
+
+ mSession.setPlayer(new MockPlayer(0), volumeProvider);
+ final MediaController2 controller = createController(mSession.getToken(), true, null);
+
+ final int targetVolume = 50;
+ controller.setVolumeTo(targetVolume, 0 /* flags */);
+ assertTrue(volumeProvider.mLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
+ assertTrue(volumeProvider.mSetVolumeToCalled);
+ assertEquals(targetVolume, volumeProvider.mVolume);
+ }
+
+ @Test
+ public void testAdjustVolume() throws Exception {
+ final int maxVolume = 100;
+ final int currentVolume = 23;
+ final int volumeControlType = VolumeProvider2.VOLUME_CONTROL_ABSOLUTE;
+ TestVolumeProvider volumeProvider =
+ new TestVolumeProvider(mContext, volumeControlType, maxVolume, currentVolume);
+
+ mSession.setPlayer(new MockPlayer(0), volumeProvider);
+ final MediaController2 controller = createController(mSession.getToken(), true, null);
+
+ final int direction = AudioManager.ADJUST_RAISE;
+ controller.adjustVolume(direction, 0 /* flags */);
+ assertTrue(volumeProvider.mLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
+ assertTrue(volumeProvider.mAdjustVolumeCalled);
+ assertEquals(direction, volumeProvider.mDirection);
+ }
+
+ @Test
public void testGetPackageName() {
assertEquals(mContext.getPackageName(), mController.getSessionToken().getPackageName());
}
@@ -563,4 +599,31 @@
// TODO(jaewan): Add test for service connect rejection, when we differentiate session
// active/inactive and connection accept/refuse
+
+ class TestVolumeProvider extends VolumeProvider2 {
+ final CountDownLatch mLatch = new CountDownLatch(1);
+ boolean mSetVolumeToCalled;
+ boolean mAdjustVolumeCalled;
+ int mVolume;
+ int mDirection;
+
+ public TestVolumeProvider(Context context, int controlType, int maxVolume,
+ int currentVolume) {
+ super(context, controlType, maxVolume, currentVolume);
+ }
+
+ @Override
+ public void onSetVolumeTo(int volume) {
+ mSetVolumeToCalled = true;
+ mVolume = volume;
+ mLatch.countDown();
+ }
+
+ @Override
+ public void onAdjustVolume(int direction) {
+ mAdjustVolumeCalled = true;
+ mDirection = direction;
+ mLatch.countDown();
+ }
+ }
}