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