blob: 431cf073063d51a9928f90402d7b6ce29bec8870 [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()
Keun Soo Yima5a0dc22016-07-16 17:56:19 -0700399 self.adb.wait_for_device()
400 self.adb.remount()
Keun Soo Yim731e9172016-07-16 17:48:39 -0700401 self.adb.wait_for_device()
402 except adb.AdbError as e:
403 # adb wait-for-device is not always possible in the lab
Keun Soo Yima5a0dc22016-07-16 17:56:19 -0700404 # continue with an assumption it's done by the harness.
Keun Soo Yim731e9172016-07-16 17:48:39 -0700405 logging.exception(e)
Ang Li93420002016-05-10 19:11:44 -0700406
Ang Li93420002016-05-10 19:11:44 -0700407 def startAdbLogcat(self):
408 """Starts a standing adb logcat collection in separate subprocesses and
409 save the logcat in a file.
410 """
411 if self.isAdbLogcatOn:
Ang Li7f0e1c72016-06-14 11:23:49 -0700412 raise AndroidDeviceError(("Android device %s already has an adb "
Ang Lie2139f12016-05-12 17:39:06 -0700413 "logcat thread going on. Cannot start "
Ang Li7f0e1c72016-06-14 11:23:49 -0700414 "another one.") % self.serial)
Ang Li7f0e1c72016-06-14 11:23:49 -0700415 f_name = "adblog,%s,%s.txt" % (self.model, self.serial)
Ang Li93420002016-05-10 19:11:44 -0700416 utils.create_dir(self.log_path)
417 logcat_file_path = os.path.join(self.log_path, f_name)
418 try:
419 extra_params = self.adb_logcat_param
420 except AttributeError:
421 extra_params = "-b all"
Ang Li7f0e1c72016-06-14 11:23:49 -0700422 cmd = "adb -s %s logcat -v threadtime %s >> %s" % (
Ang Li93420002016-05-10 19:11:44 -0700423 self.serial, extra_params, logcat_file_path)
424 self.adb_logcat_process = utils.start_standing_subprocess(cmd)
425 self.adb_logcat_file_path = logcat_file_path
426
427 def stopAdbLogcat(self):
428 """Stops the adb logcat collection subprocess.
429 """
430 if not self.isAdbLogcatOn:
Ang Li7f0e1c72016-06-14 11:23:49 -0700431 raise AndroidDeviceError(
432 "Android device %s does not have an ongoing adb logcat collection."
433 % self.serial)
Ang Li93420002016-05-10 19:11:44 -0700434 utils.stop_standing_subprocess(self.adb_logcat_process)
435 self.adb_logcat_process = None
436
437 def takeBugReport(self, test_name, begin_time):
438 """Takes a bug report on the device and stores it in a file.
439
440 Args:
441 test_name: Name of the test case that triggered this bug report.
442 begin_time: Logline format timestamp taken when the test started.
443 """
444 br_path = os.path.join(self.log_path, "BugReports")
445 utils.create_dir(br_path)
Ang Li7f0e1c72016-06-14 11:23:49 -0700446 base_name = ",%s,%s.txt" % (begin_time, self.serial)
Ang Li93420002016-05-10 19:11:44 -0700447 test_name_len = utils.MAX_FILENAME_LEN - len(base_name)
448 out_name = test_name[:test_name_len] + base_name
449 full_out_path = os.path.join(br_path, out_name.replace(' ', '\ '))
450 self.log.info("Taking bugreport for %s on %s", test_name, self.serial)
Ang Li7f0e1c72016-06-14 11:23:49 -0700451 self.adb.bugreport(" > %s" % full_out_path)
Ang Li93420002016-05-10 19:11:44 -0700452 self.log.info("Bugreport for %s taken at %s", test_name, full_out_path)
453
Ang Li93420002016-05-10 19:11:44 -0700454 @utils.timeout(15 * 60)
455 def waitForBootCompletion(self):
456 """Waits for Android framework to broadcast ACTION_BOOT_COMPLETED.
457
458 This function times out after 15 minutes.
459 """
Keun Soo Yim731e9172016-07-16 17:48:39 -0700460 try:
461 self.adb.wait_for_device()
462 except adb.AdbError as e:
463 # adb wait-for-device is not always possible in the lab
464 logging.exception(e)
Ang Li93420002016-05-10 19:11:44 -0700465 while True:
466 try:
467 out = self.adb.shell("getprop sys.boot_completed")
468 completed = out.decode('utf-8').strip()
469 if completed == '1':
470 return
471 except adb.AdbError:
472 # adb shell calls may fail during certain period of booting
473 # process, which is normal. Ignoring these errors.
474 pass
475 time.sleep(5)
476
477 def reboot(self):
Ang Li7f0e1c72016-06-14 11:23:49 -0700478 """Reboots the device and wait for device to complete booting.
Ang Li93420002016-05-10 19:11:44 -0700479
480 This is probably going to print some error messages in console. Only
481 use if there's no other option.
482
Ang Li93420002016-05-10 19:11:44 -0700483 Raises:
484 AndroidDeviceError is raised if waiting for completion timed
485 out.
486 """
487 if self.isBootloaderMode:
488 self.fastboot.reboot()
489 return
490 has_adb_log = self.isAdbLogcatOn
Ang Lie014a8b2016-06-28 18:24:52 -0700491 has_vts_agent = True if self.vts_agent_process else False
Ang Li93420002016-05-10 19:11:44 -0700492 if has_adb_log:
493 self.stopAdbLogcat()
Ang Lie014a8b2016-06-28 18:24:52 -0700494 if has_vts_agent:
495 self.stopVtsAgent()
Ang Li93420002016-05-10 19:11:44 -0700496 self.adb.reboot()
497 self.waitForBootCompletion()
498 self.rootAdb()
Ang Li93420002016-05-10 19:11:44 -0700499 if has_adb_log:
500 self.startAdbLogcat()
Ang Lie014a8b2016-06-28 18:24:52 -0700501 if has_vts_agent:
502 self.startVtsAgent()
Sahil Jain06dd6a22016-06-24 13:47:37 -0700503
Ang Lie014a8b2016-06-28 18:24:52 -0700504 def startVtsAgent(self):
505 """Start HAL agent on the AndroidDevice.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700506
507 This function starts the target side native agent and is persisted
Ang Lie014a8b2016-06-28 18:24:52 -0700508 throughout the test run.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700509 """
Keun Soo Yimab7fb062016-07-13 14:47:19 -0700510 self.log.info("start a VTS agent")
Ang Lie014a8b2016-06-28 18:24:52 -0700511 if self.vts_agent_process:
512 raise AndroidDeviceError("HAL agent is already running on %s." %
513 self.serial)
Keun Soo Yima066dd52016-07-01 15:18:28 -0700514
515 cleanup_commands = [
Keun Soo Yim02da0272016-07-19 07:56:38 -0700516 "rm -f /data/local/tmp/vts_driver_*",
517 "rm -f /data/local/tmp/vts_agent_callback*"]
Ang Lie014a8b2016-06-28 18:24:52 -0700518 kill_commands = ["killall vts_hal_agent", "killall fuzzer32",
Yuexi Ma674e59d2016-07-19 15:39:54 -0700519 "killall fuzzer64", "killall vts_shell_driver32",
520 "killall vts_shell_driver64"]
Keun Soo Yima066dd52016-07-01 15:18:28 -0700521 cleanup_commands.extend(kill_commands)
Keun Soo Yimbf8f7b42016-07-13 13:58:28 -0700522 chmod_commands = [
523 "chmod 755 %s/64/vts_hal_agent" % DEFAULT_AGENT_BASE_DIR,
524 "chmod 755 %s/32/fuzzer32" % DEFAULT_AGENT_BASE_DIR,
Keun Soo Yim02da0272016-07-19 07:56:38 -0700525 "chmod 755 %s/64/fuzzer64" % DEFAULT_AGENT_BASE_DIR,
526 "chmod 755 %s/32/vts_shell_driver32" % DEFAULT_AGENT_BASE_DIR,
527 "chmod 755 %s/64/vts_shell_driver64" % DEFAULT_AGENT_BASE_DIR]
Keun Soo Yimbf8f7b42016-07-13 13:58:28 -0700528 cleanup_commands.extend(chmod_commands)
Keun Soo Yima066dd52016-07-01 15:18:28 -0700529 for cmd in cleanup_commands:
Sahil Jain06dd6a22016-06-24 13:47:37 -0700530 try:
531 self.adb.shell(cmd)
Keun Soo Yimab7fb062016-07-13 14:47:19 -0700532 except adb.AdbError as e:
533 self.log.warning(
534 "A command to setup the env to start the VTS Agent failed %s", e)
Ang Lie014a8b2016-06-28 18:24:52 -0700535 vts_agent_log_path = os.path.join(self.log_path, "vts_agent.log")
536 cmd = (
537 'adb -s {s} shell LD_LIBRARY_PATH={path}/64 {path}/64/vts_hal_agent'
Keun Soo Yima066dd52016-07-01 15:18:28 -0700538 ' {path}/32/fuzzer32 {path}/64/fuzzer64 {path}/spec'
539 ' {path}/32/vts_shell_driver32 {path}/64/vts_shell_driver64 >> {log}'
Ang Lie014a8b2016-06-28 18:24:52 -0700540 ).format(s=self.serial,
541 path=DEFAULT_AGENT_BASE_DIR,
542 log=vts_agent_log_path)
543 self.vts_agent_process = utils.start_standing_subprocess(
544 cmd, check_health_delay=1)
Sahil Jain06dd6a22016-06-24 13:47:37 -0700545
Ang Lie014a8b2016-06-28 18:24:52 -0700546 def stopVtsAgent(self):
547 """Stop the HAL agent running on the AndroidDevice.
Sahil Jain06dd6a22016-06-24 13:47:37 -0700548 """
Ang Lie014a8b2016-06-28 18:24:52 -0700549 if self.vts_agent_process:
550 utils.stop_standing_subprocess(self.vts_agent_process)
551 self.vts_agent_process = None
Sahil Jain06dd6a22016-06-24 13:47:37 -0700552
Sahil Jain06dd6a22016-06-24 13:47:37 -0700553
Ang Lie014a8b2016-06-28 18:24:52 -0700554class AndroidDeviceLoggerAdapter(logging.LoggerAdapter):
555 """A wrapper class that attaches a prefix to all log lines from an
556 AndroidDevice object.
557 """
558
559 def process(self, msg, kwargs):
560 """Process every log message written via the wrapped logger object.
561
562 We are adding the prefix "[AndroidDevice|<serial>]" to all log lines.
563
564 Args:
565 msg: string, the original log message.
566 kwargs: dict, the key value pairs that can be used to modify the
567 original log message.
568 """
569 msg = "[AndroidDevice|%s] %s" % (self.extra["serial"], msg)
570 return (msg, kwargs)