• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef OHOS_MEMORY_MEMMGR_RECALIM_PRIORITY_MANAGER_H
17 #define OHOS_MEMORY_MEMMGR_RECALIM_PRIORITY_MANAGER_H
18 
19 #include "single_instance.h"
20 #include "event_handler.h"
21 #include "reclaim_priority_constants.h"
22 #include "process_priority_info.h"
23 #include "bundle_priority_info.h"
24 #include "account_bundle_info.h"
25 #include "os_account_manager.h"
26 #include "reclaim_param.h"
27 #include "memmgr_config_manager.h"
28 
29 #include <map>
30 #include <mutex>
31 #include <string>
32 #include <set>
33 
34 namespace OHOS {
35 namespace Memory {
36 struct ReclaimHandleRequest {
37     int32_t callerPid;
38     int32_t callerUid;
39     pid_t pid;
40     int uid;
41     std::string callerBundleName;
42     std::string bundleName;
43     AppStateUpdateReason reason;
44 };
45 
SingleRequest(int pid,int uid,const std::string & bundleName,AppStateUpdateReason reason)46 inline ReclaimHandleRequest SingleRequest(int pid, int uid, const std::string &bundleName, AppStateUpdateReason reason)
47 {
48     ReclaimHandleRequest request;
49     request.pid = pid;
50     request.uid = uid;
51     request.bundleName = bundleName;
52     request.reason = reason;
53     return request;
54 }
55 
56 class ReclaimPriorityManager {
57     DECLARE_SINGLE_INSTANCE_BASE(ReclaimPriorityManager);
58 
59 public:
60     struct BundleInfoPtrCmp {
operatorBundleInfoPtrCmp61         bool operator() (const std::shared_ptr<BundlePriorityInfo> p1, const std::shared_ptr<BundlePriorityInfo> p2)
62         {
63             if (p1->uid_ == p2->uid_) {
64                 // remove duplicate BundlePriorityInfo according to uid_
65                 return false;
66             } else {
67                 if (p1->priority_ != p2->priority_) {
68                     // in ascending order
69                     return p1->priority_ < p2->priority_;
70                 } else {
71                     // when in same priority_, sort by uid_
72                     // it will be sorted by last used time
73                     return p1->uid_ < p2->uid_;
74                 }
75             }
76         }
77     };
78     struct BundleInfoCmp {
operatorBundleInfoCmp79         bool operator() (const BundlePriorityInfo &p1, const BundlePriorityInfo &p2)
80         {
81             if (p1.uid_ == p2.uid_) {
82                 // remove duplicate BundlePriorityInfo according to uid_
83                 return false;
84             } else {
85                 if (p1.priority_ != p2.priority_) {
86                     // in descending order
87                     return p1.priority_ > p2.priority_;
88                 } else {
89                     // when in same priority_, sort by uid_
90                     // it will be sorted by last used time
91                     return p1.uid_ < p2.uid_;
92                 }
93             }
94         }
95     };
96 
97     using BundlePrioSet = std::set<std::shared_ptr<BundlePriorityInfo>, BundleInfoPtrCmp>;
98     using BunldeCopySet = std::set<BundlePriorityInfo, BundleInfoCmp>;
99     // map <bundleUid, std::shared_ptr<BundlePriorityInfo>>
100     using BundlePrioMap = std::map<int, std::shared_ptr<BundlePriorityInfo>>;
101     using OsAccountsMap = std::map<int, std::shared_ptr<AccountBundleInfo>>;
102     bool Init();
103     bool UpdateReclaimPriority(const ReclaimHandleRequest &request);
104     bool OsAccountChanged(int accountId, AccountSA::OS_ACCOUNT_SWITCH_MOD switchMod);
105 
Initailized()106     inline bool Initailized()
107     {
108         return initialized_;
109     };
110 
111     // for lmkd and memory reclaim
112     void GetBundlePrioSet(BunldeCopySet &bundleSet);
113 
114     void GetOneKillableBundle(int minPrio, BunldeCopySet &bundleSet);
115 
116     void SetBundleState(int accountId, int uid, BundleState state);
117 
118     // for hidumper, usage: hdc shell hidumper -s 1909
119     void Dump(int fd);
120 
121     void Reset();
122 private:
123     bool initialized_ = false;
124 
125     // map <accountId, accountInfo>
126     OsAccountsMap osAccountsInfoMap_;
127     // total system prioritySet
128     // when new a BundlePriorityInfo, it will be added into this set
129     // when delete a BundlePriorityInfo, it will be removed from this set
130     // when change the priority of BundlePriorityInfo, it will be removed and added from this set to re-sort it
131     BundlePrioSet totalBundlePrioSet_;
132     std::mutex totalBundlePrioSetLock_;
133 
134     std::shared_ptr<AppExecFwk::EventHandler> handler_;
135     std::map<int32_t, std::string> updateReasonStrMapping_;
136     std::string UNKOWN_REASON = "UNKOWN_REASON";
137     ReclaimPriorityConfig config_;
138     std::set<std::string> allKillableSystemApps_;
139 
140     ReclaimPriorityManager();
141     bool GetEventHandler();
142     void UpdateForegroundApps();
143     bool IsFrontApp(const std::string& pkgName, int32_t uid, int32_t pid);
144     void GetAllKillableSystemApps();
145     void GetKillableSystemAppsFromAms(std::set<std::string> &killableApps);
146     void HandlePreStartedProcs();
147     bool UpdateReclaimPriorityInner(const ReclaimHandleRequest &request);
148     void UpdateReclaimPriorityWithLock(const ReclaimHandleRequest &request);
149     bool HandleExtensionProcess(int32_t callerPid, int32_t callerUid, const std::string &callerBundleName,
150         pid_t pid, int bundleUid, const std::string &bundleName, AppStateUpdateReason priorityReason);
151     bool OsAccountChangedInner(int accountId, AccountSA::OS_ACCOUNT_SWITCH_MOD switchMod);
152     bool UpdateAllPrioForOsAccountChanged(int accountId, AccountSA::OS_ACCOUNT_SWITCH_MOD switchMod);
153     bool ApplyReclaimPriority(std::shared_ptr<BundlePriorityInfo> bundle, pid_t pid, AppAction action);
154     bool IsProcExist(pid_t pid, int bundleUid, int accountId);
155     bool IsOsAccountExist(int accountId);
156     bool HandleCreateProcess(int pid, int bundleUid, const std::string &bundleName, int accountId,
157                              bool isRender = false);
158     bool HandleTerminateProcess(ProcessPriorityInfo proc, std::shared_ptr<BundlePriorityInfo> bundle,
159             std::shared_ptr<AccountBundleInfo> account);
160     void HandleUpdateProcess(AppStateUpdateReason reason, std::shared_ptr<BundlePriorityInfo> bundle,
161             ProcessPriorityInfo &proc, AppAction &action);
162     void UpdatePriorityByProcStatus(std::shared_ptr<BundlePriorityInfo> bundle, ProcessPriorityInfo &proc);
163     bool HandleApplicationSuspend(std::shared_ptr<BundlePriorityInfo> bundle);
164     std::shared_ptr<AccountBundleInfo> FindOsAccountById(int accountId);
165     void RemoveOsAccountById(int accountId);
166     void AddOsAccountInfo(std::shared_ptr<AccountBundleInfo> account);
167     bool IsKillableSystemApp(std::shared_ptr<BundlePriorityInfo> bundle);
168     void NotifyKillableSystemAppsAdded(std::set<std::string> &newKillableApps);
169     bool IsImportantApp(std::shared_ptr<BundlePriorityInfo> bundle, int &dstPriority);
170     bool UpdateProcessForExtension(int32_t callerPid, int32_t callerUid, const std::string &callerBundleName,
171             pid_t pid, int bundleUid, const std::string &bundleName, AppStateUpdateReason priorityReason);
172     bool UpdateConnectorsForExtension(int32_t callerPid, int32_t callerUid, const std::string &callerBundleName,
173             pid_t pid, int bundleUid, const std::string &bundleName, AppStateUpdateReason priorityReason);
174     void UpdatePriorityByProcForExtension(const ProcessPriorityInfo &proc);
175     void UpdatePriorityByProcConnector(ProcessPriorityInfo &proc);
176     bool HandleUpdateExtensionBundle(int bundleUid);
177 
178     // two methods below used to manage totalBundlePrioSet_ by BundlePriorityInfo
179     void AddBundleInfoToSet(std::shared_ptr<BundlePriorityInfo> bundle);
180     void UpdateBundlePriority(std::shared_ptr<BundlePriorityInfo> bundle);
181     void DeleteBundleInfoFromSet(std::shared_ptr<BundlePriorityInfo> bundle);
182 
183     std::string& AppStateUpdateResonToString(AppStateUpdateReason reason);
GetOsAccountLocalIdFromUid(int bundleUid)184     static inline int GetOsAccountLocalIdFromUid(int bundleUid)
185     {
186         return GetOsAccountIdByUid(bundleUid);
187     }
188 };
189 } // namespace Memory
190 } // namespace OHOS
191 #endif // OHOS_MEMORY_MEMMGR_RECALIM_PRIORITY_MANAGER_H
192