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 (mitigation_ != nullptr) {
116 int32_t ret = mitigation_->CpuRequest(freq);
117 if (ret != HDF_SUCCESS) {
118 THERMAL_HILOGE(COMP_HDI, "failed to set freq %{public}d", ret);
119 return ret;
120 }
121 }
122 return HDF_SUCCESS;
123 }
124
SetGpuFreq(int32_t freq)125 int32_t ThermalInterfaceImpl::SetGpuFreq(int32_t freq)
126 {
127 if (mitigation_ != nullptr) {
128 int32_t ret = mitigation_->GpuRequest(freq);
129 if (ret != HDF_SUCCESS) {
130 THERMAL_HILOGE(COMP_HDI, "failed to set freq %{public}d", ret);
131 return ret;
132 }
133 }
134 return HDF_SUCCESS;
135 }
136
SetBatteryCurrent(int32_t current)137 int32_t ThermalInterfaceImpl::SetBatteryCurrent(int32_t current)
138 {
139 if (mitigation_ != nullptr) {
140 int32_t ret = mitigation_->ChargerRequest(current);
141 if (ret != HDF_SUCCESS) {
142 THERMAL_HILOGE(COMP_HDI, "failed to set current %{public}d", ret);
143 return ret;
144 }
145 }
146 return HDF_SUCCESS;
147 }
148
GetThermalZoneInfo(HdfThermalCallbackInfo & event)149 int32_t ThermalInterfaceImpl::GetThermalZoneInfo(HdfThermalCallbackInfo& event)
150 {
151 if (thermalZoneMgr_ != nullptr) {
152 thermalZoneMgr_->ParseThermalZoneInfo();
153 event.info = thermalZoneMgr_->GetCallbackInfo().info;
154 }
155 return HDF_SUCCESS;
156 }
157
IsolateCpu(int32_t num)158 int32_t ThermalInterfaceImpl::IsolateCpu(int32_t num)
159 {
160 if (mitigation_ != nullptr) {
161 int32_t ret = mitigation_->IsolateCpu(num);
162 if (ret != HDF_SUCCESS) {
163 THERMAL_HILOGE(COMP_HDI, "failed to set isolate cpu num %{public}d", ret);
164 return ret;
165 }
166 }
167 return HDF_SUCCESS;
168 }
169
Register(const sptr<IThermalCallback> & callbackObj)170 int32_t ThermalInterfaceImpl::Register(const sptr<IThermalCallback>& callbackObj)
171 {
172 if (thermalZoneMgr_ == nullptr) {
173 return HDF_FAILURE;
174 }
175
176 thermalZoneMgr_->SetThermalEventCb(callbackObj);
177 StartTimerThread();
178
179 return g_isHdiStart ? HDF_SUCCESS : HDF_FAILURE;
180 }
181
Unregister()182 int32_t ThermalInterfaceImpl::Unregister()
183 {
184 if (thermalZoneMgr_ == nullptr) {
185 return HDF_FAILURE;
186 }
187
188 thermalZoneMgr_->DelThermalEventCb();
189 return HDF_SUCCESS;
190 }
191
RegisterFanCallback(const sptr<IFanCallback> & callbackObj)192 int32_t ThermalInterfaceImpl::RegisterFanCallback(const sptr<IFanCallback>& callbackObj)
193 {
194 if (thermalZoneMgr_ == nullptr) {
195 return HDF_FAILURE;
196 }
197
198 thermalZoneMgr_->SetFanEventCb(callbackObj);
199 StartTimerThread();
200
201 return g_isHdiStart ? HDF_SUCCESS : HDF_FAILURE;
202 }
203
UnregisterFanCallback()204 int32_t ThermalInterfaceImpl::UnregisterFanCallback()
205 {
206 if (thermalZoneMgr_ == nullptr) {
207 return HDF_FAILURE;
208 }
209
210 thermalZoneMgr_->DelFanEventCb();
211 return HDF_SUCCESS;
212 }
213
StartTimerThread()214 void ThermalInterfaceImpl::StartTimerThread()
215 {
216 if (hdfTimer_ == nullptr) {
217 return;
218 }
219
220 std::lock_guard<std::mutex> lock(mutex_);
221 if (!g_isHdiStart) {
222 int32_t ret = hdfTimer_->Init();
223 if (ret != HDF_SUCCESS) {
224 return;
225 }
226 g_isHdiStart = true;
227 }
228
229 return;
230 }
231
232 } // V1_1
233 } // Thermal
234 } // HDI
235 } // OHOS
236