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 subprocess
9import sys
10
11class Adb:
12  def __init__(self, device_serial=None, echo=False):
13    self.__invocation = ['adb']
14    if device_serial:
15      self.__invocation.extend(['-s', device_serial])
16    self.__echo = echo
17    self.__is_root = None
18
19  def shell(self, cmd):
20    if self.__echo:
21      self.__echo_shell_cmd(cmd)
22    self.__invoke('shell', cmd)
23
24  def check(self, cmd):
25    if self.__echo:
26      self.__echo_shell_cmd(cmd)
27    result = subprocess.check_output(self.__invocation + ['shell', cmd])
28    if self.__echo:
29      print(result, file=sys.stderr)
30    return result
31
32  def root(self):
33    if not self.is_root():
34      self.__invoke('root')
35      self.__invoke('wait-for-device')
36      self.__is_root = None
37    return self.is_root()
38
39  def is_root(self):
40    if self.__is_root is None:
41      self.__is_root = ('root' == self.check('whoami').strip())
42    return self.__is_root
43
44  def remount(self):
45    self.__invoke('remount')
46
47  def __echo_shell_cmd(self, cmd):
48    escaped = [re.sub(r'([^a-zA-Z0-9])', r'\\\1', x)
49               for x in cmd.strip().splitlines()]
50    self.__invoke('shell', 'echo', '$(whoami)@$(getprop ro.serialno)$',
51                  " '\n>' ".join(escaped))
52
53  def __invoke(self, *args):
54    subprocess.call(self.__invocation + list(args), stdout=sys.stderr)
55