14702556bfd15c9819a7b2af759aee0f719cd631fsusnata/* 295ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * Copyright (C) 2016 The Android Open Source Project 34702556bfd15c9819a7b2af759aee0f719cd631fsusnata * 495ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * Licensed under the Apache License, Version 2.0 (the "License"); 595ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * you may not use this file except in compliance with the License. 695ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * You may obtain a copy of the License at 74702556bfd15c9819a7b2af759aee0f719cd631fsusnata * 895ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * http://www.apache.org/licenses/LICENSE-2.0 94702556bfd15c9819a7b2af759aee0f719cd631fsusnata * 1095ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * Unless required by applicable law or agreed to in writing, software 1195ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * distributed under the License is distributed on an "AS IS" BASIS, 1295ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1395ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * See the License for the specific language governing permissions and 1495ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * limitations under the License. 154702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 164702556bfd15c9819a7b2af759aee0f719cd631fsusnata 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.leanback.media; 184702556bfd15c9819a7b2af759aee0f719cd631fsusnata 194702556bfd15c9819a7b2af759aee0f719cd631fsusnataimport android.content.Context; 204702556bfd15c9819a7b2af759aee0f719cd631fsusnataimport android.graphics.drawable.Drawable; 214702556bfd15c9819a7b2af759aee0f719cd631fsusnataimport android.media.AudioManager; 224702556bfd15c9819a7b2af759aee0f719cd631fsusnataimport android.media.MediaPlayer; 234702556bfd15c9819a7b2af759aee0f719cd631fsusnataimport android.net.Uri; 244702556bfd15c9819a7b2af759aee0f719cd631fsusnataimport android.os.Handler; 258619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport android.view.KeyEvent; 268619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport android.view.SurfaceHolder; 278619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport android.view.View; 288619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikas 29ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.RestrictTo; 30ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.Action; 31ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.ArrayObjectAdapter; 32ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.OnItemViewSelectedListener; 33ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.PlaybackControlsRow; 34ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.Presenter; 35ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.Row; 36ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.RowPresenter; 374702556bfd15c9819a7b2af759aee0f719cd631fsusnata 384702556bfd15c9819a7b2af759aee0f719cd631fsusnataimport java.io.IOException; 393bcad88cbf4488e747d84893c35f2351b8f84afeDake Guimport java.util.List; 404702556bfd15c9819a7b2af759aee0f719cd631fsusnata 414702556bfd15c9819a7b2af759aee0f719cd631fsusnata/** 42ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * This glue extends the {@link androidx.leanback.media.PlaybackControlGlue} with a 4395ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * {@link MediaPlayer} synchronization. It supports 7 actions: 444702556bfd15c9819a7b2af759aee0f719cd631fsusnata * 454702556bfd15c9819a7b2af759aee0f719cd631fsusnata * <ul> 46ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{@link androidx.leanback.widget.PlaybackControlsRow.FastForwardAction}</li> 47ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{@link androidx.leanback.widget.PlaybackControlsRow.RewindAction}</li> 48ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{@link androidx.leanback.widget.PlaybackControlsRow.PlayPauseAction}</li> 49ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{@link androidx.leanback.widget.PlaybackControlsRow.RepeatAction}</li> 50ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{@link androidx.leanback.widget.PlaybackControlsRow.ThumbsDownAction}</li> 51ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <li>{@link androidx.leanback.widget.PlaybackControlsRow.ThumbsUpAction}</li> 524702556bfd15c9819a7b2af759aee0f719cd631fsusnata * </ul> 534702556bfd15c9819a7b2af759aee0f719cd631fsusnata * 544702556bfd15c9819a7b2af759aee0f719cd631fsusnata * @hide 559f7da98dbcd12a0bbd48a563ff82fdcba7de3deaDake Gu * @deprecated Use {@link MediaPlayerAdapter} with {@link PlaybackTransportControlGlue} or 569f7da98dbcd12a0bbd48a563ff82fdcba7de3deaDake Gu * {@link PlaybackBannerControlGlue}. 574702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 589f7da98dbcd12a0bbd48a563ff82fdcba7de3deaDake Gu@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 599f7da98dbcd12a0bbd48a563ff82fdcba7de3deaDake Gu@Deprecated 604702556bfd15c9819a7b2af759aee0f719cd631fsusnatapublic class MediaPlayerGlue extends PlaybackControlGlue implements 614702556bfd15c9819a7b2af759aee0f719cd631fsusnata OnItemViewSelectedListener { 624702556bfd15c9819a7b2af759aee0f719cd631fsusnata 634702556bfd15c9819a7b2af759aee0f719cd631fsusnata public static final int NO_REPEAT = 0; 644702556bfd15c9819a7b2af759aee0f719cd631fsusnata public static final int REPEAT_ONE = 1; 654702556bfd15c9819a7b2af759aee0f719cd631fsusnata public static final int REPEAT_ALL = 2; 664702556bfd15c9819a7b2af759aee0f719cd631fsusnata 674702556bfd15c9819a7b2af759aee0f719cd631fsusnata public static final int FAST_FORWARD_REWIND_STEP = 10 * 1000; // in milliseconds 684702556bfd15c9819a7b2af759aee0f719cd631fsusnata public static final int FAST_FORWARD_REWIND_REPEAT_DELAY = 200; // in milliseconds 694702556bfd15c9819a7b2af759aee0f719cd631fsusnata private static final String TAG = "MediaPlayerGlue"; 704702556bfd15c9819a7b2af759aee0f719cd631fsusnata protected final PlaybackControlsRow.ThumbsDownAction mThumbsDownAction; 714702556bfd15c9819a7b2af759aee0f719cd631fsusnata protected final PlaybackControlsRow.ThumbsUpAction mThumbsUpAction; 724702556bfd15c9819a7b2af759aee0f719cd631fsusnata MediaPlayer mPlayer = new MediaPlayer(); 734702556bfd15c9819a7b2af759aee0f719cd631fsusnata private final PlaybackControlsRow.RepeatAction mRepeatAction; 744702556bfd15c9819a7b2af759aee0f719cd631fsusnata private Runnable mRunnable; 754702556bfd15c9819a7b2af759aee0f719cd631fsusnata private Handler mHandler = new Handler(); 764702556bfd15c9819a7b2af759aee0f719cd631fsusnata private boolean mInitialized = false; // true when the MediaPlayer is prepared/initialized 774702556bfd15c9819a7b2af759aee0f719cd631fsusnata private Action mSelectedAction; // the action which is currently selected by the user 784702556bfd15c9819a7b2af759aee0f719cd631fsusnata private long mLastKeyDownEvent = 0L; // timestamp when the last DPAD_CENTER KEY_DOWN occurred 794702556bfd15c9819a7b2af759aee0f719cd631fsusnata private Uri mMediaSourceUri = null; 804702556bfd15c9819a7b2af759aee0f719cd631fsusnata private String mMediaSourcePath = null; 814702556bfd15c9819a7b2af759aee0f719cd631fsusnata private MediaPlayer.OnCompletionListener mOnCompletionListener; 824702556bfd15c9819a7b2af759aee0f719cd631fsusnata private String mArtist; 834702556bfd15c9819a7b2af759aee0f719cd631fsusnata private String mTitle; 844702556bfd15c9819a7b2af759aee0f719cd631fsusnata private Drawable mCover; 854702556bfd15c9819a7b2af759aee0f719cd631fsusnata 864702556bfd15c9819a7b2af759aee0f719cd631fsusnata /** 874702556bfd15c9819a7b2af759aee0f719cd631fsusnata * Sets the drawable representing cover image. 884702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 894702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void setCover(Drawable cover) { 904702556bfd15c9819a7b2af759aee0f719cd631fsusnata this.mCover = cover; 914702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 924702556bfd15c9819a7b2af759aee0f719cd631fsusnata 934702556bfd15c9819a7b2af759aee0f719cd631fsusnata /** 944702556bfd15c9819a7b2af759aee0f719cd631fsusnata * Sets the artist name. 954702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 964702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void setArtist(String artist) { 974702556bfd15c9819a7b2af759aee0f719cd631fsusnata this.mArtist = artist; 984702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 994702556bfd15c9819a7b2af759aee0f719cd631fsusnata 1004702556bfd15c9819a7b2af759aee0f719cd631fsusnata /** 1014702556bfd15c9819a7b2af759aee0f719cd631fsusnata * Sets the media title. 1024702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 1034702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void setTitle(String title) { 1044702556bfd15c9819a7b2af759aee0f719cd631fsusnata this.mTitle = title; 1054702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 1064702556bfd15c9819a7b2af759aee0f719cd631fsusnata 1074702556bfd15c9819a7b2af759aee0f719cd631fsusnata /** 1084702556bfd15c9819a7b2af759aee0f719cd631fsusnata * Sets the url for the video. 1094702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 1104702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void setVideoUrl(String videoUrl) { 1114702556bfd15c9819a7b2af759aee0f719cd631fsusnata setMediaSource(videoUrl); 1124702556bfd15c9819a7b2af759aee0f719cd631fsusnata onMetadataChanged(); 1134702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 1144702556bfd15c9819a7b2af759aee0f719cd631fsusnata 1154702556bfd15c9819a7b2af759aee0f719cd631fsusnata /** 1164702556bfd15c9819a7b2af759aee0f719cd631fsusnata * Constructor. 1174702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 11895ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu public MediaPlayerGlue(Context context) { 11995ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu this(context, new int[]{1}, new int[]{1}); 1204702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 1214702556bfd15c9819a7b2af759aee0f719cd631fsusnata 1224702556bfd15c9819a7b2af759aee0f719cd631fsusnata /** 1234702556bfd15c9819a7b2af759aee0f719cd631fsusnata * Constructor. 1244702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 1254702556bfd15c9819a7b2af759aee0f719cd631fsusnata public MediaPlayerGlue( 12695ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu Context context, int[] fastForwardSpeeds, int[] rewindSpeeds) { 12795ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu super(context, fastForwardSpeeds, rewindSpeeds); 1284702556bfd15c9819a7b2af759aee0f719cd631fsusnata 1294702556bfd15c9819a7b2af759aee0f719cd631fsusnata // Instantiate secondary actions 13095ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu mRepeatAction = new PlaybackControlsRow.RepeatAction(getContext()); 13195ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(getContext()); 13295ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(getContext()); 133946a01cfedb6838e98d7a37e30f64c39b603893dDake Gu mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.INDEX_OUTLINE); 134946a01cfedb6838e98d7a37e30f64c39b603893dDake Gu mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.INDEX_OUTLINE); 1354702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 1364702556bfd15c9819a7b2af759aee0f719cd631fsusnata 1374702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 13895ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu protected void onAttachedToHost(PlaybackGlueHost host) { 13995ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu super.onAttachedToHost(host); 14095ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu if (host instanceof SurfaceHolderGlueHost) { 14195ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu ((SurfaceHolderGlueHost) host).setSurfaceHolderCallback( 14295ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu new VideoPlayerSurfaceHolderCallback()); 1434702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 1444702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 1454702556bfd15c9819a7b2af759aee0f719cd631fsusnata 1464702556bfd15c9819a7b2af759aee0f719cd631fsusnata /** 1474702556bfd15c9819a7b2af759aee0f719cd631fsusnata * Will reset the {@link MediaPlayer} and the glue such that a new file can be played. You are 1484702556bfd15c9819a7b2af759aee0f719cd631fsusnata * not required to call this method before playing the first file. However you have to call it 1494702556bfd15c9819a7b2af759aee0f719cd631fsusnata * before playing a second one. 1504702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 151aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata public void reset() { 1523bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu changeToUnitialized(); 1534702556bfd15c9819a7b2af759aee0f719cd631fsusnata mPlayer.reset(); 1544702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 1554702556bfd15c9819a7b2af759aee0f719cd631fsusnata 1563bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu void changeToUnitialized() { 1573bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (mInitialized) { 1583bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mInitialized = false; 1593bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu List<PlayerCallback> callbacks = getPlayerCallbacks(); 1603bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (callbacks != null) { 1613bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu for (PlayerCallback callback: callbacks) { 1623bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu callback.onPreparedStateChanged(MediaPlayerGlue.this); 1633bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1643bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1653bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1663bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1673bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 16895ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu /** 16995ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * Release internal MediaPlayer. Should not use the object after call release(). 17095ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu */ 171aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata public void release() { 1723bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu changeToUnitialized(); 173aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata mPlayer.release(); 174aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata } 175aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata 176aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata @Override 17795ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu protected void onDetachedFromHost() { 1783961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu if (getHost() instanceof SurfaceHolderGlueHost) { 1793961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu ((SurfaceHolderGlueHost) getHost()).setSurfaceHolderCallback(null); 1803961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu } 181aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata reset(); 182aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata release(); 1833961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu super.onDetachedFromHost(); 184aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata } 185aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata 18695ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu @Override 18795ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu protected void onCreateSecondaryActions(ArrayObjectAdapter secondaryActionsAdapter) { 1884702556bfd15c9819a7b2af759aee0f719cd631fsusnata secondaryActionsAdapter.add(mRepeatAction); 1894702556bfd15c9819a7b2af759aee0f719cd631fsusnata secondaryActionsAdapter.add(mThumbsDownAction); 1904702556bfd15c9819a7b2af759aee0f719cd631fsusnata secondaryActionsAdapter.add(mThumbsUpAction); 1914702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 1924702556bfd15c9819a7b2af759aee0f719cd631fsusnata 1934702556bfd15c9819a7b2af759aee0f719cd631fsusnata /** 1944702556bfd15c9819a7b2af759aee0f719cd631fsusnata * @see MediaPlayer#setDisplay(SurfaceHolder) 1954702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 1964702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void setDisplay(SurfaceHolder surfaceHolder) { 1974702556bfd15c9819a7b2af759aee0f719cd631fsusnata mPlayer.setDisplay(surfaceHolder); 1984702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 1994702556bfd15c9819a7b2af759aee0f719cd631fsusnata 2004702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 2014702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void enableProgressUpdating(final boolean enabled) { 2023961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu if (mRunnable != null) mHandler.removeCallbacks(mRunnable); 2034702556bfd15c9819a7b2af759aee0f719cd631fsusnata if (!enabled) { 2044702556bfd15c9819a7b2af759aee0f719cd631fsusnata return; 2054702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 2063961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu if (mRunnable == null) { 2073961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu mRunnable = new Runnable() { 2083961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu @Override 2093961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu public void run() { 2103961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu updateProgress(); 2113961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu mHandler.postDelayed(this, getUpdatePeriod()); 2123961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu } 2133961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu }; 2143961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu } 2154702556bfd15c9819a7b2af759aee0f719cd631fsusnata mHandler.postDelayed(mRunnable, getUpdatePeriod()); 2164702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 2174702556bfd15c9819a7b2af759aee0f719cd631fsusnata 2184702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 2194702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void onActionClicked(Action action) { 2204702556bfd15c9819a7b2af759aee0f719cd631fsusnata // If either 'Shuffle' or 'Repeat' has been clicked we need to make sure the actions index 2214702556bfd15c9819a7b2af759aee0f719cd631fsusnata // is incremented and the UI updated such that we can display the new state. 2224702556bfd15c9819a7b2af759aee0f719cd631fsusnata super.onActionClicked(action); 2234702556bfd15c9819a7b2af759aee0f719cd631fsusnata if (action instanceof PlaybackControlsRow.RepeatAction) { 224946a01cfedb6838e98d7a37e30f64c39b603893dDake Gu ((PlaybackControlsRow.RepeatAction) action).nextIndex(); 225946a01cfedb6838e98d7a37e30f64c39b603893dDake Gu } else if (action == mThumbsUpAction) { 226946a01cfedb6838e98d7a37e30f64c39b603893dDake Gu if (mThumbsUpAction.getIndex() == PlaybackControlsRow.ThumbsAction.INDEX_SOLID) { 227946a01cfedb6838e98d7a37e30f64c39b603893dDake Gu mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.INDEX_OUTLINE); 2284702556bfd15c9819a7b2af759aee0f719cd631fsusnata } else { 229946a01cfedb6838e98d7a37e30f64c39b603893dDake Gu mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.INDEX_SOLID); 230946a01cfedb6838e98d7a37e30f64c39b603893dDake Gu mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.INDEX_OUTLINE); 2314702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 232946a01cfedb6838e98d7a37e30f64c39b603893dDake Gu } else if (action == mThumbsDownAction) { 233946a01cfedb6838e98d7a37e30f64c39b603893dDake Gu if (mThumbsDownAction.getIndex() == PlaybackControlsRow.ThumbsAction.INDEX_SOLID) { 234946a01cfedb6838e98d7a37e30f64c39b603893dDake Gu mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.INDEX_OUTLINE); 2354702556bfd15c9819a7b2af759aee0f719cd631fsusnata } else { 236946a01cfedb6838e98d7a37e30f64c39b603893dDake Gu mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.INDEX_SOLID); 237946a01cfedb6838e98d7a37e30f64c39b603893dDake Gu mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.INDEX_OUTLINE); 2384702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 2394702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 2404702556bfd15c9819a7b2af759aee0f719cd631fsusnata onMetadataChanged(); 2414702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 2424702556bfd15c9819a7b2af759aee0f719cd631fsusnata 2434702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 2444702556bfd15c9819a7b2af759aee0f719cd631fsusnata public boolean onKey(View v, int keyCode, KeyEvent event) { 2454702556bfd15c9819a7b2af759aee0f719cd631fsusnata // This method is overridden in order to make implement fast forwarding and rewinding when 2464702556bfd15c9819a7b2af759aee0f719cd631fsusnata // the user keeps the corresponding action pressed. 2474702556bfd15c9819a7b2af759aee0f719cd631fsusnata // We only consume DPAD_CENTER Action_DOWN events on the Fast-Forward and Rewind action and 2484702556bfd15c9819a7b2af759aee0f719cd631fsusnata // only if it has not been pressed in the last X milliseconds. 2494702556bfd15c9819a7b2af759aee0f719cd631fsusnata boolean consume = mSelectedAction instanceof PlaybackControlsRow.RewindAction; 2504702556bfd15c9819a7b2af759aee0f719cd631fsusnata consume = consume || mSelectedAction instanceof PlaybackControlsRow.FastForwardAction; 2514702556bfd15c9819a7b2af759aee0f719cd631fsusnata consume = consume && mInitialized; 2524702556bfd15c9819a7b2af759aee0f719cd631fsusnata consume = consume && event.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER; 2534702556bfd15c9819a7b2af759aee0f719cd631fsusnata consume = consume && event.getAction() == KeyEvent.ACTION_DOWN; 2544702556bfd15c9819a7b2af759aee0f719cd631fsusnata consume = consume && System 2554702556bfd15c9819a7b2af759aee0f719cd631fsusnata .currentTimeMillis() - mLastKeyDownEvent > FAST_FORWARD_REWIND_REPEAT_DELAY; 2564702556bfd15c9819a7b2af759aee0f719cd631fsusnata 2574702556bfd15c9819a7b2af759aee0f719cd631fsusnata if (consume) { 2584702556bfd15c9819a7b2af759aee0f719cd631fsusnata mLastKeyDownEvent = System.currentTimeMillis(); 2594702556bfd15c9819a7b2af759aee0f719cd631fsusnata int newPosition = getCurrentPosition() + FAST_FORWARD_REWIND_STEP; 2604702556bfd15c9819a7b2af759aee0f719cd631fsusnata if (mSelectedAction instanceof PlaybackControlsRow.RewindAction) { 2614702556bfd15c9819a7b2af759aee0f719cd631fsusnata newPosition = getCurrentPosition() - FAST_FORWARD_REWIND_STEP; 2624702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 2634702556bfd15c9819a7b2af759aee0f719cd631fsusnata // Make sure the new calculated duration is in the range 0 >= X >= MediaDuration 2644702556bfd15c9819a7b2af759aee0f719cd631fsusnata if (newPosition < 0) newPosition = 0; 2654702556bfd15c9819a7b2af759aee0f719cd631fsusnata if (newPosition > getMediaDuration()) newPosition = getMediaDuration(); 2664702556bfd15c9819a7b2af759aee0f719cd631fsusnata seekTo(newPosition); 2674702556bfd15c9819a7b2af759aee0f719cd631fsusnata return true; 2684702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 2694702556bfd15c9819a7b2af759aee0f719cd631fsusnata 2704702556bfd15c9819a7b2af759aee0f719cd631fsusnata return super.onKey(v, keyCode, event); 2714702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 2724702556bfd15c9819a7b2af759aee0f719cd631fsusnata 2734702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 2744702556bfd15c9819a7b2af759aee0f719cd631fsusnata public boolean hasValidMedia() { 275aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata return mTitle != null && (mMediaSourcePath != null || mMediaSourceUri != null); 2764702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 2774702556bfd15c9819a7b2af759aee0f719cd631fsusnata 2784702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 2794702556bfd15c9819a7b2af759aee0f719cd631fsusnata public boolean isMediaPlaying() { 280f37579e64940bfdd642cc315f6347d60b5addd69Dake Gu return mInitialized && mPlayer.isPlaying(); 2814702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 2824702556bfd15c9819a7b2af759aee0f719cd631fsusnata 2834702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 2843bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public boolean isPlaying() { 2853bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return isMediaPlaying(); 2863bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2873bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 2883bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 2894702556bfd15c9819a7b2af759aee0f719cd631fsusnata public CharSequence getMediaTitle() { 2904702556bfd15c9819a7b2af759aee0f719cd631fsusnata return mTitle != null ? mTitle : "N/a"; 2914702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 2924702556bfd15c9819a7b2af759aee0f719cd631fsusnata 2934702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 2944702556bfd15c9819a7b2af759aee0f719cd631fsusnata public CharSequence getMediaSubtitle() { 2954702556bfd15c9819a7b2af759aee0f719cd631fsusnata return mArtist != null ? mArtist : "N/a"; 2964702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 2974702556bfd15c9819a7b2af759aee0f719cd631fsusnata 2984702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 2994702556bfd15c9819a7b2af759aee0f719cd631fsusnata public int getMediaDuration() { 3004702556bfd15c9819a7b2af759aee0f719cd631fsusnata return mInitialized ? mPlayer.getDuration() : 0; 3014702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 3024702556bfd15c9819a7b2af759aee0f719cd631fsusnata 3034702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 3044702556bfd15c9819a7b2af759aee0f719cd631fsusnata public Drawable getMediaArt() { 3054702556bfd15c9819a7b2af759aee0f719cd631fsusnata return mCover; 3064702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 3074702556bfd15c9819a7b2af759aee0f719cd631fsusnata 3084702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 3094702556bfd15c9819a7b2af759aee0f719cd631fsusnata public long getSupportedActions() { 3104702556bfd15c9819a7b2af759aee0f719cd631fsusnata return PlaybackControlGlue.ACTION_PLAY_PAUSE 3114702556bfd15c9819a7b2af759aee0f719cd631fsusnata | PlaybackControlGlue.ACTION_FAST_FORWARD 3124702556bfd15c9819a7b2af759aee0f719cd631fsusnata | PlaybackControlGlue.ACTION_REWIND; 3134702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 3144702556bfd15c9819a7b2af759aee0f719cd631fsusnata 3154702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 3164702556bfd15c9819a7b2af759aee0f719cd631fsusnata public int getCurrentSpeedId() { 3174702556bfd15c9819a7b2af759aee0f719cd631fsusnata // 0 = Pause, 1 = Normal Playback Speed 318f37579e64940bfdd642cc315f6347d60b5addd69Dake Gu return isMediaPlaying() ? 1 : 0; 3194702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 3204702556bfd15c9819a7b2af759aee0f719cd631fsusnata 3214702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 3224702556bfd15c9819a7b2af759aee0f719cd631fsusnata public int getCurrentPosition() { 3234702556bfd15c9819a7b2af759aee0f719cd631fsusnata return mInitialized ? mPlayer.getCurrentPosition() : 0; 3244702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 3254702556bfd15c9819a7b2af759aee0f719cd631fsusnata 3264702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 32795ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu public void play(int speed) { 3283961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu if (!mInitialized || mPlayer.isPlaying()) { 3293961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu return; 3303961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu } 3314702556bfd15c9819a7b2af759aee0f719cd631fsusnata mPlayer.start(); 3324702556bfd15c9819a7b2af759aee0f719cd631fsusnata onMetadataChanged(); 3334702556bfd15c9819a7b2af759aee0f719cd631fsusnata onStateChanged(); 3344702556bfd15c9819a7b2af759aee0f719cd631fsusnata updateProgress(); 3354702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 3364702556bfd15c9819a7b2af759aee0f719cd631fsusnata 3374702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 3384702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void pause() { 339f37579e64940bfdd642cc315f6347d60b5addd69Dake Gu if (isMediaPlaying()) { 3404702556bfd15c9819a7b2af759aee0f719cd631fsusnata mPlayer.pause(); 3413961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu onStateChanged(); 3424702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 3434702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 3444702556bfd15c9819a7b2af759aee0f719cd631fsusnata 3454702556bfd15c9819a7b2af759aee0f719cd631fsusnata /** 3464702556bfd15c9819a7b2af759aee0f719cd631fsusnata * Sets the playback mode. It currently support no repeat, repeat once and infinite 3474702556bfd15c9819a7b2af759aee0f719cd631fsusnata * loop mode. 3484702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 3494702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void setMode(int mode) { 3504702556bfd15c9819a7b2af759aee0f719cd631fsusnata switch(mode) { 3514702556bfd15c9819a7b2af759aee0f719cd631fsusnata case NO_REPEAT: 3524702556bfd15c9819a7b2af759aee0f719cd631fsusnata mOnCompletionListener = null; 3534702556bfd15c9819a7b2af759aee0f719cd631fsusnata break; 3544702556bfd15c9819a7b2af759aee0f719cd631fsusnata case REPEAT_ONE: 3554702556bfd15c9819a7b2af759aee0f719cd631fsusnata mOnCompletionListener = new MediaPlayer.OnCompletionListener() { 3564702556bfd15c9819a7b2af759aee0f719cd631fsusnata public boolean mFirstRepeat; 3574702556bfd15c9819a7b2af759aee0f719cd631fsusnata 3584702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 3594702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void onCompletion(MediaPlayer mediaPlayer) { 3604702556bfd15c9819a7b2af759aee0f719cd631fsusnata if (!mFirstRepeat) { 3614702556bfd15c9819a7b2af759aee0f719cd631fsusnata mFirstRepeat = true; 3624702556bfd15c9819a7b2af759aee0f719cd631fsusnata mediaPlayer.setOnCompletionListener(null); 3634702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 3644702556bfd15c9819a7b2af759aee0f719cd631fsusnata play(); 3654702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 3664702556bfd15c9819a7b2af759aee0f719cd631fsusnata }; 3674702556bfd15c9819a7b2af759aee0f719cd631fsusnata break; 3684702556bfd15c9819a7b2af759aee0f719cd631fsusnata case REPEAT_ALL: 3694702556bfd15c9819a7b2af759aee0f719cd631fsusnata mOnCompletionListener = new MediaPlayer.OnCompletionListener() { 3704702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 3714702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void onCompletion(MediaPlayer mediaPlayer) { 3724702556bfd15c9819a7b2af759aee0f719cd631fsusnata play(); 3734702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 3744702556bfd15c9819a7b2af759aee0f719cd631fsusnata }; 3754702556bfd15c9819a7b2af759aee0f719cd631fsusnata break; 3764702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 3774702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 3784702556bfd15c9819a7b2af759aee0f719cd631fsusnata 3794702556bfd15c9819a7b2af759aee0f719cd631fsusnata /** 3804702556bfd15c9819a7b2af759aee0f719cd631fsusnata * Called whenever the user presses fast-forward/rewind or when the user keeps the 3814702556bfd15c9819a7b2af759aee0f719cd631fsusnata * corresponding action pressed. 3824702556bfd15c9819a7b2af759aee0f719cd631fsusnata * 3834702556bfd15c9819a7b2af759aee0f719cd631fsusnata * @param newPosition The new position of the media track in milliseconds. 3844702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 3854702556bfd15c9819a7b2af759aee0f719cd631fsusnata protected void seekTo(int newPosition) { 386f37579e64940bfdd642cc315f6347d60b5addd69Dake Gu if (!mInitialized) { 387f37579e64940bfdd642cc315f6347d60b5addd69Dake Gu return; 388f37579e64940bfdd642cc315f6347d60b5addd69Dake Gu } 3894702556bfd15c9819a7b2af759aee0f719cd631fsusnata mPlayer.seekTo(newPosition); 3904702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 3914702556bfd15c9819a7b2af759aee0f719cd631fsusnata 3924702556bfd15c9819a7b2af759aee0f719cd631fsusnata /** 3934702556bfd15c9819a7b2af759aee0f719cd631fsusnata * Sets the media source of the player witha given URI. 3944702556bfd15c9819a7b2af759aee0f719cd631fsusnata * 3954702556bfd15c9819a7b2af759aee0f719cd631fsusnata * @return Returns <code>true</code> if uri represents a new media; <code>false</code> 3964702556bfd15c9819a7b2af759aee0f719cd631fsusnata * otherwise. 3974702556bfd15c9819a7b2af759aee0f719cd631fsusnata * @see MediaPlayer#setDataSource(String) 3984702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 3994702556bfd15c9819a7b2af759aee0f719cd631fsusnata public boolean setMediaSource(Uri uri) { 400694edde99dc3782374977dab6d9aa34a16c13337Dake Gu if (mMediaSourceUri != null ? mMediaSourceUri.equals(uri) : uri == null) { 4014702556bfd15c9819a7b2af759aee0f719cd631fsusnata return false; 4024702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 403694edde99dc3782374977dab6d9aa34a16c13337Dake Gu mMediaSourceUri = uri; 404694edde99dc3782374977dab6d9aa34a16c13337Dake Gu mMediaSourcePath = null; 405694edde99dc3782374977dab6d9aa34a16c13337Dake Gu prepareMediaForPlaying(); 4064702556bfd15c9819a7b2af759aee0f719cd631fsusnata return true; 4074702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 4084702556bfd15c9819a7b2af759aee0f719cd631fsusnata 4094702556bfd15c9819a7b2af759aee0f719cd631fsusnata /** 4104702556bfd15c9819a7b2af759aee0f719cd631fsusnata * Sets the media source of the player with a String path URL. 4114702556bfd15c9819a7b2af759aee0f719cd631fsusnata * 4124702556bfd15c9819a7b2af759aee0f719cd631fsusnata * @return Returns <code>true</code> if path represents a new media; <code>false</code> 4134702556bfd15c9819a7b2af759aee0f719cd631fsusnata * otherwise. 4144702556bfd15c9819a7b2af759aee0f719cd631fsusnata * @see MediaPlayer#setDataSource(String) 4154702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 4164702556bfd15c9819a7b2af759aee0f719cd631fsusnata public boolean setMediaSource(String path) { 417694edde99dc3782374977dab6d9aa34a16c13337Dake Gu if (mMediaSourcePath != null ? mMediaSourcePath.equals(path) : path == null) { 4184702556bfd15c9819a7b2af759aee0f719cd631fsusnata return false; 4194702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 420694edde99dc3782374977dab6d9aa34a16c13337Dake Gu mMediaSourceUri = null; 421694edde99dc3782374977dab6d9aa34a16c13337Dake Gu mMediaSourcePath = path; 422694edde99dc3782374977dab6d9aa34a16c13337Dake Gu prepareMediaForPlaying(); 4234702556bfd15c9819a7b2af759aee0f719cd631fsusnata return true; 4244702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 4254702556bfd15c9819a7b2af759aee0f719cd631fsusnata 4264702556bfd15c9819a7b2af759aee0f719cd631fsusnata private void prepareMediaForPlaying() { 4274702556bfd15c9819a7b2af759aee0f719cd631fsusnata reset(); 4284702556bfd15c9819a7b2af759aee0f719cd631fsusnata try { 429aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata if (mMediaSourceUri != null) { 430aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata mPlayer.setDataSource(getContext(), mMediaSourceUri); 431aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata } else if (mMediaSourcePath != null) { 432aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata mPlayer.setDataSource(mMediaSourcePath); 433aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata } else { 434aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata return; 435aa49439ba6276137f94fcdc1bf4f69b78833dad6susnata } 4364702556bfd15c9819a7b2af759aee0f719cd631fsusnata } catch (IOException e) { 4374702556bfd15c9819a7b2af759aee0f719cd631fsusnata e.printStackTrace(); 4384702556bfd15c9819a7b2af759aee0f719cd631fsusnata throw new RuntimeException(e); 4394702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 4404702556bfd15c9819a7b2af759aee0f719cd631fsusnata mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 4414702556bfd15c9819a7b2af759aee0f719cd631fsusnata mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 4424702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 4434702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void onPrepared(MediaPlayer mp) { 4444702556bfd15c9819a7b2af759aee0f719cd631fsusnata mInitialized = true; 4453bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu List<PlayerCallback> callbacks = getPlayerCallbacks(); 4463bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (callbacks != null) { 4473bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu for (PlayerCallback callback: callbacks) { 4483bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu callback.onPreparedStateChanged(MediaPlayerGlue.this); 4493bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 4504702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 4514702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 4524702556bfd15c9819a7b2af759aee0f719cd631fsusnata }); 4534702556bfd15c9819a7b2af759aee0f719cd631fsusnata 4544702556bfd15c9819a7b2af759aee0f719cd631fsusnata if (mOnCompletionListener != null) { 4554702556bfd15c9819a7b2af759aee0f719cd631fsusnata mPlayer.setOnCompletionListener(mOnCompletionListener); 4564702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 4574702556bfd15c9819a7b2af759aee0f719cd631fsusnata 4584702556bfd15c9819a7b2af759aee0f719cd631fsusnata mPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() { 4594702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 4604702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void onBufferingUpdate(MediaPlayer mp, int percent) { 4613961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu if (getControlsRow() == null) { 4623961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu return; 4633961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu } 46495ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu getControlsRow().setBufferedProgress((int) (mp.getDuration() * (percent / 100f))); 4654702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 4664702556bfd15c9819a7b2af759aee0f719cd631fsusnata }); 4674702556bfd15c9819a7b2af759aee0f719cd631fsusnata mPlayer.prepareAsync(); 4684702556bfd15c9819a7b2af759aee0f719cd631fsusnata onStateChanged(); 4694702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 4704702556bfd15c9819a7b2af759aee0f719cd631fsusnata 4714702556bfd15c9819a7b2af759aee0f719cd631fsusnata /** 47295ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * This is a listener implementation for the {@link OnItemViewSelectedListener}. 47395ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * This implementation is required in order to detect KEY_DOWN events 474ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * on the {@link androidx.leanback.widget.PlaybackControlsRow.FastForwardAction} and 475ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * {@link androidx.leanback.widget.PlaybackControlsRow.RewindAction}. Thus you 4764702556bfd15c9819a7b2af759aee0f719cd631fsusnata * should <u>NOT</u> set another {@link OnItemViewSelectedListener} on your 47795ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * Fragment. Instead, override this method and call its super (this) 4784702556bfd15c9819a7b2af759aee0f719cd631fsusnata * implementation. 4794702556bfd15c9819a7b2af759aee0f719cd631fsusnata * 4804702556bfd15c9819a7b2af759aee0f719cd631fsusnata * @see OnItemViewSelectedListener#onItemSelected( 4814702556bfd15c9819a7b2af759aee0f719cd631fsusnata *Presenter.ViewHolder, Object, RowPresenter.ViewHolder, Object) 4824702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 4834702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 4844702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, 4854702556bfd15c9819a7b2af759aee0f719cd631fsusnata RowPresenter.ViewHolder rowViewHolder, Row row) { 4864702556bfd15c9819a7b2af759aee0f719cd631fsusnata if (item instanceof Action) { 4874702556bfd15c9819a7b2af759aee0f719cd631fsusnata mSelectedAction = (Action) item; 4884702556bfd15c9819a7b2af759aee0f719cd631fsusnata } else { 4894702556bfd15c9819a7b2af759aee0f719cd631fsusnata mSelectedAction = null; 4904702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 4914702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 4924702556bfd15c9819a7b2af759aee0f719cd631fsusnata 4934702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 4943bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public boolean isPrepared() { 4953bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return mInitialized; 4963bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 4973bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 4984702556bfd15c9819a7b2af759aee0f719cd631fsusnata /** 49995ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * Implements {@link SurfaceHolder.Callback} that can then be set on the 50095ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu * {@link PlaybackGlueHost}. 5014702556bfd15c9819a7b2af759aee0f719cd631fsusnata */ 50295ac470f2bbea06114a64906d95c0da7d9412db0Dake Gu class VideoPlayerSurfaceHolderCallback implements SurfaceHolder.Callback { 5034702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 5044702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void surfaceCreated(SurfaceHolder surfaceHolder) { 5053961cea270f51c29433a7eb21ec5f8c9ca7bd7d7Dake Gu setDisplay(surfaceHolder); 5064702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 5074702556bfd15c9819a7b2af759aee0f719cd631fsusnata 5084702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 5094702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) { 5104702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 5114702556bfd15c9819a7b2af759aee0f719cd631fsusnata 5124702556bfd15c9819a7b2af759aee0f719cd631fsusnata @Override 5134702556bfd15c9819a7b2af759aee0f719cd631fsusnata public void surfaceDestroyed(SurfaceHolder surfaceHolder) { 5144702556bfd15c9819a7b2af759aee0f719cd631fsusnata setDisplay(null); 5154702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 5164702556bfd15c9819a7b2af759aee0f719cd631fsusnata } 5174702556bfd15c9819a7b2af759aee0f719cd631fsusnata} 518