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 "ipc_skeleton.h"
19 #include "kernel_interface.h"
20 #include "low_memory_killer.h"
21 #include "memmgr_log.h"
22 #include "memmgr_config_manager.h"
23 #include "parcel.h"
24
25 namespace OHOS {
26 namespace Memory {
27 namespace {
28 const std::string TAG = "MemMgrStub";
29 constexpr int MAX_PARCEL_SIZE = 100000;
30 constexpr int CAMERA_SERVICE_UID = 1047;
31 }
32
MemMgrStub()33 MemMgrStub::MemMgrStub()
34 {
35 memberFuncMap_[static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_BUNDLE_PRIORITY_LIST)] =
36 &MemMgrStub::HandleGetBunldePriorityList;
37 memberFuncMap_[static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_NOTIFY_DIST_DEV_STATUS)] =
38 &MemMgrStub::HandleNotifyDistDevStatus;
39 memberFuncMap_[static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_KILL_LEVEL_OF_LMKD)] =
40 &MemMgrStub::HandleGetKillLevelOfLmkd;
41 #ifdef USE_PURGEABLE_MEMORY
42 memberFuncMap_[static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_REGISTER_ACTIVE_APPS)] =
43 &MemMgrStub::HandleRegisterActiveApps;
44 memberFuncMap_[static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_DEREGISTER_ACTIVE_APPS)] =
45 &MemMgrStub::HandleDeregisterActiveApps;
46 memberFuncMap_[static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_SUBSCRIBE_APP_STATE)] =
47 &MemMgrStub::HandleSubscribeAppState;
48 memberFuncMap_[static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_UNSUBSCRIBE_APP_STATE)] =
49 &MemMgrStub::HandleUnsubscribeAppState;
50 memberFuncMap_[static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_AVAILABLE_MEMORY)] =
51 &MemMgrStub::HandleGetAvailableMemory;
52 memberFuncMap_[static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_TOTAL_MEMORY)] =
53 &MemMgrStub::HandleGetTotalMemory;
54 #endif
55 memberFuncMap_[static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_ON_WINDOW_VISIBILITY_CHANGED)] =
56 &MemMgrStub::HandleOnWindowVisibilityChanged;
57 memberFuncMap_[static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_PRIORITY_BY_PID)] =
58 &MemMgrStub::HandleGetReclaimPriorityByPid;
59 }
60
~MemMgrStub()61 MemMgrStub::~MemMgrStub()
62 {
63 memberFuncMap_.clear();
64 }
65
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)66 int MemMgrStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
67 {
68 HILOGI("MemMgrStub::OnReceived, code = %{public}d, flags= %{public}d.", code, option.GetFlags());
69 std::u16string descriptor = MemMgrStub::GetDescriptor();
70 std::u16string remoteDescriptor = data.ReadInterfaceToken();
71 if (descriptor != remoteDescriptor) {
72 HILOGE("local descriptor is not equal to remote");
73 return ERR_INVALID_STATE;
74 }
75
76 auto itFunc = memberFuncMap_.find(code);
77 if (itFunc != memberFuncMap_.end()) {
78 auto memberFunc = itFunc->second;
79 if (memberFunc != nullptr) {
80 return (this->*memberFunc)(data, reply);
81 }
82 }
83 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
84 }
85
HandleGetBunldePriorityList(MessageParcel & data,MessageParcel & reply)86 int32_t MemMgrStub::HandleGetBunldePriorityList(MessageParcel &data, MessageParcel &reply)
87 {
88 HILOGI("called");
89 std::shared_ptr<BundlePriorityList> list
90 = std::shared_ptr<BundlePriorityList>(data.ReadParcelable<BundlePriorityList>());
91
92 if (!list) {
93 HILOGE("BundlePriorityList ReadParcelable failed");
94 return -1;
95 }
96 int32_t ret = GetBundlePriorityList(*list);
97 reply.WriteParcelable(list.get());
98 return ret;
99 }
100
HandleNotifyDistDevStatus(MessageParcel & data,MessageParcel & reply)101 int32_t MemMgrStub::HandleNotifyDistDevStatus(MessageParcel &data, MessageParcel &reply)
102 {
103 HILOGI("called");
104 int32_t pid = 0;
105 int32_t uid = 0;
106 std::string name;
107 bool connected;
108 if (!data.ReadInt32(pid) || !data.ReadInt32(uid) || !data.ReadString(name) || !data.ReadBool(connected)) {
109 HILOGE("read params failed");
110 return IPC_STUB_ERR;
111 }
112 HILOGI("called, pid=%{public}d, uid=%{public}d, name=%{public}s, connected=%{public}d", pid, uid, name.c_str(),
113 connected);
114
115 int32_t ret = NotifyDistDevStatus(pid, uid, name, connected);
116 if (!reply.WriteInt32(ret)) {
117 return IPC_STUB_ERR;
118 }
119 return ret;
120 }
121
HandleGetKillLevelOfLmkd(MessageParcel & data,MessageParcel & reply)122 int32_t MemMgrStub::HandleGetKillLevelOfLmkd(MessageParcel &data, MessageParcel &reply)
123 {
124 HILOGI("called");
125 int32_t killLevel = LowMemoryKiller::GetInstance().GetKillLevel();
126 if (!reply.WriteInt32(killLevel)) {
127 return IPC_STUB_ERR;
128 }
129 return 0;
130 }
131
132 #ifdef USE_PURGEABLE_MEMORY
HandleRegisterActiveApps(MessageParcel & data,MessageParcel & reply)133 int32_t MemMgrStub::HandleRegisterActiveApps(MessageParcel &data, MessageParcel &reply)
134 {
135 HILOGI("called");
136 int32_t pid = 0;
137 int32_t uid = 0;
138 if (!data.ReadInt32(pid) || !data.ReadInt32(uid)) {
139 HILOGE("read params failed");
140 return IPC_STUB_ERR;
141 }
142 HILOGI("called, pid=%{public}d, uid=%{public}d", pid, uid);
143
144 int32_t ret = RegisterActiveApps(pid, uid);
145 if (!reply.WriteInt32(ret)) {
146 return IPC_STUB_ERR;
147 }
148 return ret;
149 }
150
HandleDeregisterActiveApps(MessageParcel & data,MessageParcel & reply)151 int32_t MemMgrStub::HandleDeregisterActiveApps(MessageParcel &data, MessageParcel &reply)
152 {
153 HILOGI("called");
154 int32_t pid = 0;
155 int32_t uid = 0;
156 if (!data.ReadInt32(pid) || !data.ReadInt32(uid)) {
157 HILOGE("read params failed");
158 return IPC_STUB_ERR;
159 }
160 HILOGI("called, pid=%{public}d, uid=%{public}d", pid, uid);
161
162 int32_t ret = DeregisterActiveApps(pid, uid);
163 if (!reply.WriteInt32(ret)) {
164 return IPC_STUB_ERR;
165 }
166 return ret;
167 }
168
HandleSubscribeAppState(MessageParcel & data,MessageParcel & reply)169 int32_t MemMgrStub::HandleSubscribeAppState(MessageParcel &data, MessageParcel &reply)
170 {
171 HILOGI("called");
172 sptr<IRemoteObject> subscriber = data.ReadRemoteObject();
173 if (subscriber == nullptr) {
174 HILOGE("read params failed");
175 return IPC_STUB_ERR;
176 }
177 int32_t ret = SubscribeAppState(iface_cast<IAppStateSubscriber>(subscriber));
178 if (!reply.WriteInt32(ret)) {
179 return IPC_STUB_ERR;
180 }
181 return ret;
182 }
183
HandleUnsubscribeAppState(MessageParcel & data,MessageParcel & reply)184 int32_t MemMgrStub::HandleUnsubscribeAppState(MessageParcel &data, MessageParcel &reply)
185 {
186 HILOGI("called");
187 sptr<IRemoteObject> subscriber = data.ReadRemoteObject();
188 if (subscriber == nullptr) {
189 HILOGE("read params failed");
190 return IPC_STUB_ERR;
191 }
192
193 int32_t ret = UnsubscribeAppState(iface_cast<IAppStateSubscriber>(subscriber));
194 if (!reply.WriteInt32(ret)) {
195 return IPC_STUB_ERR;
196 }
197 return ret;
198 }
199
HandleGetAvailableMemory(MessageParcel & data,MessageParcel & reply)200 int32_t MemMgrStub::HandleGetAvailableMemory(MessageParcel &data, MessageParcel &reply)
201 {
202 HILOGI("called");
203 int32_t memSize = 0;
204 int32_t ret = GetAvailableMemory(memSize);
205 if (!reply.WriteInt32(memSize)) {
206 return IPC_STUB_ERR;
207 }
208 return ret;
209 }
210
HandleGetTotalMemory(MessageParcel & data,MessageParcel & reply)211 int32_t MemMgrStub::HandleGetTotalMemory(MessageParcel &data, MessageParcel &reply)
212 {
213 HILOGI("called");
214 int32_t memSize = 0;
215 int32_t ret = GetTotalMemory(memSize);
216 if (!reply.WriteInt32(memSize)) {
217 return IPC_STUB_ERR;
218 }
219 return ret;
220 }
221 #endif // USE_PURGEABLE_MEMORY
222
HandleOnWindowVisibilityChanged(MessageParcel & data,MessageParcel & reply)223 int32_t MemMgrStub::HandleOnWindowVisibilityChanged(MessageParcel &data, MessageParcel &reply)
224 {
225 HILOGD("called");
226 std::vector<sptr<MemMgrWindowInfo>> infos;
227 uint32_t len = data.ReadUint32();
228 if (len < 0 || len > MAX_PARCEL_SIZE) {
229 return IPC_STUB_ERR;
230 }
231
232 size_t readAbleSize = data.GetReadableBytes();
233 size_t size = static_cast<size_t>(len);
234 if ((size > readAbleSize) || (size > infos.max_size())) {
235 return IPC_STUB_ERR;
236 }
237 infos.resize(size);
238 if (infos.size() < size) {
239 return IPC_STUB_ERR;
240 }
241 size_t minDesireCapacity = sizeof(int32_t);
242 for (size_t i = 0; i < size; i++) {
243 readAbleSize = data.GetReadableBytes();
244 if (minDesireCapacity > readAbleSize) {
245 return IPC_STUB_ERR;
246 }
247 infos[i] = data.ReadParcelable<MemMgrWindowInfo>();
248 }
249
250 int32_t ret = OnWindowVisibilityChanged(infos);
251 if (!reply.WriteInt32(ret)) {
252 return IPC_STUB_ERR;
253 }
254 return ret;
255 }
256
IsCameraServiceCalling()257 bool MemMgrStub::IsCameraServiceCalling()
258 {
259 int32_t callingUid = IPCSkeleton::GetCallingUid();
260 return callingUid == CAMERA_SERVICE_UID;
261 }
262
HandleGetReclaimPriorityByPid(MessageParcel & data,MessageParcel & reply)263 int32_t MemMgrStub::HandleGetReclaimPriorityByPid(MessageParcel &data, MessageParcel &reply)
264 {
265 HILOGD("called");
266
267 if (!IsCameraServiceCalling()) {
268 HILOGE("calling process has no permission, call failled");
269 return IPC_STUB_ERR;
270 }
271 int32_t pid = data.ReadUint32();
272 int32_t priority = RECLAIM_PRIORITY_UNKNOWN + 1;
273 int32_t ret = GetReclaimPriorityByPid(pid, priority);
274
275 if (!reply.WriteInt32(priority)) {
276 return IPC_STUB_ERR;
277 }
278 return ret;
279 }
280 } // namespace Memory
281 } // namespace OHOS
282