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 39namespace OHOS { 40namespace Memory { 41namespace { 42const std::string TAG = "MemMgrService"; 43const int32_t ENG_MODE = OHOS::system::GetIntParameter("const.debuggable", 0); 44const int32_t ERR_MEMMGR_PERMISSION_DENIED = -1; 45} 46 47IMPLEMENT_SINGLE_INSTANCE(MemMgrService); 48const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(&MemMgrService::GetInstance()); 49 50MemMgrService::MemMgrService() : SystemAbility(MEMORY_MANAGER_SA_ID, true) 51{ 52} 53 54bool 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 90void 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 112void MemMgrService::OnStop() 113{ 114 HILOGI("called"); 115} 116 117// implements of innerkits list below 118 119int32_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 133int32_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 149int32_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 157int32_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 164int32_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 171int32_t MemMgrService::SubscribeAppState(const sptr<IAppStateSubscriber> &subscriber) 172{ 173 HILOGI("called"); 174 PurgeableMemManager::GetInstance().AddSubscriber(subscriber); 175 return 0; 176} 177 178int32_t MemMgrService::UnsubscribeAppState(const sptr<IAppStateSubscriber> &subscriber) 179{ 180 HILOGI("called"); 181 PurgeableMemManager::GetInstance().RemoveSubscriber(subscriber); 182 return 0; 183} 184 185int32_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 195int32_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 206void MemMgrService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) 207{ 208 HILOGI("systemAbilityId: %{public}d add", systemAbilityId); 209 MemMgrEventCenter::GetInstance().RetryRegisterEventObserver(systemAbilityId); 210} 211 212int32_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 225int32_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 249int32_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 267int32_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 285int32_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 292int32_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 298void MemMgrService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId) 299{ 300 HILOGI("systemAbilityId: %{public}d add", systemAbilityId); 301 MemMgrEventCenter::GetInstance().RemoveEventObserver(systemAbilityId); 302} 303 304void ParseParams(const std::vector<std::string> ¶ms, 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 335bool 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 350int 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