| # Copyright 2014 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| from measurements import smooth_gesture_util |
| |
| from telemetry.core.backends.chrome import tracing_backend |
| from telemetry.timeline.model import TimelineModel |
| from telemetry.page.actions import action_runner |
| from telemetry.web_perf import timeline_interaction_record as tir_module |
| |
| |
| RUN_SMOOTH_ACTIONS = 'RunSmoothAllActions' |
| |
| |
| class TimelineController(object): |
| def __init__(self): |
| super(TimelineController, self).__init__() |
| self.trace_categories = tracing_backend.DEFAULT_TRACE_CATEGORIES |
| self._model = None |
| self._renderer_process = None |
| self._smooth_records = [] |
| self._interaction = None |
| |
| def Start(self, page, tab): |
| """Starts gathering timeline data. |
| |
| """ |
| # Resets these member variables incase this object is reused. |
| self._model = None |
| self._renderer_process = None |
| if not tab.browser.supports_tracing: |
| raise Exception('Not supported') |
| if self.trace_categories: |
| categories = [self.trace_categories] + \ |
| page.GetSyntheticDelayCategories() |
| else: |
| categories = page.GetSyntheticDelayCategories() |
| tab.browser.StartTracing(','.join(categories)) |
| # Start the smooth marker for all actions. |
| runner = action_runner.ActionRunner(tab) |
| self._interaction = runner.BeginInteraction( |
| RUN_SMOOTH_ACTIONS, is_smooth=True) |
| |
| def Stop(self, tab): |
| # End the smooth marker for all actions. |
| self._interaction.End() |
| # Stop tracing. |
| timeline_data = tab.browser.StopTracing() |
| self._model = TimelineModel(timeline_data) |
| self._renderer_process = self._model.GetRendererProcessFromTabId(tab.id) |
| renderer_thread = self.model.GetRendererThreadFromTabId(tab.id) |
| |
| run_smooth_actions_record = None |
| self._smooth_records = [] |
| for event in renderer_thread.async_slices: |
| if not tir_module.IsTimelineInteractionRecord(event.name): |
| continue |
| r = tir_module.TimelineInteractionRecord.FromAsyncEvent(event) |
| if r.logical_name == RUN_SMOOTH_ACTIONS: |
| assert run_smooth_actions_record is None, ( |
| 'TimelineController cannot issue more than 1 %s record' % |
| RUN_SMOOTH_ACTIONS) |
| run_smooth_actions_record = r |
| elif r.is_smooth: |
| self._smooth_records.append( |
| smooth_gesture_util.GetAdjustedInteractionIfContainGesture( |
| self.model, r)) |
| |
| # If there is no other smooth records, we make measurements on time range |
| # marked by timeline_controller itself. |
| # TODO(nednguyen): when crbug.com/239179 is marked fixed, makes sure that |
| # page sets are responsible for issueing the markers themselves. |
| if len(self._smooth_records) == 0 and run_smooth_actions_record: |
| self._smooth_records = [run_smooth_actions_record] |
| |
| |
| def CleanUp(self, tab): |
| if tab.browser.is_tracing_running: |
| tab.browser.StopTracing() |
| |
| @property |
| def model(self): |
| return self._model |
| |
| @property |
| def renderer_process(self): |
| return self._renderer_process |
| |
| @property |
| def smooth_records(self): |
| return self._smooth_records |