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