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