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_application_process.h"
17
18 #include <csignal>
19 #include <map>
20 #include <sys/types.h>
21
22 #include "constants.h"
23 #include "file_operation.h"
24 #include "sa_mgr_client.h"
25 #include "system_ability_definition.h"
26 #include "if_system_ability_manager.h"
27 #include "iremote_object.h"
28 #include "singleton.h"
29 #include "securec.h"
30
31 #include "thermal_hisysevent.h"
32 #include "thermal_service.h"
33
34 using namespace OHOS::AppExecFwk;
35
36 namespace OHOS {
37 namespace PowerMgr {
38 namespace {
39 const int32_t SIGNAL_KILL = 9;
40 auto g_service = DelayedSpSingleton<ThermalService>::GetInstance();
41 constexpr const char* PROCESS_PATH = "/data/service/el0/thermal/config/process_ctrl";
42 const int MAX_PATH = 256;
43 }
44
ActionApplicationProcess(const std::string & actionName)45 ActionApplicationProcess::ActionApplicationProcess(const std::string& actionName)
46 {
47 actionName_ = actionName;
48 }
49
InitParams(const std::string & params)50 void ActionApplicationProcess::InitParams(const std::string& params)
51 {
52 if (appMgrClient_ == nullptr) {
53 appMgrClient_ = std::make_unique<AppMgrClient>();
54 }
55 }
56
SetStrict(bool enable)57 void ActionApplicationProcess::SetStrict(bool enable)
58 {
59 isStrict_ = enable;
60 }
61
SetEnableEvent(bool enable)62 void ActionApplicationProcess::SetEnableEvent(bool enable)
63 {
64 enableEvent_ = enable;
65 }
66
AddActionValue(std::string value)67 void ActionApplicationProcess::AddActionValue(std::string value)
68 {
69 if (value.empty()) {
70 return;
71 }
72 valueList_.push_back(static_cast<uint32_t>(strtol(value.c_str(), nullptr, STRTOL_FORMART_DEC)));
73 }
74
Execute()75 void ActionApplicationProcess::Execute()
76 {
77 THERMAL_RETURN_IF (g_service == nullptr);
78 uint32_t value = GetActionValue();
79 if (value != lastValue_) {
80 if (!g_service->GetSimulationXml()) {
81 ProcessAppActionRequest(value);
82 } else {
83 ProcessAppActionExecution(value);
84 }
85 WriteActionTriggeredHiSysEvent(enableEvent_, actionName_, value);
86 g_service->GetObserver()->SetDecisionValue(actionName_, std::to_string(value));
87 lastValue_ = value;
88 }
89 valueList_.clear();
90 }
91
GetActionValue()92 uint32_t ActionApplicationProcess::GetActionValue()
93 {
94 std::string scene = g_service->GetScene();
95 auto iter = g_sceneMap.find(scene);
96 if (iter != g_sceneMap.end()) {
97 return static_cast<uint32_t>(strtol(iter->second.c_str(), nullptr, STRTOL_FORMART_DEC));
98 }
99 uint32_t value = FALLBACK_VALUE_UINT_ZERO;
100 if (!valueList_.empty()) {
101 if (isStrict_) {
102 value = *min_element(valueList_.begin(), valueList_.end());
103 } else {
104 value = *max_element(valueList_.begin(), valueList_.end());
105 }
106 }
107 return value;
108 }
109
KillApplicationAction(const std::string & bundleName)110 ErrCode ActionApplicationProcess::KillApplicationAction(const std::string& bundleName)
111 {
112 int result = ERR_OK;
113 result = appMgrClient_->KillApplication(bundleName);
114 if (result == ERR_OK) {
115 THERMAL_HILOGE(COMP_SVC, "kill application:%{public}s successfully.", bundleName.c_str());
116 } else {
117 THERMAL_HILOGE(COMP_SVC, "failed to kill application:%{public}s.", bundleName.c_str());
118 }
119 return result;
120 }
121
GetRunningProcessInfo(std::vector<RunningProcessInfo> & info)122 ErrCode ActionApplicationProcess::GetRunningProcessInfo(std::vector<RunningProcessInfo>& info)
123 {
124 ErrCode result = ERR_OK;
125 result = appMgrClient_->GetAllRunningProcesses(info);
126 if (result == ERR_OK) {
127 THERMAL_HILOGI(COMP_SVC, "get running process info successfully.");
128 } else {
129 THERMAL_HILOGE(COMP_SVC, "failed to get running process info.");
130 }
131 return result;
132 }
133
KillProcess(const pid_t pid)134 ErrCode ActionApplicationProcess::KillProcess(const pid_t pid)
135 {
136 int32_t ret = -1;
137 if (pid > 0) {
138 ret = kill(pid, SIGNAL_KILL);
139 if (ret == ERR_OK) {
140 THERMAL_HILOGI(COMP_SVC, "KillProcess: success kill, pid=%{public}d", pid);
141 } else {
142 THERMAL_HILOGE(COMP_SVC, "KillProcess: failed to kill, pid=%{public}d", pid);
143 }
144 }
145 return ret;
146 }
147
GetAppProcessInfoByName(const std::string & processName)148 RunningProcessInfo ActionApplicationProcess::GetAppProcessInfoByName(const std::string& processName)
149 {
150 RunningProcessInfo appProcessInfo;
151 appProcessInfo.pid_ = 0;
152 if (ERR_OK == GetRunningProcessInfo(allAppProcessInfos_)) {
153 const auto& it = std::find_if(allAppProcessInfos_.begin(), allAppProcessInfos_.end(), [&](const auto& info) {
154 return processName == info.processName_;
155 });
156 appProcessInfo = (it != allAppProcessInfos_.end()) ? *it : appProcessInfo;
157 }
158 return appProcessInfo;
159 }
160
161
GetAllRunnningAppProcess()162 void ActionApplicationProcess::GetAllRunnningAppProcess()
163 {
164 if (ERR_OK == GetRunningProcessInfo(allAppProcessInfos_)) {
165 for (const auto& info : allAppProcessInfos_) {
166 if (info.state_ == AppProcessState::APP_STATE_BACKGROUND) {
167 bgAppProcessInfos_.push_back(info);
168 } else if (info.state_ == AppProcessState::APP_STATE_FOREGROUND) {
169 fgAppProcessInfos_.push_back(info);
170 }
171 }
172 }
173 }
174
KillBgAppProcess()175 void ActionApplicationProcess::KillBgAppProcess()
176 {
177 for (auto bg : bgAppProcessInfos_) {
178 if (KillProcess(bg.pid_) != ERR_OK) {
179 THERMAL_HILOGE(COMP_SVC, "failed to kill bg process");
180 }
181 }
182 }
183
KillFgAppProcess()184 void ActionApplicationProcess::KillFgAppProcess()
185 {
186 for (auto fg : fgAppProcessInfos_) {
187 if (KillProcess(fg.pid_) != ERR_OK) {
188 THERMAL_HILOGE(COMP_SVC, "failed to kill fg process");
189 }
190 }
191 }
192
KillAllAppProcess()193 void ActionApplicationProcess::KillAllAppProcess()
194 {
195 for (auto all : allAppProcessInfos_) {
196 if (KillProcess(all.pid_) != ERR_OK) {
197 THERMAL_HILOGE(COMP_SVC, "failed to kill all process");
198 }
199 }
200 }
201
ProcessAppActionRequest(const uint32_t & value)202 void ActionApplicationProcess::ProcessAppActionRequest(const uint32_t& value)
203 {
204 THERMAL_HILOGD(COMP_SVC, "value: %{public}d", value);
205 GetAllRunnningAppProcess();
206 switch (value) {
207 case KILL_FG_PROCESS_APP: {
208 KillFgAppProcess();
209 break;
210 }
211 case KILL_BG_PROCESS_APP: {
212 KillBgAppProcess();
213 break;
214 }
215 case KILL_ALL_PROCESS_APP: {
216 KillAllAppProcess();
217 break;
218 }
219 default: {
220 break;
221 }
222 }
223 }
224
ProcessAppActionExecution(const uint32_t & value)225 void ActionApplicationProcess::ProcessAppActionExecution(const uint32_t& value)
226 {
227 int32_t ret = -1;
228 char processBuf[MAX_PATH] = {0};
229 ret = snprintf_s(processBuf, MAX_PATH, sizeof(processBuf) - 1, PROCESS_PATH);
230 if (ret < EOK) {
231 return;
232 }
233 std::string valueString = std::to_string(value) + "\n";
234 ret = FileOperation::WriteFile(processBuf, valueString, valueString.length());
235 if (ret != EOK) {
236 return;
237 }
238 }
239 } // namespace PowerMgr
240 } // namespace OHOS
241