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_stub.h" 17 18#include "accesstoken_kit.h" 19#include "ipc_skeleton.h" 20#include "kernel_interface.h" 21#include "low_memory_killer.h" 22#include "memmgr_log.h" 23#include "memmgr_config_manager.h" 24#include "parcel.h" 25 26namespace OHOS { 27namespace Memory { 28namespace { 29 const std::string TAG = "MemMgrStub"; 30 constexpr int MAX_PARCEL_SIZE = 100000; 31 constexpr int CAMERA_SERVICE_UID = 1047; 32 constexpr int FOUNDATION_UID = 5523; 33} 34 35MemMgrStub::MemMgrStub() 36{ 37} 38 39MemMgrStub::~MemMgrStub() 40{ 41} 42 43int MemMgrStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) 44{ 45 HILOGI("MemMgrStub::OnReceived, code = %{public}d, flags= %{public}d.", code, option.GetFlags()); 46 std::u16string descriptor = MemMgrStub::GetDescriptor(); 47 std::u16string remoteDescriptor = data.ReadInterfaceToken(); 48 if (descriptor != remoteDescriptor) { 49 HILOGE("local descriptor is not equal to remote"); 50 return ERR_INVALID_STATE; 51 } 52 53 return OnRemoteRequestInner(code, data, reply, option); 54} 55 56int32_t MemMgrStub::OnRemoteRequestInner(uint32_t code, 57 MessageParcel &data, MessageParcel &reply, MessageOption &option) 58{ 59 switch (code) { 60 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_BUNDLE_PRIORITY_LIST): 61 return HandleGetBunldePriorityList(data, reply); 62 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_NOTIFY_DIST_DEV_STATUS): 63 return HandleNotifyDistDevStatus(data, reply); 64 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_KILL_LEVEL_OF_LMKD): 65 return HandleGetKillLevelOfLmkd(data, reply); 66#ifdef USE_PURGEABLE_MEMORY 67 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_REGISTER_ACTIVE_APPS): 68 return HandleRegisterActiveApps(data, reply); 69 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_DEREGISTER_ACTIVE_APPS): 70 return HandleDeregisterActiveApps(data, reply); 71 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_SUBSCRIBE_APP_STATE): 72 return HandleSubscribeAppState(data, reply); 73 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_UNSUBSCRIBE_APP_STATE): 74 return HandleUnsubscribeAppState(data, reply); 75 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_AVAILABLE_MEMORY): 76 return HandleGetAvailableMemory(data, reply); 77 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_TOTAL_MEMORY): 78 return HandleGetTotalMemory(data, reply); 79#endif 80 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_ON_WINDOW_VISIBILITY_CHANGED): 81 return HandleOnWindowVisibilityChanged(data, reply); 82 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_PRIORITY_BY_PID): 83 return HandleGetReclaimPriorityByPid(data, reply); 84 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_NOTIFY_PROCESS_STATE_CHANGED_SYNC): 85 return HandleNotifyProcessStateChangedSync(data, reply); 86 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_NOTIFY_PROCESS_STATE_CHANGED_ASYNC): 87 return HandleNotifyProcessStateChangedAsync(data, reply); 88 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_NOTIFY_PROCESS_STATUS): 89 return HandleNotifyProcessStatus(data, reply); 90 case static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_SET_CRITICAL): 91 return HandleSetCritical(data, reply); 92 default: 93 return IPCObjectStub::OnRemoteRequest(code, data, reply, option); 94 } 95} 96 97int32_t MemMgrStub::HandleGetBunldePriorityList(MessageParcel &data, MessageParcel &reply) 98{ 99 HILOGI("called"); 100 std::shared_ptr<BundlePriorityList> list 101 = std::shared_ptr<BundlePriorityList>(data.ReadParcelable<BundlePriorityList>()); 102 103 if (!list) { 104 HILOGE("BundlePriorityList ReadParcelable failed"); 105 return -1; 106 } 107 int32_t ret = GetBundlePriorityList(*list); 108 reply.WriteParcelable(list.get()); 109 return ret; 110} 111 112int32_t MemMgrStub::HandleNotifyDistDevStatus(MessageParcel &data, MessageParcel &reply) 113{ 114 HILOGI("called"); 115 int32_t pid = 0; 116 int32_t uid = 0; 117 std::string name; 118 bool connected; 119 if (!data.ReadInt32(pid) || !data.ReadInt32(uid) || !data.ReadString(name) || !data.ReadBool(connected)) { 120 HILOGE("read params failed"); 121 return IPC_STUB_ERR; 122 } 123 HILOGI("called, pid=%{public}d, uid=%{public}d, name=%{public}s, connected=%{public}d", pid, uid, name.c_str(), 124 connected); 125 126 int32_t ret = NotifyDistDevStatus(pid, uid, name, connected); 127 if (!reply.WriteInt32(ret)) { 128 return IPC_STUB_ERR; 129 } 130 return ret; 131} 132 133int32_t MemMgrStub::HandleGetKillLevelOfLmkd(MessageParcel &data, MessageParcel &reply) 134{ 135 HILOGI("called"); 136 int32_t killLevel = LowMemoryKiller::GetInstance().GetKillLevel(); 137 if (!reply.WriteInt32(killLevel)) { 138 return IPC_STUB_ERR; 139 } 140 return 0; 141} 142 143#ifdef USE_PURGEABLE_MEMORY 144int32_t MemMgrStub::HandleRegisterActiveApps(MessageParcel &data, MessageParcel &reply) 145{ 146 HILOGI("called"); 147 int32_t pid = 0; 148 int32_t uid = 0; 149 if (!data.ReadInt32(pid) || !data.ReadInt32(uid)) { 150 HILOGE("read params failed"); 151 return IPC_STUB_ERR; 152 } 153 HILOGI("called, pid=%{public}d, uid=%{public}d", pid, uid); 154 155 int32_t ret = RegisterActiveApps(pid, uid); 156 if (!reply.WriteInt32(ret)) { 157 return IPC_STUB_ERR; 158 } 159 return ret; 160} 161 162int32_t MemMgrStub::HandleDeregisterActiveApps(MessageParcel &data, MessageParcel &reply) 163{ 164 HILOGI("called"); 165 int32_t pid = 0; 166 int32_t uid = 0; 167 if (!data.ReadInt32(pid) || !data.ReadInt32(uid)) { 168 HILOGE("read params failed"); 169 return IPC_STUB_ERR; 170 } 171 HILOGI("called, pid=%{public}d, uid=%{public}d", pid, uid); 172 173 int32_t ret = DeregisterActiveApps(pid, uid); 174 if (!reply.WriteInt32(ret)) { 175 return IPC_STUB_ERR; 176 } 177 return ret; 178} 179 180int32_t MemMgrStub::HandleSubscribeAppState(MessageParcel &data, MessageParcel &reply) 181{ 182 HILOGI("called"); 183 sptr<IRemoteObject> subscriber = data.ReadRemoteObject(); 184 if (subscriber == nullptr) { 185 HILOGE("read params failed"); 186 return IPC_STUB_ERR; 187 } 188 int32_t ret = SubscribeAppState(iface_cast<IAppStateSubscriber>(subscriber)); 189 if (!reply.WriteInt32(ret)) { 190 return IPC_STUB_ERR; 191 } 192 return ret; 193} 194 195int32_t MemMgrStub::HandleUnsubscribeAppState(MessageParcel &data, MessageParcel &reply) 196{ 197 HILOGI("called"); 198 sptr<IRemoteObject> subscriber = data.ReadRemoteObject(); 199 if (subscriber == nullptr) { 200 HILOGE("read params failed"); 201 return IPC_STUB_ERR; 202 } 203 204 int32_t ret = UnsubscribeAppState(iface_cast<IAppStateSubscriber>(subscriber)); 205 if (!reply.WriteInt32(ret)) { 206 return IPC_STUB_ERR; 207 } 208 return ret; 209} 210 211int32_t MemMgrStub::HandleGetAvailableMemory(MessageParcel &data, MessageParcel &reply) 212{ 213 HILOGI("called"); 214 int32_t memSize = 0; 215 int32_t ret = GetAvailableMemory(memSize); 216 if (!reply.WriteInt32(memSize)) { 217 return IPC_STUB_ERR; 218 } 219 return ret; 220} 221 222int32_t MemMgrStub::HandleGetTotalMemory(MessageParcel &data, MessageParcel &reply) 223{ 224 HILOGI("called"); 225 int32_t memSize = 0; 226 int32_t ret = GetTotalMemory(memSize); 227 if (!reply.WriteInt32(memSize)) { 228 return IPC_STUB_ERR; 229 } 230 return ret; 231} 232#endif // USE_PURGEABLE_MEMORY 233 234int32_t MemMgrStub::HandleOnWindowVisibilityChanged(MessageParcel &data, MessageParcel &reply) 235{ 236 HILOGD("called"); 237 std::vector<sptr<MemMgrWindowInfo>> infos; 238 uint32_t len = data.ReadUint32(); 239 if (len < 0 || len > MAX_PARCEL_SIZE) { 240 return IPC_STUB_ERR; 241 } 242 243 size_t readAbleSize = data.GetReadableBytes(); 244 size_t size = static_cast<size_t>(len); 245 if ((size > readAbleSize) || (size > infos.max_size())) { 246 return IPC_STUB_ERR; 247 } 248 infos.resize(size); 249 if (infos.size() < size) { 250 return IPC_STUB_ERR; 251 } 252 size_t minDesireCapacity = sizeof(int32_t); 253 for (size_t i = 0; i < size; i++) { 254 readAbleSize = data.GetReadableBytes(); 255 if (minDesireCapacity > readAbleSize) { 256 return IPC_STUB_ERR; 257 } 258 infos[i] = data.ReadParcelable<MemMgrWindowInfo>(); 259 } 260 261 int32_t ret = OnWindowVisibilityChanged(infos); 262 if (!reply.WriteInt32(ret)) { 263 return IPC_STUB_ERR; 264 } 265 return ret; 266} 267 268bool MemMgrStub::IsCameraServiceCalling() 269{ 270 int32_t callingUid = IPCSkeleton::GetCallingUid(); 271 return callingUid == CAMERA_SERVICE_UID; 272} 273 274int32_t MemMgrStub::HandleGetReclaimPriorityByPid(MessageParcel &data, MessageParcel &reply) 275{ 276 HILOGD("called"); 277 278 if (!IsCameraServiceCalling()) { 279 HILOGE("calling process has no permission, call failled"); 280 return IPC_STUB_ERR; 281 } 282 int32_t pid = data.ReadUint32(); 283 int32_t priority = RECLAIM_PRIORITY_UNKNOWN + 1; 284 int32_t ret = GetReclaimPriorityByPid(pid, priority); 285 286 if (!reply.WriteInt32(priority)) { 287 return IPC_STUB_ERR; 288 } 289 return ret; 290} 291 292bool MemMgrStub::CheckCallingToken() 293{ 294 Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); 295 auto tokenFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId); 296 if (tokenFlag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE || 297 tokenFlag == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) { 298 return true; 299 } 300 return false; 301} 302 303bool IsFoundationCalling() 304{ 305 return IPCSkeleton::GetCallingUid() == FOUNDATION_UID; 306} 307 308int32_t MemMgrStub::HandleNotifyProcessStateChangedSync(MessageParcel &data, MessageParcel &reply) 309{ 310 HILOGD("called"); 311 312 if (!IsFoundationCalling()) { 313 HILOGE("calling process has no permission, call failed"); 314 return IPC_STUB_ERR; 315 } 316 std::unique_ptr<MemMgrProcessStateInfo> processStateInfo(data.ReadParcelable<MemMgrProcessStateInfo>()); 317 if (processStateInfo == nullptr) { 318 HILOGE("ReadParcelable<MemMgrProcessStateInfo> failed"); 319 return IPC_STUB_ERR; 320 } 321 322 int32_t ret = NotifyProcessStateChangedSync(*processStateInfo); 323 if (!reply.WriteInt32(ret)) { 324 HILOGE("reply write failed"); 325 return IPC_STUB_ERR; 326 } 327 return ret; 328} 329 330int32_t MemMgrStub::HandleNotifyProcessStateChangedAsync(MessageParcel &data, MessageParcel &reply) 331{ 332 HILOGD("called"); 333 334 if (!IsFoundationCalling()) { 335 HILOGE("calling process has no permission, call failed"); 336 return IPC_STUB_ERR; 337 } 338 std::unique_ptr<MemMgrProcessStateInfo> processStateInfo(data.ReadParcelable<MemMgrProcessStateInfo>()); 339 if (processStateInfo == nullptr) { 340 HILOGE("ReadParcelable<MemMgrProcessStateInfo> failed"); 341 return IPC_STUB_ERR; 342 } 343 344 int32_t ret = NotifyProcessStateChangedAsync(*processStateInfo); 345 if (!reply.WriteInt32(ret)) { 346 HILOGE("reply write failed"); 347 return IPC_STUB_ERR; 348 } 349 return ret; 350} 351int32_t MemMgrStub::HandleNotifyProcessStatus(MessageParcel &data, MessageParcel &reply) 352{ 353 HILOGD("called"); 354 355 if (!CheckCallingToken()) { 356 HILOGE("calling process has no permission, call failed"); 357 return IPC_STUB_ERR; 358 } 359 int32_t pid = 0; 360 int32_t type = 0; 361 int32_t status = 0; 362 int32_t saId = -1; 363 if (!data.ReadInt32(pid) || !data.ReadInt32(type) || !data.ReadInt32(status) || !data.ReadInt32(saId)) { 364 HILOGE("read params failed"); 365 return IPC_STUB_ERR; 366 } 367 368 NotifyProcessStatus(pid, type, status, saId); 369 370 return 0; 371} 372 373int32_t MemMgrStub::HandleSetCritical(MessageParcel &data, MessageParcel &reply) 374{ 375 HILOGD("called"); 376 377 if (!CheckCallingToken()) { 378 HILOGE("calling process has no permission, call failed"); 379 return IPC_STUB_ERR; 380 } 381 int32_t pid = 0; 382 bool critical = false; 383 int32_t saId = -1; 384 if (!data.ReadInt32(pid) || !data.ReadBool(critical) || !data.ReadInt32(saId)) { 385 HILOGE("read params failed"); 386 return IPC_STUB_ERR; 387 } 388 if (IPCSkeleton::GetCallingPid() != pid) { 389 return 0; 390 } 391 392 SetCritical(pid, critical, saId); 393 394 return 0; 395} 396} // namespace Memory 397} // namespace OHOS 398