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. 4from measurements import smooth_gesture_util 5 6from telemetry.core.platform import tracing_category_filter 7from telemetry.core.platform import tracing_options 8from telemetry.timeline.model import TimelineModel 9from telemetry.page.actions import action_runner 10from telemetry.web_perf import timeline_interaction_record as tir_module 11 12 13RUN_SMOOTH_ACTIONS = 'RunSmoothAllActions' 14 15 16class TimelineController(object): 17 def __init__(self): 18 super(TimelineController, self).__init__() 19 self.trace_categories = None 20 self._model = None 21 self._renderer_process = None 22 self._smooth_records = [] 23 self._interaction = None 24 25 def SetUp(self, page, tab): 26 """Starts gathering timeline data. 27 28 """ 29 # Resets these member variables incase this object is reused. 30 self._model = None 31 self._renderer_process = None 32 if not tab.browser.platform.tracing_controller.IsChromeTracingSupported( 33 tab.browser): 34 raise Exception('Not supported') 35 category_filter = tracing_category_filter.TracingCategoryFilter( 36 filter_string=self.trace_categories) 37 for delay in page.GetSyntheticDelayCategories(): 38 category_filter.AddSyntheticDelay(delay) 39 options = tracing_options.TracingOptions() 40 options.enable_chrome_trace = True 41 tab.browser.platform.tracing_controller.Start(options, category_filter) 42 43 def Start(self, tab): 44 # Start the smooth marker for all actions. 45 runner = action_runner.ActionRunner(tab) 46 self._interaction = runner.BeginInteraction( 47 RUN_SMOOTH_ACTIONS, is_smooth=True) 48 49 def Stop(self, tab): 50 # End the smooth marker for all actions. 51 self._interaction.End() 52 # Stop tracing. 53 timeline_data = tab.browser.platform.tracing_controller.Stop() 54 self._model = TimelineModel(timeline_data) 55 self._renderer_process = self._model.GetRendererProcessFromTabId(tab.id) 56 renderer_thread = self.model.GetRendererThreadFromTabId(tab.id) 57 58 run_smooth_actions_record = None 59 self._smooth_records = [] 60 for event in renderer_thread.async_slices: 61 if not tir_module.IsTimelineInteractionRecord(event.name): 62 continue 63 r = tir_module.TimelineInteractionRecord.FromAsyncEvent(event) 64 if r.label == RUN_SMOOTH_ACTIONS: 65 assert run_smooth_actions_record is None, ( 66 'TimelineController cannot issue more than 1 %s record' % 67 RUN_SMOOTH_ACTIONS) 68 run_smooth_actions_record = r 69 elif r.is_smooth: 70 self._smooth_records.append( 71 smooth_gesture_util.GetAdjustedInteractionIfContainGesture( 72 self.model, r)) 73 74 # If there is no other smooth records, we make measurements on time range 75 # marked by timeline_controller itself. 76 # TODO(nednguyen): when crbug.com/239179 is marked fixed, makes sure that 77 # page sets are responsible for issueing the markers themselves. 78 if len(self._smooth_records) == 0 and run_smooth_actions_record: 79 self._smooth_records = [run_smooth_actions_record] 80 81 82 def CleanUp(self, tab): 83 if tab.browser.platform.tracing_controller.is_tracing_running: 84 tab.browser.platform.tracing_controller.Stop() 85 86 @property 87 def model(self): 88 return self._model 89 90 @property 91 def renderer_process(self): 92 return self._renderer_process 93 94 @property 95 def smooth_records(self): 96 return self._smooth_records 97