blob: b81e798d04656e23aa4af1ffb4183ae8d8ce77c6 [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
Keun Soo Yim63d67512016-07-01 17:13:47 -070036from vts.utils.python.mirror import shell_mirror
Sahil Jain06dd6a22016-06-24 13:47:37 -070037from vts.runners.host import errors
38import subprocess
Ang Li93420002016-05-10 19:11:44 -070039
40VTS_CONTROLLER_CONFIG_NAME = "AndroidDevice"
41VTS_CONTROLLER_REFERENCE_NAME = "android_devices"
42
43ANDROID_DEVICE_PICK_ALL_TOKEN = "*"
44# Key name for adb logcat extra params in config file.
45ANDROID_DEVICE_ADB_LOGCAT_PARAM_KEY = "adb_logcat_param"
46ANDROID_DEVICE_EMPTY_CONFIG_MSG = "Configuration is empty, abort!"
47ANDROID_DEVICE_NOT_LIST_CONFIG_MSG = "Configuration should be a list, abort!"
48
Sahil Jain06dd6a22016-06-24 13:47:37 -070049# Target-side directory where the VTS binaries are uploaded
50DEFAULT_AGENT_BASE_DIR = "/data/local/tmp"
51# Time for which the current is put on sleep when the client is unable to
52# make a connection.
53THREAD_SLEEP_TIME = 1
54# Max number of attempts that the client can make to connect to the agent
55MAX_AGENT_CONNECT_RETRIES = 10
56
Ang Lie2139f12016-05-12 17:39:06 -070057
Ang Li93420002016-05-10 19:11:44 -070058class AndroidDeviceError(signals.ControllerError):
59 pass
60
Ang Lie2139f12016-05-12 17:39:06 -070061
Ang Li7f0e1c72016-06-14 11:23:49 -070062def create(configs):
Ang Li93420002016-05-10 19:11:44 -070063 if not configs:
64 raise AndroidDeviceError(ANDROID_DEVICE_EMPTY_CONFIG_MSG)
65 elif configs == ANDROID_DEVICE_PICK_ALL_TOKEN:
Ang Li7f0e1c72016-06-14 11:23:49 -070066 ads = get_all_instances()
Ang Li93420002016-05-10 19:11:44 -070067 elif not isinstance(configs, list):
68 raise AndroidDeviceError(ANDROID_DEVICE_NOT_LIST_CONFIG_MSG)
69 elif isinstance(configs[0], str):
70 # Configs is a list of serials.
Ang Li7f0e1c72016-06-14 11:23:49 -070071 ads = get_instances(configs)
Ang Li93420002016-05-10 19:11:44 -070072 else:
73 # Configs is a list of dicts.
Ang Li7f0e1c72016-06-14 11:23:49 -070074 ads = get_instances_with_configs(configs)
Ang Li93420002016-05-10 19:11:44 -070075 connected_ads = list_adb_devices()
76 for ad in ads:
77 if ad.serial not in connected_ads:
Ang Lie2139f12016-05-12 17:39:06 -070078 raise AndroidDeviceError(
79 ("Android device %s is specified in config"
80 " but is not attached.") % ad.serial)
Ang Li93420002016-05-10 19:11:44 -070081 ad.startAdbLogcat()
Ang Lie014a8b2016-06-28 18:24:52 -070082 ad.startVtsAgent()
Ang Li93420002016-05-10 19:11:44 -070083 return ads
84
Ang Lie2139f12016-05-12 17:39:06 -070085
Ang Li93420002016-05-10 19:11:44 -070086def destroy(ads):
87 for ad in ads:
Ang Lie014a8b2016-06-28 18:24:52 -070088 ad.stopVtsAgent()
Ang Li93420002016-05-10 19:11:44 -070089 if ad.adb_logcat_process:
90 ad.stopAdbLogcat()
91
Ang Lie2139f12016-05-12 17:39:06 -070092
Ang Li93420002016-05-10 19:11:44 -070093def _parse_device_list(device_list_str, key):
94 """Parses a byte string representing a list of devices. The string is
95 generated by calling either adb or fastboot.
96
97 Args:
98 device_list_str: Output of adb or fastboot.
99 key: The token that signifies a device in device_list_str.
100
101 Returns:
102 A list of android device serial numbers.
103 """
104 clean_lines = str(device_list_str, 'utf-8').strip().split('\n')
105 results = []
106 for line in clean_lines:
107 tokens = line.strip().split('\t')
108 if len(tokens) == 2 and tokens[1] == key:
109 results.append(tokens[0])
110 return results
111
Ang Lie2139f12016-05-12 17:39:06 -0700112
Ang Li93420002016-05-10 19:11:44 -0700113def list_adb_devices():
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700114 """List all target devices connected to the host and detected by adb.
Ang Li93420002016-05-10 19:11:44 -0700115
116 Returns:
117 A list of android device serials. Empty if there's none.
118 """
119 out = adb.AdbProxy().devices()
120 return _parse_device_list(out, "device")
121
Ang Lie2139f12016-05-12 17:39:06 -0700122
Ang Li93420002016-05-10 19:11:44 -0700123def list_fastboot_devices():
124 """List all android devices connected to the computer that are in in
125 fastboot mode. These are detected by fastboot.
126
127 Returns:
128 A list of android device serials. Empty if there's none.
129 """
130 out = fastboot.FastbootProxy().devices()
131 return _parse_device_list(out, "fastboot")
132
Ang Lie2139f12016-05-12 17:39:06 -0700133
Ang Li7f0e1c72016-06-14 11:23:49 -0700134def get_instances(serials):
Ang Li93420002016-05-10 19:11:44 -0700135 """Create AndroidDevice instances from a list of serials.
136
137 Args:
138 serials: A list of android device serials.
Ang Li93420002016-05-10 19:11:44 -0700139
140 Returns:
141 A list of AndroidDevice objects.
142 """
143 results = []
144 for s in serials:
Ang Li7f0e1c72016-06-14 11:23:49 -0700145 results.append(AndroidDevice(s))
Ang Li93420002016-05-10 19:11:44 -0700146 return results
147
Ang Lie2139f12016-05-12 17:39:06 -0700148
Ang Li7f0e1c72016-06-14 11:23:49 -0700149def get_instances_with_configs(configs):
Ang Li93420002016-05-10 19:11:44 -0700150 """Create AndroidDevice instances from a list of json configs.
151
152 Each config should have the required key-value pair "serial".
153
154 Args:
155 configs: A list of dicts each representing the configuration of one
156 android device.
Ang Li93420002016-05-10 19:11:44 -0700157
158 Returns:
159 A list of AndroidDevice objects.
160 """
161 results = []
162 for c in configs:
163 try:
164 serial = c.pop("serial")
165 except KeyError:
166 raise AndroidDeviceError(('Required value "serial" is missing in '
Ang Lie2139f12016-05-12 17:39:06 -0700167 'AndroidDevice config %s.') % c)
Ang Li7f0e1c72016-06-14 11:23:49 -0700168 ad = AndroidDevice(serial)
Ang Li93420002016-05-10 19:11:44 -0700169 ad.loadConfig(c)
170 results.append(ad)
171 return results
172
Ang Lie2139f12016-05-12 17:39:06 -0700173
Ang Li7f0e1c72016-06-14 11:23:49 -0700174def get_all_instances(include_fastboot=False):
Ang Li93420002016-05-10 19:11:44 -0700175 """Create AndroidDevice instances for all attached android devices.
176
177 Args:
178 include_fastboot: Whether to include devices in bootloader mode or not.
Ang Li93420002016-05-10 19:11:44 -0700179
180 Returns:
181 A list of AndroidDevice objects each representing an android device
182 attached to the computer.
183 """
184 if include_fastboot:
185 serial_list = list_adb_devices() + list_fastboot_devices()
Ang Li7f0e1c72016-06-14 11:23:49 -0700186 return get_instances(serial_list)
187 return get_instances(list_adb_devices())
Ang Li93420002016-05-10 19:11:44 -0700188
Ang Lie2139f12016-05-12 17:39:06 -0700189
Ang Li93420002016-05-10 19:11:44 -0700190def filter_devices(ads, func):
191 """Finds the AndroidDevice instances from a list that match certain
192 conditions.
193
194 Args:
195 ads: A list of AndroidDevice instances.
196 func: A function that takes an AndroidDevice object and returns True
197 if the device satisfies the filter condition.
198
199 Returns:
200 A list of AndroidDevice instances that satisfy the filter condition.
201 """
202 results = []
203 for ad in ads:
204 if func(ad):
205 results.append(ad)
206 return results
207
Ang Lie2139f12016-05-12 17:39:06 -0700208
Ang Li93420002016-05-10 19:11:44 -0700209def get_device(ads, **kwargs):
210 """Finds a unique AndroidDevice instance from a list that has specific
211 attributes of certain values.
212
213 Example:
214 get_device(android_devices, label="foo", phone_number="1234567890")
215 get_device(android_devices, model="angler")
216
217 Args:
218 ads: A list of AndroidDevice instances.
219 kwargs: keyword arguments used to filter AndroidDevice instances.
220
221 Returns:
222 The target AndroidDevice instance.
223
224 Raises:
225 AndroidDeviceError is raised if none or more than one device is
226 matched.
227 """
Ang Lie2139f12016-05-12 17:39:06 -0700228
Ang Li93420002016-05-10 19:11:44 -0700229 def _get_device_filter(ad):
230 for k, v in kwargs.items():
231 if not hasattr(ad, k):
232 return False
233 elif getattr(ad, k) != v:
234 return False
235 return True
Ang Lie2139f12016-05-12 17:39:06 -0700236
Ang Li93420002016-05-10 19:11:44 -0700237 filtered = filter_devices(ads, _get_device_filter)
238 if not filtered:
239 raise AndroidDeviceError(("Could not find a target device that matches"
240 " condition: %s.") % kwargs)
241 elif len(filtered) == 1:
242 return filtered[0]
243 else:
244 serials = [ad.serial for ad in filtered]
245 raise AndroidDeviceError("More than one device matched: %s" % serials)
246
Ang Lie2139f12016-05-12 17:39:06 -0700247
Ang Li93420002016-05-10 19:11:44 -0700248def takeBugReports(ads, test_name, begin_time):
249 """Takes bug reports on a list of android devices.
250
251 If you want to take a bug report, call this function with a list of
252 android_device objects in on_fail. But reports will be taken on all the
253 devices in the list concurrently. Bug report takes a relative long
254 time to take, so use this cautiously.
255
256 Args:
257 ads: A list of AndroidDevice instances.
258 test_name: Name of the test case that triggered this bug report.
259 begin_time: Logline format timestamp taken when the test started.
260 """
261 begin_time = vts_logger.normalizeLogLineTimestamp(begin_time)
Ang Lie2139f12016-05-12 17:39:06 -0700262
Ang Li93420002016-05-10 19:11:44 -0700263 def take_br(test_name, begin_time, ad):
264 ad.takeBugReport(test_name, begin_time)
Ang Lie2139f12016-05-12 17:39:06 -0700265
Ang Li93420002016-05-10 19:11:44 -0700266 args = [(test_name, begin_time, ad) for ad in ads]
267 utils.concurrent_exec(take_br, args)
268
Ang Lie2139f12016-05-12 17:39:06 -0700269
Ang Li7f0e1c72016-06-14 11:23:49 -0700270class AndroidDevice(object):
Ang Li93420002016-05-10 19:11:44 -0700271 """Class representing an android device.
272
273 Each object of this class represents one Android device in ACTS, including
274 handles to adb, fastboot, and sl4a clients. In addition to direct adb
275 commands, this object also uses adb port forwarding to talk to the Android
276 device.
277
278 Attributes:
279 serial: A string that's the serial number of the Androi device.
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700280 device_command_port: int, the port number used on the Android device
281 for adb port forwarding (for command-response sessions).
282 device_callback_port: int, the port number used on the Android device
283 for adb port reverse forwarding (for callback sessions).
Ang Lie014a8b2016-06-28 18:24:52 -0700284 log: A logger project with a device-specific prefix for each line -
285 [AndroidDevice|<serial>]
Ang Li93420002016-05-10 19:11:44 -0700286 log_path: A string that is the path where all logs collected on this
287 android device should be stored.
288 adb_logcat_process: A process that collects the adb logcat.
289 adb_logcat_file_path: A string that's the full path to the adb logcat
290 file collected, if any.
Ang Lie014a8b2016-06-28 18:24:52 -0700291 vts_agent_process: A process that runs the HAL agent.
Ang Li93420002016-05-10 19:11:44 -0700292 adb: An AdbProxy object used for interacting with the device via adb.
293 fastboot: A FastbootProxy object used for interacting with the device
294 via fastboot.
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700295 host_command_port: the host-side port for runner to agent sessions
296 (to send commands and receive responses).
297 host_callback_port: the host-side port for agent to runner sessions
298 (to get callbacks from agent).
Ang Li93420002016-05-10 19:11:44 -0700299 """
300
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700301 def __init__(self, serial="", device_port=5001, device_callback_port=5010):
Ang Li93420002016-05-10 19:11:44 -0700302 self.serial = serial
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700303 self.device_command_port = device_port
304 self.device_callback_port = device_callback_port
Ang Lie014a8b2016-06-28 18:24:52 -0700305 self.log = AndroidDeviceLoggerAdapter(logging.getLogger(),
306 {"serial": self.serial})
307 base_log_path = getattr(logging, "log_path", "/tmp/logs/")
Ang Li7f0e1c72016-06-14 11:23:49 -0700308 self.log_path = os.path.join(base_log_path, "AndroidDevice%s" % serial)
Ang Li93420002016-05-10 19:11:44 -0700309 self.adb_logcat_process = None
310 self.adb_logcat_file_path = None
Ang Lie014a8b2016-06-28 18:24:52 -0700311 self.vts_agent_process = None
Ang Li93420002016-05-10 19:11:44 -0700312 self.adb = adb.AdbProxy(serial)
313 self.fastboot = fastboot.FastbootProxy(serial)
314 if not self.isBootloaderMode:
315 self.rootAdb()
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700316 self.host_command_port = adb.get_available_host_port()
317 self.host_callback_port = adb.get_available_host_port()
318 self.adb.tcp_forward(self.host_command_port, self.device_command_port)
Ang Lie014a8b2016-06-28 18:24:52 -0700319 self.adb.reverse_tcp_forward(self.device_callback_port,
320 self.host_callback_port)
321 self.hal = hal_mirror.HalMirror(self.host_command_port,
322 self.host_callback_port)
Keun Soo Yim63d67512016-07-01 17:13:47 -0700323 self.shell = shell_mirror.ShellMirror(self.host_command_port)
Ang Li93420002016-05-10 19:11:44 -0700324
325 def __del__(self):
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700326 if self.host_command_port:
327 self.adb.forward("--remove tcp:%s" % self.host_command_port)
Ang Li93420002016-05-10 19:11:44 -0700328 if self.adb_logcat_process:
329 self.stopAdbLogcat()
330
331 @property
332 def isBootloaderMode(self):
333 """True if the device is in bootloader mode.
334 """
335 return self.serial in list_fastboot_devices()
336
337 @property
338 def isAdbRoot(self):
339 """True if adb is running as root for this device.
340 """
341 return "root" in self.adb.shell("id -u").decode("utf-8")
342
343 @property
344 def model(self):
345 """The Android code name for the device.
346 """
347 # If device is in bootloader mode, get mode name from fastboot.
348 if self.isBootloaderMode:
349 out = self.fastboot.getvar("product").strip()
350 # "out" is never empty because of the "total time" message fastboot
351 # writes to stderr.
352 lines = out.decode("utf-8").split('\n', 1)
353 if lines:
354 tokens = lines[0].split(' ')
355 if len(tokens) > 1:
356 return tokens[1].lower()
357 return None
358 out = self.adb.shell('getprop | grep ro.build.product')
359 model = out.decode("utf-8").strip().split('[')[-1][:-1].lower()
360 if model == "sprout":
361 return model
362 else:
363 out = self.adb.shell('getprop | grep ro.product.name')
364 model = out.decode("utf-8").strip().split('[')[-1][:-1].lower()
365 return model
366
367 @property
Ang Li93420002016-05-10 19:11:44 -0700368 def isAdbLogcatOn(self):
369 """Whether there is an ongoing adb logcat collection.
370 """
371 if self.adb_logcat_process:
372 return True
373 return False
374
375 def loadConfig(self, config):
376 """Add attributes to the AndroidDevice object based on json config.
377
378 Args:
379 config: A dictionary representing the configs.
380
381 Raises:
382 AndroidDeviceError is raised if the config is trying to overwrite
383 an existing attribute.
384 """
385 for k, v in config.items():
386 if hasattr(self, k):
Ang Li7f0e1c72016-06-14 11:23:49 -0700387 raise AndroidDeviceError(
388 "Attempting to set existing attribute %s on %s" %
389 (k, self.serial))
Ang Li93420002016-05-10 19:11:44 -0700390 setattr(self, k, v)
391
392 def rootAdb(self):
393 """Change adb to root mode for this device.
394 """
395 if not self.isAdbRoot:
396 self.adb.root()
397 self.adb.wait_for_device()
398 self.adb.remount()
399 self.adb.wait_for_device()
400
Ang Li93420002016-05-10 19:11:44 -0700401 def startAdbLogcat(self):
402 """Starts a standing adb logcat collection in separate subprocesses and
403 save the logcat in a file.
404 """
405 if self.isAdbLogcatOn:
Ang Li7f0e1c72016-06-14 11:23:49 -0700406 raise AndroidDeviceError(("Android device %s already has an adb "
Ang Lie2139f12016-05-12 17:39:06 -0700407 "logcat thread going on. Cannot start "
Ang Li7f0e1c72016-06-14 11:23:49 -0700408 "another one.") % self.serial)
Ang Li7f0e1c72016-06-14 11:23:49 -0700409 f_name = "adblog,%s,%s.txt" % (self.model, self.serial)
Ang Li93420002016-05-10 19:11:44 -0700410 utils.create_dir(self.log_path)
411 logcat_file_path = os.path.join(self.log_path, f_name)
412 try:
413 extra_params = self.adb_logcat_param
414 except AttributeError:
415 extra_params = "-b all"
Ang Li7f0e1c72016-06-14 11:23:49 -0700416 cmd = "adb -s %s logcat -v threadtime %s >> %s" % (
Ang Li93420002016-05-10 19:11:44 -0700417 self.serial, extra_params, logcat_file_path)
418 self.adb_logcat_process = utils.start_standing_subprocess(cmd)
419 self.adb_logcat_file_path = logcat_file_path
420
421 def stopAdbLogcat(self):
422 """Stops the adb logcat collection subprocess.
423 """
424 if not self.isAdbLogcatOn:
Ang Li7f0e1c72016-06-14 11:23:49 -0700425 raise AndroidDeviceError(
426 "Android device %s does not have an ongoing adb logcat collection."
427 % self.serial)
Ang Li93420002016-05-10 19:11:44 -0700428 utils.stop_standing_subprocess(self.adb_logcat_process)
429 self.adb_logcat_process = None
430
431 def takeBugReport(self, test_name, begin_time):
432 """Takes a bug report on the device and stores it in a file.
433
434 Args:
435 test_name: Name of the test case that triggered this bug report.
436 begin_time: Logline format timestamp taken when the test started.
437 """
438 br_path = os.path.join(self.log_path, "BugReports")
439 utils.create_dir(br_path)
Ang Li7f0e1c72016-06-14 11:23:49 -0700440 base_name = ",%s,%s.txt" % (begin_time, self.serial)
Ang Li93420002016-05-10 19:11:44 -0700441 test_name_len = utils.MAX_FILENAME_LEN - len(base_name)
442 out_name = test_name[:test_name_len] + base_name
443 full_out_path = os.path.join(br_path, out_name.replace(' ', '\ '))
444 self.log.info("Taking bugreport for %s on %s", test_name, self.serial)
Ang Li7f0e1c72016-06-14 11:23:49 -0700445 self.adb.bugreport(" > %s" % full_out_path)
Ang Li93420002016-05-10 19:11:44 -0700446 self.log.info("Bugreport for %s taken at %s", test_name, full_out_path)
447
Ang Li93420002016-05-10 19:11:44 -0700448 @utils.timeout(15 * 60)
449 def waitForBootCompletion(self):
450 """Waits for Android framework to broadcast ACTION_BOOT_COMPLETED.
451
452 This function times out after 15 minutes.
453 """
454 self.adb.wait_for_device()
455 while True:
456 try:
457 out = self.adb.shell("getprop sys.boot_completed")
458 completed = out.decode('utf-8').strip()
459 if completed == '1':
460 return
461 except adb.AdbError:
462 # adb shell calls may fail during certain period of booting
463 # process, which is normal. Ignoring these errors.
464 pass
465 time.sleep(5)
466
467 def reboot(self):
Ang Li7f0e1c72016-06-14 11:23:49 -0700468 """Reboots the device and wait for device to complete booting.
Ang Li93420002016-05-10 19:11:44 -0700469
470 This is probably going to print some error messages in console. Only
471 use if there's no other option.
472
Ang Li93420002016-05-10 19:11:44 -0700473 Raises:
474 AndroidDeviceError is raised if waiting for completion timed
475 out.
476 """
477 if self.isBootloaderMode:
478 self.fastboot.reboot()
479 return
480 has_adb_log = self.isAdbLogcatOn
Ang Lie014a8b2016-06-28 18:24:52 -0700481 has_vts_agent = True if self.vts_agent_process else False
Ang Li93420002016-05-10 19:11:44 -0700482 if has_adb_log:
483 self.stopAdbLogcat()
Ang Lie014a8b2016-06-28 18:24:52 -0700484 if has_vts_agent:
485 self.stopVtsAgent()
Ang Li93420002016-05-10 19:11:44 -0700486 self.adb.reboot()
487 self.waitForBootCompletion()
488 self.rootAdb()
Ang Li93420002016-05-10 19:11:44 -0700489 if has_adb_log:
490 self.startAdbLogcat()
Ang Lie014a8b2016-06-28 18:24:52 -0700491 if has_vts_agent:
492 self.startVtsAgent()
Sahil Jain06dd6a22016-06-24 13:47:37 -0700493
Ang Lie014a8b2016-06-28 18:24:52 -0700494 def startVtsAgent(self):
495 """Start HAL agent on the AndroidDevice.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700496
497 This function starts the target side native agent and is persisted
Ang Lie014a8b2016-06-28 18:24:52 -0700498 throughout the test run.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700499 """
Ang Lie014a8b2016-06-28 18:24:52 -0700500 if self.vts_agent_process:
501 raise AndroidDeviceError("HAL agent is already running on %s." %
502 self.serial)
Keun Soo Yima066dd52016-07-01 15:18:28 -0700503
504 cleanup_commands = [
505 "rm -f /data/local/tmp/vts_driver_* /data/local/tmp/vts_agent_callback*"]
Ang Lie014a8b2016-06-28 18:24:52 -0700506 kill_commands = ["killall vts_hal_agent", "killall fuzzer32",
507 "killall fuzzer64"]
Keun Soo Yima066dd52016-07-01 15:18:28 -0700508 cleanup_commands.extend(kill_commands)
509 for cmd in cleanup_commands:
Sahil Jain06dd6a22016-06-24 13:47:37 -0700510 try:
511 self.adb.shell(cmd)
Ang Lie014a8b2016-06-28 18:24:52 -0700512 except adb.AdbError:
513 # Ignore errors from killall in case process was not running.
514 pass
515 vts_agent_log_path = os.path.join(self.log_path, "vts_agent.log")
516 cmd = (
517 'adb -s {s} shell LD_LIBRARY_PATH={path}/64 {path}/64/vts_hal_agent'
Keun Soo Yima066dd52016-07-01 15:18:28 -0700518 ' {path}/32/fuzzer32 {path}/64/fuzzer64 {path}/spec'
519 ' {path}/32/vts_shell_driver32 {path}/64/vts_shell_driver64 >> {log}'
Ang Lie014a8b2016-06-28 18:24:52 -0700520 ).format(s=self.serial,
521 path=DEFAULT_AGENT_BASE_DIR,
522 log=vts_agent_log_path)
523 self.vts_agent_process = utils.start_standing_subprocess(
524 cmd, check_health_delay=1)
Sahil Jain06dd6a22016-06-24 13:47:37 -0700525
Ang Lie014a8b2016-06-28 18:24:52 -0700526 def stopVtsAgent(self):
527 """Stop the HAL agent running on the AndroidDevice.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700528 """
Ang Lie014a8b2016-06-28 18:24:52 -0700529 if self.vts_agent_process:
530 utils.stop_standing_subprocess(self.vts_agent_process)
531 self.vts_agent_process = None
Sahil Jain06dd6a22016-06-24 13:47:37 -0700532
Sahil Jain06dd6a22016-06-24 13:47:37 -0700533
Ang Lie014a8b2016-06-28 18:24:52 -0700534class AndroidDeviceLoggerAdapter(logging.LoggerAdapter):
535 """A wrapper class that attaches a prefix to all log lines from an
536 AndroidDevice object.
537 """
538
539 def process(self, msg, kwargs):
540 """Process every log message written via the wrapped logger object.
541
542 We are adding the prefix "[AndroidDevice|<serial>]" to all log lines.
543
544 Args:
545 msg: string, the original log message.
546 kwargs: dict, the key value pairs that can be used to modify the
547 original log message.
548 """
549 msg = "[AndroidDevice|%s] %s" % (self.extra["serial"], msg)
550 return (msg, kwargs)