1#!/usr/bin/env python
2#
3# Copyright (C) 2016 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18"""utils.py: export utility functions.
19"""
20
21from __future__ import print_function
22import logging
23import os.path
24import subprocess
25import sys
26
27def get_script_dir():
28    return os.path.dirname(os.path.realpath(__file__))
29
30
31def is_windows():
32    return sys.platform == 'win32' or sys.platform == 'cygwin'
33
34
35def log_debug(msg):
36    logging.debug(msg)
37
38
39def log_info(msg):
40    logging.info(msg)
41
42
43def log_warning(msg):
44    logging.warning(msg)
45
46
47def log_fatal(msg):
48    raise Exception(msg)
49
50
51def get_target_binary_path(arch, binary_name):
52    if arch == 'aarch64':
53        arch = 'arm64'
54    arch_dir = os.path.join(get_script_dir(), "bin", "android", arch)
55    if not os.path.isdir(arch_dir):
56        log_fatal("can't find arch directory: %s" % arch_dir)
57    binary_path = os.path.join(arch_dir, binary_name)
58    if not os.path.isfile(binary_path):
59        log_fatal("can't find binary: %s" % binary_path)
60    return binary_path
61
62
63def get_host_binary_path(binary_name):
64    dir = os.path.join(get_script_dir(), 'bin')
65    if is_windows():
66        if binary_name.endswith('.so'):
67            binary_name = binary_name[0:-3] + '.dll'
68        dir = os.path.join(dir, 'windows')
69    elif sys.platform == 'darwin': # OSX
70        if binary_name.endswith('.so'):
71            binary_name = binary_name[0:-3] + '.dylib'
72        dir = os.path.join(dir, 'darwin')
73    else:
74        dir = os.path.join(dir, 'linux')
75    dir = os.path.join(dir, 'x86_64' if sys.maxsize > 2 ** 32 else 'x86')
76    binary_path = os.path.join(dir, binary_name)
77    if not os.path.isfile(binary_path):
78        log_fatal("can't find binary: %s" % binary_path)
79    return binary_path
80
81
82class AdbHelper(object):
83    def __init__(self, adb_path):
84        self.adb_path = adb_path
85
86
87    def run(self, adb_args):
88        return self.run_and_return_output(adb_args)[0]
89
90
91    def run_and_return_output(self, adb_args):
92        adb_args = [self.adb_path] + adb_args
93        log_debug('run adb cmd: %s' % adb_args)
94        subproc = subprocess.Popen(adb_args, stdout=subprocess.PIPE)
95        (stdoutdata, _) = subproc.communicate()
96        result = (subproc.returncode == 0)
97        if stdoutdata:
98            log_debug(stdoutdata)
99        log_debug('run adb cmd: %s  [result %s]' % (adb_args, result))
100        return (result, stdoutdata)
101
102
103    def check_run(self, adb_args):
104        self.check_run_and_return_output(adb_args)
105
106
107    def check_run_and_return_output(self, adb_args):
108        result, stdoutdata = self.run_and_return_output(adb_args)
109        if not result:
110            log_fatal('run "adb %s" failed' % adb_args)
111        return stdoutdata
112
113
114    def switch_to_root(self):
115        result, stdoutdata = self.run_and_return_output(['shell', 'whoami'])
116        if not result:
117            return False
118        if stdoutdata.find('root') != -1:
119            return True
120        build_type = self.get_property('ro.build.type')
121        if build_type == 'user':
122            return False
123        self.run(['root'])
124        result, stdoutdata = self.run_and_return_output(['shell', 'whoami'])
125        if result and stdoutdata.find('root') != -1:
126            return True
127        return False
128
129    def get_property(self, name):
130        result, stdoutdata = self.run_and_return_output(['shell', 'getprop', name])
131        if not result:
132            return None
133        return stdoutdata
134
135
136    def set_property(self, name, value):
137        return self.run(['shell', 'setprop', name, value])
138
139
140def load_config(config_file):
141    if not os.path.exists(config_file):
142        log_fatal("can't find config_file: %s" % config_file)
143    config = {}
144    execfile(config_file, config)
145    return config
146
147
148logging.getLogger().setLevel(logging.DEBUG)
149