• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 #include <cinttypes>
16 #include <thread>
17 #include <chrono>
18 #include <sstream>
19 #include <string>
20 #include <fcntl.h>
21 #include <cstdio>
22 #include <cstdlib>
23 #include <cstring>
24 #include <securec.h>
25 #include <random>
26 #include "system_ability_definition.h"
27 #include "iservice_registry.h"
28 #include "ipc_kit.h"
29 #include "test_capi_skeleton.h"
30 #include "ipc_debug.h"
31 #include "ipc_inner_object.h"
32 #include "fd_san.h"
33 
34 namespace OHOS {
35 
36 static constexpr int MAX_MEMORY_SIZE = 204800;
37 static constexpr int8_t TEST_VAL_INT8 = 121;
38 static constexpr int16_t TEST_VAL_INT16 = 1234;
39 static constexpr int32_t TEST_VAL_INT32 = 12345678;
40 static constexpr int64_t TEST_VAL_INT64 = 1234567890123L;
41 static constexpr float TEST_VAL_FLOAT = 123.456f;
42 static constexpr double TEST_VAL_DOUBLE = 123.456789;
43 static const std::string TEST_VAL_STRING = "0123456789abcdefghijklmnopqrstuvwxyz~!@#$%^&*()_+{}?/[]<>-='|~";
44 static constexpr uint8_t TEST_VAL_BUFFER[] = { 0xA1, 0xB2, 0xC3, 0xD4, 0xE5 };
45 static const std::string TEST_VAL_INTERFACE_TOKEN = "interface_token: test capi skeleton!";
46 
LocalMemAllocator(int32_t len)47 static void* LocalMemAllocator(int32_t len)
48 {
49     if (len <= 0 || len > MAX_MEMORY_SIZE) {
50         return nullptr;
51     }
52     void *buffer = malloc(len);
53     if (buffer != nullptr) {
54         if (memset_s(buffer, len, 0, len) != EOK) {
55             ZLOGE(NativeRemoteProxyTest::LABEL, "memset_s failed!");
56         }
57     }
58 
59     return buffer;
60 }
61 
NativeRemoteBase(const sptr<ITestService> & testService)62 NativeRemoteBase::NativeRemoteBase(const sptr<ITestService> &testService)
63     : testService_(testService)
64 {
65 }
66 
NativeRemoteProxyTest(const sptr<ITestService> & testService)67 NativeRemoteProxyTest::NativeRemoteProxyTest(const sptr<ITestService> &testService)
68     : NativeRemoteBase(testService)
69 {
70     if (testService_ == nullptr) {
71         ZLOGE(LABEL, "Test service is nullptr");
72         return;
73     }
74 
75     sptr<IRemoteObject> remote = testService_->TestQueryRemoteProxy(NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str());
76     proxy_ = CreateIPCRemoteProxy(remote);
77     if (proxy_ == nullptr) {
78         ZLOGE(LABEL, "CreateNativeRemoteProxy failed!");
79         return;
80     }
81     stubCallBack_ = OH_IPCRemoteStub_Create(NATIVEREMOTESTUBCALLBACKTEST_DESCRIPTOR.c_str(),
82         OnRemoteRequestStubCallBack, nullptr, this);
83 }
84 
~NativeRemoteProxyTest()85 NativeRemoteProxyTest::~NativeRemoteProxyTest()
86 {
87     if (stubCallBack_ != nullptr) {
88         OH_IPCRemoteStub_Destroy(stubCallBack_);
89     }
90     if (proxy_ != nullptr) {
91         OH_IPCRemoteProxy_Destroy(proxy_);
92     }
93 }
94 
SyncAdd()95 int NativeRemoteProxyTest::SyncAdd()
96 {
97     if (proxy_ == nullptr) {
98         ZLOGE(LABEL, "proxy_ is nullptr");
99         return -1;
100     }
101     OHIPCParcel *data = OH_IPCParcel_Create();
102     if (data == nullptr) {
103         ZLOGE(LABEL, "data is nullptr");
104         return -1;
105     }
106     OHIPCParcel *reply = OH_IPCParcel_Create();
107     if (reply == nullptr) {
108         OH_IPCParcel_Destroy(data);
109         ZLOGE(LABEL, "reply is nullptr");
110         return -1;
111     }
112     OH_IPC_MessageOption option{ OH_IPC_REQUEST_MODE_SYNC, 0 };
113     int ret = OH_IPCParcel_WriteInterfaceToken(data, NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str());
114     if (ret != OH_IPC_SUCCESS) {
115         ZLOGE(LABEL, "OH_IPCParcel_WriteInterfaceToken failed! ret:%{public}d", ret);
116         OH_IPCParcel_Destroy(data);
117         OH_IPCParcel_Destroy(reply);
118         return -1;
119     }
120     int a = randomDistribution_(randomDevice_);
121     int b = randomDistribution_(randomDevice_);
122     OH_IPCParcel_WriteInt32(data, a);
123     OH_IPCParcel_WriteInt32(data, b);
124     ret = OH_IPCRemoteProxy_SendRequest(proxy_, NATIVE_TEST_CMD_SYNC_ADD, data, reply, &option);
125     if (ret != OH_IPC_SUCCESS) {
126         ZLOGE(LABEL, "OH_IPCRemoteProxy_SendRequest failed! ret:%{public}d", ret);
127         OH_IPCParcel_Destroy(data);
128         OH_IPCParcel_Destroy(reply);
129         return -1;
130     }
131     int result = 0;
132     OH_IPCParcel_ReadInt32(reply, &result);
133     OH_IPCParcel_Destroy(data);
134     OH_IPCParcel_Destroy(reply);
135     if ((a + b) == result) {
136         ZLOGI(LABEL, "SyncAdd success! %{public}d + %{public}d = %{public}d", a, b, result);
137         return 0;
138     }
139     ZLOGE(LABEL, "SyncAdd failed! %{public}d + %{public}d = %{public}d", a, b, result);
140     return -1;
141 }
142 
ASyncAdd()143 int NativeRemoteProxyTest::ASyncAdd()
144 {
145     if (proxy_ == nullptr) {
146         ZLOGE(LABEL, "proxy_ is nullptr");
147         return -1;
148     }
149     OHIPCParcel *data = OH_IPCParcel_Create();
150     if (data == nullptr) {
151         ZLOGE(LABEL, "data is nullptr");
152         return -1;
153     }
154 
155     OH_IPC_MessageOption option{ OH_IPC_REQUEST_MODE_ASYNC, 0 };
156     if (OH_IPCParcel_WriteInterfaceToken(data, NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str()) != OH_IPC_SUCCESS) {
157         OH_IPCParcel_Destroy(data);
158         ZLOGE(LABEL, "OH_IPCParcel_WriteInterfaceToken failed!");
159         return -1;
160     }
161     int a = randomDistribution_(randomDevice_);
162     int b = randomDistribution_(randomDevice_);
163     OH_IPCParcel_WriteInt32(data, a);
164     OH_IPCParcel_WriteInt32(data, b);
165     OH_IPCParcel_WriteRemoteStub(data, stubCallBack_);
166     int ret = OH_IPCRemoteProxy_SendRequest(proxy_, NATIVE_TEST_CMD_ASYNC_ADD, data, nullptr, &option);
167     OH_IPCParcel_Destroy(data);
168     if (ret != OH_IPC_SUCCESS) {
169         ZLOGE(LABEL, "ipc sendRequest return = %{public}d ", ret);
170         return -1;
171     }
172     static constexpr int TIMEOUT = 3;
173     WaitForAsyncReply(TIMEOUT);
174     if ((a + b) == asyncReply_) {
175         ZLOGI(LABEL, "ASyncAdd success! %{public}d + %{public}d = %{public}d", a, b, asyncReply_);
176         return 0;
177     }
178     ZLOGE(LABEL, "ASyncAdd failed! %{public}d + %{public}d = %{public}d", a, b, asyncReply_);
179     return -1;
180 }
181 
OnRemoteRequestStubCallBack(uint32_t code,const OHIPCParcel * data,OHIPCParcel * reply,void * userData)182 int NativeRemoteProxyTest::OnRemoteRequestStubCallBack(uint32_t code,
183     const OHIPCParcel *data, OHIPCParcel *reply, void *userData)
184 {
185     ZLOGI(LABEL, "start %{public}u", code);
186     auto *proxyTest = reinterpret_cast<NativeRemoteProxyTest *>(userData);
187     if (code != NATIVE_TEST_CMD_ASYNC_ADD || proxyTest == nullptr) {
188         ZLOGE(LABEL, "check params or init failed!");
189         return OH_IPC_CHECK_PARAM_ERROR;
190     }
191 
192     int32_t val = 0;
193     int ret = OH_IPCParcel_ReadInt32(data, &val);
194     if (ret != OH_IPC_SUCCESS) {
195         ZLOGE(LABEL, "OH_IPCParcel_ReadInt32 failed!");
196         return ret;
197     }
198 
199     switch (code) {
200         case NATIVE_TEST_CMD_ASYNC_ADD: {
201             proxyTest->SendAsyncReply(val);
202             return OH_IPC_SUCCESS;
203         }
204         default:
205             break;
206     }
207     return OH_IPC_SUCCESS;
208 }
209 
WaitForAsyncReply(int timeout)210 int NativeRemoteProxyTest::WaitForAsyncReply(int timeout)
211 {
212     asyncReply_ = 0;
213     std::unique_lock<std::mutex> lck(mutex_);
214     cv_.wait_for(lck, std::chrono::seconds(timeout), [this]() {
215         return this->asyncReply_ != 0;
216     });
217     return asyncReply_;
218 }
219 
SendAsyncReply(int & replyValue)220 void NativeRemoteProxyTest::SendAsyncReply(int &replyValue)
221 {
222     std::unique_lock<std::mutex> lck(mutex_);
223     asyncReply_ = replyValue;
224     cv_.notify_all();
225 }
226 
SendBasicDataType(OHIPCParcel * data)227 void NativeRemoteProxyTest::SendBasicDataType(OHIPCParcel *data)
228 {
229     if (data != nullptr) {
230         OH_IPCParcel_WriteInt8(data, TEST_VAL_INT8);
231         OH_IPCParcel_WriteInt16(data, TEST_VAL_INT16);
232         OH_IPCParcel_WriteInt32(data, TEST_VAL_INT32);
233         OH_IPCParcel_WriteInt64(data, TEST_VAL_INT64);
234         OH_IPCParcel_WriteFloat(data, TEST_VAL_FLOAT);
235         OH_IPCParcel_WriteDouble(data, TEST_VAL_DOUBLE);
236     }
237 }
238 
239 template <typename T>
CheckBaseDataReply(const OHIPCParcel * data,T checkValue,int (* readFunc)(const OHIPCParcel * data,T * value))240 static int CheckBaseDataReply(const OHIPCParcel *data, T checkValue,
241     int (*readFunc)(const OHIPCParcel *data, T *value))
242 {
243     int ret = OH_IPC_SUCCESS;
244     T value = 0;
245     ret = readFunc(data, &value);
246     if (value != checkValue) {
247         ZLOGE(NativeRemoteProxyTest::LABEL, "CheckBaseDataReply failed! expect value:%{public}" PRId64
248             ", real value:%{public}" PRId64, static_cast<int64_t>(checkValue), static_cast<int64_t>(value));
249         return -1;
250     }
251     return 0;
252 }
253 
TestBasicDataTypeReply(const OHIPCParcel * reply)254 int NativeRemoteProxyTest::TestBasicDataTypeReply(const OHIPCParcel *reply)
255 {
256     static const double ESP = 1e-6;
257     if (reply == nullptr) {
258         return -1;
259     }
260     if (CheckBaseDataReply<int8_t>(reply, TEST_VAL_INT8, OH_IPCParcel_ReadInt8) != 0) {
261         return -1;
262     }
263     if (CheckBaseDataReply<int16_t>(reply, TEST_VAL_INT16, OH_IPCParcel_ReadInt16) != 0) {
264         return -1;
265     }
266     if (CheckBaseDataReply<int32_t>(reply, TEST_VAL_INT32, OH_IPCParcel_ReadInt32) != 0) {
267         return -1;
268     }
269     if (CheckBaseDataReply<int64_t>(reply, TEST_VAL_INT64, OH_IPCParcel_ReadInt64) != 0) {
270         return -1;
271     }
272     float valFloat = 0.0f;
273     int ret = OH_IPCParcel_ReadFloat(reply, &valFloat);
274     if (abs(valFloat - TEST_VAL_FLOAT) > ESP) {
275         ZLOGE(LABEL, "CheckBaseDataReply failed! expect value:%{public}f, real value:%{public}f",
276             TEST_VAL_FLOAT, valFloat);
277         return -1;
278     }
279 
280     double valDouble = 0.0;
281     ret = OH_IPCParcel_ReadDouble(reply, &valDouble);
282     if (abs(valDouble - TEST_VAL_DOUBLE) > ESP) {
283         ZLOGE(LABEL, "CheckBaseDataReply failed! expect value:%{public}f, real value:%{public}f",
284             TEST_VAL_DOUBLE, valDouble);
285         return -1;
286     }
287     return 0;
288 }
289 
SendAndEchoBase()290 int NativeRemoteProxyTest::SendAndEchoBase()
291 {
292     if (proxy_ == nullptr) {
293         return -1;
294     }
295     OHIPCParcel *data = OH_IPCParcel_Create();
296     if (data == nullptr) {
297         return -1;
298     }
299     OHIPCParcel *reply = OH_IPCParcel_Create();
300     if (reply == nullptr) {
301         OH_IPCParcel_Destroy(data);
302         return -1;
303     }
304     OH_IPC_MessageOption option{ OH_IPC_REQUEST_MODE_SYNC, 0 };
305     if (OH_IPCParcel_WriteInterfaceToken(data, NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str()) != OH_IPC_SUCCESS) {
306         OH_IPCParcel_Destroy(data);
307         OH_IPCParcel_Destroy(reply);
308         return -1;
309     }
310 
311     SendBasicDataType(data);
312 
313     int ret = OH_IPCRemoteProxy_SendRequest(proxy_, NATIVE_TEST_CMD_SEND_AND_ECHO_BASE, data, reply, &option);
314     if (ret != OH_IPC_SUCCESS) {
315         OH_IPCParcel_Destroy(data);
316         OH_IPCParcel_Destroy(reply);
317         ZLOGE(LABEL, "SendAndEchoBase SendRequest ret:%{public}d", ret);
318         return -1;
319     }
320     OH_IPCParcel_Destroy(data);
321     if (TestBasicDataTypeReply(reply) != 0) {
322         OH_IPCParcel_Destroy(reply);
323         return -1;
324     }
325 
326     OH_IPCParcel_Destroy(reply);
327     return 0;
328 }
329 
SendAndEchoString()330 int NativeRemoteProxyTest::SendAndEchoString()
331 {
332     if (proxy_ == nullptr) {
333         return -1;
334     }
335     OHIPCParcel *data = OH_IPCParcel_Create();
336     if (data == nullptr) {
337         return -1;
338     }
339     OHIPCParcel *reply = OH_IPCParcel_Create();
340     if (reply == nullptr) {
341         OH_IPCParcel_Destroy(data);
342         return -1;
343     }
344     OH_IPC_MessageOption option{ OH_IPC_REQUEST_MODE_SYNC, 0 };
345     if (OH_IPCParcel_WriteInterfaceToken(data, NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str()) != OH_IPC_SUCCESS) {
346         OH_IPCParcel_Destroy(data);
347         OH_IPCParcel_Destroy(reply);
348         return -1;
349     }
350     if (OH_IPCParcel_WriteString(data, TEST_VAL_STRING.c_str()) != OH_IPC_SUCCESS) {
351         ZLOGE(LABEL, "OH_IPCParcel_WriteString failed!");
352         OH_IPCParcel_Destroy(data);
353         OH_IPCParcel_Destroy(reply);
354         return -1;
355     }
356     int ret = OH_IPCRemoteProxy_SendRequest(proxy_, NATIVE_TEST_CMD_SEND_AND_ECHO_SRING,
357         data, reply, &option);
358     if (ret != OH_IPC_SUCCESS) {
359         ZLOGE(LABEL, "SendAndEchoString SendRequest ret:%{public}d", ret);
360         OH_IPCParcel_Destroy(data);
361         OH_IPCParcel_Destroy(reply);
362         return -1;
363     }
364 
365     const char *readStr = OH_IPCParcel_ReadString(reply);
366     if (readStr == nullptr || TEST_VAL_STRING != readStr) {
367         ZLOGE(LABEL, "OH_IPCParcel_ReadString failed!");
368         OH_IPCParcel_Destroy(data);
369         OH_IPCParcel_Destroy(reply);
370         return -1;
371     }
372     OH_IPCParcel_Destroy(data);
373     OH_IPCParcel_Destroy(reply);
374     return 0;
375 }
376 
SendAndEchoBuffer()377 int NativeRemoteProxyTest::SendAndEchoBuffer()
378 {
379     if (proxy_ == nullptr) {
380         return -1;
381     }
382     OHIPCParcel *data = OH_IPCParcel_Create();
383     if (data == nullptr) {
384         return -1;
385     }
386     OHIPCParcel *reply = OH_IPCParcel_Create();
387     if (reply == nullptr) {
388         OH_IPCParcel_Destroy(data);
389         return -1;
390     }
391     OH_IPC_MessageOption option{ OH_IPC_REQUEST_MODE_SYNC, 0 };
392     if (OH_IPCParcel_WriteInterfaceToken(data, NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str()) != OH_IPC_SUCCESS) {
393         OH_IPCParcel_Destroy(data);
394         OH_IPCParcel_Destroy(reply);
395         return -1;
396     }
397     OH_IPCParcel_WriteInt32(data, sizeof(TEST_VAL_BUFFER));
398     OH_IPCParcel_WriteBuffer(data, TEST_VAL_BUFFER, sizeof(TEST_VAL_BUFFER));
399 
400     int ret = OH_IPCRemoteProxy_SendRequest(proxy_, NATIVE_TEST_CMD_SEND_AND_ECHO_BUFFER,
401         data, reply, &option);
402     if (ret != OH_IPC_SUCCESS) {
403         ZLOGE(LABEL, "SendAndEchoBuffer SendRequest ret:%{public}d", ret);
404         OH_IPCParcel_Destroy(data);
405         OH_IPCParcel_Destroy(reply);
406         return -1;
407     }
408 
409     const uint8_t *readBuff = OH_IPCParcel_ReadBuffer(reply, sizeof(TEST_VAL_BUFFER));
410     if (readBuff == nullptr) {
411         OH_IPCParcel_Destroy(data);
412         OH_IPCParcel_Destroy(reply);
413         return -1;
414     }
415     int cmpResult = memcmp(readBuff, TEST_VAL_BUFFER, sizeof(TEST_VAL_BUFFER));
416     if (cmpResult != 0) {
417         ZLOGE(LABEL, "SendAndEchoBuffer check echo buffer faield!");
418         OH_IPCParcel_Destroy(data);
419         OH_IPCParcel_Destroy(reply);
420         return -1;
421     }
422     OH_IPCParcel_Destroy(data);
423     OH_IPCParcel_Destroy(reply);
424     return 0;
425 }
426 
SendAndEchoFileDescriptor()427 int NativeRemoteProxyTest::SendAndEchoFileDescriptor()
428 {
429     if (proxy_ == nullptr) {
430         return -1;
431     }
432     OHIPCParcel *data = OH_IPCParcel_Create();
433     if (data == nullptr) {
434         return -1;
435     }
436     OHIPCParcel *reply = OH_IPCParcel_Create();
437     if (reply == nullptr) {
438         OH_IPCParcel_Destroy(data);
439         return -1;
440     }
441     OH_IPC_MessageOption option{ OH_IPC_REQUEST_MODE_SYNC, 0 };
442     if (OH_IPCParcel_WriteInterfaceToken(data, NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str()) != OH_IPC_SUCCESS) {
443         OH_IPCParcel_Destroy(data);
444         OH_IPCParcel_Destroy(reply);
445         return -1;
446     }
447     int32_t fd = open("/data/capiTest.txt", O_RDWR | O_CREAT);
448     if (fd == INVALID_FD) {
449         OH_IPCParcel_Destroy(data);
450         OH_IPCParcel_Destroy(reply);
451         ZLOGE(LABEL, "open file failed!");
452         return -1;
453     }
454     fdsan_exchange_owner_tag(fd, 0, IPC_FD_TAG);
455     OH_IPCParcel_WriteFileDescriptor(data, fd);
456     int ret = OH_IPCRemoteProxy_SendRequest(proxy_, NATIVE_TEST_CMD_SEND_FILE_DESCRIPTOR, data, reply, &option);
457     if (ret != OH_IPC_SUCCESS) {
458         ZLOGE(LABEL, "SendAndEchoFileDescriptor SendRequest ret:%{public}d", ret);
459         OH_IPCParcel_Destroy(data);
460         OH_IPCParcel_Destroy(reply);
461         fdsan_close_with_tag(fd, IPC_FD_TAG);
462         return -1;
463     }
464     fdsan_close_with_tag(fd, IPC_FD_TAG);
465     OH_IPCParcel_Destroy(data);
466     OH_IPCParcel_Destroy(reply);
467     return 0;
468 }
469 
SendErrorCode()470 int NativeRemoteProxyTest::SendErrorCode()
471 {
472     static std::map<int, int> vec = {
473         { OH_IPC_USER_ERROR_CODE_MIN, OH_IPC_USER_ERROR_CODE_MIN },
474         { OH_IPC_USER_ERROR_CODE_MAX, OH_IPC_USER_ERROR_CODE_MAX },
475         { OH_IPC_USER_ERROR_CODE_MIN - 1, OH_IPC_INVALID_USER_ERROR_CODE },
476         { OH_IPC_USER_ERROR_CODE_MAX + 1, OH_IPC_INVALID_USER_ERROR_CODE }
477     };
478 
479     if (proxy_ == nullptr) {
480         return -1;
481     }
482     auto func = [proxy = this->proxy_](int val, int expect) -> int {
483         OHIPCParcel *data = OH_IPCParcel_Create();
484         if (data == nullptr) {
485             return -1;
486         }
487         OHIPCParcel *reply = OH_IPCParcel_Create();
488         if (reply == nullptr) {
489             OH_IPCParcel_Destroy(data);
490             return -1;
491         }
492         OH_IPC_MessageOption option{ OH_IPC_REQUEST_MODE_SYNC, 0 };
493         if (OH_IPCParcel_WriteInterfaceToken(data, NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str()) != OH_IPC_SUCCESS) {
494             OH_IPCParcel_Destroy(data);
495             OH_IPCParcel_Destroy(reply);
496             return -1;
497         }
498         OH_IPCParcel_WriteInt32(data, val);
499         int ret = OH_IPCRemoteProxy_SendRequest(proxy, NATIVE_TEST_CMD_SEND_ERROR_CODE, data, reply, &option);
500         OH_IPCParcel_Destroy(data);
501         OH_IPCParcel_Destroy(reply);
502         return (ret == expect) ? 0 : -1;
503     };
504 
505     for (const auto &item : vec) {
506         if (func(item.first, item.second) != 0) {
507             ZLOGE(LABEL, "SendErrorCode test failed error code:%{public}d, expect error code:%{public}d",
508                 item.first, item.second);
509             return -1;
510         }
511     }
512     return 0;
513 }
514 
AddParallel(bool isSync)515 int NativeRemoteProxyTest::AddParallel(bool isSync)
516 {
517     static constexpr int PARALLEL_NUMBER = 1000;
518     static constexpr int PARALLEL_ACTION_SLEEP_CNT = 20;
519     int parallelNum = PARALLEL_NUMBER;
520     while (parallelNum-- > 0) {
521         std::this_thread::sleep_for(std::chrono::milliseconds(PARALLEL_ACTION_SLEEP_CNT));
522         int ret = isSync ? SyncAdd() : ASyncAdd();
523         if (ret != 0) {
524             ZLOGE(LABEL, "Add Parallel Test failed!");
525             return ret;
526         }
527     }
528     ZLOGI(LABEL, "Parallel test success!");
529     return 0;
530 }
531 
532 thread_local const OHIPCParcel *NativeRemoteStubTest::currentData_ = nullptr;
533 thread_local OHIPCParcel *NativeRemoteStubTest::currentReply_ = nullptr;
534 
535 std::map<int, std::function<int(NativeRemoteStubTest *stub)>> NativeRemoteStubTest::funcMap_ = {
__anonae4af5200302() 536     { NATIVE_TEST_CMD_SYNC_ADD, [](NativeRemoteStubTest *stub) { return stub->SyncAdd(); }},
__anonae4af5200402() 537     { NATIVE_TEST_CMD_ASYNC_ADD, [](NativeRemoteStubTest *stub) { return stub->ASyncAdd(); }},
__anonae4af5200502() 538     { NATIVE_TEST_CMD_SEND_AND_ECHO_BASE, [](NativeRemoteStubTest *stub) { return stub->SendAndEchoBase(); }},
__anonae4af5200602() 539     { NATIVE_TEST_CMD_SEND_AND_ECHO_SRING, [](NativeRemoteStubTest *stub) { return stub->SendAndEchoString(); }},
__anonae4af5200702() 540     { NATIVE_TEST_CMD_SEND_AND_ECHO_BUFFER, [](NativeRemoteStubTest *stub) { return stub->SendAndEchoBuffer(); }},
541     { NATIVE_TEST_CMD_SEND_FILE_DESCRIPTOR, [](NativeRemoteStubTest *stub)
__anonae4af5200802() 542         { return stub->SendAndEchoFileDescriptor(); }},
__anonae4af5200902() 543     { NATIVE_TEST_CMD_SEND_ERROR_CODE, [](NativeRemoteStubTest *stub) { return stub->SendErrorCode(); }},
544 };
545 
NativeRemoteStubTest(const sptr<ITestService> & testService)546 NativeRemoteStubTest::NativeRemoteStubTest(const sptr<ITestService> &testService)
547     : NativeRemoteBase(testService)
548 {
549     stub_ = OH_IPCRemoteStub_Create(NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str(),
550         &NativeRemoteStubTest::OnRemoteRequest, nullptr, this);
551 }
552 
~NativeRemoteStubTest()553 NativeRemoteStubTest::~NativeRemoteStubTest()
554 {
555     if (stub_ != nullptr) {
556         OH_IPCRemoteStub_Destroy(stub_);
557     }
558 }
559 
RegisterRemoteStub()560 int NativeRemoteStubTest::RegisterRemoteStub()
561 {
562     ZLOGI(LABEL, "TestRegisterRemoteStubTest");
563     if (testService_ == nullptr) {
564         ZLOGE(LABEL, "Member variable testService_ Is a null pointer");
565         return OH_IPC_INNER_ERROR;
566     }
567     int result = testService_->TestRegisterRemoteStub(NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str(), stub_->remote);
568     return result;
569 }
570 
UnRegisterRemoteStub()571 int NativeRemoteStubTest::UnRegisterRemoteStub()
572 {
573     ZLOGI(LABEL, "TestRegisterRemoteStubTest");
574     if (testService_ == nullptr) {
575         ZLOGE(LABEL, "Member variable testService_ Is a null pointer");
576         return OH_IPC_INNER_ERROR;
577     }
578     int result = testService_->TestUnRegisterRemoteStub(NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str());
579     return result;
580 }
581 
OnRemoteRequest(uint32_t code,const OHIPCParcel * data,OHIPCParcel * reply,void * userData)582 int NativeRemoteStubTest::OnRemoteRequest(uint32_t code, const OHIPCParcel *data, OHIPCParcel *reply, void *userData)
583 {
584     NativeRemoteStubTest *stubTest = reinterpret_cast<NativeRemoteStubTest *>(userData);
585     if (stubTest == nullptr) {
586         ZLOGE(LABEL, "change user data failed!");
587         return OH_IPC_INNER_ERROR;
588     }
589 
590     int readLen = 0;
591     char *token = nullptr;
592     if (OH_IPCParcel_ReadInterfaceToken(data, &token, &readLen, LocalMemAllocator) != OH_IPC_SUCCESS
593         || NATIVEREMOTESTUBTEST_DESCRIPTOR != token) {
594         if (token != nullptr) {
595             ZLOGE(LABEL, "ReadInterfaceToken failed");
596             free(token);
597         }
598         return OH_IPC_INNER_ERROR;
599     }
600     free(token);
601 
602     stubTest->currentData_ = data;
603     stubTest->currentReply_ = reply;
604     auto it = funcMap_.find(static_cast<int>(code));
605     if (it != funcMap_.end()) {
606         return it->second(stubTest);
607     } else {
608         ZLOGE(LABEL, "unknown code:%{public}d", code);
609         return OH_IPC_INNER_ERROR;
610     }
611 }
612 
SyncAdd()613 int NativeRemoteStubTest::SyncAdd()
614 {
615     int32_t a = 0;
616     int32_t b = 0;
617     OH_IPCParcel_ReadInt32(this->currentData_, &a);
618     OH_IPCParcel_ReadInt32(this->currentData_, &b);
619 
620     OH_IPCParcel_WriteInt32(this->currentReply_, a + b);
621     return 0;
622 }
623 
ASyncAdd()624 int NativeRemoteStubTest::ASyncAdd()
625 {
626     int32_t a = 0;
627     int32_t b = 0;
628     OH_IPCParcel_ReadInt32(this->currentData_, &a);
629     OH_IPCParcel_ReadInt32(this->currentData_, &b);
630     auto proxyCallBack = OH_IPCParcel_ReadRemoteProxy(this->currentData_);
631     if (proxyCallBack == nullptr) {
632         return OH_IPC_PARCEL_READ_ERROR;
633     }
634     OHIPCParcel *dataParcel = OH_IPCParcel_Create();
635     if (dataParcel == nullptr) {
636         OH_IPCRemoteProxy_Destroy(proxyCallBack);
637         return OH_IPC_MEM_ALLOCATOR_ERROR;
638     }
639     OHIPCParcel *replyParcel = OH_IPCParcel_Create();
640     if (replyParcel == nullptr) {
641         OH_IPCRemoteProxy_Destroy(proxyCallBack);
642         OH_IPCParcel_Destroy(dataParcel);
643         return OH_IPC_MEM_ALLOCATOR_ERROR;
644     }
645     ZLOGI(LABEL, "start create sendCallback thread!");
646     std::thread th([proxyCallBack, dataParcel, replyParcel, a, b] {
647         std::this_thread::sleep_for(std::chrono::seconds(1));
648         OH_IPCParcel_WriteInt32(dataParcel, a + b);
649         OH_IPC_MessageOption option{ OH_IPC_REQUEST_MODE_ASYNC, 0 };
650         ZLOGI(LABEL, "thread start sendCallback!");
651         int ret = OH_IPCRemoteProxy_SendRequest(proxyCallBack, NATIVE_TEST_CMD_ASYNC_ADD,
652             dataParcel, replyParcel, &option);
653         if (ret != OH_IPC_SUCCESS) {
654             ZLOGE(LABEL, "ASyncAdd SendRequest failed! ret = %{public}d", ret);
655         }
656         OH_IPCRemoteProxy_Destroy(proxyCallBack);
657         OH_IPCParcel_Destroy(dataParcel);
658         OH_IPCParcel_Destroy(replyParcel);
659     });
660     th.detach();
661     return OH_IPC_SUCCESS;
662 }
663 
664 template <typename T>
ReadAndEchoBaseType(const OHIPCParcel * data,OHIPCParcel * reply,int (* readFunc)(const OHIPCParcel * data,T * value),int (* writeFunc)(OHIPCParcel * reply,T value))665 static int ReadAndEchoBaseType(const OHIPCParcel *data, OHIPCParcel *reply,
666     int (*readFunc)(const OHIPCParcel *data, T *value), int (*writeFunc)(OHIPCParcel *reply, T value))
667 {
668     T value = 0;
669     int ret = readFunc(data, &value);
670     if (ret != OH_IPC_SUCCESS) {
671         return OH_IPC_PARCEL_READ_ERROR;
672     }
673     return writeFunc(reply, value);
674 }
675 
SendAndEchoBase()676 int NativeRemoteStubTest::SendAndEchoBase()
677 {
678     int ret = ReadAndEchoBaseType<int8_t>(this->currentData_, this->currentReply_,
679         OH_IPCParcel_ReadInt8, OH_IPCParcel_WriteInt8);
680     if (ret != OH_IPC_SUCCESS) {
681         ZLOGE(LABEL, "Read or Write Int8 failed! ret:%{public}d", ret);
682         return ret;
683     }
684     ret = ReadAndEchoBaseType<int16_t>(this->currentData_, this->currentReply_,
685         OH_IPCParcel_ReadInt16, OH_IPCParcel_WriteInt16);
686     if (ret != OH_IPC_SUCCESS) {
687         ZLOGE(LABEL, "Read or Write Int16 failed! ret:%{public}d", ret);
688         return ret;
689     }
690     ret = ReadAndEchoBaseType<int32_t>(this->currentData_, this->currentReply_,
691         OH_IPCParcel_ReadInt32, OH_IPCParcel_WriteInt32);
692     if (ret != OH_IPC_SUCCESS) {
693         ZLOGE(LABEL, "Read or Write Int32 failed! ret:%{public}d", ret);
694         return ret;
695     }
696     ret = ReadAndEchoBaseType<int64_t>(this->currentData_, this->currentReply_,
697         OH_IPCParcel_ReadInt64, OH_IPCParcel_WriteInt64);
698     if (ret != OH_IPC_SUCCESS) {
699         ZLOGE(LABEL, "Read or Write Int64 failed! ret:%{public}d", ret);
700         return ret;
701     }
702     ret = ReadAndEchoBaseType<float>(this->currentData_, this->currentReply_,
703         OH_IPCParcel_ReadFloat, OH_IPCParcel_WriteFloat);
704     if (ret != OH_IPC_SUCCESS) {
705         ZLOGE(LABEL, "Read or Write float failed! ret:%{public}d", ret);
706         return ret;
707     }
708     ret = ReadAndEchoBaseType<double>(this->currentData_, this->currentReply_,
709         OH_IPCParcel_ReadDouble, OH_IPCParcel_WriteDouble);
710     if (ret != OH_IPC_SUCCESS) {
711         ZLOGE(LABEL, "Read or Write double failed! ret:%{public}d", ret);
712     }
713     return ret;
714 }
715 
SendAndEchoString()716 int OHOS::NativeRemoteStubTest::SendAndEchoString()
717 {
718     const char *readString = OH_IPCParcel_ReadString(this->currentData_);
719     if (readString == nullptr) {
720         ZLOGE(LABEL, "OH_IPCParcel_ReadString failed!");
721         return OH_IPC_PARCEL_READ_ERROR;
722     }
723 
724     return OH_IPCParcel_WriteString(this->currentReply_, readString);
725 }
726 
SendAndEchoBuffer()727 int OHOS::NativeRemoteStubTest::SendAndEchoBuffer()
728 {
729     int32_t buffLen = 0;
730     int ret = OH_IPCParcel_ReadInt32(this->currentData_, &buffLen);
731     if (ret != OH_IPC_SUCCESS) {
732         ZLOGE(LABEL, "SendAndEchoBuffer read buffer len failed! ret:%{public}d", ret);
733         return OH_IPC_PARCEL_READ_ERROR;
734     }
735     const uint8_t *buffer = OH_IPCParcel_ReadBuffer(this->currentData_, buffLen);
736     if (buffer == nullptr) {
737         ZLOGE(LABEL, "OH_IPCParcel_ReadBuffer failed!");
738         return OH_IPC_PARCEL_READ_ERROR;
739     }
740 
741     return OH_IPCParcel_WriteBuffer(this->currentReply_, buffer, buffLen);
742 }
743 
SendAndEchoFileDescriptor()744 int OHOS::NativeRemoteStubTest::SendAndEchoFileDescriptor()
745 {
746     int32_t fd = INVALID_FD;
747     int ret = OH_IPCParcel_ReadFileDescriptor(this->currentData_, &fd);
748     if (ret != OH_IPC_SUCCESS || fd == INVALID_FD) {
749         ZLOGE(LABEL, "OH_IPCParcel_ReadFileDescriptor failed! ret:%{public}d", ret);
750         return OH_IPC_PARCEL_READ_ERROR;
751     }
752     fdsan_exchange_owner_tag(fd, 0, IPC_FD_TAG);
753     (void)write(fd, TEST_VAL_STRING.c_str(), TEST_VAL_STRING.length());
754     fdsan_close_with_tag(fd, IPC_FD_TAG);
755     return OH_IPC_SUCCESS;
756 }
757 
SendErrorCode()758 int NativeRemoteStubTest::SendErrorCode()
759 {
760     int32_t valInt32 = 0;
761     int ret = OH_IPCParcel_ReadInt32(this->currentData_, &valInt32);
762     return ret == OH_IPC_SUCCESS ? valInt32 : OH_IPC_PARCEL_READ_ERROR;
763 }
764 }
765