OLD | NEW |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 import sys | |
5 | |
6 from telemetry.core.platform import tracing_category_filter | 4 from telemetry.core.platform import tracing_category_filter |
7 from telemetry.core.platform import tracing_options | 5 from telemetry.core.platform import tracing_options |
8 from telemetry.page import action_runner | |
9 from telemetry.timeline.model import TimelineModel | 6 from telemetry.timeline.model import TimelineModel |
10 from telemetry.value import trace | 7 from telemetry.value import trace |
11 from telemetry.web_perf.metrics import smoothness | 8 from telemetry.web_perf.metrics import smoothness |
12 from telemetry.web_perf import smooth_gesture_util | 9 from telemetry.web_perf import smooth_gesture_util |
13 from telemetry.web_perf import timeline_interaction_record as tir_module | 10 from telemetry.web_perf import timeline_interaction_record as tir_module |
14 | 11 |
15 | 12 |
16 RUN_SMOOTH_ACTIONS = 'RunSmoothAllActions' | 13 class SmoothnessTestException(Exception): |
| 14 pass |
17 | 15 |
18 | 16 |
19 class SmoothnessController(object): | 17 class SmoothnessController(object): |
20 def __init__(self, auto_issuing_marker=True): | 18 def __init__(self, auto_issuing_marker=True): |
21 self._timeline_model = None | 19 self._timeline_model = None |
22 self._trace_data = None | 20 self._trace_data = None |
23 self._interaction = None | 21 self._interaction = None |
24 self._surface_flinger_trace_data = None | 22 self._surface_flinger_trace_data = None |
25 self._auto_issuing_marker = auto_issuing_marker | |
26 | 23 |
27 def SetUp(self, page, tab): | 24 def Start(self, page, tab): |
28 # FIXME: Remove webkit.console when blink.console lands in chromium and | 25 # FIXME: Remove webkit.console when blink.console lands in chromium and |
29 # the ref builds are updated. crbug.com/386847 | 26 # the ref builds are updated. crbug.com/386847 |
30 custom_categories = ['webkit.console', 'blink.console', 'benchmark'] | 27 custom_categories = ['webkit.console', 'blink.console', 'benchmark'] |
31 custom_categories += page.GetSyntheticDelayCategories() | 28 custom_categories += page.GetSyntheticDelayCategories() |
32 category_filter = tracing_category_filter.TracingCategoryFilter() | 29 category_filter = tracing_category_filter.TracingCategoryFilter() |
33 for c in custom_categories: | 30 for c in custom_categories: |
34 category_filter.AddIncludedCategory(c) | 31 category_filter.AddIncludedCategory(c) |
35 options = tracing_options.TracingOptions() | 32 options = tracing_options.TracingOptions() |
36 options.enable_chrome_trace = True | 33 options.enable_chrome_trace = True |
37 options.enable_platform_display_trace = True | 34 options.enable_platform_display_trace = True |
38 tab.browser.platform.tracing_controller.Start(options, category_filter, 60) | 35 tab.browser.platform.tracing_controller.Start(options, category_filter, 60) |
39 | 36 |
40 def Start(self, tab): | |
41 # Start the smooth marker for all smooth actions. | |
42 runner = action_runner.ActionRunner(tab) | |
43 if self._auto_issuing_marker: | |
44 self._interaction = runner.CreateInteraction( | |
45 RUN_SMOOTH_ACTIONS) | |
46 self._interaction.Begin() | |
47 | |
48 def Stop(self, tab): | 37 def Stop(self, tab): |
49 # End the smooth marker for all smooth actions. | |
50 if self._auto_issuing_marker: | |
51 self._interaction.End() | |
52 self._trace_data = tab.browser.platform.tracing_controller.Stop() | 38 self._trace_data = tab.browser.platform.tracing_controller.Stop() |
53 self._timeline_model = TimelineModel(self._trace_data) | 39 self._timeline_model = TimelineModel(self._trace_data) |
54 | 40 |
55 def AddResults(self, tab, results): | 41 def AddResults(self, tab, results): |
56 # Add results of smoothness metric. This computes the smoothness metric for | 42 # Add results of smoothness metric. This computes the smoothness metric for |
57 # the time ranges of gestures, if there is at least one, else the the time | 43 # the time ranges of gestures, if there is at least one, else the the time |
58 # ranges from the first action to the last action. | 44 # ranges from the first action to the last action. |
59 results.AddValue(trace.TraceValue( | 45 results.AddValue(trace.TraceValue( |
60 results.current_page, self._trace_data)) | 46 results.current_page, self._trace_data)) |
61 renderer_thread = self._timeline_model.GetRendererThreadFromTabId( | 47 renderer_thread = self._timeline_model.GetRendererThreadFromTabId( |
62 tab.id) | 48 tab.id) |
63 run_smooth_actions_record = None | |
64 smooth_records = [] | 49 smooth_records = [] |
65 for event in renderer_thread.async_slices: | 50 for event in renderer_thread.async_slices: |
66 if not tir_module.IsTimelineInteractionRecord(event.name): | 51 if not tir_module.IsTimelineInteractionRecord(event.name): |
67 continue | 52 continue |
68 r = tir_module.TimelineInteractionRecord.FromAsyncEvent(event) | 53 r = tir_module.TimelineInteractionRecord.FromAsyncEvent(event) |
69 if r.label == RUN_SMOOTH_ACTIONS: | 54 smooth_records.append( |
70 assert run_smooth_actions_record is None, ( | 55 smooth_gesture_util.GetAdjustedInteractionIfContainGesture( |
71 'SmoothnessController cannot issue more than 1 %s record' % | 56 self._timeline_model, r)) |
72 RUN_SMOOTH_ACTIONS) | |
73 run_smooth_actions_record = r | |
74 else: | |
75 smooth_records.append( | |
76 smooth_gesture_util.GetAdjustedInteractionIfContainGesture( | |
77 self._timeline_model, r)) | |
78 | 57 |
79 # If there is no other smooth records, we make measurements on time range | 58 # If there is no other smooth records, we make measurements on time range |
80 # marked smoothness_controller itself. | 59 # marked smoothness_controller itself. |
81 # TODO(nednguyen): when crbug.com/239179 is marked fixed, makes sure that | 60 # TODO(nednguyen): when crbug.com/239179 is marked fixed, makes sure that |
82 # page sets are responsible for issueing the markers themselves. | 61 # page sets are responsible for issueing the markers themselves. |
83 if len(smooth_records) == 0: | 62 if len(smooth_records) == 0: |
84 if run_smooth_actions_record is None: | 63 raise SmoothnessTestException('Page failed to issue any markers.') |
85 sys.stderr.write('Raw tracing data:\n') | 64 |
86 self._trace_data.Serialize(sys.stderr) | 65 # Check to make sure all smooth records have same label and repeatable if |
87 sys.stderr.write('\n') | 66 # there are more than one. |
88 raise Exception('SmoothnessController failed to issue markers for the ' | 67 need_repeatable_flag = len(smooth_records) > 1 |
89 'whole interaction.') | 68 record_label = smooth_records[0].label |
90 else: | 69 for r in smooth_records: |
91 smooth_records = [run_smooth_actions_record] | 70 if r.label != record_label: |
| 71 raise SmoothnessTestException( |
| 72 'SmoothController does not support multiple interactions with ' |
| 73 'different label.') |
| 74 if need_repeatable_flag and not r.repeatable: |
| 75 raise SmoothnessTestException( |
| 76 'If there are more than one interaction record, each interaction ' |
| 77 'must has repeatable flag.') |
92 | 78 |
93 # Create an interaction_record for this legacy measurement. Since we don't | 79 # Create an interaction_record for this legacy measurement. Since we don't |
94 # wrap the results that are sent to smoothness metric, the label will | 80 # wrap the results that are sent to smoothness metric, the label will |
95 # not be used. | 81 # not be used. |
96 smoothness_metric = smoothness.SmoothnessMetric() | 82 smoothness_metric = smoothness.SmoothnessMetric() |
97 smoothness_metric.AddResults( | 83 smoothness_metric.AddResults( |
98 self._timeline_model, renderer_thread, smooth_records, results) | 84 self._timeline_model, renderer_thread, smooth_records, results) |
99 | 85 |
100 def CleanUp(self, tab): | 86 def CleanUp(self, tab): |
101 if tab.browser.platform.tracing_controller.is_tracing_running: | 87 if tab.browser.platform.tracing_controller.is_tracing_running: |
102 tab.browser.platform.tracing_controller.Stop() | 88 tab.browser.platform.tracing_controller.Stop() |
OLD | NEW |