utils.py revision c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8a
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):
52c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    arch_dir = os.path.join(get_script_path(), "shared_libraries", "target", 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):
62c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    dir = os.path.join(get_script_dir(), 'shared_libraries', 'host')
63c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    if not os.path.isdir(dir):
64c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        log_fatal("can't find directory: %s" % dir)
65c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    if is_windows():
66c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        if so_name.endswith('.so'):
67c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui            so_name = so_name[0:-3] + '.dll'
68c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        dir = os.path.join(dir, 'windows')
69c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    elif sys.platform == 'darwin': # OSX
70c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        if so_name.endswith('.so'):
71c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui            so_name = so_name[0:-3] + '.dylib'
72c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        dir = os.path.join(dir, 'darwin')
73c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    else:
74c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        dir = os.path.join(dir, 'linux')
75c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    if not os.path.isdir(dir):
76c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        log_fatal("can't find directory: %s" % dir)
77c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    binary_path = os.path.join(dir, binary_name)
78c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    if not os.path.isfile(binary_path):
79c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        log_fatal("can't find binary: %s" % binary_path)
80c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    return binary_path
81c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
82c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
83c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuiclass AdbHelper(object):
84c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    def __init__(self, adb_path):
85c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        self.adb_path = adb_path
86c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
87c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    def run(self, adb_args):
88c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        return self.run_and_return_output(adb_args)[0]
89c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
90c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    def run_and_return_output(self, adb_args):
91c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        adb_args = [self.adb_path] + adb_args
92c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        log_debug('run adb cmd: %s' % adb_args)
93c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        subproc = subprocess.Popen(adb_args, stdout=subprocess.PIPE)
94c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        (stdoutdata, _) = subproc.communicate()
95c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        result = (subproc.returncode == 0)
96c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        if len(stdoutdata) > 0:
97c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui            log_debug(stdoutdata)
98c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        log_debug('run adb cmd: %s  [result %s]' % (adb_args, result))
99c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        return (result, stdoutdata)
100c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
101c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui    def switch_to_root(self):
102c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        result, stdoutdata = self.run_and_return_output(['shell', 'whoami'])
103c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        if not result:
104c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui            return False
105c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        if stdoutdata.find('root') != -1:
106c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui            return True
107c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        result, stdoutdata = self.run_and_return_output(['shell', 'getprop', 'ro.build.type'])
108c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        if not result:
109c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui            return False
110c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        if stdoutdata.strip() == 'user':
111c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui            return False
112c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        self.run(['root'])
113c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        result, stdoutdata = self.run_and_return_output(['shell', 'whoami'])
114c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        if result and stdoutdata.find('root') != -1:
115c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui            return True
116c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui        return False
117c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
118c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cui
119c5f4f7e30bf4d1becffbefe99cc8b7a0f76cdb8aYabin Cuilogging.getLogger().setLevel(logging.DEBUG)