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 pylib
import constants
16 from pylib
.device
import device_blacklist
17 from pylib
.device
import device_errors
18 from pylib
.device
import device_utils
19 from pylib
.utils
import apk_helper
20 from pylib
.utils
import run_tests_helper
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('-v', '--verbose', action
='count',
57 help='Enable verbose logging.')
59 args
= parser
.parse_args()
61 run_tests_helper
.SetLogLevel(args
.verbose
)
62 constants
.SetBuildType(args
.build_type
)
64 apk
= args
.apk_path
or args
.apk_name
65 if not apk
.endswith('.apk'):
67 if not os
.path
.exists(apk
):
68 apk
= os
.path
.join(constants
.GetOutDirectory(), 'apks', apk
)
69 if not os
.path
.exists(apk
):
70 parser
.error('%s not found.' % apk
)
74 base_apk_package
= apk_helper
.ApkHelper(apk
).GetPackageName()
75 for split_glob
in args
.splits
:
76 apks
= [f
for f
in glob
.glob(split_glob
) if f
.endswith('.apk')]
78 logging
.warning('No apks matched for %s.' % split_glob
)
80 helper
= apk_helper
.ApkHelper(f
)
81 if (helper
.GetPackageName() == base_apk_package
82 and helper
.GetSplitName()):
85 devices
= device_utils
.DeviceUtils
.HealthyDevices()
88 devices
= [d
for d
in devices
if d
== args
.device
]
90 raise device_errors
.DeviceUnreachableError(args
.device
)
92 raise device_errors
.NoDevicesError()
94 def blacklisting_install(device
):
97 device
.InstallSplitApk(apk
, splits
, reinstall
=args
.keep_data
)
99 device
.Install(apk
, reinstall
=args
.keep_data
)
100 except device_errors
.CommandFailedError
:
101 logging
.exception('Failed to install %s', args
.apk_name
)
102 device_blacklist
.ExtendBlacklist([str(device
)])
103 logging
.warning('Blacklisting %s', str(device
))
104 except device_errors
.CommandTimeoutError
:
105 logging
.exception('Timed out while installing %s', args
.apk_name
)
106 device_blacklist
.ExtendBlacklist([str(device
)])
107 logging
.warning('Blacklisting %s', str(device
))
109 device_utils
.DeviceUtils
.parallel(devices
).pMap(blacklisting_install
)
112 if __name__
== '__main__':