3 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
7 """Utility script to install APKs from the command line quickly."""
15 from devil
.android
import apk_helper
16 from devil
.android
import device_blacklist
17 from devil
.android
import device_errors
18 from devil
.android
import device_utils
19 from devil
.utils
import run_tests_helper
20 from pylib
import constants
24 parser
= argparse
.ArgumentParser()
26 apk_group
= parser
.add_mutually_exclusive_group(required
=True)
27 apk_group
.add_argument('--apk', dest
='apk_name',
28 help='DEPRECATED The name of the apk containing the'
29 ' application (with the .apk extension).')
30 apk_group
.add_argument('apk_path', nargs
='?',
31 help='The path to the APK to install.')
33 # TODO(jbudorick): Remove once no clients pass --apk_package
34 parser
.add_argument('--apk_package', help='DEPRECATED unused')
35 parser
.add_argument('--split',
38 help='A glob matching the apk splits. '
39 'Can be specified multiple times.')
40 parser
.add_argument('--keep_data',
43 help='Keep the package data when installing '
45 parser
.add_argument('--debug', action
='store_const', const
='Debug',
47 default
=os
.environ
.get('BUILDTYPE', 'Debug'),
48 help='If set, run test suites under out/Debug. '
49 'Default is env var BUILDTYPE or Debug')
50 parser
.add_argument('--release', action
='store_const', const
='Release',
52 help='If set, run test suites under out/Release. '
53 'Default is env var BUILDTYPE or Debug.')
54 parser
.add_argument('-d', '--device', dest
='device',
55 help='Target device for apk to install on.')
56 parser
.add_argument('--blacklist-file', help='Device blacklist JSON file.')
57 parser
.add_argument('-v', '--verbose', action
='count',
58 help='Enable verbose logging.')
60 args
= parser
.parse_args()
62 run_tests_helper
.SetLogLevel(args
.verbose
)
63 constants
.SetBuildType(args
.build_type
)
65 apk
= args
.apk_path
or args
.apk_name
66 if not apk
.endswith('.apk'):
68 if not os
.path
.exists(apk
):
69 apk
= os
.path
.join(constants
.GetOutDirectory(), 'apks', apk
)
70 if not os
.path
.exists(apk
):
71 parser
.error('%s not found.' % apk
)
75 base_apk_package
= apk_helper
.ApkHelper(apk
).GetPackageName()
76 for split_glob
in args
.splits
:
77 apks
= [f
for f
in glob
.glob(split_glob
) if f
.endswith('.apk')]
79 logging
.warning('No apks matched for %s.', split_glob
)
81 helper
= apk_helper
.ApkHelper(f
)
82 if (helper
.GetPackageName() == base_apk_package
83 and helper
.GetSplitName()):
86 blacklist
= (device_blacklist
.Blacklist(args
.blacklist_file
)
87 if args
.blacklist_file
89 devices
= device_utils
.DeviceUtils
.HealthyDevices(blacklist
)
92 devices
= [d
for d
in devices
if d
== args
.device
]
94 raise device_errors
.DeviceUnreachableError(args
.device
)
96 raise device_errors
.NoDevicesError()
98 def blacklisting_install(device
):
101 device
.InstallSplitApk(apk
, splits
, reinstall
=args
.keep_data
)
103 device
.Install(apk
, reinstall
=args
.keep_data
)
104 except device_errors
.CommandFailedError
:
105 logging
.exception('Failed to install %s', args
.apk_name
)
107 blacklist
.Extend([str(device
)])
108 logging
.warning('Blacklisting %s', str(device
))
109 except device_errors
.CommandTimeoutError
:
110 logging
.exception('Timed out while installing %s', args
.apk_name
)
112 blacklist
.Extend([str(device
)])
113 logging
.warning('Blacklisting %s', str(device
))
115 device_utils
.DeviceUtils
.parallel(devices
).pMap(blacklisting_install
)
118 if __name__
== '__main__':