1#
2# Copyright (C) 2017 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17import subprocess
18
19class AdbHandler(object):
20    """Adb wrapper to execute shell and adb command to the device."""
21
22    def __init__(self, serial=None):
23        self.serial = serial
24        self.adb_cmd = 'adb -s {}'.format(serial)
25
26    def exec_adb_command(self, cmd):
27        """Method to execute an adb command against the device."""
28        cmd = "{} {}".format(self.adb_cmd, cmd)
29        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
30        (out, err) = proc.communicate()
31        ret = proc.returncode
32        if ret == 0:
33            return out
34        raise AdbError(cmd=cmd, stdout=out, stderr=err, ret_code=ret)
35
36    def exec_shell_command(self, cmd):
37        """Method to execute a shell command against the device."""
38        cmd = '{} shell {}'.format(self.adb_cmd, cmd)
39        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
40        (out, err) = proc.communicate()
41        ret = proc.returncode
42        if ret == 0:
43            return out
44        raise AdbError(cmd=cmd, stdout=out, stderr=err, ret_code=ret)
45
46class AdbError(Exception):
47    """Raised when there is an error in adb operations."""
48
49    def __init__(self, cmd, stdout, stderr, ret_code):
50        self.cmd = cmd
51        self.stdout = stdout
52        self.stderr = stderr
53        self.ret_code = ret_code
54
55    def __str__(self):
56        return ('Error executing adb cmd "%s". ret: %d, stdout: %s, stderr: %s'
57                ) % (self.cmd, self.ret_code, self.stdout, self.stderr)
58