Mock clock and calendar time am: e5a9e7e38a am: 7f6c4239d2

Original change: https://android-review.googlesource.com/c/platform/packages/services/Iwlan/+/2218581

Change-Id: I11bef2e009a8078980c4997077e5386c34ba731a
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/src/com/google/android/iwlan/ErrorPolicyManager.java b/src/com/google/android/iwlan/ErrorPolicyManager.java
index 5cdf5cf..b2eedbd 100644
--- a/src/com/google/android/iwlan/ErrorPolicyManager.java
+++ b/src/com/google/android/iwlan/ErrorPolicyManager.java
@@ -531,10 +531,16 @@
         return selectedPolicy;
     }
 
-    private void initHandler() {
+    @VisibleForTesting
+    void initHandler() {
+        mHandler = new EpmHandler(getLooper());
+    }
+
+    @VisibleForTesting
+    Looper getLooper() {
         mHandlerThread = new HandlerThread("ErrorPolicyManagerThread");
         mHandlerThread.start();
-        mHandler = new EpmHandler(mHandlerThread.getLooper());
+        return mHandlerThread.getLooper();
     }
 
     private String getDefaultJSONConfig() throws IOException {
diff --git a/test/com/google/android/iwlan/ErrorPolicyManagerTest.java b/test/com/google/android/iwlan/ErrorPolicyManagerTest.java
index 13a51a3..a4539e5 100644
--- a/test/com/google/android/iwlan/ErrorPolicyManagerTest.java
+++ b/test/com/google/android/iwlan/ErrorPolicyManagerTest.java
@@ -30,6 +30,7 @@
 import android.content.res.AssetManager;
 import android.net.ipsec.ike.exceptions.IkeProtocolException;
 import android.os.PersistableBundle;
+import android.os.test.TestLooper;
 import android.telephony.CarrierConfigManager;
 import android.telephony.DataFailCause;
 import android.telephony.SubscriptionInfo;
@@ -60,6 +61,9 @@
     private static final int DEFAULT_SUBID = 0;
     private static final int TEST_CARRIER_ID = 1;
 
+    private TestLooper mTestLooper = new TestLooper();
+    private long mMockedClockTime = 0;
+
     @Mock private Context mMockContext;
     @Mock CarrierConfigManager mMockCarrierConfigManager;
     @Mock SubscriptionManager mMockSubscriptionManager;
@@ -75,10 +79,12 @@
         mStaticMockSession =
                 mockitoSession()
                         .mockStatic(IwlanDataService.class)
+                        .spyStatic(IwlanHelper.class)
                         .strictness(Strictness.LENIENT)
                         .startMocking();
         when(IwlanDataService.getDataServiceProvider(anyInt()))
                 .thenReturn(mMockDataServiceProvider);
+        when(IwlanHelper.elapsedRealtime()).thenAnswer(i -> mMockedClockTime);
         AssetManager mockAssetManager = mock(AssetManager.class);
         Context context = InstrumentationRegistry.getTargetContext();
         InputStream is = context.getResources().getAssets().open("defaultiwlanerrorconfig.json");
@@ -87,6 +93,8 @@
         setupMockForCarrierConfig(null);
         ErrorPolicyManager.resetAllInstances();
         mErrorPolicyManager = spy(ErrorPolicyManager.getInstance(mMockContext, DEFAULT_SLOT_INDEX));
+        doReturn(mTestLooper.getLooper()).when(mErrorPolicyManager).getLooper();
+        mErrorPolicyManager.initHandler();
     }
 
     @After
@@ -144,8 +152,7 @@
                 .mHandler
                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
                 .sendToTarget();
-
-        sleep(1000);
+        mTestLooper.dispatchAll();
 
         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4,8,16
         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
@@ -215,8 +222,7 @@
                 .mHandler
                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
                 .sendToTarget();
-
-        sleep(1000);
+        mTestLooper.dispatchAll();
 
         // Fallback to default Iwlan error policy for IKE_PROTOCOL_ERROR_TYPE(24) because of failed
         // parsing (or lack of explicit carrier-defined policy).
@@ -278,8 +284,7 @@
                 .mHandler
                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
                 .sendToTarget();
-
-        sleep(1000);
+        mTestLooper.dispatchAll();
 
         mErrorPolicyManager.logErrorPolicies();
 
@@ -332,8 +337,7 @@
                 .mHandler
                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
                 .sendToTarget();
-
-        sleep(1000);
+        mTestLooper.dispatchAll();
 
         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4,8,16
         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
@@ -343,7 +347,7 @@
         boolean bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
         assertFalse(bringUpTunnel);
 
-        sleep(4000);
+        advanceClockByTimeMs(4000);
 
         bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
         assertTrue(bringUpTunnel);
@@ -384,8 +388,7 @@
                 .mHandler
                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
                 .sendToTarget();
-
-        sleep(1000);
+        mTestLooper.dispatchAll();
 
         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4,8,16
         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
@@ -431,7 +434,7 @@
                 .mHandler
                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
                 .sendToTarget();
-        sleep(1000);
+        mTestLooper.dispatchAll();
 
         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 6, 12, 24
         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
@@ -442,7 +445,7 @@
                 .mHandler
                 .obtainMessage(IwlanEventListener.WIFI_DISABLE_EVENT)
                 .sendToTarget();
-        sleep(500);
+        advanceClockByTimeMs(500);
         verify(mMockDataServiceProvider, times(1)).notifyApnUnthrottled(eq(apn));
 
         boolean bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
@@ -482,7 +485,7 @@
                 .mHandler
                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
                 .sendToTarget();
-        sleep(1000);
+        mTestLooper.dispatchAll();
 
         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 6, 12, 24
         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
@@ -493,7 +496,7 @@
                 .mHandler
                 .obtainMessage(IwlanEventListener.WIFI_CALLING_DISABLE_EVENT)
                 .sendToTarget();
-        sleep(500);
+        advanceClockByTimeMs(500);
         verify(mMockDataServiceProvider, times(1)).notifyApnUnthrottled(eq(apn));
 
         boolean bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
@@ -533,7 +536,7 @@
                 .mHandler
                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
                 .sendToTarget();
-        sleep(1000);
+        mTestLooper.dispatchAll();
 
         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4,8,16
         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
@@ -544,7 +547,7 @@
                 .mHandler
                 .obtainMessage(IwlanEventListener.APM_ENABLE_EVENT)
                 .sendToTarget();
-        sleep(500);
+        advanceClockByTimeMs(500);
         verify(mMockDataServiceProvider, times(1)).notifyApnUnthrottled(eq(apn));
 
         boolean bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
@@ -585,8 +588,7 @@
                 .mHandler
                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
                 .sendToTarget();
-
-        sleep(1000);
+        mTestLooper.dispatchAll();
 
         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4,8,16
         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
@@ -643,8 +645,7 @@
                 .mHandler
                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
                 .sendToTarget();
-
-        sleep(1000);
+        mTestLooper.dispatchAll();
 
         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4,8,16
         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
@@ -653,9 +654,9 @@
         time = Math.round((double) mErrorPolicyManager.getCurrentRetryTimeMs(apn) / 1000);
         assertEquals(time, 2);
 
-        // sleep for 2 seconds and make sure that we can bring up tunnel after 2 secs
+        // advanceClockByTimeMs for 2 seconds and make sure that we can bring up tunnel after 2 secs
         // as back off time - 2 secs should override the retry time in policy - 10 secs
-        sleep(2000);
+        advanceClockByTimeMs(2000);
         boolean bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
         assertTrue(bringUpTunnel);
 
@@ -709,8 +710,7 @@
                 .mHandler
                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
                 .sendToTarget();
-
-        sleep(1000);
+        mTestLooper.dispatchAll();
         assertEquals(DataFailCause.NONE, mErrorPolicyManager.getMostRecentDataFailCause());
 
         // IKE_PROTOCOL_ERROR_TYPE(15500)
@@ -840,12 +840,9 @@
                 + "\"]";
     }
 
-    private void sleep(long time) {
-        try {
-            Thread.sleep(time);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+    private void advanceClockByTimeMs(long time) {
+        mMockedClockTime += time;
+        mTestLooper.dispatchAll();
     }
 
     private void setupMockForCarrierConfig(PersistableBundle bundle) {
diff --git a/test/com/google/android/iwlan/IwlanDataServiceTest.java b/test/com/google/android/iwlan/IwlanDataServiceTest.java
index 1d92737..3a7e0af 100644
--- a/test/com/google/android/iwlan/IwlanDataServiceTest.java
+++ b/test/com/google/android/iwlan/IwlanDataServiceTest.java
@@ -58,7 +58,6 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
@@ -117,6 +116,7 @@
     private IwlanDataServiceProvider mIwlanDataServiceProvider;
     private IwlanDataServiceProvider mSpyIwlanDataServiceProvider;
     private TestLooper mTestLooper = new TestLooper();
+    private long mMockedCalendarTime;
 
     private final class IwlanDataServiceCallback extends IDataServiceCallback.Stub {
 
@@ -218,6 +218,7 @@
                         mIwlanDataService.onCreateDataServiceProvider(DEFAULT_SLOT_INDEX);
         mTestLooper.dispatchAll();
         mSpyIwlanDataServiceProvider = spy(mIwlanDataServiceProvider);
+        when(Calendar.getInstance().getTime()).thenAnswer(i -> mMockedCalendarTime);
     }
 
     @After
@@ -690,12 +691,9 @@
                         isNull());
     }
 
-    private void sleep(long time) {
-        try {
-            Thread.sleep(time);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+    private void advanceCalendarByTimeMs(long time) {
+        mMockedCalendarTime += time;
+        mTestLooper.dispatchAll();
     }
 
     private DataProfile buildDataProfile() {
@@ -821,7 +819,7 @@
         long count = 3L;
         for (int i = 0; i < count; i++) {
             mockTunnelSetupFail(dp);
-            sleep(1000);
+            mTestLooper.dispatchAll();
         }
 
         IwlanDataServiceProvider.IwlanDataTunnelStats stats =
@@ -850,7 +848,6 @@
     }
 
     @Test
-    @Ignore("b/244615746- Avoid using real-world time to eliminate flaky unit tests")
     public void testIwlanTunnelStats() {
         DataProfile dp = buildDataProfile();
 
@@ -863,7 +860,7 @@
         Date beforeSetup = Calendar.getInstance().getTime();
         mockTunnelSetupSuccess(dp, 0);
         Date tunnelUp = Calendar.getInstance().getTime();
-        mockDeactivateTunnelDown(0);
+        mockDeactivateTunnel(0);
         Date tunnelDown = Calendar.getInstance().getTime();
         tunnelSetupSuccessStats.accept(tunnelUp.getTime() - beforeSetup.getTime());
         tunnelUpStats.accept(tunnelDown.getTime() - tunnelUp.getTime());
@@ -871,7 +868,7 @@
         beforeSetup = Calendar.getInstance().getTime();
         mockTunnelSetupSuccess(dp, 1000);
         tunnelUp = Calendar.getInstance().getTime();
-        mockDeactivateTunnelDown(3000);
+        mockDeactivateTunnel(3000);
         tunnelDown = Calendar.getInstance().getTime();
         tunnelSetupSuccessStats.accept(tunnelUp.getTime() - beforeSetup.getTime());
         tunnelUpStats.accept(tunnelDown.getTime() - tunnelUp.getTime());
@@ -879,7 +876,7 @@
         beforeSetup = Calendar.getInstance().getTime();
         mockTunnelSetupSuccess(dp, 600);
         tunnelUp = Calendar.getInstance().getTime();
-        mockDeactivateTunnelDown(500);
+        mockDeactivateTunnel(500);
         tunnelDown = Calendar.getInstance().getTime();
         tunnelSetupSuccessStats.accept(tunnelUp.getTime() - beforeSetup.getTime());
         tunnelUpStats.accept(tunnelDown.getTime() - tunnelUp.getTime());
@@ -924,7 +921,7 @@
                         eq(DataServiceCallback.RESULT_SUCCESS), any(DataCallResponse.class));
     }
 
-    private void mockTunnelSetupSuccess(DataProfile dp, long sleepTime) {
+    private void mockTunnelSetupSuccess(DataProfile dp, long setupTime) {
         mSpyIwlanDataServiceProvider.setupDataCall(
                 AccessNetworkType.IWLAN, /* AccessNetworkType */
                 dp, /* dataProfile */
@@ -942,7 +939,7 @@
                 .bringUpTunnel(any(TunnelSetupRequest.class), any(IwlanTunnelCallback.class));
         mTestLooper.dispatchAll();
 
-        sleep(sleepTime);
+        advanceCalendarByTimeMs(setupTime);
 
         mSpyIwlanDataServiceProvider
                 .getIwlanTunnelCallback()
@@ -960,7 +957,7 @@
         mTestLooper.dispatchAll();
     }
 
-    private void mockDeactivateTunnelDown(long sleepTime) {
+    private void mockDeactivateTunnel(long deactivationTime) {
         mSpyIwlanDataServiceProvider.deactivateDataCall(
                 TEST_APN_NAME.hashCode() /* cid: hashcode() of "ims" */,
                 DataService.REQUEST_REASON_NORMAL /* DataService.REQUEST_REASON_NORMAL */,
@@ -968,7 +965,7 @@
         mTestLooper.dispatchAll();
         verify(mMockEpdgTunnelManager, atLeastOnce()).closeTunnel(eq(TEST_APN_NAME), anyBoolean());
 
-        sleep(sleepTime);
+        advanceCalendarByTimeMs(deactivationTime);
 
         mSpyIwlanDataServiceProvider
                 .getIwlanTunnelCallback()