blob: 0a37c72c410d33e4818a9ae881264f825c211440 [file] [log] [blame]
Ang Li93420002016-05-10 19:11:44 -07001#!/usr/bin/env python3.4
2#
3# Copyright 2016 - The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17from builtins import str
18from builtins import open
19
Ang Li7f0e1c72016-06-14 11:23:49 -070020import logging
Ang Li93420002016-05-10 19:11:44 -070021import os
22import time
23import traceback
Sahil Jain06dd6a22016-06-24 13:47:37 -070024import threading
25import socket
26import Queue
Ang Li93420002016-05-10 19:11:44 -070027
28from vts.runners.host import logger as vts_logger
29from vts.runners.host import signals
30from vts.runners.host import utils
Ang Li7f0e1c72016-06-14 11:23:49 -070031from vts.utils.python.controllers import adb
32from vts.utils.python.controllers import event_dispatcher
33from vts.utils.python.controllers import fastboot
Sahil Jain06dd6a22016-06-24 13:47:37 -070034from vts.runners.host.tcp_client import vts_tcp_client
Ang Li7f0e1c72016-06-14 11:23:49 -070035from vts.utils.python.mirror import hal_mirror
Sahil Jain06dd6a22016-06-24 13:47:37 -070036from vts.runners.host import errors
37import subprocess
Ang Li93420002016-05-10 19:11:44 -070038
39VTS_CONTROLLER_CONFIG_NAME = "AndroidDevice"
40VTS_CONTROLLER_REFERENCE_NAME = "android_devices"
41
42ANDROID_DEVICE_PICK_ALL_TOKEN = "*"
43# Key name for adb logcat extra params in config file.
44ANDROID_DEVICE_ADB_LOGCAT_PARAM_KEY = "adb_logcat_param"
45ANDROID_DEVICE_EMPTY_CONFIG_MSG = "Configuration is empty, abort!"
46ANDROID_DEVICE_NOT_LIST_CONFIG_MSG = "Configuration should be a list, abort!"
47
Sahil Jain06dd6a22016-06-24 13:47:37 -070048# Target-side directory where the VTS binaries are uploaded
49DEFAULT_AGENT_BASE_DIR = "/data/local/tmp"
50# Time for which the current is put on sleep when the client is unable to
51# make a connection.
52THREAD_SLEEP_TIME = 1
53# Max number of attempts that the client can make to connect to the agent
54MAX_AGENT_CONNECT_RETRIES = 10
55
Ang Lie2139f12016-05-12 17:39:06 -070056
Ang Li93420002016-05-10 19:11:44 -070057class AndroidDeviceError(signals.ControllerError):
58 pass
59
Ang Lie2139f12016-05-12 17:39:06 -070060
Ang Li7f0e1c72016-06-14 11:23:49 -070061def create(configs):
Ang Li93420002016-05-10 19:11:44 -070062 if not configs:
63 raise AndroidDeviceError(ANDROID_DEVICE_EMPTY_CONFIG_MSG)
64 elif configs == ANDROID_DEVICE_PICK_ALL_TOKEN:
Ang Li7f0e1c72016-06-14 11:23:49 -070065 ads = get_all_instances()
Ang Li93420002016-05-10 19:11:44 -070066 elif not isinstance(configs, list):
67 raise AndroidDeviceError(ANDROID_DEVICE_NOT_LIST_CONFIG_MSG)
68 elif isinstance(configs[0], str):
69 # Configs is a list of serials.
Ang Li7f0e1c72016-06-14 11:23:49 -070070 ads = get_instances(configs)
Ang Li93420002016-05-10 19:11:44 -070071 else:
72 # Configs is a list of dicts.
Ang Li7f0e1c72016-06-14 11:23:49 -070073 ads = get_instances_with_configs(configs)
Ang Li93420002016-05-10 19:11:44 -070074 connected_ads = list_adb_devices()
75 for ad in ads:
76 if ad.serial not in connected_ads:
Ang Lie2139f12016-05-12 17:39:06 -070077 raise AndroidDeviceError(
78 ("Android device %s is specified in config"
79 " but is not attached.") % ad.serial)
Ang Li93420002016-05-10 19:11:44 -070080 ad.startAdbLogcat()
Ang Lie014a8b2016-06-28 18:24:52 -070081 ad.startVtsAgent()
Ang Li93420002016-05-10 19:11:44 -070082 return ads
83
Ang Lie2139f12016-05-12 17:39:06 -070084
Ang Li93420002016-05-10 19:11:44 -070085def destroy(ads):
86 for ad in ads:
Ang Lie014a8b2016-06-28 18:24:52 -070087 ad.stopVtsAgent()
Ang Li93420002016-05-10 19:11:44 -070088 if ad.adb_logcat_process:
89 ad.stopAdbLogcat()
90
Ang Lie2139f12016-05-12 17:39:06 -070091
Ang Li93420002016-05-10 19:11:44 -070092def _parse_device_list(device_list_str, key):
93 """Parses a byte string representing a list of devices. The string is
94 generated by calling either adb or fastboot.
95
96 Args:
97 device_list_str: Output of adb or fastboot.
98 key: The token that signifies a device in device_list_str.
99
100 Returns:
101 A list of android device serial numbers.
102 """
103 clean_lines = str(device_list_str, 'utf-8').strip().split('\n')
104 results = []
105 for line in clean_lines:
106 tokens = line.strip().split('\t')
107 if len(tokens) == 2 and tokens[1] == key:
108 results.append(tokens[0])
109 return results
110
Ang Lie2139f12016-05-12 17:39:06 -0700111
Ang Li93420002016-05-10 19:11:44 -0700112def list_adb_devices():
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700113 """List all target devices connected to the host and detected by adb.
Ang Li93420002016-05-10 19:11:44 -0700114
115 Returns:
116 A list of android device serials. Empty if there's none.
117 """
118 out = adb.AdbProxy().devices()
119 return _parse_device_list(out, "device")
120
Ang Lie2139f12016-05-12 17:39:06 -0700121
Ang Li93420002016-05-10 19:11:44 -0700122def list_fastboot_devices():
123 """List all android devices connected to the computer that are in in
124 fastboot mode. These are detected by fastboot.
125
126 Returns:
127 A list of android device serials. Empty if there's none.
128 """
129 out = fastboot.FastbootProxy().devices()
130 return _parse_device_list(out, "fastboot")
131
Ang Lie2139f12016-05-12 17:39:06 -0700132
Ang Li7f0e1c72016-06-14 11:23:49 -0700133def get_instances(serials):
Ang Li93420002016-05-10 19:11:44 -0700134 """Create AndroidDevice instances from a list of serials.
135
136 Args:
137 serials: A list of android device serials.
Ang Li93420002016-05-10 19:11:44 -0700138
139 Returns:
140 A list of AndroidDevice objects.
141 """
142 results = []
143 for s in serials:
Ang Li7f0e1c72016-06-14 11:23:49 -0700144 results.append(AndroidDevice(s))
Ang Li93420002016-05-10 19:11:44 -0700145 return results
146
Ang Lie2139f12016-05-12 17:39:06 -0700147
Ang Li7f0e1c72016-06-14 11:23:49 -0700148def get_instances_with_configs(configs):
Ang Li93420002016-05-10 19:11:44 -0700149 """Create AndroidDevice instances from a list of json configs.
150
151 Each config should have the required key-value pair "serial".
152
153 Args:
154 configs: A list of dicts each representing the configuration of one
155 android device.
Ang Li93420002016-05-10 19:11:44 -0700156
157 Returns:
158 A list of AndroidDevice objects.
159 """
160 results = []
161 for c in configs:
162 try:
163 serial = c.pop("serial")
164 except KeyError:
165 raise AndroidDeviceError(('Required value "serial" is missing in '
Ang Lie2139f12016-05-12 17:39:06 -0700166 'AndroidDevice config %s.') % c)
Ang Li7f0e1c72016-06-14 11:23:49 -0700167 ad = AndroidDevice(serial)
Ang Li93420002016-05-10 19:11:44 -0700168 ad.loadConfig(c)
169 results.append(ad)
170 return results
171
Ang Lie2139f12016-05-12 17:39:06 -0700172
Ang Li7f0e1c72016-06-14 11:23:49 -0700173def get_all_instances(include_fastboot=False):
Ang Li93420002016-05-10 19:11:44 -0700174 """Create AndroidDevice instances for all attached android devices.
175
176 Args:
177 include_fastboot: Whether to include devices in bootloader mode or not.
Ang Li93420002016-05-10 19:11:44 -0700178
179 Returns:
180 A list of AndroidDevice objects each representing an android device
181 attached to the computer.
182 """
183 if include_fastboot:
184 serial_list = list_adb_devices() + list_fastboot_devices()
Ang Li7f0e1c72016-06-14 11:23:49 -0700185 return get_instances(serial_list)
186 return get_instances(list_adb_devices())
Ang Li93420002016-05-10 19:11:44 -0700187
Ang Lie2139f12016-05-12 17:39:06 -0700188
Ang Li93420002016-05-10 19:11:44 -0700189def filter_devices(ads, func):
190 """Finds the AndroidDevice instances from a list that match certain
191 conditions.
192
193 Args:
194 ads: A list of AndroidDevice instances.
195 func: A function that takes an AndroidDevice object and returns True
196 if the device satisfies the filter condition.
197
198 Returns:
199 A list of AndroidDevice instances that satisfy the filter condition.
200 """
201 results = []
202 for ad in ads:
203 if func(ad):
204 results.append(ad)
205 return results
206
Ang Lie2139f12016-05-12 17:39:06 -0700207
Ang Li93420002016-05-10 19:11:44 -0700208def get_device(ads, **kwargs):
209 """Finds a unique AndroidDevice instance from a list that has specific
210 attributes of certain values.
211
212 Example:
213 get_device(android_devices, label="foo", phone_number="1234567890")
214 get_device(android_devices, model="angler")
215
216 Args:
217 ads: A list of AndroidDevice instances.
218 kwargs: keyword arguments used to filter AndroidDevice instances.
219
220 Returns:
221 The target AndroidDevice instance.
222
223 Raises:
224 AndroidDeviceError is raised if none or more than one device is
225 matched.
226 """
Ang Lie2139f12016-05-12 17:39:06 -0700227
Ang Li93420002016-05-10 19:11:44 -0700228 def _get_device_filter(ad):
229 for k, v in kwargs.items():
230 if not hasattr(ad, k):
231 return False
232 elif getattr(ad, k) != v:
233 return False
234 return True
Ang Lie2139f12016-05-12 17:39:06 -0700235
Ang Li93420002016-05-10 19:11:44 -0700236 filtered = filter_devices(ads, _get_device_filter)
237 if not filtered:
238 raise AndroidDeviceError(("Could not find a target device that matches"
239 " condition: %s.") % kwargs)
240 elif len(filtered) == 1:
241 return filtered[0]
242 else:
243 serials = [ad.serial for ad in filtered]
244 raise AndroidDeviceError("More than one device matched: %s" % serials)
245
Ang Lie2139f12016-05-12 17:39:06 -0700246
Ang Li93420002016-05-10 19:11:44 -0700247def takeBugReports(ads, test_name, begin_time):
248 """Takes bug reports on a list of android devices.
249
250 If you want to take a bug report, call this function with a list of
251 android_device objects in on_fail. But reports will be taken on all the
252 devices in the list concurrently. Bug report takes a relative long
253 time to take, so use this cautiously.
254
255 Args:
256 ads: A list of AndroidDevice instances.
257 test_name: Name of the test case that triggered this bug report.
258 begin_time: Logline format timestamp taken when the test started.
259 """
260 begin_time = vts_logger.normalizeLogLineTimestamp(begin_time)
Ang Lie2139f12016-05-12 17:39:06 -0700261
Ang Li93420002016-05-10 19:11:44 -0700262 def take_br(test_name, begin_time, ad):
263 ad.takeBugReport(test_name, begin_time)
Ang Lie2139f12016-05-12 17:39:06 -0700264
Ang Li93420002016-05-10 19:11:44 -0700265 args = [(test_name, begin_time, ad) for ad in ads]
266 utils.concurrent_exec(take_br, args)
267
Ang Lie2139f12016-05-12 17:39:06 -0700268
Ang Li7f0e1c72016-06-14 11:23:49 -0700269class AndroidDevice(object):
Ang Li93420002016-05-10 19:11:44 -0700270 """Class representing an android device.
271
272 Each object of this class represents one Android device in ACTS, including
273 handles to adb, fastboot, and sl4a clients. In addition to direct adb
274 commands, this object also uses adb port forwarding to talk to the Android
275 device.
276
277 Attributes:
278 serial: A string that's the serial number of the Androi device.
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700279 device_command_port: int, the port number used on the Android device
280 for adb port forwarding (for command-response sessions).
281 device_callback_port: int, the port number used on the Android device
282 for adb port reverse forwarding (for callback sessions).
Ang Lie014a8b2016-06-28 18:24:52 -0700283 log: A logger project with a device-specific prefix for each line -
284 [AndroidDevice|<serial>]
Ang Li93420002016-05-10 19:11:44 -0700285 log_path: A string that is the path where all logs collected on this
286 android device should be stored.
287 adb_logcat_process: A process that collects the adb logcat.
288 adb_logcat_file_path: A string that's the full path to the adb logcat
289 file collected, if any.
Ang Lie014a8b2016-06-28 18:24:52 -0700290 vts_agent_process: A process that runs the HAL agent.
Ang Li93420002016-05-10 19:11:44 -0700291 adb: An AdbProxy object used for interacting with the device via adb.
292 fastboot: A FastbootProxy object used for interacting with the device
293 via fastboot.
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700294 host_command_port: the host-side port for runner to agent sessions
295 (to send commands and receive responses).
296 host_callback_port: the host-side port for agent to runner sessions
297 (to get callbacks from agent).
Ang Li93420002016-05-10 19:11:44 -0700298 """
299
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700300 def __init__(self, serial="", device_port=5001, device_callback_port=5010):
Ang Li93420002016-05-10 19:11:44 -0700301 self.serial = serial
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700302 self.device_command_port = device_port
303 self.device_callback_port = device_callback_port
Ang Lie014a8b2016-06-28 18:24:52 -0700304 self.log = AndroidDeviceLoggerAdapter(logging.getLogger(),
305 {"serial": self.serial})
306 base_log_path = getattr(logging, "log_path", "/tmp/logs/")
Ang Li7f0e1c72016-06-14 11:23:49 -0700307 self.log_path = os.path.join(base_log_path, "AndroidDevice%s" % serial)
Ang Li93420002016-05-10 19:11:44 -0700308 self.adb_logcat_process = None
309 self.adb_logcat_file_path = None
Ang Lie014a8b2016-06-28 18:24:52 -0700310 self.vts_agent_process = None
Ang Li93420002016-05-10 19:11:44 -0700311 self.adb = adb.AdbProxy(serial)
312 self.fastboot = fastboot.FastbootProxy(serial)
313 if not self.isBootloaderMode:
314 self.rootAdb()
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700315 self.host_command_port = adb.get_available_host_port()
316 self.host_callback_port = adb.get_available_host_port()
317 self.adb.tcp_forward(self.host_command_port, self.device_command_port)
Ang Lie014a8b2016-06-28 18:24:52 -0700318 self.adb.reverse_tcp_forward(self.device_callback_port,
319 self.host_callback_port)
320 self.hal = hal_mirror.HalMirror(self.host_command_port,
321 self.host_callback_port)
Ang Li93420002016-05-10 19:11:44 -0700322
323 def __del__(self):
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700324 if self.host_command_port:
325 self.adb.forward("--remove tcp:%s" % self.host_command_port)
Ang Li93420002016-05-10 19:11:44 -0700326 if self.adb_logcat_process:
327 self.stopAdbLogcat()
328
329 @property
330 def isBootloaderMode(self):
331 """True if the device is in bootloader mode.
332 """
333 return self.serial in list_fastboot_devices()
334
335 @property
336 def isAdbRoot(self):
337 """True if adb is running as root for this device.
338 """
339 return "root" in self.adb.shell("id -u").decode("utf-8")
340
341 @property
342 def model(self):
343 """The Android code name for the device.
344 """
345 # If device is in bootloader mode, get mode name from fastboot.
346 if self.isBootloaderMode:
347 out = self.fastboot.getvar("product").strip()
348 # "out" is never empty because of the "total time" message fastboot
349 # writes to stderr.
350 lines = out.decode("utf-8").split('\n', 1)
351 if lines:
352 tokens = lines[0].split(' ')
353 if len(tokens) > 1:
354 return tokens[1].lower()
355 return None
356 out = self.adb.shell('getprop | grep ro.build.product')
357 model = out.decode("utf-8").strip().split('[')[-1][:-1].lower()
358 if model == "sprout":
359 return model
360 else:
361 out = self.adb.shell('getprop | grep ro.product.name')
362 model = out.decode("utf-8").strip().split('[')[-1][:-1].lower()
363 return model
364
365 @property
Ang Li93420002016-05-10 19:11:44 -0700366 def isAdbLogcatOn(self):
367 """Whether there is an ongoing adb logcat collection.
368 """
369 if self.adb_logcat_process:
370 return True
371 return False
372
373 def loadConfig(self, config):
374 """Add attributes to the AndroidDevice object based on json config.
375
376 Args:
377 config: A dictionary representing the configs.
378
379 Raises:
380 AndroidDeviceError is raised if the config is trying to overwrite
381 an existing attribute.
382 """
383 for k, v in config.items():
384 if hasattr(self, k):
Ang Li7f0e1c72016-06-14 11:23:49 -0700385 raise AndroidDeviceError(
386 "Attempting to set existing attribute %s on %s" %
387 (k, self.serial))
Ang Li93420002016-05-10 19:11:44 -0700388 setattr(self, k, v)
389
390 def rootAdb(self):
391 """Change adb to root mode for this device.
392 """
393 if not self.isAdbRoot:
394 self.adb.root()
395 self.adb.wait_for_device()
396 self.adb.remount()
397 self.adb.wait_for_device()
398
Ang Li93420002016-05-10 19:11:44 -0700399 def startAdbLogcat(self):
400 """Starts a standing adb logcat collection in separate subprocesses and
401 save the logcat in a file.
402 """
403 if self.isAdbLogcatOn:
Ang Li7f0e1c72016-06-14 11:23:49 -0700404 raise AndroidDeviceError(("Android device %s already has an adb "
Ang Lie2139f12016-05-12 17:39:06 -0700405 "logcat thread going on. Cannot start "
Ang Li7f0e1c72016-06-14 11:23:49 -0700406 "another one.") % self.serial)
Ang Li7f0e1c72016-06-14 11:23:49 -0700407 f_name = "adblog,%s,%s.txt" % (self.model, self.serial)
Ang Li93420002016-05-10 19:11:44 -0700408 utils.create_dir(self.log_path)
409 logcat_file_path = os.path.join(self.log_path, f_name)
410 try:
411 extra_params = self.adb_logcat_param
412 except AttributeError:
413 extra_params = "-b all"
Ang Li7f0e1c72016-06-14 11:23:49 -0700414 cmd = "adb -s %s logcat -v threadtime %s >> %s" % (
Ang Li93420002016-05-10 19:11:44 -0700415 self.serial, extra_params, logcat_file_path)
416 self.adb_logcat_process = utils.start_standing_subprocess(cmd)
417 self.adb_logcat_file_path = logcat_file_path
418
419 def stopAdbLogcat(self):
420 """Stops the adb logcat collection subprocess.
421 """
422 if not self.isAdbLogcatOn:
Ang Li7f0e1c72016-06-14 11:23:49 -0700423 raise AndroidDeviceError(
424 "Android device %s does not have an ongoing adb logcat collection."
425 % self.serial)
Ang Li93420002016-05-10 19:11:44 -0700426 utils.stop_standing_subprocess(self.adb_logcat_process)
427 self.adb_logcat_process = None
428
429 def takeBugReport(self, test_name, begin_time):
430 """Takes a bug report on the device and stores it in a file.
431
432 Args:
433 test_name: Name of the test case that triggered this bug report.
434 begin_time: Logline format timestamp taken when the test started.
435 """
436 br_path = os.path.join(self.log_path, "BugReports")
437 utils.create_dir(br_path)
Ang Li7f0e1c72016-06-14 11:23:49 -0700438 base_name = ",%s,%s.txt" % (begin_time, self.serial)
Ang Li93420002016-05-10 19:11:44 -0700439 test_name_len = utils.MAX_FILENAME_LEN - len(base_name)
440 out_name = test_name[:test_name_len] + base_name
441 full_out_path = os.path.join(br_path, out_name.replace(' ', '\ '))
442 self.log.info("Taking bugreport for %s on %s", test_name, self.serial)
Ang Li7f0e1c72016-06-14 11:23:49 -0700443 self.adb.bugreport(" > %s" % full_out_path)
Ang Li93420002016-05-10 19:11:44 -0700444 self.log.info("Bugreport for %s taken at %s", test_name, full_out_path)
445
Ang Li93420002016-05-10 19:11:44 -0700446 @utils.timeout(15 * 60)
447 def waitForBootCompletion(self):
448 """Waits for Android framework to broadcast ACTION_BOOT_COMPLETED.
449
450 This function times out after 15 minutes.
451 """
452 self.adb.wait_for_device()
453 while True:
454 try:
455 out = self.adb.shell("getprop sys.boot_completed")
456 completed = out.decode('utf-8').strip()
457 if completed == '1':
458 return
459 except adb.AdbError:
460 # adb shell calls may fail during certain period of booting
461 # process, which is normal. Ignoring these errors.
462 pass
463 time.sleep(5)
464
465 def reboot(self):
Ang Li7f0e1c72016-06-14 11:23:49 -0700466 """Reboots the device and wait for device to complete booting.
Ang Li93420002016-05-10 19:11:44 -0700467
468 This is probably going to print some error messages in console. Only
469 use if there's no other option.
470
Ang Li93420002016-05-10 19:11:44 -0700471 Raises:
472 AndroidDeviceError is raised if waiting for completion timed
473 out.
474 """
475 if self.isBootloaderMode:
476 self.fastboot.reboot()
477 return
478 has_adb_log = self.isAdbLogcatOn
Ang Lie014a8b2016-06-28 18:24:52 -0700479 has_vts_agent = True if self.vts_agent_process else False
Ang Li93420002016-05-10 19:11:44 -0700480 if has_adb_log:
481 self.stopAdbLogcat()
Ang Lie014a8b2016-06-28 18:24:52 -0700482 if has_vts_agent:
483 self.stopVtsAgent()
Ang Li93420002016-05-10 19:11:44 -0700484 self.adb.reboot()
485 self.waitForBootCompletion()
486 self.rootAdb()
Ang Li93420002016-05-10 19:11:44 -0700487 if has_adb_log:
488 self.startAdbLogcat()
Ang Lie014a8b2016-06-28 18:24:52 -0700489 if has_vts_agent:
490 self.startVtsAgent()
Sahil Jain06dd6a22016-06-24 13:47:37 -0700491
Ang Lie014a8b2016-06-28 18:24:52 -0700492 def startVtsAgent(self):
493 """Start HAL agent on the AndroidDevice.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700494
495 This function starts the target side native agent and is persisted
Ang Lie014a8b2016-06-28 18:24:52 -0700496 throughout the test run.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700497 """
Ang Lie014a8b2016-06-28 18:24:52 -0700498 if self.vts_agent_process:
499 raise AndroidDeviceError("HAL agent is already running on %s." %
500 self.serial)
Keun Soo Yima066dd52016-07-01 15:18:28 -0700501
502 cleanup_commands = [
503 "rm -f /data/local/tmp/vts_driver_* /data/local/tmp/vts_agent_callback*"]
Ang Lie014a8b2016-06-28 18:24:52 -0700504 kill_commands = ["killall vts_hal_agent", "killall fuzzer32",
505 "killall fuzzer64"]
Keun Soo Yima066dd52016-07-01 15:18:28 -0700506 cleanup_commands.extend(kill_commands)
507 for cmd in cleanup_commands:
Sahil Jain06dd6a22016-06-24 13:47:37 -0700508 try:
509 self.adb.shell(cmd)
Ang Lie014a8b2016-06-28 18:24:52 -0700510 except adb.AdbError:
511 # Ignore errors from killall in case process was not running.
512 pass
513 vts_agent_log_path = os.path.join(self.log_path, "vts_agent.log")
514 cmd = (
515 'adb -s {s} shell LD_LIBRARY_PATH={path}/64 {path}/64/vts_hal_agent'
Keun Soo Yima066dd52016-07-01 15:18:28 -0700516 ' {path}/32/fuzzer32 {path}/64/fuzzer64 {path}/spec'
517 ' {path}/32/vts_shell_driver32 {path}/64/vts_shell_driver64 >> {log}'
Ang Lie014a8b2016-06-28 18:24:52 -0700518 ).format(s=self.serial,
519 path=DEFAULT_AGENT_BASE_DIR,
520 log=vts_agent_log_path)
521 self.vts_agent_process = utils.start_standing_subprocess(
522 cmd, check_health_delay=1)
Sahil Jain06dd6a22016-06-24 13:47:37 -0700523
Ang Lie014a8b2016-06-28 18:24:52 -0700524 def stopVtsAgent(self):
525 """Stop the HAL agent running on the AndroidDevice.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700526 """
Ang Lie014a8b2016-06-28 18:24:52 -0700527 if self.vts_agent_process:
528 utils.stop_standing_subprocess(self.vts_agent_process)
529 self.vts_agent_process = None
Sahil Jain06dd6a22016-06-24 13:47:37 -0700530
Sahil Jain06dd6a22016-06-24 13:47:37 -0700531
Ang Lie014a8b2016-06-28 18:24:52 -0700532class AndroidDeviceLoggerAdapter(logging.LoggerAdapter):
533 """A wrapper class that attaches a prefix to all log lines from an
534 AndroidDevice object.
535 """
536
537 def process(self, msg, kwargs):
538 """Process every log message written via the wrapped logger object.
539
540 We are adding the prefix "[AndroidDevice|<serial>]" to all log lines.
541
542 Args:
543 msg: string, the original log message.
544 kwargs: dict, the key value pairs that can be used to modify the
545 original log message.
546 """
547 msg = "[AndroidDevice|%s] %s" % (self.extra["serial"], msg)
548 return (msg, kwargs)