Home | History | Annotate | Download | only in android
      1 #!/usr/bin/env python
      2 #
      3 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
      4 # Use of this source code is governed by a BSD-style license that can be
      5 # found in the LICENSE file.
      6 
      7 """Provisions Android devices with settings required for bots.
      8 
      9 Usage:
     10   ./provision_devices.py [-d <device serial number>]
     11 """
     12 
     13 import optparse
     14 import os
     15 import re
     16 import subprocess
     17 import sys
     18 import time
     19 
     20 from pylib import android_commands
     21 from pylib import constants
     22 
     23 def KillHostHeartbeat():
     24   ps = subprocess.Popen(['ps', 'aux'], stdout = subprocess.PIPE)
     25   stdout, _ = ps.communicate()
     26   matches = re.findall('\\n.*host_heartbeat.*', stdout)
     27   for match in matches:
     28     print 'An instance of host heart beart running... will kill'
     29     pid = re.findall('(\d+)', match)[1]
     30     subprocess.call(['kill', str(pid)])
     31 
     32 
     33 def LaunchHostHeartbeat():
     34   # Kill if existing host_heartbeat
     35   KillHostHeartbeat()
     36   # Launch a new host_heartbeat
     37   print 'Spawning host heartbeat...'
     38   subprocess.Popen([os.path.join(constants.DIR_SOURCE_ROOT,
     39                                  'build/android/host_heartbeat.py')])
     40 
     41 
     42 def PushAndLaunchAdbReboot(devices, target):
     43   """Pushes and launches the adb_reboot binary on the device.
     44 
     45   Arguments:
     46     devices: The list of serial numbers of the device to which the
     47              adb_reboot binary should be pushed.
     48     target : The build target (example, Debug or Release) which helps in
     49              locating the adb_reboot binary.
     50   """
     51   for device in devices:
     52     print 'Will push and launch adb_reboot on %s' % device
     53     android_cmd = android_commands.AndroidCommands(device)
     54     # Kill if adb_reboot is already running.
     55     android_cmd.KillAllBlocking('adb_reboot', 2)
     56     # Push adb_reboot
     57     print '  Pushing adb_reboot ...'
     58     adb_reboot = os.path.join(constants.DIR_SOURCE_ROOT,
     59                               'out/%s/adb_reboot' % target)
     60     android_cmd.PushIfNeeded(adb_reboot, '/data/local/tmp/')
     61     # Launch adb_reboot
     62     print '  Launching adb_reboot ...'
     63     p = subprocess.Popen(['adb', '-s', device, 'shell'], stdin=subprocess.PIPE)
     64     p.communicate('/data/local/tmp/adb_reboot; exit\n')
     65   LaunchHostHeartbeat()
     66 
     67 
     68 def ProvisionDevices(options):
     69   if options.device is not None:
     70     devices = [options.device]
     71   else:
     72     devices = android_commands.GetAttachedDevices()
     73   for device in devices:
     74     android_cmd = android_commands.AndroidCommands(device)
     75     android_cmd.RunShellCommandWithSU('date -u %f' % time.time())
     76   if options.auto_reconnect:
     77     PushAndLaunchAdbReboot(devices, options.target)
     78 
     79 
     80 def main(argv):
     81   parser = optparse.OptionParser()
     82   parser.add_option('-d', '--device',
     83                     help='The serial number of the device to be provisioned')
     84   parser.add_option('-t', '--target', default='Debug', help='The build target')
     85   parser.add_option(
     86       '-r', '--auto-reconnect', action='store_true',
     87       help='Push binary which will reboot the device on adb disconnections.')
     88   options, args = parser.parse_args(argv[1:])
     89   constants.SetBuildType(options.target)
     90 
     91   if args:
     92     print >> sys.stderr, 'Unused args %s' % args
     93     return 1
     94 
     95   ProvisionDevices(options)
     96 
     97 
     98 if __name__ == '__main__':
     99   sys.exit(main(sys.argv))
    100