• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 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
6from __future__ import print_function
7import re
8import time
9import subprocess
10import sys
11
12class Adb:
13  def __init__(self, device_serial=None, adb_binary=None, echo=False):
14    self.__invocation = [adb_binary]
15    if device_serial:
16      self.__invocation.extend(['-s', device_serial])
17    self.__echo = echo
18    self.__is_root = None
19    self.__has_established_connection = False
20
21  def shell(self, cmd):
22    if self.__echo:
23      self.__echo_shell_cmd(cmd)
24    self.__invoke('shell', cmd)
25
26  def check(self, cmd):
27    if self.__echo:
28      self.__echo_shell_cmd(cmd)
29    self.__establish_connection()
30    result = subprocess.check_output(self.__invocation + ['shell', cmd], encoding='utf-8')
31    if self.__echo:
32      print(result, file=sys.stderr)
33    return result
34
35  def root(self):
36    if not self.is_root():
37      self.__invoke('root')
38      self.__has_established_connection = False
39      self.__is_root = None
40    return self.is_root()
41
42  def is_root(self):
43    if self.__is_root is None:
44      self.__is_root = ('root' == self.check('whoami').strip())
45    return self.__is_root
46
47  def remount(self):
48    self.__invoke('remount')
49
50  def reboot(self):
51    self.__is_root = None
52    self.shell('reboot')
53    self.__has_established_connection = False
54
55  def __echo_shell_cmd(self, cmd):
56    escaped = [re.sub(r'([^a-zA-Z0-9])', r'\\\1', x)
57               for x in cmd.strip().splitlines()]
58    self.__invoke('shell', 'echo', '$(whoami)@$(getprop ro.serialno)$',
59                  " '\n>' ".join(escaped))
60
61  def __invoke(self, *args):
62    self.__establish_connection()
63    subprocess.call(self.__invocation + list(args), stdout=sys.stderr)
64
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
74