1*9c5db199SXin Li# Lint as: python2, python3 2*9c5db199SXin Li# Copyright 2022 The Chromium OS Authors. All rights reserved. 3*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 4*9c5db199SXin Li# found in the LICENSE file. 5*9c5db199SXin Li 6*9c5db199SXin Li# TODO(rkuroiwa): Rename this file to adb_utils.py to align with other utility 7*9c5db199SXin Li# modules. Also when class Adb is instantiated, the user is likely to call the 8*9c5db199SXin Li# instance "adb" which would collide with this file name (unless they always 9*9c5db199SXin Li# use "import adb as someothername". 10*9c5db199SXin Li 11*9c5db199SXin Liimport logging 12*9c5db199SXin Liimport re 13*9c5db199SXin Li 14*9c5db199SXin Lifrom autotest_lib.server import utils 15*9c5db199SXin Li 16*9c5db199SXin Li 17*9c5db199SXin Liclass Adb: 18*9c5db199SXin Li """Class for running adb commands.""" 19*9c5db199SXin Li 20*9c5db199SXin Li def __init__(self): 21*9c5db199SXin Li self._install_paths = set() 22*9c5db199SXin Li 23*9c5db199SXin Li def add_path(self, path): 24*9c5db199SXin Li """Adds path for executing commands. 25*9c5db199SXin Li 26*9c5db199SXin Li Path to ADB and AAPT may have to be added it if is not in the path. 27*9c5db199SXin Li Use this method to add it to the path before using run(). 28*9c5db199SXin Li """ 29*9c5db199SXin Li self._install_paths.add(path) 30*9c5db199SXin Li 31*9c5db199SXin Li def get_paths(self): 32*9c5db199SXin Li return self._install_paths 33*9c5db199SXin Li 34*9c5db199SXin Li def run(self, host, *args, **kwargs): 35*9c5db199SXin Li """Runs an ADB command on the host. 36*9c5db199SXin Li 37*9c5db199SXin Li @param host: DUT to issue the adb command. 38*9c5db199SXin Li @param args: Extra args passed to the adb command. 39*9c5db199SXin Li @param kwargs: Extra arguments passed to utils.run(). 40*9c5db199SXin Li """ 41*9c5db199SXin Li additional_option = _tradefed_options(host) 42*9c5db199SXin Li kwargs['args'] = additional_option + kwargs.get('args', ()) 43*9c5db199SXin Li 44*9c5db199SXin Li # _install_paths should include the directory with adb. 45*9c5db199SXin Li # utils.run() will append these to paths. 46*9c5db199SXin Li kwargs['extra_paths'] = (kwargs.get('extra_paths', []) + 47*9c5db199SXin Li list(self._install_paths)) 48*9c5db199SXin Li result = utils.run('adb', **kwargs) 49*9c5db199SXin Li logging.info('adb %s:\n%s', ' '.join(kwargs.get('args')), 50*9c5db199SXin Li result.stdout + result.stderr) 51*9c5db199SXin Li return result 52*9c5db199SXin Li 53*9c5db199SXin Li 54*9c5db199SXin Lidef get_adb_target(host): 55*9c5db199SXin Li """Get the adb target format. 56*9c5db199SXin Li 57*9c5db199SXin Li This method is slightly different from host.host_port as we need to 58*9c5db199SXin Li explicitly specify the port so the serial name of adb target would 59*9c5db199SXin Li match. 60*9c5db199SXin Li 61*9c5db199SXin Li @param host: a DUT accessible via adb. 62*9c5db199SXin Li @return a string for specifying the host using adb command. 63*9c5db199SXin Li """ 64*9c5db199SXin Li port = 22 if host.port is None else host.port 65*9c5db199SXin Li if re.search(r':.*:', host.hostname): 66*9c5db199SXin Li # Add [] for raw IPv6 addresses, stripped for ssh. 67*9c5db199SXin Li # In the Python >= 3.3 future, 'import ipaddress' will parse 68*9c5db199SXin Li # addresses. 69*9c5db199SXin Li return '[{}]:{}'.format(host.hostname, port) 70*9c5db199SXin Li return '{}:{}'.format(host.hostname, port) 71*9c5db199SXin Li 72*9c5db199SXin Li 73*9c5db199SXin Lidef get_adb_targets(hosts): 74*9c5db199SXin Li """Get a list of adb targets.""" 75*9c5db199SXin Li return [get_adb_target(host) for host in hosts] 76*9c5db199SXin Li 77*9c5db199SXin Li 78*9c5db199SXin Lidef _tradefed_options(host): 79*9c5db199SXin Li """ADB arguments for tradefed. 80*9c5db199SXin Li 81*9c5db199SXin Li These arguments are specific to using adb with tradefed. 82*9c5db199SXin Li 83*9c5db199SXin Li @param host: DUT that want to connect to. (None if the adb command is 84*9c5db199SXin Li intended to run in the server. eg. keygen) 85*9c5db199SXin Li @return a tuple of arguments for adb command. 86*9c5db199SXin Li """ 87*9c5db199SXin Li if host: 88*9c5db199SXin Li host_port = get_adb_target(host) 89*9c5db199SXin Li ret = ('-s', host_port) 90*9c5db199SXin Li return ret 91*9c5db199SXin Li # As of N, tradefed could not specify which adb socket to use, which use 92*9c5db199SXin Li # tcp:localhost:5037 by default. 93*9c5db199SXin Li return ('-H', 'localhost', '-P', '5037') 94