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 battor import battor_wrapper
8from telemetry.internal import forwarders
9from telemetry.internal.forwarders import do_nothing_forwarder
10from telemetry.internal.platform import network_controller_backend
11from telemetry.internal.platform import tracing_controller_backend
12
13
14# pylint: disable=unused-argument
15
16class PlatformBackend(object):
17
18  def __init__(self, device=None):
19    """ Initalize an instance of PlatformBackend from a device optionally.
20      Call sites need to use SupportsDevice before intialization to check
21      whether this platform backend supports the device.
22      If device is None, this constructor returns the host platform backend
23      which telemetry is running on.
24
25      Args:
26        device: an instance of telemetry.core.platform.device.Device.
27    """
28    if device and not self.SupportsDevice(device):
29      raise ValueError('Unsupported device: %s' % device.name)
30    self._platform = None
31    self._running_browser_backends = weakref.WeakSet()
32    self._network_controller_backend = None
33    self._tracing_controller_backend = None
34    self._forwarder_factory = None
35
36  def InitPlatformBackend(self):
37    self._network_controller_backend = (
38        network_controller_backend.NetworkControllerBackend(self))
39    self._tracing_controller_backend = (
40        tracing_controller_backend.TracingControllerBackend(self))
41
42  @classmethod
43  def IsPlatformBackendForHost(cls):
44    """ Returns whether this platform backend is the platform backend to be used
45    for the host device which telemetry is running on. """
46    return False
47
48  @classmethod
49  def SupportsDevice(cls, device):
50    """ Returns whether this platform backend supports intialization from the
51    device. """
52    return False
53
54  @classmethod
55  def CreatePlatformForDevice(cls, device, finder_options):
56    raise NotImplementedError
57
58  def SetPlatform(self, platform):
59    assert self._platform == None
60    self._platform = platform
61
62  @property
63  def platform(self):
64    return self._platform
65
66  @property
67  def is_host_platform(self):
68    return self._platform.is_host_platform
69
70  @property
71  def running_browser_backends(self):
72    return list(self._running_browser_backends)
73
74  @property
75  def network_controller_backend(self):
76    return self._network_controller_backend
77
78  @property
79  def tracing_controller_backend(self):
80    return self._tracing_controller_backend
81
82  @property
83  def forwarder_factory(self):
84    if not self._forwarder_factory:
85      self._forwarder_factory = do_nothing_forwarder.DoNothingForwarderFactory()
86    return self._forwarder_factory
87
88  def GetPortPairForForwarding(self, local_port):
89    return forwarders.PortPair(local_port=local_port, remote_port=local_port)
90
91  def GetRemotePort(self, port):
92    return port
93
94  def GetSystemLog(self):
95    return None
96
97  def DidCreateBrowser(self, browser, browser_backend):
98    browser_options = browser_backend.browser_options
99    self.SetFullPerformanceModeEnabled(browser_options.full_performance_mode)
100
101  def DidStartBrowser(self, browser, browser_backend):
102    assert browser not in self._running_browser_backends
103    self._running_browser_backends.add(browser_backend)
104
105  def WillCloseBrowser(self, browser, browser_backend):
106    is_last_browser = len(self._running_browser_backends) <= 1
107    if is_last_browser:
108      self.SetFullPerformanceModeEnabled(False)
109
110    self._running_browser_backends.discard(browser_backend)
111
112  def IsDisplayTracingSupported(self):
113    return False
114
115  def StartDisplayTracing(self):
116    """Start gathering a trace with frame timestamps close to physical
117    display."""
118    raise NotImplementedError()
119
120  def StopDisplayTracing(self):
121    """Stop gathering a trace with frame timestamps close to physical display.
122
123    Returns a raw tracing events that contains the timestamps of physical
124    display.
125    """
126    raise NotImplementedError()
127
128  def SetFullPerformanceModeEnabled(self, enabled):
129    pass
130
131  def CanMonitorThermalThrottling(self):
132    return False
133
134  def IsThermallyThrottled(self):
135    raise NotImplementedError()
136
137  def HasBeenThermallyThrottled(self):
138    raise NotImplementedError()
139
140  def GetSystemCommitCharge(self):
141    raise NotImplementedError()
142
143  def GetSystemTotalPhysicalMemory(self):
144    raise NotImplementedError()
145
146  def GetCpuStats(self, pid):
147    return {}
148
149  def GetCpuTimestamp(self):
150    return {}
151
152  def PurgeUnpinnedMemory(self):
153    pass
154
155  def GetMemoryStats(self, pid):
156    return {}
157
158  def GetChildPids(self, pid):
159    raise NotImplementedError()
160
161  def GetCommandLine(self, pid):
162    raise NotImplementedError()
163
164  def GetDeviceTypeName(self):
165    raise NotImplementedError()
166
167  def GetArchName(self):
168    raise NotImplementedError()
169
170  def GetOSName(self):
171    raise NotImplementedError()
172
173  def GetOSVersionName(self):
174    raise NotImplementedError()
175
176  def CanFlushIndividualFilesFromSystemCache(self):
177    raise NotImplementedError()
178
179  def SupportFlushEntireSystemCache(self):
180    return False
181
182  def FlushEntireSystemCache(self):
183    raise NotImplementedError()
184
185  def FlushSystemCacheForDirectory(self, directory):
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 CanMonitorNetworkData(self):
230    return False
231
232  def GetNetworkData(self, browser):
233    raise NotImplementedError()
234
235  def ReadMsr(self, msr_number, start=0, length=64):
236    """Read a CPU model-specific register (MSR).
237
238    Which MSRs are available depends on the CPU model.
239    On systems with multiple CPUs, this function may run on any CPU.
240
241    Args:
242      msr_number: The number of the register to read.
243      start: The least significant bit to read, zero-indexed.
244          (Said another way, the number of bits to right-shift the MSR value.)
245      length: The number of bits to read. MSRs are 64 bits, even on 32-bit CPUs.
246    """
247    raise NotImplementedError()
248
249  @property
250  def supports_test_ca(self):
251    """Indicates whether the platform supports installing test CA."""
252    return False
253
254  def InstallTestCa(self, ca_cert_path):
255    """Install a test CA on the platform."""
256    raise NotImplementedError()
257
258  def RemoveTestCa(self):
259    """Remove a previously installed test CA from the platform."""
260    raise NotImplementedError()
261
262  def CanTakeScreenshot(self):
263    return False
264
265  def TakeScreenshot(self, file_path):
266    raise NotImplementedError
267
268  def IsCooperativeShutdownSupported(self):
269    """Indicates whether CooperativelyShutdown, below, is supported.
270    It is not necessary to implement it on all platforms."""
271    return False
272
273  def CooperativelyShutdown(self, proc, app_name):
274    """Cooperatively shut down the given process from subprocess.Popen.
275
276    Currently this is only implemented on Windows. See
277    crbug.com/424024 for background on why it was added.
278
279    Args:
280      proc: a process object returned from subprocess.Popen.
281      app_name: on Windows, is the prefix of the application's window
282          class name that should be searched for. This helps ensure
283          that only the application's windows are closed.
284
285    Returns True if it is believed the attempt succeeded.
286    """
287    raise NotImplementedError()
288
289  def PathExists(self, path, timeout=None, retries=None):
290    """Tests whether the given path exists on the target platform.
291    Args:
292      path: path in request.
293      timeout: timeout.
294      retries: num of retries.
295    Return:
296      Whether the path exists on the target platform.
297    """
298    raise NotImplementedError()
299
300  def HasBattOrConnected(self):
301    return battor_wrapper.IsBattOrConnected(self.GetOSName())
302
303  def WaitForTemperature(self, temp):
304    """Waits for device under test to cool down to temperature given.
305    Args:
306      temp: temperature target in degrees C.
307    """
308    pass
309