1 package android.hardware.cts.helpers;
2 
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.Timer;
6 import java.util.TimerTask;
7 import java.util.concurrent.CountDownLatch;
8 import java.util.concurrent.TimeUnit;
9 
10 import android.hardware.Sensor;
11 import android.hardware.TriggerEvent;
12 import android.hardware.TriggerEventListener;
13 import android.os.Handler;
14 import android.os.SystemClock;
15 import android.util.Log;
16 
17 import junit.framework.Assert;
18 
19 public class SuspendStateMonitor extends TimerTask {
20     private final double firstRealTimeMillis;
21     private final double firstUpTimeMillis;
22     private double lastSleepTimeSeconds = 0;
23     private volatile long lastWakeUpTime = 0;
24     Timer sleepMonitoringTimer = new Timer();
25     private final List<CountDownLatch> mWaitForWakeUpLatch = new ArrayList<>();
26     private final String TAG = "SensorCTSDeviceSuspendMonitor";
27 
28     /**
29      * Returns the time the device slept since the start of the application,
30      * in seconds.
31      */
getSleepTimeSeconds()32     public double getSleepTimeSeconds() {
33         double totalSinceStart = android.os.SystemClock.elapsedRealtime() - firstRealTimeMillis;
34         double upTimeSinceStart = android.os.SystemClock.uptimeMillis() - firstUpTimeMillis;
35         return (totalSinceStart - upTimeSinceStart) / 1000;
36     }
37 
getLastWakeUpTime()38     public long getLastWakeUpTime() {
39         return lastWakeUpTime;
40     }
41 
42 
waitForWakeUp(int numSeconds)43     public void waitForWakeUp(int numSeconds) throws InterruptedException {
44         CountDownLatch latch = new CountDownLatch(1);
45         synchronized(mWaitForWakeUpLatch) {
46             mWaitForWakeUpLatch.add(latch);
47         }
48         if (numSeconds == -1) {
49             // Wait indefinitely.
50             latch.await();
51         } else {
52             // Wait for the specified number of seconds.
53             boolean countZero = latch.await(numSeconds, TimeUnit.SECONDS);
54             if (!countZero) {
55                Log.e(TAG, "Device did not enter suspend state.");
56             }
57         }
58     }
59 
60     /**
61      * Run every 100ms inside the TimerTask.
62      */
63     @Override
run()64     public void run() {
65         if (getSleepTimeSeconds() - lastSleepTimeSeconds > 0.1) {
66             lastSleepTimeSeconds = getSleepTimeSeconds();
67             lastWakeUpTime = SystemClock.elapsedRealtime();
68             // If any client is waiting for wake-up, call countDown to unblock it.
69             synchronized(mWaitForWakeUpLatch) {
70                 for (CountDownLatch latch : mWaitForWakeUpLatch) {
71                     latch.countDown();
72                 }
73             }
74         }
75     }
76 
SuspendStateMonitor()77     public SuspendStateMonitor() {
78         firstRealTimeMillis = android.os.SystemClock.elapsedRealtime();
79         firstUpTimeMillis = android.os.SystemClock.uptimeMillis();
80         // Every 100 miliseconds, check whether the device has slept.
81         sleepMonitoringTimer.schedule(this, 0, 100);
82     }
83 }
84