1816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko/*
2816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Copyright (C) 2015 The Android Open Source Project
3816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko *
4816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License");
5816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * you may not use this file except in compliance with the License.
6816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * You may obtain a copy of the License at
7816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko *
8816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko *      http://www.apache.org/licenses/LICENSE-2.0
9816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko *
10816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Unless required by applicable law or agreed to in writing, software
11816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS,
12816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * See the License for the specific language governing permissions and
14816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * limitations under the License.
15816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */
16816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
17816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkopackage com.android.tv.menu;
18816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
19816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.content.Context;
20816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.content.Intent;
212e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport android.media.tv.TvInputInfo;
22816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.view.View;
23816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
2465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.ApplicationSingletons;
25816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.R;
26816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.TvApplication;
27816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.analytics.Tracker;
28ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport com.android.tv.common.feature.CommonFeatures;
29816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.data.Channel;
3065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.dvr.DvrDataManager;
31816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.recommendation.Recommender;
32816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.util.SetupUtils;
332e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalkoimport com.android.tv.util.TvInputManagerHelper;
34816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
356ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport java.util.ArrayDeque;
36816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.ArrayList;
37816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.List;
38816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
39816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko/**
40816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * An adapter of the Channels row.
41816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */
426ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkopublic class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<ChannelsRowItem> {
4365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    // There are four special cards: guide, setup, dvr, applink.
442e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko    private static final int SIZE_OF_VIEW_TYPE = 5;
45ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko
46816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final Context mContext;
47816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final Tracker mTracker;
48816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final Recommender mRecommender;
4965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private final DvrDataManager mDvrDataManager;
50816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final int mMaxCount;
51816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final int mMinCount;
52816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
53816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final View.OnClickListener mGuideOnClickListener = new View.OnClickListener() {
54816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
55816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void onClick(View view) {
56816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mTracker.sendMenuClicked(R.string.channels_item_program_guide);
57816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            getMainActivity().getOverlayManager().showProgramGuide();
58816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
59816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    };
60816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
61816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final View.OnClickListener mSetupOnClickListener = new View.OnClickListener() {
62816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
63816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void onClick(View view) {
64816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mTracker.sendMenuClicked(R.string.channels_item_setup);
65ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko            getMainActivity().getOverlayManager().showSetupFragment();
66ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        }
67ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko    };
68ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko
69ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko    private final View.OnClickListener mDvrOnClickListener = new View.OnClickListener() {
70ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        @Override
71ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        public void onClick(View view) {
72ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko            mTracker.sendMenuClicked(R.string.channels_item_dvr);
73ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko            getMainActivity().getOverlayManager().showDvrManager();
74816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
75816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    };
76816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
77816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final View.OnClickListener mAppLinkOnClickListener = new View.OnClickListener() {
78816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
79816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void onClick(View view) {
80816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mTracker.sendMenuClicked(R.string.channels_item_app_link);
81816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            Intent intent = ((AppLinkCardView) view).getIntent();
82816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (intent != null) {
83816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                getMainActivity().startActivitySafe(intent);
84816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
85816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
86816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    };
87816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
88816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final View.OnClickListener mChannelOnClickListener = new View.OnClickListener() {
89816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
90816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void onClick(View view) {
91816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            // Always send the label "Channels" because the channel ID or name or number might be
92816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            // sensitive.
93816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mTracker.sendMenuClicked(R.string.menu_title_channels);
94816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            getMainActivity().tuneToChannel((Channel) view.getTag());
95816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            getMainActivity().hideOverlaysForTune();
96816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
97816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    };
98816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
99816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public ChannelsRowAdapter(Context context, Recommender recommender,
100816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            int minCount, int maxCount) {
101816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        super(context);
102816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mContext = context;
10365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        ApplicationSingletons appSingletons = TvApplication.getSingletons(context);
10465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        mTracker = appSingletons.getTracker();
10565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (CommonFeatures.DVR.isEnabled(context)) {
10665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mDvrDataManager = appSingletons.getDvrDataManager();
10765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        } else {
10865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            mDvrDataManager = null;
10965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
110816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mRecommender = recommender;
111816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mMinCount = minCount;
112816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mMaxCount = maxCount;
1136ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        setHasStableIds(true);
114816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
115816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
116816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
117816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public int getItemViewType(int position) {
1186ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        return getItemList().get(position).getLayoutId();
119816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
120816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
121816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
122816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    protected int getLayoutResId(int viewType) {
123816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return viewType;
124816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
125816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
126816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
1276ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    public long getItemId(int position) {
1286ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        return getItemList().get(position).getItemId();
1296ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
130721bd0da688cd552737fbb753a00597f95103b95Adrian Roos
1316ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    @Override
1326ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    public void onBindViewHolder(MyViewHolder viewHolder, int position) {
133816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        int viewType = getItemViewType(position);
134816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (viewType == R.layout.menu_card_guide) {
135816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            viewHolder.itemView.setOnClickListener(mGuideOnClickListener);
136816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        } else if (viewType == R.layout.menu_card_setup) {
137816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            viewHolder.itemView.setOnClickListener(mSetupOnClickListener);
138816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        } else if (viewType == R.layout.menu_card_app_link) {
139816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            viewHolder.itemView.setOnClickListener(mAppLinkOnClickListener);
140ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        } else if (viewType == R.layout.menu_card_dvr) {
141ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko            viewHolder.itemView.setOnClickListener(mDvrOnClickListener);
142d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            SimpleCardView view = (SimpleCardView) viewHolder.itemView;
143d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            view.setText(R.string.channels_item_dvr);
144816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        } else {
1456ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            viewHolder.itemView.setTag(getItemList().get(position).getChannel());
146816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            viewHolder.itemView.setOnClickListener(mChannelOnClickListener);
147816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
1486ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        super.onBindViewHolder(viewHolder, position);
149816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
150816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
151816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
152816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public void update() {
1536ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (getItemCount() == 0) {
1546ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            createItems();
1556ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        } else {
1566ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            updateItems();
1576ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
1586ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
1596ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
1606ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private void createItems() {
1616ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        List<ChannelsRowItem> items = new ArrayList<>();
1626ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        items.add(ChannelsRowItem.GUIDE_ITEM);
1636ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (needToShowSetupItem()) {
1646ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            items.add(ChannelsRowItem.SETUP_ITEM);
1656ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
1666ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (needToShowDvrItem()) {
1676ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            items.add(ChannelsRowItem.DVR_ITEM);
1686ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
1696ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (needToShowAppLinkItem()) {
1706ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            ChannelsRowItem.APP_LINK_ITEM.setChannel(
1716ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    new Channel.Builder(getMainActivity().getCurrentChannel()).build());
1726ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            items.add(ChannelsRowItem.APP_LINK_ITEM);
1736ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
1746ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        for (Channel channel : getRecentChannels()) {
1756ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            items.add(new ChannelsRowItem(channel, R.layout.menu_card_channel));
1766ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
1776ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        setItemList(items);
1786ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
1796ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
1806ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private void updateItems() {
1816ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        List<ChannelsRowItem> items = getItemList();
1826ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        // The current index of the item list to iterate. It starts from 1 because the first item
1836ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        // (GUIDE) is always visible and not updated.
1846ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        int currentIndex = 1;
1856ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (updateItem(needToShowSetupItem(), ChannelsRowItem.SETUP_ITEM, currentIndex)) {
1866ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            ++currentIndex;
1876ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
1886ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (updateItem(needToShowDvrItem(), ChannelsRowItem.DVR_ITEM, currentIndex)) {
1896ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            ++currentIndex;
1906ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
1916ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (updateItem(needToShowAppLinkItem(), ChannelsRowItem.APP_LINK_ITEM, currentIndex)) {
1926ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            if (!getMainActivity().getCurrentChannel()
1936ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    .hasSameReadOnlyInfo(ChannelsRowItem.APP_LINK_ITEM.getChannel())) {
1946ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                ChannelsRowItem.APP_LINK_ITEM.setChannel(
1956ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                        new Channel.Builder(getMainActivity().getCurrentChannel()).build());
1966ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                notifyItemChanged(currentIndex);
1976ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            }
1986ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            ++currentIndex;
1996ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
2006ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        int numOldChannels = items.size() - currentIndex;
2016ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (numOldChannels > 0) {
2026ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            while (items.size() > currentIndex) {
2036ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                items.remove(items.size() - 1);
2046ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            }
2056ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            notifyItemRangeRemoved(currentIndex, numOldChannels);
2066ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
2076ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        for (Channel channel : getRecentChannels()) {
2086ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            items.add(new ChannelsRowItem(channel, R.layout.menu_card_channel));
2096ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
2106ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        int numNewChannels = items.size() - currentIndex;
2116ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (numNewChannels > 0) {
2126ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            notifyItemRangeInserted(currentIndex, numNewChannels);
2136ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
2146ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
2156ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
2166ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    /**
2176ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko     * Returns {@code true} if the item should be shown.
2186ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko     */
2196ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private boolean updateItem(boolean needToShow, ChannelsRowItem item, int index) {
2206ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        List<ChannelsRowItem> items = getItemList();
2216ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        boolean isItemInList = index < items.size() && item.equals(items.get(index));
2226ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (needToShow && !isItemInList) {
2236ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            items.add(index, item);
2246ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            notifyItemInserted(index);
2256ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        } else if (!needToShow && isItemInList) {
2266ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            items.remove(index);
2276ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            notifyItemRemoved(index);
2286ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
2296ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        return needToShow;
2306ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
2316ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
2326ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private boolean needToShowSetupItem() {
2336ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        TvInputManagerHelper inputManager =
2346ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                TvApplication.getSingletons(mContext).getTvInputManagerHelper();
2356ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        return SetupUtils.getInstance(mContext).hasNewInput(inputManager);
2366ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
2376ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
2386ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private boolean needToShowDvrItem() {
2396ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        TvInputManagerHelper inputManager =
2406ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                TvApplication.getSingletons(mContext).getTvInputManagerHelper();
241d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (mDvrDataManager != null) {
2422e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            for (TvInputInfo info : inputManager.getTvInputInfos(true, true)) {
2432e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko                if (info.canRecord()) {
2446ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    return true;
2452e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko                }
2462e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko            }
2472e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko        }
2486ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        return false;
2496ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
250ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko
2516ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private boolean needToShowAppLinkItem() {
2526ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        TvInputManagerHelper inputManager =
2536ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                TvApplication.getSingletons(mContext).getTvInputManagerHelper();
2546ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        Channel currentChannel = getMainActivity().getCurrentChannel();
2556ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        return currentChannel != null
2566ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                && currentChannel.getAppLinkType(mContext) != Channel.APP_LINK_TYPE_NONE
2576ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                // Sometimes applicationInfo can be null. b/28932537
2586ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                && inputManager.getTvInputAppInfo(currentChannel.getInputId()) != null;
259816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
260816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
261816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private List<Channel> getRecentChannels() {
262816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        List<Channel> channelList = new ArrayList<>();
2636ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        long currentChannelId = getMainActivity().getCurrentChannelId();
2646ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        ArrayDeque<Long> recentChannels = getMainActivity().getRecentChannels();
2656ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        // Add the last watched channel as the first one.
2666ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        for (long channelId : recentChannels) {
2676ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            if (addChannelToList(
2686ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    channelList, mRecommender.getChannel(channelId), currentChannelId)) {
2696ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                break;
2706ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            }
2716ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
2726ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        // Add the recommended channels.
273816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        for (Channel channel : mRecommender.recommendChannels(mMaxCount)) {
2746ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            if (channelList.size() >= mMaxCount) {
2756ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                break;
276816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
2776ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            addChannelToList(channelList, channel, currentChannelId);
278816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
279816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // If the number of recommended channels is not enough, add more from the recent channel
280816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // list.
2816ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        for (long channelId : recentChannels) {
2826ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            if (channelList.size() >= mMinCount) {
2836ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                break;
284816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
2856ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            addChannelToList(channelList, mRecommender.getChannel(channelId), currentChannelId);
286816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
2877d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        return channelList;
288816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
2896ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
2906ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private static boolean addChannelToList(
2916ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            List<Channel> channelList, Channel channel, long currentChannelId) {
2926ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (channel == null || channel.getId() == currentChannelId
2936ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                || channelList.contains(channel) || !channel.isBrowsable()) {
2946ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            return false;
2956ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
2966ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        channelList.add(channel);
2976ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        return true;
2986ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
299816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko}
300