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