Home | History | Annotate | Download | only in chromium-trace
      1 # Copyright (c) 2015 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import optparse
      6 import subprocess
      7 import sys
      8 
      9 
     10 class OptionParserIgnoreErrors(optparse.OptionParser):
     11   """Wrapper for OptionParser that ignores errors and produces no output."""
     12 
     13   def error(self, msg):
     14     pass
     15 
     16   def exit(self):
     17     pass
     18 
     19   def print_usage(self):
     20     pass
     21 
     22   def print_help(self):
     23     pass
     24 
     25   def print_version(self):
     26     pass
     27 
     28 
     29 def add_adb_serial(adb_command, device_serial):
     30   if device_serial is not None:
     31     adb_command.insert(1, device_serial)
     32     adb_command.insert(1, '-s')
     33 
     34 
     35 def construct_adb_shell_command(shell_args, device_serial):
     36   adb_command = ['adb', 'shell', ' '.join(shell_args)]
     37   add_adb_serial(adb_command, device_serial)
     38   return adb_command
     39 
     40 
     41 def run_adb_shell(shell_args, device_serial):
     42   """Runs "adb shell" with the given arguments.
     43 
     44   Args:
     45     shell_args: array of arguments to pass to adb shell.
     46     device_serial: if not empty, will add the appropriate command-line
     47         parameters so that adb targets the given device.
     48   Returns:
     49     A tuple containing the adb output (stdout & stderr) and the return code
     50     from adb.  Will exit if adb fails to start.
     51   """
     52   adb_command = construct_adb_shell_command(shell_args, device_serial)
     53 
     54   adb_output = []
     55   adb_return_code = 0
     56   try:
     57     adb_output = subprocess.check_output(adb_command, stderr=subprocess.STDOUT,
     58                                          shell=False, universal_newlines=True)
     59   except OSError as error:
     60     # This usually means that the adb executable was not found in the path.
     61     print >> sys.stderr, ('\nThe command "%s" failed with the following error:'
     62                           % ' '.join(adb_command))
     63     print >> sys.stderr, '    %s\n' % str(error)
     64     print >> sys.stderr, 'Is adb in your path?'
     65     sys.exit(1)
     66   except subprocess.CalledProcessError as error:
     67     # The process exited with an error.
     68     adb_return_code = error.returncode
     69     adb_output = error.output
     70 
     71   return (adb_output, adb_return_code)
     72 
     73 
     74 def get_device_sdk_version():
     75   """Uses adb to attempt to determine the SDK version of a running device."""
     76 
     77   getprop_args = ['getprop', 'ro.build.version.sdk']
     78 
     79   # get_device_sdk_version() is called before we even parse our command-line
     80   # args.  Therefore, parse just the device serial number part of the
     81   # command-line so we can send the adb command to the correct device.
     82   parser = OptionParserIgnoreErrors()
     83   parser.add_option('-e', '--serial', dest='device_serial', type='string')
     84   options, unused_args = parser.parse_args()
     85 
     86   success = False
     87 
     88   adb_output, adb_return_code = run_adb_shell(getprop_args,
     89                                               options.device_serial)
     90 
     91   if adb_return_code == 0:
     92     # ADB may print output other than the version number (e.g. it chould
     93     # print a message about starting the ADB server).
     94     # Break the ADB output into white-space delimited segments.
     95     parsed_output = str.split(adb_output)
     96     if parsed_output:
     97       # Assume that the version number is the last thing printed by ADB.
     98       version_string = parsed_output[-1]
     99       if version_string:
    100         try:
    101           # Try to convert the text into an integer.
    102           version = int(version_string)
    103         except ValueError:
    104           version = -1
    105         else:
    106           success = True
    107 
    108   if not success:
    109     print >> sys.stderr, (
    110         '\nThe command "%s" failed with the following message:'
    111         % ' '.join(getprop_args))
    112     print >> sys.stderr, adb_output
    113     sys.exit(1)
    114 
    115   return version
    116