Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / core / platform / profiler / monsoon_profiler.py
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
5 import csv
6 import multiprocessing
7
8 from telemetry.core import exceptions
9 from telemetry.core.platform import profiler
10 from telemetry.core.platform.profiler import monsoon
11
12
13 def _CollectData(output_path, is_collecting):
14   mon = monsoon.Monsoon(wait=False)
15   mon.SetMaxCurrent(2.0)
16   # Note: Telemetry requires the device to be connected by USB, but that
17   # puts it in charging mode. This increases the power consumption.
18   mon.SetUsbPassthrough(1)
19   # Nominal Li-ion voltage is 3.7V, but it puts out 4.2V at max capacity. Use
20   # 4.0V to simulate a "~80%" charged battery. Google "li-ion voltage curve".
21   # This is true only for a single cell. (Most smartphones, some tablets.)
22   mon.SetVoltage(4.0)
23
24   samples = []
25   try:
26     mon.StartDataCollection()
27     # Do one CollectData() to make the Monsoon set up, which takes about
28     # 0.3 seconds, and only signal that we've started after that.
29     mon.CollectData()
30     is_collecting.set()
31     while is_collecting.is_set():
32       samples += mon.CollectData()
33   finally:
34     mon.StopDataCollection()
35
36   # Add x-axis labels.
37   plot_data = [(i / 5000., sample(0)) for i, sample in enumerate(samples)]
38
39   # Print data in csv.
40   with open(output_path, 'w') as output_file:
41     output_writer = csv.writer(output_file)
42     output_writer.writerows(plot_data)
43     output_file.flush()
44
45   print 'To view the Monsoon profile, run:'
46   print ('  echo "set datafile separator \',\'; plot \'%s\' with lines" | '
47       'gnuplot --persist' % output_path)
48
49
50 class MonsoonProfiler(profiler.Profiler):
51   """Profiler that tracks current using Monsoon Power Monitor.
52
53   http://www.msoon.com/LabEquipment/PowerMonitor/
54   The Monsoon device measures current in amps at 5000 samples/second.
55   """
56   def __init__(self, browser_backend, platform_backend, output_path, state):
57     super(MonsoonProfiler, self).__init__(
58         browser_backend, platform_backend, output_path, state)
59     # We collect the data in a separate process, so we can continuously
60     # read the samples from the USB port while running the test.
61     self._is_collecting = multiprocessing.Event()
62     self._collector = multiprocessing.Process(
63         target=_CollectData, args=(output_path, self._is_collecting))
64     self._collector.start()
65     if not self._is_collecting.wait(timeout=0.5):
66       self._collector.terminate()
67       raise exceptions.ProfilingException('Failed to start data collection.')
68
69   @classmethod
70   def name(cls):
71     return 'monsoon'
72
73   @classmethod
74   def is_supported(cls, browser_type):
75     try:
76       monsoon.Monsoon(wait=False)
77     except EnvironmentError:
78       return False
79     else:
80       return True
81
82   def CollectProfile(self):
83     self._is_collecting.clear()
84     self._collector.join()
85     return [self._output_path]