ChannelDataManagerTest.java revision 7d67089aa1e9aa2123c3cd2f386d7019a1544db1
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.data;
18816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
19816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.content.ContentProvider;
20816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.content.ContentUris;
21816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.content.ContentValues;
22816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.content.Context;
23816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.database.ContentObserver;
24816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.database.Cursor;
25816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.media.tv.TvContract;
26816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.media.tv.TvContract.Channels;
27816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.net.Uri;
28816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.test.AndroidTestCase;
29816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.test.MoreAsserts;
307d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalkoimport android.test.UiThreadTest;
31816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.test.mock.MockContentProvider;
32816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.test.mock.MockContentResolver;
33816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.test.mock.MockCursor;
34816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.test.suitebuilder.annotation.SmallTest;
35816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.text.TextUtils;
36816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.util.Log;
37816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.util.SparseArray;
38816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
3907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalkoimport com.android.tv.analytics.StubTracker;
40816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.testing.ChannelInfo;
41816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.testing.Constants;
427d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalkoimport com.android.tv.testing.Utils;
43816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.util.TvInputManagerHelper;
44816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
45816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport org.mockito.Matchers;
46816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport org.mockito.Mockito;
47816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
48816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.ArrayList;
4907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalkoimport java.util.Arrays;
50816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.List;
51816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.concurrent.CountDownLatch;
52816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.concurrent.TimeUnit;
53816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
54816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko/**
557d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * Test for {@link ChannelDataManager}
56816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko *
57816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * A test method may include tests for multiple methods to minimize the DB access.
587d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * Note that all the methods of {@link ChannelDataManager} should be called from the UI thread.
59816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */
60816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko@SmallTest
61816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkopublic class ChannelDataManagerTest extends AndroidTestCase {
62816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static final boolean DEBUG = false;
63816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static final String TAG = "ChannelDataManagerTest";
64816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
65816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    // Wait time for expected success.
66816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static final long WAIT_TIME_OUT_MS = 1000L;
67816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static final String DUMMY_INPUT_ID = "dummy";
68816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    // TODO: Use Channels.COLUMN_BROWSABLE and Channels.COLUMN_LOCKED instead.
69816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static final String COLUMN_BROWSABLE = "browsable";
70816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static final String COLUMN_LOCKED = "locked";
71816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
72816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private ChannelDataManager mChannelDataManager;
73816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private TestChannelDataManagerListener mListener;
74816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private FakeContentResolver mContentResolver;
75816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private FakeContentProvider mContentProvider;
76816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
77816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
78816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    protected void setUp() throws Exception {
79816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        super.setUp();
80816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertTrue("More than 2 channels to test", Constants.UNIT_TEST_CHANNEL_COUNT > 2);
81816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
82816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mContentProvider = new FakeContentProvider(getContext());
83816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mContentResolver = new FakeContentResolver();
84816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mContentResolver.addProvider(TvContract.AUTHORITY, mContentProvider);
85816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mListener = new TestChannelDataManagerListener();
867d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        Utils.runOnMainSync(new Runnable() {
877d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            @Override
887d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            public void run() {
897d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko                TvInputManagerHelper mockHelper = Mockito.mock(TvInputManagerHelper.class);
907d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko                Mockito.when(mockHelper.hasTvInputInfo(Matchers.anyString())).thenReturn(true);
917d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko                mChannelDataManager = new ChannelDataManager(getContext(), mockHelper,
927d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko                        new StubTracker(), mContentResolver);
937d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko                mChannelDataManager.addListener(mListener);
947d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            }
957d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        });
96816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
97816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
98816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
99816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    protected void tearDown() throws Exception {
1007d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        Utils.runOnMainSync(new Runnable() {
1017d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            @Override
1027d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            public void run() {
1037d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko                mChannelDataManager.stop();
1047d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            }
1057d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        });
106816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        super.tearDown();
107816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
108816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
109816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private void startAndWaitForComplete() throws Exception {
110816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.start();
111816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        try {
112816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            assertTrue(mListener.loadFinishedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
113816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        } catch (InterruptedException e) {
114816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            throw e;
115816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
116816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
117816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
118816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private void restart() throws Exception {
119816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.stop();
120816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mListener.reset();
121816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        startAndWaitForComplete();
122816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
123816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
1247d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    @UiThreadTest
125816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public void testIsDbLoadFinished() throws Exception {
126816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        startAndWaitForComplete();
127816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertTrue(mChannelDataManager.isDbLoadFinished());
128816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
129816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
130816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
131816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Test for following methods
132816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     *   - {@link ChannelDataManager#getChannelCount}
133816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     *   - {@link ChannelDataManager#getChannelList}
134816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     *   - {@link ChannelDataManager#getChannel}
135816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
1367d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    @UiThreadTest
137816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public void testGetChannels() throws Exception {
138816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        startAndWaitForComplete();
139816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
140816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Test {@link ChannelDataManager#getChannelCount}
141816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT, mChannelDataManager.getChannelCount());
142816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
143816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Test {@link ChannelDataManager#getChannelList}
144816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        List<ChannelInfo> channelInfoList = new ArrayList<>();
145816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        for (int i = 1; i <= Constants.UNIT_TEST_CHANNEL_COUNT; i++) {
146816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            channelInfoList.add(ChannelInfo.create(getContext(), i));
147816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
148816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        List<Channel> channelList = mChannelDataManager.getChannelList();
149816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        for (Channel channel : channelList) {
150816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            boolean found = false;
151816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            for (ChannelInfo channelInfo : channelInfoList) {
152816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                if (TextUtils.equals(channelInfo.name, channel.getDisplayName())
153816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        && TextUtils.equals(channelInfo.name, channel.getDisplayName())) {
154816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    found = true;
155816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    channelInfoList.remove(channelInfo);
156816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    break;
157816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
158816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
159816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            assertTrue("Cannot find (" + channel + ")", found);
160816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
161816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
162816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Test {@link ChannelDataManager#getChannelIndex()}
163816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        for (Channel channel : channelList) {
164816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            assertEquals(channel, mChannelDataManager.getChannel(channel.getId()));
165816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
166816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
167816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
168816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
169816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Test for {@link ChannelDataManager#getChannelCount} when no channel is available.
170816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
1717d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    @UiThreadTest
172816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public void testGetChannels_noChannels() throws Exception {
173816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mContentProvider.clear();
174816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        startAndWaitForComplete();
175816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(0, mChannelDataManager.getChannelCount());
176816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
177816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
178816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
179816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Test for following methods and channel listener with notifying change.
180816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     *   - {@link ChannelDataManager#updateBrowsable}
181816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     *   - {@link ChannelDataManager#applyUpdatedValuesToDb}
182816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
1837d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    @UiThreadTest
184816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public void testBrowsable() throws Exception {
185816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        startAndWaitForComplete();
186816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
18707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        // Test if all channels are browsable
188816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        List<Channel> channelList = new ArrayList<>(mChannelDataManager.getChannelList());
189816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        List<Channel> browsableChannelList = mChannelDataManager.getBrowsableChannelList();
190816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        for (Channel browsableChannel : browsableChannelList) {
191816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            boolean found = channelList.remove(browsableChannel);
192816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            assertTrue("Cannot find (" + browsableChannel + ")", found);
193816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
194816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(0, channelList.size());
195816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
196816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Prepare for next tests.
197816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        TestChannelDataManagerChannelListener channelListener =
198816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                new TestChannelDataManagerChannelListener();
199816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        Channel channel1 = mChannelDataManager.getChannelList().get(0);
200816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.addChannelListener(channel1.getId(), channelListener);
201816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
202816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Test {@link ChannelDataManager#updateBrowsable} & notification.
203816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.updateBrowsable(channel1.getId(), false, false);
204816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertTrue(mListener.channelBrowsableChangedCalled);
205816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertFalse(mChannelDataManager.getBrowsableChannelList().contains(channel1));
206816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        MoreAsserts.assertContentsInAnyOrder(channelListener.updatedChannels, channel1);
207816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        channelListener.reset();
208816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
209816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Test {@link ChannelDataManager#applyUpdatedValuesToDb}
210816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.applyUpdatedValuesToDb();
211816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        restart();
212816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        browsableChannelList = mChannelDataManager.getBrowsableChannelList();
213816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT - 1, browsableChannelList.size());
214816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertFalse(browsableChannelList.contains(channel1));
215816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
216816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
217816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
218816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Test for following methods and channel listener without notifying change.
219816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     *   - {@link ChannelDataManager#updateBrowsable}
220816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     *   - {@link ChannelDataManager#applyUpdatedValuesToDb}
221816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
2227d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    @UiThreadTest
223816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public void testBrowsable_skipNotification() throws Exception {
224816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        startAndWaitForComplete();
225816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
226816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Prepare for next tests.
227816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        TestChannelDataManagerChannelListener channelListener =
228816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                new TestChannelDataManagerChannelListener();
229816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        Channel channel1 = mChannelDataManager.getChannelList().get(0);
230816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        Channel channel2 = mChannelDataManager.getChannelList().get(1);
231816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.addChannelListener(channel1.getId(), channelListener);
232816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.addChannelListener(channel2.getId(), channelListener);
233816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
234816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Test {@link ChannelDataManager#updateBrowsable} & skip notification.
235816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.updateBrowsable(channel1.getId(), false, true);
236816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.updateBrowsable(channel2.getId(), false, true);
237816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.updateBrowsable(channel1.getId(), true, true);
238816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertFalse(mListener.channelBrowsableChangedCalled);
239816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        List<Channel> browsableChannelList = mChannelDataManager.getBrowsableChannelList();
240816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertTrue(browsableChannelList.contains(channel1));
241816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertFalse(browsableChannelList.contains(channel2));
242816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
243816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Test {@link ChannelDataManager#applyUpdatedValuesToDb}
244816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.applyUpdatedValuesToDb();
245816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        restart();
246816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        browsableChannelList = mChannelDataManager.getBrowsableChannelList();
247816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT - 1, browsableChannelList.size());
248816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertFalse(browsableChannelList.contains(channel2));
249816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
250816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
251816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
252816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Test for following methods and channel listener.
253816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     *   - {@link ChannelDataManager#updateLocked}
254816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     *   - {@link ChannelDataManager#applyUpdatedValuesToDb}
255816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
2567d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    @UiThreadTest
257816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public void testLocked() throws Exception {
258816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        startAndWaitForComplete();
259816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
260816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Test if all channels aren't locked at the first time.
261816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        List<Channel> channelList = mChannelDataManager.getChannelList();
262816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        for (Channel channel : channelList) {
263816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            assertFalse(channel + " is locked", channel.isLocked());
264816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
265816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
266816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Prepare for next tests.
267816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        Channel channel = mChannelDataManager.getChannelList().get(0);
268816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
269816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Test {@link ChannelDataManager#updateLocked}
270816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.updateLocked(channel.getId(), true);
271816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertTrue(mChannelDataManager.getChannel(channel.getId()).isLocked());
272816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
273816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Test {@link ChannelDataManager#applyUpdatedValuesToDb}.
274816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.applyUpdatedValuesToDb();
275816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        restart();
276816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertTrue(mChannelDataManager.getChannel(channel.getId()).isLocked());
277816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
278816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Cleanup
279816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.updateLocked(channel.getId(), false);
280816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
281816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
282816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
283816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Test ChannelDataManager when channels in TvContract are updated, removed, or added.
284816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
2857d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    @UiThreadTest
286816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public void testChannelListChanged() throws Exception {
287816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        startAndWaitForComplete();
288816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
289816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Test channel add.
290816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mListener.reset();
291816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        long testChannelId = Constants.UNIT_TEST_CHANNEL_COUNT + 1;
292816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        ChannelInfo testChannelInfo = ChannelInfo.create(getContext(), (int) testChannelId);
293816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        testChannelId = Constants.UNIT_TEST_CHANNEL_COUNT + 1;
294816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mContentProvider.simulateInsert(testChannelInfo);
29507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        assertTrue(
29607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
297816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT + 1, mChannelDataManager.getChannelCount());
298816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
299816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Test channel update
300816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mListener.reset();
301816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        TestChannelDataManagerChannelListener channelListener =
302816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                new TestChannelDataManagerChannelListener();
303816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelDataManager.addChannelListener(testChannelId, channelListener);
304816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        String newName = testChannelInfo.name + "_test";
305816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mContentProvider.simulateUpdate(testChannelId, newName);
30607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        assertTrue(
30707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
30807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        assertTrue(
30907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                channelListener.channelChangedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
310816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(0, channelListener.removedChannels.size());
311816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(1, channelListener.updatedChannels.size());
312816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        Channel updatedChannel = channelListener.updatedChannels.get(0);
313816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(testChannelId, updatedChannel.getId());
314816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(testChannelInfo.number, updatedChannel.getDisplayNumber());
315816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(newName, updatedChannel.getDisplayName());
316816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT + 1,
317816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                mChannelDataManager.getChannelCount());
318816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
319816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Test channel remove.
320816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mListener.reset();
321816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        channelListener.reset();
322816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mContentProvider.simulateDelete(testChannelId);
32307b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        assertTrue(
32407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
32507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        assertTrue(
32607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                channelListener.channelChangedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
327816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(1, channelListener.removedChannels.size());
328816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(0, channelListener.updatedChannels.size());
329816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        Channel removedChannel = channelListener.removedChannels.get(0);
330816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(newName, removedChannel.getDisplayName());
331816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(testChannelInfo.number, removedChannel.getDisplayNumber());
332816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT, mChannelDataManager.getChannelCount());
333816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
334816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
335816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private class ChannelInfoWrapper {
336816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public ChannelInfo channelInfo;
337816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public boolean browsable;
338816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public boolean locked;
339816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public ChannelInfoWrapper(ChannelInfo channelInfo) {
340816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            this.channelInfo = channelInfo;
341816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            browsable = true;
342816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            locked = false;
343816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
344816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
345816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
346816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private class FakeContentResolver extends MockContentResolver {
347816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
348816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
349816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            super.notifyChange(uri, observer, syncToNetwork);
350816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (DEBUG) {
351816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                Log.d(TAG, "onChanged(uri=" + uri + ", observer=" + observer + ")");
352816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
3537d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            // Do not call {@link ContentObserver#onChange} directly to run it on the correct
3547d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            // thread.
355816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (observer != null) {
356816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                observer.dispatchChange(false, uri);
357816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            } else {
358816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                mChannelDataManager.getContentObserver().dispatchChange(false, uri);
359816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
360816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
361816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
362816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
363816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    // This implements the minimal methods in content resolver
364816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    // and detailed assumptions are written in each method.
365816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private class FakeContentProvider extends MockContentProvider {
36607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        private final SparseArray<ChannelInfoWrapper> mChannelInfoList = new SparseArray<>();
367816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
368816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public FakeContentProvider(Context context) {
369816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            super(context);
370816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            for (int i = 1; i <= Constants.UNIT_TEST_CHANNEL_COUNT; i++) {
371816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                mChannelInfoList.put(i,
372816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        new ChannelInfoWrapper(ChannelInfo.create(getContext(), i)));
373816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
374816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
375816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
376816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        /**
377816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         * Implementation of {@link ContentProvider#query}.
378816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         * This assumes that {@link ChannelDataManager} queries channels
379816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         * with empty {@code selection}. (i.e. channels are always queries for all)
380816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         */
381816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
382816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public Cursor query(Uri uri, String[] projection, String selection, String[]
383816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                selectionArgs, String sortOrder) {
384816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (DEBUG) {
385816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                Log.d(TAG, "dump query");
386816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                Log.d(TAG, "  uri=" + uri);
38707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                Log.d(TAG, "  projection=" + Arrays.toString(projection));
38807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                Log.d(TAG, "  selection=" + selection);
389816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
390816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            assertChannelUri(uri);
391816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return new FakeCursor(projection);
392816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
393816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
394816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        /**
395816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         * Implementation of {@link ContentProvider#update}.
396816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         * This assumes that {@link ChannelDataManager} update channels
397816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         * only for changing browsable and locked.
398816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         */
399816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
400816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
401816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (DEBUG) Log.d(TAG, "update(uri=" + uri + ", selection=" + selection);
402816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            assertChannelUri(uri);
403816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            List<Long> channelIds = new ArrayList<>();
404816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            try {
405816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                long channelId = ContentUris.parseId(uri);
406816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                channelIds.add(channelId);
407816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            } catch (NumberFormatException e) {
408816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                // Update for multiple channels.
409816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                if (TextUtils.isEmpty(selection)) {
410816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    for (int i = 0; i < mChannelInfoList.size(); i++) {
411816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        channelIds.add((long) mChannelInfoList.keyAt(i));
412816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    }
413816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                } else {
414816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    // See {@link Utils#buildSelectionForIds} for the syntax.
415816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    String selectionForId = selection.substring(
416816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                            selection.indexOf("(") + 1, selection.lastIndexOf(")"));
417816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    String[] ids = selectionForId.split(", ");
418816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    if (ids != null) {
419816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        for (String id : ids) {
420816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                            channelIds.add(Long.parseLong(id));
421816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        }
422816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    }
423816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
424816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
425816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            int updateCount = 0;
426816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            for (long channelId : channelIds) {
427816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                boolean updated = false;
428816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                ChannelInfoWrapper channel = mChannelInfoList.get((int) channelId);
429816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                if (channel == null) {
430816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    return 0;
431816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
432816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                if (values.containsKey(COLUMN_BROWSABLE)) {
433816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    updated = true;
434816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    channel.browsable = (values.getAsInteger(COLUMN_BROWSABLE) == 1);
435816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
436816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                if (values.containsKey(COLUMN_LOCKED)) {
437816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    updated = true;
438816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    channel.locked = (values.getAsInteger(COLUMN_LOCKED) == 1);
439816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
440816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                updateCount += updated ? 1 : 0;
441816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
442816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (updateCount > 0) {
443816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                if (channelIds.size() == 1) {
444816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    mContentResolver.notifyChange(uri, null);
445816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                } else {
446816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    mContentResolver.notifyChange(Channels.CONTENT_URI, null);
447816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
448816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            } else {
449816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                if (DEBUG) {
450816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    Log.d(TAG, "Update to channel(uri=" + uri + ") is ignored for " + values);
451816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
452816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
453816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return updateCount;
454816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
455816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
456816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        /**
457816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         * Simulates channel data insert.
458816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         * This assigns original network ID (the same with channel number) to channel ID.
459816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         */
460816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void simulateInsert(ChannelInfo testChannelInfo) {
461816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            long channelId = testChannelInfo.originalNetworkId;
462816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mChannelInfoList.put((int) channelId,
463816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    new ChannelInfoWrapper(ChannelInfo.create(getContext(), (int) channelId)));
464816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mContentResolver.notifyChange(TvContract.buildChannelUri(channelId), null);
465816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
466816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
467816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        /**
468816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         * Simulates channel data delete.
469816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         */
470816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void simulateDelete(long channelId) {
471816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mChannelInfoList.remove((int) channelId);
472816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mContentResolver.notifyChange(TvContract.buildChannelUri(channelId), null);
473816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
474816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
475816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        /**
476816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         * Simulates channel data update.
477816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko         */
478816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void simulateUpdate(long channelId, String newName) {
479816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            ChannelInfoWrapper channel = mChannelInfoList.get((int) channelId);
480816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            ChannelInfo.Builder builder = new ChannelInfo.Builder(channel.channelInfo);
481816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            builder.setName(newName);
482816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            channel.channelInfo = builder.build();
483816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mContentResolver.notifyChange(TvContract.buildChannelUri(channelId), null);
484816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
485816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
486816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        private void assertChannelUri(Uri uri) {
487816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            assertTrue("Uri(" + uri + ") isn't channel uri",
488816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    uri.toString().startsWith(Channels.CONTENT_URI.toString()));
489816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
490816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
491816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void clear() {
492816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mChannelInfoList.clear();
493816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
494816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
495816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public ChannelInfoWrapper get(int position) {
496816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return mChannelInfoList.get(mChannelInfoList.keyAt(position));
497816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
498816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
499816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public int getCount() {
500816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return mChannelInfoList.size();
501816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
502816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
503816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public long keyAt(int position) {
504816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return mChannelInfoList.keyAt(position);
505816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
506816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
507816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
508816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private class FakeCursor extends MockCursor {
50907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        private final String[] ALL_COLUMNS =  {
510816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                Channels._ID,
511816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                Channels.COLUMN_DISPLAY_NAME,
512816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                Channels.COLUMN_DISPLAY_NUMBER,
513816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                Channels.COLUMN_INPUT_ID,
514816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                Channels.COLUMN_VIDEO_FORMAT,
515816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                Channels.COLUMN_ORIGINAL_NETWORK_ID,
516816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                COLUMN_BROWSABLE,
517816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                COLUMN_LOCKED};
51807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        private final String[] mColumns;
519816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        private int mPosition;
520816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
521816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public FakeCursor(String[] columns) {
522816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mColumns = (columns == null) ? ALL_COLUMNS : columns;
523816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mPosition = -1;
524816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
525816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
526816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
527816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public String getColumnName(int columnIndex) {
528816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return mColumns[columnIndex];
529816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
530816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
531816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
532816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public int getColumnIndex(String columnName) {
533816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            for (int i = 0; i < mColumns.length; i++) {
534816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                if (mColumns[i].equalsIgnoreCase(columnName)) {
535816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    return i;
536816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
537816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
538816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return -1;
539816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
540816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
541816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
542816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public long getLong(int columnIndex) {
543816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            String columnName = getColumnName(columnIndex);
544816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            switch (columnName) {
545816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                case Channels._ID:
546816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    return mContentProvider.keyAt(mPosition);
547816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
548816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (DEBUG) {
549816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                Log.d(TAG, "Column (" + columnName + ") is ignored in getLong()");
550816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
551816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return 0;
552816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
553816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
554816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
555816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public String getString(int columnIndex) {
556816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            String columnName = getColumnName(columnIndex);
557816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            ChannelInfoWrapper channel = mContentProvider.get(mPosition);
558816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            switch (columnName) {
559816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                case Channels.COLUMN_DISPLAY_NAME:
560816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    return channel.channelInfo.name;
561816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                case Channels.COLUMN_DISPLAY_NUMBER:
562816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    return channel.channelInfo.number;
563816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                case Channels.COLUMN_INPUT_ID:
564816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    return DUMMY_INPUT_ID;
565816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                case Channels.COLUMN_VIDEO_FORMAT:
566816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    return channel.channelInfo.getVideoFormat();
567816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
568816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (DEBUG) {
569816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                Log.d(TAG, "Column (" + columnName + ") is ignored in getString()");
570816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
571816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return null;
572816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
573816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
574816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
575816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public int getInt(int columnIndex) {
576816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            String columnName = getColumnName(columnIndex);
577816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            ChannelInfoWrapper channel = mContentProvider.get(mPosition);
578816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            switch (columnName) {
579816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                case Channels.COLUMN_ORIGINAL_NETWORK_ID:
580816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    return channel.channelInfo.originalNetworkId;
581816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                case COLUMN_BROWSABLE:
582816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    return channel.browsable ? 1 : 0;
583816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                case COLUMN_LOCKED:
584816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    return channel.locked ? 1 : 0;
585816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
586816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (DEBUG) {
587816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                Log.d(TAG, "Column (" + columnName + ") is ignored in getInt()");
588816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
589816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return 0;
590816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
591816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
592816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
593816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public int getCount() {
594816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return mContentProvider.getCount();
595816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
596816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
597816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
598816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public boolean moveToNext() {
599816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return ++mPosition < mContentProvider.getCount();
600816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
601816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
602816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
603816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void close() {
604816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            // No-op.
605816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
606816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
607816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
608816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private class TestChannelDataManagerListener implements ChannelDataManager.Listener {
609816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public CountDownLatch loadFinishedLatch = new CountDownLatch(1);
61007b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        public CountDownLatch channelListUpdatedLatch = new CountDownLatch(1);
611816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public boolean channelBrowsableChangedCalled;
612816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
613816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
614816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void onLoadFinished() {
615816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            loadFinishedLatch.countDown();
616816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
617816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
618816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
619816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void onChannelListUpdated() {
62007b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko            channelListUpdatedLatch.countDown();
621816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
622816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
623816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
624816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void onChannelBrowsableChanged() {
625816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            channelBrowsableChangedCalled = true;
626816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
627816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
628816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void reset() {
629816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            loadFinishedLatch = new CountDownLatch(1);
63007b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko            channelListUpdatedLatch = new CountDownLatch(1);
631816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            channelBrowsableChangedCalled = false;
632816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
633816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
634816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
635816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private class TestChannelDataManagerChannelListener
636816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            implements ChannelDataManager.ChannelListener {
637816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public CountDownLatch channelChangedLatch = new CountDownLatch(1);
63807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        public final List<Channel> removedChannels = new ArrayList<>();
63907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko        public final List<Channel> updatedChannels = new ArrayList<>();
640816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
641816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
642816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void onChannelRemoved(Channel channel) {
643816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            removedChannels.add(channel);
644816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            channelChangedLatch.countDown();
645816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
646816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
647816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
648816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void onChannelUpdated(Channel channel) {
649816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            updatedChannels.add(channel);
650816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            channelChangedLatch.countDown();
651816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
652816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
653816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void reset() {
654816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            channelChangedLatch = new CountDownLatch(1);
655816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            removedChannels.clear();
656816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            updatedChannels.clear();
657816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
658816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
659816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko}
660