Merge remote-tracking branch 'goog/stage-aosp-master' into HEAD am: 63fd9cc1fc am: 5ff310359f
am: cacad4c29a

Change-Id: Ibc8eff977b742730470a309036810a9f5dca702a
diff --git a/devlib/module/cpufreq.py b/devlib/module/cpufreq.py
index e18d95b..5e8c585 100644
--- a/devlib/module/cpufreq.py
+++ b/devlib/module/cpufreq.py
@@ -12,6 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+import json
 from devlib.module import Module
 from devlib.exception import TargetError
 from devlib.utils.misc import memoized
@@ -434,3 +435,55 @@
             domain = self.target.cpufreq.get_domain_cpus(cpu)
             yield domain
             cpus = cpus.difference(domain)
+
+    def get_time_in_state(self, clusters):
+        """
+        Gets the time at each frequency on each cluster
+        :param clusters: A list of clusters on the device. Each cluster is a
+                    list of cpus on that cluster.
+        """
+        time_in_state_by_cluster = {}
+
+        for i, cluster in enumerate(clusters):
+            frequencies = self.list_frequencies(cluster[0])
+            time_in_state = dict((str(freq), 0) for freq in frequencies)
+
+            for cpu in cluster:
+                stats = self.target.execute('cat '\
+                        '/sys/devices/system/cpu/cpu{}/cpufreq/stats'
+                        '/time_in_state'.format(cpu))
+                for entry in stats.split('\n'):
+                    if len(entry) > 0:
+                        freq, time = entry.split(' ')
+                        time_in_state[freq] += int(time)
+
+            time_in_state_by_cluster[str(i)] = time_in_state
+
+        return time_in_state_by_cluster
+
+    def dump_time_in_state_delta(self, start, clusters, dump_file):
+        """
+        Dumps the time between the stop and start by cluster by frequency
+        :param start: The inital output from a call to cpufreq.get_time_in_state
+        :param clusters: A list of clusters on the device. Each cluster is a
+                    list of cpus on that cluster.
+        :param dump_file: A file to dump the delta time_in_state_delta to.
+        """
+        stop = self.get_time_in_state(clusters)
+
+        time_in_state_delta = {}
+
+        for cl in start:
+            time_in_state_delta[cl] = {}
+
+            for freq in start[cl].keys():
+                time_in_start = start[cl][freq]
+                time_in_stop = stop[cl][freq]
+                time_in_state_delta[cl][freq] = time_in_stop - time_in_start
+
+        output = {'time_delta' : time_in_state_delta,
+                'clusters' : {str(i) : [str(c) for c in cl]
+                        for i, cl in enumerate(clusters)}}
+
+        with open(dump_file, 'w') as dfile:
+            json.dump(output, dfile, indent=4, sort_keys=True)
diff --git a/devlib/utils/android_build.py b/devlib/utils/android_build.py
new file mode 100644
index 0000000..de638ba
--- /dev/null
+++ b/devlib/utils/android_build.py
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: Apache-2.0
+#
+# Copyright (C) 2015, ARM Limited and contributors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import logging
+import os
+import shutil
+import subprocess
+from collections import namedtuple
+
+class Build(object):
+    """
+    Collection of Android related build actions
+    """
+    def __init__(self, te):
+        if (te.ANDROID_BUILD_TOP and te.TARGET_PRODUCT and te.TARGET_BUILD_VARIANT):
+            self._te = te
+        else:
+            te._log.warning('Build initialization failed: invalid paramterers')
+            raise
+
+    def exec_cmd(self, cmd):
+        ret = subprocess.call(cmd, shell=True)
+        if ret != 0:
+            raise RuntimeError('Command \'{}\' returned error code {}'.format(cmd, ret))
+
+    def build_module(self, module_path):
+        """
+        Build a module and its dependencies.
+
+        :param module_path: module path
+        :type module_path: str
+
+        """
+        cur_dir = os.getcwd()
+        os.chdir(self._te.ANDROID_BUILD_TOP)
+        lunch_target = self._te.TARGET_PRODUCT + '-' + self._te.TARGET_BUILD_VARIANT
+        self.exec_cmd('source build/envsetup.sh && lunch ' +
+            lunch_target + ' && mmma -j16 ' + module_path)
+        os.chdir(cur_dir)
+
+
+# vim :set tabstop=4 shiftwidth=4 expandtab