utils.py revision cbddd3829b6cf125340d1795f04931a5c8ff83ef
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 23c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuiimport os.path 24c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuiimport subprocess 25c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuiimport sys 26c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 27c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef get_script_dir(): 28c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return os.path.dirname(os.path.realpath(__file__)) 29c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 30c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 31c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef is_windows(): 32c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return sys.platform == 'win32' or sys.platform == 'cygwin' 33c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 34c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 35c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef log_debug(msg): 36c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui logging.debug(msg) 37c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 38c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 39c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef log_info(msg): 40c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui logging.info(msg) 41c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 42c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 43c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef log_warning(msg): 44c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui logging.warning(msg) 45c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 46c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 47c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef log_fatal(msg): 48c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui raise Exception(msg) 49c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 50c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 51c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef get_target_binary_path(arch, binary_name): 5243c6963ba019dfc131c8cdb92cd4fcac8e23bba0Yabin Cui if arch == 'aarch64': 5343c6963ba019dfc131c8cdb92cd4fcac8e23bba0Yabin Cui arch = 'arm64' 548d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui arch_dir = os.path.join(get_script_dir(), "bin", "android", arch) 55c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui if not os.path.isdir(arch_dir): 56c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui log_fatal("can't find arch directory: %s" % arch_dir) 57c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui binary_path = os.path.join(arch_dir, binary_name) 58c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui if not os.path.isfile(binary_path): 59c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui log_fatal("can't find binary: %s" % binary_path) 60c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return binary_path 61c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 62c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 63c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef get_host_binary_path(binary_name): 648d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui dir = os.path.join(get_script_dir(), 'bin') 65c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui if is_windows(): 668d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui if binary_name.endswith('.so'): 678d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui binary_name = binary_name[0:-3] + '.dll' 68cbddd3829b6cf125340d1795f04931a5c8ff83efYabin Cui elif binary_name.find('.') == -1: 69cbddd3829b6cf125340d1795f04931a5c8ff83efYabin Cui binary_name += '.exe' 70c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui dir = os.path.join(dir, 'windows') 71c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui elif sys.platform == 'darwin': # OSX 728d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui if binary_name.endswith('.so'): 738d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui binary_name = binary_name[0:-3] + '.dylib' 74c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui dir = os.path.join(dir, 'darwin') 75c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui else: 76c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui dir = os.path.join(dir, 'linux') 778d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui dir = os.path.join(dir, 'x86_64' if sys.maxsize > 2 ** 32 else 'x86') 78c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui binary_path = os.path.join(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 Cuiclass AdbHelper(object): 85c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui def __init__(self, adb_path): 86c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui self.adb_path = adb_path 87c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 887c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 89c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui def run(self, adb_args): 90c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return self.run_and_return_output(adb_args)[0] 91c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 927c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 93c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui def run_and_return_output(self, adb_args): 94c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui adb_args = [self.adb_path] + adb_args 95c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui log_debug('run adb cmd: %s' % adb_args) 96c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui subproc = subprocess.Popen(adb_args, stdout=subprocess.PIPE) 97c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui (stdoutdata, _) = subproc.communicate() 98c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui result = (subproc.returncode == 0) 997c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui if stdoutdata: 100c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui log_debug(stdoutdata) 101c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui log_debug('run adb cmd: %s [result %s]' % (adb_args, result)) 102c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return (result, stdoutdata) 103c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 1047c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 1057c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui def check_run(self, adb_args): 1067c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui self.check_run_and_return_output(adb_args) 1077c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 1087c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 1097c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui def check_run_and_return_output(self, adb_args): 1107c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui result, stdoutdata = self.run_and_return_output(adb_args) 1117c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui if not result: 1127c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui log_fatal('run "adb %s" failed' % adb_args) 1137c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui return stdoutdata 1147c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 1157c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 116c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui def switch_to_root(self): 117c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui result, stdoutdata = self.run_and_return_output(['shell', 'whoami']) 118c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui if not result: 119c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return False 120c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui if stdoutdata.find('root') != -1: 121c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return True 1227c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui build_type = self.get_property('ro.build.type') 1237c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui if build_type == 'user': 124c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return False 125c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui self.run(['root']) 126c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui result, stdoutdata = self.run_and_return_output(['shell', 'whoami']) 127c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui if result and stdoutdata.find('root') != -1: 128c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return True 129c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui return False 130c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 1317c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui def get_property(self, name): 1327c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui result, stdoutdata = self.run_and_return_output(['shell', 'getprop', name]) 1337c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui if not result: 1347c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui return None 1357c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui return stdoutdata 1367c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 1377c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 1387c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui def set_property(self, name, value): 1397c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui return self.run(['shell', 'setprop', name, value]) 1407c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 1417c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 1427c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cuidef load_config(config_file): 1437c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui if not os.path.exists(config_file): 1447c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui log_fatal("can't find config_file: %s" % config_file) 1457c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui config = {} 1467c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui execfile(config_file, config) 1477c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui return config 1487c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui 149c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui 15043c6963ba019dfc131c8cdb92cd4fcac8e23bba0Yabin Cuilogging.getLogger().setLevel(logging.DEBUG) 151