Support HAL callback with args.
-Rename vts_tcp_server to callback_server.
-Clean up existing code to properly manage the lifecycle of each
component.
+ Properly shut down the server.
+ Properly cleans up resources held by AndroidDevice, including
hal and callback server.
-Add input args support to callback functions.
-Improve resource management in android_device controller module.
-Update the generated AndroidSystemControlMessage_pb2.py
-Fix a bug in mirror_object's arg parsing.
Bug=29420383
Change-Id: Iaa2ce3526dad5c240aceafc4fb7d285c8bb3ee9c
diff --git a/utils/python/controllers/android_device.py b/utils/python/controllers/android_device.py
index 431cf07..b739ac8 100644
--- a/utils/python/controllers/android_device.py
+++ b/utils/python/controllers/android_device.py
@@ -61,6 +61,15 @@
def create(configs):
+ """Creates AndroidDevice controller objects.
+
+ Args:
+ configs: A list of dicts, each representing a configuration for an
+ Android device.
+
+ Returns:
+ A list of AndroidDevice objects.
+ """
if not configs:
raise AndroidDeviceError(ANDROID_DEVICE_EMPTY_CONFIG_MSG)
elif configs == ANDROID_DEVICE_PICK_ALL_TOKEN:
@@ -77,19 +86,43 @@
for ad in ads:
if ad.serial not in connected_ads:
- raise AndroidDeviceError(
- ("Android device %s is specified in config"
- " but is not attached.") % ad.serial)
- ad.startAdbLogcat()
- ad.startVtsAgent()
+ raise DoesNotExistError(("Android device %s is specified in config"
+ " but is not attached.") % ad.serial)
+ _startServicesOnAds(ads)
return ads
def destroy(ads):
+ """Cleans up AndroidDevice objects.
+
+ Args:
+ ads: A list of AndroidDevice objects.
+ """
for ad in ads:
- ad.stopVtsAgent()
- if ad.adb_logcat_process:
- ad.stopAdbLogcat()
+ try:
+ ad.cleanUp()
+ except:
+ ad.log.exception("Failed to clean up properly.")
+
+
+def _startServicesOnAds(ads):
+ """Starts long running services on multiple AndroidDevice objects.
+
+ If any one AndroidDevice object fails to start services, cleans up all
+ existing AndroidDevice objects and their services.
+
+ Args:
+ ads: A list of AndroidDevice objects whose services to start.
+ """
+ running_ads = []
+ for ad in ads:
+ running_ads.append(ad)
+ try:
+ ad.start_services()
+ except:
+ ad.log.exception("Failed to start some services, abort!")
+ destroy(running_ads)
+ raise
def _parse_device_list(device_list_str, key):
@@ -272,10 +305,8 @@
class AndroidDevice(object):
"""Class representing an android device.
- Each object of this class represents one Android device in ACTS, including
- handles to adb, fastboot, and sl4a clients. In addition to direct adb
- commands, this object also uses adb port forwarding to talk to the Android
- device.
+ Each object of this class represents one Android device. The object holds
+ handles to adb, fastboot, and various RPC clients.
Attributes:
serial: A string that's the serial number of the Androi device.
@@ -298,6 +329,10 @@
(to send commands and receive responses).
host_callback_port: the host-side port for agent to runner sessions
(to get callbacks from agent).
+ hal: HalMirror, in charge of all communications with the HAL layer.
+ lib: LibMirror, in charge of all communications with static and shared
+ native libs.
+ shell: ShellMirror, in charge of all communications with shell.
"""
def __init__(self, serial="", device_port=5001, device_callback_port=5010):
@@ -320,16 +355,20 @@
self.adb.tcp_forward(self.host_command_port, self.device_command_port)
self.adb.reverse_tcp_forward(self.device_callback_port,
self.host_callback_port)
- self.hal = hal_mirror.HalMirror(self.host_command_port,
- self.host_callback_port)
+ self.hal = None
self.lib = lib_mirror.LibMirror(self.host_command_port)
self.shell = shell_mirror.ShellMirror(self.host_command_port)
def __del__(self):
+ self.cleanUp()
+
+ def cleanUp(self):
+ """Cleans up the AndroidDevice object and releases any resources it
+ claimed.
+ """
+ self.stopServices()
if self.host_command_port:
self.adb.forward("--remove tcp:%s" % self.host_command_port)
- if self.adb_logcat_process:
- self.stopAdbLogcat()
@property
def isBootloaderMode(self):
@@ -501,6 +540,31 @@
if has_vts_agent:
self.startVtsAgent()
+ def startServices(self):
+ """Starts long running services on the android device.
+
+ 1. Start adb logcat capture.
+ 2. Start VtsAgent.
+ 3. Create HalMirror
+ """
+ try:
+ self.startAdbLogcat()
+ except:
+ self.log.exception("Failed to start adb logcat!")
+ raise
+ self.startVtsAgent()
+ self.hal = hal_mirror.HalMirror(self.host_command_port,
+ self.host_callback_port)
+
+ def stopServices(self):
+ """Stops long running services on the android device.
+ """
+ if self.adb_logcat_process:
+ self.stopAdbLogcat()
+ self.stopVtsAgent()
+ if self.hal:
+ self.hal.CleanUp()
+
def startVtsAgent(self):
"""Start HAL agent on the AndroidDevice.
@@ -514,7 +578,8 @@
cleanup_commands = [
"rm -f /data/local/tmp/vts_driver_*",
- "rm -f /data/local/tmp/vts_agent_callback*"]
+ "rm -f /data/local/tmp/vts_agent_callback*"
+ ]
kill_commands = ["killall vts_hal_agent", "killall fuzzer32",
"killall fuzzer64", "killall vts_shell_driver32",
"killall vts_shell_driver64"]
@@ -524,14 +589,16 @@
"chmod 755 %s/32/fuzzer32" % DEFAULT_AGENT_BASE_DIR,
"chmod 755 %s/64/fuzzer64" % DEFAULT_AGENT_BASE_DIR,
"chmod 755 %s/32/vts_shell_driver32" % DEFAULT_AGENT_BASE_DIR,
- "chmod 755 %s/64/vts_shell_driver64" % DEFAULT_AGENT_BASE_DIR]
+ "chmod 755 %s/64/vts_shell_driver64" % DEFAULT_AGENT_BASE_DIR
+ ]
cleanup_commands.extend(chmod_commands)
for cmd in cleanup_commands:
try:
self.adb.shell(cmd)
except adb.AdbError as e:
self.log.warning(
- "A command to setup the env to start the VTS Agent failed %s", e)
+ "A command to setup the env to start the VTS Agent failed %s",
+ e)
vts_agent_log_path = os.path.join(self.log_path, "vts_agent.log")
cmd = (
'adb -s {s} shell LD_LIBRARY_PATH={path}/64 {path}/64/vts_hal_agent'
@@ -541,7 +608,8 @@
path=DEFAULT_AGENT_BASE_DIR,
log=vts_agent_log_path)
self.vts_agent_process = utils.start_standing_subprocess(
- cmd, check_health_delay=1)
+ cmd,
+ check_health_delay=1)
def stopVtsAgent(self):
"""Stop the HAL agent running on the AndroidDevice.