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