Home | History | Annotate | Download | only in menu
      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 
    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