• 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 <unistd.h>
19 
20 #include "ipc_skeleton.h"
21 #include "low_memory_killer.h"
22 #include "mem_mgr_event_center.h"
23 #include "memmgr_config_manager.h"
24 #include "memmgr_log.h"
25 #include "multi_account_manager.h"
26 #include "nandlife_controller.h"
27 #include "reclaim_priority_manager.h"
28 #include "reclaim_strategy_manager.h"
29 #include "system_ability_definition.h"
30 #include "window_visibility_observer.h"
31 #ifdef USE_PURGEABLE_MEMORY
32 #include "kernel_interface.h"
33 #include "purgeable_mem_manager.h"
34 #endif
35 #include "dump_command_dispatcher.h"
36 
37 namespace OHOS {
38 namespace Memory {
39 namespace {
40 const std::string TAG = "MemMgrService";
41 }
42 
43 IMPLEMENT_SINGLE_INSTANCE(MemMgrService);
44 const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(&MemMgrService::GetInstance());
45 
MemMgrService()46 MemMgrService::MemMgrService() : SystemAbility(MEMORY_MANAGER_SA_ID, true)
47 {
48 }
49 
Init()50 bool MemMgrService::Init()
51 {
52     MemmgrConfigManager::GetInstance().Init();
53 
54     // init reclaim priority manager
55     if (!ReclaimPriorityManager::GetInstance().Init()) {
56         HILOGE("ReclaimPriorityManager init failed");
57         return false;
58     }
59 
60     // init multiple account manager
61     MultiAccountManager::GetInstance().Init();
62 
63     // init reclaim strategy manager
64     if (!ReclaimStrategyManager::GetInstance().Init()) {
65         HILOGE("ReclaimStrategyManager init failed");
66         return false;
67     }
68 
69     // init event center, then managers above can work by event trigger
70     if (!MemMgrEventCenter::GetInstance().Init()) {
71         HILOGE("MemMgrEventCenter init failed");
72         return false;
73     }
74 
75     // init nandlife controller
76     NandLifeController::GetInstance().Init();
77     HILOGI("init successed");
78     return true;
79 }
80 
OnStart()81 void MemMgrService::OnStart()
82 {
83     HILOGI("called");
84     if (!Init()) {
85         HILOGE("init failed");
86         return;
87     }
88     if (!Publish(this)) {
89         HILOGE("publish SA failed");
90         return;
91     }
92     HILOGI("publish SA successed");
93 
94     AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
95     AddSystemAbilityListener(COMMON_EVENT_SERVICE_ABILITY_ID);
96     AddSystemAbilityListener(BACKGROUND_TASK_MANAGER_SERVICE_ID);
97     AddSystemAbilityListener(SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN);
98     AddSystemAbilityListener(SUBSYS_APPLICATIONS_SYS_ABILITY_ID_BEGIN);
99     AddSystemAbilityListener(APP_MGR_SERVICE_ID);
100     AddSystemAbilityListener(ABILITY_MGR_SERVICE_ID);
101 }
102 
OnStop()103 void MemMgrService::OnStop()
104 {
105     HILOGI("called");
106 }
107 
108 // implements of innerkits list below
109 
GetBundlePriorityList(BundlePriorityList & bundlePrioList)110 int32_t MemMgrService::GetBundlePriorityList(BundlePriorityList &bundlePrioList)
111 {
112     HILOGI("called");
113     ReclaimPriorityManager::BunldeCopySet bundleSet;
114     ReclaimPriorityManager::GetInstance().GetBundlePrioSet(bundleSet);
115     for (auto bundlePriorityInfo : bundleSet) {
116         Memory::BundlePriority bi = Memory::BundlePriority(bundlePriorityInfo.uid_,
117             bundlePriorityInfo.name_, bundlePriorityInfo.priority_, bundlePriorityInfo.accountId_);
118         bundlePrioList.AddBundleInfo(bi);
119     }
120     bundlePrioList.SetCount(bundlePrioList.Size());
121     return 0;
122 }
123 
NotifyDistDevStatus(int32_t pid,int32_t uid,const std::string & name,bool connected)124 int32_t MemMgrService::NotifyDistDevStatus(int32_t pid, int32_t uid, const std::string &name, bool connected)
125 {
126     HILOGI("called, pid=%{public}d, uid=%{public}d, name=%{public}s, connected=%{public}d", pid, uid, name.c_str(),
127         connected);
128     ReclaimHandleRequest request;
129     request.pid = pid;
130     request.uid = uid;
131     request.bundleName = name;
132     request.reason =
133         connected ? AppStateUpdateReason::DIST_DEVICE_CONNECTED : AppStateUpdateReason::DIST_DEVICE_DISCONNECTED;
134     ReclaimPriorityManager::GetInstance().UpdateReclaimPriority(
135         SingleRequest({pid, uid, "", name},
136             connected ? AppStateUpdateReason::DIST_DEVICE_CONNECTED : AppStateUpdateReason::DIST_DEVICE_DISCONNECTED));
137     return 0;
138 }
139 
GetKillLevelOfLmkd(int32_t & killLevel)140 int32_t MemMgrService::GetKillLevelOfLmkd(int32_t &killLevel)
141 {
142     HILOGI("called");
143     killLevel = LowMemoryKiller::GetInstance().GetKillLevel();
144     return 0;
145 }
146 
147 #ifdef USE_PURGEABLE_MEMORY
RegisterActiveApps(int32_t pid,int32_t uid)148 int32_t MemMgrService::RegisterActiveApps(int32_t pid, int32_t uid)
149 {
150     HILOGI("called, pid=%{public}d, uid=%{public}d", pid, uid);
151     PurgeableMemManager::GetInstance().RegisterActiveApps(pid, uid);
152     return 0;
153 }
154 
DeregisterActiveApps(int32_t pid,int32_t uid)155 int32_t MemMgrService::DeregisterActiveApps(int32_t pid, int32_t uid)
156 {
157     HILOGI("called, pid=%{public}d, uid=%{public}d", pid, uid);
158     PurgeableMemManager::GetInstance().DeregisterActiveApps(pid, uid);
159     return 0;
160 }
161 
SubscribeAppState(const sptr<IAppStateSubscriber> & subscriber)162 int32_t MemMgrService::SubscribeAppState(const sptr<IAppStateSubscriber> &subscriber)
163 {
164     HILOGI("called");
165     PurgeableMemManager::GetInstance().AddSubscriber(subscriber);
166     return 0;
167 }
168 
UnsubscribeAppState(const sptr<IAppStateSubscriber> & subscriber)169 int32_t MemMgrService::UnsubscribeAppState(const sptr<IAppStateSubscriber> &subscriber)
170 {
171     HILOGI("called");
172     PurgeableMemManager::GetInstance().RemoveSubscriber(subscriber);
173     return 0;
174 }
175 
GetAvailableMemory(int32_t & memSize)176 int32_t MemMgrService::GetAvailableMemory(int32_t &memSize)
177 {
178     HILOGI("called");
179     memSize = KernelInterface::GetInstance().GetCurrentBuffer();
180     if (memSize < 0 || memSize >= MAX_BUFFER_KB) {
181         return -1;
182     }
183     return 0;
184 }
185 
GetTotalMemory(int32_t & memSize)186 int32_t MemMgrService::GetTotalMemory(int32_t &memSize)
187 {
188     HILOGI("called");
189     memSize = KernelInterface::GetInstance().GetTotalBuffer();
190     if (memSize < 0 || memSize >= MAX_BUFFER_KB) {
191         return -1;
192     }
193     return 0;
194 }
195 #endif // USE_PURGEABLE_MEMORY
196 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)197 void MemMgrService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
198 {
199     HILOGI("systemAbilityId: %{public}d add", systemAbilityId);
200     MemMgrEventCenter::GetInstance().RetryRegisterEventObserver(systemAbilityId);
201 }
202 
OnWindowVisibilityChanged(const std::vector<sptr<MemMgrWindowInfo>> & MemMgrWindowInfo)203 int32_t MemMgrService::OnWindowVisibilityChanged(const std::vector<sptr<MemMgrWindowInfo>> &MemMgrWindowInfo)
204 {
205     HILOGI("called");
206     int32_t callingUid = IPCSkeleton::GetCallingUid();
207     if (callingUid != windowManagerUid_) {
208         HILOGE("OnWindowVisibilityChanged refused for%{public}d", callingUid);
209         return -1;
210     }
211     HILOGI("OnWindowVisibilityChanged called %{public}d", callingUid);
212     WindowVisibilityObserver::GetInstance().UpdateWindowVisibilityPriority(MemMgrWindowInfo);
213     return 0;
214 }
215 
GetReclaimPriorityByPid(int32_t pid,int32_t & priority)216 int32_t MemMgrService::GetReclaimPriorityByPid(int32_t pid, int32_t &priority)
217 {
218     HILOGI("called");
219     std::string path = KernelInterface::GetInstance().JoinPath("/proc/", std::to_string(pid), "/oom_score_adj");
220     std::string contentStr;
221     if (KernelInterface::GetInstance().ReadFromFile(path, contentStr) || contentStr.size() == 0) {
222         HILOGE("read %{public}s failed, content=[%{public}s]", path.c_str(), contentStr.c_str());
223         return -1;
224     }
225     HILOGD("read %{public}s succ, content=[%{public}s]", path.c_str(), contentStr.c_str());
226 
227     try {
228         priority = std::stoi(contentStr);
229     } catch (std::out_of_range&) {
230         HILOGW("stoi() failed: out_of_range");
231         return -1;
232     } catch (std::invalid_argument&) {
233         HILOGW("stoi() failed: invalid_argument");
234         return -1;
235     }
236     return 0;
237 }
238 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)239 void MemMgrService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
240 {
241     HILOGI("systemAbilityId: %{public}d add", systemAbilityId);
242     MemMgrEventCenter::GetInstance().RemoveEventObserver(systemAbilityId);
243 }
244 
ParseParams(const std::vector<std::string> & params,std::map<std::string,std::vector<std::string>> & keyValuesMapping)245 void ParseParams(const std::vector<std::string> &params,
246                  std::map<std::string, std::vector<std::string>> &keyValuesMapping)
247 {
248     std::string tmpKey;
249     std::vector<std::string> tmpValue;
250     for (auto i = 0; i < params.size(); i++) {
251         if (params[i].empty())
252             continue;
253         if (params[i][0] == '-') {
254             if (!tmpKey.empty()) {
255                 keyValuesMapping[tmpKey] = tmpValue;
256                 tmpValue.clear();
257             }
258             tmpKey = params[i];
259         } else {
260             tmpValue.emplace_back(params[i]);
261         }
262     }
263     if (!tmpKey.empty()) {
264         keyValuesMapping[tmpKey] = tmpValue;
265     }
266 
267     HILOGD("keyValuesMapping.size()=%{public}zu\n", keyValuesMapping.size());
268     for (auto &it : keyValuesMapping) {
269         HILOGD("key=%{public}s", it.first.c_str());
270         for (auto i = 0; i < it.second.size(); i++) {
271             HILOGD("value[%{public}d]=%{public}s", i, it.second[i].c_str());
272         }
273     }
274 }
275 
Dump(int fd,const std::vector<std::u16string> & args)276 int MemMgrService::Dump(int fd, const std::vector<std::u16string> &args)
277 {
278     HILOGI("called");
279     std::vector<std::string> params;
280     for (auto &arg : args) {
281         params.emplace_back(Str16ToStr8(arg));
282     }
283     std::map<std::string, std::vector<std::string>> keyValuesMapping;
284     ParseParams(params, keyValuesMapping);
285     DispatchDumpCommand(fd, keyValuesMapping);
286     return 0;
287 }
288 } // namespace Memory
289 } // namespace OHOS
290