ChannelsBlockedFragment.java revision 816a4be1a0f34f6a48877c8afd3dbbca19eac435
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 17package com.android.tv.ui.sidepanel.parentalcontrols; 18 19import android.database.ContentObserver; 20import android.media.tv.TvContract; 21import android.net.Uri; 22import android.os.Bundle; 23import android.os.Handler; 24import android.support.v17.leanback.widget.VerticalGridView; 25import android.view.KeyEvent; 26import android.view.LayoutInflater; 27import android.view.View; 28import android.view.ViewGroup; 29import android.widget.TextView; 30 31import com.android.tv.R; 32import com.android.tv.data.Channel; 33import com.android.tv.data.ChannelNumber; 34import com.android.tv.ui.sidepanel.ActionItem; 35import com.android.tv.ui.sidepanel.ChannelCheckItem; 36import com.android.tv.ui.sidepanel.DividerItem; 37import com.android.tv.ui.sidepanel.Item; 38import com.android.tv.ui.sidepanel.SideFragment; 39 40import java.util.ArrayList; 41import java.util.Collections; 42import java.util.Comparator; 43import java.util.List; 44 45public class ChannelsBlockedFragment extends SideFragment { 46 private static final String TRACKER_LABEL = "Channels blocked"; 47 private int mBlockedChannelCount; 48 private final List<Channel> mChannels = new ArrayList<>(); 49 private long mLastFocusedChannelId = Channel.INVALID_ID; 50 private int mSelectedPosition = INVALID_POSITION; 51 private final ContentObserver mProgramUpdateObserver = new ContentObserver(new Handler()) { 52 @Override 53 public void onChange(boolean selfChange, Uri uri) { 54 notifyItemsChanged(); 55 } 56 }; 57 private final Item mLockAllItem = new BlockAllItem(); 58 private final List<Item> mItems = new ArrayList<>(); 59 60 private final VerticalGridView.OnKeyInterceptListener mOnKeyInterceptListener = 61 new VerticalGridView.OnKeyInterceptListener() { 62 @Override 63 public boolean onInterceptKeyEvent(KeyEvent event) { 64 // In order to send tune operation once for continuous channel up/down events, we only 65 // call the moveToChannel method on ACTION_UP event of channel switch keys. 66 if (event.getAction() == KeyEvent.ACTION_UP) { 67 switch (event.getKeyCode()) { 68 case KeyEvent.KEYCODE_DPAD_UP: 69 case KeyEvent.KEYCODE_DPAD_DOWN: 70 if (mLastFocusedChannelId != Channel.INVALID_ID) { 71 getMainActivity().tuneToChannel( 72 getChannelDataManager().getChannel(mLastFocusedChannelId)); 73 } 74 break; 75 } 76 } 77 return false; 78 } 79 }; 80 81 @Override 82 public View onCreateView(LayoutInflater inflater, ViewGroup container, 83 Bundle savedInstanceState) { 84 View view = super.onCreateView(inflater, container, savedInstanceState); 85 if (mSelectedPosition != INVALID_POSITION) { 86 setSelectedPosition(mSelectedPosition); 87 } 88 VerticalGridView listView = (VerticalGridView) view.findViewById(R.id.side_panel_list); 89 listView.setOnKeyInterceptListener(mOnKeyInterceptListener); 90 getActivity().getContentResolver().registerContentObserver(TvContract.Programs.CONTENT_URI, 91 true, mProgramUpdateObserver); 92 getMainActivity().startShrunkenTvView(true, true); 93 return view; 94 } 95 96 @Override 97 public void onDestroyView() { 98 getActivity().getContentResolver().unregisterContentObserver(mProgramUpdateObserver); 99 getChannelDataManager().applyUpdatedValuesToDb(); 100 getMainActivity().endShrunkenTvView(); 101 super.onDestroyView(); 102 } 103 104 @Override 105 protected String getTitle() { 106 return getString(R.string.option_channels_locked); 107 } 108 109 @Override 110 public String getTrackerLabel() { 111 return TRACKER_LABEL; 112 } 113 114 @Override 115 protected List<Item> getItemList() { 116 mItems.clear(); 117 mItems.add(mLockAllItem); 118 mChannels.clear(); 119 mChannels.addAll(getChannelDataManager().getChannelList()); 120 Collections.sort(mChannels, new Comparator<Channel>() { 121 @Override 122 public int compare(Channel lhs, Channel rhs) { 123 if (lhs.isBrowsable() != rhs.isBrowsable()) { 124 return lhs.isBrowsable() ? -1 : 1; 125 } 126 return ChannelNumber.compare(lhs.getDisplayNumber(), rhs.getDisplayNumber()); 127 } 128 }); 129 130 final long currentChannelId = getMainActivity().getCurrentChannelId(); 131 boolean hasHiddenChannels = false; 132 for (Channel channel : mChannels) { 133 if (!channel.isBrowsable() && !hasHiddenChannels) { 134 mItems.add(new DividerItem( 135 getString(R.string.option_channels_subheader_hidden))); 136 hasHiddenChannels = true; 137 } 138 mItems.add(new ChannelBlockedItem(channel)); 139 if (channel.isLocked()) { 140 ++mBlockedChannelCount; 141 } 142 if (channel.getId() == currentChannelId) { 143 mSelectedPosition = mItems.size() - 1; 144 } 145 } 146 return mItems; 147 } 148 149 private class BlockAllItem extends ActionItem { 150 private TextView mTextView; 151 152 public BlockAllItem() { 153 super(null); 154 } 155 156 @Override 157 protected void onBind(View view) { 158 super.onBind(view); 159 mTextView = (TextView) view.findViewById(R.id.title); 160 } 161 162 @Override 163 protected void onUpdate() { 164 super.onUpdate(); 165 updateText(); 166 } 167 168 @Override 169 protected void onUnbind() { 170 super.onUnbind(); 171 mTextView = null; 172 } 173 174 @Override 175 protected void onSelected() { 176 boolean lock = !areAllChannelsBlocked(); 177 for (Channel channel : mChannels) { 178 getChannelDataManager().updateLocked(channel.getId(), lock); 179 } 180 mBlockedChannelCount = lock ? mChannels.size() : 0; 181 notifyItemsChanged(); 182 } 183 184 @Override 185 protected void onFocused() { 186 super.onFocused(); 187 mLastFocusedChannelId = Channel.INVALID_ID; 188 } 189 190 private void updateText() { 191 mTextView.setText(getString(areAllChannelsBlocked() ? 192 R.string.option_channels_unlock_all : R.string.option_channels_lock_all)); 193 } 194 195 private boolean areAllChannelsBlocked() { 196 return mBlockedChannelCount == mChannels.size(); 197 } 198 } 199 200 private class ChannelBlockedItem extends ChannelCheckItem { 201 private ChannelBlockedItem(Channel channel) { 202 super(channel, getChannelDataManager(), getProgramDataManager()); 203 } 204 205 @Override 206 protected int getResourceId() { 207 return R.layout.option_item_channel_lock; 208 } 209 210 @Override 211 protected void onUpdate() { 212 super.onUpdate(); 213 setChecked(getChannel().isLocked()); 214 } 215 216 @Override 217 protected void onSelected() { 218 super.onSelected(); 219 getChannelDataManager().updateLocked(getChannel().getId(), isChecked()); 220 mBlockedChannelCount += isChecked() ? 1 : -1; 221 notifyItemChanged(mLockAllItem); 222 } 223 224 @Override 225 protected void onFocused() { 226 super.onFocused(); 227 mLastFocusedChannelId = getChannel().getId(); 228 } 229 } 230} 231