Home | History | Annotate | Download | only in controllers
      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 
     17 from acts.libs.proc import job
     18 
     19 import logging
     20 
     21 
     22 class 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 
     37 class 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