| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2015 The Chromium Authors. All rights reserved. | 3 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 """Install *_incremental.apk targets as well as their dependent files.""" | 7 """Install *_incremental.apk targets as well as their dependent files.""" |
| 8 | 8 |
| 9 import argparse | 9 import argparse |
| 10 import glob | 10 import glob |
| 11 import logging | 11 import logging |
| 12 import os | 12 import os |
| 13 import posixpath | 13 import posixpath |
| 14 import shutil | |
| 15 import sys | 14 import sys |
| 16 | 15 |
| 17 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir)) | 16 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir)) |
| 18 from devil.android import apk_helper | 17 from devil.android import apk_helper |
| 19 from devil.android import device_utils | 18 from devil.android import device_utils |
| 20 from devil.android import device_errors | 19 from devil.android import device_errors |
| 21 from devil.android.sdk import version_codes | 20 from devil.android.sdk import version_codes |
| 22 from devil.utils import reraiser_thread | 21 from devil.utils import reraiser_thread |
| 23 from pylib import constants | 22 from pylib import constants |
| 24 from pylib.utils import run_tests_helper | 23 from pylib.utils import run_tests_helper |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 | 57 |
| 59 def Uninstall(device, package): | 58 def Uninstall(device, package): |
| 60 """Uninstalls and removes all incremental files for the given package.""" | 59 """Uninstalls and removes all incremental files for the given package.""" |
| 61 main_timer = time_profile.TimeProfile() | 60 main_timer = time_profile.TimeProfile() |
| 62 device.Uninstall(package) | 61 device.Uninstall(package) |
| 63 device.RunShellCommand(['rm', '-rf', _GetDeviceIncrementalDir(package)], | 62 device.RunShellCommand(['rm', '-rf', _GetDeviceIncrementalDir(package)], |
| 64 check_return=True) | 63 check_return=True) |
| 65 logging.info('Uninstall took %s seconds.', main_timer.GetDelta()) | 64 logging.info('Uninstall took %s seconds.', main_timer.GetDelta()) |
| 66 | 65 |
| 67 | 66 |
| 68 def Install(device, apk, split_globs=None, lib_dir=None, dex_files=None, | 67 def Install(device, apk, split_globs=None, native_libs=None, dex_files=None, |
| 69 enable_device_cache=True, use_concurrency=True, | 68 enable_device_cache=True, use_concurrency=True, |
| 70 show_proguard_warning=False): | 69 show_proguard_warning=False): |
| 71 """Installs the given incremental apk and all required supporting files. | 70 """Installs the given incremental apk and all required supporting files. |
| 72 | 71 |
| 73 Args: | 72 Args: |
| 74 device: A DeviceUtils instance. | 73 device: A DeviceUtils instance. |
| 75 apk: The path to the apk, or an ApkHelper instance. | 74 apk: The path to the apk, or an ApkHelper instance. |
| 76 split_globs: Glob patterns for any required apk splits (optional). | 75 split_globs: Glob patterns for any required apk splits (optional). |
| 77 lib_dir: Directory containing the app's native libraries (optional). | 76 native_libs: List of app's native libraries (optional). |
| 78 dex_files: List of .dex.jar files that comprise the app's Dalvik code. | 77 dex_files: List of .dex.jar files that comprise the app's Dalvik code. |
| 79 enable_device_cache: Whether to enable on-device caching of checksums. | 78 enable_device_cache: Whether to enable on-device caching of checksums. |
| 80 use_concurrency: Whether to speed things up using multiple threads. | 79 use_concurrency: Whether to speed things up using multiple threads. |
| 81 show_proguard_warning: Whether to print a warning about Proguard not being | 80 show_proguard_warning: Whether to print a warning about Proguard not being |
| 82 enabled after installing. | 81 enabled after installing. |
| 83 """ | 82 """ |
| 84 main_timer = time_profile.TimeProfile() | 83 main_timer = time_profile.TimeProfile() |
| 85 install_timer = time_profile.TimeProfile() | 84 install_timer = time_profile.TimeProfile() |
| 86 push_native_timer = time_profile.TimeProfile() | 85 push_native_timer = time_profile.TimeProfile() |
| 87 push_dex_timer = time_profile.TimeProfile() | 86 push_dex_timer = time_profile.TimeProfile() |
| (...skipping 10 matching lines...) Expand all Loading... |
| 98 for split_glob in split_globs: | 97 for split_glob in split_globs: |
| 99 splits.extend((f for f in glob.glob(split_glob))) | 98 splits.extend((f for f in glob.glob(split_glob))) |
| 100 device.InstallSplitApk(apk, splits, reinstall=True, | 99 device.InstallSplitApk(apk, splits, reinstall=True, |
| 101 allow_cached_props=True, permissions=()) | 100 allow_cached_props=True, permissions=()) |
| 102 else: | 101 else: |
| 103 device.Install(apk, reinstall=True, permissions=()) | 102 device.Install(apk, reinstall=True, permissions=()) |
| 104 install_timer.Stop(log=False) | 103 install_timer.Stop(log=False) |
| 105 | 104 |
| 106 # Push .so and .dex files to the device (if they have changed). | 105 # Push .so and .dex files to the device (if they have changed). |
| 107 def do_push_files(): | 106 def do_push_files(): |
| 108 if lib_dir: | 107 if native_libs: |
| 109 push_native_timer.Start() | 108 push_native_timer.Start() |
| 110 device_lib_dir = posixpath.join(device_incremental_dir, 'lib') | 109 with build_utils.TempDir() as temp_dir: |
| 111 device.PushChangedFiles([(lib_dir, device_lib_dir)], | 110 device_lib_dir = posixpath.join(device_incremental_dir, 'lib') |
| 112 delete_device_stale=True) | 111 for path in native_libs: |
| 112 os.symlink(path, os.path.join(temp_dir, os.path.basename(path))) |
| 113 device.PushChangedFiles([(temp_dir, device_lib_dir)], |
| 114 delete_device_stale=True) |
| 113 push_native_timer.Stop(log=False) | 115 push_native_timer.Stop(log=False) |
| 114 | 116 |
| 115 if dex_files: | 117 if dex_files: |
| 116 push_dex_timer.Start() | 118 push_dex_timer.Start() |
| 117 # Put all .dex files to be pushed into a temporary directory so that we | 119 # Put all .dex files to be pushed into a temporary directory so that we |
| 118 # can use delete_device_stale=True. | 120 # can use delete_device_stale=True. |
| 119 with build_utils.TempDir() as temp_dir: | 121 with build_utils.TempDir() as temp_dir: |
| 120 device_dex_dir = posixpath.join(device_incremental_dir, 'dex') | 122 device_dex_dir = posixpath.join(device_incremental_dir, 'dex') |
| 121 # Ensure no two files have the same name. | 123 # Ensure no two files have the same name. |
| 122 transformed_names = _TransformDexPaths(dex_files) | 124 transformed_names = _TransformDexPaths(dex_files) |
| 123 for src_path, dest_name in zip(dex_files, transformed_names): | 125 for src_path, dest_name in zip(dex_files, transformed_names): |
| 124 shutil.copyfile(src_path, os.path.join(temp_dir, dest_name)) | 126 os.symlink(src_path, os.path.join(temp_dir, dest_name)) |
| 125 device.PushChangedFiles([(temp_dir, device_dex_dir)], | 127 device.PushChangedFiles([(temp_dir, device_dex_dir)], |
| 126 delete_device_stale=True) | 128 delete_device_stale=True) |
| 127 push_dex_timer.Stop(log=False) | 129 push_dex_timer.Stop(log=False) |
| 128 | 130 |
| 129 def check_selinux(): | 131 def check_selinux(): |
| 130 # Marshmallow has no filesystem access whatsoever. It might be possible to | 132 # Marshmallow has no filesystem access whatsoever. It might be possible to |
| 131 # get things working on Lollipop, but attempts so far have failed. | 133 # get things working on Lollipop, but attempts so far have failed. |
| 132 # http://crbug.com/558818 | 134 # http://crbug.com/558818 |
| 133 has_selinux = device.build_version_sdk >= version_codes.LOLLIPOP | 135 has_selinux = device.build_version_sdk >= version_codes.LOLLIPOP |
| 134 if has_selinux and apk.HasIsolatedProcesses(): | 136 if has_selinux and apk.HasIsolatedProcesses(): |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 | 196 |
| 195 def main(): | 197 def main(): |
| 196 parser = argparse.ArgumentParser() | 198 parser = argparse.ArgumentParser() |
| 197 parser.add_argument('apk_path', | 199 parser.add_argument('apk_path', |
| 198 help='The path to the APK to install.') | 200 help='The path to the APK to install.') |
| 199 parser.add_argument('--split', | 201 parser.add_argument('--split', |
| 200 action='append', | 202 action='append', |
| 201 dest='splits', | 203 dest='splits', |
| 202 help='A glob matching the apk splits. ' | 204 help='A glob matching the apk splits. ' |
| 203 'Can be specified multiple times.') | 205 'Can be specified multiple times.') |
| 204 parser.add_argument('--lib-dir', | 206 parser.add_argument('--native_lib', |
| 205 help='Path to native libraries directory.') | 207 dest='native_libs', |
| 206 parser.add_argument('--dex-files', | 208 help='Path to native library (repeatable)', |
| 207 help='List of dex files to push.', | 209 action='append', |
| 210 default=[]) |
| 211 parser.add_argument('--dex-file', |
| 212 dest='dex_files', |
| 213 help='Path to dex files (repeatable)', |
| 208 action='append', | 214 action='append', |
| 209 default=[]) | 215 default=[]) |
| 210 parser.add_argument('-d', '--device', dest='device', | 216 parser.add_argument('-d', '--device', dest='device', |
| 211 help='Target device for apk to install on.') | 217 help='Target device for apk to install on.') |
| 212 parser.add_argument('--uninstall', | 218 parser.add_argument('--uninstall', |
| 213 action='store_true', | 219 action='store_true', |
| 214 default=False, | 220 default=False, |
| 215 help='Remove the app and all side-loaded files.') | 221 help='Remove the app and all side-loaded files.') |
| 216 parser.add_argument('--output-directory', | 222 parser.add_argument('--output-directory', |
| 217 help='Path to the root build directory.') | 223 help='Path to the root build directory.') |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 'Available devices:\n') | 269 'Available devices:\n') |
| 264 descriptions = all_devices.pMap(lambda d: d.build_description).pGet(None) | 270 descriptions = all_devices.pMap(lambda d: d.build_description).pGet(None) |
| 265 for d, desc in zip(devices, descriptions): | 271 for d, desc in zip(devices, descriptions): |
| 266 msg += ' %s (%s)\n' % (d, desc) | 272 msg += ' %s (%s)\n' % (d, desc) |
| 267 raise Exception(msg) | 273 raise Exception(msg) |
| 268 | 274 |
| 269 apk = apk_helper.ToHelper(args.apk_path) | 275 apk = apk_helper.ToHelper(args.apk_path) |
| 270 if args.uninstall: | 276 if args.uninstall: |
| 271 Uninstall(device, apk.GetPackageName()) | 277 Uninstall(device, apk.GetPackageName()) |
| 272 else: | 278 else: |
| 273 Install(device, apk, split_globs=args.splits, lib_dir=args.lib_dir, | 279 Install(device, apk, split_globs=args.splits, native_libs=args.native_libs, |
| 274 dex_files=args.dex_files, enable_device_cache=args.cache, | 280 dex_files=args.dex_files, enable_device_cache=args.cache, |
| 275 use_concurrency=args.threading, | 281 use_concurrency=args.threading, |
| 276 show_proguard_warning=args.show_proguard_warning) | 282 show_proguard_warning=args.show_proguard_warning) |
| 277 | 283 |
| 278 | 284 |
| 279 if __name__ == '__main__': | 285 if __name__ == '__main__': |
| 280 sys.exit(main()) | 286 sys.exit(main()) |
| OLD | NEW |