Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: telemetry/telemetry/internal/platform/cros_platform_backend.py

Issue 2876843002: Simulate interactivity boost for simulated user input events
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 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 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import logging 5 import logging
6 6
7 from telemetry import decorators 7 from telemetry import decorators
8 from telemetry.core import cros_interface 8 from telemetry.core import cros_interface
9 from telemetry.core import platform 9 from telemetry.core import platform
10 from telemetry.core import util 10 from telemetry.core import util
11 from telemetry.internal.forwarders import cros_forwarder 11 from telemetry.internal.forwarders import cros_forwarder
12 from telemetry.internal.platform import cros_device 12 from telemetry.internal.platform import cros_device
13 from telemetry.internal.platform import linux_based_platform_backend 13 from telemetry.internal.platform import linux_based_platform_backend
14 from telemetry.internal.platform.power_monitor import cros_power_monitor 14 from telemetry.internal.platform.power_monitor import cros_power_monitor
15 from telemetry.internal.util import ps_util 15 from telemetry.internal.util import ps_util
16 from telemetry.internal.util import repeating_timer
16 17
17 18
18 class CrosPlatformBackend( 19 class CrosPlatformBackend(
19 linux_based_platform_backend.LinuxBasedPlatformBackend): 20 linux_based_platform_backend.LinuxBasedPlatformBackend):
20 def __init__(self, device=None): 21 def __init__(self, device=None):
21 super(CrosPlatformBackend, self).__init__(device) 22 super(CrosPlatformBackend, self).__init__(device)
22 if device and not device.is_local: 23 if device and not device.is_local:
23 self._cri = cros_interface.CrOSInterface( 24 self._cri = cros_interface.CrOSInterface(
24 device.host_name, device.ssh_port, device.ssh_identity) 25 device.host_name, device.ssh_port, device.ssh_identity)
25 self._cri.TryLogin() 26 self._cri.TryLogin()
26 else: 27 else:
27 self._cri = cros_interface.CrOSInterface() 28 self._cri = cros_interface.CrOSInterface()
28 self._powermonitor = cros_power_monitor.CrosPowerMonitor(self) 29 self._powermonitor = cros_power_monitor.CrosPowerMonitor(self)
30 self._InitialiseInteractiveBoost()
29 31
30 @classmethod 32 @classmethod
31 def IsPlatformBackendForHost(cls): 33 def IsPlatformBackendForHost(cls):
32 return util.IsRunningOnCrosDevice() 34 return util.IsRunningOnCrosDevice()
33 35
34 @classmethod 36 @classmethod
35 def SupportsDevice(cls, device): 37 def SupportsDevice(cls, device):
36 return isinstance(device, cros_device.CrOSDevice) 38 return isinstance(device, cros_device.CrOSDevice)
37 39
38 @classmethod 40 @classmethod
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 logging.warning( 163 logging.warning(
162 'PathExists: params timeout and retries are not support on CrOS.') 164 'PathExists: params timeout and retries are not support on CrOS.')
163 return self._cri.FileExistsOnDevice(path) 165 return self._cri.FileExistsOnDevice(path)
164 166
165 def CanTakeScreenshot(self): 167 def CanTakeScreenshot(self):
166 # crbug.com/609001: screenshots don't work on VMs. 168 # crbug.com/609001: screenshots don't work on VMs.
167 return not self.cri.IsRunningOnVM() 169 return not self.cri.IsRunningOnVM()
168 170
169 def TakeScreenshot(self, file_path): 171 def TakeScreenshot(self, file_path):
170 return self._cri.TakeScreenshot(file_path) 172 return self._cri.TakeScreenshot(file_path)
173
174 def _InitialiseInteractiveBoost(self):
175 """On ChromeOS on ARM, the kernel boosts CPU frequency when an input (key
176 press, touch event, etc) is received. For simulated inputs, this doesn't
177 happen, so this functionality activates the same boost mechanism by
178 using the sysfs controls.
179 The boost should be turned on for specific interaction events, for the
180 duration of the interaction, to simulate normal system behaviour.
181 On systems which do not support frequency boost, this has no effect
182 (consistent with normal non-simulated behaviour).
183 """
184 self._boost_duration = None
185 self._boost_timer = None
186 governor = self.GetFileContents(
187 "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor").strip()
188 if governor != "interactive":
189 logging.warning("no interactive cpufreq governor present, not setting"
190 " up interactivity boost")
191 return
192 core = 0
193 durations = {}
194 while True:
195 path = "/sys/devices/system/cpu/cpu" + str(core) + "/cpufreq/interactive"
196 if self.PathExists(path + "/boostpulse_duration") \
197 and self.PathExists(path + "/boostpulse"):
198 durations[core] = self.GetFileContents(path
199 + "/boostpulse_duration").strip()
200 else:
201 break
202 core = core + 1
203 if durations:
204 # Set timer to drive boost every 9 minutes. It lasts for 10 minutes
205 # so this ensures it will remain constantly on with minimal
206 # overhead, until turned off.
207 self._boost_timer = repeating_timer.RepeatingTimer(
208 lambda: self._WriteCPUFreqControl("boostpulse", "1"), 9 * 60)
209 self._boost_duration = durations
210 logging.info("interactivity boost set up")
211 else:
212 logging.info("kernel does not support frequency boost controls,"
213 "interactivity boost could not be set up")
214
215 def _WriteCPUFreqControl(self, leaf, content):
216 if self._boost_duration is not None:
217 cmds = []
218 for core in self._boost_duration:
219 path = "/sys/devices/system/cpu/cpu" + str(core) \
220 + "/cpufreq/interactive"
221 value = content if not isinstance(content, dict) else content[core]
222 if cmds:
223 cmds.append(';')
224 cmds.extend(['echo', value, '>', path + "/" + leaf])
225 self.RunCommand(cmds)
226
227 def SetInteractivityBoost(self, enable):
228 if self._boost_duration is not None \
229 and self._boost_timer.IsRunning() != enable:
230 logging.info('SetInteractivityBoost: %s boost on %d cores',
231 ("enabling" if enable else "disabling"), len(self._boost_duration))
232
233 # enable a timer to initiate a regular boost pulse
234 #
235 # the boost pulse duration and timer are such that boost will remain
236 # constantly enabled
237 if enable:
238 # set the boost duration to 10 minutes
239 self._WriteCPUFreqControl("boostpulse_duration", "600000000")
240 self._WriteCPUFreqControl("boostpulse", "1")
241 self._boost_timer.Start()
242 else:
243 # set the boost duration back to the default setting if disabling.
244 self._WriteCPUFreqControl("boostpulse_duration", self._boost_duration)
245 self._boost_timer.Stop()
246 # this ensures that the pulse continues for the default pulse duration
247 # (typically 80 ms) after the input event ends - as would normally
248 # happen with real user interaction.
249 self._WriteCPUFreqControl("boostpulse", "1")
OLDNEW
« no previous file with comments | « telemetry/telemetry/internal/browser/browser.py ('k') | telemetry/telemetry/internal/platform/platform_backend.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698