11ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang/*
21ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Copyright 2018 The Android Open Source Project
31ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang *
41ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Licensed under the Apache License, Version 2.0 (the "License");
51ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * you may not use this file except in compliance with the License.
61ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * You may obtain a copy of the License at
71ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang *
81ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang *      http://www.apache.org/licenses/LICENSE-2.0
91ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang *
101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Unless required by applicable law or agreed to in writing, software
111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * distributed under the License is distributed on an "AS IS" BASIS,
121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * See the License for the specific language governing permissions and
141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * limitations under the License.
151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */
161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangpackage androidx.media.widget;
181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.content.Context;
221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.content.pm.ActivityInfo;
231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.content.res.Resources;
241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.graphics.Bitmap;
251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.graphics.BitmapFactory;
261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.graphics.Point;
271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.graphics.drawable.BitmapDrawable;
281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.graphics.drawable.Drawable;
291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.media.AudioAttributes;
301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.media.AudioFocusRequest;
311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.media.AudioManager;
321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.media.MediaMetadataRetriever;
331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.media.PlaybackParams;
341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.media.SubtitleData;
351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.net.Uri;
361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.os.AsyncTask;
371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.os.Bundle;
381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.os.ResultReceiver;
391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.support.v4.media.MediaMetadataCompat;
401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.support.v4.media.session.MediaControllerCompat;
411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.support.v4.media.session.MediaControllerCompat.PlaybackInfo;
421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.support.v4.media.session.MediaSessionCompat;
431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.support.v4.media.session.PlaybackStateCompat;
441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.util.AttributeSet;
451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.util.DisplayMetrics;
461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.util.Log;
471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.util.Pair;
481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.view.LayoutInflater;
491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.view.MotionEvent;
501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.view.View;
511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.view.ViewGroup.LayoutParams;
521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.view.WindowManager;
531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.view.accessibility.AccessibilityManager;
541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.widget.ImageView;
551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.widget.TextView;
561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.annotation.NonNull;
581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.annotation.Nullable;
591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.annotation.RequiresApi;
601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.annotation.RestrictTo;
611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.AudioAttributesCompat;
621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.DataSourceDesc;
631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.MediaItem2;
641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.MediaMetadata2;
651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.MediaPlayer2;
661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.MediaPlayer2.MediaPlayer2EventCallback;
671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.SessionToken2;
681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.subtitle.ClosedCaptionRenderer;
691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.subtitle.SubtitleController;
701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.subtitle.SubtitleTrack;
711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.mediarouter.media.MediaControlIntent;
721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.mediarouter.media.MediaItemStatus;
731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.mediarouter.media.MediaRouteSelector;
741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.mediarouter.media.MediaRouter;
751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.palette.graphics.Palette;
761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport java.util.ArrayList;
781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport java.util.List;
791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport java.util.Map;
801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport java.util.concurrent.Executor;
811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang/**
831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Base implementation of VideoView2.
841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */
851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang@RequiresApi(28) // TODO correct minSdk API use incompatibilities and remove before release.
861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangclass VideoView2ImplBase implements VideoView2Impl, VideoViewInterface.SurfaceListener {
871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final String TAG = "VideoView2ImplBase";
881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final long DEFAULT_SHOW_CONTROLLER_INTERVAL_MS = 2000;
901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final int STATE_ERROR = -1;
921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final int STATE_IDLE = 0;
931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final int STATE_PREPARING = 1;
941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final int STATE_PREPARED = 2;
951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final int STATE_PLAYING = 3;
961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final int STATE_PAUSED = 4;
971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final int STATE_PLAYBACK_COMPLETED = 5;
981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final int INVALID_TRACK_INDEX = -1;
1001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final float INVALID_SPEED = 0f;
1011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final int SIZE_TYPE_EMBEDDED = 0;
1031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final int SIZE_TYPE_FULL = 1;
1041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private static final int SIZE_TYPE_MINIMAL = 2;
1051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private AccessibilityManager mAccessibilityManager;
1071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private AudioManager mAudioManager;
1081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private AudioAttributesCompat mAudioAttributes;
1091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int mAudioFocusType = AudioManager.AUDIOFOCUS_GAIN; // legacy focus gain
1101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private boolean mAudioFocused = false;
1111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private Pair<Executor, VideoView2.OnCustomActionListener> mCustomActionListenerRecord;
1131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private VideoView2.OnViewTypeChangedListener mViewTypeChangedListener;
1141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private VideoViewInterface mCurrentView;
1161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private VideoTextureView mTextureView;
1171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private VideoSurfaceView mSurfaceView;
1181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private MediaPlayer2 mMediaPlayer;
1201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private DataSourceDesc mDsd;
1211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private Uri mUri;
1221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private Map<String, String> mHeaders;
1231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private MediaControlView2 mMediaControlView;
1241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private MediaSessionCompat mMediaSession;
1251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private MediaControllerCompat mMediaController;
1261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private MediaMetadata2 mMediaMetadata;
1271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private MediaMetadataRetriever mRetriever;
1281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private boolean mNeedUpdateMediaType;
1291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private Bundle mMediaTypeData;
1301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private String mTitle;
1311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private WindowManager mManager;
1331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private Resources mResources;
1341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private View mMusicView;
1351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private Drawable mMusicAlbumDrawable;
1361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private String mMusicTitleText;
1371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private String mMusicArtistText;
1381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private boolean mIsMusicMediaType;
1391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int mPrevWidth;
1401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int mPrevHeight;
1411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int mDominantColor;
1421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int mSizeType;
1431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private PlaybackStateCompat.Builder mStateBuilder;
1451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private List<PlaybackStateCompat.CustomAction> mCustomActionList;
1461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int mTargetState = STATE_IDLE;
1481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int mCurrentState = STATE_IDLE;
1491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int mCurrentBufferPercentage;
1501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private long mSeekWhenPrepared;  // recording the seek position while preparing
1511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int mVideoWidth;
1531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int mVideoHeight;
1541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private ArrayList<Integer> mVideoTrackIndices;
1561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private ArrayList<Integer> mAudioTrackIndices;
1571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private ArrayList<Pair<Integer, SubtitleTrack>> mSubtitleTrackIndices;
1581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private SubtitleController mSubtitleController;
1591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    // selected video/audio/subtitle track index as MediaPlayer returns
1611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int mSelectedVideoTrackIndex;
1621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int mSelectedAudioTrackIndex;
1631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int mSelectedSubtitleTrackIndex;
1641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private SubtitleView mSubtitleView;
1661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private boolean mSubtitleEnabled;
1671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private float mSpeed;
1691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private float mFallbackSpeed;  // keep the original speed before 'pause' is called.
1701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private float mVolumeLevelFloat;
1711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int mVolumeLevel;
1721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private VideoView2 mInstance;
1731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private long mShowControllerIntervalMs;
1751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private MediaRouter mMediaRouter;
1771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private MediaRouteSelector mRouteSelector;
1781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private MediaRouter.RouteInfo mRoute;
1791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private RoutePlayer mRoutePlayer;
1801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
1811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private final MediaRouter.Callback mRouterCallback = new MediaRouter.Callback() {
1821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        @Override
1831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) {
1841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {
1851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                // Stop local playback (if necessary)
1861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                resetPlayer();
1871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mRoute = route;
1881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mRoutePlayer = new RoutePlayer(mInstance.getContext(), route);
1891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mRoutePlayer.setPlayerEventCallback(new RoutePlayer.PlayerEventCallback() {
1901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    @Override
1911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    public void onPlayerStateChanged(MediaItemStatus itemStatus) {
1921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        PlaybackStateCompat.Builder psBuilder = new PlaybackStateCompat.Builder();
1931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        psBuilder.setActions(RoutePlayer.PLAYBACK_ACTIONS);
1941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        long position = itemStatus.getContentPosition();
1951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        switch (itemStatus.getPlaybackState()) {
1961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            case MediaItemStatus.PLAYBACK_STATE_PENDING:
1971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                psBuilder.setState(PlaybackStateCompat.STATE_NONE, position, 0);
1981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                mCurrentState = STATE_IDLE;
1991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                break;
2001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            case MediaItemStatus.PLAYBACK_STATE_PLAYING:
2011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                psBuilder.setState(PlaybackStateCompat.STATE_PLAYING, position, 1);
2021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                mCurrentState = STATE_PLAYING;
2031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                break;
2041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            case MediaItemStatus.PLAYBACK_STATE_PAUSED:
2051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                psBuilder.setState(PlaybackStateCompat.STATE_PAUSED, position, 0);
2061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                mCurrentState = STATE_PAUSED;
2071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                break;
2081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            case MediaItemStatus.PLAYBACK_STATE_BUFFERING:
2091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                psBuilder.setState(
2101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                        PlaybackStateCompat.STATE_BUFFERING, position, 0);
2111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                mCurrentState = STATE_PAUSED;
2121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                break;
2131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            case MediaItemStatus.PLAYBACK_STATE_FINISHED:
2141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                psBuilder.setState(PlaybackStateCompat.STATE_STOPPED, position, 0);
2151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                mCurrentState = STATE_PLAYBACK_COMPLETED;
2161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                break;
2171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        }
2181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
2191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        PlaybackStateCompat pbState = psBuilder.build();
2201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMediaSession.setPlaybackState(pbState);
2211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
2221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        MediaMetadataCompat.Builder mmBuilder = new MediaMetadataCompat.Builder();
2231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mmBuilder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION,
2241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                itemStatus.getContentDuration());
2251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMediaSession.setMetadata(mmBuilder.build());
2261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
2271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                });
2281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                // Start remote playback (if necessary)
2291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                // TODO: b/77556429
2301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mRoutePlayer.openVideo(mUri);
2311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
2321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
2331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
2341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        @Override
2351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route, int reason) {
2361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (mRoute != null && mRoutePlayer != null) {
2371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mRoutePlayer.release();
2381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mRoutePlayer = null;
2391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
2401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (mRoute == route) {
2411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mRoute = null;
2421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
2431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (reason != MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) {
2441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                // TODO: Resume local playback  (if necessary)
2451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                // TODO: b/77556429
2461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                openVideo(mDsd);
2471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
2481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
2491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    };
2501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
2511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
2521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void initialize(
2531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            VideoView2 instance, Context context,
2541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            @Nullable AttributeSet attrs, int defStyleAttr) {
2551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mInstance = instance;
2561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
2571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mVideoWidth = 0;
2581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mVideoHeight = 0;
2591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mSpeed = 1.0f;
2601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mFallbackSpeed = mSpeed;
2611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mSelectedSubtitleTrackIndex = INVALID_TRACK_INDEX;
2621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mShowControllerIntervalMs = DEFAULT_SHOW_CONTROLLER_INTERVAL_MS;
2631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
2641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mAccessibilityManager = (AccessibilityManager) context.getSystemService(
2651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                Context.ACCESSIBILITY_SERVICE);
2661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
2671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
2681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mAudioAttributes = new AudioAttributesCompat.Builder()
2691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                .setUsage(AudioAttributesCompat.USAGE_MEDIA)
2701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                .setContentType(AudioAttributesCompat.CONTENT_TYPE_MOVIE).build();
2711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
2721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mInstance.setFocusable(true);
2731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mInstance.setFocusableInTouchMode(true);
2741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mInstance.requestFocus();
2751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
2761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mTextureView = new VideoTextureView(context);
2771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mSurfaceView = new VideoSurfaceView(context);
2781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
2791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                LayoutParams.MATCH_PARENT);
2801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mTextureView.setLayoutParams(params);
2811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mSurfaceView.setLayoutParams(params);
2821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mTextureView.setSurfaceListener(this);
2831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mSurfaceView.setSurfaceListener(this);
2841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
2851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mInstance.addView(mTextureView);
2861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mInstance.addView(mSurfaceView);
2871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
2881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mSubtitleView = new SubtitleView(context);
2891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mSubtitleView.setLayoutParams(params);
2901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mSubtitleView.setBackgroundColor(0);
2911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mInstance.addView(mSubtitleView);
2921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
2931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        boolean enableControlView = (attrs == null) || attrs.getAttributeBooleanValue(
2941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                "http://schemas.android.com/apk/res/android",
2951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                "enableControlView", true);
2961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (enableControlView) {
2971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaControlView = new MediaControlView2(context);
2981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
2991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
3001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mSubtitleEnabled = (attrs == null) || attrs.getAttributeBooleanValue(
3011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                "http://schemas.android.com/apk/res/android",
3021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                "enableSubtitle", false);
3031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
3041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        // Choose surface view by default
3051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        int viewType = (attrs == null) ? VideoView2.VIEW_TYPE_SURFACEVIEW
3061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                : attrs.getAttributeIntValue(
3071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                "http://schemas.android.com/apk/res/android",
3081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                "viewType", VideoView2.VIEW_TYPE_SURFACEVIEW);
3091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) {
3101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Log.d(TAG, "viewType attribute is surfaceView.");
3111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mTextureView.setVisibility(View.GONE);
3121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mSurfaceView.setVisibility(View.VISIBLE);
3131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mCurrentView = mSurfaceView;
3141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        } else if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) {
3151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Log.d(TAG, "viewType attribute is textureView.");
3161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mTextureView.setVisibility(View.VISIBLE);
3171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mSurfaceView.setVisibility(View.GONE);
3181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mCurrentView = mTextureView;
3191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
3201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
3211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        MediaRouteSelector.Builder builder = new MediaRouteSelector.Builder();
3221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        builder.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
3231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        builder.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO);
3241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        builder.addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO);
3251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mRouteSelector = builder.build();
3261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
3271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
3281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
3291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Sets MediaControlView2 instance. It will replace the previously assigned MediaControlView2
3301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * instance if any.
3311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
3321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param mediaControlView a media control view2 instance.
3331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param intervalMs a time interval in milliseconds until VideoView2 hides MediaControlView2.
3341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
3351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
3361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void setMediaControlView2(MediaControlView2 mediaControlView, long intervalMs) {
3371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaControlView = mediaControlView;
3381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mShowControllerIntervalMs = intervalMs;
3391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaControlView.setRouteSelector(mRouteSelector);
3401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
3411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mInstance.isAttachedToWindow()) {
3421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            attachMediaControlView();
3431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
3441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
3451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
3461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
3471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Returns MediaControlView2 instance which is currently attached to VideoView2 by default or by
3481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * {@link #setMediaControlView2} method.
3491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
3501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
3511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public MediaControlView2 getMediaControlView2() {
3521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        return mMediaControlView;
3531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
3541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
3551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
3561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Sets MediaMetadata2 instance. It will replace the previously assigned MediaMetadata2 instance
3571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * if any.
3581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
3591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param metadata a MediaMetadata2 instance.
3601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @hide
3611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
3621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @RestrictTo(LIBRARY_GROUP)
3631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
3641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void setMediaMetadata(MediaMetadata2 metadata) {
3651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang      //mProvider.setMediaMetadata_impl(metadata);
3661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
3671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
3681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
3691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Returns MediaMetadata2 instance which is retrieved from MediaPlayer inside VideoView2 by
3701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * default or by {@link #setMediaMetadata} method.
3711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @hide
3721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
3731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @RestrictTo(LIBRARY_GROUP)
3741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
3751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public MediaMetadata2 getMediaMetadata() {
3761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        return mMediaMetadata;
3771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
3781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
3791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
3801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Returns MediaController instance which is connected with MediaSession that VideoView2 is
3811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * using. This method should be called when VideoView2 is attached to window, or it throws
3821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * IllegalStateException, since internal MediaSession instance is not available until
3831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * this view is attached to window. Please check {@link View#isAttachedToWindow}
3841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * before calling this method.
3851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
3861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @throws IllegalStateException if interal MediaSession is not created yet.
3871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @hide  TODO: remove
3881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
3891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @RestrictTo(LIBRARY_GROUP)
3901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
3911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public MediaControllerCompat getMediaController() {
3921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mMediaSession == null) {
3931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            throw new IllegalStateException("MediaSession instance is not available.");
3941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
3951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        return mMediaController;
3961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
3971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
3981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
3991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Returns {@link SessionToken2} so that developers create their own
4001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * {@link androidx.media.MediaController2} instance. This method should be called when
4011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * VideoView2 is attached to window, or it throws IllegalStateException.
4021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
4031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @throws IllegalStateException if interal MediaSession is not created yet.
4041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @hide
4051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
4061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @RestrictTo(LIBRARY_GROUP)
4071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
4081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public SessionToken2 getMediaSessionToken() {
4091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        //return mProvider.getMediaSessionToken_impl();
4101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        return null;
4111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
4121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
4131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
4141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Shows or hides closed caption or subtitles if there is any.
4151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * The first subtitle track will be chosen if there multiple subtitle tracks exist.
4161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Default behavior of VideoView2 is not showing subtitle.
4171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param enable shows closed caption or subtitles if this value is true, or hides.
4181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
4191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
4201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void setSubtitleEnabled(boolean enable) {
4211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        // No-op on API < 28
4221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
4231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
4241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
4251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Returns true if showing subtitle feature is enabled or returns false.
4261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Although there is no subtitle track or closed caption, it can return true, if the feature
4271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * has been enabled by {@link #setSubtitleEnabled}.
4281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
4291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
4301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public boolean isSubtitleEnabled() {
4311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        // Not supported on API < 28
4321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        return false;
4331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
4341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
4351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
4361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Sets playback speed.
4371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
4381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * It is expressed as a multiplicative factor, where normal speed is 1.0f. If it is less than
4391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * or equal to zero, it will be just ignored and nothing will be changed. If it exceeds the
4401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * maximum speed that internal engine supports, system will determine best handling or it will
4411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * be reset to the normal speed 1.0f.
4421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param speed the playback speed. It should be positive.
4431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
4441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
4451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void setSpeed(float speed) {
4461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (speed <= 0.0f) {
4471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Log.e(TAG, "Unsupported speed (" + speed + ") is ignored.");
4481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            return;
4491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
4501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mSpeed = speed;
4511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (isPlaying()) {
4521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            applySpeed();
4531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
4541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        updatePlaybackState();
4551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
4561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
4571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
4581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Returns playback speed.
4591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
4601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * It returns the same value that has been set by {@link #setSpeed}, if it was available value.
4611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * If {@link #setSpeed} has not been called before, then the normal speed 1.0f will be returned.
4621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
4631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
4641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public float getSpeed() {
4651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        return mSpeed;
4661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
4671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
4681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
4691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Sets which type of audio focus will be requested during the playback, or configures playback
4701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * to not request audio focus. Valid values for focus requests are
4711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * {@link AudioManager#AUDIOFOCUS_GAIN}, {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT},
4721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and
4731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}. Or use
4741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * {@link AudioManager#AUDIOFOCUS_NONE} to express that audio focus should not be
4751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * requested when playback starts. You can for instance use this when playing a silent animation
4761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * through this class, and you don't want to affect other audio applications playing in the
4771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * background.
4781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
4791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param focusGain the type of audio focus gain that will be requested, or
4801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *                  {@link AudioManager#AUDIOFOCUS_NONE} to disable the use audio focus during
4811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *                  playback.
4821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
4831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
4841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void setAudioFocusRequest(int focusGain) {
4851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (focusGain != AudioManager.AUDIOFOCUS_NONE
4861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                && focusGain != AudioManager.AUDIOFOCUS_GAIN
4871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
4881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
4891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) {
4901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            throw new IllegalArgumentException("Illegal audio focus type " + focusGain);
4911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
4921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mAudioFocusType = focusGain;
4931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
4941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
4951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
4961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Sets the {@link AudioAttributesCompat} to be used during the playback of the video.
4971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
4981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param attributes non-null <code>AudioAttributesCompat</code>.
4991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
5001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
5011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void setAudioAttributes(@NonNull AudioAttributesCompat attributes) {
5021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (attributes == null) {
5031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            throw new IllegalArgumentException("Illegal null AudioAttributes");
5041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
5051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mAudioAttributes = attributes;
5061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
5071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
5081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
5091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Sets video path.
5101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
5111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param path the path of the video.
5121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
5131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @hide
5141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
5151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @RestrictTo(LIBRARY_GROUP)
5161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
5171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void setVideoPath(String path) {
5181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        setVideoUri(Uri.parse(path));
5191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
5201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
5211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
5221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Sets video URI.
5231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
5241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param uri the URI of the video.
5251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
5261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @hide
5271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
5281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @RestrictTo(LIBRARY_GROUP)
5291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
5301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void setVideoUri(Uri uri) {
5311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        setVideoUri(uri, null);
5321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
5331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
5341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
5351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Sets video URI using specific headers.
5361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
5371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param uri     the URI of the video.
5381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param headers the headers for the URI request.
5391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *                Note that the cross domain redirection is allowed by default, but that can be
5401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *                changed with key/value pairs through the headers parameter with
5411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *                "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value
5421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *                to disallow or allow cross domain redirection.
5431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
5441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
5451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void setVideoUri(Uri uri, @Nullable Map<String, String> headers) {
5461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        DataSourceDesc.Builder builder = new DataSourceDesc.Builder();
5471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        builder.setDataSource(mInstance.getContext(), uri, headers, null);
5481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        setDataSource(builder.build());
5491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
5501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
5511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
5521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Sets {@link MediaItem2} object to render using VideoView2. Alternative way to set media
5531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * object to VideoView2 is {@link #setDataSource}.
5541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param mediaItem the MediaItem2 to play
5551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @see #setDataSource
5561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
5571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @hide
5581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
5591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @RestrictTo(LIBRARY_GROUP)
5601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
5611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void setMediaItem(@NonNull MediaItem2 mediaItem) {
5621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
5631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
5641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
5651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Sets {@link DataSourceDesc} object to render using VideoView2.
5661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param dataSource the {@link DataSourceDesc} object to play.
5671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @see #setMediaItem
5681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @hide
5691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
5701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @RestrictTo(LIBRARY_GROUP)
5711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
5721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void setDataSource(@NonNull DataSourceDesc dataSource) {
5731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mDsd = dataSource;
5741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mSeekWhenPrepared = 0;
5751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        openVideo(dataSource);
5761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
5771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
5781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
5791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Selects which view will be used to render video between SurfacView and TextureView.
5801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
5811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param viewType the view type to render video
5821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * <ul>
5831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * <li>{@link #VideoView2.VIEW_TYPE_SURFACEVIEW}
5841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * <li>{@link #VideoView2.VIEW_TYPE_TEXTUREVIEW}
5851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * </ul>
5861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
5871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
5881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void setViewType(@VideoView2.ViewType int viewType) {
5891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (viewType == mCurrentView.getViewType()) {
5901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            return;
5911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
5921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        VideoViewInterface targetView;
5931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) {
5941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Log.d(TAG, "switching to TextureView");
5951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            targetView = mTextureView;
5961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        } else if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) {
5971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Log.d(TAG, "switching to SurfaceView");
5981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            targetView = mSurfaceView;
5991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        } else {
6001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            throw new IllegalArgumentException("Unknown view type: " + viewType);
6011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
6021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        ((View) targetView).setVisibility(View.VISIBLE);
6031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        targetView.takeOver(mCurrentView);
6041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mInstance.requestLayout();
6051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
6061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
6071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
6081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Returns view type.
6091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
6101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @return view type. See {@see setViewType}.
6111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
6121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @VideoView2.ViewType
6131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
6141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public int getViewType() {
6151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        return mCurrentView.getViewType();
6161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
6171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
6181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
6191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Sets custom actions which will be shown as custom buttons in {@link MediaControlView2}.
6201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *
6211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param actionList A list of {@link PlaybackStateCompat.CustomAction}. The return value of
6221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *                   {@link PlaybackStateCompat.CustomAction#getIcon()} will be used to draw
6231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     *                   buttons in {@link MediaControlView2}.
6241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param executor executor to run callbacks on.
6251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param listener A listener to be called when a custom button is clicked.
6261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @hide
6271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
6281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @RestrictTo(LIBRARY_GROUP)
6291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
6301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void setCustomActions(List<PlaybackStateCompat.CustomAction> actionList,
6311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Executor executor, VideoView2.OnCustomActionListener listener) {
6321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mCustomActionList = actionList;
6331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mCustomActionListenerRecord = new Pair<>(executor, listener);
6341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
6351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        // Create a new playback builder in order to clear existing the custom actions.
6361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mStateBuilder = null;
6371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        updatePlaybackState();
6381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
6391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
6401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
6411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Registers a callback to be invoked when a view type change is done.
6421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * {@see #setViewType(int)}
6431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @param l The callback that will be run
6441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @hide
6451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
6461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @RestrictTo(LIBRARY_GROUP)
6471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
6481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void setOnViewTypeChangedListener(VideoView2.OnViewTypeChangedListener l) {
6491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mViewTypeChangedListener = l;
6501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
6511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
6521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
6531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void onAttachedToWindowImpl() {
6541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        // Create MediaSession
6551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaSession = new MediaSessionCompat(mInstance.getContext(), "VideoView2MediaSession");
6561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaSession.setCallback(new MediaSessionCallback());
6571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaSession.setActive(true);
6581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaController = mMediaSession.getController();
6591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        attachMediaControlView();
6601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mCurrentState == STATE_PREPARED) {
6611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            extractTracks();
6621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            extractMetadata();
6631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            extractAudioMetadata();
6641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (mNeedUpdateMediaType) {
6651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mMediaSession.sendSessionEvent(
6661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        MediaControlView2.EVENT_UPDATE_MEDIA_TYPE_STATUS,
6671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMediaTypeData);
6681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mNeedUpdateMediaType = false;
6691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
6701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
6711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
6721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaRouter = MediaRouter.getInstance(mInstance.getContext());
6731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaRouter.setMediaSessionCompat(mMediaSession);
6741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaRouter.addCallback(mRouteSelector, mRouterCallback,
6751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
6761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
6771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
6781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
6791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void onDetachedFromWindowImpl() {
6801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaSession.release();
6811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaSession = null;
6821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaController = null;
6831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
6841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
6851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
6861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void onTouchEventImpl(MotionEvent ev) {
6871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (DEBUG) {
6881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Log.d(TAG, "onTouchEvent(). mCurrentState=" + mCurrentState
6891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    + ", mTargetState=" + mTargetState);
6901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
6911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) {
6921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (!mIsMusicMediaType || mSizeType != SIZE_TYPE_FULL) {
6931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                toggleMediaControlViewVisibility();
6941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
6951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
6961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
6971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
6981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
6991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void onTrackballEventImpl(MotionEvent ev) {
7001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) {
7011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (!mIsMusicMediaType || mSizeType != SIZE_TYPE_FULL) {
7021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                toggleMediaControlViewVisibility();
7031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
7041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
7051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
7061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
7071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
7081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void onMeasureImpl(int widthMeasureSpec, int heightMeasureSpec) {
7091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mIsMusicMediaType) {
7101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            int currWidth = mInstance.getMeasuredWidth();
7111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            int currHeight = mInstance.getMeasuredHeight();
7121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (mPrevWidth != currWidth || mPrevHeight != currHeight) {
7131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                Point screenSize = new Point();
7141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mManager.getDefaultDisplay().getSize(screenSize);
7151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                int screenWidth = screenSize.x;
7161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                int screenHeight = screenSize.y;
7171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
7181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                if (currWidth == screenWidth && currHeight == screenHeight) {
7191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    int orientation = retrieveOrientation();
7201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
7211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        inflateMusicView(R.layout.full_landscape_music);
7221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    } else {
7231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        inflateMusicView(R.layout.full_portrait_music);
7241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
7251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
7261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (mSizeType != SIZE_TYPE_FULL) {
7271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mSizeType = SIZE_TYPE_FULL;
7281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        // Remove existing mFadeOut callback
7291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMediaControlView.removeCallbacks(mFadeOut);
7301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMediaControlView.setVisibility(View.VISIBLE);
7311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
7321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                } else {
7331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (mSizeType != SIZE_TYPE_EMBEDDED) {
7341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mSizeType = SIZE_TYPE_EMBEDDED;
7351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        inflateMusicView(R.layout.embedded_music);
7361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        // Add new mFadeOut callback
7371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs);
7381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
7391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
7401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mPrevWidth = currWidth;
7411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mPrevHeight = currHeight;
7421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
7431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
7441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
7451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
7461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    ///////////////////////////////////////////////////
7471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    // Implements VideoViewInterface.SurfaceListener
7481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    ///////////////////////////////////////////////////
7491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
7501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
7511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @hide
7521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
7531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
7541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @RestrictTo(LIBRARY_GROUP)
7551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void onSurfaceCreated(View view, int width, int height) {
7561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (DEBUG) {
7571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Log.d(TAG, "onSurfaceCreated(). mCurrentState=" + mCurrentState
7581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    + ", mTargetState=" + mTargetState + ", width/height: " + width + "/" + height
7591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    + ", " + view.toString());
7601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
7611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (needToStart()) {
7621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaController.getTransportControls().play();
7631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
7641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
7651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
7661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
7671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @hide
7681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
7691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
7701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @RestrictTo(LIBRARY_GROUP)
7711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void onSurfaceDestroyed(View view) {
7721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (DEBUG) {
7731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Log.d(TAG, "onSurfaceDestroyed(). mCurrentState=" + mCurrentState
7741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    + ", mTargetState=" + mTargetState + ", " + view.toString());
7751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
7761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
7771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
7781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
7791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @hide
7801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
7811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
7821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @RestrictTo(LIBRARY_GROUP)
7831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void onSurfaceChanged(View view, int width, int height) {
7841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (DEBUG) {
7851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Log.d(TAG, "onSurfaceChanged(). width/height: " + width + "/" + height
7861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    + ", " + view.toString());
7871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
7881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
7891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
7901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /**
7911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * @hide
7921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
7931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @Override
7941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @RestrictTo(LIBRARY_GROUP)
7951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    public void onSurfaceTakeOverDone(VideoViewInterface view) {
7961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (DEBUG) {
7971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Log.d(TAG, "onSurfaceTakeOverDone(). Now current view is: " + view);
7981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
7991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mCurrentView = view;
8001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mViewTypeChangedListener != null) {
8011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mViewTypeChangedListener.onViewTypeChanged(mInstance, view.getViewType());
8021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
8031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (needToStart()) {
8041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaController.getTransportControls().play();
8051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
8061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
8071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
8081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    ///////////////////////////////////////////////////
8091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    // Protected or private methods
8101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    ///////////////////////////////////////////////////
8111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
8121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private void attachMediaControlView() {
8131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        // Get MediaController from MediaSession and set it inside MediaControlView
8141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaControlView.setController(mMediaSession.getController());
8151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
8161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        LayoutParams params =
8171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
8181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mInstance.addView(mMediaControlView, params);
8191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
8201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
8211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private boolean isInPlaybackState() {
8221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        return (mMediaPlayer != null || mRoutePlayer != null)
8231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                && mCurrentState != STATE_ERROR
8241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                && mCurrentState != STATE_IDLE
8251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                && mCurrentState != STATE_PREPARING;
8261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
8271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
8281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private boolean needToStart() {
8291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        return (mMediaPlayer != null || mRoutePlayer != null)
8301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                && isAudioGranted()
8311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                && isWaitingPlayback();
8321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
8331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
8341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private boolean isPlaying() {
8351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        return mMediaPlayer != null
8361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                && mMediaPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING;
8371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
8381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
8391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private boolean isWaitingPlayback() {
8401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        return mCurrentState != STATE_PLAYING && mTargetState == STATE_PLAYING;
8411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
8421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
8431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private boolean isAudioGranted() {
8441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        return mAudioFocused || mAudioFocusType == AudioManager.AUDIOFOCUS_NONE;
8451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
8461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
8471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private AudioManager.OnAudioFocusChangeListener mAudioFocusListener =
8481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            new AudioManager.OnAudioFocusChangeListener() {
8491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        @Override
8501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        public void onAudioFocusChange(int focusChange) {
8511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            switch (focusChange) {
8521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                case AudioManager.AUDIOFOCUS_GAIN:
8531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mAudioFocused = true;
8541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (needToStart()) {
8551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMediaController.getTransportControls().play();
8561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
8571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    break;
8581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                case AudioManager.AUDIOFOCUS_LOSS:
8591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
8601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
8611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mAudioFocused = false;
8621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (isInPlaybackState() && isPlaying()) {
8631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMediaController.getTransportControls().pause();
8641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    } else {
8651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mTargetState = STATE_PAUSED;
8661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
8671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
8681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
8691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    };
8701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
8711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @SuppressWarnings("deprecation")
8721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private void requestAudioFocus(int focusType) {
8731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        int result;
8741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (android.os.Build.VERSION.SDK_INT >= 26) {
8751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            AudioFocusRequest focusRequest;
8761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            focusRequest = new AudioFocusRequest.Builder(focusType)
8771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    .setAudioAttributes((AudioAttributes) mAudioAttributes.unwrap())
8781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    .setOnAudioFocusChangeListener(mAudioFocusListener)
8791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    .build();
8801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            result = mAudioManager.requestAudioFocus(focusRequest);
8811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        } else {
8821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            result = mAudioManager.requestAudioFocus(mAudioFocusListener,
8831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    AudioManager.STREAM_MUSIC,
8841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    focusType);
8851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
8861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (result == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
8871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mAudioFocused = false;
8881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        } else if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
8891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mAudioFocused = true;
8901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        } else if (result == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
8911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mAudioFocused = false;
8921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
8931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
8941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
8951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    // Creates a MediaPlayer instance and prepare playback.
8961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private void openVideo(DataSourceDesc dsd) {
8971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        Uri uri = dsd.getUri();
8981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        Map<String, String> headers = dsd.getUriHeaders();
8991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        resetPlayer();
9001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (isRemotePlayback()) {
9011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            // TODO: b/77556429
9021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mRoutePlayer.openVideo(uri);
9031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            return;
9041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
9051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
9061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        try {
9071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Log.d(TAG, "openVideo(): creating new MediaPlayer instance.");
9081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaPlayer = MediaPlayer2.create();
9091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mSurfaceView.setMediaPlayer(mMediaPlayer);
9101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mTextureView.setMediaPlayer(mMediaPlayer);
9111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mCurrentView.assignSurfaceToMediaPlayer(mMediaPlayer);
9121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
9131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            final Context context = mInstance.getContext();
9141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mSubtitleController = new SubtitleController(context);
9151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mSubtitleController.registerRenderer(new ClosedCaptionRenderer(context));
9161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mSubtitleController.setAnchor((SubtitleController.Anchor) mSubtitleView);
9171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Executor executor = new Executor() {
9181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                @Override
9191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                public void execute(Runnable runnable) {
9201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    runnable.run();
9211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
9221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            };
9231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaPlayer.setMediaPlayer2EventCallback(executor, mMediaPlayer2Callback);
9241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
9251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mCurrentBufferPercentage = -1;
9261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaPlayer.setDataSource(dsd);
9271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaPlayer.setAudioAttributes(mAudioAttributes);
9281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            // we don't set the target state here either, but preserve the
9291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            // target state that was there before.
9301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mCurrentState = STATE_PREPARING;
9311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaPlayer.prepare();
9321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
9331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            // Save file name as title since the file may not have a title Metadata.
9341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mTitle = uri.getPath();
9351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            String scheme = uri.getScheme();
9361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (scheme != null && scheme.equals("file")) {
9371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mTitle = uri.getLastPathSegment();
9381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mRetriever = new MediaMetadataRetriever();
9391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mRetriever.setDataSource(context, uri);
9401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
9411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
9421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (DEBUG) {
9431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                Log.d(TAG, "openVideo(). mCurrentState=" + mCurrentState
9441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        + ", mTargetState=" + mTargetState);
9451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
9461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        } catch (IllegalArgumentException ex) {
9471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Log.w(TAG, "Unable to open content: " + uri, ex);
9481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mCurrentState = STATE_ERROR;
9491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mTargetState = STATE_ERROR;
9501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaPlayer2Callback.onError(mMediaPlayer, dsd,
9511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    MediaPlayer2.MEDIA_ERROR_UNKNOWN, MediaPlayer2.MEDIA_ERROR_IO);
9521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
9531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
9541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
9551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    /*
9561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     * Reset the media player in any state
9571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang     */
9581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @SuppressWarnings("deprecation")
9591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private void resetPlayer() {
9601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mMediaPlayer != null) {
9611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            final MediaPlayer2 player = mMediaPlayer;
9621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            new AsyncTask<MediaPlayer2, Void, Void>() {
9631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                @Override
9641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                protected Void doInBackground(MediaPlayer2... players) {
9651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    // TODO: Fix NPE while MediaPlayer2.close()
9661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    //players[0].close();
9671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    return null;
9681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
9691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, player);
9701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaPlayer = null;
9711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mTextureView.setMediaPlayer(null);
9721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mSurfaceView.setMediaPlayer(null);
9731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mCurrentState = STATE_IDLE;
9741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mTargetState = STATE_IDLE;
9751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
9761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mAudioManager.abandonAudioFocus(null);
9771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
9781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
9791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mVideoWidth = 0;
9801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mVideoHeight = 0;
9811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
9821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
9831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private void updatePlaybackState() {
9841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mStateBuilder == null) {
9851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            long playbackActions = PlaybackStateCompat.ACTION_PLAY
9861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    | PlaybackStateCompat.ACTION_PAUSE
9871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    | PlaybackStateCompat.ACTION_REWIND | PlaybackStateCompat.ACTION_FAST_FORWARD
9881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    | PlaybackStateCompat.ACTION_SEEK_TO;
9891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mStateBuilder = new PlaybackStateCompat.Builder();
9901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mStateBuilder.setActions(playbackActions);
9911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
9921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (mCustomActionList != null) {
9931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                for (PlaybackStateCompat.CustomAction action : mCustomActionList) {
9941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mStateBuilder.addCustomAction(action);
9951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
9961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
9971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
9981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mStateBuilder.setState(getCorrespondingPlaybackState(),
9991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mMediaPlayer.getCurrentPosition(), mSpeed);
10001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mCurrentState != STATE_ERROR
10011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                && mCurrentState != STATE_IDLE
10021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                && mCurrentState != STATE_PREPARING) {
10031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (mCurrentBufferPercentage == -1) {
10041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mStateBuilder.setBufferedPosition(-1);
10051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            } else {
10061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mStateBuilder.setBufferedPosition(
10071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        (long) (mCurrentBufferPercentage / 100.0 * mMediaPlayer.getDuration()));
10081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
10091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
10101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
10111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        // Set PlaybackState for MediaSession
10121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mMediaSession != null) {
10131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            PlaybackStateCompat state = mStateBuilder.build();
10141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaSession.setPlaybackState(state);
10151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
10161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
10171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
10181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int getCorrespondingPlaybackState() {
10191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        switch (mCurrentState) {
10201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            case STATE_ERROR:
10211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                return PlaybackStateCompat.STATE_ERROR;
10221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            case STATE_IDLE:
10231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                return PlaybackStateCompat.STATE_NONE;
10241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            case STATE_PREPARING:
10251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                return PlaybackStateCompat.STATE_CONNECTING;
10261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            case STATE_PREPARED:
10271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                return PlaybackStateCompat.STATE_PAUSED;
10281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            case STATE_PLAYING:
10291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                return PlaybackStateCompat.STATE_PLAYING;
10301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            case STATE_PAUSED:
10311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                return PlaybackStateCompat.STATE_PAUSED;
10321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            case STATE_PLAYBACK_COMPLETED:
10331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                return PlaybackStateCompat.STATE_STOPPED;
10341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            default:
10351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                return -1;
10361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
10371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
10381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
10391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private final Runnable mFadeOut = new Runnable() {
10401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        @Override
10411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        public void run() {
10421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (mCurrentState == STATE_PLAYING) {
10431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mMediaControlView.setVisibility(View.GONE);
10441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
10451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
10461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    };
10471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
10481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private void showController() {
10491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mMediaControlView == null || !isInPlaybackState()
10501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                || (mIsMusicMediaType && mSizeType == SIZE_TYPE_FULL)) {
10511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            return;
10521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
10531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaControlView.removeCallbacks(mFadeOut);
10541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaControlView.setVisibility(View.VISIBLE);
10551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mShowControllerIntervalMs != 0
10561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                && !mAccessibilityManager.isTouchExplorationEnabled()) {
10571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs);
10581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
10591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
10601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
10611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private void toggleMediaControlViewVisibility() {
10621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mMediaControlView.getVisibility() == View.VISIBLE) {
10631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaControlView.removeCallbacks(mFadeOut);
10641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaControlView.setVisibility(View.GONE);
10651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        } else {
10661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            showController();
10671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
10681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
10691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
10701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private void applySpeed() {
10711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (android.os.Build.VERSION.SDK_INT < 23) {
10721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            return;
10731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
10741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        PlaybackParams params = mMediaPlayer.getPlaybackParams().allowDefaults();
10751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mSpeed != params.getSpeed()) {
10761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            try {
10771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                params.setSpeed(mSpeed);
10781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mMediaPlayer.setPlaybackParams(params);
10791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mFallbackSpeed = mSpeed;
10801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            } catch (IllegalArgumentException e) {
10811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                Log.e(TAG, "PlaybackParams has unsupported value: " + e);
10821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                float fallbackSpeed = mMediaPlayer.getPlaybackParams().allowDefaults().getSpeed();
10831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                if (fallbackSpeed > 0.0f) {
10841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mFallbackSpeed = fallbackSpeed;
10851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
10861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mSpeed = mFallbackSpeed;
10871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
10881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
10891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
10901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
10911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private boolean isRemotePlayback() {
10921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mMediaController == null) {
10931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            return false;
10941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
10951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        PlaybackInfo playbackInfo = mMediaController.getPlaybackInfo();
10961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        return playbackInfo != null
10971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                && playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE;
10981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
10991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
11001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private void selectOrDeselectSubtitle(boolean select) {
11011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (!isInPlaybackState()) {
11021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            return;
11031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
11041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (select) {
11051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (mSubtitleTrackIndices.size() > 0) {
11061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mSelectedSubtitleTrackIndex = mSubtitleTrackIndices.get(0).first;
11071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mSubtitleController.selectTrack(mSubtitleTrackIndices.get(0).second);
11081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mMediaPlayer.selectTrack(mSelectedSubtitleTrackIndex);
11091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mSubtitleView.setVisibility(View.VISIBLE);
11101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
11111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        } else {
11121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (mSelectedSubtitleTrackIndex != INVALID_TRACK_INDEX) {
11131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mMediaPlayer.deselectTrack(mSelectedSubtitleTrackIndex);
11141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mSelectedSubtitleTrackIndex = INVALID_TRACK_INDEX;
11151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mSubtitleView.setVisibility(View.GONE);
11161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
11171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
11181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
11191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
11201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private void extractTracks() {
11211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        List<MediaPlayer2.TrackInfo> trackInfos = mMediaPlayer.getTrackInfo();
11221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mVideoTrackIndices = new ArrayList<>();
11231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mAudioTrackIndices = new ArrayList<>();
11241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mSubtitleTrackIndices = new ArrayList<>();
11251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mSubtitleController.reset();
11261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        for (int i = 0; i < trackInfos.size(); ++i) {
11271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            int trackType = trackInfos.get(i).getTrackType();
11281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_VIDEO) {
11291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mVideoTrackIndices.add(i);
11301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            } else if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_AUDIO) {
11311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mAudioTrackIndices.add(i);
11321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            } else if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
11331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                SubtitleTrack track = mSubtitleController.addTrack(trackInfos.get(i).getFormat());
11341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                if (track != null) {
11351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mSubtitleTrackIndices.add(new Pair<>(i, track));
11361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
11371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
11381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
11391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        // Select first tracks as default
11401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mVideoTrackIndices.size() > 0) {
11411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mSelectedVideoTrackIndex = 0;
11421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
11431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mAudioTrackIndices.size() > 0) {
11441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mSelectedAudioTrackIndex = 0;
11451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
11461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mVideoTrackIndices.size() == 0 && mAudioTrackIndices.size() > 0) {
11471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mIsMusicMediaType = true;
11481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
11491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
11501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        Bundle data = new Bundle();
11511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        data.putInt(MediaControlView2.KEY_VIDEO_TRACK_COUNT, mVideoTrackIndices.size());
11521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        data.putInt(MediaControlView2.KEY_AUDIO_TRACK_COUNT, mAudioTrackIndices.size());
11531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        data.putInt(MediaControlView2.KEY_SUBTITLE_TRACK_COUNT, mSubtitleTrackIndices.size());
11541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mSubtitleTrackIndices.size() > 0) {
11551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            selectOrDeselectSubtitle(mSubtitleEnabled);
11561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
11571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaSession.sendSessionEvent(MediaControlView2.EVENT_UPDATE_TRACK_STATUS, data);
11581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
11591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
11601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private void extractMetadata() {
11611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mRetriever == null) {
11621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            return;
11631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
11641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        // Get and set duration and title values as MediaMetadata for MediaControlView2
11651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
11661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
11671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (title != null) {
11681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mTitle = title;
11691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
11701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mTitle);
11711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        builder.putLong(
11721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                MediaMetadataCompat.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
11731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
11741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mMediaSession != null) {
11751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMediaSession.setMetadata(builder.build());
11761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
11771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
11781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
11791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    @SuppressWarnings("deprecation")
11801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private void extractAudioMetadata() {
11811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (mRetriever == null || !mIsMusicMediaType) {
11821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            return;
11831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
11841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
11851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mResources = mInstance.getResources();
11861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mManager = (WindowManager) mInstance.getContext().getApplicationContext()
11871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                .getSystemService(Context.WINDOW_SERVICE);
11881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
11891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        byte[] album = mRetriever.getEmbeddedPicture();
11901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (album != null) {
11911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Bitmap bitmap = BitmapFactory.decodeByteArray(album, 0, album.length);
11921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMusicAlbumDrawable = new BitmapDrawable(bitmap);
11931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
11941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            Palette.Builder builder = Palette.from(bitmap);
11951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            builder.generate(new Palette.PaletteAsyncListener() {
11961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                @Override
11971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                public void onGenerated(Palette palette) {
11981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mDominantColor = palette.getDominantColor(0);
11991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (mMusicView != null) {
12001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMusicView.setBackgroundColor(mDominantColor);
12011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
12021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
12031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            });
12041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        } else {
12051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMusicAlbumDrawable = mResources.getDrawable(R.drawable.ic_default_album_image);
12061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
12071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
12081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
12091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (title != null) {
12101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMusicTitleText = title;
12111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        } else {
12121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMusicTitleText = mResources.getString(R.string.mcv2_music_title_unknown_text);
12131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
12141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
12151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        String artist = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
12161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (artist != null) {
12171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMusicArtistText = artist;
12181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        } else {
12191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mMusicArtistText = mResources.getString(R.string.mcv2_music_artist_unknown_text);
12201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
12211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
12221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        // Send title and artist string to MediaControlView2
12231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
12241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mMusicTitleText);
12251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, mMusicArtistText);
12261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMediaSession.setMetadata(builder.build());
12271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
12281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        // Display Embedded mode as default
12291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mInstance.removeView(mSurfaceView);
12301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mInstance.removeView(mTextureView);
12311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        inflateMusicView(R.layout.embedded_music);
12321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
12331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
12341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private int retrieveOrientation() {
12351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        DisplayMetrics dm = Resources.getSystem().getDisplayMetrics();
12361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        int width = dm.widthPixels;
12371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        int height = dm.heightPixels;
12381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
12391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        return (height > width)
12401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
12411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
12421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
12431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
12441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private void inflateMusicView(int layoutId) {
12451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mInstance.removeView(mMusicView);
12461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
12471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        LayoutInflater inflater = (LayoutInflater) mInstance.getContext()
12481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
12491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        View v = inflater.inflate(layoutId, null);
12501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        v.setBackgroundColor(mDominantColor);
12511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
12521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        ImageView albumView = v.findViewById(R.id.album);
12531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (albumView != null) {
12541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            albumView.setImageDrawable(mMusicAlbumDrawable);
12551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
12561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
12571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        TextView titleView = v.findViewById(R.id.title);
12581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (titleView != null) {
12591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            titleView.setText(mMusicTitleText);
12601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
12611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
12621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        TextView artistView = v.findViewById(R.id.artist);
12631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        if (artistView != null) {
12641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            artistView.setText(mMusicArtistText);
12651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
12661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
12671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mMusicView = v;
12681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        mInstance.addView(mMusicView, 0);
12691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
12701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
12711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    MediaPlayer2EventCallback mMediaPlayer2Callback =
12721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            new MediaPlayer2EventCallback() {
12731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                @Override
12741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                public void onVideoSizeChanged(
12751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        MediaPlayer2 mp, DataSourceDesc dsd, int width, int height) {
12761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (DEBUG) {
12771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        Log.d(TAG, "onVideoSizeChanged(): size: " + width + "/" + height);
12781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
12791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mVideoWidth = mp.getVideoWidth();
12801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mVideoHeight = mp.getVideoHeight();
12811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (DEBUG) {
12821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        Log.d(TAG, "onVideoSizeChanged(): mVideoSize:" + mVideoWidth + "/"
12831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                + mVideoHeight);
12841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
12851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (mVideoWidth != 0 && mVideoHeight != 0) {
12861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mInstance.requestLayout();
12871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
12881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
12891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
12901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                @Override
12911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                public void onInfo(
12921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
12931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (what == MediaPlayer2.MEDIA_INFO_METADATA_UPDATE) {
12941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        extractTracks();
12951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    } else if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
12961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        this.onPrepared(mp, dsd);
12971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    } else if (what == MediaPlayer2.MEDIA_INFO_PLAYBACK_COMPLETE) {
12981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        this.onCompletion(mp, dsd);
12991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    } else if (what == MediaPlayer2.MEDIA_INFO_BUFFERING_UPDATE) {
13001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        this.onBufferingUpdate(mp, dsd, extra);
13011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
13021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
13031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
13041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                @Override
13051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                public void onError(
13061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        MediaPlayer2 mp, DataSourceDesc dsd, int frameworkErr, int implErr) {
13071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (DEBUG) {
13081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        Log.d(TAG, "Error: " + frameworkErr + "," + implErr);
13091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
13101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mCurrentState = STATE_ERROR;
13111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mTargetState = STATE_ERROR;
13121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    updatePlaybackState();
13131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
13141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (mMediaControlView != null) {
13151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMediaControlView.setVisibility(View.GONE);
13161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
13171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
13181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
13191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                @Override
13201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                public void onCallCompleted(
13211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) {
13221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) {
13231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        updatePlaybackState();
13241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
13251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
13261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
13271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                @Override
13281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                public void onSubtitleData(MediaPlayer2 mp, DataSourceDesc dsd, SubtitleData data) {
13291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (DEBUG) {
13301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        Log.d(TAG, "onSubtitleData(): getTrackIndex: " + data.getTrackIndex()
13311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                + ", getCurrentPosition: " + mp.getCurrentPosition()
13321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                + ", getStartTimeUs(): " + data.getStartTimeUs()
13331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                + ", diff: "
13341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                + (data.getStartTimeUs() / 1000 - mp.getCurrentPosition())
13351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                + "ms, getDurationUs(): " + data.getDurationUs());
13361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
13371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
13381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    final int index = data.getTrackIndex();
13391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (index != mSelectedSubtitleTrackIndex) {
13401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        Log.d(TAG, "onSubtitleData(): getTrackIndex: " + data.getTrackIndex()
13411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                + ", selected track index: " + mSelectedSubtitleTrackIndex);
13421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        return;
13431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
13441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    for (Pair<Integer, SubtitleTrack> p : mSubtitleTrackIndices) {
13451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        if (p.first == index) {
13461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            SubtitleTrack track = p.second;
13471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            track.onData(data);
13481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        }
13491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
13501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
13511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
13521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                private void onPrepared(MediaPlayer2 mp, DataSourceDesc dsd) {
13531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (DEBUG) {
13541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        Log.d(TAG, "OnPreparedListener(). mCurrentState=" + mCurrentState
13551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                + ", mTargetState=" + mTargetState);
13561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
13571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mCurrentState = STATE_PREPARED;
13581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    // Create and set playback state for MediaControlView2
13591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    updatePlaybackState();
13601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
13611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (mMediaSession != null) {
13621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        extractTracks();
13631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        extractMetadata();
13641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        extractAudioMetadata();
13651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
13661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
13671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (mMediaControlView != null) {
13681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMediaControlView.setEnabled(true);
13691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
13701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    int videoWidth = mp.getVideoWidth();
13711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    int videoHeight = mp.getVideoHeight();
13721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
13731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    // mSeekWhenPrepared may be changed after seekTo() call
13741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    long seekToPosition = mSeekWhenPrepared;
13751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (seekToPosition != 0) {
13761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMediaController.getTransportControls().seekTo(seekToPosition);
13771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
13781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
13791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (videoWidth != 0 && videoHeight != 0) {
13801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        if (videoWidth != mVideoWidth || videoHeight != mVideoHeight) {
13811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            mVideoWidth = videoWidth;
13821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            mVideoHeight = videoHeight;
13831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            mInstance.requestLayout();
13841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        }
13851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
13861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        if (needToStart()) {
13871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            mMediaController.getTransportControls().play();
13881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        }
13891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
13901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    } else {
13911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        // We don't know the video size yet, but should start anyway.
13921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        // The video size might be reported to us later.
13931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        if (needToStart()) {
13941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            mMediaController.getTransportControls().play();
13951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        }
13961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
13971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    // Get and set duration and title values as MediaMetadata for MediaControlView2
13981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
13991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
14001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mTitle);
14011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    builder.putLong(
14021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            MediaMetadataCompat.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
14031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
14041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (mMediaSession != null) {
14051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMediaSession.setMetadata(builder.build());
14061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
14071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        if (mNeedUpdateMediaType) {
14081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            mMediaSession.sendSessionEvent(
14091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                    MediaControlView2.EVENT_UPDATE_MEDIA_TYPE_STATUS,
14101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                    mMediaTypeData);
14111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            mNeedUpdateMediaType = false;
14121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        }
14131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
14141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
14151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
14161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                @SuppressWarnings("deprecation")
14171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                private void onCompletion(MediaPlayer2 mp, DataSourceDesc dsd) {
14181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mCurrentState = STATE_PLAYBACK_COMPLETED;
14191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mTargetState = STATE_PLAYBACK_COMPLETED;
14201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    updatePlaybackState();
14211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
14221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mAudioManager.abandonAudioFocus(null);
14231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
14241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
14251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
14261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                private void onBufferingUpdate(MediaPlayer2 mp, DataSourceDesc dsd, int percent) {
14271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mCurrentBufferPercentage = percent;
14281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    updatePlaybackState();
14291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
14301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            };
14311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
14321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    private class MediaSessionCallback extends MediaSessionCompat.Callback {
14331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        @Override
14341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        public void onCommand(String command, Bundle args, ResultReceiver receiver) {
14351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (isRemotePlayback()) {
14361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mRoutePlayer.onCommand(command, args, receiver);
14371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            } else {
14381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                switch (command) {
14391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    case MediaControlView2.COMMAND_SHOW_SUBTITLE:
14401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        int subtitleIndex = args.getInt(
14411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                MediaControlView2.KEY_SELECTED_SUBTITLE_INDEX,
14421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                INVALID_TRACK_INDEX);
14431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        if (subtitleIndex != INVALID_TRACK_INDEX) {
14441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            int subtitleTrackIndex = mSubtitleTrackIndices.get(subtitleIndex).first;
14451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            if (subtitleTrackIndex != mSelectedSubtitleTrackIndex) {
14461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                mSelectedSubtitleTrackIndex = subtitleTrackIndex;
14471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                mInstance.setSubtitleEnabled(true);
14481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            }
14491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        }
14501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        break;
14511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    case MediaControlView2.COMMAND_HIDE_SUBTITLE:
14521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mInstance.setSubtitleEnabled(false);
14531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        break;
14541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    case MediaControlView2.COMMAND_SELECT_AUDIO_TRACK:
14551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        int audioIndex = args.getInt(MediaControlView2.KEY_SELECTED_AUDIO_INDEX,
14561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                INVALID_TRACK_INDEX);
14571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        if (audioIndex != INVALID_TRACK_INDEX) {
14581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            int audioTrackIndex = mAudioTrackIndices.get(audioIndex);
14591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            if (audioTrackIndex != mSelectedAudioTrackIndex) {
14601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                mSelectedAudioTrackIndex = audioTrackIndex;
14611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                mMediaPlayer.selectTrack(mSelectedAudioTrackIndex);
14621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            }
14631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        }
14641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        break;
14651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    case MediaControlView2.COMMAND_SET_PLAYBACK_SPEED:
14661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        float speed = args.getFloat(
14671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                                MediaControlView2.KEY_PLAYBACK_SPEED, INVALID_SPEED);
14681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        if (speed != INVALID_SPEED && speed != mSpeed) {
14691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            setSpeed(speed);
14701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                            mSpeed = speed;
14711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        }
14721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        break;
14731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    case MediaControlView2.COMMAND_MUTE:
14741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mVolumeLevel = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
14751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
14761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        break;
14771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    case MediaControlView2.COMMAND_UNMUTE:
14781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mVolumeLevel, 0);
14791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        break;
14801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
14811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
14821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            showController();
14831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
14841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
14851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        @Override
14861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        public void onCustomAction(final String action, final Bundle extras) {
14871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mCustomActionListenerRecord.first.execute(new Runnable() {
14881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                @Override
14891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                public void run() {
14901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mCustomActionListenerRecord.second.onCustomAction(action, extras);
14911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
14921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            });
14931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            showController();
14941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
14951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
14961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        @Override
14971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        public void onPlay() {
14981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (!isAudioGranted()) {
14991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                requestAudioFocus(mAudioFocusType);
15001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
15011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
15021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if ((isInPlaybackState() && mCurrentView.hasAvailableSurface()) || mIsMusicMediaType) {
15031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                if (isRemotePlayback()) {
15041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mRoutePlayer.onPlay();
15051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                } else {
15061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    applySpeed();
15071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mMediaPlayer.play();
15081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mCurrentState = STATE_PLAYING;
15091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    updatePlaybackState();
15101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
15111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mCurrentState = STATE_PLAYING;
15121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
15131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mTargetState = STATE_PLAYING;
15141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (DEBUG) {
15151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                Log.d(TAG, "onPlay(). mCurrentState=" + mCurrentState
15161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        + ", mTargetState=" + mTargetState);
15171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
15181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            showController();
15191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
15201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
15211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        @Override
15221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        public void onPause() {
15231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (isInPlaybackState()) {
15241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                if (isRemotePlayback()) {
15251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mRoutePlayer.onPlay();
15261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mCurrentState = STATE_PAUSED;
15271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                } else if (isPlaying()) {
15281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mMediaPlayer.pause();
15291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mCurrentState = STATE_PAUSED;
15301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    updatePlaybackState();
15311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
15321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
15331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            mTargetState = STATE_PAUSED;
15341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (DEBUG) {
15351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                Log.d(TAG, "onPause(). mCurrentState=" + mCurrentState
15361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        + ", mTargetState=" + mTargetState);
15371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
15381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            showController();
15391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
15401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
15411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        @Override
15421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        public void onSeekTo(long pos) {
15431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (isInPlaybackState()) {
15441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                if (isRemotePlayback()) {
15451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mRoutePlayer.onPlay();
15461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                } else {
15471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    if (android.os.Build.VERSION.SDK_INT < 26) {
15481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMediaPlayer.seekTo((int) pos);
15491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    } else {
15501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                        mMediaPlayer.seekTo(pos, MediaPlayer2.SEEK_PREVIOUS_SYNC);
15511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    }
15521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                    mSeekWhenPrepared = 0;
15531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                }
15541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            } else {
15551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mSeekWhenPrepared = pos;
15561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
15571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            showController();
15581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
15591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang
15601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        @Override
15611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        public void onStop() {
15621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            if (isRemotePlayback()) {
15631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                mRoutePlayer.onPlay();
15641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            } else {
15651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang                resetPlayer();
15661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            }
15671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang            showController();
15681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang        }
15691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang    }
15701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang}
1571