Home | History | Annotate | Download | only in util
      1 # Copyright 2013 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 """ A simple device interface for build steps.
      6 
      7 """
      8 
      9 import logging
     10 import os
     11 import re
     12 import sys
     13 
     14 import build_utils
     15 
     16 BUILD_ANDROID_DIR = os.path.join(os.path.dirname(__file__), '..', '..')
     17 sys.path.append(BUILD_ANDROID_DIR)
     18 
     19 from pylib import android_commands
     20 
     21 from pylib.android_commands import GetAttachedDevices
     22 
     23 
     24 class BuildDevice(object):
     25   def __init__(self, configuration):
     26     self.id = configuration['id']
     27     self.description = configuration['description']
     28     self.install_metadata = configuration['install_metadata']
     29     self.adb = android_commands.AndroidCommands(self.id)
     30 
     31   def RunShellCommand(self, *args, **kwargs):
     32     return self.adb.RunShellCommand(*args, **kwargs)
     33 
     34   def PushIfNeeded(self, *args, **kwargs):
     35     return self.adb.PushIfNeeded(*args, **kwargs)
     36 
     37   def GetSerialNumber(self):
     38     return self.id
     39 
     40   def Install(self, *args, **kwargs):
     41     return self.adb.Install(*args, **kwargs)
     42 
     43   def GetInstallMetadata(self, apk_package):
     44     """Gets the metadata on the device for the apk_package apk."""
     45     # Matches lines like:
     46     # -rw-r--r-- system   system    7376582 2013-04-19 16:34 \
     47     #   org.chromium.chrome.testshell.apk
     48     # -rw-r--r-- system   system    7376582 2013-04-19 16:34 \
     49     #   org.chromium.chrome.testshell-1.apk
     50     apk_matcher = lambda s: re.match('.*%s(-[0-9]*)?.apk$' % apk_package, s)
     51     matches = filter(apk_matcher, self.install_metadata)
     52     return matches[0] if matches else None
     53 
     54 
     55 def GetConfigurationForDevice(id):
     56   adb = android_commands.AndroidCommands(id)
     57   configuration = None
     58   has_root = False
     59   is_online = adb.IsOnline()
     60   if is_online:
     61     cmd = 'ls -l /data/app; getprop ro.build.description'
     62     cmd_output = adb.RunShellCommand(cmd)
     63     has_root = not 'Permission denied' in cmd_output[0]
     64     if not has_root:
     65       # Disable warning log messages from EnableAdbRoot()
     66       logging.getLogger().disabled = True
     67       has_root = adb.EnableAdbRoot()
     68       logging.getLogger().disabled = False
     69       cmd_output = adb.RunShellCommand(cmd)
     70 
     71     configuration = {
     72         'id': id,
     73         'description': cmd_output[-1],
     74         'install_metadata': cmd_output[:-1],
     75       }
     76   return configuration, is_online, has_root
     77 
     78 
     79 def WriteConfigurations(configurations, path):
     80   # Currently we only support installing to the first device.
     81   build_utils.WriteJson(configurations[:1], path, only_if_changed=True)
     82 
     83 
     84 def ReadConfigurations(path):
     85   return build_utils.ReadJson(path)
     86 
     87 
     88 def GetBuildDevice(configurations):
     89   assert len(configurations) == 1
     90   return BuildDevice(configurations[0])
     91 
     92 
     93 def GetBuildDeviceFromPath(path):
     94   configurations = ReadConfigurations(path)
     95   if len(configurations) > 0:
     96     return GetBuildDevice(ReadConfigurations(path))
     97   return None
     98 
     99