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(request);
135 return 0;
136 }
137
GetKillLevelOfLmkd(int32_t & killLevel)138 int32_t MemMgrService::GetKillLevelOfLmkd(int32_t &killLevel)
139 {
140 HILOGI("called");
141 killLevel = LowMemoryKiller::GetInstance().GetKillLevel();
142 return 0;
143 }
144
145 #ifdef USE_PURGEABLE_MEMORY
RegisterActiveApps(int32_t pid,int32_t uid)146 int32_t MemMgrService::RegisterActiveApps(int32_t pid, int32_t uid)
147 {
148 HILOGI("called, pid=%{public}d, uid=%{public}d", pid, uid);
149 PurgeableMemManager::GetInstance().RegisterActiveApps(pid, uid);
150 return 0;
151 }
152
DeregisterActiveApps(int32_t pid,int32_t uid)153 int32_t MemMgrService::DeregisterActiveApps(int32_t pid, int32_t uid)
154 {
155 HILOGI("called, pid=%{public}d, uid=%{public}d", pid, uid);
156 PurgeableMemManager::GetInstance().DeregisterActiveApps(pid, uid);
157 return 0;
158 }
159
SubscribeAppState(const sptr<IAppStateSubscriber> & subscriber)160 int32_t MemMgrService::SubscribeAppState(const sptr<IAppStateSubscriber> &subscriber)
161 {
162 HILOGI("called");
163 PurgeableMemManager::GetInstance().AddSubscriber(subscriber);
164 return 0;
165 }
166
UnsubscribeAppState(const sptr<IAppStateSubscriber> & subscriber)167 int32_t MemMgrService::UnsubscribeAppState(const sptr<IAppStateSubscriber> &subscriber)
168 {
169 HILOGI("called");
170 PurgeableMemManager::GetInstance().RemoveSubscriber(subscriber);
171 return 0;
172 }
173
GetAvailableMemory(int32_t & memSize)174 int32_t MemMgrService::GetAvailableMemory(int32_t &memSize)
175 {
176 HILOGI("called");
177 memSize = KernelInterface::GetInstance().GetCurrentBuffer();
178 if (memSize < 0 || memSize >= MAX_BUFFER_KB) {
179 return -1;
180 }
181 return 0;
182 }
183
GetTotalMemory(int32_t & memSize)184 int32_t MemMgrService::GetTotalMemory(int32_t &memSize)
185 {
186 HILOGI("called");
187 memSize = KernelInterface::GetInstance().GetTotalBuffer();
188 if (memSize < 0 || memSize >= MAX_BUFFER_KB) {
189 return -1;
190 }
191 return 0;
192 }
193 #endif // USE_PURGEABLE_MEMORY
194
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)195 void MemMgrService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
196 {
197 HILOGI("systemAbilityId: %{public}d add", systemAbilityId);
198 MemMgrEventCenter::GetInstance().RetryRegisterEventObserver(systemAbilityId);
199 }
200
OnWindowVisibilityChanged(const std::vector<sptr<MemMgrWindowInfo>> & MemMgrWindowInfo)201 int32_t MemMgrService::OnWindowVisibilityChanged(const std::vector<sptr<MemMgrWindowInfo>> &MemMgrWindowInfo)
202 {
203 HILOGI("called");
204 int32_t callingUid = IPCSkeleton::GetCallingUid();
205 if (callingUid != windowManagerUid_) {
206 HILOGE("OnWindowVisibilityChanged refused for%{public}d", callingUid);
207 return -1;
208 }
209 HILOGI("OnWindowVisibilityChanged called %{public}d", callingUid);
210 WindowVisibilityObserver::GetInstance().UpdateWindowVisibilityPriority(MemMgrWindowInfo);
211 return 0;
212 }
213
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)214 void MemMgrService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
215 {
216 HILOGI("systemAbilityId: %{public}d remove", systemAbilityId);
217 MemMgrEventCenter::GetInstance().RemoveEventObserver(systemAbilityId);
218 }
219
ParseParams(const std::vector<std::string> & params,std::map<std::string,std::vector<std::string>> & keyValuesMapping)220 void ParseParams(const std::vector<std::string> ¶ms,
221 std::map<std::string, std::vector<std::string>> &keyValuesMapping)
222 {
223 std::string tmpKey;
224 std::vector<std::string> tmpValue;
225 for (auto i = 0; i < params.size(); i++) {
226 if (params[i].empty())
227 continue;
228 if (params[i][0] == '-') {
229 if (!tmpKey.empty()) {
230 keyValuesMapping[tmpKey] = tmpValue;
231 tmpValue.clear();
232 }
233 tmpKey = params[i];
234 } else {
235 tmpValue.emplace_back(params[i]);
236 }
237 }
238 if (!tmpKey.empty()) {
239 keyValuesMapping[tmpKey] = tmpValue;
240 }
241
242 HILOGD("keyValuesMapping.size()=%{public}zu\n", keyValuesMapping.size());
243 for (auto &it : keyValuesMapping) {
244 HILOGD("key=%{public}s", it.first.c_str());
245 for (auto i = 0; i < it.second.size(); i++) {
246 HILOGD("value[%{public}d]=%{public}s", i, it.second[i].c_str());
247 }
248 }
249 }
250
Dump(int fd,const std::vector<std::u16string> & args)251 int MemMgrService::Dump(int fd, const std::vector<std::u16string> &args)
252 {
253 HILOGI("called");
254 std::vector<std::string> params;
255 for (auto &arg : args) {
256 params.emplace_back(Str16ToStr8(arg));
257 }
258 std::map<std::string, std::vector<std::string>> keyValuesMapping;
259 ParseParams(params, keyValuesMapping);
260 DispatchDumpCommand(fd, keyValuesMapping);
261 return 0;
262 }
263 } // namespace Memory
264 } // namespace OHOS
265