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 }