• 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_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