1 /*
2 * Copyright (c) 2022-2023 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 "reclaim_priority_manager.h"
17
18 #include "app_mgr_interface.h"
19 #include "bundle_mgr_proxy.h"
20 #include "iservice_registry.h"
21 #include "kernel_interface.h"
22 #include "memmgr_log.h"
23 #include "memmgr_ptr_util.h"
24 #include "multi_account_manager.h"
25 #include "oom_score_adj_utils.h"
26 #include "reclaim_strategy_manager.h"
27 #include "render_process_info.h"
28 #include "singleton.h"
29 #include "system_ability_definition.h"
30
31 namespace OHOS {
32 namespace Memory {
33 namespace {
34 const std::string TAG = "ReclaimPriorityManager";
35 }
36 IMPLEMENT_SINGLE_INSTANCE(ReclaimPriorityManager);
37
ReclaimPriorityManager()38 ReclaimPriorityManager::ReclaimPriorityManager()
39 {
40 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::CREATE_PROCESS)] = "CREATE_PROCESS";
41 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::PROCESS_READY)] = "PROCESS_READY";
42 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::FOREGROUND)] = "FOREGROUND";
43 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::BACKGROUND)] = "BACKGROUND";
44 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::SUSPEND_DELAY_START)] = "SUSPEND_DELAY_START";
45 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::SUSPEND_DELAY_END)] = "SUSPEND_DELAY_END";
46 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::BACKGROUND_RUNNING_START)] =
47 "BACKGROUND_RUNNING_START";
48 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::BACKGROUND_RUNNING_END)] =
49 "BACKGROUND_RUNNING_END";
50 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::EVENT_START)] = "EVENT_START";
51 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::EVENT_END)] = "EVENT_END";
52 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::APPLICATION_SUSPEND)] = "APPLICATION_SUSPEND";
53 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::PROCESS_TERMINATED)] = "PROCESS_TERMINATED";
54 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::OS_ACCOUNT_CHANGED)] = "OS_ACCOUNT_CHANGED";
55 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::DIST_DEVICE_CONNECTED)] =
56 "DIST_DEVICE_CONNECTED";
57 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::DIST_DEVICE_DISCONNECTED)] =
58 "DIST_DEVICE_DISCONNECTED";
59 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::BIND_EXTENSION)] = "BIND_EXTENSION";
60 updateReasonStrMapping_[static_cast<int32_t>(AppStateUpdateReason::UNBIND_EXTENSION)] = "UNBIND_EXTENSION";
61 }
62
AppStateUpdateResonToString(AppStateUpdateReason reason)63 std::string& ReclaimPriorityManager::AppStateUpdateResonToString(AppStateUpdateReason reason)
64 {
65 auto ptr = updateReasonStrMapping_.find(static_cast<int32_t>(reason));
66 if (ptr != updateReasonStrMapping_.end()) {
67 return ptr->second;
68 } else {
69 return UNKOWN_REASON;
70 }
71 }
72
Init()73 bool ReclaimPriorityManager::Init()
74 {
75 config_ = MemmgrConfigManager::GetInstance().GetReclaimPriorityConfig();
76 initialized_ = GetEventHandler();
77 GetAllKillableSystemApps();
78 if (initialized_) {
79 HILOGI("init successed");
80 } else {
81 HILOGE("init failed");
82 }
83 return initialized_;
84 }
85
GetEventHandler()86 bool ReclaimPriorityManager::GetEventHandler()
87 {
88 if (!handler_) {
89 MAKE_POINTER(handler_, shared, AppExecFwk::EventHandler, "failed to create event handler", return false,
90 AppExecFwk::EventRunner::Create());
91 }
92 return true;
93 }
94
Dump(int fd)95 void ReclaimPriorityManager::Dump(int fd)
96 {
97 // add lock
98 std::lock_guard<std::mutex> setLock(totalBundlePrioSetLock_);
99
100 dprintf(fd, "priority list of all managed apps\n");
101 dprintf(fd, " uid name priority\n");
102 for (auto bundlePtr : totalBundlePrioSet_) {
103 dprintf(fd, "%8d %42s %5d %3d\n", bundlePtr->uid_, bundlePtr->name_.c_str(), bundlePtr->priority_,
104 bundlePtr->GetProcsCount());
105 }
106 dprintf(fd, "-----------------------------------------------------------------\n\n");
107
108 dprintf(fd,
109 "priority list of all managed processes, status:(fg,visible,bgtask,trantask,evt,dist,extb,ext,render)\n");
110 dprintf(fd, " pid uid bundle priority status\
111 connnectorpids connnectoruids processuids\n");
112 for (auto bundlePtr : totalBundlePrioSet_) {
113 dprintf(fd, "|-----------------------------------------\n");
114 for (auto procEntry : bundlePtr->procs_) {
115 ProcessPriorityInfo &proc = procEntry.second;
116 dprintf(fd, "|%8d %8d %42s %5d %d%d%d%d%d%d%d%d%d %30s %30s %30s\n",
117 proc.pid_, bundlePtr->uid_, bundlePtr->name_.c_str(),
118 proc.priority_, proc.isFreground, proc.isVisible_, proc.isBackgroundRunning,
119 proc.isSuspendDelay, proc.isEventStart, proc.isDistDeviceConnected,
120 proc.extensionBindStatus, proc.isExtension, proc.isRender_, proc.ConnectorsToString().c_str(),
121 proc.ExtensionConnectorsUidToString().c_str(), proc.ExtensionProcessUidToString().c_str());
122 }
123 }
124 dprintf(fd, "-----------------------------------------------------------------\n");
125 }
126
GetAppMgrProxy()127 sptr<AppExecFwk::IAppMgr> GetAppMgrProxy()
128 {
129 auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
130 auto appObject = systemAbilityManager->GetSystemAbility(APP_MGR_SERVICE_ID);
131 return iface_cast<AppExecFwk::IAppMgr>(appObject);
132 }
133
IsFrontApp(const std::string & pkgName,int32_t uid,int32_t pid)134 bool ReclaimPriorityManager::IsFrontApp(const std::string& pkgName, int32_t uid, int32_t pid)
135 {
136 sptr<AppExecFwk::IAppMgr> appMgrProxy_ = GetAppMgrProxy();
137 if (!appMgrProxy_) {
138 HILOGE("GetAppMgrProxy failed");
139 return false;
140 }
141 std::vector<AppExecFwk::AppStateData> fgAppList;
142 appMgrProxy_->GetForegroundApplications(fgAppList);
143 for (auto fgApp : fgAppList) {
144 if (fgApp.bundleName == pkgName && fgApp.uid == uid) {
145 return true;
146 }
147 }
148 return false;
149 }
150
GetAllKillableSystemApps()151 void ReclaimPriorityManager::GetAllKillableSystemApps()
152 {
153 HILOGI("called");
154 // get killable system apps from xml
155 allKillableSystemApps_.merge(config_.GetkillalbeSystemApps());
156 // get killable system apps from fwk (finally from bms)
157 std::set<std::string> killableSystemAppsFromAms_;
158 GetKillableSystemAppsFromAms(killableSystemAppsFromAms_);
159 allKillableSystemApps_.merge(killableSystemAppsFromAms_);
160 }
161
GetKillableSystemAppsFromAms(std::set<std::string> & killableApps)162 void ReclaimPriorityManager::GetKillableSystemAppsFromAms(std::set<std::string> &killableApps)
163 {
164 // get killable system apps from fwk (finally from bms)
165 }
166
167 // if user install new killable system apps, fwk should tell me by calling this interface.
168 // if user uninstall some killable system apps, we can do nothing since killable info will be updated on next rebooting.
NotifyKillableSystemAppsAdded(std::set<std::string> & newKillableApps)169 void ReclaimPriorityManager::NotifyKillableSystemAppsAdded(std::set<std::string> &newKillableApps)
170 {
171 allKillableSystemApps_.merge(newKillableApps);
172 }
173
174 // handle process started before our service
HandlePreStartedProcs()175 void ReclaimPriorityManager::HandlePreStartedProcs()
176 {
177 std::vector<unsigned int> preStartedPids;
178 KernelInterface::GetInstance().GetAllProcPids(preStartedPids);
179 for (unsigned int pid : preStartedPids) {
180 unsigned int uid = 0;
181 if (!KernelInterface::GetInstance().GetUidByPid(pid, uid)) {
182 HILOGE("process[pid=%{public}d] started before me, but GetUidByPid failed.", pid);
183 continue;
184 }
185 struct ProcInfo procInfo;
186 std::string name;
187 if (!KernelInterface::GetInstance().GetProcNameByPid(pid, name)) {
188 HILOGE("process[pid=%{public}d, uid=%{public}d] started before me, but GetProcNameByPid failed.", pid, uid);
189 continue;
190 }
191 if (allKillableSystemApps_.find(name) != allKillableSystemApps_.end()) {
192 OomScoreAdjUtils::WriteOomScoreAdjToKernel(pid, RECLAIM_PRIORITY_KILLABLE_SYSTEM);
193 HILOGI("process[pid=%{public}d, uid=%{public}d, name=%{public}s] started before me, killable = %{public}d",
194 pid, uid, name.c_str(), true);
195 }
196 }
197 }
198
GetBundlePrioSet(BunldeCopySet & bundleSet)199 void ReclaimPriorityManager::GetBundlePrioSet(BunldeCopySet &bundleSet)
200 {
201 // add lock
202 std::lock_guard<std::mutex> setLock(totalBundlePrioSetLock_);
203
204 HILOGD("iter %{public}zu bundles begin", totalBundlePrioSet_.size());
205 int count = 0;
206 for (auto itrBundle = totalBundlePrioSet_.rbegin(); itrBundle != totalBundlePrioSet_.rend(); ++itrBundle, ++count) {
207 std::shared_ptr<BundlePriorityInfo> bundle = *itrBundle;
208 if (bundle == nullptr) {
209 HILOGD("bundle %{public}d/%{public}zu is nullptr", count, totalBundlePrioSet_.size());
210 continue;
211 }
212
213 HILOGD("bundle %{public}d/%{public}zu, uid=%{publics}d", count, totalBundlePrioSet_.size(), bundle->uid_);
214 BundlePriorityInfo tmpBundleInfo(bundle->name_, bundle->uid_, bundle->priority_,
215 bundle->accountId_, bundle->state_);
216
217 for (auto itrProcess = bundle->procs_.begin(); itrProcess != bundle->procs_.end(); itrProcess++) {
218 ProcessPriorityInfo processInfo = itrProcess->second;
219 ProcessPriorityInfo tmpProcess(processInfo);
220
221 tmpBundleInfo.procs_.insert(std::make_pair(tmpProcess.pid_, tmpProcess));
222 }
223
224 HILOGD("insert bundle [%{public}d][%{public}s] to set, priority=%{public}d",
225 tmpBundleInfo.uid_, tmpBundleInfo.name_.c_str(), tmpBundleInfo.priority_);
226 bundleSet.insert(tmpBundleInfo);
227 }
228 HILOGD("iter bundles end");
229 }
230
GetOneKillableBundle(int minPrio,BunldeCopySet & bundleSet)231 void ReclaimPriorityManager::GetOneKillableBundle(int minPrio, BunldeCopySet &bundleSet)
232 {
233 HILOGD("called, minPrio=%{public}d", minPrio);
234 // add lock
235 std::lock_guard<std::mutex> setLock(totalBundlePrioSetLock_);
236
237 HILOGD("iter %{public}zu bundles begin", totalBundlePrioSet_.size());
238 int count = 0;
239 for (auto itrBundle = totalBundlePrioSet_.rbegin(); itrBundle != totalBundlePrioSet_.rend(); ++itrBundle) {
240 std::shared_ptr<BundlePriorityInfo> bundle = *itrBundle;
241 if (bundle == nullptr) {
242 HILOGD("bundle %{public}d/%{public}zu is nullptr", count, totalBundlePrioSet_.size());
243 continue;
244 }
245 if (bundle->priority_ < minPrio) {
246 HILOGD("there is no bundle with priority bigger than %{public}d, break!", minPrio);
247 break;
248 }
249 if (bundle->GetState() == BundleState::STATE_WAITING_FOR_KILL) {
250 HILOGD("bundle<%{public}d, %{public}s}> is waiting to kill, skiped!", bundle->uid_, bundle->name_.c_str());
251 continue;
252 }
253
254 try {
255 auto ret = bundleSet.insert(*bundle);
256 if (ret.second) {
257 HILOGI("insert bundle<%{public}d, %{public}s}> to set, priority=%{public}d", bundle->uid_,
258 bundle->name_.c_str(), bundle->priority_);
259 ++count;
260 break;
261 }
262 } catch (...) {
263 HILOGE("new BundlePriorityInfo failed, need kill quickly!");
264 for (auto procEntry : bundle->procs_) {
265 HILOGE("quick killing bundle<%{public}d, %{public}s}>, pid=%{public}d", bundle->uid_,
266 bundle->name_.c_str(), procEntry.second.pid_);
267 KernelInterface::GetInstance().KillOneProcessByPid(procEntry.second.pid_);
268 }
269 }
270 }
271 HILOGD("iter bundles end");
272 }
273
SetBundleState(int accountId,int uid,BundleState state)274 void ReclaimPriorityManager::SetBundleState(int accountId, int uid, BundleState state)
275 {
276 std::lock_guard<std::mutex> setLock(totalBundlePrioSetLock_);
277 std::shared_ptr<AccountBundleInfo> account = FindOsAccountById(accountId);
278 if (account != nullptr) {
279 auto pairPtr = account->bundleIdInfoMapping_.find(uid);
280 if (pairPtr != account->bundleIdInfoMapping_.end()) {
281 if (pairPtr->second != nullptr) {
282 auto bundlePtr = pairPtr->second;
283 bundlePtr->SetState(state);
284 }
285 }
286 }
287 }
288
IsOsAccountExist(int accountId)289 bool ReclaimPriorityManager::IsOsAccountExist(int accountId)
290 {
291 if (osAccountsInfoMap_.find(accountId) == osAccountsInfoMap_.end()) {
292 HILOGE("accountId not exist");
293 return false;
294 }
295 return true;
296 }
297
AddBundleInfoToSet(std::shared_ptr<BundlePriorityInfo> bundle)298 void ReclaimPriorityManager::AddBundleInfoToSet(std::shared_ptr<BundlePriorityInfo> bundle)
299 {
300 auto ret = totalBundlePrioSet_.insert(bundle);
301 if (ret.second) {
302 HILOGD("success to insert bundle to set, uid=%{public}d, totalBundlePrioSet_.size=%{public}zu",
303 bundle->uid_, totalBundlePrioSet_.size());
304 }
305 }
306
DeleteBundleInfoFromSet(std::shared_ptr<BundlePriorityInfo> bundle)307 void ReclaimPriorityManager::DeleteBundleInfoFromSet(std::shared_ptr<BundlePriorityInfo> bundle)
308 {
309 int delCount = totalBundlePrioSet_.erase(bundle);
310 HILOGD("delete %{public}d bundles from set, uid=%{public}d, totalBundlePrioSet_.size=%{public}zu",
311 delCount, bundle->uid_, totalBundlePrioSet_.size());
312 }
313
FindOsAccountById(int accountId)314 std::shared_ptr<AccountBundleInfo> ReclaimPriorityManager::FindOsAccountById(int accountId)
315 {
316 auto iter = osAccountsInfoMap_.find(accountId);
317 if (iter != osAccountsInfoMap_.end()) {
318 return iter->second;
319 }
320 HILOGI("not found the account info");
321 return nullptr;
322 }
323
RemoveOsAccountById(int accountId)324 void ReclaimPriorityManager::RemoveOsAccountById(int accountId)
325 {
326 // erase the accountId data
327 osAccountsInfoMap_.erase(accountId);
328 }
329
AddOsAccountInfo(std::shared_ptr<AccountBundleInfo> account)330 void ReclaimPriorityManager::AddOsAccountInfo(std::shared_ptr<AccountBundleInfo> account)
331 {
332 osAccountsInfoMap_.insert(std::make_pair(account->id_, account));
333 }
334
IsProcExist(pid_t pid,int bundleUid,int accountId)335 bool ReclaimPriorityManager::IsProcExist(pid_t pid, int bundleUid, int accountId)
336 {
337 std::shared_ptr<AccountBundleInfo> account = FindOsAccountById(accountId);
338 if (account == nullptr || !account->HasBundle(bundleUid)) {
339 HILOGE("account or bundle name not exist");
340 return false;
341 }
342 std::shared_ptr<BundlePriorityInfo> bundle = account->FindBundleById(bundleUid);
343 if (bundle == nullptr) {
344 return false;
345 }
346 if (pid == IGNORE_PID) {
347 return true;
348 }
349 if (!bundle->HasProc(pid)) {
350 HILOGE("pid not exist");
351 return false;
352 }
353 return true;
354 }
355
UpdateReclaimPriority(const ReclaimHandleRequest & request)356 bool ReclaimPriorityManager::UpdateReclaimPriority(const ReclaimHandleRequest &request)
357 {
358 if (!initialized_) {
359 HILOGE("has not been initialized_, skiped!");
360 return false;
361 }
362 std::function<void()> updateReclaimPriorityInnerFunc =
363 std::bind(&ReclaimPriorityManager::UpdateReclaimPriorityWithLock, this, request);
364 return handler_->PostImmediateTask(updateReclaimPriorityInnerFunc);
365 }
366
GetBundleMgr()367 sptr<AppExecFwk::IBundleMgr> GetBundleMgr()
368 {
369 sptr<ISystemAbilityManager> saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
370 if (saMgr == nullptr) {
371 HILOGE("failed to get system ability manager!");
372 return nullptr;
373 }
374 sptr<IRemoteObject> remoteObject_ = saMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
375 if (remoteObject_ == nullptr) {
376 HILOGE("bms not found!");
377 return nullptr;
378 }
379 sptr<AppExecFwk::IBundleMgr> bundleMgr = iface_cast<AppExecFwk::IBundleMgr>(remoteObject_);
380 if (bundleMgr == nullptr) {
381 HILOGE("bms interface cast failed!");
382 }
383 return bundleMgr;
384 }
385
IsKillableSystemApp(std::shared_ptr<BundlePriorityInfo> bundle)386 bool ReclaimPriorityManager::IsKillableSystemApp(std::shared_ptr<BundlePriorityInfo> bundle)
387 {
388 if (allKillableSystemApps_.find(bundle->name_) != allKillableSystemApps_.end()) {
389 HILOGD("find bundle (%{public}s) in killable system app list", bundle->name_.c_str());
390 return true;
391 }
392
393 sptr<AppExecFwk::IBundleMgr> bmsPtr = GetBundleMgr();
394 if (bmsPtr == nullptr) {
395 HILOGE("failed to get BundleMgr!");
396 return false;
397 }
398
399 AppExecFwk::ApplicationInfo info;
400 bool result = bmsPtr->GetApplicationInfo(bundle->name_.c_str(),
401 AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, GetOsAccountLocalIdFromUid(bundle->uid_), info);
402 if (result) {
403 HILOGD("appInfo<%{public}s,%{public}d><keepAlive=%{public}d, isSystemApp=%{public}d, isLauncherApp=%{public}d>",
404 bundle->name_.c_str(), bundle->uid_, info.keepAlive, info.isSystemApp, info.isLauncherApp);
405 if (info.keepAlive) {
406 auto ret = allKillableSystemApps_.insert(bundle->name_);
407 if (ret.second) {
408 HILOGD("add a new killable system app (%{public}s)", bundle->name_.c_str());
409 }
410 }
411 return info.keepAlive;
412 } else {
413 HILOGE("bundleMgr GetApplicationInfo failed!");
414 }
415 return false;
416 }
417
UpdateBundlePriority(std::shared_ptr<BundlePriorityInfo> bundle)418 void ReclaimPriorityManager::UpdateBundlePriority(std::shared_ptr<BundlePriorityInfo> bundle)
419 {
420 HILOGD("begin-------------------------");
421 DeleteBundleInfoFromSet(bundle);
422 bundle->UpdatePriority();
423 AddBundleInfoToSet(bundle);
424 HILOGD("end----------------------------");
425 }
426
HandleCreateProcess(pid_t pid,int bundleUid,const std::string & bundleName,int accountId,bool isRender)427 bool ReclaimPriorityManager::HandleCreateProcess(pid_t pid, int bundleUid, const std::string &bundleName, int accountId,
428 bool isRender)
429 {
430 HILOGD("called, bundleName=%{public}s, pid=%{public}d", bundleName.c_str(), pid);
431 std::shared_ptr<AccountBundleInfo> account = FindOsAccountById(accountId);
432 if (isRender) {
433 HILOGI("render create, bundleName=%{public}s, pid=%{public}d", bundleName.c_str(), pid);
434 OomScoreAdjUtils::WriteOomScoreAdjToKernel(pid, RECLAIM_PRIORITY_FOREGROUND);
435 return true;
436 }
437 if (account == nullptr) {
438 DECLARE_SHARED_POINTER(AccountBundleInfo, tmpAccount);
439 MAKE_POINTER(tmpAccount, shared, AccountBundleInfo, "cannot new account!!", return false, accountId);
440 account = tmpAccount;
441 AddOsAccountInfo(account);
442 }
443 std::shared_ptr<BundlePriorityInfo> bundle;
444 AppAction action;
445 if (account->HasBundle(bundleUid)) {
446 // insert new ProcessInfo and update new priority
447 bundle = account->FindBundleById(bundleUid);
448 action = AppAction::CREATE_PROCESS_ONLY;
449 } else {
450 // need to new BundleInfo ,add to list and map
451 MAKE_POINTER(bundle, shared, BundlePriorityInfo, "cannot new account!!", return false,
452 bundleName, bundleUid, RECLAIM_PRIORITY_BACKGROUND);
453 AddBundleInfoToSet(bundle);
454 action = AppAction::CREATE_PROCESS_AND_APP;
455 }
456
457 ProcessPriorityInfo proc(pid, bundleUid, RECLAIM_PRIORITY_BACKGROUND);
458 if (IsKillableSystemApp(bundle)) {
459 HILOGI("[bundleName=%{public}s, pid=%{public}d] is a killable system app", bundleName.c_str(), pid);
460 proc.priority_ = RECLAIM_PRIORITY_KILLABLE_SYSTEM;
461 } else {
462 HILOGI("[bundleName=%{public}s, pid=%{public}d] is not a killable system app", bundleName.c_str(), pid);
463 }
464 bundle->AddProc(proc);
465 UpdateBundlePriority(bundle);
466 account->AddBundleToOsAccount(bundle);
467 bool ret = ApplyReclaimPriority(bundle, pid, action);
468 HILOGI("create: bundleName=%{public}s, prio=%{public}d", bundleName.c_str(), bundle->priority_);
469 return ret;
470 }
471
HandleTerminateProcess(ProcessPriorityInfo proc,std::shared_ptr<BundlePriorityInfo> bundle,std::shared_ptr<AccountBundleInfo> account)472 bool ReclaimPriorityManager::HandleTerminateProcess(ProcessPriorityInfo proc,
473 std::shared_ptr<BundlePriorityInfo> bundle, std::shared_ptr<AccountBundleInfo> account)
474 {
475 HILOGI("terminated: bundleName=%{public}s, pid=%{public}d", bundle->name_.c_str(), proc.pid_);
476
477 // clear proc and bundle if needed, delete the object
478 int removedProcessPrio = proc.priority_;
479 bundle->RemoveProcByPid(proc.pid_);
480 bool ret = true;
481
482 if (bundle->GetProcsCount() == 0) {
483 ret = ApplyReclaimPriority(bundle, proc.pid_, AppAction::APP_DIED);
484 account->RemoveBundleById(bundle->uid_);
485 DeleteBundleInfoFromSet(bundle);
486 } else {
487 if (removedProcessPrio <= bundle->priority_) {
488 UpdateBundlePriority(bundle);
489 }
490 }
491 if (account->GetBundlesCount() == 0) {
492 RemoveOsAccountById(account->id_);
493 }
494 return ret;
495 }
496
HandleApplicationSuspend(std::shared_ptr<BundlePriorityInfo> bundle)497 bool ReclaimPriorityManager::HandleApplicationSuspend(std::shared_ptr<BundlePriorityInfo> bundle)
498 {
499 if (bundle == nullptr) {
500 return false;
501 }
502 HILOGI("application suspend: bundleName=%{public}s", bundle->name_.c_str());
503 for (auto i = bundle->procs_.begin(); i != bundle->procs_.end(); ++i) {
504 i->second.priority_ = RECLAIM_PRIORITY_SUSPEND;
505 }
506 UpdateBundlePriority(bundle);
507 bool ret = ApplyReclaimPriority(bundle, IGNORE_PID, AppAction::OTHERS);
508 return ret;
509 }
510
UpdateConnectorsForExtension(int32_t callerPid,int32_t callerUid,const std::string & callerBundleName,pid_t pid,int bundleUid,const std::string & bundleName,AppStateUpdateReason priorityReason)511 bool ReclaimPriorityManager::UpdateConnectorsForExtension(int32_t callerPid, int32_t callerUid,
512 const std::string &callerBundleName, pid_t pid, int bundleUid, const std::string &bundleName,
513 AppStateUpdateReason priorityReason)
514 {
515 int accountId = GetOsAccountLocalIdFromUid(bundleUid);
516 if (!IsProcExist(pid, bundleUid, accountId)) {
517 HILOGE("process not exist and not to create it!!");
518 return false;
519 }
520 std::shared_ptr<AccountBundleInfo> account = FindOsAccountById(accountId);
521 std::shared_ptr<BundlePriorityInfo> bundle = account->FindBundleById(bundleUid);
522 ProcessPriorityInfo &proc = bundle->FindProcByPid(pid);
523
524 if (proc.priority_ <= RECLAIM_PRIORITY_KILLABLE_SYSTEM || bundle->priority_ <= RECLAIM_PRIORITY_KILLABLE_SYSTEM ||
525 IsKillableSystemApp(bundle)) {
526 HILOGD("%{public}s is system app, skip!", bundleName.c_str());
527 return true;
528 }
529
530 if (priorityReason == AppStateUpdateReason::BIND_EXTENSION) {
531 proc.isFreground = false; // current process is a extension, it never be a fg app.
532 proc.isExtension = true;
533 proc.AddExtensionConnector(callerPid);
534 proc.AddExtensionConnectorUid(callerUid);
535 HILOGD("add connector %{public}d to %{public}s(%{public}d,%{public}d), now connectors:%{public}s", callerPid,
536 bundleName.c_str(), pid, bundleUid, proc.ConnectorsToString().c_str());
537 } else if (priorityReason == AppStateUpdateReason::UNBIND_EXTENSION) {
538 proc.isFreground = false; // current process is a extension, it never be a fg app.
539 proc.isExtension = true;
540 proc.RemoveExtensionConnector(callerPid);
541 proc.RemoveExtensionConnectorUid(callerUid);
542 HILOGD("del connector %{public}d from %{public}s(%{public}d,%{public}d), now connectors:%{public}s", callerPid,
543 bundleName.c_str(), pid, bundleUid, proc.ConnectorsToString().c_str());
544 }
545 AppAction action = AppAction::OTHERS;
546 HandleUpdateProcess(priorityReason, bundle, proc, action);
547 return ApplyReclaimPriority(bundle, pid, action);
548 }
549
UpdateProcessForExtension(int32_t callerPid,int32_t callerUid,const std::string & callerBundleName,pid_t pid,int bundleUid,const std::string & bundleName,AppStateUpdateReason priorityReason)550 bool ReclaimPriorityManager::UpdateProcessForExtension(int32_t callerPid, int32_t callerUid,
551 const std::string &callerBundleName, pid_t pid, int bundleUid, const std::string &bundleName,
552 AppStateUpdateReason priorityReason)
553 {
554 int callerAccountId = GetOsAccountLocalIdFromUid(callerUid);
555 if (!IsProcExist(callerPid, callerUid, callerAccountId)) {
556 HILOGE("caller process not exist and not to create it!!");
557 return false;
558 }
559 std::shared_ptr<AccountBundleInfo> callerAccount = FindOsAccountById(callerAccountId);
560 std::shared_ptr<BundlePriorityInfo> callerBundle = callerAccount->FindBundleById(callerUid);
561 ProcessPriorityInfo &callerProc = callerBundle->FindProcByPid(callerPid);
562
563 if (priorityReason == AppStateUpdateReason::BIND_EXTENSION) {
564 callerProc.AddExtensionProcessUid(bundleUid);
565 HILOGD("add caller %{public}d to %{public}s(%{public}d,%{public}d), now calling:%{public}s", callerPid,
566 bundleName.c_str(), pid, bundleUid, callerProc.ExtensionProcessUidToString().c_str());
567 } else if (priorityReason == AppStateUpdateReason::UNBIND_EXTENSION) {
568 callerProc.RemoveExtensionProcessUid(bundleUid);
569 HILOGD("del caller %{public}d from %{public}s(%{public}d,%{public}d), now calling:%{public}s ", callerPid,
570 bundleName.c_str(), pid, bundleUid, callerProc.ExtensionProcessUidToString().c_str());
571 }
572 return true;
573 }
574
HandleUpdateExtensionBundle(int bundleUid)575 bool ReclaimPriorityManager::HandleUpdateExtensionBundle(int bundleUid)
576 {
577 int accountId = GetOsAccountLocalIdFromUid(bundleUid);
578 std::shared_ptr<AccountBundleInfo> accountPtr = FindOsAccountById(accountId);
579 if (accountPtr == nullptr || !accountPtr->HasBundle(bundleUid)) {
580 return false;
581 }
582 std::shared_ptr<BundlePriorityInfo> bundlePtr = accountPtr->FindBundleById(bundleUid);
583 if (bundlePtr == nullptr) {
584 return false;
585 }
586 for (auto i = bundlePtr->procs_.begin(); i != bundlePtr->procs_.end(); ++i) {
587 UpdatePriorityByProcConnector(i->second);
588 }
589 UpdateBundlePriority(bundlePtr);
590 return true;
591 }
592
HandleExtensionProcess(int32_t callerPid,int32_t callerUid,const std::string & callerBundleName,pid_t pid,int bundleUid,const std::string & bundleName,AppStateUpdateReason priorityReason)593 bool ReclaimPriorityManager::HandleExtensionProcess(int32_t callerPid, int32_t callerUid,
594 const std::string &callerBundleName, pid_t pid, int bundleUid, const std::string &bundleName,
595 AppStateUpdateReason priorityReason)
596 {
597 UpdateProcessForExtension(callerPid, callerUid,
598 callerBundleName, pid, bundleUid, bundleName, priorityReason);
599 return UpdateConnectorsForExtension(callerPid, callerUid,
600 callerBundleName, pid, bundleUid, bundleName, priorityReason);
601 }
602
UpdateReclaimPriorityWithLock(const ReclaimHandleRequest & request)603 void ReclaimPriorityManager::UpdateReclaimPriorityWithLock(const ReclaimHandleRequest &request)
604 {
605 std::lock_guard<std::mutex> lock(totalBundlePrioSetLock_);
606 UpdateReclaimPriorityInner(request);
607 }
608
UpdateReclaimPriorityInner(const ReclaimHandleRequest & request)609 bool ReclaimPriorityManager::UpdateReclaimPriorityInner(const ReclaimHandleRequest &request)
610 {
611 HILOGI("called, pid=%{public}d, bundleUid=%{public}d, bundleName=%{public}s, reason=%{public}s",
612 request.pid, request.uid, request.bundleName.c_str(), AppStateUpdateResonToString(request.reason).c_str());
613 int accountId = GetOsAccountLocalIdFromUid(request.uid);
614 HILOGD("accountId=%{public}d", accountId);
615
616 if (request.reason == AppStateUpdateReason::BIND_EXTENSION ||
617 request.reason == AppStateUpdateReason::UNBIND_EXTENSION) {
618 bool ret = HandleExtensionProcess(request.callerPid, request.callerUid,
619 request.callerBundleName, request.pid, request.uid, request.bundleName, request.reason);
620 return ret;
621 }
622
623 if (request.reason == AppStateUpdateReason::UPDATE_EXTENSION_PROCESS) {
624 bool ret = HandleUpdateExtensionBundle(request.callerUid);
625 return ret;
626 }
627
628 if (request.reason == AppStateUpdateReason::CREATE_PROCESS) {
629 bool ret = HandleCreateProcess(request.pid, request.uid, request.bundleName, accountId);
630 return ret;
631 }
632
633 if (request.reason == AppStateUpdateReason::RENDER_CREATE_PROCESS) {
634 HILOGD("call HandleCreateProcess");
635 return HandleCreateProcess(request.pid, request.uid, request.bundleName, accountId, true);
636 }
637
638 if (!IsProcExist(request.pid, request.uid, accountId)) {
639 HILOGE("process not exist and not to create it!!");
640 return false;
641 }
642 std::shared_ptr<AccountBundleInfo> account = FindOsAccountById(accountId);
643 std::shared_ptr<BundlePriorityInfo> bundle = account->FindBundleById(request.uid);
644 if (bundle->priority_ <= RECLAIM_PRIORITY_KILLABLE_SYSTEM) {
645 HILOGI("%{public}s is system app, skip!", request.bundleName.c_str());
646 return true;
647 }
648
649 if (request.reason == AppStateUpdateReason::APPLICATION_SUSPEND) {
650 bool ret = HandleApplicationSuspend(bundle);
651 return ret;
652 }
653
654 ProcessPriorityInfo &proc = bundle->FindProcByPid(request.pid);
655 bool ret = true;
656 AppAction action = AppAction::OTHERS;
657 if (request.reason == AppStateUpdateReason::PROCESS_TERMINATED) {
658 ret = HandleTerminateProcess(proc, bundle, account);
659 return ret;
660 } else {
661 HandleUpdateProcess(request.reason, bundle, proc, action);
662 }
663 ret = ApplyReclaimPriority(bundle, request.pid, action);
664 return ret;
665 }
666
IsImportantApp(std::shared_ptr<BundlePriorityInfo> bundle,int & dstPriority)667 bool ReclaimPriorityManager::IsImportantApp(std::shared_ptr<BundlePriorityInfo> bundle, int &dstPriority)
668 {
669 std::map<std::string, int> importantApps = config_.GetImportantBgApps();
670 std::string targetAppName = bundle->name_;
671
672 if (importantApps.count(targetAppName)) {
673 dstPriority = importantApps.at(targetAppName);
674 return true;
675 }
676 return false;
677 }
678
UpdatePriorityByProcForExtension(const ProcessPriorityInfo & proc)679 void ReclaimPriorityManager::UpdatePriorityByProcForExtension(const ProcessPriorityInfo &proc)
680 {
681 for (auto callerUid : proc.extensionProcessUids_) {
682 ReclaimHandleRequest request;
683 request.callerUid = callerUid;
684 request.reason = AppStateUpdateReason::UPDATE_EXTENSION_PROCESS;
685 UpdateReclaimPriorityInner(request);
686 }
687 }
688
UpdatePriorityByProcConnector(ProcessPriorityInfo & proc)689 void ReclaimPriorityManager::UpdatePriorityByProcConnector(ProcessPriorityInfo &proc)
690 {
691 if (proc.extensionConnectorUids_.size() == 0) {
692 return;
693 }
694 int minPriority = RECLAIM_PRIORITY_UNKNOWN;
695 for (auto connectorUid : proc.extensionConnectorUids_) {
696 int connectorAccountId = GetOsAccountLocalIdFromUid(connectorUid);
697 std::shared_ptr<AccountBundleInfo> connectorAccount = FindOsAccountById(connectorAccountId);
698 if (connectorAccount == nullptr || !connectorAccount->HasBundle(connectorUid)) {
699 minPriority = 0; // native
700 continue;
701 }
702 std::shared_ptr<BundlePriorityInfo> connectorBundle = connectorAccount->FindBundleById(connectorUid);
703 if (connectorBundle == nullptr) {
704 return;
705 }
706 for (auto procEntry : connectorBundle->procs_) {
707 ProcessPriorityInfo &connectorProc = procEntry.second;
708 minPriority = connectorProc.priority_ < minPriority ? connectorProc.priority_ : minPriority;
709 }
710 }
711 proc.SetPriority(minPriority + 100); //raise the priority of the lowest-priority process by 100
712 }
713
UpdatePriorityByProcStatus(std::shared_ptr<BundlePriorityInfo> bundle,ProcessPriorityInfo & proc)714 void ReclaimPriorityManager::UpdatePriorityByProcStatus(std::shared_ptr<BundlePriorityInfo> bundle,
715 ProcessPriorityInfo &proc)
716 {
717 int priorityBefore = proc.priority_;
718
719 if (bundle->priority_ < RECLAIM_PRIORITY_FOREGROUND) { // is a system process
720 HILOGD("%{public}d is a system process, skiped!", proc.pid_);
721 return;
722 }
723 if (proc.isRender_) { // priority of render follow its host and it is updated by action of its host
724 HILOGD("%{public}d is a render process, skiped!", proc.pid_);
725 return;
726 }
727 if (proc.isFreground) { // is a freground process
728 HILOGD("%{public}d is a freground process", proc.pid_);
729 if (proc.priority_ > RECLAIM_PRIORITY_FOREGROUND) {
730 proc.SetPriority(RECLAIM_PRIORITY_FOREGROUND);
731 }
732 UpdatePriorityByProcForExtension(proc);
733 } else { // is a background process
734 int bgPriority = RECLAIM_PRIORITY_BACKGROUND;
735 if (IsImportantApp(bundle, bgPriority)) {
736 HILOGD("%{public}d is a important background process, set process priority to %{public}d first",
737 proc.pid_, bgPriority);
738 } else {
739 HILOGD("%{public}d is a background process, set process priority to %{public}d first",
740 proc.pid_, bgPriority);
741 }
742 proc.SetPriority(bgPriority);
743 UpdatePriorityByProcForExtension(proc);
744 }
745 if (proc.isVisible_) {
746 HILOGD("%{public}d is a process with visible window", proc.pid_);
747 if (proc.priority_ > RECLAIM_PRIORITY_VISIBLE) {
748 proc.SetPriority(RECLAIM_PRIORITY_VISIBLE);
749 }
750 }
751 if (proc.isSuspendDelay) { // is a background process with transient task
752 HILOGD("%{public}d is a background process with transient task", proc.pid_);
753 if (proc.priority_ > RECLAIM_PRIORITY_BG_SUSPEND_DELAY) {
754 proc.SetPriority(RECLAIM_PRIORITY_BG_SUSPEND_DELAY);
755 }
756 } else if (proc.extensionBindStatus == EXTENSION_STATUS_FG_BIND) { // is a extension and bind to a fg process
757 HILOGD("%{public}d is a extension process bind to a fg process", proc.pid_);
758 if (proc.priority_ > RECLAIM_PRIORITY_FG_BIND_EXTENSION) {
759 proc.SetPriority(RECLAIM_PRIORITY_FG_BIND_EXTENSION);
760 }
761 } else if (proc.isBackgroundRunning || proc.isEventStart) {
762 // is a background perceived process
763 HILOGD("%{public}d is a background perceived process", proc.pid_);
764 if (proc.priority_ > RECLAIM_PRIORITY_BG_PERCEIVED) {
765 proc.SetPriority(RECLAIM_PRIORITY_BG_PERCEIVED);
766 }
767 } else if (proc.extensionBindStatus == EXTENSION_STATUS_BG_BIND) { // is a extension and bind to a bg process
768 HILOGD("%{public}d is a extension process bind to a bg process", proc.pid_);
769 if (proc.priority_ > RECLAIM_PRIORITY_BG_BIND_EXTENSION) {
770 proc.SetPriority(RECLAIM_PRIORITY_BG_BIND_EXTENSION);
771 }
772 } else if (proc.isDistDeviceConnected) { // is a background process connected by distribute device
773 HILOGD("%{public}d is a process connect to a dist device", proc.pid_);
774 if (proc.priority_ > RECLAIM_PRIORITY_BG_DIST_DEVICE) {
775 proc.SetPriority(RECLAIM_PRIORITY_BG_DIST_DEVICE);
776 }
777 } else if (proc.extensionBindStatus == EXTENSION_STATUS_NO_BIND) { // is a extension and no bind to any process
778 HILOGD("%{public}d is a extension process no bind to any process", proc.pid_);
779 if (proc.priority_ > RECLAIM_PRIORITY_NO_BIND_EXTENSION) {
780 proc.SetPriority(RECLAIM_PRIORITY_NO_BIND_EXTENSION);
781 }
782 } else {
783 // is a plain background process
784 }
785 if (proc.isExtension) {
786 UpdatePriorityByProcConnector(proc);
787 }
788 HILOGI(": bundle[uid_=%{public}d,name=%{public}s,priority=%{public}d], proc[pid_=%{public}d, uid=%{public}d, "
789 "isFreground=%{public}d, isBackgroundRunning=%{public}d, isSuspendDelay=%{public}d, isEventStart=%{public}d, "
790 "isDistDeviceConnected=%{public}d, extensionBindStatus=%{public}d], priority:%{public}d-->%{public}d",
791 bundle->uid_, bundle->name_.c_str(), bundle->priority_,
792 proc.pid_, proc.uid_, proc.isFreground, proc.isBackgroundRunning, proc.isSuspendDelay, proc.isEventStart,
793 proc.isDistDeviceConnected, proc.extensionBindStatus, priorityBefore, proc.priority_);
794 UpdateBundlePriority(bundle);
795 }
796
HandleUpdateProcess(AppStateUpdateReason reason,std::shared_ptr<BundlePriorityInfo> bundle,ProcessPriorityInfo & proc,AppAction & action)797 void ReclaimPriorityManager::HandleUpdateProcess(AppStateUpdateReason reason,
798 std::shared_ptr<BundlePriorityInfo> bundle, ProcessPriorityInfo &proc, AppAction &action)
799 {
800 HILOGD("called, bundle[uid_=%{public}d,name=%{public}s,priority=%{public}d], proc[pid_=%{public}d, uid=%{public}d,"
801 "isFreground=%{public}d, isBackgroundRunning=%{public}d, isSuspendDelay=%{public}d, isEventStart=%{public}d,"
802 "isDistDeviceConnected=%{public}d, extensionBindStatus=%{public}d, priority=%{public}d], case:%{public}s",
803 bundle->uid_, bundle->name_.c_str(), bundle->priority_, proc.pid_, proc.uid_, proc.isFreground,
804 proc.isBackgroundRunning, proc.isSuspendDelay, proc.isEventStart, proc.isDistDeviceConnected,
805 proc.extensionBindStatus, proc.priority_, AppStateUpdateResonToString(reason).c_str());
806 switch (reason) {
807 case AppStateUpdateReason::FOREGROUND: {
808 proc.isFreground = true;
809 action = AppAction::APP_FOREGROUND;
810 break;
811 }
812 case AppStateUpdateReason::BACKGROUND: {
813 proc.isFreground = false;
814 action = AppAction::APP_BACKGROUND;
815 break;
816 }
817 case AppStateUpdateReason::SUSPEND_DELAY_START:
818 proc.isSuspendDelay = true;
819 break;
820 case AppStateUpdateReason::SUSPEND_DELAY_END:
821 proc.isSuspendDelay = false;
822 break;
823 case AppStateUpdateReason::BACKGROUND_RUNNING_START:
824 proc.isBackgroundRunning = true;
825 break;
826 case AppStateUpdateReason::BACKGROUND_RUNNING_END:
827 proc.isBackgroundRunning = false;
828 break;
829 case AppStateUpdateReason::EVENT_START:
830 proc.isEventStart = true;
831 break;
832 case AppStateUpdateReason::EVENT_END:
833 proc.isEventStart = false;
834 break;
835 case AppStateUpdateReason::DIST_DEVICE_CONNECTED:
836 proc.isDistDeviceConnected = true;
837 break;
838 case AppStateUpdateReason::DIST_DEVICE_DISCONNECTED:
839 proc.isDistDeviceConnected = false;
840 break;
841 case AppStateUpdateReason::BIND_EXTENSION:
842 if (proc.ExtensionConnectorsCount() > 0) {
843 proc.extensionBindStatus = EXTENSION_STATUS_FG_BIND;
844 }
845 break;
846 case AppStateUpdateReason::UNBIND_EXTENSION:
847 if (proc.ExtensionConnectorsCount() == 0) {
848 proc.extensionBindStatus = EXTENSION_STATUS_NO_BIND;
849 }
850 break;
851 case AppStateUpdateReason::VISIBLE:
852 proc.isVisible_ = true;
853 break;
854 case AppStateUpdateReason::UN_VISIBLE:
855 proc.isVisible_ = false;
856 break;
857 default:
858 break;
859 }
860 UpdatePriorityByProcStatus(bundle, proc);
861 }
862
ApplyReclaimPriority(std::shared_ptr<BundlePriorityInfo> bundle,pid_t pid,AppAction action)863 bool ReclaimPriorityManager::ApplyReclaimPriority(std::shared_ptr<BundlePriorityInfo> bundle,
864 pid_t pid, AppAction action)
865 {
866 HILOGD("called");
867 if (bundle == nullptr) {
868 return false;
869 }
870 DECLARE_SHARED_POINTER(ReclaimParam, para);
871 MAKE_POINTER(para, shared, ReclaimParam, "make ReclaimParam failed", return false,
872 pid, bundle->uid_, bundle->name_, bundle->accountId_, bundle->priority_, action);
873 ReclaimStrategyManager::GetInstance().NotifyAppStateChanged(para);
874 return OomScoreAdjUtils::WriteOomScoreAdjToKernel(bundle);
875 }
876
OsAccountChanged(int accountId,AccountSA::OS_ACCOUNT_SWITCH_MOD switchMod)877 bool ReclaimPriorityManager::OsAccountChanged(int accountId, AccountSA::OS_ACCOUNT_SWITCH_MOD switchMod)
878 {
879 if (!initialized_) {
880 HILOGE("has not been initialized_, skiped!");
881 return false;
882 }
883 if (accountId < 0) {
884 HILOGE("invalid account id!");
885 return false;
886 }
887 std::function<bool()> osAccountChangedInnerFunc =
888 std::bind(&ReclaimPriorityManager::OsAccountChangedInner, this, accountId, switchMod);
889 return handler_->PostImmediateTask(osAccountChangedInnerFunc);
890 }
891
OsAccountChangedInner(int accountId,AccountSA::OS_ACCOUNT_SWITCH_MOD switchMod)892 bool ReclaimPriorityManager::OsAccountChangedInner(int accountId, AccountSA::OS_ACCOUNT_SWITCH_MOD switchMod)
893 {
894 return UpdateAllPrioForOsAccountChanged(accountId, switchMod);
895 }
896
UpdateAllPrioForOsAccountChanged(int accountId,AccountSA::OS_ACCOUNT_SWITCH_MOD switchMod)897 bool ReclaimPriorityManager::UpdateAllPrioForOsAccountChanged(int accountId,
898 AccountSA::OS_ACCOUNT_SWITCH_MOD switchMod)
899 {
900 if (!initialized_) {
901 HILOGE("has not been initialized_, skiped!");
902 return false;
903 }
904 HILOGI("UpdateReclaimPriority for all apps because of os account changed ");
905 bool ret = MultiAccountManager::GetInstance().HandleOsAccountsChanged(accountId, switchMod, osAccountsInfoMap_);
906 return ret;
907 }
908
Reset()909 void ReclaimPriorityManager::Reset()
910 {
911 std::lock_guard<std::mutex> setLock(totalBundlePrioSetLock_);
912 totalBundlePrioSet_.clear();
913 osAccountsInfoMap_.clear();
914 }
915
916 } // namespace Memory
917 } // namespace OHOS
918