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