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