Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / web_perf / timeline_interaction_record.py
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
5 import re
6
7 from telemetry import decorators
8 import telemetry.core.timeline.bounds as timeline_bounds
9
10
11 IS_SMOOTH = "is_smooth"
12 IS_LOADING_RESOURCES = "is_loading_resources"
13
14 FLAGS = [
15   IS_SMOOTH,
16   IS_LOADING_RESOURCES
17 ]
18
19 def IsTimelineInteractionRecord(event_name):
20   return event_name.startswith('Interaction.')
21
22
23 class TimelineInteractionRecord(object):
24   """Represents an interaction that took place during a timeline recording.
25
26   As a page runs, typically a number of different (simulated) user interactions
27   take place. For instance, a user might click a button in a mail app causing a
28   popup to animate in. Then they might press another button that sends data to a
29   server and simultaneously closes the popup without an animation. These are two
30   interactions.
31
32   From the point of view of the page, each interaction might have a different
33   logical name: ClickComposeButton and SendEmail, for instance. From the point
34   of view of the benchmarking harness, the names aren't so interesting as what
35   the performance expectations are for that interaction: was it loading
36   resources from the network? was there an animation?
37
38   Determining these things is hard to do, simply by observing the state given to
39   a page from javascript. There are hints, for instance if network requests are
40   sent, or if a CSS animation is pending. But this is by no means a complete
41   story.
42
43   Instead, we expect pages to mark up the timeline what they are doing, with
44   logical names, and flags indicating the semantics of that interaction. This
45   is currently done by pushing markers into the console.time/timeEnd API: this
46   for instance can be issued in JS:
47
48      var str = 'Interaction.SendEmail/is_smooth,is_loading_resources';
49      console.time(str);
50      setTimeout(function() {
51        console.timeEnd(str);
52      }, 1000);
53
54   When run with perf.measurements.timeline_based_measurement running, this will
55   then cause a TimelineInteractionRecord to be created for this range and both
56   smoothness and network metrics to be reported for the marked up 1000ms
57   time-range.
58
59   """
60   def __init__(self, logical_name, start, end):
61     assert logical_name
62     self.logical_name = logical_name
63     self.start = start
64     self.end = end
65     self.is_smooth = False
66     self.is_loading_resources = False
67
68   @staticmethod
69   def FromEvent(event):
70     m = re.match('Interaction\.(.+)\/(.+)', event.name)
71     if m:
72       logical_name = m.group(1)
73       if m.group(1) != '':
74         flags = m.group(2).split(',')
75       else:
76         flags = []
77     else:
78       m = re.match('Interaction\.(.+)', event.name)
79       assert m
80       logical_name = m.group(1)
81       flags = []
82
83     record = TimelineInteractionRecord(logical_name, event.start, event.end)
84     for f in flags:
85       if not f in FLAGS:
86         raise Exception(
87           'Unrecognized flag in timeline Interaction record: %s' % f)
88     record.is_smooth = IS_SMOOTH in flags
89     record.is_loading_resources = IS_LOADING_RESOURCES in flags
90     return record
91
92   def GetResultNameFor(self, result_name):
93     return '%s-%s' % (self.logical_name, result_name)
94
95   @decorators.Cache
96   def GetBounds(self):
97     bounds = timeline_bounds.Bounds()
98     bounds.AddValue(self.start)
99     bounds.AddValue(self.end)
100     return bounds
101
102   @staticmethod
103   def GetJavascriptMarker(logical_name, flags):
104     """ Get the marker string of an interaction record with logical_name
105     and flags.
106     """
107     assert isinstance(flags, list)
108     for f in flags:
109       if f not in FLAGS:
110         raise Exception(
111           'Unrecognized flag for a timeline Interaction record: %s' % f)
112     return 'Interaction.%s/%s' % (logical_name, ','.join(flags))