• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // CHECKSTYLE:OFF Generated code
2 /* This file is auto-generated from PlaybackControlHelper.java.  DO NOT MODIFY. */
3 
4 /*
5  * Copyright (C) 2015 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License
18  */
19 
20 package com.example.android.leanback;
21 
22 import android.content.Context;
23 import android.graphics.drawable.Drawable;
24 import android.os.Handler;
25 import android.support.v17.leanback.app.PlaybackControlSupportGlue;
26 import android.support.v17.leanback.widget.Action;
27 import android.support.v17.leanback.widget.ArrayObjectAdapter;
28 import android.support.v17.leanback.widget.ControlButtonPresenterSelector;
29 import android.support.v17.leanback.widget.PlaybackControlsRow;
30 import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
31 import android.support.v17.leanback.widget.PresenterSelector;
32 import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
33 import android.view.KeyEvent;
34 import android.view.View;
35 import android.widget.Toast;
36 
37 abstract class PlaybackControlSupportHelper extends PlaybackControlSupportGlue {
38     /**
39      * Change the location of the thumbs up/down controls
40      */
41     private static final boolean THUMBS_PRIMARY = true;
42 
43     private static final String FAUX_TITLE = "A short song of silence";
44     private static final String FAUX_SUBTITLE = "2014";
45     private static final int FAUX_DURATION = 33 * 1000;
46 
47     // These should match the playback service FF behavior
48     private static int[] sFastForwardSpeeds = { 2, 3, 4, 5 };
49 
50     private boolean mIsPlaying;
51     private int mSpeed = PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED;
52     private long mStartTime;
53     private long mStartPosition = 0;
54 
55     private PlaybackControlsRow.RepeatAction mRepeatAction;
56     private PlaybackControlsRow.ThumbsUpAction mThumbsUpAction;
57     private PlaybackControlsRow.ThumbsDownAction mThumbsDownAction;
58     private PlaybackControlsRow.PictureInPictureAction mPipAction;
59 
60     private Handler mHandler = new Handler();
61     // simulating whether the media is yet prepared and ready to play
62     private boolean mInitialized = true;
63 
64     private final Runnable mUpdateProgressRunnable = new Runnable() {
65         @Override
66         public void run() {
67             updateProgress();
68             mHandler.postDelayed(this, getUpdatePeriod());
69         }
70     };
71 
PlaybackControlSupportHelper(Context context, PlaybackOverlaySupportFragment fragment)72     PlaybackControlSupportHelper(Context context, PlaybackOverlaySupportFragment fragment) {
73         super(context, fragment, sFastForwardSpeeds);
74         mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(context);
75         mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsUpAction.INDEX_OUTLINE);
76         mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(context);
77         mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsDownAction.INDEX_OUTLINE);
78         mRepeatAction = new PlaybackControlsRow.RepeatAction(context);
79         mPipAction = new PlaybackControlsRow.PictureInPictureAction(context);
80     }
81 
82     @Override
createControlsRowAndPresenter()83     public PlaybackControlsRowPresenter createControlsRowAndPresenter() {
84         PlaybackControlsRowPresenter presenter = super.createControlsRowAndPresenter();
85 
86         ArrayObjectAdapter adapter = new ArrayObjectAdapter(new ControlButtonPresenterSelector());
87         getControlsRow().setSecondaryActionsAdapter(adapter);
88         if (!THUMBS_PRIMARY) {
89             adapter.add(mThumbsDownAction);
90         }
91         if (android.os.Build.VERSION.SDK_INT > 23) {
92             adapter.add(mPipAction);
93         }
94         adapter.add(mRepeatAction);
95         if (!THUMBS_PRIMARY) {
96             adapter.add(mThumbsUpAction);
97         }
98 
99         return presenter;
100     }
101 
102     @Override
createPrimaryActionsAdapter( PresenterSelector presenterSelector)103     protected SparseArrayObjectAdapter createPrimaryActionsAdapter(
104             PresenterSelector presenterSelector) {
105         SparseArrayObjectAdapter adapter = new SparseArrayObjectAdapter(presenterSelector);
106         if (THUMBS_PRIMARY) {
107             adapter.set(PlaybackControlSupportGlue.ACTION_CUSTOM_LEFT_FIRST, mThumbsUpAction);
108             adapter.set(PlaybackControlSupportGlue.ACTION_CUSTOM_RIGHT_FIRST, mThumbsDownAction);
109         }
110         return adapter;
111     }
112 
113     @Override
onActionClicked(Action action)114     public void onActionClicked(Action action) {
115         if (shouldDispatchAction(action)) {
116             dispatchAction(action);
117             return;
118         }
119         super.onActionClicked(action);
120     }
121 
122     @Override
onKey(View view, int keyCode, KeyEvent keyEvent)123     public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
124         if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
125             Action action = getControlsRow().getActionForKeyCode(keyEvent.getKeyCode());
126             if (shouldDispatchAction(action)) {
127                 dispatchAction(action);
128                 return true;
129             }
130         }
131         return super.onKey(view, keyCode, keyEvent);
132     }
133 
shouldDispatchAction(Action action)134     private boolean shouldDispatchAction(Action action) {
135         return action == mRepeatAction || action == mThumbsUpAction || action == mThumbsDownAction;
136     }
137 
dispatchAction(Action action)138     private void dispatchAction(Action action) {
139         Toast.makeText(getContext(), action.toString(), Toast.LENGTH_SHORT).show();
140         PlaybackControlsRow.MultiAction multiAction = (PlaybackControlsRow.MultiAction) action;
141         multiAction.nextIndex();
142         notifyActionChanged(multiAction);
143     }
144 
notifyActionChanged(PlaybackControlsRow.MultiAction action)145     private void notifyActionChanged(PlaybackControlsRow.MultiAction action) {
146         int index;
147         index = getPrimaryActionsAdapter().indexOf(action);
148         if (index >= 0) {
149             getPrimaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
150         } else {
151             index = getSecondaryActionsAdapter().indexOf(action);
152             if (index >= 0) {
153                 getSecondaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
154             }
155         }
156     }
157 
getPrimaryActionsAdapter()158     private SparseArrayObjectAdapter getPrimaryActionsAdapter() {
159         return (SparseArrayObjectAdapter) getControlsRow().getPrimaryActionsAdapter();
160     }
161 
getSecondaryActionsAdapter()162     private ArrayObjectAdapter getSecondaryActionsAdapter() {
163         return (ArrayObjectAdapter) getControlsRow().getSecondaryActionsAdapter();
164     }
165 
166     @Override
hasValidMedia()167     public boolean hasValidMedia() {
168         return mInitialized;
169     }
170 
171     @Override
isMediaPlaying()172     public boolean isMediaPlaying() {
173         return mIsPlaying;
174     }
175 
176     @Override
getMediaTitle()177     public CharSequence getMediaTitle() {
178         return FAUX_TITLE;
179     }
180 
181     @Override
getMediaSubtitle()182     public CharSequence getMediaSubtitle() {
183         return FAUX_SUBTITLE;
184     }
185 
186     @Override
getMediaDuration()187     public int getMediaDuration() {
188         return mInitialized ? FAUX_DURATION : 0;
189     }
190 
191     @Override
getMediaArt()192     public Drawable getMediaArt() {
193         return null;
194     }
195 
196     @Override
getSupportedActions()197     public long getSupportedActions() {
198         return PlaybackControlSupportGlue.ACTION_PLAY_PAUSE |
199                 PlaybackControlSupportGlue.ACTION_FAST_FORWARD |
200                 PlaybackControlSupportGlue.ACTION_REWIND;
201     }
202 
203     @Override
getCurrentSpeedId()204     public int getCurrentSpeedId() {
205         return mSpeed;
206     }
207 
208     @Override
getCurrentPosition()209     public int getCurrentPosition() {
210         int speed;
211         if (mSpeed == PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED) {
212             speed = 0;
213         } else if (mSpeed == PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL) {
214             speed = 1;
215         } else if (mSpeed >= PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0) {
216             int index = mSpeed - PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0;
217             speed = getFastForwardSpeeds()[index];
218         } else if (mSpeed <= -PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0) {
219             int index = -mSpeed - PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0;
220             speed = -getRewindSpeeds()[index];
221         } else {
222             return -1;
223         }
224         long position = mStartPosition +
225                 (System.currentTimeMillis() - mStartTime) * speed;
226         if (position > getMediaDuration()) {
227             position = getMediaDuration();
228             onPlaybackComplete(true);
229         } else if (position < 0) {
230             position = 0;
231             onPlaybackComplete(false);
232         }
233         return (int) position;
234     }
235 
onPlaybackComplete(final boolean ended)236     void onPlaybackComplete(final boolean ended) {
237         mHandler.post(new Runnable() {
238             @Override
239             public void run() {
240                 if (mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.INDEX_NONE) {
241                     pausePlayback();
242                 } else {
243                     startPlayback(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL);
244                 }
245                 mStartPosition = 0;
246                 onStateChanged();
247             }
248         });
249     }
250 
251     @Override
startPlayback(int speed)252     protected void startPlayback(int speed) {
253         if (speed == mSpeed) {
254             return;
255         }
256         mStartPosition = getCurrentPosition();
257         mSpeed = speed;
258         mIsPlaying = true;
259         mStartTime = System.currentTimeMillis();
260     }
261 
262     @Override
pausePlayback()263     protected void pausePlayback() {
264         if (mSpeed == PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED) {
265             return;
266         }
267         mStartPosition = getCurrentPosition();
268         mSpeed = PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED;
269         mIsPlaying = false;
270     }
271 
272     @Override
skipToNext()273     protected void skipToNext() {
274         // Not supported
275     }
276 
277     @Override
skipToPrevious()278     protected void skipToPrevious() {
279         // Not supported
280     }
281 
282     @Override
enableProgressUpdating(boolean enable)283     public void enableProgressUpdating(boolean enable) {
284         mHandler.removeCallbacks(mUpdateProgressRunnable);
285         if (enable) {
286             mUpdateProgressRunnable.run();
287         }
288     }
289 
isInitialized()290     public boolean isInitialized() {
291         return mInitialized;
292     }
293 
setInitialized(boolean initialized)294     public void setInitialized(boolean initialized) {
295         if (mInitialized != initialized) {
296             mInitialized = initialized;
297             onMetadataChanged();
298             onStateChanged();
299         }
300     }
301 };
302