1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "thermal_interface_impl.h"
17
18 #include <thread>
19 #include <memory>
20 #include <hdf_base.h>
21 #include "thermal_hdf_config.h"
22 #include "thermal_hdf_timer.h"
23 #include "thermal_simulation_node.h"
24 #include "thermal_device_mitigation.h"
25 #include "thermal_zone_manager.h"
26 #include "thermal_log.h"
27 #ifdef HAS_THERMAL_CONFIG_POLICY_PART
28 #include "config_policy_utils.h"
29 #endif
30
31 namespace OHOS {
32 namespace HDI {
33 namespace Thermal {
34 namespace V1_1 {
35 namespace {
36
37 const std::string HDI_XML_PATH = "etc/thermal_config/thermal_hdi_config.xml";
38 const std::string VENDOR_HDI_XML_PATH = "/vendor/etc/thermal_config/thermal_hdi_config.xml";
39 bool g_isHdiStart = false;
40 }
41 static sptr<IThermalCallback> theramalCb_ = nullptr;
42 static std::shared_ptr<HdfThermalCallbackInfo> callbackInfo_ = nullptr;
43 static std::shared_ptr<ThermalHdfTimer> hdfTimer_ = nullptr;
44 static std::shared_ptr<ThermalSimulationNode> simulation_ = nullptr;
45 static std::shared_ptr<ThermalDeviceMitigation> mitigation_ = nullptr;
46 static std::shared_ptr<ThermalZoneManager> thermalZoneMgr_ = nullptr;
47
ThermalInterfaceImplGetInstance(void)48 extern "C" IThermalInterface *ThermalInterfaceImplGetInstance(void)
49 {
50 return new (std::nothrow) ThermalInterfaceImpl();
51 }
52
ThermalInterfaceImpl()53 ThermalInterfaceImpl::ThermalInterfaceImpl()
54 {
55 Init();
56 }
57
Init()58 int32_t ThermalInterfaceImpl::Init()
59 {
60 bool parseConfigSuc = false;
61 int32_t ret;
62 #ifdef HAS_THERMAL_CONFIG_POLICY_PART
63 char buf[MAX_PATH_LEN];
64 char* path = GetOneCfgFile(HDI_XML_PATH.c_str(), buf, MAX_PATH_LEN);
65 if (path != nullptr && *path != '\0') {
66 ret = ThermalHdfConfig::GetInstance().ThermalHDIConfigInit(path);
67 if (ret != HDF_SUCCESS) {
68 THERMAL_HILOGE(COMP_HDI, "parse err pliocy thermal hdi XML");
69 return HDF_FAILURE;
70 }
71 parseConfigSuc = true;
72 }
73 #endif
74
75 if (!parseConfigSuc) {
76 ret = ThermalHdfConfig::GetInstance().ThermalHDIConfigInit(VENDOR_HDI_XML_PATH);
77 if (ret != HDF_SUCCESS) {
78 THERMAL_HILOGE(COMP_HDI, "failed to init XML, ret: %{public}d", ret);
79 return HDF_FAILURE;
80 }
81 }
82
83 if (simulation_ == nullptr) {
84 simulation_ = std::make_shared<ThermalSimulationNode>();
85 }
86
87 if (thermalZoneMgr_ == nullptr) {
88 thermalZoneMgr_ = std::make_shared<ThermalZoneManager>();
89 }
90
91 if (mitigation_ == nullptr) {
92 mitigation_ = std::make_shared<ThermalDeviceMitigation>();
93 }
94
95 if (hdfTimer_ == nullptr) {
96 hdfTimer_ = std::make_shared<ThermalHdfTimer>(simulation_, thermalZoneMgr_);
97 hdfTimer_->SetSimluationFlag();
98 }
99
100 ret = simulation_->NodeInit();
101 if (ret != HDF_SUCCESS) {
102 return HDF_FAILURE;
103 }
104
105 thermalZoneMgr_->Init();
106 thermalZoneMgr_->CalculateMaxCd();
107 ret = thermalZoneMgr_->UpdateThermalZoneData();
108 if (ret != HDF_SUCCESS) {
109 return ret;
110 }
111
112 thermalZoneMgr_->DumpPollingInfo();
113 mitigation_->SetFlag(static_cast<bool>(hdfTimer_->GetSimluationFlag()));
114 return HDF_SUCCESS;
115 }
116
SetCpuFreq(int32_t freq)117 int32_t ThermalInterfaceImpl::SetCpuFreq(int32_t freq)
118 {
119 if (freq <= 0) {
120 THERMAL_HILOGE(COMP_HDI, "invalid freq %{public}d", freq);
121 return HDF_FAILURE;
122 }
123 if (mitigation_ != nullptr) {
124 int32_t ret = mitigation_->CpuRequest(freq);
125 if (ret != HDF_SUCCESS) {
126 THERMAL_HILOGE(COMP_HDI, "failed to set freq %{public}d", ret);
127 return ret;
128 }
129 }
130 return HDF_SUCCESS;
131 }
132
SetGpuFreq(int32_t freq)133 int32_t ThermalInterfaceImpl::SetGpuFreq(int32_t freq)
134 {
135 if (freq <= 0) {
136 THERMAL_HILOGE(COMP_HDI, "invalid freq %{public}d", freq);
137 return HDF_FAILURE;
138 }
139 if (mitigation_ != nullptr) {
140 int32_t ret = mitigation_->GpuRequest(freq);
141 if (ret != HDF_SUCCESS) {
142 THERMAL_HILOGE(COMP_HDI, "failed to set freq %{public}d", ret);
143 return ret;
144 }
145 }
146 return HDF_SUCCESS;
147 }
148
SetBatteryCurrent(int32_t current)149 int32_t ThermalInterfaceImpl::SetBatteryCurrent(int32_t current)
150 {
151 if (current <= 0) {
152 THERMAL_HILOGE(COMP_HDI, "invalid current %{public}d", current);
153 return HDF_FAILURE;
154 }
155 if (mitigation_ != nullptr) {
156 int32_t ret = mitigation_->ChargerRequest(current);
157 if (ret != HDF_SUCCESS) {
158 THERMAL_HILOGE(COMP_HDI, "failed to set current %{public}d", ret);
159 return ret;
160 }
161 }
162 return HDF_SUCCESS;
163 }
164
GetThermalZoneInfo(HdfThermalCallbackInfo & event)165 int32_t ThermalInterfaceImpl::GetThermalZoneInfo(HdfThermalCallbackInfo& event)
166 {
167 if (thermalZoneMgr_ != nullptr) {
168 thermalZoneMgr_->UpdateThermalZoneData();
169 event.info = thermalZoneMgr_->GetCallbackInfo().info;
170 }
171 return HDF_SUCCESS;
172 }
173
IsolateCpu(int32_t num)174 int32_t ThermalInterfaceImpl::IsolateCpu(int32_t num)
175 {
176 if (num <= 0) {
177 THERMAL_HILOGE(COMP_HDI, "invalid num %{public}d", num);
178 return HDF_FAILURE;
179 }
180 if (mitigation_ != nullptr) {
181 int32_t ret = mitigation_->IsolateCpu(num);
182 if (ret != HDF_SUCCESS) {
183 THERMAL_HILOGE(COMP_HDI, "failed to set isolate cpu num %{public}d", ret);
184 return ret;
185 }
186 }
187 return HDF_SUCCESS;
188 }
189
Register(const sptr<IThermalCallback> & callbackObj)190 int32_t ThermalInterfaceImpl::Register(const sptr<IThermalCallback>& callbackObj)
191 {
192 if (thermalZoneMgr_ == nullptr || callbackObj == nullptr) {
193 return HDF_FAILURE;
194 }
195
196 thermalZoneMgr_->SetThermalEventCb(callbackObj);
197 StartTimerThread();
198
199 return g_isHdiStart ? HDF_SUCCESS : HDF_FAILURE;
200 }
201
Unregister()202 int32_t ThermalInterfaceImpl::Unregister()
203 {
204 if (thermalZoneMgr_ == nullptr || thermalZoneMgr_->GetThermalEventCb() == nullptr) {
205 return HDF_FAILURE;
206 }
207
208 thermalZoneMgr_->DelThermalEventCb();
209 return HDF_SUCCESS;
210 }
211
RegisterFanCallback(const sptr<IFanCallback> & callbackObj)212 int32_t ThermalInterfaceImpl::RegisterFanCallback(const sptr<IFanCallback>& callbackObj)
213 {
214 if (thermalZoneMgr_ == nullptr || callbackObj == nullptr) {
215 return HDF_FAILURE;
216 }
217
218 thermalZoneMgr_->SetFanEventCb(callbackObj);
219 StartTimerThread();
220
221 return g_isHdiStart ? HDF_SUCCESS : HDF_FAILURE;
222 }
223
UnregisterFanCallback()224 int32_t ThermalInterfaceImpl::UnregisterFanCallback()
225 {
226 if (thermalZoneMgr_ == nullptr || thermalZoneMgr_->GetFanEventCb() == nullptr) {
227 return HDF_FAILURE;
228 }
229
230 thermalZoneMgr_->DelFanEventCb();
231 return HDF_SUCCESS;
232 }
233
StartTimerThread()234 void ThermalInterfaceImpl::StartTimerThread()
235 {
236 if (hdfTimer_ == nullptr) {
237 return;
238 }
239
240 std::lock_guard<std::mutex> lock(mutex_);
241 if (!g_isHdiStart) {
242 int32_t ret = hdfTimer_->Init();
243 if (ret != HDF_SUCCESS) {
244 return;
245 }
246 g_isHdiStart = true;
247 }
248
249 return;
250 }
251
252 } // V1_1
253 } // Thermal
254 } // HDI
255 } // OHOS
256