blob: f8e41c53fcba578166b53541075e2108d49aac2b [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
Keun Soo Yim39bc0b92016-07-06 18:27:15 -070037from vts.utils.python.mirror import lib_mirror
Sahil Jain06dd6a22016-06-24 13:47:37 -070038from vts.runners.host import errors
39import subprocess
Ang Li93420002016-05-10 19:11:44 -070040
41VTS_CONTROLLER_CONFIG_NAME = "AndroidDevice"
42VTS_CONTROLLER_REFERENCE_NAME = "android_devices"
43
44ANDROID_DEVICE_PICK_ALL_TOKEN = "*"
45# Key name for adb logcat extra params in config file.
46ANDROID_DEVICE_ADB_LOGCAT_PARAM_KEY = "adb_logcat_param"
47ANDROID_DEVICE_EMPTY_CONFIG_MSG = "Configuration is empty, abort!"
48ANDROID_DEVICE_NOT_LIST_CONFIG_MSG = "Configuration should be a list, abort!"
49
Sahil Jain06dd6a22016-06-24 13:47:37 -070050# Target-side directory where the VTS binaries are uploaded
51DEFAULT_AGENT_BASE_DIR = "/data/local/tmp"
52# Time for which the current is put on sleep when the client is unable to
53# make a connection.
54THREAD_SLEEP_TIME = 1
55# Max number of attempts that the client can make to connect to the agent
56MAX_AGENT_CONNECT_RETRIES = 10
57
Ang Lie2139f12016-05-12 17:39:06 -070058
Ang Li93420002016-05-10 19:11:44 -070059class AndroidDeviceError(signals.ControllerError):
60 pass
61
Ang Lie2139f12016-05-12 17:39:06 -070062
Ang Li7f0e1c72016-06-14 11:23:49 -070063def create(configs):
Ang Li93420002016-05-10 19:11:44 -070064 if not configs:
65 raise AndroidDeviceError(ANDROID_DEVICE_EMPTY_CONFIG_MSG)
66 elif configs == ANDROID_DEVICE_PICK_ALL_TOKEN:
Ang Li7f0e1c72016-06-14 11:23:49 -070067 ads = get_all_instances()
Ang Li93420002016-05-10 19:11:44 -070068 elif not isinstance(configs, list):
69 raise AndroidDeviceError(ANDROID_DEVICE_NOT_LIST_CONFIG_MSG)
70 elif isinstance(configs[0], str):
71 # Configs is a list of serials.
Ang Li7f0e1c72016-06-14 11:23:49 -070072 ads = get_instances(configs)
Ang Li93420002016-05-10 19:11:44 -070073 else:
74 # Configs is a list of dicts.
Ang Li7f0e1c72016-06-14 11:23:49 -070075 ads = get_instances_with_configs(configs)
Ang Li93420002016-05-10 19:11:44 -070076 connected_ads = list_adb_devices()
77 for ad in ads:
78 if ad.serial not in connected_ads:
Ang Lie2139f12016-05-12 17:39:06 -070079 raise AndroidDeviceError(
80 ("Android device %s is specified in config"
81 " but is not attached.") % ad.serial)
Ang Li93420002016-05-10 19:11:44 -070082 ad.startAdbLogcat()
Ang Lie014a8b2016-06-28 18:24:52 -070083 ad.startVtsAgent()
Ang Li93420002016-05-10 19:11:44 -070084 return ads
85
Ang Lie2139f12016-05-12 17:39:06 -070086
Ang Li93420002016-05-10 19:11:44 -070087def destroy(ads):
88 for ad in ads:
Ang Lie014a8b2016-06-28 18:24:52 -070089 ad.stopVtsAgent()
Ang Li93420002016-05-10 19:11:44 -070090 if ad.adb_logcat_process:
91 ad.stopAdbLogcat()
92
Ang Lie2139f12016-05-12 17:39:06 -070093
Ang Li93420002016-05-10 19:11:44 -070094def _parse_device_list(device_list_str, key):
95 """Parses a byte string representing a list of devices. The string is
96 generated by calling either adb or fastboot.
97
98 Args:
99 device_list_str: Output of adb or fastboot.
100 key: The token that signifies a device in device_list_str.
101
102 Returns:
103 A list of android device serial numbers.
104 """
105 clean_lines = str(device_list_str, 'utf-8').strip().split('\n')
106 results = []
107 for line in clean_lines:
108 tokens = line.strip().split('\t')
109 if len(tokens) == 2 and tokens[1] == key:
110 results.append(tokens[0])
111 return results
112
Ang Lie2139f12016-05-12 17:39:06 -0700113
Ang Li93420002016-05-10 19:11:44 -0700114def list_adb_devices():
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700115 """List all target devices connected to the host and detected by adb.
Ang Li93420002016-05-10 19:11:44 -0700116
117 Returns:
118 A list of android device serials. Empty if there's none.
119 """
120 out = adb.AdbProxy().devices()
121 return _parse_device_list(out, "device")
122
Ang Lie2139f12016-05-12 17:39:06 -0700123
Ang Li93420002016-05-10 19:11:44 -0700124def list_fastboot_devices():
125 """List all android devices connected to the computer that are in in
126 fastboot mode. These are detected by fastboot.
127
128 Returns:
129 A list of android device serials. Empty if there's none.
130 """
131 out = fastboot.FastbootProxy().devices()
132 return _parse_device_list(out, "fastboot")
133
Ang Lie2139f12016-05-12 17:39:06 -0700134
Ang Li7f0e1c72016-06-14 11:23:49 -0700135def get_instances(serials):
Ang Li93420002016-05-10 19:11:44 -0700136 """Create AndroidDevice instances from a list of serials.
137
138 Args:
139 serials: A list of android device serials.
Ang Li93420002016-05-10 19:11:44 -0700140
141 Returns:
142 A list of AndroidDevice objects.
143 """
144 results = []
145 for s in serials:
Ang Li7f0e1c72016-06-14 11:23:49 -0700146 results.append(AndroidDevice(s))
Ang Li93420002016-05-10 19:11:44 -0700147 return results
148
Ang Lie2139f12016-05-12 17:39:06 -0700149
Ang Li7f0e1c72016-06-14 11:23:49 -0700150def get_instances_with_configs(configs):
Ang Li93420002016-05-10 19:11:44 -0700151 """Create AndroidDevice instances from a list of json configs.
152
153 Each config should have the required key-value pair "serial".
154
155 Args:
156 configs: A list of dicts each representing the configuration of one
157 android device.
Ang Li93420002016-05-10 19:11:44 -0700158
159 Returns:
160 A list of AndroidDevice objects.
161 """
162 results = []
163 for c in configs:
164 try:
165 serial = c.pop("serial")
166 except KeyError:
167 raise AndroidDeviceError(('Required value "serial" is missing in '
Ang Lie2139f12016-05-12 17:39:06 -0700168 'AndroidDevice config %s.') % c)
Ang Li7f0e1c72016-06-14 11:23:49 -0700169 ad = AndroidDevice(serial)
Ang Li93420002016-05-10 19:11:44 -0700170 ad.loadConfig(c)
171 results.append(ad)
172 return results
173
Ang Lie2139f12016-05-12 17:39:06 -0700174
Ang Li7f0e1c72016-06-14 11:23:49 -0700175def get_all_instances(include_fastboot=False):
Ang Li93420002016-05-10 19:11:44 -0700176 """Create AndroidDevice instances for all attached android devices.
177
178 Args:
179 include_fastboot: Whether to include devices in bootloader mode or not.
Ang Li93420002016-05-10 19:11:44 -0700180
181 Returns:
182 A list of AndroidDevice objects each representing an android device
183 attached to the computer.
184 """
185 if include_fastboot:
186 serial_list = list_adb_devices() + list_fastboot_devices()
Ang Li7f0e1c72016-06-14 11:23:49 -0700187 return get_instances(serial_list)
188 return get_instances(list_adb_devices())
Ang Li93420002016-05-10 19:11:44 -0700189
Ang Lie2139f12016-05-12 17:39:06 -0700190
Ang Li93420002016-05-10 19:11:44 -0700191def filter_devices(ads, func):
192 """Finds the AndroidDevice instances from a list that match certain
193 conditions.
194
195 Args:
196 ads: A list of AndroidDevice instances.
197 func: A function that takes an AndroidDevice object and returns True
198 if the device satisfies the filter condition.
199
200 Returns:
201 A list of AndroidDevice instances that satisfy the filter condition.
202 """
203 results = []
204 for ad in ads:
205 if func(ad):
206 results.append(ad)
207 return results
208
Ang Lie2139f12016-05-12 17:39:06 -0700209
Ang Li93420002016-05-10 19:11:44 -0700210def get_device(ads, **kwargs):
211 """Finds a unique AndroidDevice instance from a list that has specific
212 attributes of certain values.
213
214 Example:
215 get_device(android_devices, label="foo", phone_number="1234567890")
216 get_device(android_devices, model="angler")
217
218 Args:
219 ads: A list of AndroidDevice instances.
220 kwargs: keyword arguments used to filter AndroidDevice instances.
221
222 Returns:
223 The target AndroidDevice instance.
224
225 Raises:
226 AndroidDeviceError is raised if none or more than one device is
227 matched.
228 """
Ang Lie2139f12016-05-12 17:39:06 -0700229
Ang Li93420002016-05-10 19:11:44 -0700230 def _get_device_filter(ad):
231 for k, v in kwargs.items():
232 if not hasattr(ad, k):
233 return False
234 elif getattr(ad, k) != v:
235 return False
236 return True
Ang Lie2139f12016-05-12 17:39:06 -0700237
Ang Li93420002016-05-10 19:11:44 -0700238 filtered = filter_devices(ads, _get_device_filter)
239 if not filtered:
240 raise AndroidDeviceError(("Could not find a target device that matches"
241 " condition: %s.") % kwargs)
242 elif len(filtered) == 1:
243 return filtered[0]
244 else:
245 serials = [ad.serial for ad in filtered]
246 raise AndroidDeviceError("More than one device matched: %s" % serials)
247
Ang Lie2139f12016-05-12 17:39:06 -0700248
Ang Li93420002016-05-10 19:11:44 -0700249def takeBugReports(ads, test_name, begin_time):
250 """Takes bug reports on a list of android devices.
251
252 If you want to take a bug report, call this function with a list of
253 android_device objects in on_fail. But reports will be taken on all the
254 devices in the list concurrently. Bug report takes a relative long
255 time to take, so use this cautiously.
256
257 Args:
258 ads: A list of AndroidDevice instances.
259 test_name: Name of the test case that triggered this bug report.
260 begin_time: Logline format timestamp taken when the test started.
261 """
262 begin_time = vts_logger.normalizeLogLineTimestamp(begin_time)
Ang Lie2139f12016-05-12 17:39:06 -0700263
Ang Li93420002016-05-10 19:11:44 -0700264 def take_br(test_name, begin_time, ad):
265 ad.takeBugReport(test_name, begin_time)
Ang Lie2139f12016-05-12 17:39:06 -0700266
Ang Li93420002016-05-10 19:11:44 -0700267 args = [(test_name, begin_time, ad) for ad in ads]
268 utils.concurrent_exec(take_br, args)
269
Ang Lie2139f12016-05-12 17:39:06 -0700270
Ang Li7f0e1c72016-06-14 11:23:49 -0700271class AndroidDevice(object):
Ang Li93420002016-05-10 19:11:44 -0700272 """Class representing an android device.
273
274 Each object of this class represents one Android device in ACTS, including
275 handles to adb, fastboot, and sl4a clients. In addition to direct adb
276 commands, this object also uses adb port forwarding to talk to the Android
277 device.
278
279 Attributes:
280 serial: A string that's the serial number of the Androi device.
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700281 device_command_port: int, the port number used on the Android device
282 for adb port forwarding (for command-response sessions).
283 device_callback_port: int, the port number used on the Android device
284 for adb port reverse forwarding (for callback sessions).
Ang Lie014a8b2016-06-28 18:24:52 -0700285 log: A logger project with a device-specific prefix for each line -
286 [AndroidDevice|<serial>]
Ang Li93420002016-05-10 19:11:44 -0700287 log_path: A string that is the path where all logs collected on this
288 android device should be stored.
289 adb_logcat_process: A process that collects the adb logcat.
290 adb_logcat_file_path: A string that's the full path to the adb logcat
291 file collected, if any.
Ang Lie014a8b2016-06-28 18:24:52 -0700292 vts_agent_process: A process that runs the HAL agent.
Ang Li93420002016-05-10 19:11:44 -0700293 adb: An AdbProxy object used for interacting with the device via adb.
294 fastboot: A FastbootProxy object used for interacting with the device
295 via fastboot.
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700296 host_command_port: the host-side port for runner to agent sessions
297 (to send commands and receive responses).
298 host_callback_port: the host-side port for agent to runner sessions
299 (to get callbacks from agent).
Ang Li93420002016-05-10 19:11:44 -0700300 """
301
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700302 def __init__(self, serial="", device_port=5001, device_callback_port=5010):
Ang Li93420002016-05-10 19:11:44 -0700303 self.serial = serial
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700304 self.device_command_port = device_port
305 self.device_callback_port = device_callback_port
Ang Lie014a8b2016-06-28 18:24:52 -0700306 self.log = AndroidDeviceLoggerAdapter(logging.getLogger(),
307 {"serial": self.serial})
308 base_log_path = getattr(logging, "log_path", "/tmp/logs/")
Ang Li7f0e1c72016-06-14 11:23:49 -0700309 self.log_path = os.path.join(base_log_path, "AndroidDevice%s" % serial)
Ang Li93420002016-05-10 19:11:44 -0700310 self.adb_logcat_process = None
311 self.adb_logcat_file_path = None
Ang Lie014a8b2016-06-28 18:24:52 -0700312 self.vts_agent_process = None
Ang Li93420002016-05-10 19:11:44 -0700313 self.adb = adb.AdbProxy(serial)
314 self.fastboot = fastboot.FastbootProxy(serial)
315 if not self.isBootloaderMode:
316 self.rootAdb()
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700317 self.host_command_port = adb.get_available_host_port()
318 self.host_callback_port = adb.get_available_host_port()
319 self.adb.tcp_forward(self.host_command_port, self.device_command_port)
Ang Lie014a8b2016-06-28 18:24:52 -0700320 self.adb.reverse_tcp_forward(self.device_callback_port,
321 self.host_callback_port)
322 self.hal = hal_mirror.HalMirror(self.host_command_port,
323 self.host_callback_port)
Keun Soo Yim39bc0b92016-07-06 18:27:15 -0700324 self.lib = lib_mirror.LibMirror(self.host_command_port)
Keun Soo Yim63d67512016-07-01 17:13:47 -0700325 self.shell = shell_mirror.ShellMirror(self.host_command_port)
Ang Li93420002016-05-10 19:11:44 -0700326
327 def __del__(self):
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700328 if self.host_command_port:
329 self.adb.forward("--remove tcp:%s" % self.host_command_port)
Ang Li93420002016-05-10 19:11:44 -0700330 if self.adb_logcat_process:
331 self.stopAdbLogcat()
332
333 @property
334 def isBootloaderMode(self):
335 """True if the device is in bootloader mode.
336 """
337 return self.serial in list_fastboot_devices()
338
339 @property
340 def isAdbRoot(self):
341 """True if adb is running as root for this device.
342 """
343 return "root" in self.adb.shell("id -u").decode("utf-8")
344
345 @property
346 def model(self):
347 """The Android code name for the device.
348 """
349 # If device is in bootloader mode, get mode name from fastboot.
350 if self.isBootloaderMode:
351 out = self.fastboot.getvar("product").strip()
352 # "out" is never empty because of the "total time" message fastboot
353 # writes to stderr.
354 lines = out.decode("utf-8").split('\n', 1)
355 if lines:
356 tokens = lines[0].split(' ')
357 if len(tokens) > 1:
358 return tokens[1].lower()
359 return None
360 out = self.adb.shell('getprop | grep ro.build.product')
361 model = out.decode("utf-8").strip().split('[')[-1][:-1].lower()
362 if model == "sprout":
363 return model
364 else:
365 out = self.adb.shell('getprop | grep ro.product.name')
366 model = out.decode("utf-8").strip().split('[')[-1][:-1].lower()
367 return model
368
369 @property
Ang Li93420002016-05-10 19:11:44 -0700370 def isAdbLogcatOn(self):
371 """Whether there is an ongoing adb logcat collection.
372 """
373 if self.adb_logcat_process:
374 return True
375 return False
376
377 def loadConfig(self, config):
378 """Add attributes to the AndroidDevice object based on json config.
379
380 Args:
381 config: A dictionary representing the configs.
382
383 Raises:
384 AndroidDeviceError is raised if the config is trying to overwrite
385 an existing attribute.
386 """
387 for k, v in config.items():
388 if hasattr(self, k):
Ang Li7f0e1c72016-06-14 11:23:49 -0700389 raise AndroidDeviceError(
390 "Attempting to set existing attribute %s on %s" %
391 (k, self.serial))
Ang Li93420002016-05-10 19:11:44 -0700392 setattr(self, k, v)
393
394 def rootAdb(self):
395 """Change adb to root mode for this device.
396 """
397 if not self.isAdbRoot:
398 self.adb.root()
399 self.adb.wait_for_device()
400 self.adb.remount()
401 self.adb.wait_for_device()
402
Ang Li93420002016-05-10 19:11:44 -0700403 def startAdbLogcat(self):
404 """Starts a standing adb logcat collection in separate subprocesses and
405 save the logcat in a file.
406 """
407 if self.isAdbLogcatOn:
Ang Li7f0e1c72016-06-14 11:23:49 -0700408 raise AndroidDeviceError(("Android device %s already has an adb "
Ang Lie2139f12016-05-12 17:39:06 -0700409 "logcat thread going on. Cannot start "
Ang Li7f0e1c72016-06-14 11:23:49 -0700410 "another one.") % self.serial)
Ang Li7f0e1c72016-06-14 11:23:49 -0700411 f_name = "adblog,%s,%s.txt" % (self.model, self.serial)
Ang Li93420002016-05-10 19:11:44 -0700412 utils.create_dir(self.log_path)
413 logcat_file_path = os.path.join(self.log_path, f_name)
414 try:
415 extra_params = self.adb_logcat_param
416 except AttributeError:
417 extra_params = "-b all"
Ang Li7f0e1c72016-06-14 11:23:49 -0700418 cmd = "adb -s %s logcat -v threadtime %s >> %s" % (
Ang Li93420002016-05-10 19:11:44 -0700419 self.serial, extra_params, logcat_file_path)
420 self.adb_logcat_process = utils.start_standing_subprocess(cmd)
421 self.adb_logcat_file_path = logcat_file_path
422
423 def stopAdbLogcat(self):
424 """Stops the adb logcat collection subprocess.
425 """
426 if not self.isAdbLogcatOn:
Ang Li7f0e1c72016-06-14 11:23:49 -0700427 raise AndroidDeviceError(
428 "Android device %s does not have an ongoing adb logcat collection."
429 % self.serial)
Ang Li93420002016-05-10 19:11:44 -0700430 utils.stop_standing_subprocess(self.adb_logcat_process)
431 self.adb_logcat_process = None
432
433 def takeBugReport(self, test_name, begin_time):
434 """Takes a bug report on the device and stores it in a file.
435
436 Args:
437 test_name: Name of the test case that triggered this bug report.
438 begin_time: Logline format timestamp taken when the test started.
439 """
440 br_path = os.path.join(self.log_path, "BugReports")
441 utils.create_dir(br_path)
Ang Li7f0e1c72016-06-14 11:23:49 -0700442 base_name = ",%s,%s.txt" % (begin_time, self.serial)
Ang Li93420002016-05-10 19:11:44 -0700443 test_name_len = utils.MAX_FILENAME_LEN - len(base_name)
444 out_name = test_name[:test_name_len] + base_name
445 full_out_path = os.path.join(br_path, out_name.replace(' ', '\ '))
446 self.log.info("Taking bugreport for %s on %s", test_name, self.serial)
Ang Li7f0e1c72016-06-14 11:23:49 -0700447 self.adb.bugreport(" > %s" % full_out_path)
Ang Li93420002016-05-10 19:11:44 -0700448 self.log.info("Bugreport for %s taken at %s", test_name, full_out_path)
449
Ang Li93420002016-05-10 19:11:44 -0700450 @utils.timeout(15 * 60)
451 def waitForBootCompletion(self):
452 """Waits for Android framework to broadcast ACTION_BOOT_COMPLETED.
453
454 This function times out after 15 minutes.
455 """
456 self.adb.wait_for_device()
457 while True:
458 try:
459 out = self.adb.shell("getprop sys.boot_completed")
460 completed = out.decode('utf-8').strip()
461 if completed == '1':
462 return
463 except adb.AdbError:
464 # adb shell calls may fail during certain period of booting
465 # process, which is normal. Ignoring these errors.
466 pass
467 time.sleep(5)
468
469 def reboot(self):
Ang Li7f0e1c72016-06-14 11:23:49 -0700470 """Reboots the device and wait for device to complete booting.
Ang Li93420002016-05-10 19:11:44 -0700471
472 This is probably going to print some error messages in console. Only
473 use if there's no other option.
474
Ang Li93420002016-05-10 19:11:44 -0700475 Raises:
476 AndroidDeviceError is raised if waiting for completion timed
477 out.
478 """
479 if self.isBootloaderMode:
480 self.fastboot.reboot()
481 return
482 has_adb_log = self.isAdbLogcatOn
Ang Lie014a8b2016-06-28 18:24:52 -0700483 has_vts_agent = True if self.vts_agent_process else False
Ang Li93420002016-05-10 19:11:44 -0700484 if has_adb_log:
485 self.stopAdbLogcat()
Ang Lie014a8b2016-06-28 18:24:52 -0700486 if has_vts_agent:
487 self.stopVtsAgent()
Ang Li93420002016-05-10 19:11:44 -0700488 self.adb.reboot()
489 self.waitForBootCompletion()
490 self.rootAdb()
Ang Li93420002016-05-10 19:11:44 -0700491 if has_adb_log:
492 self.startAdbLogcat()
Ang Lie014a8b2016-06-28 18:24:52 -0700493 if has_vts_agent:
494 self.startVtsAgent()
Sahil Jain06dd6a22016-06-24 13:47:37 -0700495
Ang Lie014a8b2016-06-28 18:24:52 -0700496 def startVtsAgent(self):
497 """Start HAL agent on the AndroidDevice.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700498
499 This function starts the target side native agent and is persisted
Ang Lie014a8b2016-06-28 18:24:52 -0700500 throughout the test run.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700501 """
Ang Lie014a8b2016-06-28 18:24:52 -0700502 if self.vts_agent_process:
503 raise AndroidDeviceError("HAL agent is already running on %s." %
504 self.serial)
Keun Soo Yima066dd52016-07-01 15:18:28 -0700505
506 cleanup_commands = [
507 "rm -f /data/local/tmp/vts_driver_* /data/local/tmp/vts_agent_callback*"]
Ang Lie014a8b2016-06-28 18:24:52 -0700508 kill_commands = ["killall vts_hal_agent", "killall fuzzer32",
509 "killall fuzzer64"]
Keun Soo Yima066dd52016-07-01 15:18:28 -0700510 cleanup_commands.extend(kill_commands)
511 for cmd in cleanup_commands:
Sahil Jain06dd6a22016-06-24 13:47:37 -0700512 try:
513 self.adb.shell(cmd)
Ang Lie014a8b2016-06-28 18:24:52 -0700514 except adb.AdbError:
515 # Ignore errors from killall in case process was not running.
516 pass
517 vts_agent_log_path = os.path.join(self.log_path, "vts_agent.log")
518 cmd = (
519 'adb -s {s} shell LD_LIBRARY_PATH={path}/64 {path}/64/vts_hal_agent'
Keun Soo Yima066dd52016-07-01 15:18:28 -0700520 ' {path}/32/fuzzer32 {path}/64/fuzzer64 {path}/spec'
521 ' {path}/32/vts_shell_driver32 {path}/64/vts_shell_driver64 >> {log}'
Ang Lie014a8b2016-06-28 18:24:52 -0700522 ).format(s=self.serial,
523 path=DEFAULT_AGENT_BASE_DIR,
524 log=vts_agent_log_path)
525 self.vts_agent_process = utils.start_standing_subprocess(
526 cmd, check_health_delay=1)
Sahil Jain06dd6a22016-06-24 13:47:37 -0700527
Ang Lie014a8b2016-06-28 18:24:52 -0700528 def stopVtsAgent(self):
529 """Stop the HAL agent running on the AndroidDevice.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700530 """
Ang Lie014a8b2016-06-28 18:24:52 -0700531 if self.vts_agent_process:
532 utils.stop_standing_subprocess(self.vts_agent_process)
533 self.vts_agent_process = None
Sahil Jain06dd6a22016-06-24 13:47:37 -0700534
Sahil Jain06dd6a22016-06-24 13:47:37 -0700535
Ang Lie014a8b2016-06-28 18:24:52 -0700536class AndroidDeviceLoggerAdapter(logging.LoggerAdapter):
537 """A wrapper class that attaches a prefix to all log lines from an
538 AndroidDevice object.
539 """
540
541 def process(self, msg, kwargs):
542 """Process every log message written via the wrapped logger object.
543
544 We are adding the prefix "[AndroidDevice|<serial>]" to all log lines.
545
546 Args:
547 msg: string, the original log message.
548 kwargs: dict, the key value pairs that can be used to modify the
549 original log message.
550 """
551 msg = "[AndroidDevice|%s] %s" % (self.extra["serial"], msg)
552 return (msg, kwargs)