From 4abbe7602a6ae9bb1b96fe409098763444bcd844 Mon Sep 17 00:00:00 2001
From: Sascha Bischoff <sascha.bischoff@arm.com>
Date: Thu, 2 Mar 2017 11:00:49 +0000
Subject: [PATCH] Extend device with sleep functionality

This changeset adds the ability to sleep on the device via a
device.sleep() method. This invokes sleep on the target device. This
is useful for situations where the passage of time on the target
device does not match that of the host, e.g., gem5.

This changeset also updates a number of workloads to use this new
sleep method.
---
 wlauto/core/device.py                   | 13 +++++++++++++
 wlauto/workloads/apklaunch/__init__.py  |  4 +---
 wlauto/workloads/applaunch/__init__.py  |  2 --
 wlauto/workloads/audio/__init__.py      |  3 +--
 wlauto/workloads/bbench/__init__.py     |  7 +++----
 wlauto/workloads/citadel/__init__.py    |  4 +---
 wlauto/workloads/cyclictest/__init__.py |  1 -
 wlauto/workloads/facebook/__init__.py   |  3 +--
 wlauto/workloads/glbcorp/__init__.py    |  5 ++---
 wlauto/workloads/homescreen/__init__.py |  4 +---
 wlauto/workloads/idle/__init__.py       |  8 +++-----
 wlauto/workloads/manual/__init__.py     |  3 +--
 wlauto/workloads/nenamark/__init__.py   |  5 ++---
 wlauto/workloads/thechase/__init__.py   |  4 +---
 wlauto/workloads/video/__init__.py      |  3 +--
 15 files changed, 31 insertions(+), 38 deletions(-)

diff --git a/wlauto/core/device.py b/wlauto/core/device.py
index 5441bad2..3fcf811f 100644
--- a/wlauto/core/device.py
+++ b/wlauto/core/device.py
@@ -381,6 +381,19 @@ class Device(Extension):
         """
         raise NotImplementedError()
 
+    def sleep(self, seconds):
+        """Sleep for the specified time on the target device.
+
+        :param seconds: Time in seconds to sleep on the device
+
+        The sleep is executed on the device using self.execute(). We
+        set the timeout for this command to be 10 seconds longer than
+        the sleep itself to make sure the command has time to complete
+        before we timeout.
+
+        """
+        self.execute("sleep {}".format(seconds), timeout=seconds + 10)
+
     def set_sysfile_value(self, filepath, value, verify=True):
         """
         Write the specified value to the specified file on the device
diff --git a/wlauto/workloads/apklaunch/__init__.py b/wlauto/workloads/apklaunch/__init__.py
index 6dc201fc..f1fc996a 100644
--- a/wlauto/workloads/apklaunch/__init__.py
+++ b/wlauto/workloads/apklaunch/__init__.py
@@ -15,8 +15,6 @@
 # pylint: disable=attribute-defined-outside-init
 import os
 
-from time import sleep
-
 from wlauto import Workload, Parameter
 from wlauto import File
 from wlauto.exceptions import ConfigError
@@ -51,7 +49,7 @@ class ApkLaunchWorkload(Workload):
         self.device.execute('am start -W {}'.format(self.package))
 
         self.logger.info('Waiting {} seconds'.format(self.wait_time_seconds))
-        sleep(self.wait_time_seconds)
+        self.device.sleep(self.wait_time_seconds)
 
     def update_result(self, context):
         app_is_running = bool([p for p in self.device.ps() if p.name == self.package])
diff --git a/wlauto/workloads/applaunch/__init__.py b/wlauto/workloads/applaunch/__init__.py
index 4323ad29..546825df 100644
--- a/wlauto/workloads/applaunch/__init__.py
+++ b/wlauto/workloads/applaunch/__init__.py
@@ -15,8 +15,6 @@
 # pylint: disable=attribute-defined-outside-init
 import os
 
-from time import sleep
-
 from wlauto import Workload, AndroidBenchmark, AndroidUxPerfWorkload, UiAutomatorWorkload
 from wlauto import Parameter
 from wlauto import ExtensionLoader
diff --git a/wlauto/workloads/audio/__init__.py b/wlauto/workloads/audio/__init__.py
index 6487733f..59dab066 100644
--- a/wlauto/workloads/audio/__init__.py
+++ b/wlauto/workloads/audio/__init__.py
@@ -14,7 +14,6 @@
 #
 # pylint: disable=E1101,W0201
 import os
-import time
 import urllib
 
 from wlauto import settings, Workload, Parameter
@@ -70,7 +69,7 @@ class Audio(Workload):
         self.device.execute('am start -W -S -n com.android.music/.MediaPlaybackActivity -d {}'.format(self.on_device_file))
 
     def run(self, context):
-        time.sleep(self.duration)
+        self.device.sleep(self.duration)
 
     def update_result(self, context):
         # Stop the audio
diff --git a/wlauto/workloads/bbench/__init__.py b/wlauto/workloads/bbench/__init__.py
index 94161f44..918362d4 100644
--- a/wlauto/workloads/bbench/__init__.py
+++ b/wlauto/workloads/bbench/__init__.py
@@ -14,7 +14,6 @@
 #
 # pylint: disable=E1101,W0201
 import os
-import time
 import urllib
 import tarfile
 import shutil
@@ -107,11 +106,11 @@ class BBench(Workload):
 
         # Open the browser with default page
         self.device.execute('am start -n  {}/{} about:blank'.format(self.browser_package, self.browser_activity))
-        time.sleep(5)
+        self.device.sleep(5)
 
         # Stop the browser if already running and wait for it to stop
         self.device.execute('am force-stop {}'.format(self.browser_package))
-        time.sleep(5)
+        self.device.sleep(5)
 
         # Clear the logs
         self.device.clear_logcat()
@@ -134,7 +133,7 @@ class BBench(Workload):
     def run(self, context):
         # Launch the bbench
         self.device.execute('am start -n  {}/{} {}'.format(self.browser_package, self.browser_activity, self.index_noinput))
-        time.sleep(5)  # WA1 parity
+        self.device.sleep(5)  # WA1 parity
         # Launch the server waiting for Bbench to complete
         self.device.execute(self.luanch_server_command, self.server_timeout)
 
diff --git a/wlauto/workloads/citadel/__init__.py b/wlauto/workloads/citadel/__init__.py
index 71b433b9..2dd6098c 100644
--- a/wlauto/workloads/citadel/__init__.py
+++ b/wlauto/workloads/citadel/__init__.py
@@ -14,8 +14,6 @@
 #
 
 # pylint: disable=E1101
-import time
-
 from wlauto import GameWorkload, Parameter
 
 
@@ -41,4 +39,4 @@ class EpicCitadel(GameWorkload):
 
     def run(self, context):
         super(EpicCitadel, self).run(context)
-        time.sleep(self.duration)
+        self.device.sleep(self.duration)
diff --git a/wlauto/workloads/cyclictest/__init__.py b/wlauto/workloads/cyclictest/__init__.py
index c7d2e36e..e26ee0c7 100644
--- a/wlauto/workloads/cyclictest/__init__.py
+++ b/wlauto/workloads/cyclictest/__init__.py
@@ -16,7 +16,6 @@
 # pylint: disable=attribute-defined-outside-init
 
 import os
-import time
 
 from wlauto import settings, Workload, Executable, Parameter
 from wlauto.exceptions import ConfigError, WorkloadError
diff --git a/wlauto/workloads/facebook/__init__.py b/wlauto/workloads/facebook/__init__.py
index 9f456ee3..a78832da 100644
--- a/wlauto/workloads/facebook/__init__.py
+++ b/wlauto/workloads/facebook/__init__.py
@@ -15,7 +15,6 @@
 
 
 import os
-import time
 import sys
 
 from wlauto import AndroidUiAutoBenchmark
@@ -68,7 +67,7 @@ class Facebook(AndroidUiAutoBenchmark):
 
         #Start the disable update workload
         self.device.execute(command, self.du_run_timeout)
-        time.sleep(self.DELAY)
+        self.device.sleep(self.DELAY)
 
         #Stop the play store activity
         self.device.execute('am force-stop com.android.vending')
diff --git a/wlauto/workloads/glbcorp/__init__.py b/wlauto/workloads/glbcorp/__init__.py
index 449ab57f..3fe0c7b8 100644
--- a/wlauto/workloads/glbcorp/__init__.py
+++ b/wlauto/workloads/glbcorp/__init__.py
@@ -18,7 +18,6 @@
 from __future__ import division
 import os
 import re
-import time
 import select
 import json
 import threading
@@ -122,7 +121,7 @@ class GlbCorp(ApkWorkload):
                 raise WorkloadError(result)
             else:
                 self.logger.debug(result)
-            time.sleep(DELAY)
+            self.device.sleep(DELAY)
             self.monitor.wait_for_run_end(self.run_timeout)
 
     def update_result(self, context):  # NOQA
@@ -209,7 +208,7 @@ class GlbRunMonitor(threading.Thread):
         proc = subprocess.Popen(self.command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         while not self.stop_event.is_set():
             if self.run_ended.is_set():
-                time.sleep(DELAY)
+                self.device.sleep(DELAY)
             else:
                 ready, _, _ = select.select([proc.stdout, proc.stderr], [], [], 2)
                 if ready:
diff --git a/wlauto/workloads/homescreen/__init__.py b/wlauto/workloads/homescreen/__init__.py
index 737d435b..94cf912b 100644
--- a/wlauto/workloads/homescreen/__init__.py
+++ b/wlauto/workloads/homescreen/__init__.py
@@ -15,8 +15,6 @@
 
 # pylint: disable=E1101
 
-import time
-
 from wlauto import Workload, Parameter
 
 
@@ -40,4 +38,4 @@ class HomeScreen(Workload):
         self.device.execute('input keyevent 3')  # press the home key
 
     def run(self, context):
-        time.sleep(self.duration)
+        self.device.sleep(self.duration)
diff --git a/wlauto/workloads/idle/__init__.py b/wlauto/workloads/idle/__init__.py
index 8c85a289..9fe4c021 100644
--- a/wlauto/workloads/idle/__init__.py
+++ b/wlauto/workloads/idle/__init__.py
@@ -15,8 +15,6 @@
 
 # pylint: disable=E1101
 
-import time
-
 from wlauto import Workload, Parameter
 from wlauto.exceptions import WorkloadError, ConfigError
 
@@ -56,13 +54,13 @@ class IdleWorkload(Workload):
             self.device.execute('stop && sleep {} && start'.format(self.duration),
                                 timeout=timeout, as_root=True)
         else:
-            time.sleep(self.duration)
+            self.device.sleep(self.duration)
 
     def teardown(self, context):
         if self.stop_android:
             self.logger.debug('Waiting for Android restart to complete...')
             # Wait for the boot animation to start and then to finish.
             while self.device.execute('getprop init.svc.bootanim').strip() == 'stopped':
-                time.sleep(0.2)
+                self.device.sleep(0.2)
             while self.device.execute('getprop init.svc.bootanim').strip() == 'running':
-                time.sleep(1)
+                self.device.sleep(1)
diff --git a/wlauto/workloads/manual/__init__.py b/wlauto/workloads/manual/__init__.py
index 8edeefd6..05e91f97 100644
--- a/wlauto/workloads/manual/__init__.py
+++ b/wlauto/workloads/manual/__init__.py
@@ -14,7 +14,6 @@
 #
 # pylint: disable=E1101,W0201,E0203
 import os
-import time
 
 from wlauto import Workload, Parameter
 from wlauto.exceptions import ConfigError
@@ -74,7 +73,7 @@ class ManualWorkload(Workload):
     def run(self, context):
         self.logger.info('START NOW!')
         if self.duration:
-            time.sleep(self.duration)
+            self.device.sleep(self.duration)
         elif self.user_triggered:
             self.logger.info('')
             self.logger.info('hit any key to end your workload execution...')
diff --git a/wlauto/workloads/nenamark/__init__.py b/wlauto/workloads/nenamark/__init__.py
index 351dcb91..b34b6f8b 100644
--- a/wlauto/workloads/nenamark/__init__.py
+++ b/wlauto/workloads/nenamark/__init__.py
@@ -16,7 +16,6 @@
 
 import os
 import re
-import time
 
 from wlauto import AndroidBenchmark, Parameter
 
@@ -50,9 +49,9 @@ class Nenamark(AndroidBenchmark):
     regex = re.compile('.*NenaMark2.*Score.*?([0-9\.]*)fps')
 
     def run(self, context):
-        time.sleep(5)  # wait for nenamark menu to show up
+        self.device.sleep(5)  # wait for nenamark menu to show up
         self.device.execute('input keyevent 23')
-        time.sleep(self.duration)
+        self.device.sleep(self.duration)
 
     def update_result(self, context):
         super(Nenamark, self).update_result(context)
diff --git a/wlauto/workloads/thechase/__init__.py b/wlauto/workloads/thechase/__init__.py
index 947fc673..b3cc1050 100755
--- a/wlauto/workloads/thechase/__init__.py
+++ b/wlauto/workloads/thechase/__init__.py
@@ -14,8 +14,6 @@
 #
 
 # pylint: disable=E1101
-import time
-
 from wlauto import ApkWorkload, Parameter
 
 
@@ -42,4 +40,4 @@ class TheChase(ApkWorkload):
     ]
 
     def run(self, context):
-        time.sleep(self.duration)
+        self.device.sleep(self.duration)
diff --git a/wlauto/workloads/video/__init__.py b/wlauto/workloads/video/__init__.py
index 40824c4c..e2d1c535 100644
--- a/wlauto/workloads/video/__init__.py
+++ b/wlauto/workloads/video/__init__.py
@@ -16,7 +16,6 @@
 # pylint: disable=E1101,E0203,W0201
 
 import os
-import time
 import urllib
 from collections import defaultdict
 
@@ -114,7 +113,7 @@ class VideoWorkload(Workload):
         self.device.execute(command)
 
     def run(self, context):
-        time.sleep(self.play_duration)
+        self.device.sleep(self.play_duration)
 
     def update_result(self, context):
         self.device.execute('am force-stop com.android.gallery3d')