1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
10 from profile_chrome
import controllers
12 from pylib
import pexpect
13 from pylib
.device
import intent
16 _HEAP_PROFILE_MMAP_PROPERTY
= 'heapprof.mmap'
18 class ChromeTracingController(controllers
.BaseController
):
19 def __init__(self
, device
, package_info
,
20 categories
, ring_buffer
, trace_memory
=False):
21 controllers
.BaseController
.__init
__(self
)
23 self
._package
_info
= package_info
24 self
._categories
= categories
25 self
._ring
_buffer
= ring_buffer
26 self
._trace
_file
= None
27 self
._trace
_interval
= None
28 self
._trace
_memory
= trace_memory
29 self
._is
_tracing
= False
30 self
._trace
_start
_re
= \
31 re
.compile(r
'Logging performance trace to file')
32 self
._trace
_finish
_re
= \
33 re
.compile(r
'Profiler finished[.] Results are in (.*)[.]')
34 self
._device
.old_interface
.StartMonitoringLogcat(clear
=False)
40 def GetCategories(device
, package_info
):
41 device
.BroadcastIntent(intent
.Intent(
42 action
='%s.GPU_PROFILER_LIST_CATEGORIES' % package_info
.package
))
44 json_category_list
= device
.old_interface
.WaitForLogMatch(
45 re
.compile(r
'{"traceCategoriesList(.*)'), None, timeout
=5).group(0)
46 except pexpect
.TIMEOUT
:
47 raise RuntimeError('Performance trace category list marker not found. '
48 'Is the correct version of the browser running?')
50 record_categories
= []
51 disabled_by_default_categories
= []
52 json_data
= json
.loads(json_category_list
)['traceCategoriesList']
53 for item
in json_data
:
54 if item
.startswith('disabled-by-default'):
55 disabled_by_default_categories
.append(item
)
57 record_categories
.append(item
)
59 return record_categories
, disabled_by_default_categories
61 def StartTracing(self
, interval
):
62 self
._trace
_interval
= interval
63 self
._device
.old_interface
.SyncLogCat()
64 start_extras
= {'categories': ','.join(self
._categories
)}
66 start_extras
['continuous'] = None
67 self
._device
.BroadcastIntent(intent
.Intent(
68 action
='%s.GPU_PROFILER_START' % self
._package
_info
.package
,
71 if self
._trace
_memory
:
72 self
._device
.old_interface
.EnableAdbRoot()
73 self
._device
.SetProp(_HEAP_PROFILE_MMAP_PROPERTY
, 1)
75 # Chrome logs two different messages related to tracing:
77 # 1. "Logging performance trace to file"
78 # 2. "Profiler finished. Results are in [...]"
80 # The first one is printed when tracing starts and the second one indicates
81 # that the trace file is ready to be pulled.
83 self
._device
.old_interface
.WaitForLogMatch(
84 self
._trace
_start
_re
, None, timeout
=5)
85 self
._is
_tracing
= True
86 except pexpect
.TIMEOUT
:
87 raise RuntimeError('Trace start marker not found. Is the correct version '
88 'of the browser running?')
90 def StopTracing(self
):
92 self
._device
.BroadcastIntent(intent
.Intent(
93 action
='%s.GPU_PROFILER_STOP' % self
._package
_info
.package
))
94 self
._trace
_file
= self
._device
.old_interface
.WaitForLogMatch(
95 self
._trace
_finish
_re
, None, timeout
=120).group(1)
96 self
._is
_tracing
= False
97 if self
._trace
_memory
:
98 self
._device
.SetProp(_HEAP_PROFILE_MMAP_PROPERTY
, 0)
101 # Wait a bit for the browser to finish writing the trace file.
102 time
.sleep(self
._trace
_interval
/ 4 + 1)
104 trace_file
= self
._trace
_file
.replace('/storage/emulated/0/', '/sdcard/')
105 host_file
= os
.path
.join(os
.path
.curdir
, os
.path
.basename(trace_file
))
106 self
._device
.PullFile(trace_file
, host_file
)