• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3.4
2#
3#   Copyright 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
17from acts.libs.proc import job
18
19import logging
20
21
22class FastbootError(Exception):
23    """Raised when there is an error in fastboot operations."""
24
25    def __init__(self, cmd, stdout, stderr, ret_code):
26        self.cmd = cmd
27        self.stdout = stdout
28        self.stderr = stderr
29        self.ret_code = ret_code
30
31    def __str__(self):
32        return ("Error executing fastboot cmd '%s'. ret: %d, stdout: %s,"
33                " stderr: %s") % (self.cmd, self.ret_code, self.stdout,
34                                  self.stderr)
35
36
37class FastbootProxy():
38    """Proxy class for fastboot.
39
40    For syntactic reasons, the '-' in fastboot commands need to be replaced
41    with '_'. Can directly execute fastboot commands on an object:
42    >> fb = FastbootProxy(<serial>)
43    >> fb.devices() # will return the console output of "fastboot devices".
44    """
45
46    def __init__(self, serial="", ssh_connection=None):
47        self.serial = serial
48        if serial:
49            self.fastboot_str = "fastboot -s {}".format(serial)
50        else:
51            self.fastboot_str = "fastboot"
52        self.ssh_connection = ssh_connection
53
54    def _exec_fastboot_cmd(self,
55                           name,
56                           arg_str,
57                           ignore_status=False,
58                           timeout=60):
59        command = ' '.join((self.fastboot_str, name, arg_str))
60        if self.ssh_connection:
61            result = self.connection.run(command,
62                                         ignore_status=True,
63                                         timeout=timeout)
64        else:
65            result = job.run(command, ignore_status=True, timeout=timeout)
66        ret, out, err = result.exit_status, result.stdout, result.stderr
67        # TODO: This is only a temporary workaround for b/34815412.
68        # fastboot getvar outputs to stderr instead of stdout
69        if "getvar" in command:
70            out = err
71        if ret == 0 or ignore_status:
72            return out
73        else:
74            raise FastbootError(
75                cmd=command, stdout=out, stderr=err, ret_code=ret)
76
77    def args(self, *args, **kwargs):
78        return job.run(' '.join((self.fastboot_str, ) + args), **kwargs).stdout
79
80    def __getattr__(self, name):
81        def fastboot_call(*args, **kwargs):
82            clean_name = name.replace('_', '-')
83            arg_str = ' '.join(str(elem) for elem in args)
84            return self._exec_fastboot_cmd(clean_name, arg_str, **kwargs)
85
86        return fastboot_call
87