ChannelsRowAdapter.java revision 919e1ed7e914029a1a0054237d86dc7b19ced898
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.menu;
18
19import android.content.Context;
20import android.content.Intent;
21import android.media.tv.TvInputInfo;
22import android.view.View;
23
24import com.android.tv.ApplicationSingletons;
25import com.android.tv.R;
26import com.android.tv.TvApplication;
27import com.android.tv.analytics.Tracker;
28import com.android.tv.common.feature.CommonFeatures;
29import com.android.tv.data.Channel;
30import com.android.tv.dvr.DvrDataManager;
31import com.android.tv.recommendation.Recommender;
32import com.android.tv.util.SetupUtils;
33import com.android.tv.util.TvInputManagerHelper;
34import com.android.tv.util.Utils;
35
36import java.util.ArrayList;
37import java.util.List;
38
39/**
40 * An adapter of the Channels row.
41 */
42public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel> {
43    private static final String TAG = "ChannelsRowAdapter";
44
45    // There are four special cards: guide, setup, dvr, applink.
46    private static final int SIZE_OF_VIEW_TYPE = 5;
47
48    private final Context mContext;
49    private final Tracker mTracker;
50    private final Recommender mRecommender;
51    private final DvrDataManager mDvrDataManager;
52    private final int mMaxCount;
53    private final int mMinCount;
54    private final int[] mViewType = new int[SIZE_OF_VIEW_TYPE];
55
56    private final View.OnClickListener mGuideOnClickListener = new View.OnClickListener() {
57        @Override
58        public void onClick(View view) {
59            mTracker.sendMenuClicked(R.string.channels_item_program_guide);
60            getMainActivity().getOverlayManager().showProgramGuide();
61        }
62    };
63
64    private final View.OnClickListener mSetupOnClickListener = new View.OnClickListener() {
65        @Override
66        public void onClick(View view) {
67            mTracker.sendMenuClicked(R.string.channels_item_setup);
68            getMainActivity().getOverlayManager().showSetupFragment();
69        }
70    };
71
72    private final View.OnClickListener mDvrOnClickListener = new View.OnClickListener() {
73        @Override
74        public void onClick(View view) {
75            mTracker.sendMenuClicked(R.string.channels_item_dvr);
76            getMainActivity().getOverlayManager().showDvrManager();
77        }
78    };
79
80    private final View.OnClickListener mAppLinkOnClickListener = new View.OnClickListener() {
81        @Override
82        public void onClick(View view) {
83            mTracker.sendMenuClicked(R.string.channels_item_app_link);
84            Intent intent = ((AppLinkCardView) view).getIntent();
85            if (intent != null) {
86                getMainActivity().startActivitySafe(intent);
87            }
88        }
89    };
90
91    private final View.OnClickListener mChannelOnClickListener = new View.OnClickListener() {
92        @Override
93        public void onClick(View view) {
94            // Always send the label "Channels" because the channel ID or name or number might be
95            // sensitive.
96            mTracker.sendMenuClicked(R.string.menu_title_channels);
97            getMainActivity().tuneToChannel((Channel) view.getTag());
98            getMainActivity().hideOverlaysForTune();
99        }
100    };
101
102    public ChannelsRowAdapter(Context context, Recommender recommender,
103            int minCount, int maxCount) {
104        super(context);
105        mContext = context;
106        ApplicationSingletons appSingletons = TvApplication.getSingletons(context);
107        mTracker = appSingletons.getTracker();
108        if (CommonFeatures.DVR.isEnabled(context)) {
109            mDvrDataManager = appSingletons.getDvrDataManager();
110        } else {
111            mDvrDataManager = null;
112        }
113        mRecommender = recommender;
114        mMinCount = minCount;
115        mMaxCount = maxCount;
116    }
117
118    @Override
119    public int getItemViewType(int position) {
120        if (position >= SIZE_OF_VIEW_TYPE) {
121            return R.layout.menu_card_channel;
122        }
123        return mViewType[position];
124    }
125
126    @Override
127    protected int getLayoutResId(int viewType) {
128        return viewType;
129    }
130
131    @Override
132    public void onBindViewHolder(MyViewHolder viewHolder, int position) {
133        super.onBindViewHolder(viewHolder, position);
134
135        int viewType = getItemViewType(position);
136        if (viewType == R.layout.menu_card_guide) {
137            viewHolder.itemView.setOnClickListener(mGuideOnClickListener);
138        } else if (viewType == R.layout.menu_card_setup) {
139            viewHolder.itemView.setOnClickListener(mSetupOnClickListener);
140        } else if (viewType == R.layout.menu_card_app_link) {
141            viewHolder.itemView.setOnClickListener(mAppLinkOnClickListener);
142        } else if (viewType == R.layout.menu_card_dvr) {
143            viewHolder.itemView.setOnClickListener(mDvrOnClickListener);
144            SimpleCardView view = (SimpleCardView) viewHolder.itemView;
145            view.setText(R.string.channels_item_dvr);
146        } else {
147            viewHolder.itemView.setTag(getItemList().get(position));
148            viewHolder.itemView.setOnClickListener(mChannelOnClickListener);
149        }
150    }
151
152    @Override
153    public void update() {
154        List<Channel> channelList = new ArrayList<>();
155        Channel dummyChannel = new Channel.Builder().build();
156        // For guide item
157        channelList.add(dummyChannel);
158        // For setup item
159        TvInputManagerHelper inputManager = TvApplication.getSingletons(mContext)
160                .getTvInputManagerHelper();
161        boolean showSetupCard = SetupUtils.getInstance(mContext).hasNewInput(inputManager);
162        Channel currentChannel = getMainActivity().getCurrentChannel();
163        boolean showAppLinkCard = currentChannel != null
164                && currentChannel.getAppLinkType(mContext) != Channel.APP_LINK_TYPE_NONE
165                // Sometimes applicationInfo can be null. b/28932537
166                && inputManager.getTvInputAppInfo(currentChannel.getInputId()) != null;
167        boolean showDvrCard = false;
168        if (mDvrDataManager != null) {
169            for (TvInputInfo info : inputManager.getTvInputInfos(true, true)) {
170                if (info.canRecord()) {
171                    showDvrCard = true;
172                    break;
173                }
174            }
175        }
176
177        mViewType[0] = R.layout.menu_card_guide;
178        int index = 1;
179        if (showSetupCard) {
180            channelList.add(dummyChannel);
181            mViewType[index++] = R.layout.menu_card_setup;
182        }
183        if (showDvrCard) {
184            channelList.add(dummyChannel);
185            mViewType[index++] = R.layout.menu_card_dvr;
186        }
187        if (showAppLinkCard) {
188            channelList.add(currentChannel);
189            mViewType[index++] = R.layout.menu_card_app_link;
190        }
191        for ( ; index < mViewType.length; ++index) {
192            mViewType[index] = R.layout.menu_card_channel;
193        }
194        channelList.addAll(getRecentChannels());
195        setItemList(channelList);
196    }
197
198    private List<Channel> getRecentChannels() {
199        List<Channel> channelList = new ArrayList<>();
200        for (Channel channel : mRecommender.recommendChannels(mMaxCount)) {
201            if (channel.isBrowsable()) {
202                channelList.add(channel);
203            }
204        }
205        int count = channelList.size();
206        // If the number of recommended channels is not enough, add more from the recent channel
207        // list.
208        if (count < mMinCount) {
209            for (long channelId : getMainActivity().getRecentChannels()) {
210                Channel channel = mRecommender.getChannel(channelId);
211                if (channel == null || channelList.contains(channel)
212                        || !channel.isBrowsable()) {
213                   continue;
214                }
215                channelList.add(channel);
216                if (++count >= mMinCount) {
217                    break;
218                }
219            }
220        }
221        return channelList;
222    }
223}
224