blob: 9601dcb500ec187096f7c09489e9f82885d4ca57 [file] [log] [blame]
csmartdalton0262b5c2016-09-19 12:04:56 -07001# Copyright 2016 Google Inc.
2#
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
csmartdaltone4fd0782016-11-09 08:41:23 -08006from __future__ import print_function
csmartdaltond7a9db62016-09-22 05:10:02 -07007import re
Chris Dalton34d90552017-10-20 09:58:32 -06008import time
csmartdalton0262b5c2016-09-19 12:04:56 -07009import subprocess
csmartdalton310d72c2016-10-18 09:19:50 -070010import sys
csmartdalton0262b5c2016-09-19 12:04:56 -070011
csmartdaltond7a9db62016-09-22 05:10:02 -070012class Adb:
Kevin Lubickcccaef12017-10-13 08:15:09 -040013 def __init__(self, device_serial=None, adb_binary=None, echo=False):
14 self.__invocation = [adb_binary]
csmartdaltond7a9db62016-09-22 05:10:02 -070015 if device_serial:
16 self.__invocation.extend(['-s', device_serial])
csmartdaltona1151292016-11-09 15:37:48 -050017 self.__echo = echo
csmartdaltone4fd0782016-11-09 08:41:23 -080018 self.__is_root = None
Chris Dalton88b448a2019-07-26 16:20:04 -040019 self.__has_established_connection = False
csmartdalton0262b5c2016-09-19 12:04:56 -070020
csmartdaltond7a9db62016-09-22 05:10:02 -070021 def shell(self, cmd):
csmartdaltona1151292016-11-09 15:37:48 -050022 if self.__echo:
23 self.__echo_shell_cmd(cmd)
24 self.__invoke('shell', cmd)
csmartdaltond7a9db62016-09-22 05:10:02 -070025
26 def check(self, cmd):
csmartdaltona1151292016-11-09 15:37:48 -050027 if self.__echo:
28 self.__echo_shell_cmd(cmd)
Chris Dalton88b448a2019-07-26 16:20:04 -040029 self.__establish_connection()
csmartdaltond7a9db62016-09-22 05:10:02 -070030 result = subprocess.check_output(self.__invocation + ['shell', cmd])
csmartdaltona1151292016-11-09 15:37:48 -050031 if self.__echo:
32 print(result, file=sys.stderr)
csmartdaltone4fd0782016-11-09 08:41:23 -080033 return result
csmartdaltond7a9db62016-09-22 05:10:02 -070034
csmartdaltone4fd0782016-11-09 08:41:23 -080035 def root(self):
36 if not self.is_root():
csmartdaltona1151292016-11-09 15:37:48 -050037 self.__invoke('root')
Chris Dalton88b448a2019-07-26 16:20:04 -040038 self.__has_established_connection = False
csmartdaltone4fd0782016-11-09 08:41:23 -080039 self.__is_root = None
40 return self.is_root()
csmartdaltond7a9db62016-09-22 05:10:02 -070041
42 def is_root(self):
csmartdaltone4fd0782016-11-09 08:41:23 -080043 if self.__is_root is None:
44 self.__is_root = ('root' == self.check('whoami').strip())
45 return self.__is_root
csmartdaltond7a9db62016-09-22 05:10:02 -070046
47 def remount(self):
csmartdaltona1151292016-11-09 15:37:48 -050048 self.__invoke('remount')
csmartdaltone4fd0782016-11-09 08:41:23 -080049
Chris Dalton34d90552017-10-20 09:58:32 -060050 def reboot(self):
51 self.__is_root = None
52 self.shell('reboot')
Chris Dalton88b448a2019-07-26 16:20:04 -040053 self.__has_established_connection = False
Chris Dalton34d90552017-10-20 09:58:32 -060054
csmartdaltona1151292016-11-09 15:37:48 -050055 def __echo_shell_cmd(self, cmd):
csmartdaltone4fd0782016-11-09 08:41:23 -080056 escaped = [re.sub(r'([^a-zA-Z0-9])', r'\\\1', x)
57 for x in cmd.strip().splitlines()]
csmartdaltona1151292016-11-09 15:37:48 -050058 self.__invoke('shell', 'echo', '$(whoami)@$(getprop ro.serialno)$',
59 " '\n>' ".join(escaped))
60
61 def __invoke(self, *args):
Chris Dalton88b448a2019-07-26 16:20:04 -040062 self.__establish_connection()
csmartdaltona1151292016-11-09 15:37:48 -050063 subprocess.call(self.__invocation + list(args), stdout=sys.stderr)
Chris Dalton88b448a2019-07-26 16:20:04 -040064
65 def __establish_connection(self):
66 if self.__has_established_connection:
67 return
68 self.__has_established_connection = True
69 self.__invoke('wait-for-device')
70 while True:
71 time.sleep(1)
72 if '1' == self.check('getprop sys.boot_completed').strip():
73 break