• 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.menu;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.media.tv.TvInputInfo;
22 import android.view.View;
23 
24 import com.android.tv.ApplicationSingletons;
25 import com.android.tv.R;
26 import com.android.tv.TvApplication;
27 import com.android.tv.analytics.Tracker;
28 import com.android.tv.common.feature.CommonFeatures;
29 import com.android.tv.data.Channel;
30 import com.android.tv.dvr.DvrDataManager;
31 import com.android.tv.recommendation.Recommender;
32 import com.android.tv.util.SetupUtils;
33 import com.android.tv.util.TvInputManagerHelper;
34 import com.android.tv.util.Utils;
35 
36 import java.util.ArrayList;
37 import java.util.List;
38 
39 /**
40  * An adapter of the Channels row.
41  */
42 public 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 
ChannelsRowAdapter(Context context, Recommender recommender, int minCount, int maxCount)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
getItemViewType(int position)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
getLayoutResId(int viewType)127     protected int getLayoutResId(int viewType) {
128         return viewType;
129     }
130 
131     @Override
onBindViewHolder(MyViewHolder viewHolder, int position)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
update()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 
getRecentChannels()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