xref: /aosp_15_r20/external/cronet/build/android/adb_install_apk.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker#!/usr/bin/env vpython3
2*6777b538SAndroid Build Coastguard Worker#
3*6777b538SAndroid Build Coastguard Worker# Copyright 2012 The Chromium Authors
4*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
5*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file.
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker"""Utility script to install APKs from the command line quickly."""
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Workerimport argparse
10*6777b538SAndroid Build Coastguard Workerimport glob
11*6777b538SAndroid Build Coastguard Workerimport logging
12*6777b538SAndroid Build Coastguard Workerimport os
13*6777b538SAndroid Build Coastguard Workerimport sys
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Workerimport devil_chromium
16*6777b538SAndroid Build Coastguard Workerfrom devil.android import apk_helper
17*6777b538SAndroid Build Coastguard Workerfrom devil.android import device_denylist
18*6777b538SAndroid Build Coastguard Workerfrom devil.android import device_errors
19*6777b538SAndroid Build Coastguard Workerfrom devil.android import device_utils
20*6777b538SAndroid Build Coastguard Workerfrom devil.utils import run_tests_helper
21*6777b538SAndroid Build Coastguard Workerfrom pylib import constants
22*6777b538SAndroid Build Coastguard Worker
23*6777b538SAndroid Build Coastguard Worker
24*6777b538SAndroid Build Coastguard Workerdef main():
25*6777b538SAndroid Build Coastguard Worker  parser = argparse.ArgumentParser()
26*6777b538SAndroid Build Coastguard Worker
27*6777b538SAndroid Build Coastguard Worker  apk_group = parser.add_mutually_exclusive_group(required=True)
28*6777b538SAndroid Build Coastguard Worker  apk_group.add_argument('--apk', dest='apk_name',
29*6777b538SAndroid Build Coastguard Worker                         help='DEPRECATED The name of the apk containing the'
30*6777b538SAndroid Build Coastguard Worker                              ' application (with the .apk extension).')
31*6777b538SAndroid Build Coastguard Worker  apk_group.add_argument('apk_path', nargs='?',
32*6777b538SAndroid Build Coastguard Worker                         help='The path to the APK to install.')
33*6777b538SAndroid Build Coastguard Worker
34*6777b538SAndroid Build Coastguard Worker  # TODO(jbudorick): Remove once no clients pass --apk_package
35*6777b538SAndroid Build Coastguard Worker  parser.add_argument('--apk_package', help='DEPRECATED unused')
36*6777b538SAndroid Build Coastguard Worker  parser.add_argument('--split',
37*6777b538SAndroid Build Coastguard Worker                      action='append',
38*6777b538SAndroid Build Coastguard Worker                      dest='splits',
39*6777b538SAndroid Build Coastguard Worker                      help='A glob matching the apk splits. '
40*6777b538SAndroid Build Coastguard Worker                           'Can be specified multiple times.')
41*6777b538SAndroid Build Coastguard Worker  parser.add_argument('--keep_data',
42*6777b538SAndroid Build Coastguard Worker                      action='store_true',
43*6777b538SAndroid Build Coastguard Worker                      default=False,
44*6777b538SAndroid Build Coastguard Worker                      help='Keep the package data when installing '
45*6777b538SAndroid Build Coastguard Worker                           'the application.')
46*6777b538SAndroid Build Coastguard Worker  parser.add_argument('--debug', action='store_const', const='Debug',
47*6777b538SAndroid Build Coastguard Worker                      dest='build_type',
48*6777b538SAndroid Build Coastguard Worker                      default=os.environ.get('BUILDTYPE', 'Debug'),
49*6777b538SAndroid Build Coastguard Worker                      help='If set, run test suites under out/Debug. '
50*6777b538SAndroid Build Coastguard Worker                           'Default is env var BUILDTYPE or Debug')
51*6777b538SAndroid Build Coastguard Worker  parser.add_argument('--release', action='store_const', const='Release',
52*6777b538SAndroid Build Coastguard Worker                      dest='build_type',
53*6777b538SAndroid Build Coastguard Worker                      help='If set, run test suites under out/Release. '
54*6777b538SAndroid Build Coastguard Worker                           'Default is env var BUILDTYPE or Debug.')
55*6777b538SAndroid Build Coastguard Worker  parser.add_argument('-d', '--device', dest='devices', action='append',
56*6777b538SAndroid Build Coastguard Worker                      default=[],
57*6777b538SAndroid Build Coastguard Worker                      help='Target device for apk to install on. Enter multiple'
58*6777b538SAndroid Build Coastguard Worker                           ' times for multiple devices.')
59*6777b538SAndroid Build Coastguard Worker  parser.add_argument('--adb-path', type=os.path.abspath,
60*6777b538SAndroid Build Coastguard Worker                      help='Absolute path to the adb binary to use.')
61*6777b538SAndroid Build Coastguard Worker  parser.add_argument('--denylist-file', help='Device denylist JSON file.')
62*6777b538SAndroid Build Coastguard Worker  parser.add_argument('-v',
63*6777b538SAndroid Build Coastguard Worker                      '--verbose',
64*6777b538SAndroid Build Coastguard Worker                      action='count',
65*6777b538SAndroid Build Coastguard Worker                      help='Enable verbose logging.',
66*6777b538SAndroid Build Coastguard Worker                      default=0)
67*6777b538SAndroid Build Coastguard Worker  parser.add_argument('--downgrade', action='store_true',
68*6777b538SAndroid Build Coastguard Worker                      help='If set, allows downgrading of apk.')
69*6777b538SAndroid Build Coastguard Worker  parser.add_argument('--timeout', type=int,
70*6777b538SAndroid Build Coastguard Worker                      default=device_utils.DeviceUtils.INSTALL_DEFAULT_TIMEOUT,
71*6777b538SAndroid Build Coastguard Worker                      help='Seconds to wait for APK installation. '
72*6777b538SAndroid Build Coastguard Worker                           '(default: %(default)s)')
73*6777b538SAndroid Build Coastguard Worker
74*6777b538SAndroid Build Coastguard Worker  args = parser.parse_args()
75*6777b538SAndroid Build Coastguard Worker
76*6777b538SAndroid Build Coastguard Worker  run_tests_helper.SetLogLevel(args.verbose)
77*6777b538SAndroid Build Coastguard Worker  constants.SetBuildType(args.build_type)
78*6777b538SAndroid Build Coastguard Worker
79*6777b538SAndroid Build Coastguard Worker  devil_chromium.Initialize(
80*6777b538SAndroid Build Coastguard Worker      output_directory=constants.GetOutDirectory(),
81*6777b538SAndroid Build Coastguard Worker      adb_path=args.adb_path)
82*6777b538SAndroid Build Coastguard Worker
83*6777b538SAndroid Build Coastguard Worker  apk = args.apk_path or args.apk_name
84*6777b538SAndroid Build Coastguard Worker  if not apk.endswith('.apk'):
85*6777b538SAndroid Build Coastguard Worker    apk += '.apk'
86*6777b538SAndroid Build Coastguard Worker  if not os.path.exists(apk):
87*6777b538SAndroid Build Coastguard Worker    apk = os.path.join(constants.GetOutDirectory(), 'apks', apk)
88*6777b538SAndroid Build Coastguard Worker    if not os.path.exists(apk):
89*6777b538SAndroid Build Coastguard Worker      parser.error('%s not found.' % apk)
90*6777b538SAndroid Build Coastguard Worker
91*6777b538SAndroid Build Coastguard Worker  if args.splits:
92*6777b538SAndroid Build Coastguard Worker    splits = []
93*6777b538SAndroid Build Coastguard Worker    base_apk_package = apk_helper.ApkHelper(apk).GetPackageName()
94*6777b538SAndroid Build Coastguard Worker    for split_glob in args.splits:
95*6777b538SAndroid Build Coastguard Worker      apks = [f for f in glob.glob(split_glob) if f.endswith('.apk')]
96*6777b538SAndroid Build Coastguard Worker      if not apks:
97*6777b538SAndroid Build Coastguard Worker        logging.warning('No apks matched for %s.', split_glob)
98*6777b538SAndroid Build Coastguard Worker      for f in apks:
99*6777b538SAndroid Build Coastguard Worker        helper = apk_helper.ApkHelper(f)
100*6777b538SAndroid Build Coastguard Worker        if (helper.GetPackageName() == base_apk_package
101*6777b538SAndroid Build Coastguard Worker            and helper.GetSplitName()):
102*6777b538SAndroid Build Coastguard Worker          splits.append(f)
103*6777b538SAndroid Build Coastguard Worker
104*6777b538SAndroid Build Coastguard Worker  denylist = (device_denylist.Denylist(args.denylist_file)
105*6777b538SAndroid Build Coastguard Worker              if args.denylist_file else None)
106*6777b538SAndroid Build Coastguard Worker  devices = device_utils.DeviceUtils.HealthyDevices(denylist=denylist,
107*6777b538SAndroid Build Coastguard Worker                                                    device_arg=args.devices)
108*6777b538SAndroid Build Coastguard Worker
109*6777b538SAndroid Build Coastguard Worker  def denylisting_install(device):
110*6777b538SAndroid Build Coastguard Worker    try:
111*6777b538SAndroid Build Coastguard Worker      if args.splits:
112*6777b538SAndroid Build Coastguard Worker        device.InstallSplitApk(apk, splits, reinstall=args.keep_data,
113*6777b538SAndroid Build Coastguard Worker                               allow_downgrade=args.downgrade)
114*6777b538SAndroid Build Coastguard Worker      else:
115*6777b538SAndroid Build Coastguard Worker        device.Install(apk, reinstall=args.keep_data,
116*6777b538SAndroid Build Coastguard Worker                       allow_downgrade=args.downgrade,
117*6777b538SAndroid Build Coastguard Worker                       timeout=args.timeout)
118*6777b538SAndroid Build Coastguard Worker    except (device_errors.CommandFailedError,
119*6777b538SAndroid Build Coastguard Worker            device_errors.DeviceUnreachableError):
120*6777b538SAndroid Build Coastguard Worker      logging.exception('Failed to install %s', apk)
121*6777b538SAndroid Build Coastguard Worker      if denylist:
122*6777b538SAndroid Build Coastguard Worker        denylist.Extend([str(device)], reason='install_failure')
123*6777b538SAndroid Build Coastguard Worker        logging.warning('Denylisting %s', str(device))
124*6777b538SAndroid Build Coastguard Worker    except device_errors.CommandTimeoutError:
125*6777b538SAndroid Build Coastguard Worker      logging.exception('Timed out while installing %s', apk)
126*6777b538SAndroid Build Coastguard Worker      if denylist:
127*6777b538SAndroid Build Coastguard Worker        denylist.Extend([str(device)], reason='install_timeout')
128*6777b538SAndroid Build Coastguard Worker        logging.warning('Denylisting %s', str(device))
129*6777b538SAndroid Build Coastguard Worker
130*6777b538SAndroid Build Coastguard Worker  device_utils.DeviceUtils.parallel(devices).pMap(denylisting_install)
131*6777b538SAndroid Build Coastguard Worker
132*6777b538SAndroid Build Coastguard Worker
133*6777b538SAndroid Build Coastguard Workerif __name__ == '__main__':
134*6777b538SAndroid Build Coastguard Worker  sys.exit(main())
135