1 /*
2 * Copyright (c) 2021 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 "app_running_manager.h"
17
18 #include "datetime_ex.h"
19 #include "iremote_object.h"
20
21 #include "appexecfwk_errors.h"
22 #include "hilog_wrapper.h"
23 #include "os_account_manager.h"
24 #include "perf_profile.h"
25
26 namespace OHOS {
27 namespace AppExecFwk {
AppRunningManager()28 AppRunningManager::AppRunningManager()
29 {}
~AppRunningManager()30 AppRunningManager::~AppRunningManager()
31 {}
32
CreateAppRunningRecord(const std::shared_ptr<ApplicationInfo> & appInfo,const std::string & processName,const BundleInfo & bundleInfo)33 std::shared_ptr<AppRunningRecord> AppRunningManager::CreateAppRunningRecord(
34 const std::shared_ptr<ApplicationInfo> &appInfo, const std::string &processName, const BundleInfo &bundleInfo)
35 {
36 std::lock_guard<std::recursive_mutex> guard(lock_);
37 if (!appInfo) {
38 HILOG_ERROR("param error");
39 return nullptr;
40 }
41
42 if (processName.empty()) {
43 HILOG_ERROR("processName error");
44 return nullptr;
45 }
46
47 auto recordId = AppRecordId::Create();
48 auto appRecord = std::make_shared<AppRunningRecord>(appInfo, recordId, processName);
49 if (!appRecord) {
50 return nullptr;
51 }
52
53 std::regex rule("[a-zA-Z.]+[-_#]{1}");
54 std::string signCode;
55 ClipStringContent(rule, bundleInfo.appId, signCode);
56
57 HILOG_INFO("Create processName : %{public}s | recordId : %{public}d | signCode : %{public}s",
58 processName.c_str(), recordId, signCode.c_str());
59 appRecord->SetSignCode(signCode);
60 appRecord->SetJointUserId(bundleInfo.jointUserId);
61 appRunningRecordMap_.emplace(recordId, appRecord);
62 return appRecord;
63 }
64
CheckAppRunningRecordIsExist(const std::string & appName,const std::string & processName,const int uid,const BundleInfo & bundleInfo)65 std::shared_ptr<AppRunningRecord> AppRunningManager::CheckAppRunningRecordIsExist(const std::string &appName,
66 const std::string &processName, const int uid, const BundleInfo &bundleInfo)
67 {
68 HILOG_INFO("CheckAppRunningRecordIsExist appName : %{public}s | processName : %{public}s | uid : %{public}d",
69 appName.c_str(), processName.c_str(), uid);
70 std::lock_guard<std::recursive_mutex> guard(lock_);
71
72 std::regex rule("[a-zA-Z.]+[-_#]{1}");
73 std::string signCode;
74 auto jointUserId = bundleInfo.jointUserId;
75 HILOG_INFO("jointUserId : %{public}s", jointUserId.c_str());
76 ClipStringContent(rule, bundleInfo.appId, signCode);
77
78 auto FindSameProcess = [signCode, processName, jointUserId](const auto &pair) {
79 return ((pair.second->GetSignCode() == signCode) &&
80 (pair.second->GetProcessName() == processName) &&
81 (pair.second->GetJointUserId() == jointUserId) &&
82 !(pair.second->IsTerminating()) &&
83 !(pair.second->IsKilling()));
84 };
85
86 // If it is not empty, look for whether it can come in the same process
87 if (jointUserId.empty()) {
88 for (const auto &item : appRunningRecordMap_) {
89 const auto &appRecord = item.second;
90 if (appRecord && appRecord->GetProcessName() == processName &&
91 !(appRecord->IsTerminating()) && !(appRecord->IsKilling())) {
92 HILOG_INFO("appRecord->GetProcessName() : %{public}s", appRecord->GetProcessName().c_str());
93 auto appInfoList = appRecord->GetAppInfoList();
94 HILOG_INFO("appInfoList : %{public}zu", appInfoList.size());
95 auto isExist = [&appName, &uid](const std::shared_ptr<ApplicationInfo> &appInfo) {
96 HILOG_INFO("appInfo->name : %{public}s", appInfo->name.c_str());
97 return appInfo->name == appName && appInfo->uid == uid;
98 };
99 auto appInfoIter = std::find_if(appInfoList.begin(), appInfoList.end(), isExist);
100 if (appInfoIter != appInfoList.end()) {
101 return appRecord;
102 }
103 }
104 }
105 return nullptr;
106 }
107
108 auto iter = std::find_if(appRunningRecordMap_.begin(), appRunningRecordMap_.end(), FindSameProcess);
109 return ((iter == appRunningRecordMap_.end()) ? nullptr : iter->second);
110 }
111
GetAppRunningRecordByPid(const pid_t pid)112 std::shared_ptr<AppRunningRecord> AppRunningManager::GetAppRunningRecordByPid(const pid_t pid)
113 {
114 std::lock_guard<std::recursive_mutex> guard(lock_);
115 auto iter = std::find_if(appRunningRecordMap_.begin(), appRunningRecordMap_.end(), [&pid](const auto &pair) {
116 return pair.second->GetPriorityObject()->GetPid() == pid;
117 });
118 return ((iter == appRunningRecordMap_.end()) ? nullptr : iter->second);
119 }
120
GetAppRunningRecordByAbilityToken(const sptr<IRemoteObject> & abilityToken)121 std::shared_ptr<AppRunningRecord> AppRunningManager::GetAppRunningRecordByAbilityToken(
122 const sptr<IRemoteObject> &abilityToken)
123 {
124 std::lock_guard<std::recursive_mutex> guard(lock_);
125 for (const auto &item : appRunningRecordMap_) {
126 const auto &appRecord = item.second;
127 if (appRecord && appRecord->GetAbilityRunningRecordByToken(abilityToken)) {
128 HILOG_INFO("appRecord is exit");
129 return appRecord;
130 }
131 }
132 return nullptr;
133 }
134
ProcessExitByBundleName(const std::string & bundleName,std::list<pid_t> & pids)135 bool AppRunningManager::ProcessExitByBundleName(const std::string &bundleName, std::list<pid_t> &pids)
136 {
137 std::lock_guard<std::recursive_mutex> guard(lock_);
138 for (const auto &item : appRunningRecordMap_) {
139 const auto &appRecord = item.second;
140 // condition [!appRecord->IsKeepAliveApp()] Is to not kill the resident process.
141 // Before using this method, consider whether you need.
142 if (appRecord && !appRecord->IsKeepAliveApp()) {
143 pid_t pid = appRecord->GetPriorityObject()->GetPid();
144 auto appInfoList = appRecord->GetAppInfoList();
145 auto isExist = [&bundleName](const std::shared_ptr<ApplicationInfo> &appInfo) {
146 return appInfo->bundleName == bundleName;
147 };
148 auto iter = std::find_if(appInfoList.begin(), appInfoList.end(), isExist);
149 if (iter != appInfoList.end() && pid > 0) {
150 pids.push_back(pid);
151 appRecord->ScheduleProcessSecurityExit();
152 }
153 }
154 }
155
156 return !pids.empty();
157 }
158
GetPidsByUserId(int32_t userId,std::list<pid_t> & pids)159 bool AppRunningManager::GetPidsByUserId(int32_t userId, std::list<pid_t> &pids)
160 {
161 std::lock_guard<std::recursive_mutex> guard(lock_);
162 for (const auto &item : appRunningRecordMap_) {
163 const auto &appRecord = item.second;
164 if (appRecord) {
165 int32_t id = -1;
166 if ((AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(appRecord->GetUid(), id) == 0) &&
167 (id == userId)) {
168 pid_t pid = appRecord->GetPriorityObject()->GetPid();
169 if (pid > 0) {
170 pids.push_back(pid);
171 appRecord->ScheduleProcessSecurityExit();
172 }
173 }
174 }
175 }
176
177 return (pids.empty() ? false : true);
178 }
179
ProcessExitByBundleNameAndUid(const std::string & bundleName,const int uid,std::list<pid_t> & pids)180 bool AppRunningManager::ProcessExitByBundleNameAndUid(
181 const std::string &bundleName, const int uid, std::list<pid_t> &pids)
182 {
183 std::lock_guard<std::recursive_mutex> guard(lock_);
184 for (const auto &item : appRunningRecordMap_) {
185 const auto &appRecord = item.second;
186 if (appRecord) {
187 auto appInfoList = appRecord->GetAppInfoList();
188 auto isExist = [&bundleName, &uid](const std::shared_ptr<ApplicationInfo> &appInfo) {
189 return appInfo->bundleName == bundleName && appInfo->uid == uid;
190 };
191 auto iter = std::find_if(appInfoList.begin(), appInfoList.end(), isExist);
192 pid_t pid = appRecord->GetPriorityObject()->GetPid();
193 if (iter != appInfoList.end() && pid > 0) {
194 pids.push_back(pid);
195
196 appRecord->SetKilling();
197 appRecord->ScheduleProcessSecurityExit();
198 }
199 }
200 }
201
202 return (pids.empty() ? false : true);
203 }
204
OnRemoteDied(const wptr<IRemoteObject> & remote)205 std::shared_ptr<AppRunningRecord> AppRunningManager::OnRemoteDied(const wptr<IRemoteObject> &remote)
206 {
207 std::lock_guard<std::recursive_mutex> guard(lock_);
208 if (remote == nullptr) {
209 HILOG_ERROR("remote is null");
210 return nullptr;
211 }
212 sptr<IRemoteObject> object = remote.promote();
213 if (!object) {
214 HILOG_ERROR("object is null");
215 return nullptr;
216 }
217 const auto &iter =
218 std::find_if(appRunningRecordMap_.begin(), appRunningRecordMap_.end(), [&object](const auto &pair) {
219 if (pair.second && pair.second->GetApplicationClient() != nullptr) {
220 return pair.second->GetApplicationClient()->AsObject() == object;
221 }
222 return false;
223 });
224 if (iter == appRunningRecordMap_.end()) {
225 HILOG_ERROR("remote is not exist in the map.");
226 return nullptr;
227 }
228 auto appRecord = iter->second;
229 if (appRecord != nullptr) {
230 appRecord->SetApplicationClient(nullptr);
231 }
232 appRunningRecordMap_.erase(iter);
233 return appRecord;
234 }
235
GetAppRunningRecordMap()236 const std::map<const int32_t, const std::shared_ptr<AppRunningRecord>> &AppRunningManager::GetAppRunningRecordMap()
237 {
238 std::lock_guard<std::recursive_mutex> guard(lock_);
239 return appRunningRecordMap_;
240 }
241
RemoveAppRunningRecordById(const int32_t recordId)242 void AppRunningManager::RemoveAppRunningRecordById(const int32_t recordId)
243 {
244 std::lock_guard<std::recursive_mutex> guard(lock_);
245 appRunningRecordMap_.erase(recordId);
246 }
247
ClearAppRunningRecordMap()248 void AppRunningManager::ClearAppRunningRecordMap()
249 {
250 std::lock_guard<std::recursive_mutex> guard(lock_);
251 appRunningRecordMap_.clear();
252 }
253
HandleTerminateTimeOut(int64_t eventId)254 void AppRunningManager::HandleTerminateTimeOut(int64_t eventId)
255 {
256 HILOG_INFO("Handle terminate timeout.");
257 auto abilityRecord = GetAbilityRunningRecord(eventId);
258 if (!abilityRecord) {
259 HILOG_ERROR("abilityRecord is nullptr.");
260 return;
261 }
262 auto abilityToken = abilityRecord->GetToken();
263 auto appRecord = GetTerminatingAppRunningRecord(abilityToken);
264 if (!appRecord) {
265 HILOG_ERROR("appRecord is nullptr.");
266 return;
267 }
268 appRecord->AbilityTerminated(abilityToken);
269 }
270
GetTerminatingAppRunningRecord(const sptr<IRemoteObject> & abilityToken)271 std::shared_ptr<AppRunningRecord> AppRunningManager::GetTerminatingAppRunningRecord(
272 const sptr<IRemoteObject> &abilityToken)
273 {
274 std::lock_guard<std::recursive_mutex> guard(lock_);
275 for (const auto &item : appRunningRecordMap_) {
276 const auto &appRecord = item.second;
277 if (appRecord && appRecord->GetAbilityByTerminateLists(abilityToken)) {
278 return appRecord;
279 }
280 }
281 return nullptr;
282 }
283
GetAbilityRunningRecord(const int64_t eventId)284 std::shared_ptr<AbilityRunningRecord> AppRunningManager::GetAbilityRunningRecord(const int64_t eventId)
285 {
286 HILOG_INFO("Get ability running record by eventId.");
287 std::lock_guard<std::recursive_mutex> guard(lock_);
288 for (auto &item : appRunningRecordMap_) {
289 if (item.second) {
290 auto abilityRecord = item.second->GetAbilityRunningRecord(eventId);
291 if (abilityRecord) {
292 return abilityRecord;
293 }
294 }
295 }
296 return nullptr;
297 }
298
GetAppRunningRecord(const int64_t eventId)299 std::shared_ptr<AppRunningRecord> AppRunningManager::GetAppRunningRecord(const int64_t eventId)
300 {
301 HILOG_INFO("Get app running record by eventId.");
302 std::lock_guard<std::recursive_mutex> guard(lock_);
303 auto iter = std::find_if(appRunningRecordMap_.begin(), appRunningRecordMap_.end(), [&eventId](const auto &pair) {
304 return pair.second->GetEventId() == eventId;
305 });
306 return ((iter == appRunningRecordMap_.end()) ? nullptr : iter->second);
307 }
308
HandleAbilityAttachTimeOut(const sptr<IRemoteObject> & token)309 void AppRunningManager::HandleAbilityAttachTimeOut(const sptr<IRemoteObject> &token)
310 {
311 HILOG_INFO("Handle ability attach timeOut.");
312 if (token == nullptr) {
313 HILOG_ERROR("token is nullptr.");
314 return;
315 }
316
317 auto appRecord = GetAppRunningRecordByAbilityToken(token);
318 if (!appRecord) {
319 HILOG_ERROR("appRecord is nullptr.");
320 return;
321 }
322
323 std::shared_ptr<AbilityRunningRecord> abilityRecord = appRecord->GetAbilityRunningRecordByToken(token);
324 if (abilityRecord) {
325 abilityRecord->SetTerminating();
326 }
327
328 if (appRecord->IsLastAbilityRecord(token)) {
329 appRecord->SetTerminating();
330 }
331
332 appRecord->TerminateAbility(token, true);
333 }
334
PrepareTerminate(const sptr<IRemoteObject> & token)335 void AppRunningManager::PrepareTerminate(const sptr<IRemoteObject> &token)
336 {
337 HILOG_INFO("Prepare terminate.");
338 if (token == nullptr) {
339 HILOG_ERROR("token is nullptr.");
340 return;
341 }
342
343 auto appRecord = GetAppRunningRecordByAbilityToken(token);
344 if (!appRecord) {
345 HILOG_ERROR("appRecord is nullptr.");
346 return;
347 }
348
349 if (appRecord->IsLastAbilityRecord(token)) {
350 appRecord->SetTerminating();
351 }
352 }
353
TerminateAbility(const sptr<IRemoteObject> & token)354 void AppRunningManager::TerminateAbility(const sptr<IRemoteObject> &token)
355 {
356 HILOG_INFO("Terminate ability.");
357 if (!token) {
358 HILOG_ERROR("token is nullptr.");
359 return;
360 }
361
362 auto appRecord = GetAppRunningRecordByAbilityToken(token);
363 if (!appRecord) {
364 HILOG_ERROR("appRecord is nullptr.");
365 return;
366 }
367
368 if (appRecord->IsLastAbilityRecord(token) && !appRecord->IsKeepAliveApp()) {
369 appRecord->SetTerminating();
370 }
371
372 appRecord->TerminateAbility(token, false);
373 }
374
GetRunningProcessInfoByToken(const sptr<IRemoteObject> & token,AppExecFwk::RunningProcessInfo & info)375 void AppRunningManager::GetRunningProcessInfoByToken(
376 const sptr<IRemoteObject> &token, AppExecFwk::RunningProcessInfo &info)
377 {
378 std::lock_guard<std::recursive_mutex> guard(lock_);
379 auto appRecord = GetAppRunningRecordByAbilityToken(token);
380 if (!appRecord) {
381 HILOG_ERROR("appRecord is nullptr");
382 return;
383 }
384
385 info.processName_ = appRecord->GetProcessName();
386 info.pid_ = appRecord->GetPriorityObject()->GetPid();
387 info.uid_ = appRecord->GetUid();
388 info.bundleNames.emplace_back(appRecord->GetBundleName());
389 }
390
ClipStringContent(const std::regex & re,const std::string & sorce,std::string & afferCutStr)391 void AppRunningManager::ClipStringContent(const std::regex &re, const std::string &sorce, std::string &afferCutStr)
392 {
393 std::smatch basket;
394 if (std::regex_search(sorce, basket, re)) {
395 HILOG_INFO("prefix str: [%{public}s]", basket.prefix().str().c_str());
396 HILOG_INFO("suffix str: [%{public}s]", basket.suffix().str().c_str());
397 afferCutStr = basket.prefix().str() + basket.suffix().str();
398 }
399 }
400
GetForegroundApplications(std::vector<AppStateData> & list)401 void AppRunningManager::GetForegroundApplications(std::vector<AppStateData> &list)
402 {
403 HILOG_INFO("%{public}s, begin.", __func__);
404 std::lock_guard<std::recursive_mutex> guard(lock_);
405 for (const auto &item : appRunningRecordMap_) {
406 const auto &appRecord = item.second;
407 if (appRecord && appRecord->GetState() == ApplicationState::APP_STATE_FOREGROUND) {
408 AppStateData appData;
409 appData.bundleName = appRecord->GetBundleName();
410 appData.uid = appRecord->GetUid();
411 appData.state = static_cast<int32_t>(ApplicationState::APP_STATE_FOREGROUND);
412 list.push_back(appData);
413 HILOG_INFO("%{public}s, bundleName:%{public}s", __func__, appData.bundleName.c_str());
414 }
415 }
416 }
417
HandleAddAbilityStageTimeOut(const int64_t eventId)418 void AppRunningManager::HandleAddAbilityStageTimeOut(const int64_t eventId)
419 {
420 HILOG_DEBUG("Handle add ability stage timeout.");
421 auto abilityRecord = GetAbilityRunningRecord(eventId);
422 if (!abilityRecord) {
423 HILOG_ERROR("abilityRecord is nullptr");
424 return;
425 }
426
427 auto abilityToken = abilityRecord->GetToken();
428 auto appRecord = GetTerminatingAppRunningRecord(abilityToken);
429 if (!appRecord) {
430 HILOG_ERROR("appRecord is nullptr");
431 return;
432 }
433
434 appRecord->ScheduleProcessSecurityExit();
435 }
436
HandleStartSpecifiedAbilityTimeOut(const int64_t eventId)437 void AppRunningManager::HandleStartSpecifiedAbilityTimeOut(const int64_t eventId)
438 {
439 HILOG_DEBUG("Handle receive multi instances timeout.");
440 auto abilityRecord = GetAbilityRunningRecord(eventId);
441 if (!abilityRecord) {
442 HILOG_ERROR("abilityRecord is nullptr");
443 return;
444 }
445
446 auto abilityToken = abilityRecord->GetToken();
447 auto appRecord = GetTerminatingAppRunningRecord(abilityToken);
448 if (!appRecord) {
449 HILOG_ERROR("appRecord is nullptr");
450 return;
451 }
452
453 appRecord->ScheduleProcessSecurityExit();
454 }
455
UpdateConfiguration(const Configuration & config)456 void AppRunningManager::UpdateConfiguration(const Configuration &config)
457 {
458 HILOG_INFO("call %{public}s", __func__);
459 std::lock_guard<std::recursive_mutex> guard(lock_);
460 HILOG_INFO("current app size %{public}d", static_cast<int>(appRunningRecordMap_.size()));
461 for (const auto &item : appRunningRecordMap_) {
462 const auto &appRecord = item.second;
463 if (appRecord) {
464 HILOG_INFO("Notification app [%{public}s]", appRecord->GetName().c_str());
465 appRecord->UpdateConfiguration(config);
466 }
467 }
468 }
469
GetAppRunningRecordByRenderPid(const pid_t pid)470 std::shared_ptr<AppRunningRecord> AppRunningManager::GetAppRunningRecordByRenderPid(const pid_t pid)
471 {
472 std::lock_guard<std::recursive_mutex> guard(lock_);
473 auto iter = std::find_if(appRunningRecordMap_.begin(), appRunningRecordMap_.end(), [&pid](const auto &pair) {
474 auto renderRecord = pair.second->GetRenderRecord();
475 return renderRecord && renderRecord->GetPid() == pid;
476 });
477 return ((iter == appRunningRecordMap_.end()) ? nullptr : iter->second);
478 }
479
OnRemoteRenderDied(const wptr<IRemoteObject> & remote)480 void AppRunningManager::OnRemoteRenderDied(const wptr<IRemoteObject> &remote)
481 {
482 std::lock_guard<std::recursive_mutex> guard(lock_);
483 if (remote == nullptr) {
484 HILOG_ERROR("remote is null");
485 return;
486 }
487 sptr<IRemoteObject> object = remote.promote();
488 if (!object) {
489 HILOG_ERROR("promote failed.");
490 return;
491 }
492
493 const auto &it =
494 std::find_if(appRunningRecordMap_.begin(), appRunningRecordMap_.end(), [&object](const auto &pair) {
495 if (!pair.second) {
496 return false;
497 }
498
499 auto renderRecord = pair.second->GetRenderRecord();
500 if (!renderRecord) {
501 return false;
502 }
503
504 auto scheduler = renderRecord->GetScheduler();
505 return scheduler && scheduler->AsObject() == object;
506 });
507 if (it != appRunningRecordMap_.end()) {
508 auto appRecord = it->second;
509 appRecord->SetRenderRecord(nullptr);
510 }
511 }
512 } // namespace AppExecFwk
513 } // namespace OHOS