1 // Copyright 2019 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // 5 package org.chromium.base.test.util; 6 7 import android.os.Debug; 8 9 /** 10 * Encapsulates timeout logic, and disables timeouts when debugger is attached. 11 */ 12 public class TimeoutTimer { 13 private static final boolean IS_REAL_ANDROID = 14 System.getProperty("java.class.path").endsWith(".apk"); 15 private static final long MS_TO_NANO = 1000000; 16 private final long mEndTimeNano; 17 private final long mTimeoutMs; 18 19 static { 20 if (!IS_REAL_ANDROID) { 21 try { 22 // BaseRobolectricTestRunner marks this class as "DoNotAcquire" so that 23 // System.nanoTime() will not return fake time. 24 Class.forName("android.os.Debug"); 25 assert false : "Cannot use TimeoutTimer without using BaseRobolectricTestRunner"; 26 } catch (Throwable e) { 27 } 28 } 29 } 30 31 /** 32 * @param timeoutMs Relative time for the timeout (unscaled). 33 */ TimeoutTimer(long timeoutMs)34 public TimeoutTimer(long timeoutMs) { 35 mTimeoutMs = ScalableTimeout.scaleTimeout(timeoutMs); 36 mEndTimeNano = System.nanoTime() + mTimeoutMs * MS_TO_NANO; 37 } 38 39 /** Whether this timer has expired. */ isTimedOut()40 public boolean isTimedOut() { 41 return getRemainingMs() == 0; 42 } 43 shouldPauseTimeouts()44 private static boolean shouldPauseTimeouts() { 45 if (IS_REAL_ANDROID) { 46 return Debug.isDebuggerConnected(); 47 } 48 // Our test runner sets this when --wait-for-java-debugger is passed. 49 // This will cause tests to never time out since the value is not updated when debugger 50 // detaches (oh well). 51 return "true".equals(System.getProperty("chromium.jdwp_active")); 52 } 53 54 /** Returns how much time is left in milliseconds. */ getRemainingMs()55 public long getRemainingMs() { 56 if (shouldPauseTimeouts()) { 57 // Never decreases, but still short enough that it's safe to wait() on and have a 58 // timeout happen once the debugger detaches. 59 return mTimeoutMs; 60 } 61 long ret = mEndTimeNano - System.nanoTime(); 62 return ret < 0 ? 0 : ret / MS_TO_NANO; 63 } 64 } 65