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_skeleton.h"
17 #include <cinttypes>
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <sys/ioctl.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include "access_token_adapter.h"
26 #include "ipc_debug.h"
27 #include "string_ex.h"
28 #include "iremote_proxy.h"
29 #include "ipc_skeleton.h"
30 #include "ipc_file_descriptor.h"
31 #include "ipc_test_helper.h"
32 #include "if_system_ability_manager.h"
33 #include "iservice_registry.h"
34 #include "system_ability_definition.h"
35
36 namespace OHOS {
37 using namespace OHOS::HiviewDFX;
38
TestServiceProxy(const sptr<IRemoteObject> & impl)39 TestServiceProxy::TestServiceProxy(const sptr<IRemoteObject> &impl)
40 : IRemoteProxy<ITestService>(impl)
41 {
42 }
43
TestSyncTransaction(int data,int & reply,int delayTime)44 int TestServiceProxy::TestSyncTransaction(int data, int &reply, int delayTime)
45 {
46 int error;
47 MessageOption option;
48 MessageParcel dataParcel, replyParcel;
49 ZLOGD(LABEL, "send to server data = %{public}d", data);
50 if (data > 0) {
51 dataParcel.WriteInt32(data);
52 dataParcel.WriteInt32(delayTime);
53 }
54 error = Remote()->SendRequest(TRANS_ID_SYNC_TRANSACTION, dataParcel, replyParcel, option);
55 reply = replyParcel.ReadInt32();
56 ZLOGD(LABEL, "get result from server data = %{public}d", reply);
57 return error;
58 }
59
TestAsyncTransaction(int data,int timeout)60 int TestServiceProxy::TestAsyncTransaction(int data, int timeout)
61 {
62 MessageOption option = { MessageOption::TF_ASYNC };
63 MessageParcel dataParcel, replyParcel;
64 ZLOGD(LABEL, "%{public}s:in, data = %{public}d", __func__, data);
65 dataParcel.WriteInt32(data);
66 dataParcel.WriteInt32(timeout);
67 dataParcel.WriteBool(false);
68 return Remote()->SendRequest(TRANS_ID_ASYNC_TRANSACTION, dataParcel, replyParcel, option);
69 }
70
TestAsyncCallbackTrans(int data,int & reply,int timeout)71 int TestServiceProxy::TestAsyncCallbackTrans(int data, int &reply, int timeout)
72 {
73 int error;
74 MessageOption option = { MessageOption::TF_ASYNC };
75 MessageParcel dataParcel, replyParcel;
76 ZLOGD(LABEL, "%{public}s:in, data = %{public}d", __func__, data);
77 dataParcel.WriteInt32(data);
78 dataParcel.WriteInt32(timeout);
79 dataParcel.WriteBool(true);
80 sptr<FooStub> fooCallback = new FooStub();
81 dataParcel.WriteRemoteObject(fooCallback->AsObject());
82 error = Remote()->SendRequest(TRANS_ID_ASYNC_TRANSACTION, dataParcel, replyParcel, option);
83 reply = fooCallback->WaitForAsyncReply(timeout);
84
85 FooStub::CleanDecTimes();
86 fooCallback = nullptr;
87 if (FooStub::GetDecTimes() != 1) {
88 error = ERR_TRANSACTION_FAILED;
89 }
90 return error;
91 }
92
TestZtraceTransaction(std::string & send,std::string & reply,int len)93 int TestServiceProxy::TestZtraceTransaction(std::string &send, std::string &reply, int len)
94 {
95 int error;
96 MessageParcel dataParcel, replyParcel;
97 MessageOption option;
98
99 dataParcel.WriteInt32(len);
100 dataParcel.WriteString(send);
101 error = Remote()->SendRequest(TRANS_ID_ZTRACE_TRANSACTION, dataParcel, replyParcel, option);
102 reply = replyParcel.ReadString();
103
104 return error;
105 }
106
TestPingService(const std::u16string & serviceName)107 int TestServiceProxy::TestPingService(const std::u16string &serviceName)
108 {
109 int error;
110 MessageOption option;
111 MessageParcel dataParcel, replyParcel;
112 ZLOGD(LABEL, "PingService");
113 dataParcel.WriteString16(serviceName);
114 error = Remote()->SendRequest(TRANS_ID_PING_SERVICE, dataParcel, replyParcel, option);
115 int result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1;
116 ZLOGD(LABEL, "PingService result = %d", result);
117 return result;
118 }
119
TestGetFooService()120 sptr<IFoo> TestServiceProxy::TestGetFooService()
121 {
122 MessageOption option;
123 MessageParcel dataParcel, replyParcel;
124 Remote()->SendRequest(TRANS_ID_GET_FOO_SERVICE, dataParcel, replyParcel, option);
125 auto rep = replyParcel.ReadRemoteObject();
126 if (rep == nullptr) {
127 ZLOGE(LABEL, "null foo service");
128 return nullptr;
129 }
130 return iface_cast<IFoo>(rep);
131 }
132
TestGetFileDescriptor()133 int TestServiceProxy::TestGetFileDescriptor()
134 {
135 MessageOption option;
136 MessageParcel dataParcel, replyParcel;
137 sptr<IPCFileDescriptor> desc;
138 option.SetFlags(MessageOption::TF_ACCEPT_FDS);
139 Remote()->SendRequest(TRANS_ID_TRANSACT_FILE_DESC, dataParcel, replyParcel, option);
140 int fd = replyParcel.ReadFileDescriptor();
141 return fd;
142 }
143
TestStringTransaction(const std::string & data)144 int TestServiceProxy::TestStringTransaction(const std::string &data)
145 {
146 MessageOption option;
147 MessageParcel dataParcel, replyParcel;
148 dataParcel.WriteString(data);
149 Remote()->SendRequest(TRANS_ID_STRING_TRANSACTION, dataParcel, replyParcel, option);
150 int testSize = replyParcel.ReadInt32();
151 return testSize;
152 }
153
TestDumpService()154 void TestServiceProxy::TestDumpService()
155 {
156 ZLOGD(LABEL, "call StartDumpService");
157 int fd = open("/data/dump.txt",
158 O_RDWR | O_APPEND | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
159 if (fd != INVALID_FD) {
160 ZLOGD(LABEL, "Start Dump Service");
161 std::vector<std::u16string> args;
162 args.push_back(u"DumpTest");
163 Remote()->Dump(fd, args);
164 close(fd);
165 }
166 }
167
TestAsyncDumpService()168 void TestServiceProxy::TestAsyncDumpService()
169 {
170 int fd = open("/data/nonblockingDump.txt",
171 O_RDWR | O_APPEND | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
172 if (fd == INVALID_FD) {
173 return;
174 }
175
176 ZLOGD(LABEL, "Start Async Dump Service");
177 std::vector<std::u16string> args;
178 args.push_back(u"NonblockingDumpTest");
179 MessageParcel data, reply;
180 MessageOption option {MessageOption::TF_ASYNC};
181 data.WriteFileDescriptor(fd);
182 data.WriteString16Vector(args);
183 (void)Remote()->SendRequest(DUMP_TRANSACTION, data, reply, option);
184 close(fd);
185 }
186
TestRawDataTransaction(int length,int & reply)187 int TestServiceProxy::TestRawDataTransaction(int length, int &reply)
188 {
189 int error;
190 MessageOption option;
191 MessageParcel dataParcel, replyParcel;
192 ZLOGE(LABEL, "send to server data length = %{public}d", length);
193 if (length <= 1 || static_cast<unsigned>(length) > dataParcel.GetRawDataCapacity()) {
194 ZLOGE(LABEL, "length should > 1, length is %{public}d", length);
195 return -1;
196 }
197 unsigned char *buffer = new (std::nothrow) unsigned char[length];
198 if (buffer == nullptr) {
199 ZLOGE(LABEL, "new buffer failed of length = %{public}d", length);
200 return -1;
201 }
202 buffer[0] = 'a';
203 buffer[length - 1] = 'z';
204
205 dataParcel.WriteInt32(length);
206 dataParcel.WriteRawData(buffer, length);
207 dataParcel.WriteInt32(length);
208 error = Remote()->SendRequest(TRANS_ID_RAWDATA_TRANSACTION, dataParcel, replyParcel, option);
209 reply = replyParcel.ReadInt32();
210 ZLOGE(LABEL, "get result from server data = %{public}d", reply);
211 delete [] buffer;
212 return error;
213 }
214
TestRawDataReply(int length)215 int TestServiceProxy::TestRawDataReply(int length)
216 {
217 MessageOption option;
218 MessageParcel dataParcel, replyParcel;
219 if (length <= 1 || static_cast<unsigned>(length) > dataParcel.GetRawDataCapacity()) {
220 ZLOGE(LABEL, "length should > 1, length is %{public}d", length);
221 return ERR_INVALID_STATE;
222 }
223
224 if (!dataParcel.WriteInt32(length)) {
225 ZLOGE(LABEL, "fail to write parcel");
226 return ERR_INVALID_STATE;
227 }
228
229 int ret = Remote()->SendRequest(TRANS_ID_RAWDATA_REPLY, dataParcel, replyParcel, option);
230 if (ret != ERR_NONE) {
231 ZLOGE(LABEL, "ret = %{public}d", ret);
232 return ret;
233 }
234
235 if (replyParcel.ReadInt32() != length) {
236 ZLOGE(LABEL, "reply false data");
237 return ERR_INVALID_DATA;
238 }
239
240 if (!replyParcel.ContainFileDescriptors()) {
241 ZLOGE(LABEL, "replied raw data is less than 32k");
242 }
243
244 const char *buffer = nullptr;
245 if ((buffer = reinterpret_cast<const char *>(replyParcel.ReadRawData((size_t)length))) == nullptr) {
246 ZLOGE(LABEL, "read raw data failed, length = %{public}d", length);
247 return ERR_INVALID_DATA;
248 }
249 if (buffer[0] != 'a' || buffer[length - 1] != 'z') {
250 ZLOGE(LABEL, "buffer error, length = %{public}d", length);
251 return ERR_INVALID_DATA;
252 }
253
254 if (replyParcel.ReadInt32() != length) {
255 ZLOGE(LABEL, "read raw data after failed, length = %{public}d", length);
256 return ERR_INVALID_DATA;
257 }
258
259 return ERR_NONE;
260 }
261
TestCallingUidPid()262 int TestServiceProxy::TestCallingUidPid()
263 {
264 MessageOption option;
265 MessageParcel dataParcel, replyParcel;
266 int ret = Remote()->SendRequest(TRANS_ID_CALLING_UID_PID, dataParcel, replyParcel, option);
267 if (ret != ERR_NONE) {
268 ZLOGE(LABEL, "ret = %{public}d", ret);
269 return ret;
270 }
271
272 int uid = replyParcel.ReadInt32();
273 int pid = replyParcel.ReadInt32();
274
275 IPCTestHelper helper;
276 int actualUid = static_cast<int>(helper.GetUid());
277 int actualPid = static_cast<int>(helper.GetPid());
278 ZLOGD(LABEL, "uid = %{public}d, pid = %{public}d, actualUid = %{public}d, actualPid = %{public}d",
279 uid, pid, actualUid, actualPid);
280
281 if (uid == actualUid && pid == actualPid) {
282 return 0;
283 }
284 return -1;
285 }
286
287 constexpr char ACCESS_TOKEN_ID_IOCTL_BASE = 'A';
288
289 enum {
290 GET_TOKEN_ID = 1,
291 SET_TOKEN_ID,
292 GET_FTOKEN_ID,
293 SET_FTOKEN_ID,
294 ACCESS_TOKENID_MAX_NR,
295 };
296
297 #define ACCESS_TOKENID_SET_TOKENID \
298 _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, SET_TOKEN_ID, unsigned long long)
299 #define ACCESS_TOKENID_SET_FTOKENID \
300 _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, SET_FTOKEN_ID, unsigned long long)
301
302 constexpr int ACCESS_TOKEN_OK = 0;
303 constexpr int ACCESS_TOKEN_ERROR = -1;
304
305 constexpr char TOKENID_DEVNODE[] = "/dev/access_token_id";
306
RpcSetSelfTokenID(uint64_t tokenID)307 int RpcSetSelfTokenID(uint64_t tokenID)
308 {
309 int fd = open(TOKENID_DEVNODE, O_RDWR);
310 if (fd < 0) {
311 return ACCESS_TOKEN_ERROR;
312 }
313 int ret = ioctl(fd, ACCESS_TOKENID_SET_TOKENID, &tokenID);
314 if (ret) {
315 close(fd);
316 return ACCESS_TOKEN_ERROR;
317 }
318
319 close(fd);
320 return ACCESS_TOKEN_OK;
321 }
322
RpcSetFirstCallerTokenID(uint64_t tokenID)323 int RpcSetFirstCallerTokenID(uint64_t tokenID)
324 {
325 int fd = open(TOKENID_DEVNODE, O_RDWR);
326 if (fd < 0) {
327 return ACCESS_TOKEN_ERROR;
328 }
329 int ret = ioctl(fd, ACCESS_TOKENID_SET_FTOKENID, &tokenID);
330 if (ret) {
331 close(fd);
332 return ACCESS_TOKEN_ERROR;
333 }
334
335 close(fd);
336 return ACCESS_TOKEN_OK;
337 }
338
TestAccessTokenID64(uint64_t token_expected,uint64_t ftoken_expected)339 int TestServiceProxy::TestAccessTokenID64(uint64_t token_expected, uint64_t ftoken_expected)
340 {
341 MessageOption option;
342 MessageParcel dataParcel, replyParcel1, replyParcel2;
343 uint64_t token = IPCSkeleton::GetCallingFullTokenID();
344 uint64_t ftoken = IPCSkeleton::GetFirstFullTokenID();
345 uint64_t tokenSelf = IPCSkeleton::GetSelfTokenID();
346 uint64_t oldTokenSelf = tokenSelf;
347 int32_t ret = 0;
348
349 if (token != tokenSelf) {
350 ZLOGE(LABEL, "token != tokenSelf");
351 return -1;
352 }
353 if (ftoken != 0) {
354 ZLOGE(LABEL, "ftoken != 0");
355 return -1;
356 }
357
358 if (RpcSetFirstCallerTokenID(ftoken_expected) != 0) {
359 ZLOGE(LABEL, "RpcSetFirstCallerTokenID err");
360 ret = -1;
361 goto ERR;
362 }
363 if (RpcGetFirstCallerTokenID() != ftoken_expected) {
364 ZLOGE(LABEL, "RpcGetFirstCallerTokenID err");
365 ret = -1;
366 goto ERR;
367 }
368
369 if (RpcSetSelfTokenID(token_expected) != 0) {
370 ZLOGE(LABEL, "RpcSetSelfTokenID err");
371 ret = -1;
372 goto ERR;
373 }
374 if (RpcGetSelfTokenID() != token_expected) {
375 ZLOGE(LABEL, "RpcGetSelfTokenID err");
376 ret = -1;
377 goto ERR;
378 }
379 ret = Remote()->SendRequest(TRANS_ID_ACCESS_TOKENID_64, dataParcel, replyParcel1, option);
380 if (ret != ERR_NONE) {
381 ZLOGE(LABEL, "SendRequest ret = %{public}d", ret);
382 ret = -1;
383 goto ERR;
384 }
385 token = replyParcel1.ReadUint64();
386 ftoken = replyParcel1.ReadUint64();
387
388 if (token != token_expected) {
389 ZLOGE(LABEL, "token != token_expected, token:%{public}" PRIu64, token);
390 ret = -1;
391 goto ERR;
392 }
393 if (ftoken != ftoken_expected) {
394 ZLOGE(LABEL, "ftoken != ftoken_expected, ftoken:%{public}" PRIu64, ftoken);
395 ret = -1;
396 goto ERR;
397 }
398
399 ERR:
400 RpcSetFirstCallerTokenID(0);
401 RpcSetSelfTokenID(oldTokenSelf);
402 return ret;
403 }
404
TestAccessTokenID(int32_t ftoken_expected)405 int TestServiceProxy::TestAccessTokenID(int32_t ftoken_expected)
406 {
407 MessageOption option;
408 MessageParcel dataParcel, replyParcel1, replyParcel2;
409
410 int32_t token = (int32_t)IPCSkeleton::GetCallingTokenID();
411 int32_t ftoken = (int32_t)IPCSkeleton::GetFirstTokenID();
412 int32_t tokenSelf = RpcGetSelfTokenID();
413 ZLOGE(LABEL, "TestServiceProxy tokenSelf: %{public}d", tokenSelf);
414 ZLOGE(LABEL, "TestServiceProxy ftoken: %{public}d", ftoken);
415 ZLOGE(LABEL, "TestServiceProxy ftoken_expected: %{public}d", ftoken_expected);
416
417 if (token != tokenSelf) {
418 ZLOGE(LABEL, "token != tokenSelf 1, token:%{public}d", token);
419 return -1;
420 }
421
422 if (ftoken != 0) {
423 ZLOGE(LABEL, "ftoken != 0 1");
424 return -1;
425 }
426
427 int ret = RpcSetFirstCallerTokenID(ftoken_expected);
428 if (ret != 0) {
429 ZLOGE(LABEL, "RpcSetFirstCallerTokenID ret = %{public}d", ret);
430 return -1;
431 }
432
433 ret = RpcGetFirstCallerTokenID();
434 ZLOGE(LABEL, "TestServiceProxy get ftoken after set: %{public}d", ret);
435
436 ret = Remote()->SendRequest(TRANS_ID_ACCESS_TOKENID, dataParcel, replyParcel1, option);
437 if (ret != ERR_NONE) {
438 ZLOGE(LABEL, "SendRequest ret = %{public}d", ret);
439 return ret;
440 }
441
442 token = replyParcel1.ReadInt32();
443 ftoken = replyParcel1.ReadInt32();
444
445 if (token != tokenSelf) {
446 ZLOGE(LABEL, "token != tokenSelf 2, token:%{public}d", token);
447 return -1;
448 }
449
450 if (ftoken != ftoken_expected) {
451 ZLOGE(LABEL, "ftoken != ftoken_expected 2, ftoken:%{public}d", ftoken);
452 return -1;
453 }
454
455 ret = RpcSetSelfTokenID(666);
456 if (ret != 0) {
457 ZLOGE(LABEL, "RpcSetSelfTokenID ret = %{public}d", ret);
458 return -1;
459 }
460
461 tokenSelf = RpcGetSelfTokenID();
462 ZLOGE(LABEL, "TestServiceProxy get token after set: %{public}d", tokenSelf);
463 ret = Remote()->SendRequest(TRANS_ID_ACCESS_TOKENID, dataParcel, replyParcel2, option);
464 if (ret != ERR_NONE) {
465 ZLOGE(LABEL, "ret = %{public}d", ret);
466 return ret;
467 }
468
469 token = replyParcel2.ReadInt32();
470 ftoken = replyParcel2.ReadInt32();
471
472 if (token != tokenSelf) {
473 ZLOGE(LABEL, "token != tokenSelf 3, token:%{public}d", token);
474 return -1;
475 }
476
477 if (ftoken != ftoken_expected) {
478 ZLOGE(LABEL, "ftoken != ftoken_expected 3, ftoken:%{public}d", ftoken);
479 return -1;
480 }
481
482 ret = RpcSetFirstCallerTokenID(0);
483 if (ret != 0) {
484 ZLOGE(LABEL, "RpcSetFirstCallerTokenID ret = %{public}d", ret);
485 return -1;
486 }
487
488 ret = RpcSetSelfTokenID(0);
489 if (ret != 0) {
490 ZLOGE(LABEL, "RpcSetSelfTokenID ret = %{public}d", ret);
491 return -1;
492 }
493 return 0;
494 }
495
TestMessageParcelAppend(MessageParcel & dst,MessageParcel & src)496 int TestServiceProxy::TestMessageParcelAppend(MessageParcel &dst, MessageParcel &src)
497 {
498 bool res = dst.Append(src);
499 if (!res) {
500 ZLOGE(LABEL, "message parcel append without ipc failed");
501 return -1;
502 }
503 return 0;
504 }
505
TestMessageParcelAppendWithIpc(MessageParcel & dst,MessageParcel & src,MessageParcel & reply,bool withObject)506 int TestServiceProxy::TestMessageParcelAppendWithIpc(MessageParcel &dst, MessageParcel &src,
507 MessageParcel &reply, bool withObject)
508 {
509 bool res = dst.Append(src);
510 if (!res) {
511 ZLOGE(LABEL, "message parcel append with ipc failed");
512 return -1;
513 }
514 MessageOption option;
515 uint32_t code = TRANS_MESSAGE_PARCEL_ADDPED;
516 if (withObject) {
517 code = TRANS_MESSAGE_PARCEL_ADDPED_WITH_OBJECT;
518 }
519 int ret = Remote()->SendRequest(code, dst, reply, option);
520 ZLOGE(LABEL, "TestMessageParcelAppend with ipc sendrequest ret = %{public}d", ret);
521 return ret;
522 }
523
TestFlushAsyncCalls(int count,int length)524 int TestServiceProxy::TestFlushAsyncCalls(int count, int length)
525 {
526 int ret;
527 MessageOption option = { MessageOption::TF_ASYNC };
528 MessageParcel dataParcel, replyParcel;
529 std::u16string legalData(length, 'a');
530 dataParcel.WriteString16(legalData);
531 for (int i = 0; i < count; i++) {
532 ret = Remote()->SendRequest(TRANS_ID_FLUSH_ASYNC_CALLS, dataParcel, replyParcel, option);
533 if (ret != ERR_NONE) {
534 ZLOGE(LABEL, "fail to send request when count = %{public}d, ret = %{public}d", count, ret);
535 return ret;
536 }
537 }
538
539 ret = IPCSkeleton::FlushCommands(this->AsObject());
540 return ret;
541 }
542
TestMultipleProcesses(int data,int & rep,int delayTime)543 int TestServiceProxy::TestMultipleProcesses(int data, int &rep, int delayTime)
544 {
545 int error;
546 MessageOption option;
547 MessageParcel dataParcel, replyParcel;
548 ZLOGD(LABEL, "send to server data = %{public}d", data);
549 if (data > 0) {
550 dataParcel.WriteInt32(data);
551 dataParcel.WriteInt32(delayTime);
552 }
553 error = Remote()->SendRequest(TRANS_ID_MULTIPLE_PROCESSES, dataParcel, replyParcel, option);
554 rep = replyParcel.ReadInt32();
555 error += replyParcel.ReadInt32();
556 return error;
557 }
558
TestAshmem(sptr<Ashmem> ashmem,int32_t contentSize)559 std::u16string TestServiceProxy::TestAshmem(sptr<Ashmem> ashmem, int32_t contentSize)
560 {
561 if (ashmem == nullptr || contentSize <= 0) {
562 return u"";
563 }
564
565 MessageOption option;
566 MessageParcel dataParcel, replyParcel;
567 if (!dataParcel.WriteInt32(contentSize) || !dataParcel.WriteAshmem(ashmem)) {
568 return u"";
569 }
570
571 int error = Remote()->SendRequest(TRANS_ID_ASHMEM, dataParcel, replyParcel, option);
572 if (error != ERR_NONE) {
573 return u"";
574 }
575
576 int32_t readContentSize = replyParcel.ReadInt32();
577 if (readContentSize <= 0) {
578 return u"";
579 }
580
581 sptr<Ashmem> ashmem2 = replyParcel.ReadAshmem();
582 if (ashmem2 == nullptr || !ashmem2->MapReadAndWriteAshmem()) {
583 return u"";
584 }
585
586 const void *content = ashmem2->ReadFromAshmem(readContentSize, 0);
587 if (content == nullptr) {
588 ashmem2->UnmapAshmem();
589 return u"";
590 }
591
592 auto readContent = static_cast<const char *>(content);
593 std::string str(readContent, readContentSize);
594
595 ashmem2->UnmapAshmem();
596 ashmem2->CloseAshmem();
597 return Str8ToStr16(str);
598 }
599
TestNestingSend(int sendCode,int & replyCode)600 int TestServiceProxy::TestNestingSend(int sendCode, int &replyCode)
601 {
602 ZLOGW(LABEL, "%{public}s", __func__);
603 MessageOption option;
604 MessageParcel dataParcel, replyParcel;
605 sptr<IFoo> foo = new FooStub();
606 sptr<IRemoteObject> sendFoo = foo->AsObject();
607 sendFoo->SetBehavior(Parcelable::BehaviorFlag::HOLD_OBJECT);
608 if (!dataParcel.WriteRemoteObject(sendFoo) || !dataParcel.WriteInt32(sendCode)) {
609 ZLOGE(LABEL, "%{public}s: fail to write data", __func__);
610 return -1;
611 }
612 int error = Remote()->SendRequest(TRANS_ID_NESTING_SEND, dataParcel, replyParcel, option);
613 replyCode = replyParcel.ReadInt32();
614 ZLOGW(LABEL, "%{public}s: outer = %{public}d, inner = %{public}d", __func__, error, replyCode);
615 return error;
616 }
617
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)618 int TestServiceStub::OnRemoteRequest(uint32_t code,
619 MessageParcel &data, MessageParcel &reply, MessageOption &option)
620 {
621 int ret = 0;
622 int result = 0;
623 ZLOGD(LABEL, "OnRemoteRequest, cmd = %{public}d, flags= %{public}d", code, option.GetFlags());
624 switch (code) {
625 case TRANS_ID_SYNC_TRANSACTION: {
626 int32_t reqData = data.ReadInt32();
627 int32_t delayTime = data.ReadInt32();
628 ret = TestSyncTransaction(reqData, result, delayTime);
629 reply.WriteInt32(result);
630 break;
631 }
632 case TRANS_ID_ASYNC_TRANSACTION: {
633 int32_t reqData = data.ReadInt32();
634 int timeout = data.ReadInt32();
635 bool acquireResult = data.ReadBool();
636 if (acquireResult) {
637 sptr<IFoo> fooProxy = iface_cast<IFoo>(data.ReadRemoteObject());
638 if (fooProxy != nullptr) {
639 TestAsyncCallbackTrans(reqData, result, timeout);
640 fooProxy->SendAsyncReply(result);
641 }
642 } else {
643 (void)TestAsyncTransaction(reqData, timeout);
644 }
645 break;
646 }
647 case TRANS_ID_PING_SERVICE: {
648 std::u16string serviceName = data.ReadString16();
649 result = TestPingService(serviceName);
650 ZLOGD(LABEL, "%s:PingService: result=%d", __func__, result);
651 reply.WriteInt32(result);
652 break;
653 }
654 case TRANS_ID_GET_FOO_SERVICE: {
655 sptr<IFoo> fooService = TestGetFooService();
656 sptr<IRemoteObject> object = fooService->AsObject();
657 object->SetBehavior(Parcelable::BehaviorFlag::HOLD_OBJECT);
658 reply.WriteRemoteObject(object);
659 break;
660 }
661 case TRANS_ID_TRANSACT_FILE_DESC: {
662 int desc = TestGetFileDescriptor();
663 reply.WriteFileDescriptor(desc);
664 close(desc);
665 break;
666 }
667 case TRANS_ID_STRING_TRANSACTION: {
668 const std::string testString = data.ReadString();
669 int testSize = TestStringTransaction(testString);
670 reply.WriteInt32(testSize);
671 reply.WriteString(testString);
672 break;
673 }
674 case TRANS_ID_ZTRACE_TRANSACTION: {
675 int32_t len = data.ReadInt32();
676 if (len < 0) {
677 ZLOGE(LABEL, "%s:get len failed, len = %d", __func__, len);
678 break;
679 }
680 std::string recvString;
681 std::string replyString(len, 0);
682 recvString = data.ReadString();
683 ret = TestZtraceTransaction(recvString, replyString, len);
684 if (!ret) {
685 reply.WriteString(replyString);
686 }
687 break;
688 }
689 case TRANS_ID_RAWDATA_TRANSACTION: {
690 ret = TransferRawData(data, reply);
691 break;
692 }
693 case TRANS_ID_RAWDATA_REPLY: {
694 ret = ReplyRawData(data, reply);
695 break;
696 }
697 case TRANS_ID_CALLING_UID_PID: {
698 reply.WriteInt32(IPCSkeleton::GetCallingUid());
699 reply.WriteInt32(IPCSkeleton::GetCallingPid());
700
701 ZLOGE(LABEL, "calling before reset uid = %{public}d, pid = %{public}d",
702 IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingPid());
703 std::string token = IPCSkeleton::ResetCallingIdentity();
704
705 ZLOGE(LABEL, "calling before set uid = %{public}d, pid = %{public}d",
706 IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingPid());
707 if (!IPCSkeleton::SetCallingIdentity(token)) {
708 ZLOGE(LABEL, "Set Calling Identity fail");
709 break;
710 }
711
712 ZLOGE(LABEL, "calling after set uid = %{public}d, pid = %{public}d",
713 IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingPid());
714 break;
715 }
716 case TRANS_ID_FLUSH_ASYNC_CALLS: {
717 (void)data.ReadString16();
718 break;
719 }
720 case TRANS_ID_MULTIPLE_PROCESSES: {
721 TransferToNextProcess(data, reply);
722 break;
723 }
724 case TRANS_ID_ASHMEM: {
725 ReadAshmem(data, reply);
726 break;
727 }
728 case TRANS_ID_NESTING_SEND: {
729 sptr<IRemoteObject> object = data.ReadRemoteObject();
730 sptr<IFoo> foo = iface_cast<IFoo>(object);
731 int innerResult = foo->TestNestingSend(data.ReadInt32());
732 reply.WriteInt32(innerResult);
733 break;
734 }
735 case TRANS_ID_ACCESS_TOKENID: {
736 int32_t token = (int32_t)IPCSkeleton::GetCallingTokenID();
737 int32_t ftoken = (int32_t)IPCSkeleton::GetFirstTokenID();
738 ZLOGE(LABEL, "server GetCallingTokenID:%{public}d", token);
739 ZLOGE(LABEL, "server GetFirstTokenID:%{public}d", ftoken);
740 reply.WriteInt32(token);
741 reply.WriteInt32(ftoken);
742 break;
743 }
744 case TRANS_ID_ACCESS_TOKENID_64: {
745 uint64_t token = IPCSkeleton::GetCallingFullTokenID();
746 uint64_t ftoken = IPCSkeleton::GetFirstFullTokenID();
747 ZLOGE(LABEL, "server GetCallingFullTokenID:%{public}" PRIu64, token);
748 ZLOGE(LABEL, "server GetFirstFullTokenID:%{public}" PRIu64, ftoken);
749 reply.WriteUint64(token);
750 reply.WriteUint64(ftoken);
751 break;
752 }
753 case TRANS_MESSAGE_PARCEL_ADDPED: {
754 reply.WriteInt32(data.ReadInt32());
755 reply.WriteInt32(data.ReadInt32());
756 reply.WriteString(data.ReadString());
757 break;
758 }
759 case TRANS_MESSAGE_PARCEL_ADDPED_WITH_OBJECT: {
760 reply.WriteInt32(data.ReadInt32());
761 reply.WriteInt32(data.ReadInt32());
762 reply.WriteString(data.ReadString());
763 reply.WriteRemoteObject(data.ReadRemoteObject());
764 reply.WriteFileDescriptor(data.ReadFileDescriptor());
765 break;
766 }
767 default:
768 ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option);
769 break;
770 }
771
772 return ret;
773 }
774
TransferRawData(MessageParcel & data,MessageParcel & reply)775 int TestServiceStub::TransferRawData(MessageParcel &data, MessageParcel &reply)
776 {
777 ZLOGD(LABEL, "enter transfer raw data");
778 int length = data.ReadInt32();
779 if (length <= 1) {
780 ZLOGE(LABEL, "%{public}s: length should > 1, length is %{public}d", __func__, length);
781 if (!reply.WriteInt32(length)) {
782 ZLOGE(LABEL, "fail to write parcel");
783 }
784 return ERR_INVALID_DATA;
785 }
786
787 if (!data.ContainFileDescriptors()) {
788 ZLOGE(LABEL, "sent raw data is less than 32k");
789 }
790
791 const char *buffer = nullptr;
792 if ((buffer = reinterpret_cast<const char *>(data.ReadRawData((size_t)length))) == nullptr) {
793 ZLOGE(LABEL, "%{public}s:read raw data failed, length = %{public}d", __func__, length);
794 if (reply.WriteInt32(0)) {
795 ZLOGE(LABEL, "fail to write parcel");
796 }
797 return ERR_INVALID_DATA;
798 }
799 if (buffer[0] != 'a' || buffer[length - 1] != 'z') {
800 ZLOGE(LABEL, "%{public}s:buffer error, length = %{public}d", __func__, length);
801 if (reply.WriteInt32(0)) {
802 ZLOGE(LABEL, "fail to write parcel");
803 }
804 return ERR_INVALID_DATA;
805 }
806 if (data.ReadInt32() != length) {
807 ZLOGE(LABEL, "%{public}s:read raw data after failed, length = %{public}d", __func__, length);
808 if (!reply.WriteInt32(0)) {
809 ZLOGE(LABEL, "fail to write parcel");
810 }
811 return ERR_INVALID_DATA;
812 }
813 if (!reply.WriteInt32(length)) {
814 ZLOGE(LABEL, "fail to write parcel");
815 return ERR_INVALID_DATA;
816 }
817 return ERR_NONE;
818 }
819
ReplyRawData(MessageParcel & data,MessageParcel & reply)820 int TestServiceStub::ReplyRawData(MessageParcel &data, MessageParcel &reply)
821 {
822 ZLOGD(LABEL, "enter reply raw data");
823 int length = data.ReadInt32();
824 if (length <= 1) {
825 ZLOGE(LABEL, "%{public}s: length should > 1, length is %{public}d", __func__, length);
826 if (!reply.WriteInt32(length)) {
827 ZLOGE(LABEL, "fail to write parcel");
828 }
829 return ERR_INVALID_DATA;
830 }
831
832 unsigned char *buffer = new (std::nothrow) unsigned char[length];
833 if (buffer == nullptr) {
834 ZLOGE(LABEL, "new buffer failed of length = %{public}d", length);
835 return ERR_INVALID_STATE;
836 }
837 buffer[0] = 'a';
838 buffer[length - 1] = 'z';
839 if (!reply.WriteInt32(length) ||
840 !reply.WriteRawData(buffer, (size_t)length) ||
841 !reply.WriteInt32(length)) {
842 ZLOGE(LABEL, "fail to write parcel");
843 delete [] buffer;
844 return ERR_INVALID_STATE;
845 }
846
847 delete [] buffer;
848 return ERR_NONE;
849 }
850
TransferToNextProcess(MessageParcel & data,MessageParcel & reply)851 void TestServiceStub::TransferToNextProcess(MessageParcel &data, MessageParcel &reply)
852 {
853 int32_t reqData = data.ReadInt32();
854 int32_t delayTime = data.ReadInt32();
855 int result;
856 int ret = TestSyncTransaction(reqData, result, delayTime);
857 reply.WriteInt32(result);
858
859 auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
860 if (saMgr == nullptr) {
861 reply.WriteInt32(ERR_TRANSACTION_FAILED);
862 return;
863 }
864
865 sptr<IRemoteObject> object = saMgr->GetSystemAbility(IPC_EXTRA_TEST_SERVICE);
866 if (object == nullptr) {
867 reply.WriteInt32(ERR_TRANSACTION_FAILED);
868 return;
869 }
870
871 sptr<ITestService> testService = iface_cast<ITestService>(object);
872 if (testService == nullptr) {
873 reply.WriteInt32(ERR_TRANSACTION_FAILED);
874 return;
875 }
876
877 ret += testService->TestSyncTransaction(reqData, result, delayTime);
878 ret += testService->TestAsyncCallbackTrans(reqData, result, delayTime);
879 if (ret != 0) {
880 reply.WriteInt32(ERR_TRANSACTION_FAILED);
881 return;
882 }
883
884 reply.WriteInt32(ERR_NONE);
885 }
886
ReadAshmem(MessageParcel & data,MessageParcel & reply)887 void TestServiceStub::ReadAshmem(MessageParcel &data, MessageParcel &reply)
888 {
889 int32_t contentSize = data.ReadInt32();
890 if (contentSize < 0) {
891 reply.WriteInt32(-1);
892 return;
893 }
894
895 sptr<Ashmem> ashmem = data.ReadAshmem();
896 if (ashmem == nullptr) {
897 reply.WriteInt32(-1);
898 return;
899 }
900
901 int32_t ashmemSize = ashmem->GetAshmemSize();
902 if (ashmemSize < contentSize || !ashmem->MapReadOnlyAshmem()) {
903 reply.WriteInt32(-1);
904 return;
905 }
906
907 const void *content = ashmem->ReadFromAshmem(contentSize, 0);
908 if (content == nullptr) {
909 reply.WriteInt32(-1);
910 ashmem->UnmapAshmem();
911 ashmem->CloseAshmem();
912 return;
913 }
914
915 auto pt = static_cast<const char *>(content);
916 std::string str(pt, contentSize);
917 ashmem->UnmapAshmem();
918 ashmem->CloseAshmem();
919
920 std::string name = "ashmem2";
921 sptr<Ashmem> ashmem2 = Ashmem::CreateAshmem(name.c_str(), ashmemSize);
922 if (ashmem2 == nullptr || !ashmem2->MapReadAndWriteAshmem() ||
923 !ashmem2->WriteToAshmem(str.c_str(), contentSize, 0)) {
924 reply.WriteInt32(-1);
925 if (ashmem2 != nullptr) {
926 ashmem2->UnmapAshmem();
927 ashmem2->CloseAshmem();
928 }
929 return;
930 }
931
932 reply.WriteInt32(contentSize);
933 reply.WriteAshmem(ashmem2);
934
935 ashmem2->UnmapAshmem();
936 ashmem2->CloseAshmem();
937 }
938
939 bool TestDeathRecipient::gotDeathRecipient_ = false;
940
GotDeathRecipient()941 bool TestDeathRecipient::GotDeathRecipient()
942 {
943 return gotDeathRecipient_;
944 }
945
OnRemoteDied(const wptr<IRemoteObject> & remote)946 void TestDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
947 {
948 gotDeathRecipient_ = true;
949 ZLOGD(LABEL, "recv death notice");
950 }
951
TestDeathRecipient()952 TestDeathRecipient::TestDeathRecipient()
953 {
954 }
955
~TestDeathRecipient()956 TestDeathRecipient::~TestDeathRecipient()
957 {
958 }
959 } // namespace OHOS
960