blob: a0b3b3bafd036b4d55b8202f23db7c0edaf3546a [file] [log] [blame]
Yabin Cuic5f4f7e2016-11-30 11:46:20 -08001#!/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
Yabin Cui98058a82017-05-08 14:23:19 -070034def is_python3():
35 return sys.version_info >= (3, 0)
36
Yabin Cuic5f4f7e2016-11-30 11:46:20 -080037
38def log_debug(msg):
39 logging.debug(msg)
40
41
42def log_info(msg):
43 logging.info(msg)
44
45
46def log_warning(msg):
47 logging.warning(msg)
48
49
50def log_fatal(msg):
51 raise Exception(msg)
52
Yabin Cui98058a82017-05-08 14:23:19 -070053def str_to_bytes(str):
54 if not is_python3():
55 return str
56 # In python 3, str are wide strings whereas the C api expects 8 bit strings, hence we have to convert
57 # For now using utf-8 as the encoding.
58 return str.encode('utf-8')
59
60def bytes_to_str(bytes):
61 if not is_python3():
62 return bytes
63 return bytes.decode('utf-8')
Yabin Cuic5f4f7e2016-11-30 11:46:20 -080064
65def get_target_binary_path(arch, binary_name):
Yabin Cui43c69632017-01-12 17:18:13 -080066 if arch == 'aarch64':
67 arch = 'arm64'
Yabin Cui8d367ac2017-01-05 15:44:08 -080068 arch_dir = os.path.join(get_script_dir(), "bin", "android", arch)
Yabin Cuic5f4f7e2016-11-30 11:46:20 -080069 if not os.path.isdir(arch_dir):
70 log_fatal("can't find arch directory: %s" % arch_dir)
71 binary_path = os.path.join(arch_dir, binary_name)
72 if not os.path.isfile(binary_path):
73 log_fatal("can't find binary: %s" % binary_path)
74 return binary_path
75
76
77def get_host_binary_path(binary_name):
Yabin Cui8d367ac2017-01-05 15:44:08 -080078 dir = os.path.join(get_script_dir(), 'bin')
Yabin Cuic5f4f7e2016-11-30 11:46:20 -080079 if is_windows():
Yabin Cui8d367ac2017-01-05 15:44:08 -080080 if binary_name.endswith('.so'):
81 binary_name = binary_name[0:-3] + '.dll'
Yabin Cuicbddd382017-05-03 14:46:55 -070082 elif binary_name.find('.') == -1:
83 binary_name += '.exe'
Yabin Cuic5f4f7e2016-11-30 11:46:20 -080084 dir = os.path.join(dir, 'windows')
85 elif sys.platform == 'darwin': # OSX
Yabin Cui8d367ac2017-01-05 15:44:08 -080086 if binary_name.endswith('.so'):
87 binary_name = binary_name[0:-3] + '.dylib'
Yabin Cuic5f4f7e2016-11-30 11:46:20 -080088 dir = os.path.join(dir, 'darwin')
89 else:
90 dir = os.path.join(dir, 'linux')
Yabin Cui8d367ac2017-01-05 15:44:08 -080091 dir = os.path.join(dir, 'x86_64' if sys.maxsize > 2 ** 32 else 'x86')
Yabin Cuic5f4f7e2016-11-30 11:46:20 -080092 binary_path = os.path.join(dir, binary_name)
93 if not os.path.isfile(binary_path):
94 log_fatal("can't find binary: %s" % binary_path)
95 return binary_path
96
97
98class AdbHelper(object):
99 def __init__(self, adb_path):
100 self.adb_path = adb_path
101
Yabin Cui7c83a612016-12-05 14:26:02 -0800102
Yabin Cuic5f4f7e2016-11-30 11:46:20 -0800103 def run(self, adb_args):
104 return self.run_and_return_output(adb_args)[0]
105
Yabin Cui7c83a612016-12-05 14:26:02 -0800106
Yabin Cui21db24b2017-06-05 18:08:23 -0700107 def run_and_return_output(self, adb_args, stdout_file=None):
Yabin Cuic5f4f7e2016-11-30 11:46:20 -0800108 adb_args = [self.adb_path] + adb_args
109 log_debug('run adb cmd: %s' % adb_args)
Yabin Cui21db24b2017-06-05 18:08:23 -0700110 if stdout_file:
Yabin Cuicb38f942017-05-26 11:16:13 -0700111 with open(stdout_file, 'wb') as stdout_fh:
Yabin Cui21db24b2017-06-05 18:08:23 -0700112 returncode = subprocess.call(adb_args, stdout=stdout_fh)
Yabin Cuicb38f942017-05-26 11:16:13 -0700113 stdoutdata = ''
114 else:
115 subproc = subprocess.Popen(adb_args, stdout=subprocess.PIPE)
116 (stdoutdata, _) = subproc.communicate()
117 returncode = subproc.returncode
118 result = (returncode == 0)
Yabin Cui7c83a612016-12-05 14:26:02 -0800119 if stdoutdata:
Yabin Cui98058a82017-05-08 14:23:19 -0700120 stdoutdata = bytes_to_str(stdoutdata)
Yabin Cuic5f4f7e2016-11-30 11:46:20 -0800121 log_debug(stdoutdata)
122 log_debug('run adb cmd: %s [result %s]' % (adb_args, result))
123 return (result, stdoutdata)
124
Yabin Cui7c83a612016-12-05 14:26:02 -0800125 def check_run(self, adb_args):
126 self.check_run_and_return_output(adb_args)
127
128
Yabin Cui21db24b2017-06-05 18:08:23 -0700129 def check_run_and_return_output(self, adb_args, stdout_file=None):
130 result, stdoutdata = self.run_and_return_output(adb_args, stdout_file)
Yabin Cui7c83a612016-12-05 14:26:02 -0800131 if not result:
132 log_fatal('run "adb %s" failed' % adb_args)
133 return stdoutdata
134
135
Yabin Cuic5f4f7e2016-11-30 11:46:20 -0800136 def switch_to_root(self):
137 result, stdoutdata = self.run_and_return_output(['shell', 'whoami'])
138 if not result:
139 return False
140 if stdoutdata.find('root') != -1:
141 return True
Yabin Cui7c83a612016-12-05 14:26:02 -0800142 build_type = self.get_property('ro.build.type')
143 if build_type == 'user':
Yabin Cuic5f4f7e2016-11-30 11:46:20 -0800144 return False
145 self.run(['root'])
146 result, stdoutdata = self.run_and_return_output(['shell', 'whoami'])
147 if result and stdoutdata.find('root') != -1:
148 return True
149 return False
150
Yabin Cui7c83a612016-12-05 14:26:02 -0800151 def get_property(self, name):
152 result, stdoutdata = self.run_and_return_output(['shell', 'getprop', name])
153 if not result:
154 return None
155 return stdoutdata
156
157
158 def set_property(self, name, value):
159 return self.run(['shell', 'setprop', name, value])
160
161
162def load_config(config_file):
163 if not os.path.exists(config_file):
164 log_fatal("can't find config_file: %s" % config_file)
165 config = {}
Yabin Cui98058a82017-05-08 14:23:19 -0700166 if is_python3():
167 with open(config_file, 'r') as fh:
168 source = fh.read()
169 exec(source, config)
170 else:
171 execfile(config_file, config)
Yabin Cui7c83a612016-12-05 14:26:02 -0800172 return config
173
Yabin Cuic5f4f7e2016-11-30 11:46:20 -0800174
Yabin Cui43c69632017-01-12 17:18:13 -0800175logging.getLogger().setLevel(logging.DEBUG)