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