MediaControlView2: Add Additional UX for Settings

This CL adds additional UX for Settings, adding a second ListView to
show the view for choosing CC, audio track, video quality, and
playback speed.

Also, this CL allows video & audio track information to be
sent to MediaControlView2 from VideoView2.

Bug: 73703113
Test: manually
Change-Id: Ic5f7223b2688fe7a11e0ef46fc3aec0bb900f5ac
diff --git a/packages/MediaComponents/res/layout/media_controller.xml b/packages/MediaComponents/res/layout/media_controller.xml
index 38f139d..aafe8b0 100644
--- a/packages/MediaComponents/res/layout/media_controller.xml
+++ b/packages/MediaComponents/res/layout/media_controller.xml
@@ -194,6 +194,9 @@
                 android:visibility="gone" />
 
             <ImageButton
+                android:id="@+id/mute"
+                style="@style/BottomBarButton.Mute" />
+            <ImageButton
                 android:id="@+id/subtitle"
                 android:scaleType="fitCenter"
                 style="@style/BottomBarButton.CC" />
@@ -221,12 +224,12 @@
                 android:layout_height="wrap_content" />
 
             <ImageButton
-                android:id="@+id/mute"
-                style="@style/BottomBarButton.Mute" />
-            <ImageButton
                 android:id="@+id/aspect_ratio"
                 style="@style/BottomBarButton.AspectRatio" />
             <ImageButton
+                android:id="@+id/video_quality"
+                style="@style/BottomBarButton.VideoQuality" />
+            <ImageButton
                 android:id="@+id/settings"
                 style="@style/BottomBarButton.Settings" />
             <ImageButton
diff --git a/packages/MediaComponents/res/values/strings.xml b/packages/MediaComponents/res/values/strings.xml
index 5f9c78d..305cef4 100644
--- a/packages/MediaComponents/res/values/strings.xml
+++ b/packages/MediaComponents/res/values/strings.xml
@@ -105,11 +105,27 @@
     </string>
     <!-- Placeholder text indicating that the user can press the button to go to an external website. -->
     <string name="MediaControlView2_ad_text">Visit Advertiser</string>
-    <string name="MediaControlView2_cc_text">Closed caption</string>
+    <string name="MediaControlView2_subtitle_text">Closed caption</string>
+    <string name="MediaControlView2_subtitle_off_text">Off</string>
     <string name="MediaControlView2_audio_track_text">Audio track</string>
+    <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_normal_text">Normal</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 &amp; feedback</string>
+    <!-- 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>
+    </string>
+    <!-- Text for displaying audio track number. -->
+    <string name="MediaControlView2_audio_track_number_text">
+        Track <xliff:g id="audio_number" example="1">%1$s</xliff:g>
+    </string>
 </resources>
diff --git a/packages/MediaComponents/res/values/style.xml b/packages/MediaComponents/res/values/style.xml
index 299f16b..23c7bc9 100644
--- a/packages/MediaComponents/res/values/style.xml
+++ b/packages/MediaComponents/res/values/style.xml
@@ -81,4 +81,8 @@
     <style name="BottomBarButton.Mute">
         <item name="android:src">@drawable/ic_mute</item>
     </style>
+
+    <style name="BottomBarButton.VideoQuality">
+        <item name="android:src">@drawable/ic_high_quality</item>
+    </style>
 </resources>
diff --git a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
index f440ad6..e10aaca 100644
--- a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
@@ -30,6 +30,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.AdapterView;
 import android.widget.BaseAdapter;
 import android.widget.Button;
 import android.widget.ImageButton;
@@ -63,8 +64,11 @@
     static final String ARGUMENT_KEY_FULLSCREEN = "fullScreen";
 
     // TODO: Move these constants to public api to support custom video view.
-    static final String KEY_STATE_CONTAINS_SUBTITLE = "StateContainsSubtitle";
-    static final String EVENT_UPDATE_SUBTITLE_STATUS = "UpdateSubtitleStatus";
+    // TODO: Combine these constants into one regarding TrackInfo.
+    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 EVENT_UPDATE_TRACK_STATUS = "UpdateTrackStatus";
 
     // TODO: Remove this once integrating with MediaSession2 & MediaMetadata2
     static final String KEY_STATE_IS_ADVERTISEMENT = "MediaTypeAdvertisement";
@@ -76,6 +80,7 @@
     private static final int FORWARD_TIME_MS = 30000;
     private static final int AD_SKIP_WAIT_TIME_MS = 5000;
     private static final int RESOURCE_NON_EXISTENT = -1;
+    private static final String RESOURCE_EMPTY = "";
 
     private Resources mResources;
     private MediaController mController;
@@ -91,13 +96,15 @@
     private int mDuration;
     private int mPrevState;
     private int mPrevLeftBarWidth;
+    private int mVideoTrackCount;
+    private int mAudioTrackCount;
+    private int mSubtitleTrackCount;
     private long mPlaybackActions;
     private boolean mDragging;
     private boolean mIsFullScreen;
     private boolean mOverflowExpanded;
     private boolean mIsStopped;
     private boolean mSubtitleIsEnabled;
-    private boolean mContainsSubtitle;
     private boolean mSeekAvailable;
     private boolean mIsAdvertisement;
     private ImageButton mPlayPauseButton;
@@ -118,11 +125,17 @@
     private ImageButton mAspectRationButton;
     private ImageButton mSettingsButton;
 
+    private ListView mSettingsListView;
     private PopupWindow mSettingsWindow;
     private SettingsAdapter mSettingsAdapter;
-    private List<Integer> mSettingsMainTextIdsList;
-    private List<Integer> mSettingsSubTextIdsList;
+
+    private List<String> mSettingsMainTextsList;
+    private List<String> mSettingsSubTextsList;
     private List<Integer> mSettingsIconIdsList;
+    private List<String> mSubtitleDescriptionsList;
+    private List<String> mAudioTrackList;
+    private List<String> mVideoQualityList;
+    private List<String> mPlaybackSpeedTextIdsList;
 
     private CharSequence mPlayDescription;
     private CharSequence mPauseDescription;
@@ -200,7 +213,7 @@
                 }
                 break;
             case MediaControlView2.BUTTON_SUBTITLE:
-                if (mSubtitleButton != null && mContainsSubtitle) {
+                if (mSubtitleButton != null && mSubtitleTrackCount > 0) {
                     mSubtitleButton.setVisibility(visibility);
                 }
                 break;
@@ -459,17 +472,17 @@
         mAdRemainingView = v.findViewById(R.id.ad_remaining);
         mAdExternalLink = v.findViewById(R.id.ad_external_link);
 
-        populateResourceIds();
-        ListView settingsListView = (ListView) ApiHelper.inflateLibLayout(mInstance.getContext(),
+        initializeSettingsLists();
+        mSettingsListView = (ListView) ApiHelper.inflateLibLayout(mInstance.getContext(),
                 R.layout.settings_list);
-        mSettingsAdapter = new SettingsAdapter(mSettingsMainTextIdsList, mSettingsSubTextIdsList,
-                mSettingsIconIdsList, true);
-        settingsListView.setAdapter(mSettingsAdapter);
-
+        mSettingsAdapter = new SettingsAdapter(mSettingsMainTextsList, mSettingsSubTextsList,
+                mSettingsIconIdsList, false);
+        mSettingsListView.setAdapter(mSettingsAdapter);
+        mSettingsListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+        mSettingsListView.setOnItemClickListener(mSettingsItemClickListener);
         int width = mResources.getDimensionPixelSize(R.dimen.MediaControlView2_settings_width);
-        mSettingsWindow = new PopupWindow(settingsListView, width,
+        mSettingsWindow = new PopupWindow(mSettingsListView, width,
                 ViewGroup.LayoutParams.WRAP_CONTENT, true);
-        // TODO: add listener to list view to allow each item to be selected.
     }
 
     /**
@@ -769,11 +782,72 @@
     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);
+        }
+    };
+
+    private final AdapterView.OnItemClickListener mSettingsItemClickListener
+            = 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);
+                    }
+                    mSettingsAdapter = new SettingsAdapter(mSubtitleDescriptionsList, null,
+                            null, true);
+                    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);
+                    }
+                    mSettingsAdapter = new SettingsAdapter(mAudioTrackList, null,
+                            null, true);
+                    break;
+                case 2:
+                    // TODO: add support for multiple quality video tracks
+                    mSettingsAdapter = new SettingsAdapter(mVideoQualityList, null,
+                            null, true);
+                    break;
+                case 3:
+                    // TODO: implement code to reflect change in speed.
+                    mSettingsAdapter = new SettingsAdapter(mPlaybackSpeedTextIdsList, null,
+                            null, true);
+                    break;
+                default:
+                    return;
+            }
+            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);
         }
@@ -860,29 +934,79 @@
         }
     }
 
-    private void populateResourceIds() {
-        // TODO: create record class for storing this info
-        mSettingsMainTextIdsList = new ArrayList<Integer>();
-        mSettingsMainTextIdsList.add(R.string.MediaControlView2_cc_text);
-        mSettingsMainTextIdsList.add(R.string.MediaControlView2_audio_track_text);
-        mSettingsMainTextIdsList.add(R.string.MediaControlView2_video_quality_text);
-        mSettingsMainTextIdsList.add(R.string.MediaControlView2_playback_speed_text);
-        mSettingsMainTextIdsList.add(R.string.MediaControlView2_help_text);
+    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));
+        }
 
         // TODO: Update the following code to be dynamic.
-        mSettingsSubTextIdsList = new ArrayList<Integer>();
-        mSettingsSubTextIdsList.add(R.string.MediaControlView2_cc_text);
-        mSettingsSubTextIdsList.add(R.string.MediaControlView2_audio_track_text);
-        mSettingsSubTextIdsList.add(R.string.MediaControlView2_video_quality_text);
-        mSettingsSubTextIdsList.add(R.string.MediaControlView2_playback_speed_text);
-        mSettingsSubTextIdsList.add(RESOURCE_NON_EXISTENT);
+        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);
+        }
 
-        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);
+        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);
+        }
+
+        if (mSubtitleDescriptionsList == null) {
+            mSubtitleDescriptionsList = new ArrayList<String>();
+            mSubtitleDescriptionsList.add(
+                    mResources.getString(R.string.MediaControlView2_subtitle_off_text));
+        }
+
+        if (mAudioTrackList == null) {
+            mAudioTrackList = new ArrayList<String>();
+            mAudioTrackList.add(
+                    mResources.getString(R.string.MediaControlView2_audio_track_none_text));
+        }
+
+        if (mVideoQualityList == null) {
+            mVideoQualityList = new ArrayList<String>();
+            mVideoQualityList.add(
+                    mResources.getString(R.string.MediaControlView2_video_quality_auto_text));
+        }
+
+        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));
+        }
     }
 
     private class MediaControllerCallback extends MediaController.Callback {
@@ -977,45 +1101,48 @@
 
         @Override
         public void onSessionEvent(String event, Bundle extras) {
-            if (event.equals(EVENT_UPDATE_SUBTITLE_STATUS)) {
-                boolean newSubtitleStatus = extras.getBoolean(KEY_STATE_CONTAINS_SUBTITLE);
-                if (newSubtitleStatus != mContainsSubtitle) {
-                    if (newSubtitleStatus) {
+            switch (event) {
+                case EVENT_UPDATE_TRACK_STATUS:
+                    mVideoTrackCount = extras.getInt(KEY_VIDEO_TRACK_COUNT);
+                    mAudioTrackCount = extras.getInt(KEY_AUDIO_TRACK_COUNT);
+                    int newSubtitleTrackCount = extras.getInt(KEY_SUBTITLE_TRACK_COUNT);
+                    if (newSubtitleTrackCount > 0) {
                         mSubtitleButton.clearColorFilter();
                         mSubtitleButton.setEnabled(true);
                     } else {
                         mSubtitleButton.setColorFilter(R.color.gray);
                         mSubtitleButton.setEnabled(false);
                     }
-                    mContainsSubtitle = newSubtitleStatus;
-                }
-            } else if (event.equals(EVENT_UPDATE_MEDIA_TYPE_STATUS)) {
-                boolean newStatus = extras.getBoolean(KEY_STATE_IS_ADVERTISEMENT);
-                if (newStatus != mIsAdvertisement) {
-                    mIsAdvertisement = newStatus;
-                    updateLayout();
-                }
+                    mSubtitleTrackCount = newSubtitleTrackCount;
+                    break;
+                case EVENT_UPDATE_MEDIA_TYPE_STATUS:
+                    boolean newStatus = extras.getBoolean(KEY_STATE_IS_ADVERTISEMENT);
+                    if (newStatus != mIsAdvertisement) {
+                        mIsAdvertisement = newStatus;
+                        updateLayout();
+                    }
+                    break;
             }
         }
     }
 
     private class SettingsAdapter extends BaseAdapter {
-        List<Integer> mMainTextIds;
-        List<Integer> mSubTextIds;
         List<Integer> mIconIds;
+        List<String> mMainTexts;
+        List<String> mSubTexts;
         boolean mIsCheckable;
 
-        public SettingsAdapter(List<Integer> mainTextIds, @Nullable List<Integer> subTextIds,
+        public SettingsAdapter(List<String> mainTexts, @Nullable List<String> subTexts,
                 @Nullable List<Integer> iconIds, boolean isCheckable) {
-            mMainTextIds = mainTextIds;
-            mSubTextIds = subTextIds;
+            mMainTexts = mainTexts;
+            mSubTexts = subTexts;
             mIconIds = iconIds;
             mIsCheckable = isCheckable;
         }
 
         @Override
         public int getCount() {
-            return (mMainTextIds == null) ? 0 : mMainTextIds.size();
+            return (mMainTexts == null) ? 0 : mMainTexts.size();
         }
 
         @Override
@@ -1042,15 +1169,15 @@
             ImageView checkView = (ImageView) row.findViewById(R.id.check);
 
             // Set main text
-            mainTextView.setText(mResources.getString(mMainTextIds.get(position)));
+            mainTextView.setText(mMainTexts.get(position));
 
             // Remove sub text and center the main text if sub texts do not exist at all or the sub
-            // text at this particular position is set to RESOURCE_NON_EXISTENT.
-            if (mSubTextIds == null || mSubTextIds.get(position) == RESOURCE_NON_EXISTENT) {
+            // text at this particular position is empty.
+            if (mSubTexts == null || mSubTexts.get(position) == RESOURCE_EMPTY) {
                 subTextView.setVisibility(View.GONE);
             } else {
                 // Otherwise, set sub text.
-                subTextView.setText(mResources.getString(mSubTextIds.get(position)));
+                subTextView.setText(mSubTexts.get(position));
             }
 
             // Remove main icon and set visibility to gone if icons are set to null or the icon at
diff --git a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
index 805c262..dd6a27d 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
@@ -123,10 +123,17 @@
     private int mVideoWidth;
     private int mVideoHeight;
 
+    private ArrayList<Integer> mVideoTrackIndices;
+    private ArrayList<Integer> mAudioTrackIndices;
     private ArrayList<Integer> mSubtitleTrackIndices;
+
+    // selected video/audio/subtitle track index as MediaPlayer2 returns
+    private int mSelectedVideoTrackIndex;
+    private int mSelectedAudioTrackIndex;
+    private int mSelectedSubtitleTrackIndex;
+
     private SubtitleView mSubtitleView;
     private boolean mSubtitleEnabled;
-    private int mSelectedTrackIndex;  // selected subtitle track index as MediaPlayer2 returns
 
     private float mSpeed;
     // TODO: Remove mFallbackSpeed when integration with MediaPlayer2's new setPlaybackParams().
@@ -147,7 +154,7 @@
         mVideoHeight = 0;
         mSpeed = 1.0f;
         mFallbackSpeed = mSpeed;
-        mSelectedTrackIndex = INVALID_TRACK_INDEX;
+        mSelectedSubtitleTrackIndex = INVALID_TRACK_INDEX;
         // TODO: add attributes to get this value.
         mShowControllerIntervalMs = DEFAULT_SHOW_CONTROLLER_INTERVAL_MS;
 
@@ -409,8 +416,11 @@
         if (mMediaRouter != null) {
             mMediaRouter.setMediaSession(mMediaSession);
         }
-
         attachMediaControlView();
+        // TODO: remove this after moving MediaSession creating code inside initializing VideoView2
+        if (mCurrentState == STATE_PREPARED) {
+            extractTracks();
+        }
     }
 
     @Override
@@ -773,48 +783,44 @@
         }
         if (select) {
             if (mSubtitleTrackIndices.size() > 0) {
-                // Select first subtitle track
-                mSelectedTrackIndex = mSubtitleTrackIndices.get(0);
-                mMediaPlayer.selectTrack(mSelectedTrackIndex);
+                // TODO: make this selection dynamic
+                mSelectedSubtitleTrackIndex = mSubtitleTrackIndices.get(0);
+                mMediaPlayer.selectTrack(mSelectedSubtitleTrackIndex);
                 mSubtitleView.setVisibility(View.VISIBLE);
             }
         } else {
-            if (mSelectedTrackIndex != INVALID_TRACK_INDEX) {
-                mMediaPlayer.deselectTrack(mSelectedTrackIndex);
-                mSelectedTrackIndex = INVALID_TRACK_INDEX;
+            if (mSelectedSubtitleTrackIndex != INVALID_TRACK_INDEX) {
+                mMediaPlayer.deselectTrack(mSelectedSubtitleTrackIndex);
+                mSelectedSubtitleTrackIndex = INVALID_TRACK_INDEX;
                 mSubtitleView.setVisibility(View.GONE);
             }
         }
     }
 
-    private void extractSubtitleTracks() {
+    private void extractTracks() {
         MediaPlayer.TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo();
-        boolean previouslyNoTracks = mSubtitleTrackIndices == null
-                || mSubtitleTrackIndices.size() == 0;
+        mVideoTrackIndices = new ArrayList<>();
+        mAudioTrackIndices = new ArrayList<>();
         mSubtitleTrackIndices = new ArrayList<>();
         for (int i = 0; i < trackInfos.length; ++i) {
             int trackType = trackInfos[i].getTrackType();
-            if (trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE
+            if (trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_VIDEO) {
+                mVideoTrackIndices.add(i);
+            } else if (trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO) {
+                mAudioTrackIndices.add(i);
+            } else if (trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE
                     || trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
                   mSubtitleTrackIndices.add(i);
             }
         }
+        Bundle data = new Bundle();
+        data.putInt(MediaControlView2Impl.KEY_VIDEO_TRACK_COUNT, mVideoTrackIndices.size());
+        data.putInt(MediaControlView2Impl.KEY_AUDIO_TRACK_COUNT, mAudioTrackIndices.size());
+        data.putInt(MediaControlView2Impl.KEY_SUBTITLE_TRACK_COUNT, mSubtitleTrackIndices.size());
         if (mSubtitleTrackIndices.size() > 0) {
-            if (previouslyNoTracks) {
-                selectOrDeselectSubtitle(mSubtitleEnabled);
-                // Notify MediaControlView that subtitle track exists
-                // TODO: Send the subtitle track list to MediaSession for MCV2.
-                Bundle data = new Bundle();
-                data.putBoolean(MediaControlView2Impl.KEY_STATE_CONTAINS_SUBTITLE, true);
-                mMediaSession.sendSessionEvent(
-                        MediaControlView2Impl.EVENT_UPDATE_SUBTITLE_STATUS, data);
-            }
-        } else {
-            Bundle data = new Bundle();
-            data.putBoolean(MediaControlView2Impl.KEY_STATE_CONTAINS_SUBTITLE, false);
-            mMediaSession.sendSessionEvent(
-                    MediaControlView2Impl.EVENT_UPDATE_SUBTITLE_STATUS, data);
+            selectOrDeselectSubtitle(mSubtitleEnabled);
         }
+        mMediaSession.sendSessionEvent(MediaControlView2Impl.EVENT_UPDATE_TRACK_STATUS, data);
     }
 
     MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener =
@@ -845,7 +851,12 @@
             mCurrentState = STATE_PREPARED;
             // Create and set playback state for MediaControlView2
             updatePlaybackState();
-            extractSubtitleTracks();
+
+            // TODO: change this to send TrackInfos to MediaControlView2
+            // TODO: create MediaSession when initializing VideoView2
+            if (mMediaSession != null) {
+                extractTracks();
+            }
 
             if (mMediaControlView != null) {
                 mMediaControlView.setEnabled(true);
@@ -924,7 +935,7 @@
             new MediaPlayer.OnInfoListener() {
                 public boolean onInfo(MediaPlayer mp, int what, int extra) {
                     if (what == MediaPlayer.MEDIA_INFO_METADATA_UPDATE) {
-                        extractSubtitleTracks();
+                        extractTracks();
                     }
                     return true;
                 }