• 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 "mem_mgr_service.h"
17 
18 #include <parameters.h>
19 #include <unistd.h>
20 
21 #include "accesstoken_kit.h"
22 #include "ipc_skeleton.h"
23 #include "low_memory_killer.h"
24 #include "mem_mgr_event_center.h"
25 #include "memmgr_config_manager.h"
26 #include "memmgr_log.h"
27 #include "multi_account_manager.h"
28 #include "nandlife_controller.h"
29 #include "reclaim_priority_manager.h"
30 #include "reclaim_strategy_manager.h"
31 #include "system_ability_definition.h"
32 #include "window_visibility_observer.h"
33 #ifdef USE_PURGEABLE_MEMORY
34 #include "kernel_interface.h"
35 #include "purgeable_mem_manager.h"
36 #endif
37 #include "dump_command_dispatcher.h"
38 
39 namespace OHOS {
40 namespace Memory {
41 namespace {
42 const std::string TAG = "MemMgrService";
43 const int32_t ENG_MODE = OHOS::system::GetIntParameter("const.debuggable", 0);
44 const int32_t ERR_MEMMGR_PERMISSION_DENIED = -1;
45 }
46 
47 IMPLEMENT_SINGLE_INSTANCE(MemMgrService);
48 const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(&MemMgrService::GetInstance());
49 
MemMgrService()50 MemMgrService::MemMgrService() : SystemAbility(MEMORY_MANAGER_SA_ID, true)
51 {
52 }
53 
Init()54 bool MemMgrService::Init()
55 {
56     MemmgrConfigManager::GetInstance().Init();
57 
58     // init reclaim priority manager
59     if (!ReclaimPriorityManager::GetInstance().Init()) {
60         HILOGE("ReclaimPriorityManager init failed");
61         return false;
62     }
63 
64     // init multiple account manager
65     MultiAccountManager::GetInstance().Init();
66 
67 #ifdef USE_HYPERHOLD_MEMORY
68     // init reclaim strategy manager
69     if (!ReclaimStrategyManager::GetInstance().Init()) {
70         HILOGE("ReclaimStrategyManager init failed");
71         return false;
72     }
73 #endif
74 
75     // init event center, then managers above can work by event trigger
76     if (!MemMgrEventCenter::GetInstance().Init()) {
77         HILOGE("MemMgrEventCenter init failed");
78         return false;
79     }
80 
81 #ifdef USE_HYPERHOLD_MEMORY
82     // init nandlife controller
83     NandLifeController::GetInstance().Init();
84 #endif
85 
86     HILOGI("init successed");
87     return true;
88 }
89 
OnStart()90 void MemMgrService::OnStart()
91 {
92     HILOGI("called");
93     if (!Init()) {
94         HILOGE("init failed");
95         return;
96     }
97     if (!Publish(this)) {
98         HILOGE("publish SA failed");
99         return;
100     }
101     HILOGI("publish SA successed");
102 
103     AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
104     AddSystemAbilityListener(COMMON_EVENT_SERVICE_ABILITY_ID);
105     AddSystemAbilityListener(BACKGROUND_TASK_MANAGER_SERVICE_ID);
106     AddSystemAbilityListener(SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN);
107     AddSystemAbilityListener(SUBSYS_APPLICATIONS_SYS_ABILITY_ID_BEGIN);
108     AddSystemAbilityListener(APP_MGR_SERVICE_ID);
109     AddSystemAbilityListener(ABILITY_MGR_SERVICE_ID);
110 }
111 
OnStop()112 void MemMgrService::OnStop()
113 {
114     HILOGI("called");
115 }
116 
117 // implements of innerkits list below
118 
GetBundlePriorityList(BundlePriorityList & bundlePrioList)119 int32_t MemMgrService::GetBundlePriorityList(BundlePriorityList &bundlePrioList)
120 {
121     HILOGI("called");
122     ReclaimPriorityManager::BunldeCopySet bundleSet;
123     ReclaimPriorityManager::GetInstance().GetBundlePrioSet(bundleSet);
124     for (auto bundlePriorityInfo : bundleSet) {
125         Memory::BundlePriority bi = Memory::BundlePriority(bundlePriorityInfo.uid_,
126             bundlePriorityInfo.name_, bundlePriorityInfo.priority_, bundlePriorityInfo.accountId_);
127         bundlePrioList.AddBundleInfo(bi);
128     }
129     bundlePrioList.SetCount(bundlePrioList.Size());
130     return 0;
131 }
132 
NotifyDistDevStatus(int32_t pid,int32_t uid,const std::string & name,bool connected)133 int32_t MemMgrService::NotifyDistDevStatus(int32_t pid, int32_t uid, const std::string &name, bool connected)
134 {
135     HILOGI("called, pid=%{public}d, uid=%{public}d, name=%{public}s, connected=%{public}d", pid, uid, name.c_str(),
136         connected);
137     ReclaimHandleRequest request;
138     request.pid = pid;
139     request.uid = uid;
140     request.bundleName = name;
141     request.reason =
142         connected ? AppStateUpdateReason::DIST_DEVICE_CONNECTED : AppStateUpdateReason::DIST_DEVICE_DISCONNECTED;
143     ReclaimPriorityManager::GetInstance().UpdateReclaimPriority(
144         SingleRequest({pid, uid, "", name},
145             connected ? AppStateUpdateReason::DIST_DEVICE_CONNECTED : AppStateUpdateReason::DIST_DEVICE_DISCONNECTED));
146     return 0;
147 }
148 
GetKillLevelOfLmkd(int32_t & killLevel)149 int32_t MemMgrService::GetKillLevelOfLmkd(int32_t &killLevel)
150 {
151     HILOGI("called");
152     killLevel = LowMemoryKiller::GetInstance().GetKillLevel();
153     return 0;
154 }
155 
156 #ifdef USE_PURGEABLE_MEMORY
RegisterActiveApps(int32_t pid,int32_t uid)157 int32_t MemMgrService::RegisterActiveApps(int32_t pid, int32_t uid)
158 {
159     HILOGI("called, pid=%{public}d, uid=%{public}d", pid, uid);
160     PurgeableMemManager::GetInstance().RegisterActiveApps(pid, uid);
161     return 0;
162 }
163 
DeregisterActiveApps(int32_t pid,int32_t uid)164 int32_t MemMgrService::DeregisterActiveApps(int32_t pid, int32_t uid)
165 {
166     HILOGI("called, pid=%{public}d, uid=%{public}d", pid, uid);
167     PurgeableMemManager::GetInstance().DeregisterActiveApps(pid, uid);
168     return 0;
169 }
170 
SubscribeAppState(const sptr<IAppStateSubscriber> & subscriber)171 int32_t MemMgrService::SubscribeAppState(const sptr<IAppStateSubscriber> &subscriber)
172 {
173     HILOGI("called");
174     PurgeableMemManager::GetInstance().AddSubscriber(subscriber);
175     return 0;
176 }
177 
UnsubscribeAppState(const sptr<IAppStateSubscriber> & subscriber)178 int32_t MemMgrService::UnsubscribeAppState(const sptr<IAppStateSubscriber> &subscriber)
179 {
180     HILOGI("called");
181     PurgeableMemManager::GetInstance().RemoveSubscriber(subscriber);
182     return 0;
183 }
184 
GetAvailableMemory(int32_t & memSize)185 int32_t MemMgrService::GetAvailableMemory(int32_t &memSize)
186 {
187     HILOGI("called");
188     memSize = KernelInterface::GetInstance().GetCurrentBuffer();
189     if (memSize < 0 || memSize >= MAX_BUFFER_KB) {
190         return -1;
191     }
192     return 0;
193 }
194 
GetTotalMemory(int32_t & memSize)195 int32_t MemMgrService::GetTotalMemory(int32_t &memSize)
196 {
197     HILOGI("called");
198     memSize = KernelInterface::GetInstance().GetTotalBuffer();
199     if (memSize < 0 || memSize >= MAX_BUFFER_KB) {
200         return -1;
201     }
202     return 0;
203 }
204 #endif // USE_PURGEABLE_MEMORY
205 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)206 void MemMgrService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
207 {
208     HILOGI("systemAbilityId: %{public}d add", systemAbilityId);
209     MemMgrEventCenter::GetInstance().RetryRegisterEventObserver(systemAbilityId);
210 }
211 
OnWindowVisibilityChanged(const std::vector<sptr<MemMgrWindowInfo>> & MemMgrWindowInfo)212 int32_t MemMgrService::OnWindowVisibilityChanged(const std::vector<sptr<MemMgrWindowInfo>> &MemMgrWindowInfo)
213 {
214     HILOGI("called");
215     int32_t callingUid = IPCSkeleton::GetCallingUid();
216     if (callingUid != windowManagerUid_) {
217         HILOGE("OnWindowVisibilityChanged refused for%{public}d", callingUid);
218         return -1;
219     }
220     HILOGI("OnWindowVisibilityChanged called %{public}d", callingUid);
221     WindowVisibilityObserver::GetInstance().UpdateWindowVisibilityPriority(MemMgrWindowInfo);
222     return 0;
223 }
224 
GetReclaimPriorityByPid(int32_t pid,int32_t & priority)225 int32_t MemMgrService::GetReclaimPriorityByPid(int32_t pid, int32_t &priority)
226 {
227     HILOGI("called");
228     std::string path = KernelInterface::GetInstance().JoinPath("/proc/", std::to_string(pid), "/oom_score_adj");
229     std::string contentStr;
230     if (KernelInterface::GetInstance().ReadFromFile(path, contentStr) || contentStr.size() == 0) {
231         HILOGE("read %{public}s failed, content=[%{public}s]", path.c_str(), contentStr.c_str());
232         return -1;
233     }
234     HILOGD("read %{public}s succ, content=[%{public}s]", path.c_str(), contentStr.c_str());
235 
236     try {
237         priority = std::stoi(contentStr);
238     } catch (std::out_of_range&) {
239         HILOGW("stoi() failed: out_of_range");
240         return -1;
241     } catch (std::invalid_argument&) {
242         HILOGW("stoi() failed: invalid_argument");
243         return -1;
244     }
245     return 0;
246 }
247 
248 
NotifyProcessStateChangedSync(const MemMgrProcessStateInfo & processStateInfo)249 int32_t MemMgrService::NotifyProcessStateChangedSync(const MemMgrProcessStateInfo &processStateInfo)
250 {
251     HILOGD("called");
252     if (processStateInfo.reason_ == ProcPriorityUpdateReason::START_ABILITY) {
253         HILOGD("callerpid=%{public}d,calleruid=%{public}d,pid=%{public}d,uid=%{public}d,reason=%{public}u",
254             processStateInfo.callerPid_, processStateInfo.callerUid_, processStateInfo.pid_, processStateInfo.uid_,
255             static_cast<uint32_t>(processStateInfo.reason_));
256         UpdateRequest request = CallerRequest({processStateInfo.callerPid_, processStateInfo.callerUid_, "", ""},
257             {processStateInfo.pid_, processStateInfo.uid_, "", ""}, AppStateUpdateReason::ABILITY_START);
258         if (!ReclaimPriorityManager::GetInstance().UpdateRecalimPrioritySyncWithLock(request)) {
259             HILOGE("NotifyProcessStateChangedSync <pid=%{public}d,uid=%{public}d,reason=%{public}u> failed",
260                 processStateInfo.pid_, processStateInfo.uid_, static_cast<uint32_t>(processStateInfo.reason_));
261             return static_cast<int32_t>(MemMgrErrorCode::MEMMGR_SERVICE_ERR);
262         }
263     }
264     return 0;
265 }
266 
NotifyProcessStateChangedAsync(const MemMgrProcessStateInfo & processStateInfo)267 int32_t MemMgrService::NotifyProcessStateChangedAsync(const MemMgrProcessStateInfo &processStateInfo)
268 {
269     HILOGD("called");
270     if (processStateInfo.reason_ == ProcPriorityUpdateReason::START_ABILITY) {
271         HILOGD("callerpid=%{public}d,calleruid=%{public}d,pid=%{public}d,uid=%{public}d,reason=%{public}u",
272             processStateInfo.callerPid_, processStateInfo.callerUid_, processStateInfo.pid_, processStateInfo.uid_,
273             static_cast<uint32_t>(processStateInfo.reason_));
274         UpdateRequest request = CallerRequest({processStateInfo.callerPid_, processStateInfo.callerUid_, "", ""},
275             {processStateInfo.pid_, processStateInfo.uid_, "", ""}, AppStateUpdateReason::ABILITY_START);
276         if (!ReclaimPriorityManager::GetInstance().UpdateReclaimPriority(request)) {
277             HILOGE("NotifyProcessStateChangedAsync <pid=%{public}d,uid=%{public}d,reason=%{public}u> failed",
278                 processStateInfo.pid_, processStateInfo.uid_, static_cast<uint32_t>(processStateInfo.reason_));
279             return static_cast<int32_t>(MemMgrErrorCode::MEMMGR_SERVICE_ERR);
280         }
281     }
282     return 0;
283 }
284 
NotifyProcessStatus(int32_t pid,int32_t type,int32_t status,int32_t saId)285 int32_t MemMgrService::NotifyProcessStatus(int32_t pid, int32_t type, int32_t status, int32_t saId)
286 {
287     HILOGI("pid=%{public}d,type=%{public}d,status=%{public}d,saId=%{public}d",
288         pid, type, status, saId);
289     return 0;
290 }
291 
SetCritical(int32_t pid,bool critical,int32_t saId)292 int32_t MemMgrService::SetCritical(int32_t pid, bool critical, int32_t saId)
293 {
294     HILOGI("pid=%{public}d,critical=%{public}d,saId=%{public}d", pid, critical, saId);
295     return 0;
296 }
297 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)298 void MemMgrService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
299 {
300     HILOGI("systemAbilityId: %{public}d add", systemAbilityId);
301     MemMgrEventCenter::GetInstance().RemoveEventObserver(systemAbilityId);
302 }
303 
ParseParams(const std::vector<std::string> & params,std::map<std::string,std::vector<std::string>> & keyValuesMapping)304 void ParseParams(const std::vector<std::string> &params,
305                  std::map<std::string, std::vector<std::string>> &keyValuesMapping)
306 {
307     std::string tmpKey;
308     std::vector<std::string> tmpValue;
309     for (auto i = 0; i < params.size(); i++) {
310         if (params[i].empty())
311             continue;
312         if (params[i][0] == '-') {
313             if (!tmpKey.empty()) {
314                 keyValuesMapping[tmpKey] = tmpValue;
315                 tmpValue.clear();
316             }
317             tmpKey = params[i];
318         } else {
319             tmpValue.emplace_back(params[i]);
320         }
321     }
322     if (!tmpKey.empty()) {
323         keyValuesMapping[tmpKey] = tmpValue;
324     }
325 
326     HILOGD("keyValuesMapping.size()=%{public}zu\n", keyValuesMapping.size());
327     for (auto &it : keyValuesMapping) {
328         HILOGD("key=%{public}s", it.first.c_str());
329         for (auto i = 0; i < it.second.size(); i++) {
330             HILOGD("value[%{public}d]=%{public}s", i, it.second[i].c_str());
331         }
332     }
333 }
334 
AllowDump()335 bool MemMgrService::AllowDump()
336 {
337     if (ENG_MODE == 0) {
338         HILOGE("Not eng mode");
339         return false;
340     }
341     Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetFirstTokenID();
342     int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, "ohos.permission.DUMP");
343     if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
344         HILOGE("CheckPermission failed");
345         return false;
346     }
347     return true;
348 }
349 
Dump(int fd,const std::vector<std::u16string> & args)350 int MemMgrService::Dump(int fd, const std::vector<std::u16string> &args)
351 {
352     if (!AllowDump()) {
353         return ERR_MEMMGR_PERMISSION_DENIED;
354     }
355     HILOGI("called");
356     std::vector<std::string> params;
357     for (auto &arg : args) {
358         params.emplace_back(Str16ToStr8(arg));
359     }
360     std::map<std::string, std::vector<std::string>> keyValuesMapping;
361     ParseParams(params, keyValuesMapping);
362     DispatchDumpCommand(fd, keyValuesMapping);
363     return 0;
364 }
365 } // namespace Memory
366 } // namespace OHOS
367