Merge "MediaSession2: Replace PlaybackState2" into pi-dev
diff --git a/packages/MediaComponents/res/drawable/custom_progress.xml b/packages/MediaComponents/res/drawable/custom_progress.xml
new file mode 100644
index 0000000..9731a6e
--- /dev/null
+++ b/packages/MediaComponents/res/drawable/custom_progress.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
+    <item android:id="@android:id/background">
+        <shape android:shape="rectangle" >
+            <solid android:color="#26000000" />
+        </shape>
+    </item>
+    <item android:id="@android:id/secondaryProgress">
+        <clip>
+            <shape android:shape="rectangle" >
+                <solid android:color="#5Cffffff" />
+            </shape>
+        </clip>
+    </item>
+    <item android:id="@android:id/progress">
+        <clip>
+            <shape android:shape="rectangle" >
+                <solid android:color="#ffffff" />
+            </shape>
+        </clip>
+    </item>
+</layer-list>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/custom_progress_thumb.xml b/packages/MediaComponents/res/drawable/custom_progress_thumb.xml
new file mode 100644
index 0000000..2e247f2
--- /dev/null
+++ b/packages/MediaComponents/res/drawable/custom_progress_thumb.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval" >
+    <solid android:color="#ffffff" />
+    <size
+        android:height="12dp"
+        android:width="12dp" />
+</shape>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/ic_high_quality.xml b/packages/MediaComponents/res/drawable/ic_high_quality.xml
index e27d3e2..f76e22f 100644
--- a/packages/MediaComponents/res/drawable/ic_high_quality.xml
+++ b/packages/MediaComponents/res/drawable/ic_high_quality.xml
@@ -1,9 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24.0"
-    android:viewportHeight="24.0">
+    android:width="34dp"
+    android:height="34dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:pathData="M0 0h24v24H0z" />
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M19,4L5,4c-1.11,0 -2,0.9 -2,2v12c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,6c0,-1.1 -0.9,-2 -2,-2zM11,15L9.5,15v-2h-2v2L6,15L6,9h1.5v2.5h2L9.5,9L11,9v6zM18,14c0,0.55 -0.45,1 -1,1h-0.75v1.5h-1.5L14.75,15L14,15c-0.55,0 -1,-0.45 -1,-1v-4c0,-0.55 0.45,-1 1,-1h3c0.55,0 1,0.45 1,1v4zM14.5,13.5h2v-3h-2v3z"/>
+        android:pathData="M19 4H5c-1.11 0-2 0.9-2 2v12c0 1.1 0.89 2 2 2h14c1.1 0 2-0.9 2-2V6c0-1.1-0.9-2-2-2zm-8 11H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 0.55-0.45 1-1 1h-0.75v1.5h-1.5V15H14c-0.55 0-1-0.45-1-1v-4c0-0.55 0.45 -1 1-1h3c0.55 0 1 0.45 1 1v4zm-3.5-0.5h2v-3h-2v3z" />
 </vector>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/ic_subtitle_off.xml b/packages/MediaComponents/res/drawable/ic_subtitle_off.xml
index a79cd11..c0a727a 100644
--- a/packages/MediaComponents/res/drawable/ic_subtitle_off.xml
+++ b/packages/MediaComponents/res/drawable/ic_subtitle_off.xml
@@ -9,8 +9,7 @@
         android:pathData="M0,0h24v24H0V0z" />
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M19,5.5c0.27,0,0.5,0.23,0.5,0.5v12c0,0.27-0.23,0.5-0.5,0.5H5c-0.28,0-0.5-0.22-0.5-0.5V6c0-0.28,0.22-0.5,0.5-0.5H19
-M19,4H5C3.89,4,3,4.9,3,6v12c0,1.1,0.89,2,2,2h14c1.1,0,2-0.9,2-2V6C21,4.9,20.1,4,19,4L19,4z" />
+        android:pathData="M19.5,5.5v13h-15v-13H19.5z M19,4H5C3.89,4,3,4.9,3,6v12c0,1.1,0.89,2,2,2h14c1.1,0,2-0.9,2-2V6C21,4.9,20.1,4,19,4L19,4z" />
     <path
         android:fillColor="#FFFFFF"
         android:pathData="M11,11H9.5v-0.5h-2v3h2V13H11v1c0,0.55-0.45,1-1,1H7c-0.55,0-1-0.45-1-1v-4c0-0.55,0.45-1,1-1h3c0.55,0,1,0.45,1,1V11z" />
diff --git a/packages/MediaComponents/res/drawable/ic_subtitle_on.xml b/packages/MediaComponents/res/drawable/ic_subtitle_on.xml
new file mode 100644
index 0000000..7c91c06
--- /dev/null
+++ b/packages/MediaComponents/res/drawable/ic_subtitle_on.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:pathData="M0 0h24v24H0z" />
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M19 4H5c-1.11 0-2 0.9-2 2v12c0 1.1 0.89 2 2 2h14c1.1 0 2-0.9 2-2V6c0-1.1-0.9-2-2-2zm-8 7H9.5v-0.5h-2v3h2V13H11v1c0 0.55-0.45 1-1 1H7c-0.55 0-1-0.45-1-1v-4c0-0.55 0.45 -1 1-1h3c0.55 0 1 0.45 1 1v1zm7 0h-1.5v-0.5h-2v3h2V13H18v1c0 0.55-0.45 1-1 1h-3c-0.55 0-1-0.45-1-1v-4c0-0.55 0.45 -1 1-1h3c0.55 0 1 0.45 1 1v1z" />
+</vector>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/media_controller.xml b/packages/MediaComponents/res/layout/media_controller.xml
index 885bcf5..eab2309 100644
--- a/packages/MediaComponents/res/layout/media_controller.xml
+++ b/packages/MediaComponents/res/layout/media_controller.xml
@@ -129,10 +129,10 @@
     <SeekBar
         android:id="@+id/mediacontroller_progress"
         android:layout_width="match_parent"
-        android:layout_height="32dp"
-        android:padding="0dp"
-        android:progressTint="#FFFFFFFF"
-        android:thumbTint="#FFFFFFFF"/>
+        android:layout_height="12dp"
+        android:maxHeight="2dp"
+        android:minHeight="2dp"
+        android:padding="0dp"/>
 
     <RelativeLayout
         android:layout_width="match_parent"
diff --git a/packages/MediaComponents/res/values/style.xml b/packages/MediaComponents/res/values/style.xml
index 9c94aa2..e6ed039 100644
--- a/packages/MediaComponents/res/values/style.xml
+++ b/packages/MediaComponents/res/values/style.xml
@@ -56,7 +56,7 @@
     </style>
 
     <style name="BottomBarButton.CC">
-        <item name="android:src">@drawable/ic_media_subtitle_disabled</item>
+        <item name="android:src">@drawable/ic_subtitle_off</item>
     </style>
 
     <style name="BottomBarButton.FullScreen">
@@ -76,7 +76,7 @@
     </style>
 
     <style name="BottomBarButton.Mute">
-        <item name="android:src">@drawable/ic_mute</item>
+        <item name="android:src">@drawable/ic_unmute</item>
     </style>
 
     <style name="BottomBarButton.VideoQuality">
diff --git a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
index 7044404..16707c6 100644
--- a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
@@ -74,19 +74,25 @@
     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";
     static final String EVENT_UPDATE_MEDIA_TYPE_STATUS = "UpdateMediaTypeStatus";
 
-    // String for receiving command to show subtitle from MediaSession.
+    // String for sending command to show subtitle to MediaSession.
     static final String COMMAND_SHOW_SUBTITLE = "showSubtitle";
-    // String for receiving command to hide subtitle from MediaSession.
+    // String for sending command to hide subtitle to MediaSession.
     static final String COMMAND_HIDE_SUBTITLE = "hideSubtitle";
     // TODO: remove once the implementation is revised
     public static final String COMMAND_SET_FULLSCREEN = "setFullscreen";
+    // String for sending command to select audio track to MediaSession.
+    static final String COMMAND_SELECT_AUDIO_TRACK = "SelectTrack";
+    // String for sending command to set playback speed to MediaSession.
+    static final String COMMAND_SET_PLAYBACK_SPEED = "SetPlaybackSpeed";
+    // String for sending command to mute audio to MediaSession.
+    static final String COMMAND_MUTE= "Mute";
+    // String for sending command to unmute audio to MediaSession.
+    static final String COMMAND_UNMUTE = "Unmute";
 
     private static final int SETTINGS_MODE_AUDIO_TRACK = 0;
     private static final int SETTINGS_MODE_PLAYBACK_SPEED = 1;
@@ -113,6 +119,7 @@
     private TextView mTitleView;
     private TextView mAdSkipView, mAdRemainingView;
     private View mAdExternalLink;
+    private View mTitleBar;
     private View mRoot;
     private int mDuration;
     private int mPrevState;
@@ -135,11 +142,13 @@
     private boolean mSubtitleIsEnabled;
     private boolean mSeekAvailable;
     private boolean mIsAdvertisement;
+    private boolean mIsMute;
     private ImageButton mPlayPauseButton;
     private ImageButton mFfwdButton;
     private ImageButton mRewButton;
     private ImageButton mNextButton;
     private ImageButton mPrevButton;
+    private ImageButton mBackButton;
 
     private ViewGroup mBasicControls;
     private ImageButton mSubtitleButton;
@@ -188,7 +197,6 @@
         mResources = ApiHelper.getLibResources();
         // Inflate MediaControlView2 from XML
         mRoot = makeControllerView();
-        mRoot.addOnLayoutChangeListener(mTitleBarLayoutChangeListener);
         mInstance.addView(mRoot);
     }
 
@@ -376,7 +384,8 @@
         }
         mPlaybackState = mController.getPlaybackState();
         if (mPlaybackState != null) {
-            return (int) (mPlaybackState.getBufferedPosition() * 100) / mDuration;
+            long bufferedPos = mPlaybackState.getBufferedPosition();
+            return (bufferedPos == -1) ? -1 : (int) (bufferedPos * 100 / mDuration);
         }
         return 0;
     }
@@ -445,6 +454,10 @@
         if (mPrevButton != null) {
             mPrevButton.setOnClickListener(mPrevListener);
         }
+        mBackButton = v.findViewById(R.id.back);
+        if (mBackButton != null) {
+            mBackButton.setOnClickListener(mBackListener);
+        }
 
         mBasicControls = v.findViewById(R.id.basic_controls);
         mSubtitleButton = v.findViewById(R.id.subtitle);
@@ -469,6 +482,9 @@
             mOverflowButtonLeft.setOnClickListener(mOverflowLeftListener);
         }
         mMuteButton = v.findViewById(R.id.mute);
+        if (mMuteButton != null) {
+            mMuteButton.setOnClickListener(mMuteButtonListener);
+        }
         mSettingsButton = v.findViewById(R.id.settings);
         if (mSettingsButton != null) {
             mSettingsButton.setOnClickListener(mSettingsButtonListener);
@@ -483,10 +499,16 @@
             if (mProgress instanceof SeekBar) {
                 SeekBar seeker = (SeekBar) mProgress;
                 seeker.setOnSeekBarChangeListener(mSeekListener);
+                seeker.setProgressDrawable(mResources.getDrawable(R.drawable.custom_progress));
+                seeker.setThumb(mResources.getDrawable(R.drawable.custom_progress_thumb));
             }
             mProgress.setMax(MAX_PROGRESS);
         }
 
+        mTitleBar = v.findViewById(R.id.title_bar);
+        if (mTitleBar != null) {
+            mTitleBar.addOnLayoutChangeListener(mTitleBarLayoutChangeListener);
+        }
         mTitleView = v.findViewById(R.id.title_text);
 
         mEndTime = v.findViewById(R.id.time);
@@ -588,7 +610,13 @@
         }
         if (mProgress != null && currentPosition != mDuration) {
             mProgress.setProgress(positionOnProgressBar);
-            mProgress.setSecondaryProgress(getBufferPercentage() * 10);
+            // If the media is a local file, there is no need to set a buffer, so set secondary
+            // progress to maximum.
+            if (getBufferPercentage() < 0) {
+                mProgress.setSecondaryProgress(MAX_PROGRESS);
+            } else {
+                mProgress.setSecondaryProgress(getBufferPercentage() * 10);
+            }
         }
 
         if (mEndTime != null) {
@@ -758,6 +786,13 @@
         }
     };
 
+    private final View.OnClickListener mBackListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            // TODO: implement
+        }
+    };
+
     private final View.OnClickListener mSubtitleListener = new View.OnClickListener() {
         @Override
         public void onClick(View v) {
@@ -814,6 +849,23 @@
         }
     };
 
+    private final View.OnClickListener mMuteButtonListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            if (!mIsMute) {
+                mMuteButton.setImageDrawable(
+                        mResources.getDrawable(R.drawable.ic_mute, null));
+                mIsMute = true;
+                mController.sendCommand(COMMAND_MUTE, null, null);
+            } else {
+                mMuteButton.setImageDrawable(
+                        mResources.getDrawable(R.drawable.ic_unmute, null));
+                mIsMute = false;
+                mController.sendCommand(COMMAND_UNMUTE, null, null);
+            }
+        }
+    };
+
     private final View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
         @Override
         public void onClick(View v) {
@@ -879,14 +931,15 @@
                             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));
+                            mSubtitleButton.setImageDrawable(
+                                    mResources.getDrawable(R.drawable.ic_subtitle_on, null));
                             mSubtitleIsEnabled = true;
                         } else {
                             mController.sendCommand(
                                     MediaControlView2Impl.COMMAND_HIDE_SUBTITLE, null, null);
-                            mSubtitleButton.setImageDrawable(mResources.getDrawable(
-                                    R.drawable.ic_media_subtitle_disabled, null));
+                            mSubtitleButton.setImageDrawable(
+                                    mResources.getDrawable(R.drawable.ic_subtitle_off, null));
+
                             mSubtitleIsEnabled = false;
                         }
                     }
diff --git a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
index d4d289a..264f632 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
@@ -138,6 +138,9 @@
     // TODO: Remove mFallbackSpeed when integration with MediaPlayer2's new setPlaybackParams().
     // Refer: https://docs.google.com/document/d/1nzAfns6i2hJ3RkaUre3QMT6wsDedJ5ONLiA_OOBFFX8/edit
     private float mFallbackSpeed;  // keep the original speed before 'pause' is called.
+    private float mVolumeLevelFloat;
+    private int mVolumeLevel;
+
     private long mShowControllerIntervalMs;
 
     private MediaRouter mMediaRouter;
@@ -652,7 +655,7 @@
             };
             mMediaPlayer.setMediaPlayer2EventCallback(executor, mMediaPlayer2Callback);
 
-            mCurrentBufferPercentage = 0;
+            mCurrentBufferPercentage = -1;
             mMediaPlayer.setDataSource(dsd);
             mMediaPlayer.setAudioAttributes(mAudioAttributes);
             // we don't set the target state here either, but preserve the
@@ -754,8 +757,12 @@
             && mCurrentState != STATE_PREPARING) {
             // TODO: this should be replaced with MediaPlayer2.getBufferedPosition() once it is
             // implemented.
-            mStateBuilder.setBufferedPosition(
-                    (long) (mCurrentBufferPercentage / 100.0) * mMediaPlayer.getDuration());
+            if (mCurrentBufferPercentage == -1) {
+                mStateBuilder.setBufferedPosition(-1);
+            } else {
+                mStateBuilder.setBufferedPosition(
+                        (long) (mCurrentBufferPercentage / 100.0 * mMediaPlayer.getDuration()));
+            }
         }
 
         // Set PlaybackState for MediaSession
@@ -1095,6 +1102,13 @@
                             mSpeed = speed;
                         }
                         break;
+                    case MediaControlView2Impl.COMMAND_MUTE:
+                        mVolumeLevel = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
+                        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
+                        break;
+                    case MediaControlView2Impl.COMMAND_UNMUTE:
+                        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mVolumeLevel, 0);
+                        break;
                 }
             }
             showController();