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