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 #include "config_policy_utils.h"
28
29 namespace OHOS {
30 namespace HDI {
31 namespace Thermal {
32 namespace V1_1 {
33 namespace {
34
35 const std::string HDI_XML_PATH = "etc/thermal_config/thermal_hdi_config.xml";
36 const std::string VENDOR_HDI_XML_PATH = "/vendor/etc/thermal_config/thermal_hdi_config.xml";
37 bool g_isHdiStart = false;
38 }
39 static sptr<IThermalCallback> theramalCb_ = nullptr;
40 static std::shared_ptr<HdfThermalCallbackInfo> callbackInfo_ = nullptr;
41 static std::shared_ptr<ThermalHdfTimer> hdfTimer_ = nullptr;
42 static std::shared_ptr<ThermalSimulationNode> simulation_ = nullptr;
43 static std::shared_ptr<ThermalDeviceMitigation> mitigation_ = nullptr;
44 static std::shared_ptr<ThermalZoneManager> thermalZoneMgr_ = nullptr;
45
ThermalInterfaceImplGetInstance(void)46 extern "C" IThermalInterface *ThermalInterfaceImplGetInstance(void)
47 {
48 return new (std::nothrow) ThermalInterfaceImpl();
49 }
50
ThermalInterfaceImpl()51 ThermalInterfaceImpl::ThermalInterfaceImpl()
52 {
53 Init();
54 }
55
Init()56 int32_t ThermalInterfaceImpl::Init()
57 {
58 char buf[MAX_PATH_LEN];
59 bool parseConfigSuc = false;
60 int32_t ret;
61 char* path = GetOneCfgFile(HDI_XML_PATH.c_str(), buf, MAX_PATH_LEN);
62 if (path != nullptr && *path != '\0') {
63 ret = ThermalHdfConfig::GetInstance().ThermalHDIConfigInit(path);
64 if (ret != HDF_SUCCESS) {
65 THERMAL_HILOGE(COMP_HDI, "parse err pliocy thermal hdi XML");
66 return HDF_FAILURE;
67 }
68 parseConfigSuc = true;
69 }
70
71 if (!parseConfigSuc) {
72 ret = ThermalHdfConfig::GetInstance().ThermalHDIConfigInit(VENDOR_HDI_XML_PATH);
73 if (ret != HDF_SUCCESS) {
74 THERMAL_HILOGE(COMP_HDI, "failed to init XML, ret: %{public}d", ret);
75 return HDF_FAILURE;
76 }
77 }
78
79 if (simulation_ == nullptr) {
80 simulation_ = std::make_shared<ThermalSimulationNode>();
81 }
82
83 if (thermalZoneMgr_ == nullptr) {
84 thermalZoneMgr_ = std::make_shared<ThermalZoneManager>();
85 }
86
87 if (mitigation_ == nullptr) {
88 mitigation_ = std::make_shared<ThermalDeviceMitigation>();
89 }
90
91 if (hdfTimer_ == nullptr) {
92 hdfTimer_ = std::make_shared<ThermalHdfTimer>(simulation_, thermalZoneMgr_);
93 hdfTimer_->SetSimluationFlag();
94 }
95
96 ret = simulation_->NodeInit();
97 if (ret != HDF_SUCCESS) {
98 return HDF_FAILURE;
99 }
100
101 thermalZoneMgr_->Init();
102 thermalZoneMgr_->CalculateMaxCd();
103 ret = thermalZoneMgr_->ParseThermalZoneInfo();
104 if (ret != HDF_SUCCESS) {
105 return ret;
106 }
107
108 thermalZoneMgr_->DumpPollingInfo();
109 mitigation_->SetFlag(static_cast<bool>(hdfTimer_->GetSimluationFlag()));
110 return HDF_SUCCESS;
111 }
112
SetCpuFreq(int32_t freq)113 int32_t ThermalInterfaceImpl::SetCpuFreq(int32_t freq)
114 {
115 if (freq <= 0) {
116 THERMAL_HILOGE(COMP_HDI, "invalid freq %{public}d", freq);
117 return HDF_FAILURE;
118 }
119 if (mitigation_ != nullptr) {
120 int32_t ret = mitigation_->CpuRequest(freq);
121 if (ret != HDF_SUCCESS) {
122 THERMAL_HILOGE(COMP_HDI, "failed to set freq %{public}d", ret);
123 return ret;
124 }
125 }
126 return HDF_SUCCESS;
127 }
128
SetGpuFreq(int32_t freq)129 int32_t ThermalInterfaceImpl::SetGpuFreq(int32_t freq)
130 {
131 if (freq <= 0) {
132 THERMAL_HILOGE(COMP_HDI, "invalid freq %{public}d", freq);
133 return HDF_FAILURE;
134 }
135 if (mitigation_ != nullptr) {
136 int32_t ret = mitigation_->GpuRequest(freq);
137 if (ret != HDF_SUCCESS) {
138 THERMAL_HILOGE(COMP_HDI, "failed to set freq %{public}d", ret);
139 return ret;
140 }
141 }
142 return HDF_SUCCESS;
143 }
144
SetBatteryCurrent(int32_t current)145 int32_t ThermalInterfaceImpl::SetBatteryCurrent(int32_t current)
146 {
147 if (current <= 0) {
148 THERMAL_HILOGE(COMP_HDI, "invalid current %{public}d", current);
149 return HDF_FAILURE;
150 }
151 if (mitigation_ != nullptr) {
152 int32_t ret = mitigation_->ChargerRequest(current);
153 if (ret != HDF_SUCCESS) {
154 THERMAL_HILOGE(COMP_HDI, "failed to set current %{public}d", ret);
155 return ret;
156 }
157 }
158 return HDF_SUCCESS;
159 }
160
GetThermalZoneInfo(HdfThermalCallbackInfo & event)161 int32_t ThermalInterfaceImpl::GetThermalZoneInfo(HdfThermalCallbackInfo& event)
162 {
163 if (thermalZoneMgr_ != nullptr) {
164 thermalZoneMgr_->ParseThermalZoneInfo();
165 event.info = thermalZoneMgr_->GetCallbackInfo().info;
166 }
167 return HDF_SUCCESS;
168 }
169
IsolateCpu(int32_t num)170 int32_t ThermalInterfaceImpl::IsolateCpu(int32_t num)
171 {
172 if (num <= 0) {
173 THERMAL_HILOGE(COMP_HDI, "invalid num %{public}d", num);
174 return HDF_FAILURE;
175 }
176 if (mitigation_ != nullptr) {
177 int32_t ret = mitigation_->IsolateCpu(num);
178 if (ret != HDF_SUCCESS) {
179 THERMAL_HILOGE(COMP_HDI, "failed to set isolate cpu num %{public}d", ret);
180 return ret;
181 }
182 }
183 return HDF_SUCCESS;
184 }
185
Register(const sptr<IThermalCallback> & callbackObj)186 int32_t ThermalInterfaceImpl::Register(const sptr<IThermalCallback>& callbackObj)
187 {
188 if (thermalZoneMgr_ == nullptr || callbackObj == nullptr) {
189 return HDF_FAILURE;
190 }
191
192 thermalZoneMgr_->SetThermalEventCb(callbackObj);
193 StartTimerThread();
194
195 return g_isHdiStart ? HDF_SUCCESS : HDF_FAILURE;
196 }
197
Unregister()198 int32_t ThermalInterfaceImpl::Unregister()
199 {
200 if (thermalZoneMgr_ == nullptr || thermalZoneMgr_->GetThermalEventCb() == nullptr) {
201 return HDF_FAILURE;
202 }
203
204 thermalZoneMgr_->DelThermalEventCb();
205 return HDF_SUCCESS;
206 }
207
RegisterFanCallback(const sptr<IFanCallback> & callbackObj)208 int32_t ThermalInterfaceImpl::RegisterFanCallback(const sptr<IFanCallback>& callbackObj)
209 {
210 if (thermalZoneMgr_ == nullptr || callbackObj == nullptr) {
211 return HDF_FAILURE;
212 }
213
214 thermalZoneMgr_->SetFanEventCb(callbackObj);
215 StartTimerThread();
216
217 return g_isHdiStart ? HDF_SUCCESS : HDF_FAILURE;
218 }
219
UnregisterFanCallback()220 int32_t ThermalInterfaceImpl::UnregisterFanCallback()
221 {
222 if (thermalZoneMgr_ == nullptr || thermalZoneMgr_->GetFanEventCb() == nullptr) {
223 return HDF_FAILURE;
224 }
225
226 thermalZoneMgr_->DelFanEventCb();
227 return HDF_SUCCESS;
228 }
229
StartTimerThread()230 void ThermalInterfaceImpl::StartTimerThread()
231 {
232 if (hdfTimer_ == nullptr) {
233 return;
234 }
235
236 std::lock_guard<std::mutex> lock(mutex_);
237 if (!g_isHdiStart) {
238 int32_t ret = hdfTimer_->Init();
239 if (ret != HDF_SUCCESS) {
240 return;
241 }
242 g_isHdiStart = true;
243 }
244
245 return;
246 }
247
248 } // V1_1
249 } // Thermal
250 } // HDI
251 } // OHOS
252