1 package com.android.server.location; 2 3 import static com.google.common.truth.Truth.assertThat; 4 5 import static org.mockito.Mockito.doReturn; 6 7 import android.os.Looper; 8 import android.os.SystemClock; 9 import android.platform.test.annotations.Presubmit; 10 import android.util.NtpTrustedTime; 11 12 import com.android.server.location.NtpTimeHelper.InjectNtpTimeCallback; 13 14 import org.junit.Before; 15 import org.junit.Test; 16 import org.junit.runner.RunWith; 17 import org.mockito.Mock; 18 import org.mockito.MockitoAnnotations; 19 import org.robolectric.RobolectricTestRunner; 20 import org.robolectric.RuntimeEnvironment; 21 import org.robolectric.shadows.ShadowLooper; 22 23 import java.util.concurrent.CountDownLatch; 24 import java.util.concurrent.TimeUnit; 25 26 /** 27 * Unit tests for {@link NtpTimeHelper}. 28 */ 29 @RunWith(RobolectricTestRunner.class) 30 @Presubmit 31 public class NtpTimeHelperTest { 32 33 private static final long MOCK_NTP_TIME = 1519930775453L; 34 @Mock 35 private NtpTrustedTime mMockNtpTrustedTime; 36 private NtpTimeHelper mNtpTimeHelper; 37 private CountDownLatch mCountDownLatch; 38 39 @Before setUp()40 public void setUp() throws Exception { 41 MockitoAnnotations.initMocks(this); 42 mCountDownLatch = new CountDownLatch(1); 43 InjectNtpTimeCallback callback = 44 (time, timeReference, uncertainty) -> { 45 assertThat(time).isEqualTo(MOCK_NTP_TIME); 46 mCountDownLatch.countDown(); 47 }; 48 mNtpTimeHelper = new NtpTimeHelper(RuntimeEnvironment.application, 49 Looper.myLooper(), 50 callback, mMockNtpTrustedTime); 51 } 52 53 @Test handleInjectNtpTime_cachedAgeLow_injectTime()54 public void handleInjectNtpTime_cachedAgeLow_injectTime() throws InterruptedException { 55 doReturn(NtpTimeHelper.NTP_INTERVAL - 1).when(mMockNtpTrustedTime).getCacheAge(); 56 doReturn(MOCK_NTP_TIME).when(mMockNtpTrustedTime).getCachedNtpTime(); 57 58 mNtpTimeHelper.retrieveAndInjectNtpTime(); 59 60 waitForTasksToBePostedOnHandlerAndRunThem(); 61 assertThat(mCountDownLatch.await(2, TimeUnit.SECONDS)).isTrue(); 62 } 63 64 @Test handleInjectNtpTime_injectTimeFailed_injectTimeDelayed()65 public void handleInjectNtpTime_injectTimeFailed_injectTimeDelayed() 66 throws InterruptedException { 67 doReturn(NtpTimeHelper.NTP_INTERVAL + 1).when(mMockNtpTrustedTime).getCacheAge(); 68 doReturn(false).when(mMockNtpTrustedTime).forceRefresh(); 69 70 mNtpTimeHelper.retrieveAndInjectNtpTime(); 71 waitForTasksToBePostedOnHandlerAndRunThem(); 72 assertThat(mCountDownLatch.await(2, TimeUnit.SECONDS)).isFalse(); 73 74 doReturn(true).when(mMockNtpTrustedTime).forceRefresh(); 75 doReturn(1L).when(mMockNtpTrustedTime).getCacheAge(); 76 doReturn(MOCK_NTP_TIME).when(mMockNtpTrustedTime).getCachedNtpTime(); 77 SystemClock.sleep(NtpTimeHelper.RETRY_INTERVAL); 78 79 waitForTasksToBePostedOnHandlerAndRunThem(); 80 assertThat(mCountDownLatch.await(2, TimeUnit.SECONDS)).isTrue(); 81 } 82 83 /** 84 * Since a thread is created in {@link NtpTimeHelper#retrieveAndInjectNtpTime} and the task to 85 * be verified is posted in the thread, we have to wait for the task to be posted and then it 86 * can be run. 87 */ waitForTasksToBePostedOnHandlerAndRunThem()88 private void waitForTasksToBePostedOnHandlerAndRunThem() throws InterruptedException { 89 mCountDownLatch.await(1, TimeUnit.SECONDS); 90 ShadowLooper.runUiThreadTasks(); 91 } 92 } 93 94