1 /*
2  * Copyright (C) 2021 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 "dbinder_test_service_skeleton.h"
17 
18 #include <cinttypes>
19 
20 #include "dbinder_log.h"
21 #include "if_system_ability_manager.h"
22 #include "ipc_skeleton.h"
23 #include "ipc_object_proxy.h"
24 #include "iremote_proxy.h"
25 #include "iservice_registry.h"
26 #include "string_ex.h"
27 #include "system_ability_definition.h"
28 
29 namespace OHOS {
30 using namespace OHOS::HiviewDFX;
31 
32 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_TEST, "DBinderTestServiceProxy" };
33 
34 // set wait time for raw data
35 static constexpr int RAW_DATA_TIMEOUT = 300;
36 
DBinderTestServiceProxy(const sptr<IRemoteObject> & impl)37 DBinderTestServiceProxy::DBinderTestServiceProxy(const sptr<IRemoteObject> &impl)
38     : IRemoteProxy<IDBinderTestService>(impl)
39 {}
40 
ReverseInt(int data,int & rep)41 int DBinderTestServiceProxy::ReverseInt(int data, int &rep)
42 {
43     DBINDER_LOGE(LOG_LABEL, "data = %{public}d", data);
44     int error;
45     MessageOption option;
46     MessageParcel dataParcel, replyParcel;
47     if (!dataParcel.WriteInt32(data)) {
48         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
49         return ERR_INVALID_STATE;
50     }
51     error = Remote()->SendRequest(REVERSEINT, dataParcel, replyParcel, option);
52 
53     rep = replyParcel.ReadInt32();
54     DBINDER_LOGE(LOG_LABEL, "rep = %{public}d, error = %{public}d", rep, error);
55     return error;
56 }
57 
GetChildId(uint64_t & rep)58 int DBinderTestServiceProxy::GetChildId(uint64_t &rep)
59 {
60     int error;
61     MessageOption option;
62     MessageParcel dataParcel, replyParcel;
63     error = Remote()->SendRequest(TRANS_TRACE_ID, dataParcel, replyParcel, option);
64 
65     rep = replyParcel.ReadUint64();
66     DBINDER_LOGE(LOG_LABEL, "rep = %{public}" PRIu64 ", error = %{public}d", rep, error);
67     return error;
68 }
69 
TransProxyObject(int data,sptr<IRemoteObject> & transObject,int operation,int & rep,int & withdrawRes)70 int DBinderTestServiceProxy::TransProxyObject(int data, sptr<IRemoteObject> &transObject, int operation, int &rep,
71     int &withdrawRes)
72 {
73     int error;
74     MessageOption option;
75     MessageParcel dataParcel, replyParcel;
76     if (!dataParcel.WriteInt32(data) || !dataParcel.WriteInt32(operation) ||
77         !dataParcel.WriteRemoteObject(transObject)) {
78         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
79         return ERR_INVALID_STATE;
80     }
81     error = Remote()->SendRequest(TRANS_PROXY_OBJECT, dataParcel, replyParcel, option);
82 
83     rep = replyParcel.ReadInt32();
84     withdrawRes = replyParcel.ReadInt32();
85     return error;
86 }
87 
TransProxyObjectRefCount(sptr<IRemoteObject> & transObject,int operation)88 int DBinderTestServiceProxy::TransProxyObjectRefCount(sptr<IRemoteObject> &transObject, int operation)
89 {
90     MessageOption option;
91     MessageParcel data, reply;
92     if (!data.WriteInt32(operation) || !data.WriteRemoteObject(transObject)) {
93         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
94         return ERR_INVALID_STATE;
95     }
96     int error = Remote()->SendRequest(TRANS_PROXY_OBJECT_REFCOUNT, data, reply, option);
97     if (error != ERR_NONE) {
98         DBINDER_LOGE(LOG_LABEL, "fail to send proxy object");
99         return ERR_INVALID_STATE;
100     }
101     return error;
102 }
103 
TransProxyObjectAgain(int data,sptr<IRemoteObject> & transObject,int operation,int & rep,int & withdrawRes)104 int DBinderTestServiceProxy::TransProxyObjectAgain(int data, sptr<IRemoteObject> &transObject, int operation, int &rep,
105     int &withdrawRes)
106 {
107     int error;
108     MessageOption option;
109     MessageParcel dataParcel, replyParcel;
110     if (!dataParcel.WriteInt32(data) || !dataParcel.WriteInt32(operation) ||
111         !dataParcel.WriteRemoteObject(transObject)) {
112         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
113         return ERR_INVALID_STATE;
114     }
115     error = Remote()->SendRequest(TRANS_OBJECT_OVER_DEVICE_OVER_PROCESS, dataParcel, replyParcel, option);
116 
117     rep = replyParcel.ReadInt32();
118     withdrawRes = replyParcel.ReadInt32();
119     return error;
120 }
121 
TransStubObject(int data,sptr<IRemoteObject> & transObject,int & rep,int & stubRep)122 int DBinderTestServiceProxy::TransStubObject(int data, sptr<IRemoteObject> &transObject, int &rep, int &stubRep)
123 {
124     int error;
125     MessageOption option;
126     MessageParcel dataParcel, replyParcel;
127     if (!dataParcel.WriteInt32(data) || !dataParcel.WriteRemoteObject(transObject)) {
128         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
129         return ERR_INVALID_STATE;
130     }
131 
132     error = Remote()->SendRequest(TRANS_STUB_OBJECT, dataParcel, replyParcel, option);
133     if (error != ERR_NONE) {
134         DBINDER_LOGE(LOG_LABEL, "fail to send stub object");
135         return ERR_INVALID_STATE;
136     }
137 
138     rep = replyParcel.ReadInt32();
139 
140     sptr<IRemoteObject> proxy = replyParcel.ReadRemoteObject();
141     if (proxy == nullptr) {
142         DBINDER_LOGE(LOG_LABEL, "fail to get remote stub object");
143         return ERR_INVALID_STATE;
144     }
145 
146     MessageParcel dataStubParcel, replyStubParcel;
147     if (!dataStubParcel.WriteInt32(rep)) {
148         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
149         return ERR_INVALID_STATE;
150     }
151 
152     error = proxy->SendRequest(REVERSEINT, dataStubParcel, replyStubParcel, option);
153     if (error != ERR_NONE) {
154         DBINDER_LOGE(LOG_LABEL, "fail to send data info");
155         return ERR_INVALID_STATE;
156     }
157 
158     stubRep = replyStubParcel.ReadInt32();
159     return error;
160 }
161 
TransStubObjectRefCount(sptr<IRemoteObject> & transObject,int operation)162 int DBinderTestServiceProxy::TransStubObjectRefCount(sptr<IRemoteObject> &transObject, int operation)
163 {
164     MessageOption option;
165     MessageParcel data, reply;
166     if (!data.WriteInt32(operation) || !data.WriteRemoteObject(transObject)) {
167         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
168         return ERR_INVALID_STATE;
169     }
170     int error = Remote()->SendRequest(TRANS_STUB_OBJECT_REFCOUNT, data, reply, option);
171     if (error != ERR_NONE) {
172         DBINDER_LOGE(LOG_LABEL, "fail to send stub object");
173         return ERR_INVALID_STATE;
174     }
175     return error;
176 }
177 
GetRemoteObject(int type)178 sptr<IRemoteObject> DBinderTestServiceProxy::GetRemoteObject(int type)
179 {
180     MessageOption option;
181     MessageParcel dataParcel, replyParcel;
182     if (!dataParcel.WriteInt32(type)) {
183         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
184         return nullptr;
185     }
186 
187     int error = Remote()->SendRequest(GET_REMOTE_STUB_OBJECT, dataParcel, replyParcel, option);
188     if (error != ERR_NONE) {
189         DBINDER_LOGE(LOG_LABEL, "fail to send data info");
190         return nullptr;
191     }
192 
193     sptr<IRemoteObject> proxy = replyParcel.ReadRemoteObject();
194     if (proxy == nullptr) {
195         DBINDER_LOGE(LOG_LABEL, "fail to get remote stub object");
196         return nullptr;
197     }
198     return proxy;
199 }
200 
GetRemoteDecTimes()201 int DBinderTestServiceProxy::GetRemoteDecTimes()
202 {
203     MessageOption option;
204     MessageParcel dataParcel, replyParcel;
205 
206     int error = Remote()->SendRequest(GET_REMOTE_DES_TIMES, dataParcel, replyParcel, option);
207     if (error != ERR_NONE) {
208         DBINDER_LOGE(LOG_LABEL, "fail to send data info");
209         return 0;
210     }
211 
212     return replyParcel.ReadInt32();
213 }
214 
ClearRemoteDecTimes()215 void DBinderTestServiceProxy::ClearRemoteDecTimes()
216 {
217     MessageOption option;
218     MessageParcel dataParcel, replyParcel;
219 
220     int error = Remote()->SendRequest(CLEAR_REMOTE_DES_TIMES, dataParcel, replyParcel, option);
221     if (error != ERR_NONE) {
222         DBINDER_LOGE(LOG_LABEL, "fail to send data info");
223     }
224 }
225 
TransOversizedPkt(const std::string & dataStr,std::string & repStr)226 int DBinderTestServiceProxy::TransOversizedPkt(const std::string &dataStr, std::string &repStr)
227 {
228     int error;
229     MessageOption option;
230     MessageParcel dataParcel, replyParcel;
231     if (!dataParcel.WriteString(dataStr)) {
232         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
233         return ERR_INVALID_STATE;
234     }
235     error = Remote()->SendRequest(TRANS_OVERSIZED_PKT, dataParcel, replyParcel, option);
236 
237     repStr = replyParcel.ReadString();
238     return error;
239 }
240 
ProxyTransRawData(int length)241 int DBinderTestServiceProxy::ProxyTransRawData(int length)
242 {
243     MessageParcel dataParcel, replyParcel;
244 
245     MessageOption option;
246     option.SetWaitTime(RAW_DATA_TIMEOUT);
247     int waitTime = option.GetWaitTime();
248     DBINDER_LOGE(LOG_LABEL, "data length = %{public}d, wait time = %{public}d", length, waitTime);
249 
250     if (length <= 1) {
251         DBINDER_LOGE(LOG_LABEL, "length should > 1, length is %{public}d", length);
252         return ERR_INVALID_STATE;
253     }
254     unsigned char *buffer = new (std::nothrow) unsigned char[length];
255     if (buffer == nullptr) {
256         DBINDER_LOGE(LOG_LABEL, "new buffer failed of length = %{public}d", length);
257         return ERR_INVALID_STATE;
258     }
259     buffer[0] = 'a';
260     buffer[length - 1] = 'z';
261     if (!dataParcel.WriteInt32(length) || !dataParcel.WriteRawData(buffer, length) || !dataParcel.WriteInt32(length)) {
262         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
263         delete[] buffer;
264         return ERR_INVALID_STATE;
265     }
266     delete[] buffer;
267     int ret = Remote()->SendRequest(TRANS_RAW_DATA, dataParcel, replyParcel, option);
268     if (ret != ERR_NONE) {
269         DBINDER_LOGE(LOG_LABEL, "fail to send request, ret = %{public}d", ret);
270         return ret;
271     }
272     if (length != replyParcel.ReadInt32()) {
273         DBINDER_LOGE(LOG_LABEL, "reply wrong length");
274         ret += ERR_TRANSACTION_FAILED;
275     }
276     return ret;
277 }
278 
StubTransRawData(int length)279 int DBinderTestServiceProxy::StubTransRawData(int length)
280 {
281     MessageParcel dataParcel, replyParcel;
282 
283     MessageOption option;
284     option.SetWaitTime(RAW_DATA_TIMEOUT);
285     int waitTime = option.GetWaitTime();
286     DBINDER_LOGE(LOG_LABEL, "data length = %{public}d, wait time = %{public}d", length, waitTime);
287 
288     if (length <= 1) {
289         DBINDER_LOGE(LOG_LABEL, "length should > 1, length is %{public}d", length);
290         return ERR_INVALID_STATE;
291     }
292 
293     if (!dataParcel.WriteInt32(length)) {
294         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
295         return ERR_INVALID_STATE;
296     }
297 
298     int ret = Remote()->SendRequest(RECEIVE_RAW_DATA, dataParcel, replyParcel, option);
299     if (ret != ERR_NONE) {
300         DBINDER_LOGE(LOG_LABEL, "fail to send request, ret = %{public}d", ret);
301         return ret;
302     }
303 
304     if (replyParcel.ReadInt32() != length) {
305         DBINDER_LOGE(LOG_LABEL, "reply false data");
306         return ERR_INVALID_DATA;
307     }
308 
309     const char *buffer = nullptr;
310     if ((buffer = reinterpret_cast<const char *>(replyParcel.ReadRawData(length))) == nullptr) {
311         DBINDER_LOGE(LOG_LABEL, "fail to read raw data, length = %{public}d", length);
312         return ERR_INVALID_DATA;
313     }
314     if (buffer[0] != 'a' || buffer[length - 1] != 'z') {
315         DBINDER_LOGE(LOG_LABEL, "received raw data is wrong, length = %{public}d", length);
316         return ERR_INVALID_DATA;
317     }
318 
319     if (replyParcel.ReadInt32() != length) {
320         DBINDER_LOGE(LOG_LABEL, "fail to read length after raw data, length = %{public}d", length);
321         return ERR_INVALID_DATA;
322     }
323 
324     return ERR_NONE;
325 }
326 
FlushAsyncCommands(int count,int length)327 int DBinderTestServiceProxy::FlushAsyncCommands(int count, int length)
328 {
329     int ret;
330     MessageOption option = { MessageOption::TF_ASYNC };
331     MessageParcel dataParcel, replyParcel;
332     std::string dataStr(length, 'a');
333     if (!dataParcel.WriteString(dataStr)) {
334         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
335         return ERR_INVALID_STATE;
336     }
337     for (int i = 0; i < count; i++) {
338         ret = Remote()->SendRequest(TRANS_OVERSIZED_PKT, dataParcel, replyParcel, option);
339         if (ret != ERR_NONE) {
340             DBINDER_LOGE(LOG_LABEL, "fail to send request when count = %{public}d ret = %{public}d", i, ret);
341             return ret;
342         }
343     }
344     ret = IPCSkeleton::FlushCommands(this->AsObject());
345     return ret;
346 }
347 
ReverseIntNullReply(int data,int & rep)348 int DBinderTestServiceProxy::ReverseIntNullReply(int data, int &rep)
349 {
350     int error;
351     MessageOption option;
352     MessageParcel dataParcel, replyParcel;
353     if (!dataParcel.WriteInt32(data)) {
354         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
355         return ERR_INVALID_STATE;
356     }
357     error = Remote()->SendRequest(REVERSEINT, dataParcel, replyParcel, option);
358 
359     rep = replyParcel.ReadInt32();
360     return error;
361 }
362 
ReverseIntVoidData(int data,int & rep)363 int DBinderTestServiceProxy::ReverseIntVoidData(int data, int &rep)
364 {
365     int error;
366     MessageOption option;
367     MessageParcel dataParcel, replyParcel;
368     // do not write data to parcel;
369     error = Remote()->SendRequest(REVERSEINT, dataParcel, replyParcel, option);
370 
371     rep = replyParcel.ReadInt32();
372     return error;
373 }
374 
ReverseIntDelay(int data,int & rep)375 int DBinderTestServiceProxy::ReverseIntDelay(int data, int &rep)
376 {
377     int error;
378     MessageOption option;
379     MessageParcel dataParcel, replyParcel;
380     if (!dataParcel.WriteInt32(data)) {
381         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
382         return ERR_INVALID_STATE;
383     }
384     error = Remote()->SendRequest(REVERSEINTDELAY, dataParcel, replyParcel, option);
385 
386     rep = replyParcel.ReadInt32();
387     return error;
388 }
389 
Delay(int data,int & rep)390 int DBinderTestServiceProxy::Delay(int data, int &rep)
391 {
392     int error;
393     MessageOption option;
394     MessageParcel dataParcel, replyParcel;
395     if (!dataParcel.WriteInt32(data)) {
396         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
397         return ERR_INVALID_STATE;
398     }
399     error = Remote()->SendRequest(ONLY_DELAY, dataParcel, replyParcel, option);
400 
401     rep = replyParcel.ReadInt32();
402     return error;
403 }
404 
ReverseIntDelayAsync(int data,int & rep)405 int DBinderTestServiceProxy::ReverseIntDelayAsync(int data, int &rep)
406 {
407     int error;
408     MessageOption option;
409     MessageParcel dataParcel, replyParcel;
410     if (!dataParcel.WriteInt32(data) ||
411         // 2:for data update check, only in test case
412         !replyParcel.WriteInt32(data * 2)) {
413         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
414         return ERR_INVALID_STATE;
415     }
416     error = Remote()->SendRequest(REVERSEINTDELAY, dataParcel, replyParcel, option);
417 
418     rep = replyParcel.ReadInt32();
419     return error;
420 }
421 
PingService(std::u16string & serviceName)422 int DBinderTestServiceProxy::PingService(std::u16string &serviceName)
423 {
424     int error;
425     MessageOption option;
426     MessageParcel dataParcel, replyParcel;
427     DBINDER_LOGE(LOG_LABEL, "TestServiceProxy:PingService");
428     if (!dataParcel.WriteString16(serviceName.data())) {
429         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
430         return ERR_INVALID_STATE;
431     }
432     error = Remote()->SendRequest(REVERSEINT, dataParcel, replyParcel, option);
433     replyParcel.ReadInt32();
434     return error;
435 }
436 
437 pid_t DBinderTestServiceStub::g_lastCallingPid = 0;
438 pid_t DBinderTestServiceStub::g_lastCallinguid = 0;
439 
GetLastCallingPid()440 pid_t DBinderTestServiceStub::GetLastCallingPid()
441 {
442     return g_lastCallingPid;
443 }
444 
GetLastCallingUid()445 uid_t DBinderTestServiceStub::GetLastCallingUid()
446 {
447     return g_lastCallinguid;
448 }
449 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)450 int DBinderTestServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
451     MessageOption &option)
452 {
453     DBINDER_LOGE(LOG_LABEL, "TestServiceStub::OnReceived, cmd = %{public}d", code);
454     g_lastCallingPid = IPCSkeleton::GetCallingPid();
455     g_lastCallinguid = IPCSkeleton::GetCallingUid();
456     auto it = codeFuncMap_.find(code);
457     if (it != codeFuncMap_.end()) {
458         auto itFunc = it->second;
459         if (itFunc != nullptr) {
460             return (this->*itFunc)(data, reply);
461         }
462     }
463     return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
464 }
465 
ReverseIntDelayAsync(int data,int & rep)466 int DBinderTestServiceStub::ReverseIntDelayAsync(int data, int &rep)
467 {
468     (void)data;
469     HiLog::Error(LOG_LABEL, "%{public}s: not valid operate", __func__);
470     return 0;
471 }
472 
OnReverseInt(MessageParcel & data,MessageParcel & reply)473 int DBinderTestServiceStub::OnReverseInt(MessageParcel &data, MessageParcel &reply)
474 {
475     int result;
476     int32_t reqData = data.ReadInt32();
477     int ret = ReverseInt(reqData, result);
478     DBINDER_LOGI(LOG_LABEL, "ReverseInt result = %{public}d", result);
479     if (!reply.WriteInt32(result)) {
480         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
481         ret = ERR_INVALID_STATE;
482     }
483 
484     return ret;
485 }
486 
OnGetChildId(MessageParcel & data,MessageParcel & reply)487 int DBinderTestServiceStub::OnGetChildId(MessageParcel &data, MessageParcel &reply)
488 {
489     uint64_t reqData = HiTraceChain::GetId().GetChainId();
490     if (!reply.WriteUint64(reqData)) {
491         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
492         return ERR_INVALID_STATE;
493     }
494 
495     DBINDER_LOGE(LOG_LABEL,
496         "before reset uid = %{public}d, callerId = %{public}s, localId = %{public}s, islocal = %{public}d",
497         IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingDeviceID().c_str(),
498         IPCSkeleton::GetLocalDeviceID().c_str(), IPCSkeleton::IsLocalCalling());
499     std::string token = IPCSkeleton::ResetCallingIdentity();
500 
501     DBINDER_LOGE(LOG_LABEL,
502         "before set uid = %{public}d, callerId = %{public}s, localId = %{public}s, islocal = %{public}d",
503         IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingDeviceID().c_str(),
504         IPCSkeleton::GetLocalDeviceID().c_str(), IPCSkeleton::IsLocalCalling());
505     if (!IPCSkeleton::SetCallingIdentity(token)) {
506         DBINDER_LOGE(LOG_LABEL, "Set Calling Identity fail");
507     }
508 
509     DBINDER_LOGE(LOG_LABEL,
510         "after set uid = %{public}d, callerId = %{public}s, localId = %{public}s, islocal = %{public}d",
511         IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingDeviceID().c_str(),
512         IPCSkeleton::GetLocalDeviceID().c_str(), IPCSkeleton::IsLocalCalling());
513     return ERR_NONE;
514 }
515 
OnReverseIntDelay(MessageParcel & data,MessageParcel & reply)516 int DBinderTestServiceStub::OnReverseIntDelay(MessageParcel &data, MessageParcel &reply)
517 {
518     int result;
519     int32_t reqData = data.ReadInt32();
520     int ret = ReverseIntDelay(reqData, result);
521     if (!reply.WriteInt32(result)) {
522         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
523         ret = ERR_INVALID_STATE;
524     }
525 
526     return ret;
527 }
528 
OnPingService(MessageParcel & data,MessageParcel & reply)529 int DBinderTestServiceStub::OnPingService(MessageParcel &data, MessageParcel &reply)
530 {
531     std::u16string serviceName = data.ReadString16();
532     int ret = PingService(serviceName);
533     DBINDER_LOGI(LOG_LABEL, "%s:PingService: ret=%d", __func__, ret);
534     if (!reply.WriteInt32(ret)) {
535         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
536         ret = ERR_INVALID_STATE;
537     }
538 
539     return ret;
540 }
541 
OnDelay(MessageParcel & data,MessageParcel & reply)542 int DBinderTestServiceStub::OnDelay(MessageParcel &data, MessageParcel &reply)
543 {
544     int result;
545     int32_t reqData = data.ReadInt32();
546     int ret = Delay(reqData, result);
547     if (!reply.WriteInt32(result)) {
548         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
549         ret = ERR_INVALID_STATE;
550     }
551 
552     return ret;
553 }
554 
OnReceivedObject(MessageParcel & data,MessageParcel & reply)555 int DBinderTestServiceStub::OnReceivedObject(MessageParcel &data, MessageParcel &reply)
556 {
557     int32_t reqData = data.ReadInt32();
558     int32_t operation = data.ReadInt32();
559     sptr<IRemoteObject> proxy = data.ReadRemoteObject();
560     if (proxy == nullptr) {
561         DBINDER_LOGE(LOG_LABEL, "null proxy");
562         return ERR_INVALID_STATE;
563     }
564 
565     // use the received proxy to communicate
566     MessageOption option;
567     MessageParcel dataParcel, replyParcel;
568     if (!dataParcel.WriteInt32(reqData)) {
569         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
570         return ERR_INVALID_STATE;
571     }
572     DBINDER_LOGI(LOG_LABEL, "%{public}s:TRANSOBJECT: reqData=%{public}d", __func__, reqData);
573     int ret = proxy->SendRequest(REVERSEINT, dataParcel, replyParcel, option);
574     int reqResult = replyParcel.ReadInt32();
575     DBINDER_LOGI(LOG_LABEL, "%{public}s:TRANSOBJECT: result=%{public}d", __func__, reqResult);
576 
577     if (!reply.WriteInt32(reqResult)) {
578         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
579         return ERR_INVALID_STATE;
580     }
581 
582     if (operation == SAVE) {
583         recvProxy_ = proxy;
584     }
585 
586     // received proxy is different from that of last time
587     if ((operation == WITHDRAW) && (recvProxy_ != proxy)) {
588         if (!reply.WriteInt32(1)) {
589             DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
590             ret = ERR_INVALID_STATE;
591         }
592         return ret;
593     }
594 
595     if (!reply.WriteInt32(0)) {
596         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
597         return ERR_INVALID_STATE;
598     }
599     return ret;
600 }
601 
OnReceivedProxyObjectRefCount(MessageParcel & data,MessageParcel & reply)602 int DBinderTestServiceStub::OnReceivedProxyObjectRefCount(MessageParcel &data, MessageParcel &reply)
603 {
604     int32_t operation = data.ReadInt32();
605     sptr<IRemoteObject> proxy = data.ReadRemoteObject();
606     if (proxy == nullptr) {
607         DBINDER_LOGE(LOG_LABEL, "fail to get proxy");
608         return ERR_INVALID_STATE;
609     }
610     if (operation == IDBinderTestService::SAVE) {
611         recvProxy_ = proxy;
612     } else if (operation == IDBinderTestService::WITHDRAW) {
613         recvProxy_ = nullptr;
614     }
615     return ERR_NONE;
616 }
617 
OnReceivedObjectTransAgain(MessageParcel & data,MessageParcel & reply)618 int DBinderTestServiceStub::OnReceivedObjectTransAgain(MessageParcel &data, MessageParcel &reply)
619 {
620     int32_t reqData = data.ReadInt32();
621     int32_t operation = data.ReadInt32();
622     sptr<IRemoteObject> proxy = data.ReadRemoteObject();
623     if (proxy == nullptr) {
624         DBINDER_LOGE(LOG_LABEL, "null proxy");
625         return ERR_INVALID_STATE;
626     }
627     sptr<ISystemAbilityManager> manager_ = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
628     if (manager_ == nullptr) {
629         DBINDER_LOGE(LOG_LABEL, "null manager_");
630         return ERR_INVALID_STATE;
631     }
632     DBINDER_LOGI(LOG_LABEL, "%{public}s:OnReceivedObjectTransAgain-1: reqData=%{public}d", __func__, reqData);
633 
634     sptr<IRemoteObject> object = manager_->GetSystemAbility(RPC_TEST_SERVICE2);
635     if (object == nullptr) {
636         DBINDER_LOGE(LOG_LABEL, "null object of RPC_TEST_SERVICE2");
637         return ERR_INVALID_STATE;
638     }
639 
640     MessageOption option;
641     MessageParcel dataParcel, replyParcel;
642     if (!dataParcel.WriteInt32(reqData) || !dataParcel.WriteInt32(operation) ||
643         !dataParcel.WriteRemoteObject(proxy)) {
644         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
645         return ERR_INVALID_STATE;
646     }
647     DBINDER_LOGI(LOG_LABEL, "%{public}s:OnReceivedObjectTransAgain-2: reqData=%{public}d", __func__, reqData);
648     int ret = object->SendRequest(TRANS_RPC_OBJECT_TO_LOCAL, dataParcel, replyParcel, option);
649 
650     int reqResult = replyParcel.ReadInt32();
651     DBINDER_LOGI(LOG_LABEL, "%{public}s:OnReceivedObjectTransAgain-3: result=%{public}d", __func__, reqResult);
652 
653     if (!reply.WriteInt32(reqResult)) {
654         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
655         return ERR_INVALID_STATE;
656     }
657     DBINDER_LOGI(LOG_LABEL, "%{public}s:OnReceivedObjectTransAgain-4: result=%{public}d", __func__, reqResult);
658     if (!reply.WriteInt32(0)) {
659         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
660         return ERR_INVALID_STATE;
661     }
662     DBINDER_LOGI(LOG_LABEL, "%{public}s:OnReceivedObjectTransAgain-5: result=%{public}d", __func__, reqResult);
663     return ret;
664 }
665 
OnReceivedStubObject(MessageParcel & data,MessageParcel & reply)666 int DBinderTestServiceStub::OnReceivedStubObject(MessageParcel &data, MessageParcel &reply)
667 {
668     int32_t reqData = data.ReadInt32();
669     sptr<IRemoteObject> proxy = data.ReadRemoteObject();
670     if (proxy == nullptr) {
671         DBINDER_LOGE(LOG_LABEL, "fail to get proxy");
672         return ERR_INVALID_STATE;
673     }
674 
675     MessageOption option;
676     MessageParcel dataParcel, replyParcel;
677     if (!dataParcel.WriteInt32(reqData)) {
678         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
679         return ERR_INVALID_STATE;
680     }
681 
682     int error = proxy->SendRequest(REVERSEINT, dataParcel, replyParcel, option);
683     if (error != ERR_NONE) {
684         DBINDER_LOGE(LOG_LABEL, "fail to send data info");
685         return ERR_INVALID_STATE;
686     }
687     int reqResult = replyParcel.ReadInt32();
688     if (!reply.WriteInt32(reqResult)) {
689         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
690         return ERR_INVALID_STATE;
691     }
692 
693     if (!reply.WriteRemoteObject(this)) {
694         DBINDER_LOGE(LOG_LABEL, "fail to write parcel stub");
695         return ERR_INVALID_STATE;
696     }
697 
698     return error;
699 }
700 
OnReceivedStubObjectRefCount(MessageParcel & data,MessageParcel & reply)701 int DBinderTestServiceStub::OnReceivedStubObjectRefCount(MessageParcel &data, MessageParcel &reply)
702 {
703     int32_t operation = data.ReadInt32();
704     sptr<IRemoteObject> proxy = data.ReadRemoteObject();
705     if (proxy == nullptr) {
706         DBINDER_LOGE(LOG_LABEL, "fail to get proxy");
707         return ERR_INVALID_STATE;
708     }
709     if (operation == IDBinderTestService::SAVE) {
710         recvProxy_ = proxy;
711     } else if (operation == IDBinderTestService::WITHDRAW) {
712         recvProxy_ = nullptr;
713     }
714     return ERR_NONE;
715 }
716 
OnReceivedGetStubObject(MessageParcel & data,MessageParcel & reply)717 int DBinderTestServiceStub::OnReceivedGetStubObject(MessageParcel &data, MessageParcel &reply)
718 {
719     if (!reply.WriteRemoteObject(GetRemoteObject(data.ReadInt32()))) {
720         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
721         return ERR_INVALID_STATE;
722     }
723 
724     return ERR_NONE;
725 }
726 
OnReceivedGetDecTimes(MessageParcel & data,MessageParcel & reply)727 int DBinderTestServiceStub::OnReceivedGetDecTimes(MessageParcel &data, MessageParcel &reply)
728 {
729     if (!reply.WriteInt32(GetRemoteDecTimes())) {
730         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
731         return ERR_INVALID_STATE;
732     }
733 
734     return ERR_NONE;
735 }
736 
OnReceivedClearDecTimes(MessageParcel & data,MessageParcel & reply)737 int DBinderTestServiceStub::OnReceivedClearDecTimes(MessageParcel &data, MessageParcel &reply)
738 {
739     DBINDER_LOGE(LOG_LABEL, "OnReceivedClearDecTimes");
740 
741     ClearRemoteDecTimes();
742     return ERR_NONE;
743 }
744 
OnReceivedOversizedPkt(MessageParcel & data,MessageParcel & reply)745 int DBinderTestServiceStub::OnReceivedOversizedPkt(MessageParcel &data, MessageParcel &reply)
746 {
747     std::string reqStr = data.ReadString();
748     std::string resultStr = reqStr;
749     if (!reply.WriteString(resultStr)) {
750         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
751         return ERR_INVALID_STATE;
752     }
753 
754     return ERR_NONE;
755 }
756 
OnReceivedRawData(MessageParcel & data,MessageParcel & reply)757 int DBinderTestServiceStub::OnReceivedRawData(MessageParcel &data, MessageParcel &reply)
758 {
759     int length = data.ReadInt32();
760     if (length <= 1) {
761         DBINDER_LOGE(LOG_LABEL, "length should > 1, length is %{public}d", length);
762         if (!reply.WriteInt32(length)) {
763             DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
764         }
765         return ERR_INVALID_DATA;
766     }
767     const char *buffer = nullptr;
768     if ((buffer = reinterpret_cast<const char *>(data.ReadRawData(length))) == nullptr) {
769         if (!reply.WriteInt32(0)) {
770             DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
771         }
772         DBINDER_LOGE(LOG_LABEL, "read raw data failed, length = %{public}d", length);
773         return ERR_INVALID_DATA;
774     }
775     if (buffer[0] != 'a' || buffer[length - 1] != 'z') {
776         if (!reply.WriteInt32(0)) {
777             DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
778         }
779         DBINDER_LOGE(LOG_LABEL, "buffer error, length = %{public}d", length);
780         return ERR_INVALID_DATA;
781     }
782     if (data.ReadInt32() != length) {
783         if (!reply.WriteInt32(0)) {
784             DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
785         }
786         DBINDER_LOGE(LOG_LABEL, "read raw data after failed, length = %{public}d", length);
787         return ERR_INVALID_DATA;
788     }
789     if (!reply.WriteInt32(length)) {
790         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
791         return ERR_INVALID_STATE;
792     }
793 
794     return ERR_NONE;
795 }
796 
OnSentRawData(MessageParcel & data,MessageParcel & reply)797 int DBinderTestServiceStub::OnSentRawData(MessageParcel &data, MessageParcel &reply)
798 {
799     int length = data.ReadInt32();
800     if (length <= 1) {
801         DBINDER_LOGE(LOG_LABEL, "length should > 1, length is %{public}d", length);
802         if (!reply.WriteInt32(length)) {
803             DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
804         }
805         return ERR_INVALID_DATA;
806     }
807 
808     unsigned char *buffer = new (std::nothrow) unsigned char[length];
809     if (buffer == nullptr) {
810         DBINDER_LOGE(LOG_LABEL, "new buffer failed of length = %{public}d", length);
811         return ERR_INVALID_STATE;
812     }
813     buffer[0] = 'a';
814     buffer[length - 1] = 'z';
815     if (!reply.WriteInt32(length) || !reply.WriteRawData(buffer, length) || !reply.WriteInt32(length)) {
816         DBINDER_LOGE(LOG_LABEL, "fail to write parcel");
817         delete[] buffer;
818         return ERR_INVALID_STATE;
819     }
820     delete[] buffer;
821     return ERR_NONE;
822 }
823 
824 bool DBinderTestDeathRecipient::g_gotDeathRecipient = false;
GotDeathRecipient()825 bool DBinderTestDeathRecipient::GotDeathRecipient()
826 {
827     return g_gotDeathRecipient;
828 }
829 
ClearDeathRecipient()830 void DBinderTestDeathRecipient::ClearDeathRecipient()
831 {
832     g_gotDeathRecipient = false;
833 }
834 
OnRemoteDied(const wptr<IRemoteObject> & remote)835 void DBinderTestDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
836 {
837     g_gotDeathRecipient = true;
838     printf("Succ! Remote Died!\n");
839     DBINDER_LOGE(LOG_LABEL, "recv death notification");
840 }
841 
DBinderTestDeathRecipient()842 DBinderTestDeathRecipient::DBinderTestDeathRecipient() {}
843 
~DBinderTestDeathRecipient()844 DBinderTestDeathRecipient::~DBinderTestDeathRecipient() {}
845 } // namespace OHOS
846