• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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