xref: /aosp_15_r20/external/autotest/server/cros/tradefed/adb.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
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