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 AddResults(self, tab, results): # Add results of smoothness metric. This computes the smoothness metric for # the time ranges of gestures, if there is at least one, else the the time # ranges from the first action to the last action. renderer_thread = self._timeline_model.GetRendererThreadFromTabId( tab.id) run_smooth_actions_record = None 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, ( 'SmoothnessController cannot issue more than 1 %s record' % RUN_SMOOTH_ACTIONS) run_smooth_actions_record = r elif r.is_smooth: smooth_records.append( smooth_gesture_util.GetAdjustedInteractionIfContainGesture( self._timeline_model, r)) # If there is no other smooth records, we make measurements on time range # marked smoothness_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(smooth_records) == 0: if run_smooth_actions_record is None: sys.stderr.write('Raw tracing data:\n') sys.stderr.write(repr(self._tracing_timeline_data.EventData())) sys.stderr.write('\n') raise Exception( 'SmoothnessController failed to issue markers for the ' 'whole interaction.') else: smooth_records = [run_smooth_actions_record] # Create an interaction_record for this legacy measurement. Since we don't # wrap the results that is sent to smoothnes metric, the logical_name will # not be used. smoothness_metric = smoothness.SmoothnessMetric() smoothness_metric.AddResults(self._timeline_model, renderer_thread, smooth_records, results) if tab.browser.platform.IsRawDisplayFrameRateSupported(): for r in tab.browser.platform.GetRawDisplayFrameRateMeasurements(): if r.value is None: raise MissingDisplayFrameRateError(r.name) results.Add(r.name, r.unit, r.value)
def testSmoothGestureAdjusted(self): ps = self.CreateEmptyPageSet() ps.AddUserStory( ScrollingPage('file://scrollable_page.html', ps, base_dir=ps.base_dir)) models = [] tab_ids = [] class ScrollingGestureTestMeasurement(page_test.PageTest): def __init__(self): # pylint: disable=bad-super-call super(ScrollingGestureTestMeasurement, self).__init__('RunPageInteractions', False) def WillRunActions(self, _page, tab): options = tracing_options.TracingOptions() options.enable_chrome_trace = True tab.browser.platform.tracing_controller.Start( options, tracing_category_filter.TracingCategoryFilter()) def DidRunActions(self, _page, tab): models.append( model_module.TimelineModel( tab.browser.platform.tracing_controller.Stop())) tab_ids.append(tab.id) def ValidateAndMeasurePage(self, _page, _tab, _results): pass self.RunMeasurement(ScrollingGestureTestMeasurement(), ps) timeline_model = models[0] renderer_thread = timeline_model.GetRendererThreadFromTabId(tab_ids[0]) smooth_record = None for e in renderer_thread.async_slices: if tir_module.IsTimelineInteractionRecord(e.name): smooth_record = tir_module.TimelineInteractionRecord.FromAsyncEvent( e) self.assertIsNotNone(smooth_record) adjusted_smooth_gesture = ( sg_util.GetAdjustedInteractionIfContainGesture( timeline_model, smooth_record)) # Test that the scroll gesture starts at at least 500ms after the start of # the interaction record and ends at at least 500ms before the end of # interaction record. self.assertLessEqual( 500, adjusted_smooth_gesture.start - smooth_record.start) self.assertLessEqual(500, smooth_record.end - adjusted_smooth_gesture.end)
def _ExtractInteractionsRecordFromThread(thread, timeline_model): run_smooth_actions_record = None records = [] for event in thread.async_slices: if not tir_module.IsTimelineInteractionRecord(event.name): continue assert event.start_thread assert event.start_thread is event.end_thread r = smooth_gesture_util.GetAdjustedInteractionIfContainGesture( timeline_model, tir_module.TimelineInteractionRecord.FromAsyncEvent(event)) if r.label == smoothness_controller.RUN_SMOOTH_ACTIONS: assert run_smooth_actions_record is None, ( 'There can\'t be more than 1 %s record' % smoothness_controller.RUN_SMOOTH_ACTIONS) run_smooth_actions_record = r else: records.append(r) if not records: # Only include run_smooth_actions_record (label = # smoothness_controller.RUN_SMOOTH_ACTIONS) if there is no other records records = [run_smooth_actions_record] return records
def testGetAdjustedInteractionIfContainGesture(self): model = model_module.TimelineModel() renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2) renderer_main.name = 'CrRendererMain' # [ X ] [ Y ] # [ sub_async_slice_X ] # [ record_1] # [ record_6] # [ record_2 ] [ record_3 ] # [ record_4 ] # [ record_5 ] # # Note: X and Y are async slice with name # SyntheticGestureController::running async_slice_X = async_slice.AsyncSlice( 'X', 'SyntheticGestureController::running', 10, duration=20, start_thread=renderer_main, end_thread=renderer_main) sub_async_slice_X = async_slice.AsyncSlice( 'X', 'SyntheticGestureController::running', 10, duration=20, start_thread=renderer_main, end_thread=renderer_main) sub_async_slice_X.parent_slice = async_slice_X async_slice_X.AddSubSlice(sub_async_slice_X) async_slice_Y = async_slice.AsyncSlice( 'X', 'SyntheticGestureController::running', 60, duration=20, start_thread=renderer_main, end_thread=renderer_main) renderer_main.AddAsyncSlice(async_slice_X) renderer_main.AddAsyncSlice(async_slice_Y) model.FinalizeImport(shift_world_to_zero=False) record_1 = tir_module.TimelineInteractionRecord( 'Gesture_included', 15, 25) record_2 = tir_module.TimelineInteractionRecord( 'Gesture_overlapped_left', 5, 25) record_3 = tir_module.TimelineInteractionRecord( 'Gesture_overlapped_right', 25, 35) record_4 = tir_module.TimelineInteractionRecord( 'Gesture_containing', 5, 35) record_5 = tir_module.TimelineInteractionRecord( 'Gesture_non_overlapped', 35, 45) record_6 = tir_module.TimelineInteractionRecord( 'Action_included', 15, 25) adjusted_record_1 = sg_util.GetAdjustedInteractionIfContainGesture( model, record_1) self.assertEquals(adjusted_record_1.start, 10) self.assertEquals(adjusted_record_1.end, 30) self.assertTrue(adjusted_record_1 is not record_1) adjusted_record_2 = sg_util.GetAdjustedInteractionIfContainGesture( model, record_2) self.assertEquals(adjusted_record_2.start, 10) self.assertEquals(adjusted_record_2.end, 30) adjusted_record_3 = sg_util.GetAdjustedInteractionIfContainGesture( model, record_3) self.assertEquals(adjusted_record_3.start, 10) self.assertEquals(adjusted_record_3.end, 30) adjusted_record_4 = sg_util.GetAdjustedInteractionIfContainGesture( model, record_4) self.assertEquals(adjusted_record_4.start, 10) self.assertEquals(adjusted_record_4.end, 30) adjusted_record_5 = sg_util.GetAdjustedInteractionIfContainGesture( model, record_5) self.assertEquals(adjusted_record_5.start, 35) self.assertEquals(adjusted_record_5.end, 45) self.assertTrue(adjusted_record_5 is not record_5) adjusted_record_6 = sg_util.GetAdjustedInteractionIfContainGesture( model, record_6) self.assertEquals(adjusted_record_6.start, 15) self.assertEquals(adjusted_record_6.end, 25) self.assertTrue(adjusted_record_6 is not record_6)
def testGetAdjustedInteractionIfContainGesture(self): model = model_module.TimelineModel() renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2) renderer_main.name = 'CrRendererMain' # [ X ] [ Y ] # [ record_1] # [ record_6] # [ record_2 ] [ record_3 ] # [ record_4 ] # [ record_5 ] renderer_main.BeginSlice('X', 'SyntheticGestureController::running', 10, 0) renderer_main.EndSlice(30, 30) renderer_main.BeginSlice('Y', 'SyntheticGestureController::running', 60, 0) renderer_main.EndSlice(80, 80) model.FinalizeImport(shift_world_to_zero=False) record_1 = tir_module.TimelineInteractionRecord( 'Gesture_included', 15, 25) record_2 = tir_module.TimelineInteractionRecord( 'Gesture_overlapped_left', 5, 25) record_3 = tir_module.TimelineInteractionRecord( 'Gesture_overlapped_right', 25, 35) record_4 = tir_module.TimelineInteractionRecord( 'Gesture_containing', 5, 35) record_5 = tir_module.TimelineInteractionRecord( 'Gesture_non_overlapped', 35, 45) record_6 = tir_module.TimelineInteractionRecord( 'Action_included', 15, 25) adjusted_record_1 = sg_util.GetAdjustedInteractionIfContainGesture( model, record_1) self.assertEquals(adjusted_record_1.start, 10) self.assertEquals(adjusted_record_1.end, 30) self.assertTrue(adjusted_record_1 is not record_1) adjusted_record_2 = sg_util.GetAdjustedInteractionIfContainGesture( model, record_2) self.assertEquals(adjusted_record_2.start, 10) self.assertEquals(adjusted_record_2.end, 30) adjusted_record_3 = sg_util.GetAdjustedInteractionIfContainGesture( model, record_3) self.assertEquals(adjusted_record_3.start, 10) self.assertEquals(adjusted_record_3.end, 30) adjusted_record_4 = sg_util.GetAdjustedInteractionIfContainGesture( model, record_4) self.assertEquals(adjusted_record_4.start, 10) self.assertEquals(adjusted_record_4.end, 30) adjusted_record_5 = sg_util.GetAdjustedInteractionIfContainGesture( model, record_5) self.assertEquals(adjusted_record_5.start, 35) self.assertEquals(adjusted_record_5.end, 45) self.assertTrue(adjusted_record_5 is not record_5) adjusted_record_6 = sg_util.GetAdjustedInteractionIfContainGesture( model, record_6) self.assertEquals(adjusted_record_6.start, 15) self.assertEquals(adjusted_record_6.end, 25) self.assertTrue(adjusted_record_6 is not record_6)