Home | History | Annotate | Download | only in dvr
      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 
     17 package com.android.tv.dvr;
     18 
     19 import static org.mockito.Matchers.anyInt;
     20 import static org.mockito.Matchers.anyLong;
     21 import static org.mockito.Matchers.argThat;
     22 import static org.mockito.Matchers.eq;
     23 import static org.mockito.Matchers.longThat;
     24 import static org.mockito.Mockito.verify;
     25 import static org.mockito.Mockito.verifyNoMoreInteractions;
     26 import static org.mockito.Mockito.when;
     27 
     28 import android.media.tv.TvRecordingClient;
     29 import android.os.Build;
     30 import android.os.Handler;
     31 import android.os.Looper;
     32 import android.os.Message;
     33 import android.os.SystemClock;
     34 import android.support.test.filters.SdkSuppress;
     35 import android.test.AndroidTestCase;
     36 import android.test.suitebuilder.annotation.SmallTest;
     37 
     38 import com.android.tv.data.Channel;
     39 import com.android.tv.data.Program;
     40 import com.android.tv.dvr.RecordingTask.State;
     41 import com.android.tv.testing.FakeClock;
     42 import com.android.tv.testing.dvr.RecordingTestUtils;
     43 
     44 import org.hamcrest.BaseMatcher;
     45 import org.hamcrest.Description;
     46 import org.mockito.ArgumentMatcher;
     47 import org.mockito.Mock;
     48 import org.mockito.MockitoAnnotations;
     49 
     50 import java.util.concurrent.TimeUnit;
     51 
     52 /**
     53  * Tests for {@link RecordingTask}.
     54  */
     55 @SmallTest
     56 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
     57 public class RecordingTaskTest extends AndroidTestCase {
     58     private static final long DURATION = TimeUnit.MINUTES.toMillis(30);
     59     private static final long START_OFFSET = Scheduler.MS_TO_WAKE_BEFORE_START;
     60     public static final int CHANNEL_ID = 273;
     61 
     62     private FakeClock mFakeClock;
     63     private DvrDataManagerInMemoryImpl mDataManager;
     64     @Mock Handler mMockHandler;
     65     @Mock DvrManager mDvrManager;
     66     @Mock DvrSessionManager mMockSessionManager;
     67     @Mock TvRecordingClient mMockTvRecordingClient;
     68 
     69     @Override
     70     protected void setUp() throws Exception {
     71         super.setUp();
     72         if (Looper.myLooper() == null) {
     73             Looper.prepare();
     74         }
     75         MockitoAnnotations.initMocks(this);
     76         mFakeClock = FakeClock.createWithCurrentTime();
     77         mDataManager = new DvrDataManagerInMemoryImpl(getContext(), mFakeClock);
     78     }
     79 
     80     public void testHandle_init() {
     81         Channel channel = createTestChannel();
     82         ScheduledRecording r = createRecording(channel);
     83         RecordingTask task = createRecordingTask(r, channel);
     84         String inputId = channel.getInputId();
     85         when(mMockSessionManager.canAcquireDvrSession(inputId, channel)).thenReturn(true);
     86         when(mMockSessionManager.createTvRecordingClient("tag", task, null))
     87                 .thenReturn(mMockTvRecordingClient);
     88         when(mMockHandler.sendEmptyMessageDelayed(anyInt(), anyLong())).thenReturn(true);
     89 
     90         long delay = START_OFFSET - RecordingTask.MS_BEFORE_START;
     91         long uptime = SystemClock.uptimeMillis();
     92         assertTrue(task.handleMessage(createMessage(RecordingTask.MESSAGE_INIT)));
     93 
     94         assertEquals(State.CONNECTION_PENDING, task.getState());
     95         verify(mMockSessionManager).canAcquireDvrSession(inputId, channel);
     96         verify(mMockSessionManager).createTvRecordingClient("tag", task, null);
     97         verify(mMockTvRecordingClient).tune(eq(inputId), eq(channel.getUri()));
     98 
     99         verifySendMessageAt(RecordingTask.MESSAGE_START_RECORDING, uptime + delay);
    100         verifyNoMoreInteractions(mMockHandler, mMockTvRecordingClient, mMockSessionManager);
    101     }
    102 
    103     private static Channel createTestChannel() {
    104         return new Channel.Builder().setId(CHANNEL_ID).setDisplayName("Test Ch " + CHANNEL_ID)
    105                 .build();
    106     }
    107 
    108     public void testHandle_init_cannotAcquireSession() {
    109         Channel channel = createTestChannel();
    110         ScheduledRecording r = createRecording(channel);
    111         r = mDataManager.addScheduledRecordingInternal(r);
    112         RecordingTask task = createRecordingTask(r, channel);
    113 
    114         when(mMockSessionManager.canAcquireDvrSession(channel.getInputId(), channel))
    115                 .thenReturn(false);
    116 
    117         assertTrue(task.handleMessage(createMessage(RecordingTask.MESSAGE_INIT)));
    118 
    119         assertEquals(State.ERROR, task.getState());
    120         verifySendMessage(Scheduler.HandlerWrapper.MESSAGE_REMOVE);
    121         ScheduledRecording updatedScheduledRecording = mDataManager
    122                 .getScheduledRecording(r.getId());
    123         assertEquals("status", ScheduledRecording.STATE_RECORDING_FAILED,
    124                 updatedScheduledRecording.getState());
    125     }
    126 
    127     public void testOnConnected() {
    128         Channel channel = createTestChannel();
    129         ScheduledRecording r = createRecording(channel);
    130         mDataManager.addScheduledRecording(r);
    131         RecordingTask task = createRecordingTask(r, channel);
    132 
    133         task.onTuned(channel.getUri());
    134 
    135         assertEquals(State.CONNECTED, task.getState());
    136     }
    137 
    138     private ScheduledRecording createRecording(Channel c) {
    139         long startTime = mFakeClock.currentTimeMillis() + START_OFFSET;
    140         long endTime = startTime + DURATION;
    141         return RecordingTestUtils.createTestRecordingWithPeriod(c.getId(), startTime, endTime);
    142     }
    143 
    144     private RecordingTask createRecordingTask(ScheduledRecording r, Channel channel) {
    145         Program p = r.getProgramId() == ScheduledRecording.ID_NOT_SET ? null
    146                 : new Program.Builder().setId(r.getId()).build();
    147         RecordingTask recordingTask = new RecordingTask(r, channel, mDvrManager,
    148                 mMockSessionManager, mDataManager, mFakeClock);
    149         recordingTask.setHandler(mMockHandler);
    150         return recordingTask;
    151     }
    152 
    153     private void verifySendMessage(int what) {
    154         verify(mMockHandler).sendMessageAtTime(argThat(messageMatchesWhat(what)), anyLong());
    155     }
    156 
    157     private void verifySendMessageAt(int what, long when) {
    158         verify(mMockHandler).sendMessageAtTime(argThat(messageMatchesWhat(what)), delta(when, 100));
    159     }
    160 
    161     private static long delta(final long value, final long delta) {
    162         return longThat(new BaseMatcher<Long>() {
    163             @Override
    164             public boolean matches(Object item) {
    165                 Long other = (Long) item;
    166                 return other >= value - delta && other <= value + delta;
    167             }
    168 
    169             @Override
    170             public void describeTo(Description description) {
    171                 description.appendText("eq " + value + "" + delta);
    172 
    173             }
    174         });
    175     }
    176 
    177     private Message createMessage(int what) {
    178         Message msg = new Message();
    179         msg.setTarget(mMockHandler);
    180         msg.what = what;
    181         return msg;
    182     }
    183 
    184     public static ArgumentMatcher<Message> messageMatchesWhat(final int what) {
    185         return new ArgumentMatcher<Message>() {
    186             @Override
    187             public boolean matches(Object argument) {
    188                 Message message = (Message) argument;
    189                 return message.what == what;
    190             }
    191         };
    192     }
    193 }