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 module to hold adb specific action implementations.""" 6 7import re 8 9import cr 10 11 12class Adb(object): 13 """Exposes the functionality of the adb tool to the rest of cr. 14 15 This is intended as the only class in the cr that needs to understand the 16 adb command line, and expose it in neutral form to the rest of the code. 17 """ 18 19 # Tracks the set of killed target names, so we don't keep issuing kill 20 # commands that are not going to have any effect. 21 _kills = {} 22 23 @classmethod 24 def GetPids(cls, target): 25 """Gets the set of running PIDs that match the specified target.""" 26 pids = [] 27 with target: 28 output = cr.Host.Capture('{CR_ADB}', 'shell', 'ps') 29 pattern = re.compile(r'\S+\s+(\d+)\s+.*{CR_PROCESS}') 30 for line in output.split('\n'): 31 match = re.match(pattern, line) 32 if match: 33 pids.append(match.group(1)) 34 return pids 35 36 @classmethod 37 def Run(cls, target, arguments): 38 """Invoke a target binary on the device.""" 39 with target: 40 cr.Host.Execute( 41 '{CR_ADB}', 'shell', 'am', 'start', 42 '-a', '{CR_ACTION}', 43 '-n', '{CR_INTENT}', 44 '{CR_RUN_ARGUMENTS}', 45 *arguments 46 ) 47 48 @classmethod 49 def Kill(cls, target, _): 50 """Kill all running processes for a target.""" 51 target_name = target.build_target 52 if target_name in cls._kills: 53 # already killed this target, do nothing 54 return 55 pids = cls.GetPids(target) 56 if pids: 57 with target: 58 cr.Host.Execute('{CR_ADB}', 'shell', 'kill', *pids) 59 elif target.verbose: 60 print target.Substitute('{CR_TARGET_NAME} not running') 61 cls._kills[target_name] = True 62 63 @classmethod 64 def Uninstall(cls, target, arguments): 65 with target: 66 cr.Host.Execute( 67 '{CR_ADB}', 'uninstall', 68 '{CR_PACKAGE}', 69 *arguments 70 ) 71 72 @classmethod 73 def Install(cls, target, arguments): 74 with target: 75 cr.Host.Execute( 76 '{CR_ADB}', 'install', 77 '{CR_BINARY}', 78 *arguments 79 ) 80 81 @classmethod 82 def Reinstall(cls, target, arguments): 83 with target: 84 cr.Host.Execute( 85 '{CR_ADB}', 'install', 86 '-r', 87 '{CR_BINARY}', 88 *arguments 89 ) 90 91 @classmethod 92 def AttachGdb(cls, target, arguments): 93 with target: 94 cr.Host.Execute( 95 '{CR_ADB_GDB}', 96 '--adb={CR_ADB}', 97 '--symbol-dir=${CR_BUILD_DIR}/lib', 98 '--program-name={CR_TARGET_NAME}', 99 '--package-name={CR_PACKAGE}', 100 *arguments 101 ) 102 103 104class AdbRunner(cr.Runner): 105 """An implementation of cr.Runner for the android platform.""" 106 107 @property 108 def enabled(self): 109 return cr.AndroidPlatform.GetInstance().is_active 110 111 def Kill(self, targets, arguments): 112 for target in targets: 113 Adb.Kill(target, arguments) 114 115 def Run(self, target, arguments): 116 Adb.Run(target, arguments) 117 118 def Test(self, target, arguments): 119 with target: 120 cr.Host.Execute( 121 '{CR_TEST_RUNNER}', '{CR_TEST_TYPE}', 122 '-s', '{CR_TARGET_NAME}', 123 '--{CR_TEST_MODE}', 124 *arguments 125 ) 126 127 128class AdbInstaller(cr.Installer): 129 """An implementation of cr.Installer for the android platform.""" 130 131 @property 132 def enabled(self): 133 return cr.AndroidPlatform.GetInstance().is_active 134 135 def Uninstall(self, targets, arguments): 136 for target in targets: 137 Adb.Uninstall(target, arguments) 138 139 def Install(self, targets, arguments): 140 for target in targets: 141 Adb.Install(target, arguments) 142 143 def Reinstall(self, targets, arguments): 144 for target in targets: 145 Adb.Reinstall(target, arguments) 146