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