utils.py revision 8d367acde0d5fd09a3427703dc11583d44eb8199
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):
528d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui    arch_dir = os.path.join(get_script_dir(), "bin", "android", arch)
53c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    if not os.path.isdir(arch_dir):
54c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        log_fatal("can't find arch directory: %s" % arch_dir)
55c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    binary_path = os.path.join(arch_dir, binary_name)
56c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    if not os.path.isfile(binary_path):
57c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        log_fatal("can't find binary: %s" % binary_path)
58c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    return binary_path
59c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
60c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
61c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuidef get_host_binary_path(binary_name):
628d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui    dir = os.path.join(get_script_dir(), 'bin')
63c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    if is_windows():
648d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui        if binary_name.endswith('.so'):
658d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui            binary_name = binary_name[0:-3] + '.dll'
66c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        dir = os.path.join(dir, 'windows')
67c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    elif sys.platform == 'darwin': # OSX
688d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui        if binary_name.endswith('.so'):
698d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui            binary_name = binary_name[0:-3] + '.dylib'
70c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        dir = os.path.join(dir, 'darwin')
71c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    else:
72c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        dir = os.path.join(dir, 'linux')
738d367acde0d5fd09a3427703dc11583d44eb8199Yabin Cui    dir = os.path.join(dir, 'x86_64' if sys.maxsize > 2 ** 32 else 'x86')
74c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    binary_path = os.path.join(dir, binary_name)
75c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    if not os.path.isfile(binary_path):
76c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        log_fatal("can't find binary: %s" % binary_path)
77c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    return binary_path
78c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
79c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
80c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuiclass AdbHelper(object):
81c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    def __init__(self, adb_path):
82c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        self.adb_path = adb_path
83c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
847c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui
85c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    def run(self, adb_args):
86c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        return self.run_and_return_output(adb_args)[0]
87c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
887c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui
89c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    def run_and_return_output(self, adb_args):
90c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        adb_args = [self.adb_path] + adb_args
91c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        log_debug('run adb cmd: %s' % adb_args)
92c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        subproc = subprocess.Popen(adb_args, stdout=subprocess.PIPE)
93c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        (stdoutdata, _) = subproc.communicate()
94c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        result = (subproc.returncode == 0)
957c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui        if stdoutdata:
96c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui            log_debug(stdoutdata)
97c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        log_debug('run adb cmd: %s  [result %s]' % (adb_args, result))
98c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        return (result, stdoutdata)
99c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
1007c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui
1017c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui    def check_run(self, adb_args):
1027c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui        self.check_run_and_return_output(adb_args)
1037c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui
1047c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui
1057c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui    def check_run_and_return_output(self, adb_args):
1067c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui        result, stdoutdata = self.run_and_return_output(adb_args)
1077c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui        if not result:
1087c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui            log_fatal('run "adb %s" failed' % adb_args)
1097c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui        return stdoutdata
1107c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui
1117c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui
112c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    def switch_to_root(self):
113c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        result, stdoutdata = self.run_and_return_output(['shell', 'whoami'])
114c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        if not result:
115c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui            return False
116c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        if stdoutdata.find('root') != -1:
117c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui            return True
1187c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui        build_type = self.get_property('ro.build.type')
1197c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui        if build_type == 'user':
120c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui            return False
121c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        self.run(['root'])
122c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        result, stdoutdata = self.run_and_return_output(['shell', 'whoami'])
123c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        if result and stdoutdata.find('root') != -1:
124c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui            return True
125c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        return False
126c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
1277c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui    def get_property(self, name):
1287c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui        result, stdoutdata = self.run_and_return_output(['shell', 'getprop', name])
1297c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui        if not result:
1307c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui            return None
1317c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui        return stdoutdata
1327c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui
1337c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui
1347c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui    def set_property(self, name, value):
1357c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui        return self.run(['shell', 'setprop', name, value])
1367c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui
1377c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui
1387c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cuidef load_config(config_file):
1397c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui    if not os.path.exists(config_file):
1407c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui        log_fatal("can't find config_file: %s" % config_file)
1417c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui    config = {}
1427c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui    execfile(config_file, config)
1437c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui    return config
1447c83a6129e024993e5611eb2e1dc21cd574b6ab2Yabin Cui
145c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
146c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuilogging.getLogger().setLevel(logging.DEBUG)