OLD | NEW |
| 1 #! /usr/bin/env python |
1 # Copyright (c) 2015 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2015 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 4 # found in the LICENSE file. |
4 | 5 |
5 """Utility library for running a startup profile on an Android device. | 6 """Utility library for running a startup profile on an Android device. |
6 | 7 |
7 Sets up a device for cygprofile, disables sandboxing permissions, and sets up | 8 Sets up a device for cygprofile, disables sandboxing permissions, and sets up |
8 support for web page replay, device forwarding, and fake certificate authority | 9 support for web page replay, device forwarding, and fake certificate authority |
9 to make runs repeatable. | 10 to make runs repeatable. |
10 """ | 11 """ |
11 | 12 |
| 13 import argparse |
12 import logging | 14 import logging |
13 import os | 15 import os |
14 import shutil | 16 import shutil |
15 import subprocess | 17 import subprocess |
16 import sys | 18 import sys |
17 import tempfile | 19 import tempfile |
18 import time | 20 import time |
19 | 21 |
20 sys.path.append(os.path.join(sys.path[0], '..', '..', | 22 sys.path.append(os.path.join(sys.path[0], '..', '..', |
21 'third_party', 'catapult', 'devil')) | 23 'third_party', 'catapult', 'devil')) |
| 24 from devil.android import apk_helper |
22 from devil.android import device_errors | 25 from devil.android import device_errors |
23 from devil.android import device_utils | 26 from devil.android import device_utils |
24 from devil.android import flag_changer | 27 from devil.android import flag_changer |
25 from devil.android import forwarder | 28 from devil.android import forwarder |
26 from devil.android.sdk import intent | 29 from devil.android.sdk import intent |
27 | 30 |
28 sys.path.append(os.path.join(sys.path[0], '..', '..', 'build', 'android')) | 31 sys.path.append(os.path.join(sys.path[0], '..', '..', 'build', 'android')) |
| 32 import devil_chromium |
29 from pylib import constants | 33 from pylib import constants |
30 | 34 |
31 sys.path.append(os.path.join(sys.path[0], '..', '..', 'tools', 'perf')) | 35 sys.path.append(os.path.join(sys.path[0], '..', '..', 'tools', 'perf')) |
32 from chrome_telemetry_build import chromium_config | 36 from chrome_telemetry_build import chromium_config |
33 sys.path.append(chromium_config.GetTelemetryDir()) | 37 sys.path.append(chromium_config.GetTelemetryDir()) |
34 from telemetry.internal.util import wpr_server | 38 from telemetry.internal.util import wpr_server |
35 | 39 |
36 sys.path.append(os.path.join(sys.path[0], '..', '..', | 40 sys.path.append(os.path.join(sys.path[0], '..', '..', |
37 'third_party', 'webpagereplay')) | 41 'third_party', 'webpagereplay')) |
38 import adb_install_cert | 42 import adb_install_cert |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 """ | 199 """ |
196 | 200 |
197 _DEVICE_CYGLOG_DIR = '/data/local/tmp/chrome/cyglog' | 201 _DEVICE_CYGLOG_DIR = '/data/local/tmp/chrome/cyglog' |
198 | 202 |
199 # TEST_URL must be a url in the WPR_ARCHIVE. | 203 # TEST_URL must be a url in the WPR_ARCHIVE. |
200 _TEST_URL = 'https://www.google.com/#hl=en&q=science' | 204 _TEST_URL = 'https://www.google.com/#hl=en&q=science' |
201 _WPR_ARCHIVE = os.path.join( | 205 _WPR_ARCHIVE = os.path.join( |
202 constants.DIR_SOURCE_ROOT, 'tools', 'perf', 'page_sets', 'data', | 206 constants.DIR_SOURCE_ROOT, 'tools', 'perf', 'page_sets', 'data', |
203 'top_10_mobile_002.wpr') | 207 'top_10_mobile_002.wpr') |
204 | 208 |
205 | 209 # TODO(jbudorick): Make host_cyglog_dir mandatory after updating |
206 def __init__(self, output_directory): | 210 # downstream clients. See crbug.com/639831 for context. |
| 211 def __init__(self, output_directory, host_cyglog_dir=None): |
207 devices = device_utils.DeviceUtils.HealthyDevices() | 212 devices = device_utils.DeviceUtils.HealthyDevices() |
208 self._device = devices[0] | 213 self._device = devices[0] |
209 self._cygprofile_tests = os.path.join( | 214 self._cygprofile_tests = os.path.join( |
210 output_directory, 'cygprofile_unittests') | 215 output_directory, 'cygprofile_unittests') |
211 self._host_cyglog_dir = os.path.join( | 216 self._host_cyglog_dir = host_cyglog_dir or os.path.join( |
212 output_directory, 'cyglog_data') | 217 output_directory, 'cyglog_data') |
213 self._SetUpDevice() | 218 self._SetUpDevice() |
214 | 219 |
215 def RunCygprofileTests(self): | 220 def RunCygprofileTests(self): |
216 """Run the cygprofile unit tests suite on the device. | 221 """Run the cygprofile unit tests suite on the device. |
217 | 222 |
218 Args: | 223 Args: |
219 path_to_tests: The location on the host machine with the compiled | 224 path_to_tests: The location on the host machine with the compiled |
220 cygprofile test binary. | 225 cygprofile test binary. |
221 Returns: | 226 Returns: |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 # Temporary workaround/investigation: if (for unknown reason) 'adb pull' of | 369 # Temporary workaround/investigation: if (for unknown reason) 'adb pull' of |
365 # the directory 'cyglog' into '.../Release/cyglog_data' produces | 370 # the directory 'cyglog' into '.../Release/cyglog_data' produces |
366 # '...cyglog_data/cyglog/files' instead of the usual '...cyglog_data/files', | 371 # '...cyglog_data/cyglog/files' instead of the usual '...cyglog_data/files', |
367 # list the files deeper in the tree. | 372 # list the files deeper in the tree. |
368 cyglog_dir = self._host_cyglog_dir | 373 cyglog_dir = self._host_cyglog_dir |
369 if (len(files) == 1) and (files[0] == 'cyglog'): | 374 if (len(files) == 1) and (files[0] == 'cyglog'): |
370 cyglog_dir = os.path.join(self._host_cyglog_dir, 'cyglog') | 375 cyglog_dir = os.path.join(self._host_cyglog_dir, 'cyglog') |
371 files = os.listdir(cyglog_dir) | 376 files = os.listdir(cyglog_dir) |
372 | 377 |
373 return [os.path.join(cyglog_dir, x) for x in files] | 378 return [os.path.join(cyglog_dir, x) for x in files] |
| 379 |
| 380 |
| 381 def main(): |
| 382 parser = argparse.ArgumentParser() |
| 383 parser.add_argument( |
| 384 '--adb-path', type=os.path.realpath, |
| 385 help='adb binary') |
| 386 parser.add_argument( |
| 387 '--apk-path', type=os.path.realpath, required=True, |
| 388 help='APK to profile') |
| 389 parser.add_argument( |
| 390 '--output-directory', type=os.path.realpath, required=True, |
| 391 help='Chromium output directory (e.g. out/Release)') |
| 392 parser.add_argument( |
| 393 '--trace-directory', type=os.path.realpath, |
| 394 help='Directory in which cyglog traces will be stored. ' |
| 395 'Defaults to <output-directory>/cyglog_data') |
| 396 |
| 397 args = parser.parse_args() |
| 398 |
| 399 devil_chromium.Initialize( |
| 400 output_directory=args.output_directory, adb_path=args.adb_path) |
| 401 |
| 402 apk = apk_helper.ApkHelper(args.apk_path) |
| 403 package_info = None |
| 404 for p in constants.PACKAGE_INFO.itervalues(): |
| 405 if p.package == apk.GetPackageName(): |
| 406 package_info = p |
| 407 break |
| 408 else: |
| 409 raise Exception('Unable to determine package info for %s' % args.apk_path) |
| 410 |
| 411 profiler = AndroidProfileTool( |
| 412 args.output_directory, host_cyglog_dir=args.trace_directory) |
| 413 profiler.CollectProfile(args.apk_path, package_info) |
| 414 return 0 |
| 415 |
| 416 |
| 417 if __name__ == '__main__': |
| 418 sys.exit(main()) |
| 419 |
OLD | NEW |