Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / tools / perf / metrics / power.py
index 912722e..022c02f 100644 (file)
@@ -2,23 +2,31 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import logging
+import time
 
 from metrics import Metric
-from telemetry.core.platform import factory
+from telemetry.value import scalar
 
 
 class PowerMetric(Metric):
   """A metric for measuring power usage."""
 
-  enabled = True
+  # System power draw while idle.
+  _quiescent_power_draw_mwh = 0
 
-  def __init__(self):
+  def __init__(self, browser, quiescent_measurement_time_s=0):
+    """PowerMetric Constructor.
+
+    Args:
+        browser: browser object to use.
+        quiescent_measurement_time_s: time to measure quiescent power,
+            in seconds. 0 means don't measure quiescent power."""
     super(PowerMetric, self).__init__()
-    self._browser = None
+    self._browser = browser
     self._running = False
     self._starting_cpu_stats = None
     self._results = None
+    self._MeasureQuiescentPower(quiescent_measurement_time_s)
 
   def __del__(self):
     # TODO(jeremy): Remove once crbug.com/350841 is fixed.
@@ -29,7 +37,7 @@ class PowerMetric(Metric):
       parent.__del__()
 
   def _StopInternal(self):
-    """ Stop monitoring power if measurement is running. This function is
+    """Stop monitoring power if measurement is running. This function is
     idempotent."""
     if not self._running:
       return
@@ -39,30 +47,29 @@ class PowerMetric(Metric):
       self._results['cpu_stats'] = (
           _SubtractCpuStats(self._browser.cpu_stats, self._starting_cpu_stats))
 
-  @classmethod
-  def CustomizeBrowserOptions(cls, options):
-    PowerMetric.enabled = options.report_root_metrics
-
-    # Friendly informational messages if measurement won't run.
-    system_supports_power_monitoring = (
-        factory.GetPlatformBackendForCurrentOS().CanMonitorPower())
-    if system_supports_power_monitoring:
-      if not PowerMetric.enabled:
-        logging.warning(
-            "--report-root-metrics omitted, power measurement disabled.")
-    else:
-      logging.info("System doesn't support power monitoring, power measurement"
-          " disabled.")
+  def _MeasureQuiescentPower(self, measurement_time_s):
+    """Measure quiescent power draw for the system."""
+    platform = self._browser.platform
+    if not platform.CanMonitorPower() or \
+        platform.CanMeasurePerApplicationPower() or \
+        not measurement_time_s:
+      return
 
-  def Start(self, _, tab):
-    if not PowerMetric.enabled:
+    # Only perform quiescent measurement once per run.
+    if PowerMetric._quiescent_power_draw_mwh:
       return
 
+    platform.StartMonitoringPower(self._browser)
+    time.sleep(measurement_time_s)
+    power_results = platform.StopMonitoringPower()
+    PowerMetric._quiescent_power_draw_mwh = (
+        power_results.get('energy_consumption_mwh', 0))
+
+  def Start(self, _, tab):
     if not tab.browser.platform.CanMonitorPower():
       return
 
     self._results = None
-    self._browser = tab.browser
     self._StopInternal()
 
     # This line invokes top a few times, call before starting power measurement.
@@ -71,9 +78,6 @@ class PowerMetric(Metric):
     self._running = True
 
   def Stop(self, _, tab):
-    if not PowerMetric.enabled:
-      return
-
     if not tab.browser.platform.CanMonitorPower():
       return
 
@@ -91,27 +95,48 @@ class PowerMetric(Metric):
     if not self._results:
       return
 
-    energy_consumption_mwh = self._results.get('energy_consumption_mwh')
-    if energy_consumption_mwh is not None:
-      results.Add('energy_consumption_mwh', 'mWh', energy_consumption_mwh)
+    application_energy_consumption_mwh = (
+        self._results.get('application_energy_consumption_mwh'))
+    total_energy_consumption_mwh = self._results.get('energy_consumption_mwh')
+
+    if not application_energy_consumption_mwh and total_energy_consumption_mwh:
+      application_energy_consumption_mwh = max(
+          total_energy_consumption_mwh - PowerMetric._quiescent_power_draw_mwh,
+          0)
+
+    if total_energy_consumption_mwh is not None:
+      results.AddValue(scalar.ScalarValue(
+          results.current_page, 'energy_consumption_mwh', 'mWh',
+          total_energy_consumption_mwh))
+
+    if application_energy_consumption_mwh is not None:
+      results.AddValue(scalar.ScalarValue(
+          results.current_page, 'application_energy_consumption_mwh', 'mWh',
+          application_energy_consumption_mwh))
 
     component_utilization = self._results.get('component_utilization', {})
     # GPU Frequency.
     gpu_power = component_utilization.get('gpu', {})
     gpu_freq_hz = gpu_power.get('average_frequency_hz')
     if gpu_freq_hz is not None:
-      results.Add('gpu_average_frequency_hz', 'hz', gpu_freq_hz)
+      results.AddValue(scalar.ScalarValue(
+          results.current_page, 'gpu_average_frequency_hz', 'hz', gpu_freq_hz,
+          important=False))
 
     # Add idle wakeup numbers for all processes.
     for (process_type, stats) in self._results.get('cpu_stats', {}).items():
       trace_name_for_process = 'idle_wakeups_%s' % (process_type.lower())
-      results.Add(trace_name_for_process, 'count', stats)
+      results.AddValue(scalar.ScalarValue(
+          results.current_page, trace_name_for_process, 'count', stats,
+          important=False))
 
     # Add temperature measurements.
     whole_package_utilization = component_utilization.get('whole_package', {})
     board_temperature_c = whole_package_utilization.get('average_temperature_c')
     if board_temperature_c is not None:
-      results.Add('board_temperature', 'celsius', board_temperature_c)
+      results.AddValue(scalar.ScalarValue(
+          results.current_page, 'board_temperature', 'celsius',
+          board_temperature_c, important=False))
 
     self._results = None