• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "c_remote_object.h"
17 
18 #include <securec.h>
19 #include <string_ex.h>
20 #include "c_parcel_internal.h"
21 #include "c_remote_object_internal.h"
22 #include "log_tags.h"
23 #include "ipc_debug.h"
24 
25 using namespace OHOS;
26 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC, "CRemoteObject" };
27 
RemoteServiceHolderStub(std::u16string & desc,OnRemoteRequestCb callback,const void * userData,OnRemoteObjectDestroyCb destroy,OnRemoteDumpCb dumpCallback)28 RemoteServiceHolderStub::RemoteServiceHolderStub(std::u16string &desc, OnRemoteRequestCb callback,
29     const void *userData, OnRemoteObjectDestroyCb destroy, OnRemoteDumpCb dumpCallback)
30     : IPCObjectStub(desc), callback_(callback), dumpCallback_(dumpCallback),
31       userData_(userData), destroy_(destroy)
32 {
33 }
34 
~RemoteServiceHolderStub()35 RemoteServiceHolderStub::~RemoteServiceHolderStub()
36 {
37     if (destroy_) {
38         destroy_(userData_);
39     }
40     destroy_ = nullptr;
41 }
42 
OnRemoteRequest(uint32_t code,OHOS::MessageParcel & data,OHOS::MessageParcel & reply,OHOS::MessageOption & option)43 int RemoteServiceHolderStub::OnRemoteRequest(uint32_t code, OHOS::MessageParcel &data,
44     OHOS::MessageParcel &reply, OHOS::MessageOption &option)
45 {
46     (void)option;
47     if (callback_ == nullptr) {
48         ZLOGE(LOG_LABEL, "%{public}s: callback is null for code: %u\n", __func__, code);
49         return -1;
50     }
51     CParcel parcelData(&data);
52     CParcel parcelReply(&reply);
53     return callback_(userData_, code, &parcelData, &parcelReply);
54 }
55 
OnRemoteDump(uint32_t code,OHOS::MessageParcel & data,OHOS::MessageParcel & reply,OHOS::MessageOption & option)56 int RemoteServiceHolderStub::OnRemoteDump(uint32_t code, OHOS::MessageParcel &data,
57     OHOS::MessageParcel &reply, OHOS::MessageOption &option)
58 {
59     (void)option;
60     (void)reply;
61     if (dumpCallback_ == nullptr) {
62         ZLOGE(LOG_LABEL, "%{public}s: dumpCallback_ is null for code: %u\n", __func__, code);
63         return -1;
64     }
65     CParcel parcelData(&data);
66     return dumpCallback_(userData_, &parcelData);
67 }
68 
69 
CDeathRecipient(OnDeathRecipientCb onDeathRecipient,OnDeathRecipientDestroyCb onDestroy,const void * userData)70 CDeathRecipient::CDeathRecipient(OnDeathRecipientCb onDeathRecipient,
71     OnDeathRecipientDestroyCb onDestroy, const void *userData)
72     : userData_(userData), onDeathRecipient_(onDeathRecipient), onDestroy_(onDestroy)
73 {
74 }
75 
~CDeathRecipient()76 CDeathRecipient::~CDeathRecipient()
77 {
78     if (onDestroy_ != nullptr) {
79         onDestroy_(userData_);
80     }
81     onDestroy_ = nullptr;
82     onDeathRecipient_ = nullptr;
83 }
84 
OnRemoteDied(const wptr<IRemoteObject> & object)85 void CDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
86 {
87     (void)object;
88     if (onDeathRecipient_ != nullptr) {
89         onDeathRecipient_(userData_);
90     }
91 }
92 
IsValidRemoteObject(const CRemoteObject * object,const char * promot)93 bool IsValidRemoteObject(const CRemoteObject *object, const char *promot)
94 {
95     if (object == nullptr) {
96         ZLOGE(LOG_LABEL, "[%{public}s] RemoteObject is null\n", promot);
97         return false;
98     }
99     if (object->remote_ == nullptr) {
100         ZLOGE(LOG_LABEL, "[%{public}s]wrapper RemoteObject is null\n", promot);
101         return false;
102     }
103     return true;
104 }
105 
CreateRemoteStub(const char * desc,OnRemoteRequestCb callback,OnRemoteObjectDestroyCb destroy,const void * userData,OnRemoteDumpCb dumpCallback)106 CRemoteObject *CreateRemoteStub(const char *desc, OnRemoteRequestCb callback,
107     OnRemoteObjectDestroyCb destroy, const void *userData, OnRemoteDumpCb dumpCallback)
108 {
109     if (desc == nullptr || callback == nullptr || destroy == nullptr) {
110         return nullptr;
111     }
112     auto holder = new (std::nothrow) CRemoteObjectHolder();
113     if (holder == nullptr) {
114         ZLOGE(LOG_LABEL, "%{public}s: new CRemoteObjectHolder failed\n", __func__);
115         return nullptr;
116     }
117     std::u16string descriptor = Str8ToStr16(std::string(desc));
118     holder->remote_ = new (std::nothrow) RemoteServiceHolderStub(
119         descriptor, callback, userData, destroy, dumpCallback);
120     if (holder->remote_ == nullptr) {
121         ZLOGE(LOG_LABEL, "%{public}s: new RemoteServiceHolderStub failed\n", __func__);
122         delete holder;
123         return nullptr;
124     }
125     holder->IncStrongRef(nullptr);
126     return holder;
127 }
128 
RemoteObjectIncStrongRef(CRemoteObject * object)129 void RemoteObjectIncStrongRef(CRemoteObject *object)
130 {
131     if (object == nullptr) {
132         ZLOGE(LOG_LABEL, "%{public}s: unexpected CRemoteObject\n", __func__);
133         return;
134     }
135     object->IncStrongRef(nullptr);
136 }
137 
RemoteObjectDecStrongRef(CRemoteObject * object)138 void RemoteObjectDecStrongRef(CRemoteObject *object)
139 {
140     if (object == nullptr) {
141         ZLOGE(LOG_LABEL, "%{public}s: unexpected CRemoteObject\n", __func__);
142         return;
143     }
144     object->DecStrongRef(nullptr);
145 }
146 
RemoteObjectLessThan(const CRemoteObject * lhs,const CRemoteObject * rhs)147 bool RemoteObjectLessThan(const CRemoteObject *lhs, const CRemoteObject *rhs)
148 {
149     if (!IsValidRemoteObject(lhs, __func__) || !IsValidRemoteObject(rhs, __func__)) {
150         return false;
151     }
152     return lhs->remote_.GetRefPtr() < rhs->remote_.GetRefPtr();
153 }
154 
RemoteObjectSendRequest(const CRemoteObject * object,uint32_t code,const CParcel * data,CParcel * reply,bool isAsync)155 int RemoteObjectSendRequest(const CRemoteObject *object, uint32_t code,
156     const CParcel *data, CParcel *reply, bool isAsync)
157 {
158     if (!IsValidRemoteObject(object, __func__) || data == nullptr || reply == nullptr) {
159         ZLOGE(LOG_LABEL, "%{public}s: object and data must be not null\n", __func__);
160         return -EINVAL;
161     }
162     MessageOption option(isAsync ? MessageOption::TF_ASYNC : MessageOption::TF_SYNC);
163     return object->remote_->SendRequest(code, *data->parcel_, *reply->parcel_, option);
164 }
165 
CreateDeathRecipient(OnDeathRecipientCb onDeathRecipient,OnDeathRecipientDestroyCb onDestroy,const void * userData)166 CDeathRecipient *CreateDeathRecipient(OnDeathRecipientCb onDeathRecipient,
167     OnDeathRecipientDestroyCb onDestroy, const void *userData)
168 {
169     if (onDeathRecipient == nullptr || onDestroy == nullptr || userData == nullptr) {
170         ZLOGE(LOG_LABEL, "%{public}s: args must not be null\n", __func__);
171         return nullptr;
172     }
173     CDeathRecipient *recipient = new (std::nothrow) CDeathRecipient(onDeathRecipient,
174         onDestroy, userData);
175     if (recipient == nullptr) {
176         ZLOGE(LOG_LABEL, "%{public}s: create CDeathRecipient object failed\n", __func__);
177         return nullptr;
178     }
179     recipient->IncStrongRef(nullptr);
180     return recipient;
181 }
182 
DeathRecipientIncStrongRef(CDeathRecipient * recipient)183 void DeathRecipientIncStrongRef(CDeathRecipient *recipient)
184 {
185     if (recipient == nullptr) {
186         ZLOGE(LOG_LABEL, "%{public}s: unexpected CDeathRecipient\n", __func__);
187         return;
188     }
189     recipient->IncStrongRef(nullptr);
190 }
191 
DeathRecipientDecStrongRef(CDeathRecipient * recipient)192 void DeathRecipientDecStrongRef(CDeathRecipient *recipient)
193 {
194     if (recipient == nullptr) {
195         ZLOGE(LOG_LABEL, "%{public}s: unexpected CDeathRecipient\n", __func__);
196         return;
197     }
198     recipient->DecStrongRef(nullptr);
199 }
200 
AddDeathRecipient(CRemoteObject * object,CDeathRecipient * recipient)201 bool AddDeathRecipient(CRemoteObject *object, CDeathRecipient *recipient)
202 {
203     if (!IsValidRemoteObject(object, __func__) || recipient == nullptr) {
204         return false;
205     }
206     if (!object->remote_->IsProxyObject()) {
207         ZLOGE(LOG_LABEL, "%{public}s: this is not a proxy object", __func__);
208         return false;
209     }
210     sptr<IRemoteObject::DeathRecipient> callback(recipient);
211     return object->remote_->AddDeathRecipient(callback);
212 }
213 
RemoveDeathRecipient(CRemoteObject * object,CDeathRecipient * recipient)214 bool RemoveDeathRecipient(CRemoteObject *object, CDeathRecipient *recipient)
215 {
216     if (!IsValidRemoteObject(object, __func__) || recipient == nullptr) {
217         ZLOGE(LOG_LABEL, "%{public}s: recipient is null\n", __func__);
218         return false;
219     }
220     if (!object->remote_->IsProxyObject()) {
221         ZLOGE(LOG_LABEL, "%{public}s: this is not a proxy object\n", __func__);
222         return false;
223     };
224     sptr<IRemoteObject::DeathRecipient> callback(recipient);
225     return object->remote_->RemoveDeathRecipient(callback);
226 }
227 
228 
IsProxyObject(CRemoteObject * object)229 bool IsProxyObject(CRemoteObject *object)
230 {
231     if (!IsValidRemoteObject(object, __func__)) {
232         ZLOGE(LOG_LABEL, "%{public}s: recipient is null\n", __func__);
233         return false;
234     }
235     return object->remote_->IsProxyObject();
236 }
237 
Dump(CRemoteObject * object,int fd,CParcel * parcel)238 int Dump(CRemoteObject *object, int fd, CParcel *parcel)
239 {
240     if (!IsValidRemoteObject(object, __func__) || parcel == nullptr) {
241         ZLOGE(LOG_LABEL, "%{public}s: recipient is null\n", __func__);
242         return -1;
243     }
244     if (fd < 0) {
245         ZLOGE(LOG_LABEL, "%{public}s: fd is valid\n", __func__);
246         return -1;
247     }
248     std::vector<std::u16string> string16Vector;
249     parcel->parcel_->ReadString16Vector(&string16Vector);
250 
251     return object->remote_->Dump(fd, string16Vector);
252 }
253 
IsObjectDead(CRemoteObject * object)254 bool IsObjectDead(CRemoteObject *object)
255 {
256     if (!IsValidRemoteObject(object, __func__)) {
257         ZLOGE(LOG_LABEL, "%{public}s: recipient is null\n", __func__);
258         return false;
259     }
260     if (!IsProxyObject(object)) {
261         return false;
262     }
263     return object->remote_->IsObjectDead();
264 }
265 
GetInterfaceDescriptor(CRemoteObject * object,void * value,On16BytesAllocator allocator)266 bool GetInterfaceDescriptor(CRemoteObject *object, void *value, On16BytesAllocator allocator)
267 {
268     if (!IsValidRemoteObject(object, __func__)) {
269         ZLOGE(LOG_LABEL, "%{public}s: recipient is null\n", __func__);
270         return false;
271     }
272     if (!IsProxyObject(object)) {
273         return false;
274     }
275 
276     std::u16string str(object->remote_->GetInterfaceDescriptor());
277     uint16_t *buffer = nullptr;
278     bool isSuccess = allocator(value, &buffer, str.length());
279     if (!isSuccess) {
280         ZLOGE(LOG_LABEL, "%{public}s: allocate string buffer is null\n", __func__);
281         return false;
282     }
283 
284     int32_t size = sizeof(char16_t) * str.length();
285     if (str.length() > 0 && memcpy_s(buffer, size, str.data(), size) != EOK) {
286         ZLOGE(LOG_LABEL, "%{public}s: memcpy string failed\n", __func__);
287         return false;
288     }
289     return true;
290 }