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/hardware/thermal/IThermal.h>
20 
21 #include <array>
22 #include <chrono>
23 #include <map>
24 #include <mutex>
25 #include <shared_mutex>
26 #include <string>
27 #include <string_view>
28 #include <thread>
29 #include <unordered_map>
30 #include <vector>
31 
32 #include "utils/power_files.h"
33 #include "utils/powerhal_helper.h"
34 #include "utils/thermal_files.h"
35 #include "utils/thermal_info.h"
36 #include "utils/thermal_predictions_helper.h"
37 #include "utils/thermal_stats_helper.h"
38 #include "utils/thermal_throttling.h"
39 #include "utils/thermal_watcher.h"
40 
41 namespace aidl {
42 namespace android {
43 namespace hardware {
44 namespace thermal {
45 namespace implementation {
46 
47 using ::android::sp;
48 
49 using NotificationCallback = std::function<void(const Temperature &t)>;
50 
51 // Get thermal_zone type
52 bool getThermalZoneTypeById(int tz_id, std::string *);
53 
54 struct ThermalSample {
55     float temp;
56     boot_clock::time_point timestamp;
57 };
58 
59 struct EmulTemp {
60     float temp;
61     int severity;
62 };
63 
64 struct OverrideStatus {
65     std::unique_ptr<EmulTemp> emul_temp;
66     bool max_throttling;
67     bool pending_update;
68 };
69 
70 struct SensorStatus {
71     ThrottlingSeverity severity;
72     ThrottlingSeverity prev_hot_severity;
73     ThrottlingSeverity prev_cold_severity;
74     boot_clock::time_point last_update_time;
75     ThermalSample thermal_cached;
76     bool pending_notification;
77     OverrideStatus override_status;
78 };
79 
80 class ThermalHelper {
81   public:
82     virtual ~ThermalHelper() = default;
83     virtual bool fillCurrentTemperatures(bool filterType, bool filterCallback, TemperatureType type,
84                                          std::vector<Temperature> *temperatures) = 0;
85     virtual bool fillTemperatureThresholds(bool filterType, TemperatureType type,
86                                            std::vector<TemperatureThreshold> *thresholds) const = 0;
87     virtual bool fillCurrentCoolingDevices(bool filterType, CoolingType type,
88                                            std::vector<CoolingDevice> *coolingdevices) const = 0;
89     virtual bool emulTemp(std::string_view target_sensor, const float temp,
90                           const bool max_throttling) = 0;
91     virtual bool emulSeverity(std::string_view target_sensor, const int severity,
92                               const bool max_throttling) = 0;
93     virtual bool emulClear(std::string_view target_sensor) = 0;
94     virtual bool isInitializedOk() const = 0;
95     virtual SensorReadStatus readTemperature(std::string_view sensor_name, Temperature *out,
96                                              const bool force_sysfs = false) = 0;
97     virtual bool readTemperatureThreshold(std::string_view sensor_name,
98                                           TemperatureThreshold *out) const = 0;
99     virtual bool readCoolingDevice(std::string_view cooling_device, CoolingDevice *out) const = 0;
100     virtual void dumpVtEstimatorStatus(std::string_view senor_name,
101                                        std::ostringstream *dump_buf) const = 0;
102     virtual const std::unordered_map<std::string, SensorInfo> &GetSensorInfoMap() const = 0;
103     virtual const std::unordered_map<std::string, CdevInfo> &GetCdevInfoMap() const = 0;
104     virtual const std::unordered_map<std::string, SensorStatus> &GetSensorStatusMap() const = 0;
105     virtual const std::unordered_map<std::string, ThermalThrottlingStatus> &
106     GetThermalThrottlingStatusMap() const = 0;
107     virtual const std::unordered_map<std::string, PowerRailInfo> &GetPowerRailInfoMap() const = 0;
108     virtual const std::unordered_map<std::string, PowerStatus> &GetPowerStatusMap() const = 0;
109     virtual const std::unordered_map<std::string, SensorTempStats> GetSensorTempStatsSnapshot() = 0;
110     virtual const std::unordered_map<std::string,
111                                      std::unordered_map<std::string, ThermalStats<int>>>
112     GetSensorCoolingDeviceRequestStatsSnapshot() = 0;
113     virtual bool isAidlPowerHalExist() = 0;
114     virtual bool isPowerHalConnected() = 0;
115     virtual bool isPowerHalExtConnected() = 0;
116     virtual void dumpTraces(std::string_view target_sensor) = 0;
117 };
118 
119 class ThermalHelperImpl : public ThermalHelper {
120   public:
121     explicit ThermalHelperImpl(const NotificationCallback &cb);
122     ~ThermalHelperImpl() override = default;
123 
124     bool fillCurrentTemperatures(bool filterType, bool filterCallback, TemperatureType type,
125                                  std::vector<Temperature> *temperatures) override;
126     bool fillTemperatureThresholds(bool filterType, TemperatureType type,
127                                    std::vector<TemperatureThreshold> *thresholds) const override;
128     bool fillCurrentCoolingDevices(bool filterType, CoolingType type,
129                                    std::vector<CoolingDevice> *coolingdevices) const override;
130     bool emulTemp(std::string_view target_sensor, const float temp,
131                   const bool max_throttling) override;
132     bool emulSeverity(std::string_view target_sensor, const int severity,
133                       const bool max_throttling) override;
134     bool emulClear(std::string_view target_sensor) override;
135     void dumpTraces(std::string_view target_sensor) override;
136 
137     // Disallow copy and assign.
138     ThermalHelperImpl(const ThermalHelperImpl &) = delete;
139     void operator=(const ThermalHelperImpl &) = delete;
140 
isInitializedOk()141     bool isInitializedOk() const override { return is_initialized_; }
142 
143     // Read the temperature of a single sensor.
144     SensorReadStatus readTemperature(std::string_view sensor_name, Temperature *out,
145                                      const bool force_sysfs = false) override;
146 
147     bool readTemperatureThreshold(std::string_view sensor_name,
148                                   TemperatureThreshold *out) const override;
149     // Read the value of a single cooling device.
150     bool readCoolingDevice(std::string_view cooling_device, CoolingDevice *out) const override;
151     // Dump VtEstimator status
152     void dumpVtEstimatorStatus(std::string_view sensor_name,
153                                std::ostringstream *dump_buf) const override;
154     // Get SensorInfo Map
GetSensorInfoMap()155     const std::unordered_map<std::string, SensorInfo> &GetSensorInfoMap() const override {
156         return sensor_info_map_;
157     }
158     // Get CdevInfo Map
GetCdevInfoMap()159     const std::unordered_map<std::string, CdevInfo> &GetCdevInfoMap() const override {
160         return cooling_device_info_map_;
161     }
162     // Get SensorStatus Map
GetSensorStatusMap()163     const std::unordered_map<std::string, SensorStatus> &GetSensorStatusMap() const override {
164         std::shared_lock<std::shared_mutex> _lock(sensor_status_map_mutex_);
165         return sensor_status_map_;
166     }
167     // Get ThermalThrottling Map
GetThermalThrottlingStatusMap()168     const std::unordered_map<std::string, ThermalThrottlingStatus> &GetThermalThrottlingStatusMap()
169             const override {
170         return thermal_throttling_.GetThermalThrottlingStatusMap();
171     }
172     // Get PowerRailInfo Map
GetPowerRailInfoMap()173     const std::unordered_map<std::string, PowerRailInfo> &GetPowerRailInfoMap() const override {
174         return power_files_.GetPowerRailInfoMap();
175     }
176 
177     // Get PowerStatus Map
GetPowerStatusMap()178     const std::unordered_map<std::string, PowerStatus> &GetPowerStatusMap() const override {
179         return power_files_.GetPowerStatusMap();
180     }
181 
182     // Get Thermal Stats Sensor Map
GetSensorTempStatsSnapshot()183     const std::unordered_map<std::string, SensorTempStats> GetSensorTempStatsSnapshot() override {
184         return thermal_stats_helper_.GetSensorTempStatsSnapshot();
185     }
186     // Get Thermal Stats Sensor, Binded Cdev State Request Map
187     const std::unordered_map<std::string, std::unordered_map<std::string, ThermalStats<int>>>
GetSensorCoolingDeviceRequestStatsSnapshot()188     GetSensorCoolingDeviceRequestStatsSnapshot() override {
189         return thermal_stats_helper_.GetSensorCoolingDeviceRequestStatsSnapshot();
190     }
191 
isAidlPowerHalExist()192     bool isAidlPowerHalExist() override { return power_hal_service_.isAidlPowerHalExist(); }
isPowerHalConnected()193     bool isPowerHalConnected() override { return power_hal_service_.isPowerHalConnected(); }
isPowerHalExtConnected()194     bool isPowerHalExtConnected() override { return power_hal_service_.isPowerHalExtConnected(); }
195 
196   private:
197     bool initializeSensorMap(const std::unordered_map<std::string, std::string> &path_map);
198     bool initializeCoolingDevices(const std::unordered_map<std::string, std::string> &path_map);
199     bool isSubSensorValid(std::string_view sensor_data, const SensorFusionType sensor_fusion_type);
200     void setMinTimeout(SensorInfo *sensor_info);
201     void initializeTrip(const std::unordered_map<std::string, std::string> &path_map,
202                         std::set<std::string> *monitored_sensors, bool thermal_genl_enabled);
203     void clearAllThrottling();
204     // For thermal_watcher_'s polling thread, return the sleep interval
205     std::chrono::milliseconds thermalWatcherCallbackFunc(
206             const std::unordered_map<std::string, float> &uevent_sensor_map);
207     // Return hot and cold severity status as std::pair
208     std::pair<ThrottlingSeverity, ThrottlingSeverity> getSeverityFromThresholds(
209             const ThrottlingArray &hot_thresholds, const ThrottlingArray &cold_thresholds,
210             const ThrottlingArray &hot_hysteresis, const ThrottlingArray &cold_hysteresis,
211             ThrottlingSeverity prev_hot_severity, ThrottlingSeverity prev_cold_severity,
212             float value) const;
213     // Read sensor data according to the type
214     bool readDataByType(std::string_view sensor_data, float *reading_value,
215                         const SensorFusionType type, const bool force_no_cache,
216                         std::map<std::string, float> *sensor_log_map);
217     SensorReadStatus readThermalSensor(std::string_view sensor_name, float *temp,
218                                        const bool force_sysfs,
219                                        std::map<std::string, float> *sensor_log_map);
220     bool runVirtualTempEstimator(std::string_view sensor_name,
221                                  std::map<std::string, float> *sensor_log_map,
222                                  const bool force_no_cache, std::vector<float> *outputs);
223     size_t getPredictionMaxWindowMs(std::string_view sensor_name);
224     float readPredictionAfterTimeMs(std::string_view sensor_name, const size_t time_ms);
225     bool readTemperaturePredictions(std::string_view sensor_name, std::vector<float> *predictions);
226     void updateCoolingDevices(const std::vector<std::string> &cooling_devices_to_update);
227     // Check the max CDEV state for cdev_ceiling
228     void maxCoolingRequestCheck(
229             std::unordered_map<std::string, BindedCdevInfo> *binded_cdev_info_map);
230     void checkUpdateSensorForEmul(std::string_view target_sensor, const bool max_throttling);
231     ThrottlingSeverity getSeverityReference(std::string_view sensor_name);
232 
233     sp<ThermalWatcher> thermal_watcher_;
234     PowerFiles power_files_;
235     ThermalFiles thermal_sensors_;
236     ThermalFiles cooling_devices_;
237     ThermalThrottling thermal_throttling_;
238     bool is_initialized_;
239     const NotificationCallback cb_;
240     std::unordered_map<std::string, CdevInfo> cooling_device_info_map_;
241     std::unordered_map<std::string, SensorInfo> sensor_info_map_;
242     std::unordered_map<std::string, std::unordered_map<ThrottlingSeverity, ThrottlingSeverity>>
243             supported_powerhint_map_;
244     PowerHalService power_hal_service_;
245     ThermalStatsHelper thermal_stats_helper_;
246     ThermalPredictionsHelper thermal_predictions_helper_;
247     mutable std::shared_mutex sensor_status_map_mutex_;
248     std::unordered_map<std::string, SensorStatus> sensor_status_map_;
249 };
250 
251 }  // namespace implementation
252 }  // namespace thermal
253 }  // namespace hardware
254 }  // namespace android
255 }  // namespace aidl
256