1#!/usr/bin/env python3.4
2#
3# Copyright (C) 2017 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18# A helper class to generate MIXED property values that can be
19# set as the value for a diagnostic frame
20# Spritually, the same as DiagnosticEventBuilder.java
21
22from diagnostic_sensors import DIAGNOSTIC_SENSOR_INTEGER_LAST_SYSTEM_INDEX
23from diagnostic_sensors import DIAGNOSTIC_SENSOR_FLOAT_LAST_SYSTEM_INDEX
24
25class DiagnosticEventBuilder(object):
26    class ByteArray(object):
27        def __init__(self, numElements):
28            self.count = numElements
29            if 0 == (numElements % 8):
30                self.data = bytearray(numElements/8)
31            else:
32                # if not a multiple of 8, add one extra byte
33                self.data = bytearray(1+numElements/8)
34
35        def _getIndices(self, bit):
36            if (bit < 0) or (bit >= self.count):
37                raise IndexError("index %d not in range [0,%d)" % (bit, self.count))
38            byteIdx = bit / 8
39            bitIdx = (bit % 8)
40            return byteIdx, bitIdx
41
42        def setBit(self, bit):
43            byteIdx, bitIdx = self._getIndices(bit)
44            bitValue = pow(2,bitIdx)
45            self.data[byteIdx] = self.data[byteIdx] | bitValue
46
47        def getBit(self, bit):
48            byteIdx, bitIdx = self._getIndices(bit)
49            bitValue = pow(2,bitIdx)
50            return 0 != self.data[byteIdx] & bitValue
51
52        def __str__(self):
53            return str(self.data)
54
55    def __init__(self, propConfig):
56        self.string_value = ""
57        self.bytes = ""
58        self.numIntSensors = propConfig.config[0].config_array[0] + \
59            DIAGNOSTIC_SENSOR_INTEGER_LAST_SYSTEM_INDEX + 1
60        self.numFloatSensors = propConfig.config[0].config_array[1] + \
61            DIAGNOSTIC_SENSOR_FLOAT_LAST_SYSTEM_INDEX + 1
62        self.bitmask = DiagnosticEventBuilder.ByteArray(
63            self.numIntSensors+self.numFloatSensors)
64        self.int32_values = [0] * self.numIntSensors
65        self.float_values = [0.0] * self.numFloatSensors
66
67    def addIntSensor(self, idx, value):
68        self.int32_values[idx] = value
69        self.bitmask.setBit(idx)
70        return self
71
72    def addFloatSensor(self, idx, value):
73        self.float_values[idx] = value
74        self.bitmask.setBit(len(self.int32_values)+idx)
75        return self
76
77    def setStringValue(self, string):
78        self.string_value = string
79        return self
80
81    def build(self):
82        self.bytes_value = str(self.bitmask)
83        return self
84
85    def __str__(self):
86        s = "diagnostic event {\n"
87        for x in ['string_value', 'int32_values', 'float_values']:
88            s = s + "\t%s: %s\n" % (x, self.__dict__[x])
89        return s  + "}"
90