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