186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn/* 286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * Copyright (C) 2015 The Android Open Source Project 386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * 486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * in compliance with the License. You may obtain a copy of the License at 686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * 786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * http://www.apache.org/licenses/LICENSE-2.0 886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * 986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * Unless required by applicable law or agreed to in writing, software distributed under the License 1086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 1186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * or implied. See the License for the specific language governing permissions and limitations under 1286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * the License. 1386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * 1486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 1586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 16ad31f63f5843898de645f6ee1ac244c872ded8ccRobert Hahnpackage android.support.v17.leanback.supportleanbackshowcase.app.media; 1786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 1886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.content.Context; 1986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.graphics.Color; 2086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.graphics.drawable.Drawable; 2186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.media.AudioManager; 2286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.media.MediaPlayer; 2386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.net.Uri; 2486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.os.Handler; 2586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.support.v17.leanback.app.PlaybackControlGlue; 2686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.support.v17.leanback.app.PlaybackOverlayFragment; 271dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiriimport android.support.v17.leanback.supportleanbackshowcase.R; 2886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.support.v17.leanback.widget.Action; 2986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.support.v17.leanback.widget.ArrayObjectAdapter; 3086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.support.v17.leanback.widget.ControlButtonPresenterSelector; 3186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.support.v17.leanback.widget.OnItemViewSelectedListener; 3286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.support.v17.leanback.widget.PlaybackControlsRow; 3386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.support.v17.leanback.widget.PlaybackControlsRowPresenter; 3486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.support.v17.leanback.widget.Presenter; 3586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.support.v17.leanback.widget.Row; 3686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.support.v17.leanback.widget.RowPresenter; 3786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.util.Log; 3886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.view.KeyEvent; 3986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.view.SurfaceHolder; 4086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport android.view.View; 4186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 4286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnimport java.io.IOException; 4386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 4486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn/** 4586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * This glue extends the {@link PlaybackControlGlue} with a {@link MediaPlayer} synchronization. It 4686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * supports 7 actions: <ul> <li>{@link android.support.v17.leanback.widget.PlaybackControlsRow.FastForwardAction}</li> 4786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * <li>{@link android.support.v17.leanback.widget.PlaybackControlsRow.RewindAction}</li> <li>{@link 4886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * android.support.v17.leanback.widget.PlaybackControlsRow.PlayPauseAction}</li> <li>{@link 4986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * android.support.v17.leanback.widget.PlaybackControlsRow.ShuffleAction}</li> <li>{@link 5086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * android.support.v17.leanback.widget.PlaybackControlsRow.RepeatAction}</li> <li>{@link 5186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsDownAction}</li> <li>{@link 5286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsUpAction}</li> </ul> 5386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * <p/> 5486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 5586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahnpublic abstract class MediaPlayerGlue extends PlaybackControlGlue implements 5686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn OnItemViewSelectedListener { 5786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 5886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public static final int FAST_FORWARD_REWIND_STEP = 10 * 1000; // in milliseconds 5986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public static final int FAST_FORWARD_REWIND_REPEAT_DELAY = 200; // in milliseconds 6086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private static final String TAG = "MediaPlayerGlue"; 6186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn protected final PlaybackControlsRow.ThumbsDownAction mThumbsDownAction; 6286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn protected final PlaybackControlsRow.ThumbsUpAction mThumbsUpAction; 6386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private final Context mContext; 6486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private final MediaPlayer mPlayer = new MediaPlayer(); 6586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private final PlaybackControlsRow.RepeatAction mRepeatAction; 6686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private final PlaybackControlsRow.ShuffleAction mShuffleAction; 6786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private PlaybackControlsRow mControlsRow; 6886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private Runnable mRunnable; 6986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private Handler mHandler = new Handler(); 7086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private boolean mInitialized = false; // true when the MediaPlayer is prepared/initialized 7186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private OnMediaFileFinishedPlayingListener mMediaFileFinishedPlayingListener; 7286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private Action mSelectedAction; // the action which is currently selected by the user 7386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private long mLastKeyDownEvent = 0L; // timestamp when the last DPAD_CENTER KEY_DOWN occurred 7486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private MetaData mMetaData; 7586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private Uri mMediaSourceUri = null; 7686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private String mMediaSourcePath = null; 7786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 7886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public MediaPlayerGlue(Context context, PlaybackOverlayFragment fragment) { 7986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn super(context, fragment, new int[]{1}); 8086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mContext = context; 8186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 8286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn // Instantiate secondary actions 8386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mShuffleAction = new PlaybackControlsRow.ShuffleAction(mContext); 8486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mRepeatAction = new PlaybackControlsRow.RepeatAction(mContext); 8586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(mContext); 8686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(mContext); 8786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); 8886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); 8986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 9086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn // Register selected listener such that we know what action the user currently has focused. 9186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn fragment.setOnItemViewSelectedListener(this); 9286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 9386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 9486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn /** 9586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * Will reset the {@link MediaPlayer} and the glue such that a new file can be played. You are 9686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * not required to call this method before playing the first file. However you have to call it 9786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * before playing a second one. 9886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 991dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri void reset() { 1001dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri mInitialized = false; 10186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mPlayer.reset(); 10286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 10386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 10486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public void setOnMediaFileFinishedPlayingListener(OnMediaFileFinishedPlayingListener listener) { 10586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mMediaFileFinishedPlayingListener = listener; 10686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 10786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 10886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn /** 10986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * Override this method in case you need to add different secondary actions. 11086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * 11186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * @param secondaryActionsAdapter The adapter you need to add the {@link Action}s to. 11286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 11386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn protected void addSecondaryActions(ArrayObjectAdapter secondaryActionsAdapter) { 11486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn secondaryActionsAdapter.add(mShuffleAction); 11586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn secondaryActionsAdapter.add(mRepeatAction); 11686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn secondaryActionsAdapter.add(mThumbsDownAction); 11786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn secondaryActionsAdapter.add(mThumbsUpAction); 11886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 11986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 12086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn /** 12186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * @see MediaPlayer#setDisplay(SurfaceHolder) 12286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 12386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public void setDisplay(SurfaceHolder surfaceHolder) { 12486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mPlayer.setDisplay(surfaceHolder); 12586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 12686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 12786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn /** 12886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * Use this method to setup the {@link PlaybackControlsRowPresenter}. It'll be called 12986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * <u>after</u> the {@link PlaybackControlsRowPresenter} has been created and the primary and 13086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * secondary actions have been added. 13186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * 13286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * @param presenter The PlaybackControlsRowPresenter used to display the controls. 13386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 13486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public void setupControlsRowPresenter(PlaybackControlsRowPresenter presenter) { 13586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn // TODO: hahnr@ move into resources 1365fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri presenter.setProgressColor(getContext().getResources().getColor( 1375fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri R.color.player_progress_color)); 1385fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri presenter.setBackgroundColor(getContext().getResources().getColor( 1395fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri R.color.player_background_color)); 14086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 14186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 14286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public PlaybackControlsRowPresenter createControlsRowAndPresenter() { 14386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn PlaybackControlsRowPresenter presenter = super.createControlsRowAndPresenter(); 14486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mControlsRow = getControlsRow(); 14586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 14686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn // Add secondary actions and change the control row color. 14786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn ArrayObjectAdapter secondaryActions = new ArrayObjectAdapter( 14886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn new ControlButtonPresenterSelector()); 14986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mControlsRow.setSecondaryActionsAdapter(secondaryActions); 15086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn addSecondaryActions(secondaryActions); 15186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn setupControlsRowPresenter(presenter); 15286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return presenter; 15386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 15486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 15586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public void enableProgressUpdating(final boolean enabled) { 15686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn if (!enabled) { 15786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn if (mRunnable != null) mHandler.removeCallbacks(mRunnable); 15886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return; 15986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 16086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mRunnable = new Runnable() { 16186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public void run() { 16286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn updateProgress(); 16386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn Log.d(TAG, "enableProgressUpdating(boolean)"); 16486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mHandler.postDelayed(this, getUpdatePeriod()); 16586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 16686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn }; 16786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mHandler.postDelayed(mRunnable, getUpdatePeriod()); 16886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 16986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 17086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public void onActionClicked(Action action) { 17186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn // If either 'Shuffle' or 'Repeat' has been clicked we need to make sure the acitons index 17286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn // is incremented and the UI updated such that we can display the new state. 17386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn super.onActionClicked(action); 17486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn if (action instanceof PlaybackControlsRow.ShuffleAction) { 17586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mShuffleAction.nextIndex(); 17686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } else if (action instanceof PlaybackControlsRow.RepeatAction) { 17786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mRepeatAction.nextIndex(); 17886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } else if (action instanceof PlaybackControlsRow.ThumbsUpAction) { 17986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn if (mThumbsUpAction.getIndex() == PlaybackControlsRow.ThumbsAction.SOLID) { 18086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); 18186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } else { 18286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.SOLID); 18386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); 18486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 18586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } else if (action instanceof PlaybackControlsRow.ThumbsDownAction) { 18686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn if (mThumbsDownAction.getIndex() == PlaybackControlsRow.ThumbsAction.SOLID) { 18786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); 18886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } else { 18986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsAction.SOLID); 19086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsAction.OUTLINE); 19186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 19286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 19386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn onMetadataChanged(); 19486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 19586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 19686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public boolean onKey(View v, int keyCode, KeyEvent event) { 19786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn // This method is overridden in order to make implement fast forwarding and rewinding when 19886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn // the user keeps the corresponding action pressed. 19986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn // We only consume DPAD_CENTER Action_DOWN events on the Fast-Forward and Rewind action and 20086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn // only if it has not been pressed in the last X milliseconds. 20186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn boolean consume = mSelectedAction instanceof PlaybackControlsRow.RewindAction; 20286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn consume = consume || mSelectedAction instanceof PlaybackControlsRow.FastForwardAction; 20386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn consume = consume && mInitialized; 20486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn consume = consume && event.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER; 20586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn consume = consume && event.getAction() == KeyEvent.ACTION_DOWN; 20686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn consume = consume && System 20786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn .currentTimeMillis() - mLastKeyDownEvent > FAST_FORWARD_REWIND_REPEAT_DELAY; 20886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn if (consume) { 20986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mLastKeyDownEvent = System.currentTimeMillis(); 21086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn int newPosition = getCurrentPosition() + FAST_FORWARD_REWIND_STEP; 21186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn if (mSelectedAction instanceof PlaybackControlsRow.RewindAction) { 21286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn newPosition = getCurrentPosition() - FAST_FORWARD_REWIND_STEP; 21386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 21486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn // Make sure the new calculated duration is in the range 0 >= X >= MediaDuration 21586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn if (newPosition < 0) newPosition = 0; 21686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn if (newPosition > getMediaDuration()) newPosition = getMediaDuration(); 21786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn seekTo(newPosition); 21886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return true; 21986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 22086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return super.onKey(v, keyCode, event); 22186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 22286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 22386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public boolean hasValidMedia() { 22486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return mMetaData != null; 22586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 22686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 22786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public boolean isMediaPlaying() { 22886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return mPlayer.isPlaying(); 22986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 23086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 23186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public CharSequence getMediaTitle() { 23286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return hasValidMedia() ? mMetaData.getTitle() : "N/a"; 23386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 23486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 23586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public CharSequence getMediaSubtitle() { 23686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return hasValidMedia() ? mMetaData.getArtist() : "N/a"; 23786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 23886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 23986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public int getMediaDuration() { 24086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return mInitialized ? mPlayer.getDuration() : 0; 24186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 24286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 24386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public Drawable getMediaArt() { 24486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return hasValidMedia() ? mMetaData.getCover() : null; 24586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 24686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 24786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public long getSupportedActions() { 24886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return PlaybackControlGlue.ACTION_PLAY_PAUSE | PlaybackControlGlue.ACTION_FAST_FORWARD | PlaybackControlGlue.ACTION_REWIND; 24986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 25086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 25186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public int getCurrentSpeedId() { 25286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn // 0 = Pause, 1 = Normal Playback Speed 25386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return mPlayer.isPlaying() ? 1 : 0; 25486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 25586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 25686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public int getCurrentPosition() { 25786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return mInitialized ? mPlayer.getCurrentPosition() : 0; 25886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 25986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 26086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override protected void startPlayback(int speed) throws IllegalStateException { 2611dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri mPlayer.start(); 26286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 26386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 26486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override protected void pausePlayback() { 26586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn if (mPlayer.isPlaying()) { 26686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mPlayer.pause(); 26786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 26886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 26986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 27086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override protected void skipToNext() { 27186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn // Not supported. 27286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 27386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 27486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override protected void skipToPrevious() { 27586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn // Not supported. 27686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 27786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 27886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn /** 27986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * Called whenever the user presses fast-forward/rewind or when the user keeps the corresponding 28086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * action pressed. 28186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * 28286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * @param newPosition The new position of the media track in milliseconds. 28386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 28486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn protected void seekTo(int newPosition) { 28586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mPlayer.seekTo(newPosition); 28686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 28786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 28886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn /** 2895fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri * Sets the media source of the player witha given URI. 2905fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri * @see MediaPlayer#setDataSource(String) 2915fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri * @return Returns <code>true</code> if uri represents a new media; <code>false</code> 2925fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri * otherwise. 29386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 2945fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri public boolean setMediaSource(Uri uri) { 2951dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri if (mMediaSourceUri != null && mMediaSourceUri.equals(uri)) { 2965fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri return false; 2971dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri } 29886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mMediaSourceUri = uri; 2995fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri return true; 3005fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri } 3015fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri 3025fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri /** 3035fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri * Sets the media source of the player with a String path URL. 3045fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri * @see MediaPlayer#setDataSource(String) 3055fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri * @return Returns <code>true</code> if path represents a new media; <code>false</code> 3065fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri * otherwise. 3075fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri */ 3085fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri public boolean setMediaSource(String path) { 3095fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri if (mMediaSourcePath != null && mMediaSourcePath.equals(mMediaSourcePath)) { 3105fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri return false; 3115fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri } 3125fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri mMediaSourcePath = path; 3135fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri return true; 3145fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri } 3155fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri 3165fc2bf47986ea74abe87e94186dd84d72205410bKeyvan Amiri public void prepareMediaForPlaying() { 3171dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri reset(); 3181dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri try { 3191dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri if (mMediaSourceUri != null) mPlayer.setDataSource(getContext(), mMediaSourceUri); 3201dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri else mPlayer.setDataSource(mMediaSourcePath); 3211dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri } catch (IOException e) { 3221dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri throw new RuntimeException(e); 3231dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri } 3241dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 3251dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 3261dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri @Override public void onPrepared(MediaPlayer mp) { 3271dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri mInitialized = true; 3281dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri mPlayer.start(); 3291dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri onMetadataChanged(); 3301dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri onStateChanged(); 3311dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri updateProgress(); 3321dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri } 3331dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri }); 3341dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 3351dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri @Override public void onCompletion(MediaPlayer mp) { 3361dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri if (mInitialized && mMediaFileFinishedPlayingListener != null) 3371dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri mMediaFileFinishedPlayingListener.onMediaFileFinishedPlaying(mMetaData); 3381dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri } 3391dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri }); 3401dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri mPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() { 3411dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri @Override public void onBufferingUpdate(MediaPlayer mp, int percent) { 3421dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri mControlsRow.setBufferedProgress((int) (mp.getDuration() * (percent / 100f))); 3431dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri } 3441dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri }); 3451dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri mPlayer.prepareAsync(); 3461dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri onStateChanged(); 34786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 34886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 34986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn /** 35086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * Call to <code>startPlayback(1)</code>. 35186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * 35286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * @throws IllegalStateException See {@link MediaPlayer} for further information about it's 35386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * different states when setting a data source and preparing it to be played. 35486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 35586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public void startPlayback() throws IllegalStateException { 35686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn startPlayback(1); 35786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 35886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 35986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn /** 36086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * @return Returns <code>true</code> iff 'Shuffle' is <code>ON</code>. 36186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 36286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public boolean useShuffle() { 36386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return mShuffleAction.getIndex() == PlaybackControlsRow.ShuffleAction.ON; 36486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 36586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 36686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn /** 36786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * @return Returns <code>true</code> iff 'Repeat-One' is <code>ON</code>. 36886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 36986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public boolean repeatOne() { 37086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.ONE; 37186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 37286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 37386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn /** 37486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * @return Returns <code>true</code> iff 'Repeat-All' is <code>ON</code>. 37586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 37686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public boolean repeatAll() { 37786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.ALL; 37886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 37986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 38086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public void setMetaData(MetaData metaData) { 38186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mMetaData = metaData; 38286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn onMetadataChanged(); 38386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 38486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 38586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn /** 38686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * This is a listener implementation for the {@link OnItemViewSelectedListener} of the {@link 38786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * PlaybackOverlayFragment}. This implementation is required in order to detect KEY_DOWN events 38886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * on the {@link android.support.v17.leanback.widget.PlaybackControlsRow.FastForwardAction} and 38986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * {@link android.support.v17.leanback.widget.PlaybackControlsRow.RewindAction}. Thus you should 39086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * <u>NOT</u> set another {@link OnItemViewSelectedListener} on your {@link 39186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * PlaybackOverlayFragment}. Instead, override this method and call its super (this) 39286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * implementation. 39386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * 39486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * @see OnItemViewSelectedListener#onItemSelected(Presenter.ViewHolder, Object, 39586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * RowPresenter.ViewHolder, Row) 39686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 39786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn @Override public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, 39886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn RowPresenter.ViewHolder rowViewHolder, Row row) { 39986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn if (item instanceof Action) { 40086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mSelectedAction = (Action) item; 40186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } else { 40286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn mSelectedAction = null; 40386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 40486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 40586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 40686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn /** 40786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * A listener which will be called whenever a track is finished playing. 40886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 40986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public interface OnMediaFileFinishedPlayingListener { 41086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 41186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn /** 41286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * Called when a track is finished playing. 41386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * 41486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * @param metaData The track's {@link MetaData} which just finished playing. 41586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 41686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn void onMediaFileFinishedPlaying(MetaData metaData); 41786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 41886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 41986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 42086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn /** 42186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * Holds the meta data such as track title, artist and cover art. It'll be used by the {@link 42286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn * MediaPlayerGlue}. 42386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn */ 42486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public static class MetaData { 42586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 42686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private String mTitle; 42786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private String mArtist; 42886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn private Drawable mCover; 42986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 43086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public String getTitle() { 43186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return mTitle; 43286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 43386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 43486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public void setTitle(String title) { 43586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn this.mTitle = title; 43686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 43786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 43886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public String getArtist() { 43986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return mArtist; 44086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 44186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 44286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public void setArtist(String artist) { 44386163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn this.mArtist = artist; 44486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 44586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 44686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public Drawable getCover() { 44786163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn return mCover; 44886163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 44986163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 45086163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn public void setCover(Drawable cover) { 45186163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn this.mCover = cover; 45286163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 4531dd934eb3d2aa4e685585fa0f26c738feee0db4cKeyvan Amiri 45486163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn } 45586163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn 45686163d539e1aeb9ae7612def7aaf7dbfc5b88f28Robert Hahn} 457