Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: build/android/adb_profile_chrome.py

Issue 221823011: [Android] Change object types from AndroidCommands to DeviceUtils in build/android/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build/android/adb_kill_content_shell ('k') | build/android/adb_reverse_forwarder.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # 2 #
3 # Copyright 2013 The Chromium Authors. All rights reserved. 3 # Copyright 2013 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 import gzip 7 import gzip
8 import logging 8 import logging
9 import optparse 9 import optparse
10 import os 10 import os
11 import re 11 import re
12 import select 12 import select
13 import shutil 13 import shutil
14 import sys 14 import sys
15 import threading 15 import threading
16 import time 16 import time
17 import webbrowser 17 import webbrowser
18 import zipfile 18 import zipfile
19 import zlib 19 import zlib
20 20
21 from pylib import android_commands 21 from pylib import android_commands
22 from pylib import cmd_helper 22 from pylib import cmd_helper
23 from pylib import constants 23 from pylib import constants
24 from pylib import pexpect 24 from pylib import pexpect
25 from pylib.device import device_utils
25 26
26 _TRACE_VIEWER_ROOT = os.path.join(constants.DIR_SOURCE_ROOT, 27 _TRACE_VIEWER_ROOT = os.path.join(constants.DIR_SOURCE_ROOT,
27 'third_party', 'trace-viewer') 28 'third_party', 'trace-viewer')
28 sys.path.append(_TRACE_VIEWER_ROOT) 29 sys.path.append(_TRACE_VIEWER_ROOT)
29 from trace_viewer.build import trace2html # pylint: disable=F0401 30 from trace_viewer.build import trace2html # pylint: disable=F0401
30 31
31 _DEFAULT_CHROME_CATEGORIES = '_DEFAULT_CHROME_CATEGORIES' 32 _DEFAULT_CHROME_CATEGORIES = '_DEFAULT_CHROME_CATEGORIES'
32 33
33 34
34 def _GetTraceTimestamp(): 35 def _GetTraceTimestamp():
35 return time.strftime('%Y-%m-%d-%H%M%S', time.localtime()) 36 return time.strftime('%Y-%m-%d-%H%M%S', time.localtime())
36 37
37 38
38 class ChromeTracingController(object): 39 class ChromeTracingController(object):
39 def __init__(self, adb, package_info, categories, ring_buffer): 40 def __init__(self, device, package_info, categories, ring_buffer):
40 self._adb = adb 41 self._device = device
41 self._package_info = package_info 42 self._package_info = package_info
42 self._categories = categories 43 self._categories = categories
43 self._ring_buffer = ring_buffer 44 self._ring_buffer = ring_buffer
44 self._trace_file = None 45 self._trace_file = None
45 self._trace_interval = None 46 self._trace_interval = None
46 self._trace_start_re = \ 47 self._trace_start_re = \
47 re.compile(r'Logging performance trace to file: (.*)') 48 re.compile(r'Logging performance trace to file: (.*)')
48 self._trace_finish_re = \ 49 self._trace_finish_re = \
49 re.compile(r'Profiler finished[.] Results are in (.*)[.]') 50 re.compile(r'Profiler finished[.] Results are in (.*)[.]')
50 self._adb.StartMonitoringLogcat(clear=False) 51 self._device.old_interface.StartMonitoringLogcat(clear=False)
51 52
52 def __str__(self): 53 def __str__(self):
53 return 'chrome trace' 54 return 'chrome trace'
54 55
55 def StartTracing(self, interval): 56 def StartTracing(self, interval):
56 self._trace_interval = interval 57 self._trace_interval = interval
57 self._adb.SyncLogCat() 58 self._device.old_interface.SyncLogCat()
58 self._adb.BroadcastIntent(self._package_info.package, 'GPU_PROFILER_START', 59 self._device.old_interface.BroadcastIntent(
59 '-e categories "%s"' % ','.join(self._categories), 60 self._package_info.package, 'GPU_PROFILER_START',
60 '-e continuous' if self._ring_buffer else '') 61 '-e categories "%s"' % ','.join(self._categories),
62 '-e continuous' if self._ring_buffer else '')
61 # Chrome logs two different messages related to tracing: 63 # Chrome logs two different messages related to tracing:
62 # 64 #
63 # 1. "Logging performance trace to file [...]" 65 # 1. "Logging performance trace to file [...]"
64 # 2. "Profiler finished. Results are in [...]" 66 # 2. "Profiler finished. Results are in [...]"
65 # 67 #
66 # The first one is printed when tracing starts and the second one indicates 68 # The first one is printed when tracing starts and the second one indicates
67 # that the trace file is ready to be pulled. 69 # that the trace file is ready to be pulled.
68 try: 70 try:
69 self._trace_file = self._adb.WaitForLogMatch(self._trace_start_re, 71 self._trace_file = self._device.old_interface.WaitForLogMatch(
70 None, 72 self._trace_start_re, None, timeout=5).group(1)
71 timeout=5).group(1)
72 except pexpect.TIMEOUT: 73 except pexpect.TIMEOUT:
73 raise RuntimeError('Trace start marker not found. Is the correct version ' 74 raise RuntimeError('Trace start marker not found. Is the correct version '
74 'of the browser running?') 75 'of the browser running?')
75 76
76 def StopTracing(self): 77 def StopTracing(self):
77 if not self._trace_file: 78 if not self._trace_file:
78 return 79 return
79 self._adb.BroadcastIntent(self._package_info.package, 'GPU_PROFILER_STOP') 80 self._device.old_interface.BroadcastIntent(self._package_info.package,
80 self._adb.WaitForLogMatch(self._trace_finish_re, None, timeout=120) 81 'GPU_PROFILER_STOP')
82 self._device.old_interface.WaitForLogMatch(self._trace_finish_re, None,
83 timeout=120)
81 84
82 def PullTrace(self): 85 def PullTrace(self):
83 # Wait a bit for the browser to finish writing the trace file. 86 # Wait a bit for the browser to finish writing the trace file.
84 time.sleep(self._trace_interval / 4 + 1) 87 time.sleep(self._trace_interval / 4 + 1)
85 88
86 trace_file = self._trace_file.replace('/storage/emulated/0/', '/sdcard/') 89 trace_file = self._trace_file.replace('/storage/emulated/0/', '/sdcard/')
87 host_file = os.path.join(os.path.curdir, os.path.basename(trace_file)) 90 host_file = os.path.join(os.path.curdir, os.path.basename(trace_file))
88 self._adb.PullFileFromDevice(trace_file, host_file) 91 self._device.old_interface.PullFileFromDevice(trace_file, host_file)
89 return host_file 92 return host_file
90 93
91 94
92 _SYSTRACE_OPTIONS = [ 95 _SYSTRACE_OPTIONS = [
93 # Compress the trace before sending it over USB. 96 # Compress the trace before sending it over USB.
94 '-z', 97 '-z',
95 # Use a large trace buffer to increase the polling interval. 98 # Use a large trace buffer to increase the polling interval.
96 '-b', '16384' 99 '-b', '16384'
97 ] 100 ]
98 101
99 # Interval in seconds for sampling systrace data. 102 # Interval in seconds for sampling systrace data.
100 _SYSTRACE_INTERVAL = 15 103 _SYSTRACE_INTERVAL = 15
101 104
102 105
103 class SystraceController(object): 106 class SystraceController(object):
104 def __init__(self, adb, categories, ring_buffer): 107 def __init__(self, device, categories, ring_buffer):
105 self._adb = adb 108 self._device = device
106 self._categories = categories 109 self._categories = categories
107 self._ring_buffer = ring_buffer 110 self._ring_buffer = ring_buffer
108 self._done = threading.Event() 111 self._done = threading.Event()
109 self._thread = None 112 self._thread = None
110 self._trace_data = None 113 self._trace_data = None
111 114
112 def __str__(self): 115 def __str__(self):
113 return 'systrace' 116 return 'systrace'
114 117
115 @staticmethod 118 @staticmethod
116 def GetCategories(adb): 119 def GetCategories(device):
117 return adb.RunShellCommand('atrace --list_categories') 120 return device.old_interface.RunShellCommand('atrace --list_categories')
118 121
119 def StartTracing(self, _): 122 def StartTracing(self, _):
120 self._thread = threading.Thread(target=self._CollectData) 123 self._thread = threading.Thread(target=self._CollectData)
121 self._thread.start() 124 self._thread.start()
122 125
123 def StopTracing(self): 126 def StopTracing(self):
124 self._done.set() 127 self._done.set()
125 128
126 def PullTrace(self): 129 def PullTrace(self):
127 self._thread.join() 130 self._thread.join()
128 self._thread = None 131 self._thread = None
129 if self._trace_data: 132 if self._trace_data:
130 output_name = 'systrace-%s' % _GetTraceTimestamp() 133 output_name = 'systrace-%s' % _GetTraceTimestamp()
131 with open(output_name, 'w') as out: 134 with open(output_name, 'w') as out:
132 out.write(self._trace_data) 135 out.write(self._trace_data)
133 return output_name 136 return output_name
134 137
135 def _RunATraceCommand(self, command): 138 def _RunATraceCommand(self, command):
139 # TODO(jbudorick) can this be made work with DeviceUtils?
136 # We use a separate interface to adb because the one from AndroidCommands 140 # We use a separate interface to adb because the one from AndroidCommands
137 # isn't re-entrant. 141 # isn't re-entrant.
138 device = ['-s', self._adb.GetDevice()] if self._adb.GetDevice() else [] 142 device_param = (['-s', self._device.old_interface.GetDevice()]
139 cmd = ['adb'] + device + ['shell', 'atrace', '--%s' % command] + \ 143 if self._device.old_interface.GetDevice() else [])
144 cmd = ['adb'] + device_param + ['shell', 'atrace', '--%s' % command] + \
140 _SYSTRACE_OPTIONS + self._categories 145 _SYSTRACE_OPTIONS + self._categories
141 return cmd_helper.GetCmdOutput(cmd) 146 return cmd_helper.GetCmdOutput(cmd)
142 147
143 def _CollectData(self): 148 def _CollectData(self):
144 trace_data = [] 149 trace_data = []
145 self._RunATraceCommand('async_start') 150 self._RunATraceCommand('async_start')
146 try: 151 try:
147 while not self._done.is_set(): 152 while not self._done.is_set():
148 self._done.wait(_SYSTRACE_INTERVAL) 153 self._done.wait(_SYSTRACE_INTERVAL)
149 if not self._ring_buffer or self._done.is_set(): 154 if not self._ring_buffer or self._done.is_set():
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 373
369 For basic jank busting uses, use --trace-frame-viewer 374 For basic jank busting uses, use --trace-frame-viewer
370 For detailed study of ubercompositor, pass --trace-ubercompositor. 375 For detailed study of ubercompositor, pass --trace-ubercompositor.
371 376
372 When in doubt, just try out --trace-frame-viewer. 377 When in doubt, just try out --trace-frame-viewer.
373 """) 378 """)
374 379
375 if options.verbose: 380 if options.verbose:
376 logging.getLogger().setLevel(logging.DEBUG) 381 logging.getLogger().setLevel(logging.DEBUG)
377 382
378 adb = android_commands.AndroidCommands() 383 devices = android_commands.GetAttachedDevices()
384 if len(devices) != 1:
385 parser.error('Exactly 1 device much be attached.')
386 device = device_utils.DeviceUtils(devices[0])
387
379 if options.systrace_categories in ['list', 'help']: 388 if options.systrace_categories in ['list', 'help']:
380 _PrintMessage('\n'.join(SystraceController.GetCategories(adb))) 389 _PrintMessage('\n'.join(SystraceController.GetCategories(device)))
381 return 0 390 return 0
382 391
383 if not options.time and not options.continuous: 392 if not options.time and not options.continuous:
384 _PrintMessage('Time interval or continuous tracing should be specified.') 393 _PrintMessage('Time interval or continuous tracing should be specified.')
385 return 1 394 return 1
386 395
387 chrome_categories = _ComputeChromeCategories(options) 396 chrome_categories = _ComputeChromeCategories(options)
388 systrace_categories = _ComputeSystraceCategories(options) 397 systrace_categories = _ComputeSystraceCategories(options)
389 package_info = _GetSupportedBrowsers()[options.browser] 398 package_info = _GetSupportedBrowsers()[options.browser]
390 399
391 if chrome_categories and 'webview' in systrace_categories: 400 if chrome_categories and 'webview' in systrace_categories:
392 logging.warning('Using the "webview" category in systrace together with ' 401 logging.warning('Using the "webview" category in systrace together with '
393 'Chrome tracing results in duplicate trace events.') 402 'Chrome tracing results in duplicate trace events.')
394 403
395 controllers = [] 404 controllers = []
396 if chrome_categories: 405 if chrome_categories:
397 controllers.append(ChromeTracingController(adb, 406 controllers.append(ChromeTracingController(device,
398 package_info, 407 package_info,
399 chrome_categories, 408 chrome_categories,
400 options.ring_buffer)) 409 options.ring_buffer))
401 if systrace_categories: 410 if systrace_categories:
402 controllers.append(SystraceController(adb, 411 controllers.append(SystraceController(device,
403 systrace_categories, 412 systrace_categories,
404 options.ring_buffer)) 413 options.ring_buffer))
405 414
406 if not controllers: 415 if not controllers:
407 _PrintMessage('No trace categories enabled.') 416 _PrintMessage('No trace categories enabled.')
408 return 1 417 return 1
409 418
410 if options.output: 419 if options.output:
411 options.output = os.path.expanduser(options.output) 420 options.output = os.path.expanduser(options.output)
412 result = _CaptureAndPullTrace(controllers, 421 result = _CaptureAndPullTrace(controllers,
413 options.time if not options.continuous else 0, 422 options.time if not options.continuous else 0,
414 options.output, 423 options.output,
415 options.compress, 424 options.compress,
416 options.json) 425 options.json)
417 if options.view: 426 if options.view:
418 if sys.platform == 'darwin': 427 if sys.platform == 'darwin':
419 os.system('/usr/bin/open %s' % os.path.abspath(result)) 428 os.system('/usr/bin/open %s' % os.path.abspath(result))
420 else: 429 else:
421 webbrowser.open(result) 430 webbrowser.open(result)
422 431
423 432
424 if __name__ == '__main__': 433 if __name__ == '__main__':
425 sys.exit(main()) 434 sys.exit(main())
OLDNEW
« no previous file with comments | « build/android/adb_kill_content_shell ('k') | build/android/adb_reverse_forwarder.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698