• 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 "test_service_proxy.h"
17 #include <cinttypes>
18 #include <fcntl.h>
19 #include <iostream>
20 #include <cstdio>
21 #include <cstdlib>
22 #include <sys/ioctl.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <thread>
26 #include "access_token_adapter.h"
27 #include "ipc_debug.h"
28 #include "string_ex.h"
29 #include "iremote_proxy.h"
30 #include "ipc_skeleton.h"
31 #include "ipc_file_descriptor.h"
32 #include "ipc_test_helper.h"
33 #include "if_system_ability_manager.h"
34 #include "iservice_registry.h"
35 #include "system_ability_definition.h"
36 #include "fd_san.h"
37 
38 namespace OHOS {
39 using namespace OHOS::HiviewDFX;
40 
41 constexpr int32_t SEDNREQUEST_TIMES = 2000;
42 constexpr int32_t NUMBER_OF_THREADS = 20;
43 
TestServiceProxy(const sptr<IRemoteObject> & impl)44 TestServiceProxy::TestServiceProxy(const sptr<IRemoteObject> &impl)
45     : IRemoteProxy<ITestService>(impl)
46 {
47 }
48 
TestEnableSerialInvokeFlag()49 int TestServiceProxy::TestEnableSerialInvokeFlag()
50 {
51     MessageOption option;
52     MessageParcel dataParcel;
53     MessageParcel replyParcel;
54     std::string value = "testData";
55 
56     ZLOGI(LABEL, "Send to server data = %{public}s", value.c_str());
57     dataParcel.WriteString(value);
58     auto remote = Remote();
59     if (remote == nullptr) {
60         ZLOGI(LABEL, "The obtained proxy is a null pointer");
61         return -1;
62     }
63 
64     int ret = remote->SendRequest(TRANS_ENABLE_SERIAL_INVOKE_FLAG, dataParcel, replyParcel, option);
65     std::string reply = replyParcel.ReadString();
66     ZLOGI(LABEL, "Get result from server data = %{public}s", reply.c_str());
67     return ret;
68 }
69 
TestSyncTransaction(int value,int & reply,int delayTime)70 int TestServiceProxy::TestSyncTransaction(int value, int &reply, int delayTime)
71 {
72     MessageOption option;
73     MessageParcel dataParcel;
74     MessageParcel replyParcel;
75     int ret = -1;
76 
77     ZLOGI(LABEL, "Send to server data = %{public}d", value);
78     if (value > 0) {
79         dataParcel.WriteInt32(value);
80         dataParcel.WriteInt32(delayTime);
81     }
82     auto remote = Remote();
83     if (remote == nullptr) {
84         ZLOGI(LABEL, "The obtained proxy is a null pointer");
85         return ret;
86     }
87 
88     ret = remote->SendRequest(TRANS_ID_SYNC_TRANSACTION, dataParcel, replyParcel, option);
89     if (ret != 0) {
90         return ret;
91     }
92 
93     reply = replyParcel.ReadInt32();
94     ZLOGI(LABEL, "Get result from server data = %{public}d", reply);
95     return ret;
96 }
97 
TestSendTooManyRequest(int data,int & reply)98 int TestServiceProxy::TestSendTooManyRequest(int data, int &reply)
99 {
100     int ret = 0;
101     int delayTime = 0;
102     MessageOption option;
103     MessageParcel dataParcel;
104     MessageParcel replyParcel[SEDNREQUEST_TIMES];
105 
106     ZLOGI(LABEL, "Send to server data = %{public}d", data);
107     if (data > 0) {
108         dataParcel.WriteInt32(data);
109         dataParcel.WriteInt32(delayTime);
110     }
111     for (int32_t i = 0; i < SEDNREQUEST_TIMES; i++) {
112         ret = Remote()->SendRequest(TRANS_ID_SYNC_TRANSACTION, dataParcel, replyParcel[i], option);
113     }
114     reply = replyParcel[0].ReadInt32();
115     ZLOGI(LABEL, "Get result from server data = %{public}d", reply);
116     return ret;
117 }
118 
TestMultiThreadSendRequest(int data,int & reply)119 int TestServiceProxy::TestMultiThreadSendRequest(int data, int &reply)
120 {
121     int ret = 0;
122 
123     sptr<IRemoteObject> proxyObject = Remote();
124     for (int32_t i = 0; i < NUMBER_OF_THREADS; i++) {
125         // Different threads correspond to different sets of parcels.
126         std::thread t([&proxyObject, &data, &reply] {
127             MessageParcel dataParcel;
128             MessageParcel replyParcel;
129             MessageOption option;
130             if (data > 0) {
131                 dataParcel.WriteInt32(data);
132                 dataParcel.WriteInt32(0);
133             }
134             int ret = proxyObject->SendRequest(TRANS_ID_SYNC_TRANSACTION, dataParcel, replyParcel, option);
135             if (ret != 0) {
136                 ZLOGI(LABEL, "SendRequest is failed: %{public}d", ret);
137                 return;
138             }
139             reply = replyParcel.ReadInt32();
140         });
141         t.detach();
142     }
143     sleep(1); // Waiting for the thread to finish executing
144 
145     return ret;
146 }
147 
TestAsyncTransaction(int data,int timeout)148 int TestServiceProxy::TestAsyncTransaction(int data, int timeout)
149 {
150     MessageOption option = { MessageOption::TF_ASYNC };
151     MessageParcel dataParcel;
152     MessageParcel replyParcel;
153     ZLOGI(LABEL, "TestAsyncTransaction is called, data = %{public}d", data);
154     dataParcel.WriteInt32(data);
155     dataParcel.WriteInt32(timeout);
156     dataParcel.WriteBool(false);
157     auto remote = Remote();
158     if (remote == nullptr) {
159         ZLOGE(LABEL, "remote is nullptr");
160         return -1;
161     }
162     return remote->SendRequest(TRANS_ID_ASYNC_TRANSACTION, dataParcel, replyParcel, option);
163 }
164 
TestAsyncCallbackTrans(int data,int & reply,int timeout)165 int TestServiceProxy::TestAsyncCallbackTrans(int data, int &reply, int timeout)
166 {
167     int ret;
168     MessageOption option = { MessageOption::TF_ASYNC };
169     MessageParcel dataParcel;
170     MessageParcel replyParcel;
171     ZLOGI(LABEL, "TestAsyncCallbackTrans is called, data = %{public}d", data);
172     dataParcel.WriteInt32(data);
173     dataParcel.WriteInt32(timeout);
174     dataParcel.WriteBool(true);
175     sptr<FooStub> fooCallback = new FooStub();
176     dataParcel.WriteRemoteObject(fooCallback->AsObject());
177     ret = Remote()->SendRequest(TRANS_ID_ASYNC_TRANSACTION, dataParcel, replyParcel, option);
178     reply = fooCallback->WaitForAsyncReply(timeout);
179 
180     FooStub::CleanDecTimes();
181     fooCallback = nullptr;
182     if (FooStub::GetDecTimes() != 1) {
183         ret = ERR_TRANSACTION_FAILED;
184     }
185     return ret;
186 }
187 
TestZtraceTransaction(std::string & send,std::string & reply,int len)188 int TestServiceProxy::TestZtraceTransaction(std::string &send, std::string &reply, int len)
189 {
190     MessageParcel dataParcel;
191     MessageParcel replyParcel;
192     MessageOption option;
193 
194     dataParcel.WriteInt32(len);
195     dataParcel.WriteString(send);
196     int ret = Remote()->SendRequest(TRANS_ID_ZTRACE_TRANSACTION, dataParcel, replyParcel, option);
197     if (ret != 0) {
198         return ret;
199     }
200 
201     if (!replyParcel.ReadString(reply)) {
202         return -1;
203     }
204 
205     return ret;
206 }
207 
TestPingService(const std::u16string & serviceName)208 int TestServiceProxy::TestPingService(const std::u16string &serviceName)
209 {
210     int ret;
211     MessageOption option;
212     MessageParcel dataParcel;
213     MessageParcel replyParcel;
214     ZLOGI(LABEL, "PingService");
215     dataParcel.WriteString16(serviceName);
216     ret = Remote()->SendRequest(TRANS_ID_PING_SERVICE, dataParcel, replyParcel, option);
217     int result = (ret == ERR_NONE) ? replyParcel.ReadInt32() : -1;
218     ZLOGI(LABEL, "PingService result = %{public}d", result);
219     return result;
220 }
221 
TestGetFooService()222 sptr<IFoo> TestServiceProxy::TestGetFooService()
223 {
224     MessageOption option;
225     MessageParcel dataParcel;
226     MessageParcel replyParcel;
227     Remote()->SendRequest(TRANS_ID_GET_FOO_SERVICE, dataParcel, replyParcel, option);
228     auto rep = replyParcel.ReadRemoteObject();
229     if (rep == nullptr) {
230         ZLOGE(LABEL, "null foo service");
231         return nullptr;
232     }
233     return iface_cast<IFoo>(rep);
234 }
235 
TestGetFileDescriptor()236 int TestServiceProxy::TestGetFileDescriptor()
237 {
238     MessageOption option;
239     MessageParcel dataParcel;
240     MessageParcel replyParcel;
241     sptr<IPCFileDescriptor> desc;
242     option.SetFlags(MessageOption::TF_ACCEPT_FDS);
243     Remote()->SendRequest(TRANS_ID_TRANSACT_FILE_DESC, dataParcel, replyParcel, option);
244     int fd = replyParcel.ReadFileDescriptor();
245     return fd;
246 }
247 
TestStringTransaction(const std::string & data)248 int TestServiceProxy::TestStringTransaction(const std::string &data)
249 {
250     MessageOption option;
251     MessageParcel dataParcel;
252     MessageParcel replyParcel;
253     dataParcel.WriteString(data);
254     Remote()->SendRequest(TRANS_ID_STRING_TRANSACTION, dataParcel, replyParcel, option);
255     int testSize = replyParcel.ReadInt32();
256     return testSize;
257 }
258 
TestDumpService()259 int TestServiceProxy::TestDumpService()
260 {
261     ZLOGI(LABEL, "call StartDumpService");
262     int fd = open("/data/dump.txt", O_RDWR | O_APPEND | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
263     if (fd == INVALID_FD) {
264         ZLOGE(LABEL, "Call to open system function failed.");
265         return -1;
266     }
267     fdsan_exchange_owner_tag(fd, 0, IPC_FD_TAG);
268     ZLOGI(LABEL, "Start Dump Service");
269     std::vector<std::u16string> args;
270     args.push_back(u"DumpTest");
271     int ret = Remote()->Dump(fd, args);
272     if (ret != 0) {
273         return -1;
274     }
275     fdsan_close_with_tag(fd, IPC_FD_TAG);
276     return ret;
277 }
278 
TestRawDataTransaction(int length,int & reply)279 int TestServiceProxy::TestRawDataTransaction(int length, int &reply)
280 {
281     int ret;
282     MessageOption option;
283     MessageParcel dataParcel;
284     MessageParcel replyParcel;
285     ZLOGE(LABEL, "Send to server data length = %{public}d", length);
286     if (length <= 1 || static_cast<unsigned>(length) > dataParcel.GetRawDataCapacity()) {
287         ZLOGE(LABEL, "length should > 1, length is %{public}d", length);
288         return -1;
289     }
290     unsigned char *buffer = new (std::nothrow) unsigned char[length];
291     if (buffer == nullptr) {
292         ZLOGE(LABEL, "New buffer failed of length = %{public}d", length);
293         return -1;
294     }
295     buffer[0] = 'a';
296     buffer[length - 1] = 'z';
297 
298     dataParcel.WriteInt32(length);
299     dataParcel.WriteRawData(buffer, length);
300     dataParcel.WriteInt32(length);
301     ret = Remote()->SendRequest(TRANS_ID_RAWDATA_TRANSACTION, dataParcel, replyParcel, option);
302     reply = replyParcel.ReadInt32();
303     ZLOGE(LABEL, "Get result from server data = %{public}d", reply);
304     delete [] buffer;
305     return ret;
306 }
307 
TestRawDataReply(int length)308 int TestServiceProxy::TestRawDataReply(int length)
309 {
310     MessageOption option;
311     MessageParcel dataParcel;
312     MessageParcel replyParcel;
313     if (length <= 1 || static_cast<unsigned>(length) > dataParcel.GetRawDataCapacity()) {
314         ZLOGE(LABEL, "Length should > 1, length is %{public}d", length);
315         return ERR_INVALID_STATE;
316     }
317 
318     if (!dataParcel.WriteInt32(length)) {
319         ZLOGE(LABEL, "fail to write parcel");
320         return ERR_INVALID_STATE;
321     }
322 
323     int ret = Remote()->SendRequest(TRANS_ID_RAWDATA_REPLY, dataParcel, replyParcel, option);
324     if (ret != ERR_NONE) {
325         ZLOGE(LABEL, "ret = %{public}d", ret);
326         return ret;
327     }
328 
329     if (replyParcel.ReadInt32() != length) {
330         ZLOGE(LABEL, "reply false data");
331         return ERR_INVALID_DATA;
332     }
333 
334     if (!replyParcel.ContainFileDescriptors()) {
335         ZLOGE(LABEL, "replied raw data is less than 32k");
336     }
337 
338     const char *buffer = nullptr;
339     if ((buffer = reinterpret_cast<const char *>(replyParcel.ReadRawData((size_t)length))) == nullptr) {
340         ZLOGE(LABEL, "read raw data failed, length = %{public}d", length);
341         return ERR_INVALID_DATA;
342     }
343     if (buffer[0] != 'a' || buffer[length - 1] != 'z') {
344         ZLOGE(LABEL, "Buffer error, length = %{public}d", length);
345         return ERR_INVALID_DATA;
346     }
347 
348     if (replyParcel.ReadInt32() != length) {
349         ZLOGE(LABEL, "Read raw data after failed, length = %{public}d", length);
350         return ERR_INVALID_DATA;
351     }
352 
353     return ERR_NONE;
354 }
355 
TestCallingUidPid()356 int TestServiceProxy::TestCallingUidPid()
357 {
358     MessageOption option;
359     MessageParcel dataParcel;
360     MessageParcel replyParcel;
361     int ret = Remote()->SendRequest(TRANS_ID_CALLING_UID_PID, dataParcel, replyParcel, option);
362     if (ret != ERR_NONE) {
363         ZLOGE(LABEL, "ret = %{public}d", ret);
364         return ret;
365     }
366 
367     int uid  = replyParcel.ReadInt32();
368     int pid  = replyParcel.ReadInt32();
369 
370     IPCTestHelper helper;
371     int actualUid = static_cast<int>(helper.GetUid());
372     int actualPid = static_cast<int>(helper.GetPid());
373     ZLOGI(LABEL, "uid = %{public}d, pid = %{public}d, actualUid = %{public}d, actualPid = %{public}d",
374         uid, pid, actualUid, actualPid);
375 
376     if (uid == actualUid && pid == actualPid) {
377         return 0;
378     }
379     return -1;
380 }
381 
TestRegisterRemoteStub(const char * descriptor,const sptr<IRemoteObject> object)382 int TestServiceProxy::TestRegisterRemoteStub(const char *descriptor, const sptr<IRemoteObject> object)
383 {
384     MessageOption option;
385     MessageParcel dataParcel;
386     MessageParcel replyParcel;
387     dataParcel.WriteString(descriptor);
388     dataParcel.WriteRemoteObject(object);
389     int ret = Remote()->SendRequest(TRANS_ID_REGISTER_REMOTE_STUB_OBJECT, dataParcel, replyParcel, option);
390     if (ret != ERR_NONE) {
391         ZLOGE(LABEL, "ret = %{public}d", ret);
392         return ret;
393     }
394     return 0;
395 }
396 
TestUnRegisterRemoteStub(const char * descriptor)397 int TestServiceProxy::TestUnRegisterRemoteStub(const char *descriptor)
398 {
399     MessageOption option;
400     MessageParcel dataParcel;
401     MessageParcel replyParcel;
402     dataParcel.WriteString(descriptor);
403     int ret = Remote()->SendRequest(TRANS_ID_UNREGISTER_REMOTE_STUB_OBJECT, dataParcel, replyParcel, option);
404     if (ret != ERR_NONE) {
405         ZLOGE(LABEL, "ret = %{public}d", ret);
406         return ret;
407     }
408     return 0;
409 }
410 
TestQueryRemoteProxy(const char * descriptor)411 sptr<IRemoteObject> TestServiceProxy::TestQueryRemoteProxy(const char *descriptor)
412 {
413     MessageOption option;
414     MessageParcel dataParcel;
415     MessageParcel replyParcel;
416     dataParcel.WriteString(descriptor);
417     int ret = Remote()->SendRequest(TRANS_ID_QUERY_REMOTE_PROXY_OBJECT, dataParcel, replyParcel, option);
418     if (ret != ERR_NONE) {
419         ZLOGE(LABEL, "SendRequest failed ret = %{public}d", ret);
420         return nullptr;
421     }
422     auto readRemoteObject = replyParcel.ReadRemoteObject();
423     return readRemoteObject;
424 }
425 
426 constexpr char ACCESS_TOKEN_ID_IOCTL_BASE = 'A';
427 
428 enum {
429     GET_TOKEN_ID = 1,
430     SET_TOKEN_ID,
431     GET_FTOKEN_ID,
432     SET_FTOKEN_ID,
433     ACCESS_TOKENID_MAX_NR,
434 };
435 
436 #define ACCESS_TOKENID_SET_TOKENID \
437     _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, SET_TOKEN_ID, unsigned long long)
438 #define ACCESS_TOKENID_SET_FTOKENID \
439     _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, SET_FTOKEN_ID, unsigned long long)
440 
441 constexpr int ACCESS_TOKEN_OK = 0;
442 constexpr int ACCESS_TOKEN_ERROR = -1;
443 
444 constexpr char TOKENID_DEVNODE[] = "/dev/access_token_id";
445 
RpcSetSelfTokenID(uint64_t tokenID)446 int RpcSetSelfTokenID(uint64_t tokenID)
447 {
448     FILE *fp = fopen(TOKENID_DEVNODE, "r+");
449     if (fp == nullptr) {
450         return ACCESS_TOKEN_ERROR;
451     }
452     int fd = fileno(fp);
453     if (fd < 0) {
454         (void)fclose(fp);
455         return ACCESS_TOKEN_ERROR;
456     }
457     int ret = ioctl(fd, ACCESS_TOKENID_SET_TOKENID, &tokenID);
458     if (ret != 0) {
459         (void)fclose(fp);
460         return ACCESS_TOKEN_ERROR;
461     }
462     (void)fclose(fp);
463     return ACCESS_TOKEN_OK;
464 }
465 
RpcSetFirstCallerTokenID(uint64_t tokenID)466 int RpcSetFirstCallerTokenID(uint64_t tokenID)
467 {
468     FILE *fp = fopen(TOKENID_DEVNODE, "r+");
469     if (fp == nullptr) {
470         return ACCESS_TOKEN_ERROR;
471     }
472     int fd = fileno(fp);
473     if (fd < 0) {
474         (void)fclose(fp);
475         return ACCESS_TOKEN_ERROR;
476     }
477     int ret = ioctl(fd, ACCESS_TOKENID_SET_FTOKENID, &tokenID);
478     if (ret != 0) {
479         (void)fclose(fp);
480         return ACCESS_TOKEN_ERROR;
481     }
482     (void)fclose(fp);
483     return ACCESS_TOKEN_OK;
484 }
485 
CheckTokenSelf(uint64_t token,uint64_t tokenSelf,uint64_t ftoken,uint64_t ftoken_expected)486 bool TestServiceProxy::CheckTokenSelf(uint64_t token, uint64_t tokenSelf, uint64_t ftoken, uint64_t ftoken_expected)
487 {
488     if (token != tokenSelf) {
489         ZLOGE(LABEL, "token != tokenSelf");
490         return false;
491     }
492     if (ftoken != ftoken_expected) {
493         ZLOGE(LABEL, "ftoken != ftoken_expected");
494         return false;
495     }
496     return true;
497 }
498 
CheckSetFirstToken(uint64_t ftoken_expected)499 bool TestServiceProxy::CheckSetFirstToken(uint64_t ftoken_expected)
500 {
501     int ret = RpcSetFirstCallerTokenID(ftoken_expected);
502     if (ret != 0) {
503         ZLOGE(LABEL, "RpcSetFirstCallerTokenID ret = %{public}d", ret);
504         return false;
505     }
506     uint64_t result = RpcGetFirstCallerTokenID();
507     if (result != ftoken_expected) {
508         ZLOGE(LABEL, "TestServiceProxy get ftoken after set: %{public}" PRIu64, result);
509         return false;
510     }
511     return true;
512 }
513 
CheckSetSelfToken(uint64_t token_expected)514 bool TestServiceProxy::CheckSetSelfToken(uint64_t token_expected)
515 {
516     int ret = RpcSetSelfTokenID(token_expected);
517     if (ret != 0) {
518         ZLOGE(LABEL, "RpcSetSelfTokenID ret = %{public}d", ret);
519         return false;
520     }
521     uint64_t result = RpcGetSelfTokenID();
522     if (result != token_expected) {
523         ZLOGE(LABEL, "TestServiceProxy get selftoken after set: %{public}" PRIu64, result);
524         return false;
525     }
526     return true;
527 }
528 
TestAccessTokenID64(uint64_t token_expected,uint64_t ftoken_expected)529 int TestServiceProxy::TestAccessTokenID64(uint64_t token_expected, uint64_t ftoken_expected)
530 {
531     MessageOption option;
532     MessageParcel dataParcel;
533     MessageParcel replyParcel1;
534     MessageParcel replyParcel2;
535     uint64_t token  = IPCSkeleton::GetCallingFullTokenID();
536     uint64_t ftoken  = IPCSkeleton::GetFirstFullTokenID();
537     uint64_t tokenSelf = IPCSkeleton::GetSelfTokenID();
538     uint64_t oldTokenSelf = tokenSelf;
539     int32_t ret = 0;
540 
541     if (!CheckTokenSelf(token, tokenSelf, ftoken, 0)) {
542         return -1;
543     }
544     if (!CheckSetFirstToken(ftoken_expected)) {
545         ret = -1;
546         goto ERR;
547     }
548     if (!CheckSetSelfToken(token_expected)) {
549         ret = -1;
550         goto ERR;
551     }
552     ret = Remote()->SendRequest(TRANS_ID_ACCESS_TOKENID_64, dataParcel, replyParcel1, option);
553     if (ret != ERR_NONE) {
554         ZLOGE(LABEL, "SendRequest ret = %{public}d", ret);
555         ret = -1;
556         goto ERR;
557     }
558     token = replyParcel1.ReadUint64();
559     ftoken = replyParcel1.ReadUint64();
560 
561     if (token != token_expected) {
562         ZLOGE(LABEL, "token != token_expected, token = %{public}" PRIu64, token);
563         ret = -1;
564         goto ERR;
565     }
566     if (ftoken != ftoken_expected) {
567         ZLOGE(LABEL, "ftoken != ftoken_expected, ftoken = %{public}" PRIu64, ftoken);
568         ret = -1;
569         goto ERR;
570     }
571 
572 ERR:
573     RpcSetFirstCallerTokenID(0);
574     RpcSetSelfTokenID(oldTokenSelf);
575     return ret;
576 }
577 
TestAccessTokenID(int32_t ftoken_expected)578 int TestServiceProxy::TestAccessTokenID(int32_t ftoken_expected)
579 {
580     MessageOption option;
581     MessageParcel dataParcel;
582     MessageParcel replyParcel1;
583     MessageParcel replyParcel2;
584 
585     int32_t token  = (int32_t)IPCSkeleton::GetCallingTokenID();
586     int32_t ftoken  = (int32_t)IPCSkeleton::GetFirstTokenID();
587     int32_t tokenSelf = RpcGetSelfTokenID();
588     ZLOGI(LABEL, "TestServiceProxy tokenSelf: %{public}d", tokenSelf);
589     ZLOGI(LABEL, "TestServiceProxy ftoken: %{public}d", ftoken);
590     ZLOGI(LABEL, "TestServiceProxy ftoken_expected: %{public}d", ftoken_expected);
591     if (!CheckTokenSelf(token, tokenSelf, ftoken, 0)) {
592         ZLOGE(LABEL, "first");
593         return -1;
594     }
595     if (!CheckSetFirstToken(ftoken_expected)) {
596         return -1;
597     }
598     int ret = Remote()->SendRequest(TRANS_ID_ACCESS_TOKENID, dataParcel, replyParcel1, option);
599     if (ret != ERR_NONE) {
600         ZLOGE(LABEL, "SendRequest ret = %{public}d", ret);
601         return ret;
602     }
603     token  = replyParcel1.ReadInt32();
604     ftoken  = replyParcel1.ReadInt32();
605     if (!CheckTokenSelf(token, tokenSelf, ftoken, ftoken_expected)) {
606         ZLOGE(LABEL, "second");
607         return -1;
608     }
609     if (!CheckSetSelfToken(666)) { // 666: test data
610         return -1;
611     }
612     ret = Remote()->SendRequest(TRANS_ID_ACCESS_TOKENID, dataParcel, replyParcel2, option);
613     if (ret != ERR_NONE) {
614         ZLOGE(LABEL, "ret = %{public}d", ret);
615         return ret;
616     }
617     token  = replyParcel2.ReadInt32();
618     ftoken  = replyParcel2.ReadInt32();
619     if (!CheckTokenSelf(token, tokenSelf, ftoken, ftoken_expected)) {
620         ZLOGE(LABEL, "third");
621         return -1;
622     }
623     ret = RpcSetFirstCallerTokenID(0);
624     ret = RpcSetSelfTokenID(0);
625     if (ret != ERR_NONE) {
626         return -1;
627     }
628     return 0;
629 }
630 
TestMessageParcelAppend(MessageParcel & dst,MessageParcel & src)631 int TestServiceProxy::TestMessageParcelAppend(MessageParcel &dst, MessageParcel &src)
632 {
633     bool res = dst.Append(src);
634     if (!res) {
635         ZLOGE(LABEL, "Message parcel append without ipc failed");
636         return -1;
637     }
638     return 0;
639 }
640 
TestMessageParcelAppendWithIpc(MessageParcel & dst,MessageParcel & src,MessageParcel & reply,bool withObject)641 int TestServiceProxy::TestMessageParcelAppendWithIpc(MessageParcel &dst, MessageParcel &src,
642     MessageParcel &reply, bool withObject)
643 {
644     bool res = dst.Append(src);
645     if (!res) {
646         ZLOGE(LABEL, "Message parcel append with ipc failed");
647         return -1;
648     }
649     MessageOption option;
650     uint32_t code = TRANS_MESSAGE_PARCEL_ADDPED;
651     if (withObject) {
652         code = TRANS_MESSAGE_PARCEL_ADDPED_WITH_OBJECT;
653     }
654     int ret = Remote()->SendRequest(code, dst, reply, option);
655     ZLOGE(LABEL, "TestMessageParcelAppend with ipc sendrequest ret = %{public}d", ret);
656     return ret;
657 }
658 
TestFlushAsyncCalls(int count,int length)659 int TestServiceProxy::TestFlushAsyncCalls(int count, int length)
660 {
661     int ret;
662     MessageOption option = { MessageOption::TF_ASYNC };
663     MessageParcel dataParcel;
664     MessageParcel replyParcel;
665     std::u16string legalData(length, 'a');
666     dataParcel.WriteString16(legalData);
667     for (int i = 0; i < count; i++) {
668         ret = Remote()->SendRequest(TRANS_ID_FLUSH_ASYNC_CALLS, dataParcel, replyParcel, option);
669         if (ret != ERR_NONE) {
670             ZLOGE(LABEL, "Fail to send request when count = %{public}d, ret = %{public}d", count, ret);
671             return ret;
672         }
673     }
674 
675     ret = IPCSkeleton::FlushCommands(this->AsObject());
676     return ret;
677 }
678 
TestMultipleProcesses(int data,int & rep,int delayTime)679 int TestServiceProxy::TestMultipleProcesses(int data, int &rep, int delayTime)
680 {
681     int ret;
682     MessageOption option;
683     MessageParcel dataParcel;
684     MessageParcel replyParcel;
685     ZLOGI(LABEL, "Send to server data = %{public}d", data);
686     if (data > 0) {
687         dataParcel.WriteInt32(data);
688         dataParcel.WriteInt32(delayTime);
689     }
690     ret = Remote()->SendRequest(TRANS_ID_MULTIPLE_PROCESSES, dataParcel, replyParcel, option);
691     rep = replyParcel.ReadInt32();
692     ret += replyParcel.ReadInt32();
693     return ret;
694 }
695 
TestAshmem(sptr<Ashmem> ashmem,int32_t contentSize)696 std::u16string TestServiceProxy::TestAshmem(sptr<Ashmem> ashmem, int32_t contentSize)
697 {
698     if (ashmem == nullptr || contentSize <= 0) {
699         return u"";
700     }
701 
702     MessageOption option;
703     MessageParcel dataParcel;
704     MessageParcel replyParcel;
705     if (!dataParcel.WriteInt32(contentSize) || !dataParcel.WriteAshmem(ashmem)) {
706         return u"";
707     }
708 
709     int ret = Remote()->SendRequest(TRANS_ID_ASHMEM, dataParcel, replyParcel, option);
710     if (ret != ERR_NONE) {
711         return u"";
712     }
713 
714     int32_t readContentSize = replyParcel.ReadInt32();
715     if (readContentSize <= 0) {
716         return u"";
717     }
718 
719     sptr<Ashmem> ashmem2 = replyParcel.ReadAshmem();
720     if (ashmem2 == nullptr || !ashmem2->MapReadAndWriteAshmem()) {
721         return u"";
722     }
723 
724     const void *content = ashmem2->ReadFromAshmem(readContentSize, 0);
725     if (content == nullptr) {
726         ashmem2->UnmapAshmem();
727         return u"";
728     }
729 
730     auto readContent = static_cast<const char *>(content);
731     std::string str(readContent, readContentSize);
732 
733     ashmem2->UnmapAshmem();
734     ashmem2->CloseAshmem();
735     return Str8ToStr16(str);
736 }
737 
TestNestingSend(int sendCode,int & replyCode)738 int TestServiceProxy::TestNestingSend(int sendCode, int &replyCode)
739 {
740     ZLOGW(LABEL, "Start");
741     MessageOption option;
742     MessageParcel dataParcel;
743     MessageParcel replyParcel;
744     sptr<IFoo> foo = new FooStub();
745     sptr<IRemoteObject> sendFoo = foo->AsObject();
746     sendFoo->SetBehavior(Parcelable::BehaviorFlag::HOLD_OBJECT);
747     if (!dataParcel.WriteRemoteObject(sendFoo) || !dataParcel.WriteInt32(sendCode)) {
748         ZLOGE(LABEL, "Fail to write data.");
749         return -1;
750     }
751     int ret = Remote()->SendRequest(TRANS_ID_NESTING_SEND, dataParcel, replyParcel, option);
752     replyCode = replyParcel.ReadInt32();
753     ZLOGW(LABEL, "Outer = %{public}d, inner = %{public}d", ret, replyCode);
754     return ret;
755 }
756 
TestQueryThreadInvocationState()757 int TestServiceProxy::TestQueryThreadInvocationState()
758 {
759     MessageOption option;
760     MessageParcel dataParcel;
761     MessageParcel replyParcel;
762 
763     int state = IPCSkeleton::GetThreadInvocationState();
764     ZLOGI(LABEL, "Thread state = %{public}d", state);
765 
766     auto remote = Remote();
767     if (remote == nullptr) {
768         ZLOGI(LABEL, "The obtained proxy is a null pointer");
769         return -1;
770     }
771 
772     int ret = remote->SendRequest(TRANS_ID_QUERY_THREAD_INVOCATION_STATE, dataParcel, replyParcel, option);
773     int reply = replyParcel.ReadInt32();
774     ZLOGI(LABEL, "Get result from server data = %{public}d %{public}d", reply, ret);
775     if (reply != STATUS_FIRST_INVOKE) {
776         ret = ERR_TRANSACTION_FAILED;
777     }
778     return ret;
779 }
780 }  // namespace OHOS
781