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_proxy.h"
17
18#include "mem_mgr_constant.h"
19#include "memmgr_log.h"
20#include "parcel.h"
21
22namespace OHOS {
23namespace Memory {
24namespace {
25const std::string TAG = "MemMgrProxy";
26}
27
28int32_t MemMgrProxy::GetBundlePriorityList(BundlePriorityList &bundlePrioList)
29{
30    HILOGE("called");
31    sptr<IRemoteObject> remote = Remote();
32    if (remote == nullptr) {
33        HILOGE("remote is nullptr");
34        return ERR_NULL_OBJECT;
35    }
36    MessageParcel data;
37    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
38        HILOGE("write interface token failed");
39        return ERR_FLATTEN_OBJECT;
40    }
41    if (!data.WriteParcelable(&bundlePrioList)) {
42        HILOGE("write bundlePrioList failed");
43        return ERR_FLATTEN_OBJECT;
44    }
45    MessageParcel reply;
46    MessageOption option;
47    int32_t error = remote->SendRequest(
48        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_BUNDLE_PRIORITY_LIST), data, reply, option);
49    if (error != ERR_NONE) {
50        HILOGE("transact failed, error: %{public}d", error);
51        return error;
52    }
53    std::shared_ptr<BundlePriorityList> list
54        = std::shared_ptr<BundlePriorityList>(reply.ReadParcelable<BundlePriorityList>());
55    if (list == nullptr) {
56        return -1;
57    }
58    bundlePrioList = *list;
59    return ERR_OK;
60}
61
62int32_t MemMgrProxy::NotifyDistDevStatus(int32_t pid, int32_t uid, const std::string &name, bool connected)
63{
64    HILOGI("called, pid=%{public}d, uid=%{public}d, name=%{public}s, connected=%{public}d", pid, uid, name.c_str(),
65        connected);
66    sptr<IRemoteObject> remote = Remote();
67    if (remote == nullptr) {
68        HILOGE("remote is nullptr");
69        return ERR_NULL_OBJECT;
70    }
71    MessageParcel data;
72    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
73        HILOGE("write interface token failed");
74        return ERR_FLATTEN_OBJECT;
75    }
76    if (!data.WriteInt32(pid) || !data.WriteInt32(uid) || !data.WriteString(name) || !data.WriteBool(connected)) {
77        HILOGE("write params failed");
78        return ERR_INVALID_DATA;
79    }
80    MessageParcel reply;
81    MessageOption option;
82    int32_t error = remote->SendRequest(
83        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_NOTIFY_DIST_DEV_STATUS), data, reply, option);
84    if (error != ERR_NONE) {
85        HILOGE("transact failed, error: %{public}d", error);
86        return error;
87    }
88    int32_t ret;
89    if (!reply.ReadInt32(ret)) {
90        HILOGE("read result failed");
91        return IPC_PROXY_ERR;
92    }
93    return ret;
94}
95
96int32_t MemMgrProxy::GetKillLevelOfLmkd(int32_t &killLevel)
97{
98    HILOGI("called");
99    sptr<IRemoteObject> remote = Remote();
100    if (remote == nullptr) {
101        HILOGE("remote is nullptr");
102        return ERR_NULL_OBJECT;
103    }
104    MessageParcel data;
105    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
106        HILOGE("write interface token failed");
107        return ERR_FLATTEN_OBJECT;
108    }
109
110    MessageParcel reply;
111    MessageOption option;
112    int32_t error = remote->SendRequest(
113        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_KILL_LEVEL_OF_LMKD), data, reply, option);
114    if (error != ERR_NONE) {
115        HILOGE("transact failed, error: %{public}d", error);
116        return error;
117    }
118
119    int32_t curKillLevel = 0;
120    if (!reply.ReadInt32(curKillLevel)) {
121        HILOGE("read result failed");
122        return IPC_PROXY_ERR;
123    }
124    killLevel = curKillLevel;
125    return ERR_OK;
126}
127
128#ifdef USE_PURGEABLE_MEMORY
129int32_t MemMgrProxy::RegisterActiveApps(int32_t pid, int32_t uid)
130{
131    HILOGI("called, pid=%{public}d, uid=%{public}d", pid, uid);
132    sptr<IRemoteObject> remote = Remote();
133    if (remote == nullptr) {
134        HILOGE("remote is nullptr");
135        return ERR_NULL_OBJECT;
136    }
137    MessageParcel data;
138    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
139        HILOGE("write interface token failed");
140        return ERR_FLATTEN_OBJECT;
141    }
142    if (!data.WriteInt32(pid) || !data.WriteInt32(uid)) {
143        HILOGE("write params failed");
144        return ERR_INVALID_DATA;
145    }
146    MessageParcel reply;
147    MessageOption option;
148    int32_t error = remote->SendRequest(
149        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_REGISTER_ACTIVE_APPS), data, reply, option);
150    if (error != ERR_NONE) {
151        HILOGE("transact failed, error: %{public}d", error);
152        return error;
153    }
154    int32_t ret;
155    if (!reply.ReadInt32(ret)) {
156        HILOGE("read result failed");
157        return IPC_PROXY_ERR;
158    }
159    return ret;
160}
161
162int32_t MemMgrProxy::DeregisterActiveApps(int32_t pid, int32_t uid)
163{
164    HILOGI("called, pid=%{public}d, uid=%{public}d", pid, uid);
165    sptr<IRemoteObject> remote = Remote();
166    if (remote == nullptr) {
167        HILOGE("remote is nullptr");
168        return ERR_NULL_OBJECT;
169    }
170    MessageParcel data;
171    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
172        HILOGE("write interface token failed");
173        return ERR_FLATTEN_OBJECT;
174    }
175    if (!data.WriteInt32(pid) || !data.WriteInt32(uid)) {
176        HILOGE("write params failed");
177        return ERR_INVALID_DATA;
178    }
179    MessageParcel reply;
180    MessageOption option;
181    int32_t error = remote->SendRequest(
182        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_DEREGISTER_ACTIVE_APPS), data, reply, option);
183    if (error != ERR_NONE) {
184        HILOGE("transact failed, error: %{public}d", error);
185        return error;
186    }
187    int32_t ret;
188    if (!reply.ReadInt32(ret)) {
189        HILOGE("read result failed");
190        return IPC_PROXY_ERR;
191    }
192    return ret;
193}
194
195int32_t MemMgrProxy::SubscribeAppState(const sptr<IAppStateSubscriber> &subscriber)
196{
197    HILOGI("called");
198    if (subscriber == nullptr) {
199        HILOGE("subscriber is null");
200        return ERR_NULL_OBJECT;
201    }
202    sptr<IRemoteObject> remote = Remote();
203    if (remote == nullptr) {
204        HILOGE("remote is nullptr");
205        return ERR_NULL_OBJECT;
206    }
207    MessageParcel data;
208    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
209        HILOGE("write interface token failed");
210        return ERR_FLATTEN_OBJECT;
211    }
212    if (!data.WriteRemoteObject(subscriber->AsObject())) {
213        HILOGE("write subscriber failed");
214        return ERR_INVALID_DATA;
215    }
216    MessageParcel reply;
217    MessageOption option;
218    int32_t error = remote->SendRequest(
219        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_SUBSCRIBE_APP_STATE), data, reply, option);
220    if (error != ERR_NONE) {
221        HILOGE("transact failed, error: %{public}d", error);
222        return error;
223    }
224    int32_t ret;
225    if (!reply.ReadInt32(ret)) {
226        HILOGE("read result failed");
227        return IPC_PROXY_ERR;
228    }
229    return ret;
230}
231
232int32_t MemMgrProxy::UnsubscribeAppState(const sptr<IAppStateSubscriber> &subscriber)
233{
234    HILOGI("called");
235    if (subscriber == nullptr) {
236        HILOGE("subscriber is null");
237        return ERR_NULL_OBJECT;
238    }
239    sptr<IRemoteObject> remote = Remote();
240    if (remote == nullptr) {
241        HILOGE("remote is nullptr");
242        return ERR_NULL_OBJECT;
243    }
244    MessageParcel data;
245    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
246        HILOGE("write interface token failed");
247        return ERR_FLATTEN_OBJECT;
248    }
249    if (!data.WriteRemoteObject(subscriber->AsObject())) {
250        HILOGE("write subscriber failed");
251        return ERR_INVALID_DATA;
252    }
253    MessageParcel reply;
254    MessageOption option;
255    int32_t error = remote->SendRequest(
256        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_UNSUBSCRIBE_APP_STATE), data, reply, option);
257    if (error != ERR_NONE) {
258        HILOGE("transact failed, error: %{public}d", error);
259        return error;
260    }
261    int32_t ret;
262    if (!reply.ReadInt32(ret)) {
263        HILOGE("read result failed");
264        return IPC_PROXY_ERR;
265    }
266    return ret;
267}
268
269int32_t MemMgrProxy::GetAvailableMemory(int32_t &memSize)
270{
271    HILOGI("called");
272    sptr<IRemoteObject> remote = Remote();
273    if (remote == nullptr) {
274        HILOGE("remote is nullptr");
275        return ERR_NULL_OBJECT;
276    }
277    MessageParcel data;
278    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
279        HILOGE("write interface token failed");
280        return ERR_FLATTEN_OBJECT;
281    }
282    MessageParcel reply;
283    MessageOption option;
284    int32_t error = remote->SendRequest(
285        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_AVAILABLE_MEMORY), data, reply, option);
286    if (error != ERR_NONE) {
287        HILOGE("transact failed, error: %{public}d", error);
288        return error;
289    }
290    if (!reply.ReadInt32(memSize)) {
291        HILOGE("read result failed");
292        return IPC_PROXY_ERR;
293    }
294    return ERR_OK;
295}
296
297int32_t MemMgrProxy::GetTotalMemory(int32_t &memSize)
298{
299    HILOGI("called");
300    sptr<IRemoteObject> remote = Remote();
301    if (remote == nullptr) {
302        HILOGE("remote is nullptr");
303        return ERR_NULL_OBJECT;
304    }
305    MessageParcel data;
306    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
307        HILOGE("write interface token failed");
308        return ERR_FLATTEN_OBJECT;
309    }
310    MessageParcel reply;
311    MessageOption option;
312    int32_t error = remote->SendRequest(
313        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_TOTAL_MEMORY), data, reply, option);
314    if (error != ERR_NONE) {
315        HILOGE("transact failed, error: %{public}d", error);
316        return error;
317    }
318    if (!reply.ReadInt32(memSize)) {
319        HILOGE("read result failed");
320        return IPC_PROXY_ERR;
321    }
322    return ERR_OK;
323}
324#endif // USE_PURGEABLE_MEMORY
325
326int32_t MemMgrProxy::OnWindowVisibilityChanged(const std::vector<sptr<MemMgrWindowInfo>> &MemMgrWindowInfo)
327{
328    HILOGD("called");
329    sptr<IRemoteObject> remote = Remote();
330    if (remote == nullptr) {
331        HILOGE("remote is nullptr");
332        return ERR_NULL_OBJECT;
333    }
334    MessageParcel data;
335    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
336        HILOGE("write interface token failed");
337        return ERR_FLATTEN_OBJECT;
338    }
339    if (!data.WriteUint32(static_cast<uint32_t>(MemMgrWindowInfo.size()))) {
340        HILOGE("write MemMgrWindowInfo size failed");
341        return ERR_INVALID_DATA;
342    }
343    for (auto &info : MemMgrWindowInfo) {
344        if (!data.WriteParcelable(info)) {
345            HILOGE("write MemMgrWindowInfo failed");
346            return ERR_INVALID_DATA;
347        }
348    }
349    MessageParcel reply;
350    MessageOption option;
351    int32_t error = remote->SendRequest(
352        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_ON_WINDOW_VISIBILITY_CHANGED), data, reply, option);
353    if (error != ERR_NONE) {
354        HILOGE("transact failed, error: %{public}d", error);
355        return error;
356    }
357    int32_t ret;
358    if (!reply.ReadInt32(ret)) {
359        HILOGE("read result failed");
360        return IPC_PROXY_ERR;
361    }
362    return ret;
363}
364
365int32_t MemMgrProxy::GetReclaimPriorityByPid(int32_t pid, int32_t &priority)
366{
367    HILOGD("called");
368    sptr<IRemoteObject> remote = Remote();
369    if (remote == nullptr) {
370        HILOGE("remote is nullptr");
371        return ERR_NULL_OBJECT;
372    }
373    MessageParcel data;
374    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
375        HILOGE("write interface token failed");
376        return ERR_FLATTEN_OBJECT;
377    }
378    if (!data.WriteInt32(pid)) {
379        HILOGE("write pid failed");
380        return ERR_INVALID_DATA;
381    }
382    MessageParcel reply;
383    MessageOption option;
384    int32_t error = remote->SendRequest(
385        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_GET_PRIORITY_BY_PID), data, reply, option);
386    if (error != ERR_NONE) {
387        HILOGE("transact failed, error: %{public}d", error);
388        return error;
389    }
390
391    int32_t curPriority = RECLAIM_PRIORITY_UNKNOWN + 1;
392    if (!reply.ReadInt32(curPriority)) {
393        HILOGE("read result failed");
394        return IPC_PROXY_ERR;
395    }
396    priority = curPriority;
397    return ERR_OK;
398}
399
400int32_t MemMgrProxy::NotifyProcessStateChangedSync(const MemMgrProcessStateInfo &processStateInfo)
401{
402    HILOGD("called");
403    sptr<IRemoteObject> remote = Remote();
404    if (remote == nullptr) {
405        HILOGE("remote is nullptr");
406        return ERR_NULL_OBJECT;
407    }
408    MessageParcel data;
409    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
410        HILOGE("write interface token failed");
411        return ERR_FLATTEN_OBJECT;
412    }
413    if (!data.WriteParcelable(&processStateInfo)) {
414        HILOGE("write data failed");
415        return ERR_INVALID_DATA;
416    }
417    MessageParcel reply;
418    MessageOption option;
419    int32_t error = remote->SendRequest(
420        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_NOTIFY_PROCESS_STATE_CHANGED_SYNC), data, reply, option);
421    if (error != ERR_NONE) {
422        HILOGE("transact failed, error: %{public}d", error);
423        return error;
424    }
425    int32_t ret;
426    if (!reply.ReadInt32(ret)) {
427        HILOGE("read result failed");
428        return IPC_PROXY_ERR;
429    }
430    return ret;
431}
432
433int32_t MemMgrProxy::NotifyProcessStateChangedAsync(const MemMgrProcessStateInfo &processStateInfo)
434{
435    HILOGD("called");
436    sptr<IRemoteObject> remote = Remote();
437    if (remote == nullptr) {
438        HILOGE("remote is nullptr");
439        return ERR_NULL_OBJECT;
440    }
441    MessageParcel data;
442    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
443        HILOGE("write interface token failed");
444        return ERR_FLATTEN_OBJECT;
445    }
446    if (!data.WriteParcelable(&processStateInfo)) {
447        HILOGE("write data failed");
448        return ERR_INVALID_DATA;
449    }
450    MessageParcel reply;
451    MessageOption option;
452    int32_t error = remote->SendRequest(
453        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_NOTIFY_PROCESS_STATE_CHANGED_ASYNC), data, reply, option);
454    if (error != ERR_NONE) {
455        HILOGE("transact failed, error: %{public}d", error);
456        return error;
457    }
458    int32_t ret;
459    if (!reply.ReadInt32(ret)) {
460        HILOGE("read result failed");
461        return IPC_PROXY_ERR;
462    }
463    return ret;
464}
465
466int32_t MemMgrProxy::NotifyProcessStatus(int32_t pid, int32_t type, int32_t status, int32_t saId)
467{
468    HILOGD("called");
469    sptr<IRemoteObject> remote = Remote();
470    if (remote == nullptr) {
471        HILOGE("remote is nullptr");
472        return ERR_NULL_OBJECT;
473    }
474    MessageParcel data;
475    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
476        HILOGE("write interface token failed");
477        return ERR_FLATTEN_OBJECT;
478    }
479    if (!data.WriteInt32(pid)) {
480        HILOGE("write pid failed");
481        return ERR_INVALID_DATA;
482    }
483    if (!data.WriteInt32(type)) {
484        HILOGE("write type failed");
485        return ERR_INVALID_DATA;
486    }
487    if (!data.WriteInt32(status)) {
488        HILOGE("write status failed");
489        return ERR_INVALID_DATA;
490    }
491    if (!data.WriteInt32(saId)) {
492        HILOGE("write saId failed");
493        return ERR_INVALID_DATA;
494    }
495    MessageParcel reply;
496    MessageOption option;
497    int32_t error = remote->SendRequest(
498        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_NOTIFY_PROCESS_STATUS), data, reply, option);
499    if (error != ERR_NONE) {
500        HILOGE("transact failed, error: %{public}d", error);
501    }
502    return ERR_OK;
503}
504
505int32_t MemMgrProxy::SetCritical(int32_t pid, bool critical, int32_t saId)
506{
507    HILOGD("called");
508    sptr<IRemoteObject> remote = Remote();
509    if (remote == nullptr) {
510        HILOGE("remote is nullptr");
511        return ERR_NULL_OBJECT;
512    }
513    MessageParcel data;
514    if (!data.WriteInterfaceToken(IMemMgr::GetDescriptor())) {
515        HILOGE("write interface token failed");
516        return ERR_FLATTEN_OBJECT;
517    }
518    if (!data.WriteInt32(pid)) {
519        HILOGE("write pid failed");
520        return ERR_INVALID_DATA;
521    }
522    if (!data.WriteBool(critical)) {
523        HILOGE("write critical failed");
524        return ERR_INVALID_DATA;
525    }
526    if (!data.WriteInt32(saId)) {
527        HILOGE("write saId failed");
528        return ERR_INVALID_DATA;
529    }
530    MessageParcel reply;
531    MessageOption option;
532    int32_t error = remote->SendRequest(
533        static_cast<uint32_t>(MemMgrInterfaceCode::MEM_MGR_SET_CRITICAL), data, reply, option);
534    if (error != ERR_NONE) {
535        HILOGE("transact failed, error: %{public}d", error);
536    }
537    return ERR_OK;
538}
539} // namespace Memory
540} // namespace OHOS
541