1c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui#!/usr/bin/env python 2c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# 3c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# Copyright (C) 2016 The Android Open Source Project 4c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# 5c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# Licensed under the Apache License, Version 2.0 (the "License"); 6c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# you may not use this file except in compliance with the License. 7c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# You may obtain a copy of the License at 8c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# 9c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# http://www.apache.org/licenses/LICENSE-2.0 10c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# 11c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# Unless required by applicable law or agreed to in writing, software 12c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# distributed under the License is distributed on an "AS IS" BASIS, 13c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# See the License for the specific language governing permissions and 15c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# limitations under the License. 16c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui# 17c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 18c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui"""utils.py: export utility functions. 19c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui""" 20c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 21c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuifrom __future__ import print_function 22c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuiimport logging 23b8439265477bac5e32131a757e90abf510a77bf9Yabin Cuiimport os 24c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuiimport os.path 25c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuiimport subprocess 26c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuiimport sys 27c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 28c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef get_script_dir(): 29c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return os.path.dirname(os.path.realpath(__file__)) 30c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 31c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 32c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef is_windows(): 33c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return sys.platform == 'win32' or sys.platform == 'cygwin' 34c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 35b8439265477bac5e32131a757e90abf510a77bf9Yabin Cuidef is_darwin(): 36b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui return sys.platform == 'darwin' 37b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 3898058a897528620916427e96485c58b8a534c6b3Yabin Cuidef is_python3(): 3998058a897528620916427e96485c58b8a534c6b3Yabin Cui return sys.version_info >= (3, 0) 4098058a897528620916427e96485c58b8a534c6b3Yabin Cui 41c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 42c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef log_debug(msg): 43c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui logging.debug(msg) 44c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 45c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 46c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef log_info(msg): 47c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui logging.info(msg) 48c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 49c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 50c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef log_warning(msg): 51c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui logging.warning(msg) 52c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 53c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 54c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef log_fatal(msg): 55c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui raise Exception(msg) 56c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 57b8439265477bac5e32131a757e90abf510a77bf9Yabin Cuidef log_exit(msg): 58b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui sys.exit(msg) 59b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 6098058a897528620916427e96485c58b8a534c6b3Yabin Cuidef str_to_bytes(str): 6198058a897528620916427e96485c58b8a534c6b3Yabin Cui if not is_python3(): 6298058a897528620916427e96485c58b8a534c6b3Yabin Cui return str 6398058a897528620916427e96485c58b8a534c6b3Yabin Cui # In python 3, str are wide strings whereas the C api expects 8 bit strings, hence we have to convert 6498058a897528620916427e96485c58b8a534c6b3Yabin Cui # For now using utf-8 as the encoding. 6598058a897528620916427e96485c58b8a534c6b3Yabin Cui return str.encode('utf-8') 6698058a897528620916427e96485c58b8a534c6b3Yabin Cui 6798058a897528620916427e96485c58b8a534c6b3Yabin Cuidef bytes_to_str(bytes): 6898058a897528620916427e96485c58b8a534c6b3Yabin Cui if not is_python3(): 6998058a897528620916427e96485c58b8a534c6b3Yabin Cui return bytes 7098058a897528620916427e96485c58b8a534c6b3Yabin Cui return bytes.decode('utf-8') 71c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 72c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef get_target_binary_path(arch, binary_name): 7343c6963ba019dfc131c8cdb92cd4fcac8e23bba0Yabin Cui if arch == 'aarch64': 7443c6963ba019dfc131c8cdb92cd4fcac8e23bba0Yabin Cui arch = 'arm64' 758d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui arch_dir = os.path.join(get_script_dir(), "bin", "android", arch) 76c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui if not os.path.isdir(arch_dir): 77c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui log_fatal("can't find arch directory: %s" % arch_dir) 78c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui binary_path = os.path.join(arch_dir, binary_name) 79c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui if not os.path.isfile(binary_path): 80c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui log_fatal("can't find binary: %s" % binary_path) 81c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return binary_path 82c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 83c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 84c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef get_host_binary_path(binary_name): 858d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui dir = os.path.join(get_script_dir(), 'bin') 86c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui if is_windows(): 878d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui if binary_name.endswith('.so'): 888d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui binary_name = binary_name[0:-3] + '.dll' 89cbddd3829b6cf125340d1795f04931a5c8ff83efYabin Cui elif binary_name.find('.') == -1: 90cbddd3829b6cf125340d1795f04931a5c8ff83efYabin Cui binary_name += '.exe' 91c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui dir = os.path.join(dir, 'windows') 92c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui elif sys.platform == 'darwin': # OSX 938d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui if binary_name.endswith('.so'): 948d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui binary_name = binary_name[0:-3] + '.dylib' 95c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui dir = os.path.join(dir, 'darwin') 96c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui else: 97c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui dir = os.path.join(dir, 'linux') 988d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui dir = os.path.join(dir, 'x86_64' if sys.maxsize > 2 ** 32 else 'x86') 99c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui binary_path = os.path.join(dir, binary_name) 100c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui if not os.path.isfile(binary_path): 101c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui log_fatal("can't find binary: %s" % binary_path) 102c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return binary_path 103c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 104c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 105b8439265477bac5e32131a757e90abf510a77bf9Yabin Cuidef is_executable_available(executable, option='--help'): 106b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui """ Run an executable to see if it exists. """ 107b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui try: 108b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui subproc = subprocess.Popen([executable, option], stdout=subprocess.PIPE, 109b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui stderr=subprocess.PIPE) 110b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui subproc.communicate() 111b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui return subproc.returncode == 0 112b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui except: 113b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui return False 114b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 115b8439265477bac5e32131a757e90abf510a77bf9Yabin Cuiexpected_tool_paths = { 116b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'adb': { 117b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'test_option': 'version', 118b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'darwin': [(True, 'Library/Android/sdk/platform-tools/adb'), 119b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui (False, '../../platform-tools/adb')], 120b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'linux': [(True, 'Android/Sdk/platform-tools/adb'), 121b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui (False, '../../platform-tools/adb')], 122b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'windows': [(True, 'AppData/Local/Android/sdk/platform-tools/adb'), 123b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui (False, '../../platform-tools/adb')], 124b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui }, 125b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'readelf': { 126b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'test_option': '--help', 127b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'darwin': [(True, 'Library/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-readelf'), 128b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui (False, '../toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-readelf')], 129b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'linux': [(True, 'Android/Sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-readelf'), 130b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui (False, '../toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-readelf')], 131b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'windows': [(True, 'AppData/Local/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/aarch64-linux-android-readelf'), 132b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui (False, '../toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/aarch64-linux-android-readelf')], 133b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui }, 134b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'addr2line': { 135b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'test_option': '--help', 136b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'darwin': [(True, 'Library/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-addr2line'), 137b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui (False, '../toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-addr2line')], 138b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'linux': [(True, 'Android/Sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-addr2line'), 139b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui (False, '../toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-addr2line')], 140b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 'windows': [(True, 'AppData/Local/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/aarch64-linux-android-addr2line'), 141b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui (False, '../toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/aarch64-linux-android-addr2line')], 142b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui }, 143b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui} 144b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 145b8439265477bac5e32131a757e90abf510a77bf9Yabin Cuidef find_tool_path(toolname): 146b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui if toolname not in expected_tool_paths: 147b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui return None 148b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui test_option = expected_tool_paths[toolname]['test_option'] 149b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui if is_executable_available(toolname, test_option): 150b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui return toolname 151b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui platform = 'linux' 152b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui if is_windows(): 153b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui platform = 'windows' 154b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui elif is_darwin(): 155b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui platform = 'darwin' 156b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui paths = expected_tool_paths[toolname][platform] 157b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui home = os.environ.get('HOMEPATH') if is_windows() else os.environ.get('HOME') 158b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui for (relative_to_home, path) in paths: 159b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui path = path.replace('/', os.sep) 160b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui if relative_to_home: 161b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui path = os.path.join(home, path) 162b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui else: 163b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui path = os.path.join(get_script_dir(), path) 164b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui if is_executable_available(path, test_option): 165b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui return path 166b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui return None 167b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 168b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 169c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuiclass AdbHelper(object): 170b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui def __init__(self): 171b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui adb_path = find_tool_path('adb') 172b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui if not adb_path: 173b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui log_exit("Can't find adb in PATH environment.") 174c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui self.adb_path = adb_path 175c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 1767c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 177c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui def run(self, adb_args): 178c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return self.run_and_return_output(adb_args)[0] 179c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 1807c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 18121db24b10e5fd3f1833569ae5f957e114172e1d2Yabin Cui def run_and_return_output(self, adb_args, stdout_file=None): 182c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui adb_args = [self.adb_path] + adb_args 183c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui log_debug('run adb cmd: %s' % adb_args) 18421db24b10e5fd3f1833569ae5f957e114172e1d2Yabin Cui if stdout_file: 185cb38f9409733232cad495fba96590aba15fb073bYabin Cui with open(stdout_file, 'wb') as stdout_fh: 18621db24b10e5fd3f1833569ae5f957e114172e1d2Yabin Cui returncode = subprocess.call(adb_args, stdout=stdout_fh) 187cb38f9409733232cad495fba96590aba15fb073bYabin Cui stdoutdata = '' 188cb38f9409733232cad495fba96590aba15fb073bYabin Cui else: 189cb38f9409733232cad495fba96590aba15fb073bYabin Cui subproc = subprocess.Popen(adb_args, stdout=subprocess.PIPE) 190cb38f9409733232cad495fba96590aba15fb073bYabin Cui (stdoutdata, _) = subproc.communicate() 191cb38f9409733232cad495fba96590aba15fb073bYabin Cui returncode = subproc.returncode 192cb38f9409733232cad495fba96590aba15fb073bYabin Cui result = (returncode == 0) 193b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui if stdoutdata and adb_args[1] != 'push' and adb_args[1] != 'pull': 19498058a897528620916427e96485c58b8a534c6b3Yabin Cui stdoutdata = bytes_to_str(stdoutdata) 195c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui log_debug(stdoutdata) 196c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui log_debug('run adb cmd: %s [result %s]' % (adb_args, result)) 197c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return (result, stdoutdata) 198c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 1997c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui def check_run(self, adb_args): 2007c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui self.check_run_and_return_output(adb_args) 2017c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 2027c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 20321db24b10e5fd3f1833569ae5f957e114172e1d2Yabin Cui def check_run_and_return_output(self, adb_args, stdout_file=None): 20421db24b10e5fd3f1833569ae5f957e114172e1d2Yabin Cui result, stdoutdata = self.run_and_return_output(adb_args, stdout_file) 2057c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui if not result: 206b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui log_exit('run "adb %s" failed' % adb_args) 2077c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui return stdoutdata 2087c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 2097c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 210c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui def switch_to_root(self): 211c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui result, stdoutdata = self.run_and_return_output(['shell', 'whoami']) 212c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui if not result: 213c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return False 214c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui if stdoutdata.find('root') != -1: 215c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return True 2167c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui build_type = self.get_property('ro.build.type') 2177c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui if build_type == 'user': 218c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return False 219c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui self.run(['root']) 220c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui result, stdoutdata = self.run_and_return_output(['shell', 'whoami']) 221c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui if result and stdoutdata.find('root') != -1: 222c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return True 223c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return False 224c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 2257c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui def get_property(self, name): 2267c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui result, stdoutdata = self.run_and_return_output(['shell', 'getprop', name]) 2277c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui if not result: 2287c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui return None 2297c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui return stdoutdata 2307c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 2317c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 2327c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui def set_property(self, name, value): 2337c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui return self.run(['shell', 'setprop', name, value]) 2347c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 2357c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 2367c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cuidef load_config(config_file): 2377c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui if not os.path.exists(config_file): 238b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui log_exit("can't find config_file: %s" % config_file) 2397c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui config = {} 24098058a897528620916427e96485c58b8a534c6b3Yabin Cui if is_python3(): 24198058a897528620916427e96485c58b8a534c6b3Yabin Cui with open(config_file, 'r') as fh: 24298058a897528620916427e96485c58b8a534c6b3Yabin Cui source = fh.read() 24398058a897528620916427e96485c58b8a534c6b3Yabin Cui exec(source, config) 24498058a897528620916427e96485c58b8a534c6b3Yabin Cui else: 24598058a897528620916427e96485c58b8a534c6b3Yabin Cui execfile(config_file, config) 2467c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui return config 2477c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 248c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 249b8439265477bac5e32131a757e90abf510a77bf9Yabin Cuidef flatten_arg_list(arg_list): 250b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui res = [] 251b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui if arg_list: 252b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui for items in arg_list: 253b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui res += items 254b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui return res 255b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 256b8439265477bac5e32131a757e90abf510a77bf9Yabin Cui 25743c6963ba019dfc131c8cdb92cd4fcac8e23bba0Yabin Cuilogging.getLogger().setLevel(logging.DEBUG) 258