• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 
15 package com.example.android.tv.channelsprograms.playback;
16 
17 import android.content.Context;
18 import android.os.Handler;
19 import android.support.v17.leanback.media.PlaybackTransportControlGlue;
20 import android.support.v17.leanback.media.PlayerAdapter;
21 import android.support.v17.leanback.widget.Action;
22 import android.support.v17.leanback.widget.ArrayObjectAdapter;
23 import android.support.v17.leanback.widget.PlaybackControlsRow;
24 import android.view.KeyEvent;
25 import android.view.View;
26 import android.widget.Toast;
27 
28 /**
29  * Handles common primary and secondary actions such as repeat, thumbs up/down, picture in picture,
30  * and closed captions.
31  */
32 class SimplePlaybackTransportControlGlue<T extends PlayerAdapter>
33         extends PlaybackTransportControlGlue<T> {
34 
35     private PlaybackControlsRow.RepeatAction mRepeatAction;
36     private PlaybackControlsRow.ThumbsUpAction mThumbsUpAction;
37     private PlaybackControlsRow.ThumbsDownAction mThumbsDownAction;
38     private PlaybackControlsRow.PictureInPictureAction mPipAction;
39     private PlaybackControlsRow.ClosedCaptioningAction mClosedCaptioningAction;
40     private Handler mHandler = new Handler();
41 
SimplePlaybackTransportControlGlue(Context context, T impl)42     public SimplePlaybackTransportControlGlue(Context context, T impl) {
43         super(context, impl);
44         mClosedCaptioningAction = new PlaybackControlsRow.ClosedCaptioningAction(context);
45         mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(context);
46         mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsUpAction.OUTLINE);
47         mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(context);
48         mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsDownAction.OUTLINE);
49         mRepeatAction = new PlaybackControlsRow.RepeatAction(context);
50         mPipAction = new PlaybackControlsRow.PictureInPictureAction(context);
51     }
52 
53     @Override
onCreatePrimaryActions(ArrayObjectAdapter adapter)54     protected void onCreatePrimaryActions(ArrayObjectAdapter adapter) {
55         super.onCreatePrimaryActions(adapter);
56         adapter.add(mRepeatAction);
57         adapter.add(mClosedCaptioningAction);
58     }
59 
60     @Override
onCreateSecondaryActions(ArrayObjectAdapter adapter)61     protected void onCreateSecondaryActions(ArrayObjectAdapter adapter) {
62         super.onCreateSecondaryActions(adapter);
63         adapter.add(mThumbsUpAction);
64         adapter.add(mThumbsDownAction);
65         adapter.add(mPipAction);
66     }
67 
68     @Override
onActionClicked(Action action)69     public void onActionClicked(Action action) {
70         if (shouldDispatchAction(action)) {
71             dispatchAction(action, getPrimaryActionsAdapter());
72             dispatchAction(action, getSecondaryActionsAdapter());
73             return;
74         }
75         super.onActionClicked(action);
76     }
77 
78     @Override
onKey(View view, int keyCode, KeyEvent keyEvent)79     public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
80         if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
81             boolean dispatched = dispatchAction(keyEvent, getPrimaryActionsAdapter());
82             dispatched |= dispatchAction(keyEvent, getSecondaryActionsAdapter());
83             if (dispatched) {
84                 return true;
85             }
86         }
87         return super.onKey(view, keyCode, keyEvent);
88     }
89 
dispatchAction(KeyEvent keyEvent, ArrayObjectAdapter adapter)90     private boolean dispatchAction(KeyEvent keyEvent, ArrayObjectAdapter adapter) {
91         Action action = getControlsRow().getActionForKeyCode(adapter, keyEvent.getKeyCode());
92         if (shouldDispatchAction(action)) {
93             dispatchAction(action, adapter);
94             return true;
95         }
96         return false;
97     }
98 
shouldDispatchAction(Action action)99     private boolean shouldDispatchAction(Action action) {
100         return action == mRepeatAction || action == mThumbsUpAction || action == mThumbsDownAction;
101     }
102 
dispatchAction(Action action, ArrayObjectAdapter adapter)103     private void dispatchAction(Action action, ArrayObjectAdapter adapter) {
104         Toast.makeText(getContext(), action.toString(), Toast.LENGTH_SHORT).show();
105         PlaybackControlsRow.MultiAction multiAction = (PlaybackControlsRow.MultiAction) action;
106         multiAction.nextIndex();
107         notifyActionChanged(multiAction, adapter);
108     }
109 
notifyActionChanged( PlaybackControlsRow.MultiAction action, ArrayObjectAdapter adapter)110     private void notifyActionChanged(
111             PlaybackControlsRow.MultiAction action, ArrayObjectAdapter adapter) {
112         if (adapter != null) {
113             int index = adapter.indexOf(action);
114             if (index >= 0) {
115                 adapter.notifyArrayItemRangeChanged(index, 1);
116             }
117         }
118     }
119 
getPrimaryActionsAdapter()120     private ArrayObjectAdapter getPrimaryActionsAdapter() {
121         if (getControlsRow() == null) {
122             return null;
123         }
124         return (ArrayObjectAdapter) getControlsRow().getPrimaryActionsAdapter();
125     }
126 
getSecondaryActionsAdapter()127     private ArrayObjectAdapter getSecondaryActionsAdapter() {
128         if (getControlsRow() == null) {
129             return null;
130         }
131         return (ArrayObjectAdapter) getControlsRow().getSecondaryActionsAdapter();
132     }
133 
134     @Override
onPlayCompleted()135     protected void onPlayCompleted() {
136         super.onPlayCompleted();
137         mHandler.post(
138                 () -> {
139                     if (mRepeatAction.getIndex() != PlaybackControlsRow.RepeatAction.INDEX_NONE) {
140                         play();
141                     }
142                 });
143     }
144 
145     /**
146      * Sets the behavior for the repeat action. The possible modes are
147      *
148      * <ul>
149      *   <li>{@link PlaybackControlsRow.RepeatAction#INDEX_NONE}
150      *   <li>{@link PlaybackControlsRow.RepeatAction#INDEX_ALL}
151      *   <li>{@link PlaybackControlsRow.RepeatAction#INDEX_ONE}
152      * </ul>
153      *
154      * @param mode for repeat behavior.
155      */
setRepeatMode(int mode)156     public void setRepeatMode(int mode) {
157         mRepeatAction.setIndex(mode);
158         notifyActionChanged(mRepeatAction, getPrimaryActionsAdapter());
159     }
160 }
161