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