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 DidCreateBrowser(self, browser, browser_backend):
95    browser_options = browser_backend.browser_options
96    self.SetFullPerformanceModeEnabled(browser_options.full_performance_mode)
97
98  def DidStartBrowser(self, browser, browser_backend):
99    assert browser not in self._running_browser_backends
100    self._running_browser_backends.add(browser_backend)
101
102  def WillCloseBrowser(self, browser, browser_backend):
103    is_last_browser = len(self._running_browser_backends) <= 1
104    if is_last_browser:
105      self.SetFullPerformanceModeEnabled(False)
106
107    self._running_browser_backends.discard(browser_backend)
108
109  def IsDisplayTracingSupported(self):
110    return False
111
112  def StartDisplayTracing(self):
113    """Start gathering a trace with frame timestamps close to physical
114    display."""
115    raise NotImplementedError()
116
117  def StopDisplayTracing(self):
118    """Stop gathering a trace with frame timestamps close to physical display.
119
120    Returns a raw tracing events that contains the timestamps of physical
121    display.
122    """
123    raise NotImplementedError()
124
125  def SetFullPerformanceModeEnabled(self, enabled):
126    pass
127
128  def CanMonitorThermalThrottling(self):
129    return False
130
131  def IsThermallyThrottled(self):
132    raise NotImplementedError()
133
134  def HasBeenThermallyThrottled(self):
135    raise NotImplementedError()
136
137  def GetSystemCommitCharge(self):
138    raise NotImplementedError()
139
140  def GetSystemTotalPhysicalMemory(self):
141    raise NotImplementedError()
142
143  def GetCpuStats(self, pid):
144    return {}
145
146  def GetCpuTimestamp(self):
147    return {}
148
149  def PurgeUnpinnedMemory(self):
150    pass
151
152  def GetMemoryStats(self, pid):
153    return {}
154
155  def GetChildPids(self, pid):
156    raise NotImplementedError()
157
158  def GetCommandLine(self, pid):
159    raise NotImplementedError()
160
161  def GetDeviceTypeName(self):
162    raise NotImplementedError()
163
164  def GetArchName(self):
165    raise NotImplementedError()
166
167  def GetOSName(self):
168    raise NotImplementedError()
169
170  def GetOSVersionName(self):
171    raise NotImplementedError()
172
173  def CanFlushIndividualFilesFromSystemCache(self):
174    raise NotImplementedError()
175
176  def SupportFlushEntireSystemCache(self):
177    return False
178
179  def FlushEntireSystemCache(self):
180    raise NotImplementedError()
181
182  def FlushSystemCacheForDirectory(self, directory):
183    raise NotImplementedError()
184
185  def FlushDnsCache(self):
186    pass
187
188  def LaunchApplication(
189      self, application, parameters=None, elevate_privilege=False):
190    raise NotImplementedError()
191
192  def IsApplicationRunning(self, application):
193    raise NotImplementedError()
194
195  def CanLaunchApplication(self, application):
196    return False
197
198  def InstallApplication(self, application):
199    raise NotImplementedError()
200
201  def CanCaptureVideo(self):
202    return False
203
204  def StartVideoCapture(self, min_bitrate_mbps):
205    raise NotImplementedError()
206
207  @property
208  def is_video_capture_running(self):
209    return False
210
211  def StopVideoCapture(self):
212    raise NotImplementedError()
213
214  def CanMonitorPower(self):
215    return False
216
217  def CanMeasurePerApplicationPower(self):
218    return False
219
220  def StartMonitoringPower(self, browser):
221    raise NotImplementedError()
222
223  def StopMonitoringPower(self):
224    raise NotImplementedError()
225
226  def CanMonitorNetworkData(self):
227    return False
228
229  def GetNetworkData(self, browser):
230    raise NotImplementedError()
231
232  def ReadMsr(self, msr_number, start=0, length=64):
233    """Read a CPU model-specific register (MSR).
234
235    Which MSRs are available depends on the CPU model.
236    On systems with multiple CPUs, this function may run on any CPU.
237
238    Args:
239      msr_number: The number of the register to read.
240      start: The least significant bit to read, zero-indexed.
241          (Said another way, the number of bits to right-shift the MSR value.)
242      length: The number of bits to read. MSRs are 64 bits, even on 32-bit CPUs.
243    """
244    raise NotImplementedError()
245
246  @property
247  def supports_test_ca(self):
248    """Indicates whether the platform supports installing test CA."""
249    return False
250
251  def InstallTestCa(self, ca_cert_path):
252    """Install a test CA on the platform."""
253    raise NotImplementedError()
254
255  def RemoveTestCa(self):
256    """Remove a previously installed test CA from the platform."""
257    raise NotImplementedError()
258
259  def CanTakeScreenshot(self):
260    return False
261
262  def TakeScreenshot(self, file_path):
263    raise NotImplementedError
264
265  def IsCooperativeShutdownSupported(self):
266    """Indicates whether CooperativelyShutdown, below, is supported.
267    It is not necessary to implement it on all platforms."""
268    return False
269
270  def CooperativelyShutdown(self, proc, app_name):
271    """Cooperatively shut down the given process from subprocess.Popen.
272
273    Currently this is only implemented on Windows. See
274    crbug.com/424024 for background on why it was added.
275
276    Args:
277      proc: a process object returned from subprocess.Popen.
278      app_name: on Windows, is the prefix of the application's window
279          class name that should be searched for. This helps ensure
280          that only the application's windows are closed.
281
282    Returns True if it is believed the attempt succeeded.
283    """
284    raise NotImplementedError()
285
286  def PathExists(self, path, timeout=None, retries=None):
287    """Tests whether the given path exists on the target platform.
288    Args:
289      path: path in request.
290      timeout: timeout.
291      retries: num of retries.
292    Return:
293      Whether the path exists on the target platform.
294    """
295    raise NotImplementedError()
296
297  def HasBattOrConnected(self):
298    return battor_wrapper.IsBattOrConnected(self.GetOSName())
299