blob: 7269a95409638d6153b02d8f2240edc5ad7fd551 [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()
Keun Soo Yimbf8f7b42016-07-13 13:58:28 -070077
Ang Li93420002016-05-10 19:11:44 -070078 for ad in ads:
79 if ad.serial not in connected_ads:
Ang Lie2139f12016-05-12 17:39:06 -070080 raise AndroidDeviceError(
81 ("Android device %s is specified in config"
82 " but is not attached.") % ad.serial)
Ang Li93420002016-05-10 19:11:44 -070083 ad.startAdbLogcat()
Ang Lie014a8b2016-06-28 18:24:52 -070084 ad.startVtsAgent()
Ang Li93420002016-05-10 19:11:44 -070085 return ads
86
Ang Lie2139f12016-05-12 17:39:06 -070087
Ang Li93420002016-05-10 19:11:44 -070088def destroy(ads):
89 for ad in ads:
Ang Lie014a8b2016-06-28 18:24:52 -070090 ad.stopVtsAgent()
Ang Li93420002016-05-10 19:11:44 -070091 if ad.adb_logcat_process:
92 ad.stopAdbLogcat()
93
Ang Lie2139f12016-05-12 17:39:06 -070094
Ang Li93420002016-05-10 19:11:44 -070095def _parse_device_list(device_list_str, key):
96 """Parses a byte string representing a list of devices. The string is
97 generated by calling either adb or fastboot.
98
99 Args:
100 device_list_str: Output of adb or fastboot.
101 key: The token that signifies a device in device_list_str.
102
103 Returns:
104 A list of android device serial numbers.
105 """
106 clean_lines = str(device_list_str, 'utf-8').strip().split('\n')
107 results = []
108 for line in clean_lines:
109 tokens = line.strip().split('\t')
110 if len(tokens) == 2 and tokens[1] == key:
111 results.append(tokens[0])
112 return results
113
Ang Lie2139f12016-05-12 17:39:06 -0700114
Ang Li93420002016-05-10 19:11:44 -0700115def list_adb_devices():
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700116 """List all target devices connected to the host and detected by adb.
Ang Li93420002016-05-10 19:11:44 -0700117
118 Returns:
119 A list of android device serials. Empty if there's none.
120 """
121 out = adb.AdbProxy().devices()
122 return _parse_device_list(out, "device")
123
Ang Lie2139f12016-05-12 17:39:06 -0700124
Ang Li93420002016-05-10 19:11:44 -0700125def list_fastboot_devices():
126 """List all android devices connected to the computer that are in in
127 fastboot mode. These are detected by fastboot.
128
129 Returns:
130 A list of android device serials. Empty if there's none.
131 """
132 out = fastboot.FastbootProxy().devices()
133 return _parse_device_list(out, "fastboot")
134
Ang Lie2139f12016-05-12 17:39:06 -0700135
Ang Li7f0e1c72016-06-14 11:23:49 -0700136def get_instances(serials):
Ang Li93420002016-05-10 19:11:44 -0700137 """Create AndroidDevice instances from a list of serials.
138
139 Args:
140 serials: A list of android device serials.
Ang Li93420002016-05-10 19:11:44 -0700141
142 Returns:
143 A list of AndroidDevice objects.
144 """
145 results = []
146 for s in serials:
Ang Li7f0e1c72016-06-14 11:23:49 -0700147 results.append(AndroidDevice(s))
Ang Li93420002016-05-10 19:11:44 -0700148 return results
149
Ang Lie2139f12016-05-12 17:39:06 -0700150
Ang Li7f0e1c72016-06-14 11:23:49 -0700151def get_instances_with_configs(configs):
Ang Li93420002016-05-10 19:11:44 -0700152 """Create AndroidDevice instances from a list of json configs.
153
154 Each config should have the required key-value pair "serial".
155
156 Args:
157 configs: A list of dicts each representing the configuration of one
158 android device.
Ang Li93420002016-05-10 19:11:44 -0700159
160 Returns:
161 A list of AndroidDevice objects.
162 """
163 results = []
164 for c in configs:
165 try:
166 serial = c.pop("serial")
167 except KeyError:
168 raise AndroidDeviceError(('Required value "serial" is missing in '
Ang Lie2139f12016-05-12 17:39:06 -0700169 'AndroidDevice config %s.') % c)
Ang Li7f0e1c72016-06-14 11:23:49 -0700170 ad = AndroidDevice(serial)
Ang Li93420002016-05-10 19:11:44 -0700171 ad.loadConfig(c)
172 results.append(ad)
173 return results
174
Ang Lie2139f12016-05-12 17:39:06 -0700175
Ang Li7f0e1c72016-06-14 11:23:49 -0700176def get_all_instances(include_fastboot=False):
Ang Li93420002016-05-10 19:11:44 -0700177 """Create AndroidDevice instances for all attached android devices.
178
179 Args:
180 include_fastboot: Whether to include devices in bootloader mode or not.
Ang Li93420002016-05-10 19:11:44 -0700181
182 Returns:
183 A list of AndroidDevice objects each representing an android device
184 attached to the computer.
185 """
186 if include_fastboot:
187 serial_list = list_adb_devices() + list_fastboot_devices()
Ang Li7f0e1c72016-06-14 11:23:49 -0700188 return get_instances(serial_list)
189 return get_instances(list_adb_devices())
Ang Li93420002016-05-10 19:11:44 -0700190
Ang Lie2139f12016-05-12 17:39:06 -0700191
Ang Li93420002016-05-10 19:11:44 -0700192def filter_devices(ads, func):
193 """Finds the AndroidDevice instances from a list that match certain
194 conditions.
195
196 Args:
197 ads: A list of AndroidDevice instances.
198 func: A function that takes an AndroidDevice object and returns True
199 if the device satisfies the filter condition.
200
201 Returns:
202 A list of AndroidDevice instances that satisfy the filter condition.
203 """
204 results = []
205 for ad in ads:
206 if func(ad):
207 results.append(ad)
208 return results
209
Ang Lie2139f12016-05-12 17:39:06 -0700210
Ang Li93420002016-05-10 19:11:44 -0700211def get_device(ads, **kwargs):
212 """Finds a unique AndroidDevice instance from a list that has specific
213 attributes of certain values.
214
215 Example:
216 get_device(android_devices, label="foo", phone_number="1234567890")
217 get_device(android_devices, model="angler")
218
219 Args:
220 ads: A list of AndroidDevice instances.
221 kwargs: keyword arguments used to filter AndroidDevice instances.
222
223 Returns:
224 The target AndroidDevice instance.
225
226 Raises:
227 AndroidDeviceError is raised if none or more than one device is
228 matched.
229 """
Ang Lie2139f12016-05-12 17:39:06 -0700230
Ang Li93420002016-05-10 19:11:44 -0700231 def _get_device_filter(ad):
232 for k, v in kwargs.items():
233 if not hasattr(ad, k):
234 return False
235 elif getattr(ad, k) != v:
236 return False
237 return True
Ang Lie2139f12016-05-12 17:39:06 -0700238
Ang Li93420002016-05-10 19:11:44 -0700239 filtered = filter_devices(ads, _get_device_filter)
240 if not filtered:
241 raise AndroidDeviceError(("Could not find a target device that matches"
242 " condition: %s.") % kwargs)
243 elif len(filtered) == 1:
244 return filtered[0]
245 else:
246 serials = [ad.serial for ad in filtered]
247 raise AndroidDeviceError("More than one device matched: %s" % serials)
248
Ang Lie2139f12016-05-12 17:39:06 -0700249
Ang Li93420002016-05-10 19:11:44 -0700250def takeBugReports(ads, test_name, begin_time):
251 """Takes bug reports on a list of android devices.
252
253 If you want to take a bug report, call this function with a list of
254 android_device objects in on_fail. But reports will be taken on all the
255 devices in the list concurrently. Bug report takes a relative long
256 time to take, so use this cautiously.
257
258 Args:
259 ads: A list of AndroidDevice instances.
260 test_name: Name of the test case that triggered this bug report.
261 begin_time: Logline format timestamp taken when the test started.
262 """
263 begin_time = vts_logger.normalizeLogLineTimestamp(begin_time)
Ang Lie2139f12016-05-12 17:39:06 -0700264
Ang Li93420002016-05-10 19:11:44 -0700265 def take_br(test_name, begin_time, ad):
266 ad.takeBugReport(test_name, begin_time)
Ang Lie2139f12016-05-12 17:39:06 -0700267
Ang Li93420002016-05-10 19:11:44 -0700268 args = [(test_name, begin_time, ad) for ad in ads]
269 utils.concurrent_exec(take_br, args)
270
Ang Lie2139f12016-05-12 17:39:06 -0700271
Ang Li7f0e1c72016-06-14 11:23:49 -0700272class AndroidDevice(object):
Ang Li93420002016-05-10 19:11:44 -0700273 """Class representing an android device.
274
275 Each object of this class represents one Android device in ACTS, including
276 handles to adb, fastboot, and sl4a clients. In addition to direct adb
277 commands, this object also uses adb port forwarding to talk to the Android
278 device.
279
280 Attributes:
281 serial: A string that's the serial number of the Androi device.
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700282 device_command_port: int, the port number used on the Android device
283 for adb port forwarding (for command-response sessions).
284 device_callback_port: int, the port number used on the Android device
285 for adb port reverse forwarding (for callback sessions).
Ang Lie014a8b2016-06-28 18:24:52 -0700286 log: A logger project with a device-specific prefix for each line -
287 [AndroidDevice|<serial>]
Ang Li93420002016-05-10 19:11:44 -0700288 log_path: A string that is the path where all logs collected on this
289 android device should be stored.
290 adb_logcat_process: A process that collects the adb logcat.
291 adb_logcat_file_path: A string that's the full path to the adb logcat
292 file collected, if any.
Ang Lie014a8b2016-06-28 18:24:52 -0700293 vts_agent_process: A process that runs the HAL agent.
Ang Li93420002016-05-10 19:11:44 -0700294 adb: An AdbProxy object used for interacting with the device via adb.
295 fastboot: A FastbootProxy object used for interacting with the device
296 via fastboot.
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700297 host_command_port: the host-side port for runner to agent sessions
298 (to send commands and receive responses).
299 host_callback_port: the host-side port for agent to runner sessions
300 (to get callbacks from agent).
Ang Li93420002016-05-10 19:11:44 -0700301 """
302
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700303 def __init__(self, serial="", device_port=5001, device_callback_port=5010):
Ang Li93420002016-05-10 19:11:44 -0700304 self.serial = serial
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700305 self.device_command_port = device_port
306 self.device_callback_port = device_callback_port
Ang Lie014a8b2016-06-28 18:24:52 -0700307 self.log = AndroidDeviceLoggerAdapter(logging.getLogger(),
308 {"serial": self.serial})
309 base_log_path = getattr(logging, "log_path", "/tmp/logs/")
Ang Li7f0e1c72016-06-14 11:23:49 -0700310 self.log_path = os.path.join(base_log_path, "AndroidDevice%s" % serial)
Ang Li93420002016-05-10 19:11:44 -0700311 self.adb_logcat_process = None
312 self.adb_logcat_file_path = None
Ang Lie014a8b2016-06-28 18:24:52 -0700313 self.vts_agent_process = None
Ang Li93420002016-05-10 19:11:44 -0700314 self.adb = adb.AdbProxy(serial)
315 self.fastboot = fastboot.FastbootProxy(serial)
316 if not self.isBootloaderMode:
317 self.rootAdb()
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700318 self.host_command_port = adb.get_available_host_port()
319 self.host_callback_port = adb.get_available_host_port()
320 self.adb.tcp_forward(self.host_command_port, self.device_command_port)
Ang Lie014a8b2016-06-28 18:24:52 -0700321 self.adb.reverse_tcp_forward(self.device_callback_port,
322 self.host_callback_port)
323 self.hal = hal_mirror.HalMirror(self.host_command_port,
324 self.host_callback_port)
Keun Soo Yim39bc0b92016-07-06 18:27:15 -0700325 self.lib = lib_mirror.LibMirror(self.host_command_port)
Keun Soo Yim63d67512016-07-01 17:13:47 -0700326 self.shell = shell_mirror.ShellMirror(self.host_command_port)
Ang Li93420002016-05-10 19:11:44 -0700327
328 def __del__(self):
Keun Soo Yimcbd8c052016-06-20 15:10:58 -0700329 if self.host_command_port:
330 self.adb.forward("--remove tcp:%s" % self.host_command_port)
Ang Li93420002016-05-10 19:11:44 -0700331 if self.adb_logcat_process:
332 self.stopAdbLogcat()
333
334 @property
335 def isBootloaderMode(self):
Keun Soo Yimc2bc9f82016-07-16 15:36:36 -0700336 """True if the device is in bootloader mode."""
Ang Li93420002016-05-10 19:11:44 -0700337 return self.serial in list_fastboot_devices()
338
339 @property
340 def isAdbRoot(self):
Keun Soo Yimc2bc9f82016-07-16 15:36:36 -0700341 """True if adb is running as root for this device."""
342 id_str = self.adb.shell("id -u").decode("utf-8")
343 self.log.info(id_str)
344 return "root" in id_str
Ang Li93420002016-05-10 19:11:44 -0700345
346 @property
347 def model(self):
Keun Soo Yimc2bc9f82016-07-16 15:36:36 -0700348 """The Android code name for the device."""
Ang Li93420002016-05-10 19:11:44 -0700349 # 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):
Keun Soo Yimc2bc9f82016-07-16 15:36:36 -0700395 """Changes adb to root mode for this device."""
Ang Li93420002016-05-10 19:11:44 -0700396 if not self.isAdbRoot:
Keun Soo Yimc2bc9f82016-07-16 15:36:36 -0700397 try:
398 self.adb.root()
399 except adb.AdbError as e:
400 # adb root is not always possible in the lab
401 logging.exception(e)
Ang Li93420002016-05-10 19:11:44 -0700402 self.adb.wait_for_device()
403 self.adb.remount()
404 self.adb.wait_for_device()
405
Ang Li93420002016-05-10 19:11:44 -0700406 def startAdbLogcat(self):
407 """Starts a standing adb logcat collection in separate subprocesses and
408 save the logcat in a file.
409 """
410 if self.isAdbLogcatOn:
Ang Li7f0e1c72016-06-14 11:23:49 -0700411 raise AndroidDeviceError(("Android device %s already has an adb "
Ang Lie2139f12016-05-12 17:39:06 -0700412 "logcat thread going on. Cannot start "
Ang Li7f0e1c72016-06-14 11:23:49 -0700413 "another one.") % self.serial)
Ang Li7f0e1c72016-06-14 11:23:49 -0700414 f_name = "adblog,%s,%s.txt" % (self.model, self.serial)
Ang Li93420002016-05-10 19:11:44 -0700415 utils.create_dir(self.log_path)
416 logcat_file_path = os.path.join(self.log_path, f_name)
417 try:
418 extra_params = self.adb_logcat_param
419 except AttributeError:
420 extra_params = "-b all"
Ang Li7f0e1c72016-06-14 11:23:49 -0700421 cmd = "adb -s %s logcat -v threadtime %s >> %s" % (
Ang Li93420002016-05-10 19:11:44 -0700422 self.serial, extra_params, logcat_file_path)
423 self.adb_logcat_process = utils.start_standing_subprocess(cmd)
424 self.adb_logcat_file_path = logcat_file_path
425
426 def stopAdbLogcat(self):
427 """Stops the adb logcat collection subprocess.
428 """
429 if not self.isAdbLogcatOn:
Ang Li7f0e1c72016-06-14 11:23:49 -0700430 raise AndroidDeviceError(
431 "Android device %s does not have an ongoing adb logcat collection."
432 % self.serial)
Ang Li93420002016-05-10 19:11:44 -0700433 utils.stop_standing_subprocess(self.adb_logcat_process)
434 self.adb_logcat_process = None
435
436 def takeBugReport(self, test_name, begin_time):
437 """Takes a bug report on the device and stores it in a file.
438
439 Args:
440 test_name: Name of the test case that triggered this bug report.
441 begin_time: Logline format timestamp taken when the test started.
442 """
443 br_path = os.path.join(self.log_path, "BugReports")
444 utils.create_dir(br_path)
Ang Li7f0e1c72016-06-14 11:23:49 -0700445 base_name = ",%s,%s.txt" % (begin_time, self.serial)
Ang Li93420002016-05-10 19:11:44 -0700446 test_name_len = utils.MAX_FILENAME_LEN - len(base_name)
447 out_name = test_name[:test_name_len] + base_name
448 full_out_path = os.path.join(br_path, out_name.replace(' ', '\ '))
449 self.log.info("Taking bugreport for %s on %s", test_name, self.serial)
Ang Li7f0e1c72016-06-14 11:23:49 -0700450 self.adb.bugreport(" > %s" % full_out_path)
Ang Li93420002016-05-10 19:11:44 -0700451 self.log.info("Bugreport for %s taken at %s", test_name, full_out_path)
452
Ang Li93420002016-05-10 19:11:44 -0700453 @utils.timeout(15 * 60)
454 def waitForBootCompletion(self):
455 """Waits for Android framework to broadcast ACTION_BOOT_COMPLETED.
456
457 This function times out after 15 minutes.
458 """
459 self.adb.wait_for_device()
460 while True:
461 try:
462 out = self.adb.shell("getprop sys.boot_completed")
463 completed = out.decode('utf-8').strip()
464 if completed == '1':
465 return
466 except adb.AdbError:
467 # adb shell calls may fail during certain period of booting
468 # process, which is normal. Ignoring these errors.
469 pass
470 time.sleep(5)
471
472 def reboot(self):
Ang Li7f0e1c72016-06-14 11:23:49 -0700473 """Reboots the device and wait for device to complete booting.
Ang Li93420002016-05-10 19:11:44 -0700474
475 This is probably going to print some error messages in console. Only
476 use if there's no other option.
477
Ang Li93420002016-05-10 19:11:44 -0700478 Raises:
479 AndroidDeviceError is raised if waiting for completion timed
480 out.
481 """
482 if self.isBootloaderMode:
483 self.fastboot.reboot()
484 return
485 has_adb_log = self.isAdbLogcatOn
Ang Lie014a8b2016-06-28 18:24:52 -0700486 has_vts_agent = True if self.vts_agent_process else False
Ang Li93420002016-05-10 19:11:44 -0700487 if has_adb_log:
488 self.stopAdbLogcat()
Ang Lie014a8b2016-06-28 18:24:52 -0700489 if has_vts_agent:
490 self.stopVtsAgent()
Ang Li93420002016-05-10 19:11:44 -0700491 self.adb.reboot()
492 self.waitForBootCompletion()
493 self.rootAdb()
Ang Li93420002016-05-10 19:11:44 -0700494 if has_adb_log:
495 self.startAdbLogcat()
Ang Lie014a8b2016-06-28 18:24:52 -0700496 if has_vts_agent:
497 self.startVtsAgent()
Sahil Jain06dd6a22016-06-24 13:47:37 -0700498
Ang Lie014a8b2016-06-28 18:24:52 -0700499 def startVtsAgent(self):
500 """Start HAL agent on the AndroidDevice.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700501
502 This function starts the target side native agent and is persisted
Ang Lie014a8b2016-06-28 18:24:52 -0700503 throughout the test run.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700504 """
Keun Soo Yimab7fb062016-07-13 14:47:19 -0700505 self.log.info("start a VTS agent")
Ang Lie014a8b2016-06-28 18:24:52 -0700506 if self.vts_agent_process:
507 raise AndroidDeviceError("HAL agent is already running on %s." %
508 self.serial)
Keun Soo Yima066dd52016-07-01 15:18:28 -0700509
510 cleanup_commands = [
511 "rm -f /data/local/tmp/vts_driver_* /data/local/tmp/vts_agent_callback*"]
Ang Lie014a8b2016-06-28 18:24:52 -0700512 kill_commands = ["killall vts_hal_agent", "killall fuzzer32",
513 "killall fuzzer64"]
Keun Soo Yima066dd52016-07-01 15:18:28 -0700514 cleanup_commands.extend(kill_commands)
Keun Soo Yimbf8f7b42016-07-13 13:58:28 -0700515 chmod_commands = [
516 "chmod 755 %s/64/vts_hal_agent" % DEFAULT_AGENT_BASE_DIR,
517 "chmod 755 %s/32/fuzzer32" % DEFAULT_AGENT_BASE_DIR,
518 "chmod 755 %s/64/fuzzer64" % DEFAULT_AGENT_BASE_DIR]
519 cleanup_commands.extend(chmod_commands)
Keun Soo Yima066dd52016-07-01 15:18:28 -0700520 for cmd in cleanup_commands:
Sahil Jain06dd6a22016-06-24 13:47:37 -0700521 try:
522 self.adb.shell(cmd)
Keun Soo Yimab7fb062016-07-13 14:47:19 -0700523 except adb.AdbError as e:
524 self.log.warning(
525 "A command to setup the env to start the VTS Agent failed %s", e)
Ang Lie014a8b2016-06-28 18:24:52 -0700526 vts_agent_log_path = os.path.join(self.log_path, "vts_agent.log")
527 cmd = (
528 'adb -s {s} shell LD_LIBRARY_PATH={path}/64 {path}/64/vts_hal_agent'
Keun Soo Yima066dd52016-07-01 15:18:28 -0700529 ' {path}/32/fuzzer32 {path}/64/fuzzer64 {path}/spec'
530 ' {path}/32/vts_shell_driver32 {path}/64/vts_shell_driver64 >> {log}'
Ang Lie014a8b2016-06-28 18:24:52 -0700531 ).format(s=self.serial,
532 path=DEFAULT_AGENT_BASE_DIR,
533 log=vts_agent_log_path)
534 self.vts_agent_process = utils.start_standing_subprocess(
535 cmd, check_health_delay=1)
Sahil Jain06dd6a22016-06-24 13:47:37 -0700536
Ang Lie014a8b2016-06-28 18:24:52 -0700537 def stopVtsAgent(self):
538 """Stop the HAL agent running on the AndroidDevice.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700539 """
Ang Lie014a8b2016-06-28 18:24:52 -0700540 if self.vts_agent_process:
541 utils.stop_standing_subprocess(self.vts_agent_process)
542 self.vts_agent_process = None
Sahil Jain06dd6a22016-06-24 13:47:37 -0700543
Sahil Jain06dd6a22016-06-24 13:47:37 -0700544
Ang Lie014a8b2016-06-28 18:24:52 -0700545class AndroidDeviceLoggerAdapter(logging.LoggerAdapter):
546 """A wrapper class that attaches a prefix to all log lines from an
547 AndroidDevice object.
548 """
549
550 def process(self, msg, kwargs):
551 """Process every log message written via the wrapped logger object.
552
553 We are adding the prefix "[AndroidDevice|<serial>]" to all log lines.
554
555 Args:
556 msg: string, the original log message.
557 kwargs: dict, the key value pairs that can be used to modify the
558 original log message.
559 """
560 msg = "[AndroidDevice|%s] %s" % (self.extra["serial"], msg)
561 return (msg, kwargs)