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