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 "supervisor.h"
17 #include "ability_info.h"
18 #include "if_system_ability_manager.h"
19 #include "iservice_registry.h"
20 #include "system_ability_definition.h"
21 #include "cgroup_sched_log.h"
22
23 namespace OHOS {
24 namespace ResourceSchedule {
25 using OHOS::AppExecFwk::AbilityType;
26
SetName(const std::string & name)27 void ProcessRecord::SetName(const std::string& name)
28 {
29 if (processName_.empty()) {
30 processName_ = name;
31 }
32 }
33
GetAbilityInfoNonNull(int32_t recordId)34 std::shared_ptr<AbilityInfo> ProcessRecord::GetAbilityInfoNonNull(int32_t recordId)
35 {
36 auto a = std::find_if(abilities_.begin(), abilities_.end(), [ recordId ] (const auto& a) {
37 return a->recordId_ == recordId;
38 });
39 if (a != abilities_.end()) {
40 return *a;
41 }
42 std::shared_ptr<AbilityInfo> abi = std::make_shared<AbilityInfo>(recordId);
43 abilities_.push_back(abi);
44 return abi;
45 }
46
GetAbilityInfo(int32_t recordId)47 std::shared_ptr<AbilityInfo> ProcessRecord::GetAbilityInfo(int32_t recordId)
48 {
49 auto a = std::find_if(abilities_.begin(), abilities_.end(), [ recordId ] (const auto& a) {
50 return a->recordId_ == recordId;
51 });
52 if (a != abilities_.end()) {
53 return *a;
54 }
55 return nullptr;
56 }
57
GetWindowInfoNonNull(uint32_t windowId)58 std::shared_ptr<WindowInfo> ProcessRecord::GetWindowInfoNonNull(uint32_t windowId)
59 {
60 auto w = std::find_if(windows_.begin(), windows_.end(), [ windowId ] (const auto& w) {
61 return w->windowId_ == windowId;
62 });
63 if (w != windows_.end()) {
64 return *w;
65 }
66 std::shared_ptr<WindowInfo> win = std::make_shared<WindowInfo>(windowId);
67 windows_.push_back(win);
68 return win;
69 }
70
RemoveAbilityByRecordId(int32_t recordId)71 void ProcessRecord::RemoveAbilityByRecordId(int32_t recordId)
72 {
73 for (auto iter = abilities_.begin(); iter != abilities_.end(); ++iter) {
74 if ((*iter)->recordId_ == recordId) {
75 abilities_.erase(iter);
76 break;
77 }
78 }
79 }
80
HasAbility(int32_t recordId) const81 bool ProcessRecord::HasAbility(int32_t recordId) const
82 {
83 return std::any_of(abilities_.begin(), abilities_.end(), [ recordId ] (const auto& abi) {
84 return abi->recordId_ == recordId;
85 });
86 }
87
HasServiceExtension() const88 bool ProcessRecord::HasServiceExtension() const
89 {
90 return std::any_of(abilities_.begin(), abilities_.end(), [] (const auto& abi) {
91 return abi->type_ == (int32_t)(AbilityType::SERVICE)
92 || abi->type_ == (int32_t)(AbilityType::EXTENSION)
93 || abi->type_ == (int32_t)(AbilityType::DATA);
94 });
95 }
96
IsVisible() const97 bool ProcessRecord::IsVisible() const
98 {
99 return std::any_of(windows_.begin(), windows_.end(), [] (const auto& w) {
100 return w->isVisible_;
101 });
102 }
103
GetKeyTidSetByRole(int64_t role)104 std::set<int32_t> ProcessRecord::GetKeyTidSetByRole(int64_t role)
105 {
106 std::set<int32_t> tids {};
107 for (const auto [tid, tidRole] : keyThreadRoleMap_) {
108 if (tidRole != role) {
109 continue;
110 }
111 tids.insert(tid);
112 }
113 return tids;
114 }
115
AddProcessRecord(std::shared_ptr<ProcessRecord> pr)116 std::shared_ptr<ProcessRecord> Application::AddProcessRecord(std::shared_ptr<ProcessRecord> pr)
117 {
118 if (pr) {
119 pidsMap_[pr->GetPid()] = pr;
120 }
121 return pr;
122 }
123
RemoveProcessRecord(pid_t pid)124 void Application::RemoveProcessRecord(pid_t pid)
125 {
126 auto iter = pidsMap_.find(pid);
127 if (iter != pidsMap_.end()) {
128 if (focusedProcess_ == iter->second) {
129 focusedProcess_ = nullptr;
130 }
131 if (IsHostProcess(pid)) {
132 hostPidsSet_.erase(pid);
133 }
134 pidsMap_.erase(iter);
135 }
136 }
137
GetProcessRecord(pid_t pid)138 std::shared_ptr<ProcessRecord> Application::GetProcessRecord(pid_t pid)
139 {
140 auto iter = pidsMap_.find(pid);
141 if (iter != pidsMap_.end()) {
142 return iter->second;
143 }
144 return nullptr;
145 }
146
GetProcessRecordNonNull(pid_t pid)147 std::shared_ptr<ProcessRecord> Application::GetProcessRecordNonNull(pid_t pid)
148 {
149 auto iter = pidsMap_.find(pid);
150 if (iter != pidsMap_.end()) {
151 return iter->second;
152 }
153 auto pr = std::make_shared<ProcessRecord>(this->GetUid(), pid);
154 pidsMap_[pid] = pr;
155 return pr;
156 }
157
FindProcessRecordByRecordId(int32_t recordId)158 std::shared_ptr<ProcessRecord> Application::FindProcessRecordByRecordId(int32_t recordId)
159 {
160 for (auto iter = pidsMap_.begin(); iter != pidsMap_.end(); iter++) {
161 auto pr = iter->second;
162 if (pr->HasAbility(recordId)) {
163 return pr;
164 }
165 }
166 return nullptr;
167 }
168
SetName(const std::string & name)169 void Application::SetName(const std::string& name)
170 {
171 if (name_.empty()) {
172 name_ = name;
173 }
174 }
175
FindProcessRecordByWindowId(uint32_t windowId)176 std::shared_ptr<ProcessRecord> Application::FindProcessRecordByWindowId(uint32_t windowId)
177 {
178 for (auto iter = pidsMap_.begin(); iter != pidsMap_.end(); iter++) {
179 auto pr = iter->second;
180 if (std::any_of(pr->windows_.begin(), pr->windows_.end(),
181 [ windowId ] (const auto& w) {
182 return w->windowId_ == windowId;
183 })) {
184 return pr;
185 }
186 }
187 return nullptr;
188 }
189
AddHostProcess(int32_t hostPid)190 void Application::AddHostProcess(int32_t hostPid)
191 {
192 hostPidsSet_.insert(hostPid);
193 }
194
IsHostProcess(int32_t hostPid) const195 bool Application::IsHostProcess(int32_t hostPid) const
196 {
197 if (hostPidsSet_.find(hostPid) != hostPidsSet_.end()) {
198 return true;
199 } else {
200 return false;
201 }
202 }
203
GetAppRecord(int32_t uid)204 std::shared_ptr<Application> Supervisor::GetAppRecord(int32_t uid)
205 {
206 auto iter = uidsMap_.find(uid);
207 if (iter != uidsMap_.end()) {
208 return iter->second;
209 }
210 return nullptr;
211 }
212
GetAppRecordNonNull(int32_t uid)213 std::shared_ptr<Application> Supervisor::GetAppRecordNonNull(int32_t uid)
214 {
215 auto iter = uidsMap_.find(uid);
216 if (iter != uidsMap_.end()) {
217 return iter->second;
218 }
219 auto app = std::make_shared<Application>(uid);
220 uidsMap_[uid] = app;
221 return app;
222 }
223
FindProcessRecord(pid_t pid)224 std::shared_ptr<ProcessRecord> Supervisor::FindProcessRecord(pid_t pid)
225 {
226 std::shared_ptr<ProcessRecord> pr = nullptr;
227 for (auto iter = uidsMap_.begin(); iter != uidsMap_.end(); iter++) {
228 auto app = iter->second;
229 pr = app->GetProcessRecord(pid);
230 if (pr) {
231 break;
232 }
233 }
234 return pr;
235 }
236
RemoveApplication(int32_t uid)237 void Supervisor::RemoveApplication(int32_t uid)
238 {
239 auto iter = uidsMap_.find(uid);
240 if (iter != uidsMap_.end()) {
241 uidsMap_.erase(iter);
242 }
243 }
244
SearchAbilityRecordId(std::shared_ptr<Application> & application,std::shared_ptr<ProcessRecord> & procRecord,int32_t recordId)245 void Supervisor::SearchAbilityRecordId(std::shared_ptr<Application> &application,
246 std::shared_ptr<ProcessRecord> &procRecord, int32_t recordId)
247 {
248 std::shared_ptr<ProcessRecord> pr = nullptr;
249 for (auto iter = uidsMap_.begin(); iter != uidsMap_.end(); iter++) {
250 auto app = iter->second;
251 pr = app->FindProcessRecordByRecordId(recordId);
252 if (pr) {
253 application = app;
254 procRecord = pr;
255 break;
256 }
257 }
258 }
259
SearchWindowId(std::shared_ptr<Application> & application,std::shared_ptr<ProcessRecord> & procRecord,uint32_t windowId)260 void Supervisor::SearchWindowId(std::shared_ptr<Application> &application,
261 std::shared_ptr<ProcessRecord> &procRecord, uint32_t windowId)
262 {
263 std::shared_ptr<ProcessRecord> pr = nullptr;
264 for (auto iter = uidsMap_.begin(); iter != uidsMap_.end(); iter++) {
265 auto app = iter->second;
266 pr = app->FindProcessRecordByWindowId(windowId);
267 if (pr) {
268 application = app;
269 procRecord = pr;
270 break;
271 }
272 }
273 }
274
SetSystemLoadLevelState(int32_t level)275 void Supervisor::SetSystemLoadLevelState(int32_t level)
276 {
277 systemLoadLevel_ = level;
278 }
279
GetSystemLoadLevel()280 int32_t Supervisor::GetSystemLoadLevel()
281 {
282 return systemLoadLevel_;
283 }
284
ConnectAppManagerService()285 void Supervisor::ConnectAppManagerService()
286 {
287 sptr<OHOS::ISystemAbilityManager> systemAbilityManager =
288 OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
289 sptr<OHOS::IRemoteObject> object = systemAbilityManager->GetSystemAbility(OHOS::APP_MGR_SERVICE_ID);
290 appManager_ = OHOS::iface_cast<OHOS::AppExecFwk::IAppMgr>(object);
291 }
292
ReloadApplication()293 void Supervisor::ReloadApplication()
294 {
295 if (appManager_ == nullptr) {
296 return;
297 }
298 std::vector<AppExecFwk::RunningProcessInfo> runningProcess;
299 appManager_->GetAllRunningProcesses(runningProcess);
300 for (const auto& process : runningProcess) {
301 std::shared_ptr<Application> app = GetAppRecordNonNull(process.uid_);
302 if (process.bundleNames.size() != 0) {
303 app->SetName(process.bundleNames[0]);
304 }
305 app->GetProcessRecordNonNull(process.pid_);
306 CGS_LOGI("reload application cache uid:%{public}d pid:%{public}d bundleName:%{public}s isFocused:%{public}d",
307 process.uid_, process.pid_, app->GetName().c_str(), process.isFocused);
308 }
309 }
310
311 #ifdef SUPPORT_CHILD_PROCESS
ReloadChildProcess()312 void Supervisor::ReloadChildProcess()
313 {
314 if (appManager_ == nullptr) {
315 return;
316 }
317 std::vector<AppExecFwk::ChildProcessInfo> childProcess;
318 appManager_->GetAllChildrenProcesses(childProcess);
319 for (const auto& process : childProcess) {
320 std::shared_ptr<Application> app = GetAppRecordNonNull(process.hostUid);
321 app->AddHostProcess(process.hostPid);
322 auto procRecord = app->GetProcessRecordNonNull(process.pid);
323 procRecord->processType_ = ProcRecordType::CHILD;
324 procRecord->hostPid_ = process.hostPid;
325 procRecord->isReload_ = true;
326 CGS_LOGI("reload child process bundleName:%{public}s processName:%{public}s pid:%{public}d \
327 uid:%{public}d hostUid:%{public}d hostPid:%{public}d",
328 process.bundleName.c_str(), process.processName.c_str(), process.pid,
329 process.uid, process.hostUid, process.hostPid);
330 }
331 }
332 #endif // SUPPORT_CHILD_PROCESS
333
InitSuperVisorContent()334 void Supervisor::InitSuperVisorContent()
335 {
336 ConnectAppManagerService();
337 /* reload application info */
338 ReloadApplication();
339 #ifdef SUPPORT_CHILD_PROCESS
340 /* reload child process */
341 ReloadChildProcess();
342 #endif // SUPPORT_CHILD_PROCESS
343 }
344 } // namespace ResourceSchedule
345 } // namespace OHOS
346