• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tv.ui.sidepanel.parentalcontrols;
18 
19 import android.database.ContentObserver;
20 import android.media.tv.TvContract;
21 import android.net.Uri;
22 import android.os.Build.VERSION;
23 import android.os.Build.VERSION_CODES;
24 import android.os.Bundle;
25 import android.os.Handler;
26 import android.support.v17.leanback.widget.VerticalGridView;
27 import android.view.KeyEvent;
28 import android.view.LayoutInflater;
29 import android.view.View;
30 import android.view.ViewGroup;
31 import android.widget.TextView;
32 import com.android.tv.R;
33 import com.android.tv.data.ChannelNumber;
34 import com.android.tv.data.api.Channel;
35 import com.android.tv.recommendation.ChannelPreviewUpdater;
36 import com.android.tv.ui.OnRepeatedKeyInterceptListener;
37 import com.android.tv.ui.sidepanel.ActionItem;
38 import com.android.tv.ui.sidepanel.ChannelCheckItem;
39 import com.android.tv.ui.sidepanel.DividerItem;
40 import com.android.tv.ui.sidepanel.Item;
41 import com.android.tv.ui.sidepanel.SideFragment;
42 import java.util.ArrayList;
43 import java.util.Collections;
44 import java.util.Comparator;
45 import java.util.List;
46 
47 public class ChannelsBlockedFragment extends SideFragment {
48     private static final String TRACKER_LABEL = "Channels blocked";
49     private int mBlockedChannelCount;
50     private final List<Channel> mChannels = new ArrayList<>();
51     private long mLastFocusedChannelId = Channel.INVALID_ID;
52     private int mSelectedPosition = INVALID_POSITION;
53     private boolean mUpdated;
54     private final ContentObserver mProgramUpdateObserver =
55             new ContentObserver(new Handler()) {
56                 @Override
57                 public void onChange(boolean selfChange, Uri uri) {
58                     notifyItemsChanged();
59                 }
60             };
61     private final Item mLockAllItem = new BlockAllItem();
62     private final List<Item> mItems = new ArrayList<>();
63 
64     @Override
onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)65     public View onCreateView(
66             LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
67         View view = super.onCreateView(inflater, container, savedInstanceState);
68         if (mSelectedPosition != INVALID_POSITION) {
69             setSelectedPosition(mSelectedPosition);
70         }
71         VerticalGridView listView = (VerticalGridView) view.findViewById(R.id.side_panel_list);
72         listView.setOnKeyInterceptListener(
73                 new OnRepeatedKeyInterceptListener(listView) {
74                     @Override
75                     public boolean onInterceptKeyEvent(KeyEvent event) {
76                         // In order to send tune operation once for continuous channel up/down
77                         // events,
78                         // we only call the moveToChannel method on ACTION_UP event of channel
79                         // switch keys.
80                         if (event.getAction() == KeyEvent.ACTION_UP) {
81                             switch (event.getKeyCode()) {
82                                 case KeyEvent.KEYCODE_DPAD_UP:
83                                 case KeyEvent.KEYCODE_DPAD_DOWN:
84                                     if (mLastFocusedChannelId != Channel.INVALID_ID) {
85                                         getMainActivity()
86                                                 .tuneToChannel(
87                                                         getChannelDataManager()
88                                                                 .getChannel(mLastFocusedChannelId));
89                                     }
90                                     break;
91                             }
92                         }
93                         return super.onInterceptKeyEvent(event);
94                     }
95                 });
96         getActivity()
97                 .getContentResolver()
98                 .registerContentObserver(
99                         TvContract.Programs.CONTENT_URI, true, mProgramUpdateObserver);
100         getMainActivity().startShrunkenTvView(true, true);
101         mUpdated = false;
102         return view;
103     }
104 
105     @Override
onDestroyView()106     public void onDestroyView() {
107         getActivity().getContentResolver().unregisterContentObserver(mProgramUpdateObserver);
108         getChannelDataManager().applyUpdatedValuesToDb();
109         getMainActivity().endShrunkenTvView();
110         if (VERSION.SDK_INT >= VERSION_CODES.O && mUpdated) {
111             ChannelPreviewUpdater.getInstance(getMainActivity())
112                     .updatePreviewDataForChannelsImmediately();
113         }
114         super.onDestroyView();
115     }
116 
117     @Override
getTitle()118     protected String getTitle() {
119         return getString(R.string.option_channels_locked);
120     }
121 
122     @Override
getTrackerLabel()123     public String getTrackerLabel() {
124         return TRACKER_LABEL;
125     }
126 
127     @Override
getItemList()128     protected List<Item> getItemList() {
129         mItems.clear();
130         mItems.add(mLockAllItem);
131         mChannels.clear();
132         mChannels.addAll(getChannelDataManager().getChannelList());
133         Collections.sort(
134                 mChannels,
135                 new Comparator<Channel>() {
136                     @Override
137                     public int compare(Channel lhs, Channel rhs) {
138                         if (lhs.isBrowsable() != rhs.isBrowsable()) {
139                             return lhs.isBrowsable() ? -1 : 1;
140                         }
141                         return ChannelNumber.compare(
142                                 lhs.getDisplayNumber(), rhs.getDisplayNumber());
143                     }
144                 });
145 
146         final long currentChannelId = getMainActivity().getCurrentChannelId();
147         boolean hasHiddenChannels = false;
148         for (Channel channel : mChannels) {
149             if (!channel.isBrowsable() && !hasHiddenChannels) {
150                 mItems.add(new DividerItem(getString(R.string.option_channels_subheader_hidden)));
151                 hasHiddenChannels = true;
152             }
153             mItems.add(new ChannelBlockedItem(channel));
154             if (channel.isLocked()) {
155                 ++mBlockedChannelCount;
156             }
157             if (channel.getId() == currentChannelId) {
158                 mSelectedPosition = mItems.size() - 1;
159             }
160         }
161         return mItems;
162     }
163 
164     private class BlockAllItem extends ActionItem {
165         private TextView mTextView;
166 
BlockAllItem()167         public BlockAllItem() {
168             super(null);
169         }
170 
171         @Override
onBind(View view)172         protected void onBind(View view) {
173             super.onBind(view);
174             mTextView = (TextView) view.findViewById(R.id.title);
175         }
176 
177         @Override
onUpdate()178         protected void onUpdate() {
179             super.onUpdate();
180             updateText();
181         }
182 
183         @Override
onUnbind()184         protected void onUnbind() {
185             super.onUnbind();
186             mTextView = null;
187         }
188 
189         @Override
onSelected()190         protected void onSelected() {
191             boolean lock = !areAllChannelsBlocked();
192             for (Channel channel : mChannels) {
193                 getChannelDataManager().updateLocked(channel.getId(), lock);
194             }
195             mBlockedChannelCount = lock ? mChannels.size() : 0;
196             notifyItemsChanged();
197             mUpdated = true;
198         }
199 
200         @Override
onFocused()201         protected void onFocused() {
202             super.onFocused();
203             mLastFocusedChannelId = Channel.INVALID_ID;
204         }
205 
updateText()206         private void updateText() {
207             mTextView.setText(
208                     getString(
209                             areAllChannelsBlocked()
210                                     ? R.string.option_channels_unlock_all
211                                     : R.string.option_channels_lock_all));
212         }
213 
areAllChannelsBlocked()214         private boolean areAllChannelsBlocked() {
215             return mBlockedChannelCount == mChannels.size();
216         }
217     }
218 
219     private class ChannelBlockedItem extends ChannelCheckItem {
ChannelBlockedItem(Channel channel)220         private ChannelBlockedItem(Channel channel) {
221             super(channel, getChannelDataManager(), getProgramDataManager());
222         }
223 
224         @Override
getResourceId()225         protected int getResourceId() {
226             return R.layout.option_item_channel_lock;
227         }
228 
229         @Override
onUpdate()230         protected void onUpdate() {
231             super.onUpdate();
232             setChecked(getChannel().isLocked());
233         }
234 
235         @Override
onSelected()236         protected void onSelected() {
237             super.onSelected();
238             getChannelDataManager().updateLocked(getChannel().getId(), isChecked());
239             mBlockedChannelCount += isChecked() ? 1 : -1;
240             notifyItemChanged(mLockAllItem);
241             mUpdated = true;
242         }
243 
244         @Override
onFocused()245         protected void onFocused() {
246             super.onFocused();
247             mLastFocusedChannelId = getChannel().getId();
248         }
249     }
250 }
251