1# Copyright 2013 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
5import weakref
6
7from telemetry.core.platform import profiling_controller_backend
8from telemetry.core.platform import tracing_controller_backend
9
10
11# pylint: disable=W0613
12
13# pylint: disable=W0212
14class OSVersion(str):
15  def __new__(cls, friendly_name, sortable_name, *args, **kwargs):
16    version = str.__new__(cls, friendly_name)
17    version._sortable_name = sortable_name
18    return version
19
20  def __lt__(self, other):
21    return self._sortable_name < other._sortable_name
22
23  def __gt__(self, other):
24    return self._sortable_name > other._sortable_name
25
26  def __le__(self, other):
27    return self._sortable_name <= other._sortable_name
28
29  def __ge__(self, other):
30    return self._sortable_name >= other._sortable_name
31
32
33XP =           OSVersion('xp',            5.1)
34VISTA =        OSVersion('vista',         6.0)
35WIN7 =         OSVersion('win7',          6.1)
36WIN8 =         OSVersion('win8',          6.2)
37
38LEOPARD =      OSVersion('leopard',      105)
39SNOWLEOPARD =  OSVersion('snowleopard',  106)
40LION =         OSVersion('lion',         107)
41MOUNTAINLION = OSVersion('mountainlion', 108)
42MAVERICKS =    OSVersion('mavericks',    109)
43YOSEMITE =     OSVersion('yosemite',     1010)
44
45
46class PlatformBackend(object):
47
48  def __init__(self, device=None):
49    """ Initalize an instance of PlatformBackend from a device optionally.
50      Call sites need to use SupportsDevice before intialization to check
51      whether this platform backend supports the device.
52      If device is None, this constructor returns the host platform backend
53      which telemetry is running on.
54
55      Args:
56        device: an instance of telemetry.core.platform.device.Device.
57    """
58    if device and not self.SupportsDevice(device):
59      raise ValueError('Unsupported device: %s' % device.name)
60    self._platform = None
61    self._running_browser_backends = weakref.WeakSet()
62    self._tracing_controller_backend = (
63        tracing_controller_backend.TracingControllerBackend(self))
64    self._profiling_controller_backend = (
65        profiling_controller_backend.ProfilingControllerBackend(self))
66
67  @classmethod
68  def SupportsDevice(cls, device):
69    """ Returns whether this platform backend supports intialization from the
70    device. """
71    return False
72
73  def SetPlatform(self, platform):
74    assert self._platform == None
75    self._platform = platform
76
77  @property
78  def platform(self):
79    return self._platform
80
81  @property
82  def running_browser_backends(self):
83    return list(self._running_browser_backends)
84
85  @property
86  def tracing_controller_backend(self):
87    return self._tracing_controller_backend
88
89  @property
90  def profiling_controller_backend(self):
91    return self._profiling_controller_backend
92
93  def DidCreateBrowser(self, browser, browser_backend):
94    self.SetFullPerformanceModeEnabled(True)
95
96  def DidStartBrowser(self, browser, browser_backend):
97    assert browser not in self._running_browser_backends
98    self._running_browser_backends.add(browser_backend)
99    self._tracing_controller_backend.DidStartBrowser(
100        browser, browser_backend)
101
102  def WillCloseBrowser(self, browser, browser_backend):
103    self._tracing_controller_backend.WillCloseBrowser(
104        browser, browser_backend)
105    self._profiling_controller_backend.WillCloseBrowser(
106        browser_backend)
107
108    is_last_browser = len(self._running_browser_backends) == 1
109    if is_last_browser:
110      self.SetFullPerformanceModeEnabled(False)
111
112    self._running_browser_backends.remove(browser_backend)
113
114  def GetBackendForBrowser(self, browser):
115    matches = [x for x in self._running_browser_backends
116               if x.browser == browser]
117    if len(matches) == 0:
118      raise Exception('No browser found')
119    assert len(matches) == 1
120    return matches[0]
121
122  def IsRawDisplayFrameRateSupported(self):
123    return False
124
125  def StartRawDisplayFrameRateMeasurement(self):
126    raise NotImplementedError()
127
128  def StopRawDisplayFrameRateMeasurement(self):
129    raise NotImplementedError()
130
131  def GetRawDisplayFrameRateMeasurements(self):
132    raise NotImplementedError()
133
134  def SetFullPerformanceModeEnabled(self, enabled):
135    pass
136
137  def CanMonitorThermalThrottling(self):
138    return False
139
140  def IsThermallyThrottled(self):
141    raise NotImplementedError()
142
143  def HasBeenThermallyThrottled(self):
144    raise NotImplementedError()
145
146  def GetSystemCommitCharge(self):
147    raise NotImplementedError()
148
149  def GetSystemTotalPhysicalMemory(self):
150    raise NotImplementedError()
151
152  def GetCpuStats(self, pid):
153    return {}
154
155  def GetCpuTimestamp(self):
156    return {}
157
158  def PurgeUnpinnedMemory(self):
159    pass
160
161  def GetMemoryStats(self, pid):
162    return {}
163
164  def GetIOStats(self, pid):
165    return {}
166
167  def GetChildPids(self, pid):
168    raise NotImplementedError()
169
170  def GetCommandLine(self, pid):
171    raise NotImplementedError()
172
173  def GetOSName(self):
174    raise NotImplementedError()
175
176  def GetOSVersionName(self):
177    raise NotImplementedError()
178
179  def CanFlushIndividualFilesFromSystemCache(self):
180    raise NotImplementedError()
181
182  def FlushEntireSystemCache(self):
183    raise NotImplementedError()
184
185  def FlushSystemCacheForDirectory(self, directory, ignoring=None):
186    raise NotImplementedError()
187
188  def FlushDnsCache(self):
189    pass
190
191  def LaunchApplication(
192      self, application, parameters=None, elevate_privilege=False):
193    raise NotImplementedError()
194
195  def IsApplicationRunning(self, application):
196    raise NotImplementedError()
197
198  def CanLaunchApplication(self, application):
199    return False
200
201  def InstallApplication(self, application):
202    raise NotImplementedError()
203
204  def CanCaptureVideo(self):
205    return False
206
207  def StartVideoCapture(self, min_bitrate_mbps):
208    raise NotImplementedError()
209
210  @property
211  def is_video_capture_running(self):
212    return False
213
214  def StopVideoCapture(self):
215    raise NotImplementedError()
216
217  def CanMonitorPower(self):
218    return False
219
220  def CanMeasurePerApplicationPower(self):
221    return False
222
223  def StartMonitoringPower(self, browser):
224    raise NotImplementedError()
225
226  def StopMonitoringPower(self):
227    raise NotImplementedError()
228
229  def ReadMsr(self, msr_number, start=0, length=64):
230    """Read a CPU model-specific register (MSR).
231
232    Which MSRs are available depends on the CPU model.
233    On systems with multiple CPUs, this function may run on any CPU.
234
235    Args:
236      msr_number: The number of the register to read.
237      start: The least significant bit to read, zero-indexed.
238          (Said another way, the number of bits to right-shift the MSR value.)
239      length: The number of bits to read. MSRs are 64 bits, even on 32-bit CPUs.
240    """
241    raise NotImplementedError()
242