17d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko/*
27d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * Copyright (C) 2015 The Android Open Source Project
37d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko *
47d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License");
57d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * you may not use this file except in compliance with the License.
67d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * You may obtain a copy of the License at
77d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko *
87d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko *      http://www.apache.org/licenses/LICENSE-2.0
97d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko *
107d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * Unless required by applicable law or agreed to in writing, software
117d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS,
127d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * See the License for the specific language governing permissions and
147d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * limitations under the License.
157d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko */
167d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
177d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalkopackage com.android.tv.data;
187d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
197d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalkoimport android.test.AndroidTestCase;
207d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalkoimport android.test.UiThreadTest;
217d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalkoimport android.test.suitebuilder.annotation.SmallTest;
22ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport android.test.suitebuilder.annotation.Suppress;
237d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
247d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalkoimport com.android.tv.data.WatchedHistoryManager.WatchedRecord;
257d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalkoimport com.android.tv.testing.Utils;
267d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
277d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalkoimport java.util.concurrent.CountDownLatch;
287d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalkoimport java.util.concurrent.TimeUnit;
297d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
307d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko/**
317d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko * Test for {@link com.android.tv.data.WatchedHistoryManagerTest}
327d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko */
337d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko@SmallTest
34ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko@Suppress // http://b/27156462
357d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalkopublic class WatchedHistoryManagerTest extends AndroidTestCase {
367d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    private static final boolean DEBUG = false;
377d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    private static final String TAG = "WatchedHistoryManager";
387d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
397d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    // Wait time for expected success.
407d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    private static final long WAIT_TIME_OUT_MS = 1000L;
417d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    private static final int MAX_HISTORY_SIZE = 100;
427d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
437d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    private WatchedHistoryManager mWatchedHistoryManager;
447d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    private TestWatchedHistoryManagerListener mListener;
457d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
467d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    @Override
477d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    protected void setUp() throws Exception {
487d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        super.setUp();
497d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        Utils.runOnMainSync(new Runnable() {
507d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            @Override
517d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            public void run() {
527d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko                mWatchedHistoryManager = new WatchedHistoryManager(getContext(), MAX_HISTORY_SIZE);
537d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko                mListener = new TestWatchedHistoryManagerListener();
547d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko                mWatchedHistoryManager.setListener(mListener);
557d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            }
567d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        });
577d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
587d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
597d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    private void startAndWaitForComplete() throws Exception {
607d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        mWatchedHistoryManager.start();
617d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        try {
627d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            assertTrue(mListener.loadFinishedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
637d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        } catch (InterruptedException e) {
647d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            throw e;
657d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        }
667d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
677d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
687d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    @UiThreadTest
697d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    public void testIsLoaded() throws Exception {
707d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        assertFalse(mWatchedHistoryManager.isLoaded());
717d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        startAndWaitForComplete();
727d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        assertTrue(mWatchedHistoryManager.isLoaded());
737d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
747d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
757d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    @UiThreadTest
767d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    public void testLogChannelViewStop() throws Exception {
777d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        startAndWaitForComplete();
787d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        long fakeId = 100000000;
797d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        long time = System.currentTimeMillis();
807d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        long duration = TimeUnit.MINUTES.toMillis(10);
817d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        Channel channel = new Channel.Builder().setId(fakeId).build();
827d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        mWatchedHistoryManager.logChannelViewStop(channel, time, duration);
837d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
847d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        WatchedRecord record = mWatchedHistoryManager.getRecord(0);
857d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        WatchedRecord recordFromSharedPreferences =
867d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko                mWatchedHistoryManager.getRecordFromSharedPreferences(0);
877d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        assertEquals(record.channelId, fakeId);
887d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        assertEquals(record.watchedStartTime, time - duration);
897d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        assertEquals(record.duration, duration);
907d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        assertEquals(record, recordFromSharedPreferences);
917d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
927d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
937d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    @UiThreadTest
947d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    public void testCircularHistoryQueue() throws Exception {
957d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        startAndWaitForComplete();
967d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        final long startChannelId = 100000000;
977d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        long time = System.currentTimeMillis();
987d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        long duration = TimeUnit.MINUTES.toMillis(10);
997d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
1007d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        int size = MAX_HISTORY_SIZE * 2;
1017d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        for (int i = 0; i < size; ++i) {
1027d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            Channel channel = new Channel.Builder().setId(startChannelId + i).build();
1037d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            mWatchedHistoryManager.logChannelViewStop(channel, time + duration * i, duration);
1047d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        }
1057d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        for (int i = 0; i < MAX_HISTORY_SIZE; ++i) {
1067d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            WatchedRecord record = mWatchedHistoryManager.getRecord(i);
1077d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            WatchedRecord recordFromSharedPreferences =
1087d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko                    mWatchedHistoryManager.getRecordFromSharedPreferences(i);
1097d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            assertEquals(record, recordFromSharedPreferences);
1107d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            assertEquals(record.channelId, startChannelId + size - 1 - i);
1117d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        }
1127d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        // Since the WatchedHistory is a circular queue, the value for 0 and maxHistorySize
1137d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        // are same.
1147d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        assertEquals(mWatchedHistoryManager.getRecordFromSharedPreferences(0),
1157d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko                mWatchedHistoryManager.getRecordFromSharedPreferences(MAX_HISTORY_SIZE));
1167d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
1177d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
1187d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    @UiThreadTest
1197d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    public void testWatchedRecordEquals() {
1207d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        assertTrue(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 2, 3)));
1217d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        assertFalse(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 2, 4)));
1227d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        assertFalse(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 4, 3)));
1237d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        assertFalse(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(4, 2, 3)));
1247d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
1257d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
1267d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    @UiThreadTest
1277d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    public void testEncodeDecodeWatchedRecord() throws Exception {
1287d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        long fakeId = 100000000;
1297d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        long time = System.currentTimeMillis();
1307d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        long duration = TimeUnit.MINUTES.toMillis(10);
1317d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        WatchedRecord record = new WatchedRecord(fakeId, time, duration);
1327d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        WatchedRecord sameRecord = mWatchedHistoryManager.decode(
1337d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko                mWatchedHistoryManager.encode(record));
1347d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        assertEquals(record, sameRecord);
1357d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
1367d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
1377d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    private class TestWatchedHistoryManagerListener implements WatchedHistoryManager.Listener {
1387d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        public CountDownLatch loadFinishedLatch = new CountDownLatch(1);
1397d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
1407d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        @Override
1417d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        public void onLoadFinished() {
1427d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko            loadFinishedLatch.countDown();
1437d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        }
1447d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko
1457d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        @Override
1467d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        public void onNewRecordAdded(WatchedRecord watchedRecord) { }
1477d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko    }
1487d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko}
149