MediaControlView2: Final Settings UX addition
This CL does the following things:
1. Make the check button visibility in Settings window dynamic
2. Send command to VideoView2 when choosing item for Subtitle, Audio
Track, and Playback Speed.
3. Make pressing Subtitle & Video Quality buttons open Settings
window.
4. Place Subtitle & Video Quality buttons outside the Settings
window.
Also, this CL remove Aspect Ratio button (function support has been punted)
Bug: 73703113
Test: manually run VideoViewTest.apk
Change-Id: I9c8ca3f7e3c6aae8c69ca6b6ff0973a3377a88fa
diff --git a/packages/MediaComponents/res/drawable/ic_replay_circle_filled.xml b/packages/MediaComponents/res/drawable/ic_replay_circle_filled.xml
index 389396b..a56d5d9 100644
--- a/packages/MediaComponents/res/drawable/ic_replay_circle_filled.xml
+++ b/packages/MediaComponents/res/drawable/ic_replay_circle_filled.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
+ android:width="40dp"
+ android:height="40dp"
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/packages/MediaComponents/res/drawable/ic_closed_caption_off.xml b/packages/MediaComponents/res/drawable/ic_subtitle_off.xml
similarity index 100%
rename from packages/MediaComponents/res/drawable/ic_closed_caption_off.xml
rename to packages/MediaComponents/res/drawable/ic_subtitle_off.xml
diff --git a/packages/MediaComponents/res/layout/media_controller.xml b/packages/MediaComponents/res/layout/media_controller.xml
index 8488c84..885bcf5 100644
--- a/packages/MediaComponents/res/layout/media_controller.xml
+++ b/packages/MediaComponents/res/layout/media_controller.xml
@@ -199,6 +199,7 @@
<ImageButton
android:id="@+id/subtitle"
android:scaleType="fitCenter"
+ android:visibility="gone"
style="@style/BottomBarButton.CC" />
<ImageButton
android:id="@+id/fullscreen"
@@ -224,9 +225,6 @@
android:layout_height="wrap_content" />
<ImageButton
- android:id="@+id/aspect_ratio"
- style="@style/BottomBarButton.AspectRatio" />
- <ImageButton
android:id="@+id/video_quality"
style="@style/BottomBarButton.VideoQuality" />
<ImageButton
diff --git a/packages/MediaComponents/res/layout/settings_list_item.xml b/packages/MediaComponents/res/layout/settings_list_item.xml
index e7522b7..81b3275 100644
--- a/packages/MediaComponents/res/layout/settings_list_item.xml
+++ b/packages/MediaComponents/res/layout/settings_list_item.xml
@@ -28,14 +28,6 @@
android:orientation="horizontal">
<ImageView
- android:id="@+id/check"
- android:layout_width="@dimen/MediaControlView2_settings_icon_size"
- android:layout_height="@dimen/MediaControlView2_settings_icon_size"
- android:gravity="center"
- android:paddingLeft="2dp"
- android:src="@drawable/ic_check"/>
-
- <ImageView
android:id="@+id/icon"
android:layout_width="@dimen/MediaControlView2_settings_icon_size"
android:layout_height="@dimen/MediaControlView2_settings_icon_size"
diff --git a/packages/MediaComponents/res/layout/sub_settings_list_item.xml b/packages/MediaComponents/res/layout/sub_settings_list_item.xml
new file mode 100644
index 0000000..9de7f2b
--- /dev/null
+++ b/packages/MediaComponents/res/layout/sub_settings_list_item.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2018 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="@dimen/MediaControlView2_settings_width"
+ android:layout_height="@dimen/MediaControlView2_settings_height"
+ android:orientation="horizontal"
+ android:background="@color/black_transparent_70">
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/MediaControlView2_settings_height"
+ android:paddingRight="2dp"
+ android:gravity="center"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/check"
+ android:layout_width="@dimen/MediaControlView2_settings_icon_size"
+ android:layout_height="@dimen/MediaControlView2_settings_icon_size"
+ android:gravity="center"
+ android:paddingLeft="2dp"
+ android:src="@drawable/ic_check"/>
+ </LinearLayout>
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/MediaControlView2_settings_height"
+ android:gravity="center"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/text"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/MediaControlView2_text_width"
+ android:paddingLeft="2dp"
+ android:textColor="@color/white"
+ android:textSize="@dimen/MediaControlView2_settings_main_text_size"/>
+ </RelativeLayout>
+
+</LinearLayout>
diff --git a/packages/MediaComponents/res/values/arrays.xml b/packages/MediaComponents/res/values/arrays.xml
new file mode 100644
index 0000000..1187320
--- /dev/null
+++ b/packages/MediaComponents/res/values/arrays.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2018 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.
+-->
+
+<resources>
+ <integer-array name="speed_multiplied_by_100">
+ <item>25</item>
+ <item>50</item>
+ <item>75</item>
+ <item>100</item>
+ <item>125</item>
+ <item>150</item>
+ <item>200</item>
+ </integer-array>
+</resources>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/values/strings.xml b/packages/MediaComponents/res/values/strings.xml
index 305cef4..c80aaf3 100644
--- a/packages/MediaComponents/res/values/strings.xml
+++ b/packages/MediaComponents/res/values/strings.xml
@@ -111,15 +111,18 @@
<string name="MediaControlView2_audio_track_none_text">None</string>
<string name="MediaControlView2_video_quality_text">Video quality</string>
<string name="MediaControlView2_video_quality_auto_text">Auto</string>
- <string name="MediaControlView2_playback_speed_text">Playback speed</string>
- <string name="MediaControlView2_playback_speed_0_25x_text">0.25x</string>
- <string name="MediaControlView2_playback_speed_0_5x_text">0.5x</string>
- <string name="MediaControlView2_playback_speed_0_75x_text">0.75x</string>
- <string name="MediaControlView2_playback_speed_1x_text">Normal</string>
- <string name="MediaControlView2_playback_speed_1_25x_text">1.25x</string>
- <string name="MediaControlView2_playback_speed_1_5x_text">1.5x</string>
- <string name="MediaControlView2_playback_speed_2x_text">2x</string>
<string name="MediaControlView2_help_text">Help & feedback</string>
+ <string name="MediaControlView2_playback_speed_text">Playback speed</string>
+ <string-array name="MediaControlView2_playback_speeds">
+ <item>0.25x</item>
+ <item>0.5x</item>
+ <item>0.75x</item>
+ <item>Normal</item>
+ <item>1.25x</item>
+ <item>1.5x</item>
+ <item>2x</item>
+ </string-array>
+
<!-- Text for displaying subtitle track number. -->
<string name="MediaControlView2_subtitle_track_number_text">
Track <xliff:g id="track_number" example="1">%1$s</xliff:g>
diff --git a/packages/MediaComponents/res/values/style.xml b/packages/MediaComponents/res/values/style.xml
index 23c7bc9..9c94aa2 100644
--- a/packages/MediaComponents/res/values/style.xml
+++ b/packages/MediaComponents/res/values/style.xml
@@ -4,6 +4,7 @@
<item name="android:background">@null</item>
<item name="android:layout_width">70dp</item>
<item name="android:layout_height">40dp</item>
+ <item name="android:visibility">gone</item>
</style>
<style name="TransportControlsButton.Previous">
@@ -74,10 +75,6 @@
<item name="android:src">@drawable/ic_settings</item>
</style>
- <style name="BottomBarButton.AspectRatio">
- <item name="android:src">@drawable/ic_aspect_ratio</item>
- </style>
-
<style name="BottomBarButton.Mute">
<item name="android:src">@drawable/ic_mute</item>
</style>
diff --git a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
index 69febc2..7044404 100644
--- a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
@@ -52,6 +52,7 @@
import com.android.support.mediarouter.media.MediaRouter;
import com.android.support.mediarouter.media.MediaRouteSelector;
+import java.util.Arrays;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
@@ -69,7 +70,12 @@
static final String KEY_VIDEO_TRACK_COUNT = "VideoTrackCount";
static final String KEY_AUDIO_TRACK_COUNT = "AudioTrackCount";
static final String KEY_SUBTITLE_TRACK_COUNT = "SubtitleTrackCount";
+ static final String KEY_PLAYBACK_SPEED = "PlaybackSpeed";
+ static final String KEY_SELECTED_AUDIO_INDEX = "SelectedAudioIndex";
+ static final String KEY_SELECTED_SUBTITLE_INDEX = "SelectedSubtitleIndex";
static final String EVENT_UPDATE_TRACK_STATUS = "UpdateTrackStatus";
+ static final String COMMAND_SELECT_AUDIO_TRACK = "SelectTrack";
+ static final String COMMAND_SET_PLAYBACK_SPEED = "SetPlaybackSpeed";
// TODO: Remove this once integrating with MediaSession2 & MediaMetadata2
static final String KEY_STATE_IS_ADVERTISEMENT = "MediaTypeAdvertisement";
@@ -82,6 +88,13 @@
// TODO: remove once the implementation is revised
public static final String COMMAND_SET_FULLSCREEN = "setFullscreen";
+ private static final int SETTINGS_MODE_AUDIO_TRACK = 0;
+ private static final int SETTINGS_MODE_PLAYBACK_SPEED = 1;
+ private static final int SETTINGS_MODE_HELP = 2;
+ private static final int SETTINGS_MODE_SUBTITLE_TRACK = 3;
+ private static final int SETTINGS_MODE_VIDEO_QUALITY = 4;
+ private static final int SETTINGS_MODE_MAIN = 5;
+ private static final int PLAYBACK_SPEED_1x_INDEX = 3;
private static final int MAX_PROGRESS = 1000;
private static final int DEFAULT_PROGRESS_UPDATE_TIME_MS = 1000;
private static final int REWIND_TIME_MS = 10000;
@@ -107,6 +120,13 @@
private int mVideoTrackCount;
private int mAudioTrackCount;
private int mSubtitleTrackCount;
+ private int mSettingsMode;
+ private int mSelectedSubtitleTrackIndex;
+ private int mSelectedAudioTrackIndex;
+ private int mSelectedVideoQualityIndex;
+ private int mSelectedSpeedIndex;
+ private int mSettingsItemHeight;
+ private int mSettingsWindowMargin;
private long mPlaybackActions;
private boolean mDragging;
private boolean mIsFullScreen;
@@ -130,12 +150,13 @@
private ViewGroup mCustomButtons;
private ImageButton mOverflowButtonLeft;
private ImageButton mMuteButton;
- private ImageButton mAspectRationButton;
+ private ImageButton mVideoQualityButton;
private ImageButton mSettingsButton;
private ListView mSettingsListView;
private PopupWindow mSettingsWindow;
private SettingsAdapter mSettingsAdapter;
+ private SubSettingsAdapter mSubSettingsAdapter;
private List<String> mSettingsMainTextsList;
private List<String> mSettingsSubTextsList;
@@ -143,7 +164,8 @@
private List<String> mSubtitleDescriptionsList;
private List<String> mAudioTrackList;
private List<String> mVideoQualityList;
- private List<String> mPlaybackSpeedTextIdsList;
+ private List<String> mPlaybackSpeedTextList;
+ private List<Float> mPlaybackSpeedList;
private CharSequence mPlayDescription;
private CharSequence mPauseDescription;
@@ -217,15 +239,11 @@
}
break;
case MediaControlView2.BUTTON_NEXT:
- // TODO: this button is not visible unless its listener is manually set. Should this
- // function still be provided?
if (mNextButton != null) {
mNextButton.setVisibility(visibility);
}
break;
case MediaControlView2.BUTTON_PREV:
- // TODO: this button is not visible unless its listener is manually set. Should this
- // function still be provided?
if (mPrevButton != null) {
mPrevButton.setVisibility(visibility);
}
@@ -250,11 +268,6 @@
mMuteButton.setVisibility(visibility);
}
break;
- case MediaControlView2.BUTTON_ASPECT_RATIO:
- if (mAspectRationButton != null) {
- mAspectRationButton.setVisibility(visibility);
- }
- break;
case MediaControlView2.BUTTON_SETTINGS:
if (mSettingsButton != null) {
mSettingsButton.setVisibility(visibility);
@@ -415,20 +428,14 @@
if (mPlayPauseButton != null) {
mPlayPauseButton.requestFocus();
mPlayPauseButton.setOnClickListener(mPlayPauseListener);
- mPlayPauseButton.setColorFilter(R.color.gray);
- mPlayPauseButton.setEnabled(false);
}
mFfwdButton = v.findViewById(R.id.ffwd);
if (mFfwdButton != null) {
mFfwdButton.setOnClickListener(mFfwdListener);
- mFfwdButton.setColorFilter(R.color.gray);
- mFfwdButton.setEnabled(false);
}
mRewButton = v.findViewById(R.id.rew);
if (mRewButton != null) {
mRewButton.setOnClickListener(mRewListener);
- mRewButton.setColorFilter(R.color.gray);
- mRewButton.setEnabled(false);
}
mNextButton = v.findViewById(R.id.next);
if (mNextButton != null) {
@@ -443,8 +450,6 @@
mSubtitleButton = v.findViewById(R.id.subtitle);
if (mSubtitleButton != null) {
mSubtitleButton.setOnClickListener(mSubtitleListener);
- mSubtitleButton.setColorFilter(R.color.gray);
- mSubtitleButton.setEnabled(false);
}
mFullScreenButton = v.findViewById(R.id.fullscreen);
if (mFullScreenButton != null) {
@@ -464,11 +469,14 @@
mOverflowButtonLeft.setOnClickListener(mOverflowLeftListener);
}
mMuteButton = v.findViewById(R.id.mute);
- mAspectRationButton = v.findViewById(R.id.aspect_ratio);
mSettingsButton = v.findViewById(R.id.settings);
if (mSettingsButton != null) {
mSettingsButton.setOnClickListener(mSettingsButtonListener);
}
+ mVideoQualityButton = v.findViewById(R.id.video_quality);
+ if (mVideoQualityButton != null) {
+ mVideoQualityButton.setOnClickListener(mVideoQualityListener);
+ }
mProgress = v.findViewById(R.id.mediacontroller_progress);
if (mProgress != null) {
@@ -494,10 +502,16 @@
mSettingsListView = (ListView) ApiHelper.inflateLibLayout(mInstance.getContext(),
R.layout.settings_list);
mSettingsAdapter = new SettingsAdapter(mSettingsMainTextsList, mSettingsSubTextsList,
- mSettingsIconIdsList, false);
+ mSettingsIconIdsList);
+ mSubSettingsAdapter = new SubSettingsAdapter(null, 0);
mSettingsListView.setAdapter(mSettingsAdapter);
mSettingsListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
mSettingsListView.setOnItemClickListener(mSettingsItemClickListener);
+
+ mSettingsItemHeight = mResources.getDimensionPixelSize(
+ R.dimen.MediaControlView2_settings_height);
+ mSettingsWindowMargin = (-1) * mResources.getDimensionPixelSize(
+ R.dimen.MediaControlView2_settings_offset);
int width = mResources.getDimensionPixelSize(R.dimen.MediaControlView2_settings_width);
mSettingsWindow = new PopupWindow(mSettingsListView, width,
ViewGroup.LayoutParams.WRAP_CONTENT, true);
@@ -747,17 +761,20 @@
private final View.OnClickListener mSubtitleListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
- if (!mSubtitleIsEnabled) {
- mSubtitleButton.setImageDrawable(
- mResources.getDrawable(R.drawable.ic_media_subtitle_enabled, null));
- mController.sendCommand(MediaControlView2Impl.COMMAND_SHOW_SUBTITLE, null, null);
- mSubtitleIsEnabled = true;
- } else {
- mSubtitleButton.setImageDrawable(
- mResources.getDrawable(R.drawable.ic_media_subtitle_disabled, null));
- mController.sendCommand(MediaControlView2Impl.COMMAND_HIDE_SUBTITLE, null, null);
- mSubtitleIsEnabled = false;
- }
+ mSettingsMode = SETTINGS_MODE_SUBTITLE_TRACK;
+ mSubSettingsAdapter.setTexts(mSubtitleDescriptionsList);
+ mSubSettingsAdapter.setCheckPosition(mSelectedSubtitleTrackIndex);
+ displaySettingsWindow(mSubSettingsAdapter);
+ }
+ };
+
+ private final View.OnClickListener mVideoQualityListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mSettingsMode = SETTINGS_MODE_VIDEO_QUALITY;
+ mSubSettingsAdapter.setTexts(mVideoQualityList);
+ mSubSettingsAdapter.setCheckPosition(mSelectedVideoQualityIndex);
+ displaySettingsWindow(mSubSettingsAdapter);
}
};
@@ -800,17 +817,9 @@
private final View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
- mSettingsAdapter = new SettingsAdapter(mSettingsMainTextsList,
- mSettingsSubTextsList, mSettingsIconIdsList, false);
- mSettingsListView.setAdapter(mSettingsAdapter);
- int itemHeight = mResources.getDimensionPixelSize(
- R.dimen.MediaControlView2_settings_height);
- int totalHeight = mSettingsAdapter.getCount() * itemHeight;
- int margin = (-1) * mResources.getDimensionPixelSize(
- R.dimen.MediaControlView2_settings_offset);
- mSettingsWindow.dismiss();
- mSettingsWindow.showAsDropDown(mInstance, margin, margin - totalHeight,
- Gravity.BOTTOM | Gravity.RIGHT);
+ mSettingsMode = SETTINGS_MODE_MAIN;
+ mSettingsAdapter.setSubTexts(mSettingsSubTextsList);
+ displaySettingsWindow(mSettingsAdapter);
}
};
@@ -818,56 +827,77 @@
= new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- switch (position) {
- // change to identifiers
- case 0:
- // TODO: add additional subtitle track details
- mSubtitleDescriptionsList = new ArrayList<String>();
- mSubtitleDescriptionsList.add(mResources.getString(
- R.string.MediaControlView2_subtitle_off_text));
- for (int i = 0; i < mSubtitleTrackCount; i++) {
- String track = mResources.getString(
- R.string.MediaControlView2_subtitle_track_number_text, i + 1);
- mSubtitleDescriptionsList.add(track);
+ switch (mSettingsMode) {
+ case SETTINGS_MODE_MAIN:
+ if (position == SETTINGS_MODE_AUDIO_TRACK) {
+ mSubSettingsAdapter.setTexts(mAudioTrackList);
+ mSubSettingsAdapter.setCheckPosition(mSelectedAudioTrackIndex);
+ mSettingsMode = SETTINGS_MODE_AUDIO_TRACK;
+ } else if (position == SETTINGS_MODE_PLAYBACK_SPEED) {
+ mSubSettingsAdapter.setTexts(mPlaybackSpeedTextList);
+ mSubSettingsAdapter.setCheckPosition(mSelectedSpeedIndex);
+ mSettingsMode = SETTINGS_MODE_PLAYBACK_SPEED;
+ } else if (position == SETTINGS_MODE_HELP) {
+ // TODO: implement this.
+ mSettingsWindow.dismiss();
+ return;
}
- mSettingsAdapter = new SettingsAdapter(mSubtitleDescriptionsList, null,
- null, true);
+ displaySettingsWindow(mSubSettingsAdapter);
break;
- case 1:
- // TODO: add additional audio track details
- mAudioTrackList = new ArrayList<String>();
- mAudioTrackList.add(mResources.getString(
- R.string.MediaControlView2_audio_track_none_text));
- for (int i = 0; i < mAudioTrackCount; i++) {
- String track = mResources.getString(
- R.string.MediaControlView2_audio_track_number_text, i + 1);
- mAudioTrackList.add(track);
+ case SETTINGS_MODE_AUDIO_TRACK:
+ if (position != mSelectedAudioTrackIndex) {
+ mSelectedAudioTrackIndex = position;
+ if (mAudioTrackCount > 0) {
+ Bundle extra = new Bundle();
+ extra.putInt(KEY_SELECTED_AUDIO_INDEX, position);
+ mController.sendCommand(COMMAND_SELECT_AUDIO_TRACK, extra, null);
+ }
+ mSettingsSubTextsList.set(SETTINGS_MODE_AUDIO_TRACK,
+ mSubSettingsAdapter.getMainText(position));
}
- mSettingsAdapter = new SettingsAdapter(mAudioTrackList, null,
- null, true);
+ mSettingsWindow.dismiss();
break;
- case 2:
- // TODO: add support for multiple quality video tracks
- mSettingsAdapter = new SettingsAdapter(mVideoQualityList, null,
- null, true);
+ case SETTINGS_MODE_PLAYBACK_SPEED:
+ if (position != mSelectedSpeedIndex) {
+ mSelectedSpeedIndex = position;
+ Bundle extra = new Bundle();
+ extra.putFloat(KEY_PLAYBACK_SPEED, mPlaybackSpeedList.get(position));
+ mController.sendCommand(COMMAND_SET_PLAYBACK_SPEED, extra, null);
+ mSettingsSubTextsList.set(SETTINGS_MODE_PLAYBACK_SPEED,
+ mSubSettingsAdapter.getMainText(position));
+ }
+ mSettingsWindow.dismiss();
break;
- case 3:
- // TODO: implement code to reflect change in speed.
- mSettingsAdapter = new SettingsAdapter(mPlaybackSpeedTextIdsList, null,
- null, true);
+ case SETTINGS_MODE_HELP:
+ // TODO: implement this.
break;
- default:
- return;
+ case SETTINGS_MODE_SUBTITLE_TRACK:
+ if (position != mSelectedSubtitleTrackIndex) {
+ mSelectedSubtitleTrackIndex = position;
+ if (position > 0) {
+ Bundle extra = new Bundle();
+ extra.putInt(KEY_SELECTED_SUBTITLE_INDEX, position - 1);
+ mController.sendCommand(
+ MediaControlView2Impl.COMMAND_SHOW_SUBTITLE, extra, null);
+ mSubtitleButton.setImageDrawable(mResources.getDrawable(
+ R.drawable.ic_media_subtitle_enabled, null));
+ mSubtitleIsEnabled = true;
+ } else {
+ mController.sendCommand(
+ MediaControlView2Impl.COMMAND_HIDE_SUBTITLE, null, null);
+ mSubtitleButton.setImageDrawable(mResources.getDrawable(
+ R.drawable.ic_media_subtitle_disabled, null));
+ mSubtitleIsEnabled = false;
+ }
+ }
+ mSettingsWindow.dismiss();
+ break;
+ case SETTINGS_MODE_VIDEO_QUALITY:
+ // TODO: add support for video quality
+ mSelectedVideoQualityIndex = position;
+ mSettingsWindow.dismiss();
+ break;
}
- mSettingsListView.setAdapter(mSettingsAdapter);
- int itemHeight = mResources.getDimensionPixelSize(
- R.dimen.MediaControlView2_settings_height);
- int totalHeight = mSettingsAdapter.getCount() * itemHeight;
- int margin = (-1) * mResources.getDimensionPixelSize(
- R.dimen.MediaControlView2_settings_offset);
- mSettingsWindow.dismiss();
- mSettingsWindow.showAsDropDown(mInstance, margin, margin - totalHeight,
- Gravity.BOTTOM | Gravity.RIGHT);
}
};
@@ -953,80 +983,56 @@
}
private void initializeSettingsLists() {
- if (mSettingsMainTextsList == null) {
- mSettingsMainTextsList = new ArrayList<String>();
- mSettingsMainTextsList.add(
- mResources.getString(R.string.MediaControlView2_subtitle_text));
- mSettingsMainTextsList.add(
- mResources.getString(R.string.MediaControlView2_audio_track_text));
- mSettingsMainTextsList.add(
- mResources.getString(R.string.MediaControlView2_video_quality_text));
- mSettingsMainTextsList.add(
- mResources.getString(R.string.MediaControlView2_playback_speed_text));
- mSettingsMainTextsList.add(
- mResources.getString(R.string.MediaControlView2_help_text));
- }
+ mSettingsMainTextsList = new ArrayList<String>();
+ mSettingsMainTextsList.add(
+ mResources.getString(R.string.MediaControlView2_audio_track_text));
+ mSettingsMainTextsList.add(
+ mResources.getString(R.string.MediaControlView2_playback_speed_text));
+ mSettingsMainTextsList.add(
+ mResources.getString(R.string.MediaControlView2_help_text));
- // TODO: Update the following code to be dynamic.
- if (mSettingsSubTextsList == null) {
- mSettingsSubTextsList = new ArrayList<String>();
- mSettingsSubTextsList.add(
- mResources.getString(R.string.MediaControlView2_subtitle_off_text));
- mSettingsSubTextsList.add(
- mResources.getString(R.string.MediaControlView2_audio_track_none_text));
- mSettingsSubTextsList.add(
- mResources.getString(R.string.MediaControlView2_video_quality_auto_text));
- mSettingsSubTextsList.add(
- mResources.getString(R.string.MediaControlView2_playback_speed_1x_text));
- mSettingsSubTextsList.add(RESOURCE_EMPTY);
- }
+ mSettingsSubTextsList = new ArrayList<String>();
+ mSettingsSubTextsList.add(
+ mResources.getString(R.string.MediaControlView2_audio_track_none_text));
+ mSettingsSubTextsList.add(
+ mResources.getStringArray(
+ R.array.MediaControlView2_playback_speeds)[PLAYBACK_SPEED_1x_INDEX]);
+ mSettingsSubTextsList.add(RESOURCE_EMPTY);
- if (mSettingsIconIdsList == null) {
- mSettingsIconIdsList = new ArrayList<Integer>();
- mSettingsIconIdsList.add(R.drawable.ic_closed_caption_off);
- mSettingsIconIdsList.add(R.drawable.ic_audiotrack);
- mSettingsIconIdsList.add(R.drawable.ic_high_quality);
- mSettingsIconIdsList.add(R.drawable.ic_play_circle_filled);
- mSettingsIconIdsList.add(R.drawable.ic_help);
- }
+ mSettingsIconIdsList = new ArrayList<Integer>();
+ mSettingsIconIdsList.add(R.drawable.ic_audiotrack);
+ mSettingsIconIdsList.add(R.drawable.ic_play_circle_filled);
+ mSettingsIconIdsList.add(R.drawable.ic_help);
- if (mSubtitleDescriptionsList == null) {
- mSubtitleDescriptionsList = new ArrayList<String>();
- mSubtitleDescriptionsList.add(
- mResources.getString(R.string.MediaControlView2_subtitle_off_text));
- }
+ mAudioTrackList = new ArrayList<String>();
+ mAudioTrackList.add(
+ mResources.getString(R.string.MediaControlView2_audio_track_none_text));
- if (mAudioTrackList == null) {
- mAudioTrackList = new ArrayList<String>();
- mAudioTrackList.add(
- mResources.getString(R.string.MediaControlView2_audio_track_none_text));
- }
+ mVideoQualityList = new ArrayList<String>();
+ mVideoQualityList.add(
+ mResources.getString(R.string.MediaControlView2_video_quality_auto_text));
- if (mVideoQualityList == null) {
- mVideoQualityList = new ArrayList<String>();
- mVideoQualityList.add(
- mResources.getString(R.string.MediaControlView2_video_quality_auto_text));
- }
+ mPlaybackSpeedTextList = new ArrayList<String>(Arrays.asList(
+ mResources.getStringArray(R.array.MediaControlView2_playback_speeds)));
+ // Select the "1x" speed as the default value.
+ mSelectedSpeedIndex = PLAYBACK_SPEED_1x_INDEX;
- if (mPlaybackSpeedTextIdsList == null) {
- mPlaybackSpeedTextIdsList = new ArrayList<String>();
- mPlaybackSpeedTextIdsList.add(
- mResources.getString(R.string.MediaControlView2_playback_speed_0_25x_text));
- mPlaybackSpeedTextIdsList.add(
- mResources.getString(R.string.MediaControlView2_playback_speed_0_5x_text));
- mPlaybackSpeedTextIdsList.add(
- mResources.getString(R.string.MediaControlView2_playback_speed_0_75x_text));
- mPlaybackSpeedTextIdsList.add(
- mResources.getString(R.string.MediaControlView2_playback_speed_1x_text));
- mPlaybackSpeedTextIdsList.add(
- mResources.getString(R.string.MediaControlView2_playback_speed_1_25x_text));
- mPlaybackSpeedTextIdsList.add(
- mResources.getString(R.string.MediaControlView2_playback_speed_1_5x_text));
- mPlaybackSpeedTextIdsList.add(
- mResources.getString(R.string.MediaControlView2_playback_speed_2x_text));
+ mPlaybackSpeedList = new ArrayList<Float>();
+ int[] speeds = mResources.getIntArray(R.array.speed_multiplied_by_100);
+ for (int i = 0; i < speeds.length; i++) {
+ float speed = (float) speeds[i] / 100.0f;
+ mPlaybackSpeedList.add(speed);
}
}
+ private void displaySettingsWindow(BaseAdapter adapter) {
+ mSettingsListView.setAdapter(adapter);
+ int totalHeight = adapter.getCount() * mSettingsItemHeight;
+ mSettingsWindow.dismiss();
+ mSettingsWindow.showAsDropDown(mInstance, mSettingsWindowMargin,
+ mSettingsWindowMargin - totalHeight, Gravity.BOTTOM | Gravity.RIGHT);
+ }
+
private class MediaControllerCallback extends MediaController.Callback {
@Override
public void onPlaybackStateChanged(PlaybackState state) {
@@ -1065,16 +1071,13 @@
if (mPlaybackActions != mPlaybackState.getActions()) {
long newActions = mPlaybackState.getActions();
if ((newActions & PlaybackState.ACTION_PAUSE) != 0) {
- mPlayPauseButton.clearColorFilter();
- mPlayPauseButton.setEnabled(true);
+ mPlayPauseButton.setVisibility(View.VISIBLE);
}
if ((newActions & PlaybackState.ACTION_REWIND) != 0) {
- mRewButton.clearColorFilter();
- mRewButton.setEnabled(true);
+ mRewButton.setVisibility(View.VISIBLE);
}
if ((newActions & PlaybackState.ACTION_FAST_FORWARD) != 0) {
- mFfwdButton.clearColorFilter();
- mFfwdButton.setEnabled(true);
+ mFfwdButton.setVisibility(View.VISIBLE);
}
if ((newActions & PlaybackState.ACTION_SEEK_TO) != 0) {
mSeekAvailable = true;
@@ -1122,16 +1125,42 @@
switch (event) {
case EVENT_UPDATE_TRACK_STATUS:
mVideoTrackCount = extras.getInt(KEY_VIDEO_TRACK_COUNT);
+ // If there is one or more audio tracks, and this information has not been
+ // reflected into the Settings window yet, automatically check the first track.
+ // Otherwise, the Audio Track selection will be defaulted to "None".
mAudioTrackCount = extras.getInt(KEY_AUDIO_TRACK_COUNT);
- int newSubtitleTrackCount = extras.getInt(KEY_SUBTITLE_TRACK_COUNT);
- if (newSubtitleTrackCount > 0) {
- mSubtitleButton.clearColorFilter();
- mSubtitleButton.setEnabled(true);
+ mAudioTrackList = new ArrayList<String>();
+ if (mAudioTrackCount > 0) {
+ // TODO: add more text about track info.
+ for (int i = 0; i < mAudioTrackCount; i++) {
+ String track = mResources.getString(
+ R.string.MediaControlView2_audio_track_number_text, i + 1);
+ mAudioTrackList.add(track);
+ }
+ // Change sub text inside the Settings window.
+ mSettingsSubTextsList.set(SETTINGS_MODE_AUDIO_TRACK,
+ mAudioTrackList.get(0));
} else {
- mSubtitleButton.setColorFilter(R.color.gray);
+ mAudioTrackList.add(mResources.getString(
+ R.string.MediaControlView2_audio_track_none_text));
+ }
+
+ mSubtitleTrackCount = extras.getInt(KEY_SUBTITLE_TRACK_COUNT);
+ mSubtitleDescriptionsList = new ArrayList<String>();
+ if (mSubtitleTrackCount > 0) {
+ mSubtitleButton.setVisibility(View.VISIBLE);
+ mSubtitleButton.setEnabled(true);
+ mSubtitleDescriptionsList.add(mResources.getString(
+ R.string.MediaControlView2_subtitle_off_text));
+ for (int i = 0; i < mSubtitleTrackCount; i++) {
+ String track = mResources.getString(
+ R.string.MediaControlView2_subtitle_track_number_text, i + 1);
+ mSubtitleDescriptionsList.add(track);
+ }
+ } else {
+ mSubtitleButton.setVisibility(View.GONE);
mSubtitleButton.setEnabled(false);
}
- mSubtitleTrackCount = newSubtitleTrackCount;
break;
case EVENT_UPDATE_MEDIA_TYPE_STATUS:
boolean newStatus = extras.getBoolean(KEY_STATE_IS_ADVERTISEMENT);
@@ -1145,17 +1174,29 @@
}
private class SettingsAdapter extends BaseAdapter {
- List<Integer> mIconIds;
- List<String> mMainTexts;
- List<String> mSubTexts;
- boolean mIsCheckable;
+ private List<Integer> mIconIds;
+ private List<String> mMainTexts;
+ private List<String> mSubTexts;
public SettingsAdapter(List<String> mainTexts, @Nullable List<String> subTexts,
- @Nullable List<Integer> iconIds, boolean isCheckable) {
+ @Nullable List<Integer> iconIds) {
mMainTexts = mainTexts;
mSubTexts = subTexts;
mIconIds = iconIds;
- mIsCheckable = isCheckable;
+ }
+
+ public void updateSubTexts(List<String> subTexts) {
+ mSubTexts = subTexts;
+ notifyDataSetChanged();
+ }
+
+ public String getMainText(int position) {
+ if (mMainTexts != null) {
+ if (position < mMainTexts.size()) {
+ return mMainTexts.get(position);
+ }
+ }
+ return RESOURCE_EMPTY;
}
@Override
@@ -1184,7 +1225,6 @@
TextView mainTextView = (TextView) row.findViewById(R.id.main_text);
TextView subTextView = (TextView) row.findViewById(R.id.sub_text);
ImageView iconView = (ImageView) row.findViewById(R.id.icon);
- ImageView checkView = (ImageView) row.findViewById(R.id.check);
// Set main text
mainTextView.setText(mMainTexts.get(position));
@@ -1206,13 +1246,72 @@
// Otherwise, set main icon.
iconView.setImageDrawable(mResources.getDrawable(mIconIds.get(position), null));
}
+ return row;
+ }
- // Set check icon
- // TODO: make the following code dynamic
- if (!mIsCheckable) {
- checkView.setVisibility(View.GONE);
+ public void setSubTexts(List<String> subTexts) {
+ mSubTexts = subTexts;
+ }
+ }
+
+ // TODO: extend this class from SettingsAdapter
+ private class SubSettingsAdapter extends BaseAdapter {
+ private List<String> mTexts;
+ private int mCheckPosition;
+
+ public SubSettingsAdapter(List<String> texts, int checkPosition) {
+ mTexts = texts;
+ mCheckPosition = checkPosition;
+ }
+
+ public String getMainText(int position) {
+ if (mTexts != null) {
+ if (position < mTexts.size()) {
+ return mTexts.get(position);
+ }
+ }
+ return RESOURCE_EMPTY;
+ }
+
+ @Override
+ public int getCount() {
+ return (mTexts == null) ? 0 : mTexts.size();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ // Auto-generated method stub--does not have any purpose here
+ // TODO: implement this.
+ return 0;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ // Auto-generated method stub--does not have any purpose here
+ // TODO: implement this.
+ return null;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup container) {
+ View row = ApiHelper.inflateLibLayout(mInstance.getContext(),
+ R.layout.sub_settings_list_item);
+ TextView textView = (TextView) row.findViewById(R.id.text);
+ ImageView checkView = (ImageView) row.findViewById(R.id.check);
+
+ textView.setText(mTexts.get(position));
+ if (position != mCheckPosition) {
+ checkView.setVisibility(View.INVISIBLE);
}
return row;
}
+
+ public void setTexts(List<String> texts) {
+ mTexts = texts;
+ }
+
+ public void setCheckPosition(int checkPosition) {
+ mCheckPosition = checkPosition;
+ }
}
}
diff --git a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
index 0bb659d..d4d289a 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
@@ -86,6 +86,7 @@
private static final int STATE_PLAYBACK_COMPLETED = 5;
private static final int INVALID_TRACK_INDEX = -1;
+ private static final float INVALID_SPEED = 0f;
private AccessibilityManager mAccessibilityManager;
private AudioManager mAudioManager;
@@ -854,8 +855,6 @@
}
if (select) {
if (mSubtitleTrackIndices.size() > 0) {
- // TODO: make this selection dynamic
- mSelectedSubtitleTrackIndex = mSubtitleTrackIndices.get(0);
mMediaPlayer.selectTrack(mSelectedSubtitleTrackIndex);
mSubtitleView.setVisibility(View.VISIBLE);
}
@@ -881,9 +880,17 @@
mAudioTrackIndices.add(i);
} else if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE
|| trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
- mSubtitleTrackIndices.add(i);
+ mSubtitleTrackIndices.add(i);
}
}
+ // Select first tracks as default
+ if (mVideoTrackIndices.size() > 0) {
+ mSelectedVideoTrackIndex = 0;
+ }
+ if (mAudioTrackIndices.size() > 0) {
+ mSelectedAudioTrackIndex = 0;
+ }
+
Bundle data = new Bundle();
data.putInt(MediaControlView2Impl.KEY_VIDEO_TRACK_COUNT, mVideoTrackIndices.size());
data.putInt(MediaControlView2Impl.KEY_AUDIO_TRACK_COUNT, mAudioTrackIndices.size());
@@ -1048,10 +1055,19 @@
} else {
switch (command) {
case MediaControlView2Impl.COMMAND_SHOW_SUBTITLE:
- mInstance.setSubtitleEnabled(true);
+ int subtitleIndex = args.getInt(
+ MediaControlView2Impl.KEY_SELECTED_SUBTITLE_INDEX,
+ INVALID_TRACK_INDEX);
+ if (subtitleIndex != INVALID_TRACK_INDEX) {
+ int subtitleTrackIndex = mSubtitleTrackIndices.get(subtitleIndex);
+ if (subtitleTrackIndex != mSelectedSubtitleTrackIndex) {
+ mSelectedSubtitleTrackIndex = subtitleTrackIndex;
+ selectOrDeselectSubtitle(true);
+ }
+ }
break;
case MediaControlView2Impl.COMMAND_HIDE_SUBTITLE:
- mInstance.setSubtitleEnabled(false);
+ selectOrDeselectSubtitle(false);
break;
case MediaControlView2Impl.COMMAND_SET_FULLSCREEN:
if (mFullScreenRequestListener != null) {
@@ -1060,6 +1076,25 @@
args.getBoolean(MediaControlView2Impl.ARGUMENT_KEY_FULLSCREEN));
}
break;
+ case MediaControlView2Impl.COMMAND_SELECT_AUDIO_TRACK:
+ int audioIndex = args.getInt(MediaControlView2Impl.KEY_SELECTED_AUDIO_INDEX,
+ INVALID_TRACK_INDEX);
+ if (audioIndex != INVALID_TRACK_INDEX) {
+ int audioTrackIndex = mAudioTrackIndices.get(audioIndex);
+ if (audioTrackIndex != mSelectedAudioTrackIndex) {
+ mSelectedAudioTrackIndex = audioTrackIndex;
+ mMediaPlayer.selectTrack(mSelectedAudioTrackIndex);
+ }
+ }
+ break;
+ case MediaControlView2Impl.COMMAND_SET_PLAYBACK_SPEED:
+ float speed = args.getFloat(
+ MediaControlView2Impl.KEY_PLAYBACK_SPEED, INVALID_SPEED);
+ if (speed != INVALID_SPEED && speed != mSpeed) {
+ mInstance.setSpeed(speed);
+ mSpeed = speed;
+ }
+ break;
}
}
showController();