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