1 /*
2 * Copyright (c) 2021-2023 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 "action_shutdown.h"
17
18 #include <map>
19
20 #include "constants.h"
21 #include "power_mgr_client.h"
22 #include "file_operation.h"
23 #include "thermal_hisysevent.h"
24 #include "thermal_service.h"
25 #include "ffrt_utils.h"
26 #include "securec.h"
27
28 using namespace OHOS::PowerMgr;
29 using namespace OHOS::AppExecFwk;
30 namespace OHOS {
31 namespace PowerMgr {
32 namespace {
33 constexpr const char* SHUTDOWN_REASON = "DeviceTempTooHigh";
34 constexpr const char* SHUTDOWN_PATH = "/data/service/el0/thermal/config/shut_down";
35 FFRTQueue g_queue("thermal_action_shutdown");
36 FFRTHandle g_shutdownTaskHandle;
37 const int MAX_PATH = 256;
38 }
39
ActionShutdown(const std::string & actionName)40 ActionShutdown::ActionShutdown(const std::string& actionName)
41 {
42 actionName_ = actionName;
43 }
44
InitParams(const std::string & params)45 void ActionShutdown::InitParams(const std::string& params)
46 {
47 (void)params;
48 }
49
SetStrict(bool enable)50 void ActionShutdown::SetStrict(bool enable)
51 {
52 isStrict_ = enable;
53 }
54
SetEnableEvent(bool enable)55 void ActionShutdown::SetEnableEvent(bool enable)
56 {
57 enableEvent_ = enable;
58 }
59
AddActionValue(uint32_t actionId,std::string value)60 void ActionShutdown::AddActionValue(uint32_t actionId, std::string value)
61 {
62 if (value.empty()) {
63 return;
64 }
65 if (actionId > 0) {
66 auto iter = policyActionMap_.find(actionId);
67 if (iter != policyActionMap_.end()) {
68 iter->second.uintDelayValue = static_cast<uint32_t>(static_cast<uint32_t>(strtol(value.c_str(),
69 nullptr, STRTOL_FORMART_DEC)));
70 }
71 } else {
72 valueList_.push_back(static_cast<uint32_t>(strtol(value.c_str(), nullptr, STRTOL_FORMART_DEC)));
73 }
74 }
75
ExecuteInner()76 void ActionShutdown::ExecuteInner()
77 {
78 auto tms = ThermalService::GetInstance();
79 THERMAL_RETURN_IF (tms == nullptr);
80 for (auto &policyAction : policyActionMap_) {
81 if (policyAction.second.isCompleted) {
82 valueList_.push_back(policyAction.second.uintDelayValue);
83 }
84 }
85
86 uint32_t value = GetActionValue();
87 if (value != lastValue_) {
88 if (tms->GetSimulationXml()) {
89 ShutdownExecution(static_cast<bool>(value));
90 } else {
91 ShutdownRequest(static_cast<bool>(value));
92 }
93 WriteActionTriggeredHiSysEvent(enableEvent_, actionName_, value);
94 tms->GetObserver()->SetDecisionValue(actionName_, std::to_string(value));
95 lastValue_ = value;
96 THERMAL_HILOGD(COMP_SVC, "action execute: {%{public}s = %{public}u}", actionName_.c_str(), lastValue_);
97 }
98 valueList_.clear();
99 }
100
ResetActionValue()101 void ActionShutdown::ResetActionValue()
102 {
103 lastValue_ = 0;
104 }
105
GetActionValue()106 uint32_t ActionShutdown::GetActionValue()
107 {
108 uint32_t value = FALLBACK_VALUE_UINT_ZERO;
109 if (!valueList_.empty()) {
110 if (isStrict_) {
111 value = *min_element(valueList_.begin(), valueList_.end());
112 } else {
113 value = *max_element(valueList_.begin(), valueList_.end());
114 }
115 }
116 return value;
117 }
118
ShutdownRequest(bool isShutdown)119 uint32_t ActionShutdown::ShutdownRequest(bool isShutdown)
120 {
121 if (isShutdown) {
122 THERMAL_HILOGI(COMP_SVC, "device start shutdown");
123 PowerMgrClient::GetInstance().ShutDownDevice(SHUTDOWN_REASON);
124 }
125 return ERR_OK;
126 }
127
ShutdownExecution(bool isShutdown)128 int32_t ActionShutdown::ShutdownExecution(bool isShutdown)
129 {
130 int32_t ret = -1;
131 char shutdownBuf[MAX_PATH] = {0};
132 ret = snprintf_s(shutdownBuf, MAX_PATH, sizeof(shutdownBuf) - 1, SHUTDOWN_PATH);
133 if (ret < EOK) {
134 return ret;
135 }
136 std::string valueString = std::to_string(isShutdown) + "\n";
137 ret = FileOperation::WriteFile(shutdownBuf, valueString, valueString.length());
138 if (ret != ERR_OK) {
139 return ret;
140 }
141 return ERR_OK;
142 }
143
DelayShutdown(bool isShutdown,int32_t temp,int32_t thresholdClr)144 uint32_t ActionShutdown::DelayShutdown(bool isShutdown, int32_t temp, int32_t thresholdClr)
145 {
146 if (g_shutdownTaskHandle && temp < thresholdClr) {
147 THERMAL_HILOGI(COMP_SVC, "shutdown canceled");
148 FFRTUtils::CancelTask(g_shutdownTaskHandle, g_queue);
149 return ERR_OK;
150 }
151
152 uint32_t delay = 50000;
153 FFRTTask shutdownTask = [&]() {
154 THERMAL_HILOGI(COMP_SVC, "shutdown start");
155 ShutdownRequest(isShutdown);
156 };
157 g_shutdownTaskHandle = FFRTUtils::SubmitDelayTask(shutdownTask, delay, g_queue);
158 THERMAL_HILOGI(COMP_SVC, "shutdown device after %{public}u ms", delay);
159 return ERR_OK;
160 }
161 } // namespace PowerMgr
162 } // namespace OHOS
163