1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.tv.dvr.recorder;
18
19import static android.support.test.InstrumentationRegistry.getContext;
20import static org.junit.Assert.assertEquals;
21import static org.junit.Assert.assertTrue;
22import static org.mockito.Matchers.anyLong;
23import static org.mockito.Matchers.anyObject;
24import static org.mockito.Matchers.anyString;
25import static org.mockito.Matchers.eq;
26import static org.mockito.Mockito.verify;
27import static org.mockito.Mockito.verifyNoMoreInteractions;
28import static org.mockito.Mockito.when;
29
30import android.os.Build;
31import android.os.Handler;
32import android.os.Looper;
33import android.os.Message;
34import android.support.test.filters.SdkSuppress;
35import android.support.test.filters.SmallTest;
36
37import com.android.tv.InputSessionManager;
38import com.android.tv.InputSessionManager.RecordingSession;
39import com.android.tv.common.feature.CommonFeatures;
40import com.android.tv.common.feature.TestableFeature;
41import com.android.tv.data.Channel;
42import com.android.tv.dvr.DvrDataManagerInMemoryImpl;
43import com.android.tv.dvr.DvrManager;
44import com.android.tv.dvr.data.ScheduledRecording;
45import com.android.tv.dvr.recorder.RecordingTask.State;
46import com.android.tv.testing.FakeClock;
47import com.android.tv.testing.dvr.RecordingTestUtils;
48
49import org.junit.After;
50import org.junit.Before;
51import org.junit.Test;
52import org.mockito.Mock;
53import org.mockito.MockitoAnnotations;
54
55import java.util.concurrent.TimeUnit;
56
57/**
58 * Tests for {@link RecordingTask}.
59 */
60@SmallTest
61@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
62public class RecordingTaskTest {
63    private static final long DURATION = TimeUnit.MINUTES.toMillis(30);
64    private static final long START_OFFSET_MS = RecordingScheduler.MS_TO_WAKE_BEFORE_START;
65    private static final String INPUT_ID = "input_id";
66    private static final int CHANNEL_ID = 273;
67
68    private FakeClock mFakeClock;
69    private DvrDataManagerInMemoryImpl mDataManager;
70    @Mock Handler mMockHandler;
71    @Mock DvrManager mDvrManager;
72    @Mock InputSessionManager mMockSessionManager;
73    @Mock RecordingSession mMockRecordingSession;
74    private final TestableFeature mDvrFeature = CommonFeatures.DVR;
75
76    @Before
77    public void setUp() {
78        mDvrFeature.enableForTest();
79        if (Looper.myLooper() == null) {
80            Looper.prepare();
81        }
82        MockitoAnnotations.initMocks(this);
83        mFakeClock = FakeClock.createWithCurrentTime();
84        mDataManager = new DvrDataManagerInMemoryImpl(getContext(), mFakeClock);
85    }
86
87    @After
88    public void tearDown() {
89        mDvrFeature.resetForTests();
90    }
91
92    @Test
93    public void testHandle_init() {
94        Channel channel = createTestChannel();
95        ScheduledRecording r = createRecording(channel);
96        RecordingTask task = createRecordingTask(r, channel);
97        String inputId = channel.getInputId();
98        when(mMockSessionManager.createRecordingSession(eq(inputId), anyString(), eq(task),
99                eq(mMockHandler), anyLong())).thenReturn(mMockRecordingSession);
100        when(mMockHandler.sendMessageAtTime(anyObject(), anyLong())).thenReturn(true);
101        assertTrue(task.handleMessage(createMessage(RecordingTask.MSG_INITIALIZE)));
102        assertEquals(State.CONNECTION_PENDING, task.getState());
103        verify(mMockSessionManager).createRecordingSession(eq(inputId), anyString(), eq(task),
104                eq(mMockHandler), anyLong());
105        verify(mMockRecordingSession).tune(eq(inputId), eq(channel.getUri()));
106        verifyNoMoreInteractions(mMockHandler, mMockRecordingSession, mMockSessionManager);
107    }
108
109    private static Channel createTestChannel() {
110        return new Channel.Builder().setInputId(INPUT_ID).setId(CHANNEL_ID)
111                .setDisplayName("Test Ch " + CHANNEL_ID).build();
112    }
113
114    @Test
115    public void testOnConnected() {
116        Channel channel = createTestChannel();
117        ScheduledRecording r = createRecording(channel);
118        mDataManager.addScheduledRecording(r);
119        RecordingTask task = createRecordingTask(r, channel);
120        String inputId = channel.getInputId();
121        when(mMockSessionManager.createRecordingSession(eq(inputId), anyString(), eq(task),
122                eq(mMockHandler), anyLong())).thenReturn(mMockRecordingSession);
123        when(mMockHandler.sendMessageAtTime(anyObject(), anyLong())).thenReturn(true);
124        task.handleMessage(createMessage(RecordingTask.MSG_INITIALIZE));
125        task.onTuned(channel.getUri());
126        assertEquals(State.CONNECTED, task.getState());
127    }
128
129    private ScheduledRecording createRecording(Channel c) {
130        long startTime = mFakeClock.currentTimeMillis() + START_OFFSET_MS;
131        long endTime = startTime + DURATION;
132        return RecordingTestUtils.createTestRecordingWithPeriod(c.getInputId(), c.getId(),
133                startTime, endTime);
134    }
135
136    private RecordingTask createRecordingTask(ScheduledRecording r, Channel channel) {
137        RecordingTask recordingTask = new RecordingTask(getContext(), r, channel, mDvrManager,
138                mMockSessionManager, mDataManager, mFakeClock);
139        recordingTask.setHandler(mMockHandler);
140        return recordingTask;
141    }
142
143    private Message createMessage(int what) {
144        Message msg = new Message();
145        msg.setTarget(mMockHandler);
146        msg.what = what;
147        return msg;
148    }
149}