• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <aidl/android/frameworks/stats/IStats.h>
20 #include <aidl/android/hardware/thermal/Temperature.h>
21 #include <android-base/chrono_utils.h>
22 
23 #include <chrono>
24 #include <shared_mutex>
25 #include <string_view>
26 #include <unordered_map>
27 #include <vector>
28 
29 #include "thermal_info.h"
30 
31 namespace aidl {
32 namespace android {
33 namespace hardware {
34 namespace thermal {
35 namespace implementation {
36 
37 using aidl::android::frameworks::stats::IStats;
38 using aidl::android::frameworks::stats::VendorAtomValue;
39 using ::android::base::boot_clock;
40 using std::chrono::system_clock;
41 using SystemTimePoint = std::chrono::time_point<std::chrono::system_clock>;
42 
43 constexpr int kMaxStatsReportingFailCount = 3;
44 
45 struct StatsRecord {
46     int cur_state; /* temperature / cdev state at current time */
47     boot_clock::time_point cur_state_start_time;
48     boot_clock::time_point last_stats_report_time = boot_clock::time_point::min();
49     std::vector<std::chrono::milliseconds> time_in_state_ms; /* stats array */
50     int report_fail_count = 0; /* Number of times failed to report stats */
51     explicit StatsRecord(const size_t &time_in_state_size, int state = 0)
cur_stateStatsRecord52         : cur_state(state),
53           cur_state_start_time(boot_clock::now()),
54           last_stats_report_time(boot_clock::now()),
55           report_fail_count(0) {
56         time_in_state_ms = std::vector<std::chrono::milliseconds>(
57                 time_in_state_size, std::chrono::milliseconds::zero());
58     }
59     StatsRecord() = default;
60     StatsRecord(const StatsRecord &) = default;
61     StatsRecord &operator=(const StatsRecord &) = default;
62     StatsRecord(StatsRecord &&) = default;
63     StatsRecord &operator=(StatsRecord &&) = default;
64     ~StatsRecord() = default;
65 };
66 
67 template <typename ValueType>
68 struct StatsByThreshold {
69     std::vector<ValueType> thresholds;
70     std::optional<std::string> logging_name;
71     StatsRecord stats_record;
StatsByThresholdStatsByThreshold72     explicit StatsByThreshold(ThresholdList<ValueType> threshold_list)
73         : thresholds(threshold_list.thresholds), logging_name(threshold_list.logging_name) {
74         // number of states = number of thresholds + 1
75         // e.g. threshold: [30, 50, 60]
76         //      buckets: [MIN - 30, 30 - 50, 50-60, 60-MAX]
77         int time_in_state_size = threshold_list.thresholds.size() + 1;
78         stats_record = StatsRecord(time_in_state_size);
79     }
80     StatsByThreshold() = default;
81     StatsByThreshold(const StatsByThreshold &) = default;
82     StatsByThreshold &operator=(const StatsByThreshold &) = default;
83     StatsByThreshold(StatsByThreshold &&) = default;
84     StatsByThreshold &operator=(StatsByThreshold &&) = default;
85     ~StatsByThreshold() = default;
86 };
87 
88 template <typename ValueType>
89 struct ThermalStats {
90     std::vector<StatsByThreshold<ValueType>> stats_by_custom_threshold;
91     std::optional<StatsRecord> stats_by_default_threshold;
92 };
93 
94 struct SensorTempStats : ThermalStats<float> {
95     float max_temp = std::numeric_limits<float>::min();
96     SystemTimePoint max_temp_timestamp = SystemTimePoint::min();
97     float min_temp = std::numeric_limits<float>::max();
98     SystemTimePoint min_temp_timestamp = SystemTimePoint::min();
99 };
100 
101 class ThermalStatsHelper {
102   public:
103     ThermalStatsHelper() = default;
104     ~ThermalStatsHelper() = default;
105     // Disallow copy and assign
106     ThermalStatsHelper(const ThermalStatsHelper &) = delete;
107     void operator=(const ThermalStatsHelper &) = delete;
108 
109     bool initializeStats(const Json::Value &config,
110                          const std::unordered_map<std::string, SensorInfo> &sensor_info_map_,
111                          const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map_);
112     void updateSensorCdevRequestStats(std::string_view trigger_sensor, std::string_view cdev,
113                                       int new_state);
114     void updateSensorTempStatsBySeverity(std::string_view sensor,
115                                          const ThrottlingSeverity &severity);
116     void updateSensorTempStatsByThreshold(std::string_view sensor, float temperature);
117     /*
118      * Function to report all the stats by calling all specific stats reporting function.
119      * Returns:
120      *   0, if time_elapsed < kUpdateIntervalMs or if no failure in reporting
121      *  -1, if failed to get AIDL stats services
122      *  >0, count represents the number of stats failed to report.
123      */
124     int reportStats();
125     // Get a snapshot of Thermal Stats Sensor Map till that point in time
126     std::unordered_map<std::string, SensorTempStats> GetSensorTempStatsSnapshot();
127     // Get a snapshot of Thermal Stats Sensor Map till that point in time
128     std::unordered_map<std::string, std::unordered_map<std::string, ThermalStats<int>>>
129     GetSensorCoolingDeviceRequestStatsSnapshot();
130 
131   private:
132     static constexpr std::chrono::milliseconds kUpdateIntervalMs =
133             std::chrono::duration_cast<std::chrono::milliseconds>(24h);
134     boot_clock::time_point last_total_stats_report_time = boot_clock::time_point::min();
135 
136     mutable std::shared_mutex sensor_temp_stats_map_mutex_;
137     // Temperature stats for each sensor being watched
138     std::unordered_map<std::string, SensorTempStats> sensor_temp_stats_map_;
139     mutable std::shared_mutex sensor_cdev_request_stats_map_mutex_;
140     // userVote request stat for the sensor to the corresponding cdev (sensor -> cdev ->
141     // StatsRecord)
142     std::unordered_map<std::string, std::unordered_map<std::string, ThermalStats<int>>>
143             sensor_cdev_request_stats_map_;
144 
145     bool initializeSensorTempStats(
146             const StatsInfo<float> &sensor_stats_info,
147             const std::unordered_map<std::string, SensorInfo> &sensor_info_map_);
148     bool initializeSensorCdevRequestStats(
149             const StatsInfo<int> &request_stats_info,
150             const std::unordered_map<std::string, SensorInfo> &sensor_info_map_,
151             const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map_);
152     void updateStatsRecord(StatsRecord *stats_record, int new_state);
153     int reportAllSensorTempStats(const std::shared_ptr<IStats> &stats_client);
154     bool reportSensorTempStats(const std::shared_ptr<IStats> &stats_client, std::string_view sensor,
155                                const SensorTempStats &sensor_temp_stats, StatsRecord *stats_record);
156     int reportAllSensorCdevRequestStats(const std::shared_ptr<IStats> &stats_client);
157     bool reportSensorCdevRequestStats(const std::shared_ptr<IStats> &stats_client,
158                                       std::string_view sensor, std::string_view cdev,
159                                       StatsRecord *stats_record);
160     bool reportAtom(const std::shared_ptr<IStats> &stats_client, const int32_t &atom_id,
161                     std::vector<VendorAtomValue> &&values);
162     std::vector<int64_t> processStatsRecordForReporting(StatsRecord *stats_record);
163     StatsRecord restoreStatsRecordOnFailure(StatsRecord &&stats_record_before_failure);
164 };
165 
166 }  // namespace implementation
167 }  // namespace thermal
168 }  // namespace hardware
169 }  // namespace android
170 }  // namespace aidl
171