15bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# Copyright (C) 2016 The Android Open Source Project 25bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# 35bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# Licensed under the Apache License, Version 2.0 (the "License"); 45bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# you may not use this file except in compliance with the License. 55bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# You may obtain a copy of the License at 65bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# 75bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# http://www.apache.org/licenses/LICENSE-2.0 85bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# 95bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# Unless required by applicable law or agreed to in writing, software 105bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# distributed under the License is distributed on an "AS IS" BASIS, 115bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 125bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# See the License for the specific language governing permissions and 135bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# limitations under the License. 145bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond 15dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo'''Module that contains the class UtilAndroid, providing utility method to 16dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leointerface with Android ADB.''' 17dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 18a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummondfrom __future__ import absolute_import 19a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond 20dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport logging 21dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport re 22dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport subprocess 23dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport time 24dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport collections 25dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport multiprocessing 26a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummondtry: 27a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond # Python 3 28a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond import queue 29a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummondexcept ImportError: 30a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond import Queue as queue 31a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond 32a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummondfrom .exception import TestSuiteException 33dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leofrom . import util_log 34dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 35dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 36dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoclass UtilAndroid(object): 37dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Provides some utility methods that interface with Android using adb.''' 38dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # pylint: disable=too-many-public-methods 39dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 40dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def __init__(self, adb_path, lldb_server_path_device, device): 41dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # The path to the adb binary on the local machine 42dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._path_adb = adb_path 43dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # The path to the lldb server binary on the device 44dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._path_lldbserver = lldb_server_path_device 45dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._log = util_log.get_logger() 46dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.device = device 47dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._prop_stacks = collections.defaultdict(list) 48dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return 49dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 50dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo @staticmethod 51dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def _validate_string(string): 52dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Check that a string is valid and not empty. 53dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 54dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 55dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo string: The string to be checked. 56dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 57dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo assert isinstance(string, str) 58dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo assert len(string) > 0 59dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 60dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def adb(self, args, async=False, device=True, timeout=None): 61dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Run an adb command (async optional). 62dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 63dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 64dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo args: The command (including arguments) to run in adb. 65dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo async: Boolean to specify whether adb should run the command 66dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo asynchronously. 67dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo device: boolean to specify whether the serial id of the android 68dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo device should be inserted in the adb command. 69dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo timeout: it specifies the number of seconds to wait for 70dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo a synchronous invocation before aborting. If unspecified or 71dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo None it waits indefinitely for the command to complete. 72dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 73dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Raises: 74dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ValueError: it can be caused by any of the following situations: 75dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo - when both the combination async=True and timeout are 76dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo given. 77dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo - when a timeout <= 0 is specified. 78dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 79dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Returns: 80dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo If adb was synchronously run and the command completed by the 81dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo specified timeout, a string which is the output (standard out and 82dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo error) from adb. Otherwise it returns None. 83dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 84dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 85dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # Form the command 86dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if device: 87dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo cmd = '{0} -s {1} {2}'.format(self._path_adb, self.device, args) 88dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo else: 89dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo cmd = '{0} {1}'.format(self._path_adb, args) 90dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 91dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._log.debug('Execute ADB: %s', cmd) 92dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 93dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if timeout is None: 94dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # local invocation 95dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return_code, output = UtilAndroid._execute_command_local(cmd, async) 96dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 97dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo else: 98dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # remote invocation 99dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if async: 100dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo raise ValueError('Invalid combination: asynchronous invocation ' 101dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 'with timeout specified') 102dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 103dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return_code, output = UtilAndroid._execute_command_remote(cmd, 104dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo timeout) 105dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 106dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if return_code is None: 107dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._log.warn('[ADB] The command timed out: %s', cmd) 108dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 109dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # log the output message 110dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if output is not None: 111dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._adb_log_output(cmd, output, return_code) 112dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 113dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return output 114dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 115dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def adb_retry(self, args, max_num_attempts, timeout): 116dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Attempt to execute the given adb command a certain number of times. 117dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 118dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo The function executes the given command through adb, waiting for its 119dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo completion up to 'timeout' seconds. If the command completes then it 120dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo returns its output. Otherwise it aborts the execution of the adb 121dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo command and re-issues it anew with the same parameters. In case of 122dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo timeout this process is repeated up to 'max_num_attempts'. 123dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 124dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo The purpose of this function is to handle the cases when, for some 125dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo reason, a command sent to 'adb' freezes, blocking the whole test suite 126dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo indefinitely. 127dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 128dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 129dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo args: The command (including arguments) to run in adb. 130dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo max_num_attempts: the max number of attempts to repeat the command 131dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo in case of timeout. 132dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo timeout: it specifies the number of seconds to wait for the adb 133dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo command to complete. 134dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 135dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Raises: 136dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ValueError: when the parameter timeout is invalid (None or <= 0). 137dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 138dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Returns: 139dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo If adb was synchronously run and the command completes by the 140dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo specified timeout, a string which is the output (standard out and 141dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo error) from adb. Otherwise it returns None. 142dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 143dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if timeout is None or timeout <= 0: 144dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo raise ValueError('Invalid value for timeout') 145dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 146dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo output = None 147dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 148dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo for attempt in range(max_num_attempts): 149dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._log.debug('[ADB] Attempt #%d: %s', attempt + 1, args) 150dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo output = self.adb(args, False, True, timeout) 151dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if output: 152dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo break 153dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 154dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return output 155dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 156dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def _adb_log_output(self, cmd, output, return_code): 157dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Save in the log the command & output from `adb`. 158dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 159dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Internal function, helper to record in the log the issued adb command 160dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo together with its output and return code. 161dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 162dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Params: 163dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo cmd: string, the command issued to `adb`. 164dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo output: string, the output retrieved from `adb`. 165dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return_code: int, the return code from `adb`. 166dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 167dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 168dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo message = output.strip() 169dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 170dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # if return_code != 0, we wish to also record the command executed 171dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # (which occurs if and only if we are in verbose mode) 172dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo is_warning = return_code != 0 173dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo threshold = self._log.getEffectiveLevel() 174dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if is_warning and threshold > logging.DEBUG: 175dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._log.warn("[ADB] Command executed: {0}".format(cmd)) 176dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 177dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo level = logging.WARNING if is_warning else logging.DEBUG 178dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if message: 179dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # if message is composed by multiple lines, then print it after 180dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # the log preamble 181dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if re.search('\n', message): 182dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo message = '\n' + message 183dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo else: 184dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo message = '<empty>' 185dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 186dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._log.log(level, 'RC: {0}, Output: {1}'.format(return_code, 187dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo message)) 188dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 189dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def check_adb_alive(self): 190dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Ping the device and raise an exception in case of timeout. 191dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 192dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo It sends a ping message through 'adb shell'. The emulator/device should 193dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo echo the same message back by one minute. If it does not, it raises 194dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo a TestSuiteException. 195dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 196dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Purpose of this method is to check whether 'adb' became frozen or 197dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo stuck. 198dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 199dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Raises: 200dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo TestSuiteException: in case the device/emulator does not reply by 201dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo one minute or the `ping' message is not echoed 202dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo back. 203dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 204dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo token = 'PING' 205dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo log = util_log.get_logger() 206dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo cmd = "echo {0}".format(token) 207dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 208dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo tries = 10 209dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo try_number = tries 210dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo while try_number > 0: 211dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo log.debug('Sending a ping through "adb shell" (try #%s)...', 212dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo try_number) 213dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo output = self.shell(cmd, False, 60) 214dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 215dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if output is None: 216dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo raise TestSuiteException( 217dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 'Timeout when pinging the device/emulator through ' 218dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '"adb shell". Is "adb" stuck or dead?') 219dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo elif token not in output: 220dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo log.debug('Ping failed. Cannot match the token "%s" in "adb ' 221dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 'shell %s"', token, cmd) 222dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo else: 223dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo log.debug('Pong message received') 224dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return 225dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 226dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo try_number -= 1 227dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo time.sleep(5) 228dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 229dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo raise TestSuiteException('Cannot ping the device/emulator through ' 230dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '"adb shell". Tried %s times. Is "adb" stuck ' 231dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 'or dead?' % tries) 232dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 233dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def shell(self, cmd, async=False, timeout=None): 234dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Run a command via the adb shell. 235dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 236dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 237dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo cmd: The command (including arguments) to run in the adb shell. 238dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo async: Boolean to specify whether adb should run the command 239dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo asynchronously. 240dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo timeout: it specifies the number of seconds to wait for 241dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo a synchronous invocation before aborting. If unspecified or 242dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo None it waits indefinitely for the command to complete 243dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 244dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Returns: 245dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo If adb was synchronously run, a string which is the output (standard 246dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo out and error) from adb. Otherwise None. 247dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 248dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return self.adb('shell "{0}"'.format(cmd), async, True, timeout) 249dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 250dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def find_app_pid(self, process_name): 251dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Find the process ID of a process with a given name. 252dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 253dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo If more than one instance of the process is running return the first pid 254dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo it finds. 255dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 256dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 257dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo process_name: A string representing the name of the package or 258dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo binary for which the id should be found. I.e. the 259dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo string or part of the string that shows up in the "ps" 260dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo command. 261dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 262dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Returns: 263dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo An integer representing the id of the process, or None if it was not 264dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo found. 265dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 266dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._validate_string(process_name) 267dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 268dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo pid_output = self.shell('pidof ' + process_name) 269dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo pid_output = re.sub(r'\*.+\*', '', pid_output) 270dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo pids = pid_output.split() 271dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 272dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if len(pids) < 1: 273dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._log.warn('Unable to find pid of: {0}'.format(process_name)) 274dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return None 275dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 276dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if len(pids) > 1: 277dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._log.warn('Found multiple instances of {0} running: {1}' 278dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo .format(process_name, pids)) 279dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 280dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo try: 281dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo pid = int(pids[0]) 282dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._log.info('App pid found: {0}'.format(pids[0])) 283dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return pid 284dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo except ValueError: 285dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return None 286dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 287dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def adb_root(self): 288dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Set adb to be in root mode.''' 289dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.adb('root') 290dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 291dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def _adb_remount(self): 292dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Remount the filesystem of the device.''' 293dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.adb('remount') 294dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 295dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def validate_adb(self): 296dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Validate adb that it can be run. 297dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 298dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Raises: 299dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo TestSuiteException: Unable to validate that adb exists and runs 300dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo successfully. 301dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 302dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo out = self.adb('version', False, False) 303dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if out and 'Android' in out and 'version' in out: 304dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._log.info('adb found: {0}'.format(out)) 305dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return None 306dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo raise TestSuiteException('unable to validate adb') 307dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 308dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def is_booted(self): 309dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' Check if the device/emulator has finished booting. 310dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 311dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Returns: True if the property sys.boot_completed is true, False 312dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo otherwise. 313dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 314dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return self._get_prop('sys.boot_completed').strip() == '1' 315dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 316dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def validate_device(self, check_boot=True, device_substring=''): 317dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Validate that there is at least one device. 318dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 319dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 320dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo check_boot: Boolean to specify whether to check whether the device 321dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo has finished booting as well as being present. 322dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo device_substring: String that needs to be part of the name of the 323dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo device. 324dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 325dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Raises: 326dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo TestSuiteException: There was a failure to run adb to list the 327dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo devices or there is no device connected or 328dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo multiple devices connected without the user 329dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo having specified the device to use. 330dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 331dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 332dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo out = self.adb('devices', False, False) 333dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if not 'List of devices attached' in out: 334dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo raise TestSuiteException('Unable to list devices') 335dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 336dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo lines = out.split('\n') 337dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo found_device = False # True if the specified device is found 338dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo devices = [] 339dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 340dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo for line in lines[1:]: 341dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if '\tdevice' in line and device_substring in line: 342dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo device = line.split()[0] 343dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo devices.append(device) 344dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if self.device: 345dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if self.device == device: 346dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo found_device = True 347dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 348dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if len(devices) == 0: 349dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo raise TestSuiteException('adb is unable to find a connected ' 350dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 'device/emulator to test.') 351dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 352dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if not self.device: 353dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if len(devices) == 1: 354dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.device = devices[0] 355dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo else: 356dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo raise TestSuiteException('Multiple devices connected,' 357dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 'specify -d device id.') 358dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo else: 359dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if not found_device: 360dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo raise TestSuiteException('Couldn\'t find the device {0} that ' 361dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 'was specified, please check -d ' 362dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 'argument'.format(self.device)) 363dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 364dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if check_boot and not self.is_booted(): 365dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo raise TestSuiteException( 366dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 'The device {0} has not yet finished booting.' 367dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo .format(self.device)) 368dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 369dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def device_with_substring_exists(self, device_substring): 370dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Check whether a device exists whose name contains a given string. 371dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 372dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 373dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo device_substring: String that is part of the name of the device to 374dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo look for. 375dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 376dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Raises: 377dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo TestSuiteException: There was a failure to run adb to list the 378dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo devices. 379dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 380dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo out = self.adb('devices', False, False) 381dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if not 'List of devices attached' in out: 382dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo raise TestSuiteException('Unable to list devices') 383dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 384dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo lines = out.split('\n') 385dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 386dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo for line in lines[1:]: 387dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if '\tdevice' in line: 388dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo device = line.split()[0] 389dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if device.find(device_substring) != -1: 390dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return True 391dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 392dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return False 393dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 394dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def get_device_id(self): 395dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Return ID of the device that will be used for running the tests on. 396dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 397dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Returns: 398dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo String representing device ID. 399dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 400dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return self.device 401dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 402dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def _kill_pid(self, pid): 403dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Kill a process identified by its pid by issuing a "kill" command. 404dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 405dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 406dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo pid: The integer that is the process id of the process to be killed. 407dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 408dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.shell('kill -9 ' + str(pid)) 409dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 410dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def stop_app(self, package_name): 411dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Terminate an app by calling am force-stop. 412dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 413dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 414dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo package_name: The string representing the name of the package of the 415dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo app that is to be stopped. 416dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 417dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._validate_string(package_name) 418dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.shell('am force-stop ' + package_name) 419dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 420dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def kill_process(self, name): 421dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Kill a process identified by its name (package name in case of apk). 422dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 423dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Issues the "kill" command. 424dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 425dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 426dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo name: The string representing the name of the binary of the process 427dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo that is to be killed. 428dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 429dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Returns: 430dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo True if the kill command was executed, False if it could not be 431dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo found. 432dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 433dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo pid = self.find_app_pid(name) 434dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if pid: 435dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._kill_pid(pid) 436dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return True 437dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return False 438dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 439dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def kill_all_processes(self, name): 440dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Repeatedly try to call "kill" on a process to ensure it is gone. 441dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 442dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo If the process is still there after 5 attempts reboot the device. 443dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 444dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 445dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo name: The string representing the name of the binary of the process 446dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo that is to be killed. 447dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 448dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Raises: 449dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo TestSuiteException: If the process could not be killed after 5 450dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo attempts and the device then failed to boot 451dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo after rebooting. 452dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 453dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 454dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # try 5 times to kill this process 455dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo for _ in range(1, 5): 456dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if not self.kill_process(name): 457dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return 458dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # stalled process must reboot 459dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._reboot_device() 460dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 461dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def kill_servers(self): 462dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Kill all gdbserver and lldb-server instances. 463dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 464dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Raises: 465dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo TestSuiteException: If gdbserver or lldb-server could not be killed 466dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo after 5 attempts and the device then failed to 467dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo boot after rebooting. 468dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 469dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.kill_all_processes('gdbserver') 470dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.kill_all_processes('lldb-server') 471dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 472dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def launch_elf(self, binary_name): 473dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Launch a binary (compiled with the NDK). 474dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 475dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 476dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo binary_name: The string representing the name of the binary that is 477dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo to be launched. 478dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 479dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Returns: 480dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Boolean, failure if the app is not installed, success otherwise. 481dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 482dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # Ensure the apk is actually installed. 483dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo output = self.shell('ls /data/ | grep ' + binary_name) 484dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if binary_name not in output: 485dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return False 486dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 487dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo stdout = self.shell('exec /data/' + binary_name, True) 488dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._log.info(str(stdout)) 489dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 490dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return True 491dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 492dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def wait_for_device(self): 493dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Ask ADB to wait for a device to become ready.''' 494dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.adb('wait-for-device') 495dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 496dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def _reboot_device(self): 497dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Reboot the remote device. 498dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 499dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Raises: 500dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo TestSuiteException: If the device failed to boot after rebooting. 501dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 502dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.adb('reboot') 503dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.wait_for_device() 504dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # Allow 20 mins boot time to give emulators such as MIPS enough time 505dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo sleeping_countdown = 60*20 506dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo while not self.is_booted(): 507dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo time.sleep(1) 508dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo sleeping_countdown -= 1 509dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if sleeping_countdown == 0: 510dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo raise TestSuiteException('Failed to reboot. Terminating.') 511dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 512dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.adb_root() 513dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.wait_for_device() 514dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._adb_remount() 515dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.wait_for_device() 516dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 517dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def launch_app(self, name, activity): 518dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Launch a Renderscript application. 519dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 520dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 521dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo name: The string representing the name of the app that is to be 522dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo launched. 523dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo activity: The string representing the activity of the app that is to 524dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo be started. 525dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 526dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Returns: 527dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Boolean, failure if the apk is not installed, success otherwise. 528dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 529dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo assert name and activity 530dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 531dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # Ensure the apk is actually installed. 532dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo output = self.shell('pm list packages ' + name) 533dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if not output: 534dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return False 535dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 536a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond cmd = 'am start -S -W {0}/{0}.{1}'.format(name, activity) 537dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo stdout = self.shell(cmd) 538dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 539dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._log.info(str(stdout)) 540dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 541dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return True 542dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 543dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def launch_lldb_platform(self, port): 544dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Launch lldb server and attach to target app. 545dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 546dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 547dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo port: The integer that is the port on which lldb should listen. 548dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 549ea7cbdf5a4f4f987969ca2200ab590b8a4482a54I-Jui (Ray) Sung cmd = "export LLDB_DEBUGSERVER_PATH='{0}';{0} p --listen *:{1}"\ 550dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo .format(self._path_lldbserver, port) 551dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.shell(cmd, True) 552dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo time.sleep(5) 553dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 554dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def forward_port(self, local, remote): 555dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Use adb to forward a device port onto the local machine. 556dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 557dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 558dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo local: The integer that is the local port to forward. 559dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo remote: The integer that is the remote port to which to forward. 560dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 561dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo cmd = 'forward tcp:%s tcp:%s' % (str(local), str(remote)) 562dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.adb(cmd) 563dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 564dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def remove_port_forwarding(self): 565dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Remove all of the forward socket connections open in adb. 566dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 567dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Avoids a windows adb error where we can't bind to a listener 568dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo because too many files are open. 569dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 570dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.adb('forward --remove-all') 571dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 572dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def _get_prop(self, name): 573dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Get the value of an Android system property. 574dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 575dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 576dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo name: Name of the property of interest [string]. 577dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 578dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Returns: 579dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Current value of the property [string]. 580dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 581dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return self.shell('getprop %s' % str(name)) 582dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 583dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def _set_prop(self, name, value): 584dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Set the value of an Android system property. 585dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 586dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 587dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo name: Name of the property of interest [string]. 588dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo value: Desired new value for the property [string or integer]. 589dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 590dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.shell("setprop %s '%s'" % (str(name), str(value))) 591dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 592dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def push_prop(self, name, new_value): 593dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Save the value of an Android system property and set a new value. 594dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 595dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Saves the old value onto a stack so it can be restored later. 596dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 597dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 598dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo name: Name of the property of interest [string]. 599dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo new_value: Desired new value for the property [string or integer]. 600dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 601dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo old_value = self._get_prop(name) 602dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._set_prop(name, new_value) 603dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._prop_stacks[name].append(old_value.strip()) 604dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 605dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def pop_prop(self, name): 606dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Restore the value of an Android system property previously set by 607dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo push_prop. 608dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 609dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 610dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo name: Name of the property of interest [string]. 611dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 612dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Returns: 613dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Current value of the property [string]. 614dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 615dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo old_value = self._prop_stacks[name].pop() 616dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._set_prop(name, old_value) 617dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 618dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def reset_all_props(self): 619dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Restore all the android properties to the state before the first push 620dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 621dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo This is equivalent to popping each property the number of times it has 622dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo been pushed. 623dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 624dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo for name in self._prop_stacks: 625dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if self._prop_stacks[name] != []: 626dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._set_prop(name, self._prop_stacks[name][0]) 627dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._prop_stacks[name] = [] 628dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 629dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def make_device_writeable(self): 630dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' Ensure the device is full writable, in particular the system folder. 631dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 632dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo This disables verity and remounts. 633dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 634dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo output = self.adb('disable-verity') 635dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 636dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # if the remote is an emulator do not even try to reboot 637dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # otherwise check whether a reboot is advised 638dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if (self._get_prop('ro.kernel.qemu') != '1' and output and 639dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 'Now reboot your device for settings to take effect' in output): 640dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._reboot_device() 641dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 642dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self._adb_remount() 643dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.wait_for_device() 644dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.adb_root() 645dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo self.wait_for_device() 646dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 647dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo @staticmethod 648dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def _execute_command_local(command, async=False): 649dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Execute the given shell command in the same process. 650dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 651dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 652dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo command: String, the command to execute 653dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo async: Boolean to specify whether adb should run the command 654dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo asynchronously. 655dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 656dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Returns: 657dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if async == False, it returns a tuple with the return code and 658dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo the output from the executed command. Otherwise the tuple 659dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo (None, None). 660dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 661dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo proc = subprocess.Popen(command, 662dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo stdout=subprocess.PIPE, 663dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo stderr=subprocess.STDOUT, 664dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo shell=True) 665dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo if async: 666dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return None, None 667dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 668dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # read the whole output from the command 669dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo with proc.stdout as file_proc: 670dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo output = ''.join(line for line in file_proc) 671dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 672dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # release the process state 673dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo proc.terminate() 674dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return_code = proc.wait() 675dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 676dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return return_code, output 677dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 678dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo @staticmethod 679dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo def _execute_command_remote(command, timeout): 680dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Execute the given shell command remotely, in a separate process. 681dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 682dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo It spawns an ad hoc process to execute the given command. It waits up 683dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo to timeout for the command to complete, otherwise it aborts the 684dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo execution and returns None. 685dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 686dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 687dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo command: String, the command to execute. 688dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo timeout: the number of seconds to wait for the command to complete. 689dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 690dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Returns: 691dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo a pair with the return code and the output from the command, if it 692dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo completed by the specified 'timeout' seconds. Otherwise the tuple 693dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo (None, None). 694dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 695dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 696dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo channel = multiprocessing.Queue() 697dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo proc = multiprocessing.Process( 698dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo target=_handle_remote_request, 699dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo name="Executor of `{0}'".format(command), 700dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo args=(command, channel) 701dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ) 702dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 703dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # execute the command 704dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo proc.start() 705dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return_code = None 706dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo output = None 707dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 708dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # wait for the result 709dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo try: 710dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return_code, output = channel.get(True, timeout) 711a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond except queue.Empty: 712dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # timeout hit, the remote process has not fulfilled our request by 713dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # the given time. We are going to return <None, None>, nothing to 714dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # do here as it already holds return_code = output = None. 715dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo pass 716dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 717dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo # terminate the helper process 718dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo proc.terminate() 719dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 720dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo return return_code, output 721dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 722dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 723dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leodef _handle_remote_request(command, channel): 724dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo '''Entry point for the remote process. 725dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 726dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo It executes the given command and reports the result into the channel. 727dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo This function is supposed to be only called by 728dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo UtilAndroid._execute_command_remote to handle the inter-process 729dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo communication. 730dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 731dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo Args: 732dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo command: the command to execute. 733dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo channel: the channel to communicate with the caller process. 734dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo ''' 735dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo channel.put(UtilAndroid._execute_command_local(command)) 736dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo 737