• 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 <unistd.h>
26 #include <random>
27 #include "system_ability_definition.h"
28 #include "iservice_registry.h"
29 #include "ipc_kit.h"
30 #include "test_capi_skeleton.h"
31 #include "ipc_debug.h"
32 #include "ipc_inner_object.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     OH_IPCParcel_WriteFileDescriptor(data, fd);
455     int ret = OH_IPCRemoteProxy_SendRequest(proxy_, NATIVE_TEST_CMD_SEND_FILE_DESCRIPTOR, data, reply, &option);
456     if (ret != OH_IPC_SUCCESS) {
457         ZLOGE(LABEL, "SendAndEchoFileDescriptor SendRequest ret:%{public}d", ret);
458         OH_IPCParcel_Destroy(data);
459         OH_IPCParcel_Destroy(reply);
460         close(fd);
461         return -1;
462     }
463     close(fd);
464     OH_IPCParcel_Destroy(data);
465     OH_IPCParcel_Destroy(reply);
466     return 0;
467 }
468 
SendErrorCode()469 int NativeRemoteProxyTest::SendErrorCode()
470 {
471     static std::map<int, int> vec = {
472         { OH_IPC_USER_ERROR_CODE_MIN, OH_IPC_USER_ERROR_CODE_MIN },
473         { OH_IPC_USER_ERROR_CODE_MAX, OH_IPC_USER_ERROR_CODE_MAX },
474         { OH_IPC_USER_ERROR_CODE_MIN - 1, OH_IPC_INVALID_USER_ERROR_CODE },
475         { OH_IPC_USER_ERROR_CODE_MAX + 1, OH_IPC_INVALID_USER_ERROR_CODE }
476     };
477 
478     if (proxy_ == nullptr) {
479         return -1;
480     }
481     auto func = [proxy = this->proxy_](int val, int expect) -> int {
482         OHIPCParcel *data = OH_IPCParcel_Create();
483         if (data == nullptr) {
484             return -1;
485         }
486         OHIPCParcel *reply = OH_IPCParcel_Create();
487         if (reply == nullptr) {
488             OH_IPCParcel_Destroy(data);
489             return -1;
490         }
491         OH_IPC_MessageOption option{ OH_IPC_REQUEST_MODE_SYNC, 0 };
492         if (OH_IPCParcel_WriteInterfaceToken(data, NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str()) != OH_IPC_SUCCESS) {
493             OH_IPCParcel_Destroy(data);
494             OH_IPCParcel_Destroy(reply);
495             return -1;
496         }
497         OH_IPCParcel_WriteInt32(data, val);
498         int ret = OH_IPCRemoteProxy_SendRequest(proxy, NATIVE_TEST_CMD_SEND_ERROR_CODE, data, reply, &option);
499         OH_IPCParcel_Destroy(data);
500         OH_IPCParcel_Destroy(reply);
501         return (ret == expect) ? 0 : -1;
502     };
503 
504     for (const auto &item : vec) {
505         if (func(item.first, item.second) != 0) {
506             ZLOGE(LABEL, "SendErrorCode test failed error code:%{public}d, expect error code:%{public}d",
507                 item.first, item.second);
508             return -1;
509         }
510     }
511     return 0;
512 }
513 
AddParallel(bool isSync)514 int NativeRemoteProxyTest::AddParallel(bool isSync)
515 {
516     static constexpr int PARALLEL_NUMBER = 1000;
517     static constexpr int PARALLEL_ACTION_SLEEP_CNT = 20;
518     int parallelNum = PARALLEL_NUMBER;
519     while (parallelNum-- > 0) {
520         std::this_thread::sleep_for(std::chrono::milliseconds(PARALLEL_ACTION_SLEEP_CNT));
521         int ret = isSync ? SyncAdd() : ASyncAdd();
522         if (ret != 0) {
523             ZLOGE(LABEL, "Add Parallel Test failed!");
524             return ret;
525         }
526     }
527     ZLOGI(LABEL, "Parallel test success!");
528     return 0;
529 }
530 
531 thread_local const OHIPCParcel *NativeRemoteStubTest::currentData_ = nullptr;
532 thread_local OHIPCParcel *NativeRemoteStubTest::currentReply_ = nullptr;
533 
534 std::map<int, std::function<int(NativeRemoteStubTest *stub)>> NativeRemoteStubTest::funcMap_ = {
__anon3471e3fe0302() 535     { NATIVE_TEST_CMD_SYNC_ADD, [](NativeRemoteStubTest *stub) { return stub->SyncAdd(); }},
__anon3471e3fe0402() 536     { NATIVE_TEST_CMD_ASYNC_ADD, [](NativeRemoteStubTest *stub) { return stub->ASyncAdd(); }},
__anon3471e3fe0502() 537     { NATIVE_TEST_CMD_SEND_AND_ECHO_BASE, [](NativeRemoteStubTest *stub) { return stub->SendAndEchoBase(); }},
__anon3471e3fe0602() 538     { NATIVE_TEST_CMD_SEND_AND_ECHO_SRING, [](NativeRemoteStubTest *stub) { return stub->SendAndEchoString(); }},
__anon3471e3fe0702() 539     { NATIVE_TEST_CMD_SEND_AND_ECHO_BUFFER, [](NativeRemoteStubTest *stub) { return stub->SendAndEchoBuffer(); }},
540     { NATIVE_TEST_CMD_SEND_FILE_DESCRIPTOR, [](NativeRemoteStubTest *stub)
__anon3471e3fe0802() 541         { return stub->SendAndEchoFileDescriptor(); }},
__anon3471e3fe0902() 542     { NATIVE_TEST_CMD_SEND_ERROR_CODE, [](NativeRemoteStubTest *stub) { return stub->SendErrorCode(); }},
543 };
544 
NativeRemoteStubTest(const sptr<ITestService> & testService)545 NativeRemoteStubTest::NativeRemoteStubTest(const sptr<ITestService> &testService)
546     : NativeRemoteBase(testService)
547 {
548     stub_ = OH_IPCRemoteStub_Create(NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str(),
549         &NativeRemoteStubTest::OnRemoteRequest, nullptr, this);
550 }
551 
~NativeRemoteStubTest()552 NativeRemoteStubTest::~NativeRemoteStubTest()
553 {
554     if (stub_ != nullptr) {
555         OH_IPCRemoteStub_Destroy(stub_);
556     }
557 }
558 
RegisterRemoteStub()559 int NativeRemoteStubTest::RegisterRemoteStub()
560 {
561     ZLOGI(LABEL, "TestRegisterRemoteStubTest");
562     if (testService_ == nullptr) {
563         ZLOGE(LABEL, "Member variable testService_ Is a null pointer");
564         return OH_IPC_INNER_ERROR;
565     }
566     int result = testService_->TestRegisterRemoteStub(NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str(), stub_->remote);
567     return result;
568 }
569 
UnRegisterRemoteStub()570 int NativeRemoteStubTest::UnRegisterRemoteStub()
571 {
572     ZLOGI(LABEL, "TestRegisterRemoteStubTest");
573     if (testService_ == nullptr) {
574         ZLOGE(LABEL, "Member variable testService_ Is a null pointer");
575         return OH_IPC_INNER_ERROR;
576     }
577     int result = testService_->TestUnRegisterRemoteStub(NATIVEREMOTESTUBTEST_DESCRIPTOR.c_str());
578     return result;
579 }
580 
OnRemoteRequest(uint32_t code,const OHIPCParcel * data,OHIPCParcel * reply,void * userData)581 int NativeRemoteStubTest::OnRemoteRequest(uint32_t code, const OHIPCParcel *data, OHIPCParcel *reply, void *userData)
582 {
583     NativeRemoteStubTest *stubTest = reinterpret_cast<NativeRemoteStubTest *>(userData);
584     if (stubTest == nullptr) {
585         ZLOGE(LABEL, "change user data failed!");
586         return OH_IPC_INNER_ERROR;
587     }
588 
589     int readLen = 0;
590     char *token = nullptr;
591     if (OH_IPCParcel_ReadInterfaceToken(data, &token, &readLen, LocalMemAllocator) != OH_IPC_SUCCESS
592         || NATIVEREMOTESTUBTEST_DESCRIPTOR != token) {
593         if (token != nullptr) {
594             ZLOGE(LABEL, "ReadInterfaceToken failed");
595             free(token);
596         }
597         return OH_IPC_INNER_ERROR;
598     }
599     free(token);
600 
601     stubTest->currentData_ = data;
602     stubTest->currentReply_ = reply;
603     auto it = funcMap_.find(static_cast<int>(code));
604     if (it != funcMap_.end()) {
605         return it->second(stubTest);
606     } else {
607         ZLOGE(LABEL, "unknown code:%{public}d", code);
608         return OH_IPC_INNER_ERROR;
609     }
610 }
611 
SyncAdd()612 int NativeRemoteStubTest::SyncAdd()
613 {
614     int32_t a = 0;
615     int32_t b = 0;
616     OH_IPCParcel_ReadInt32(this->currentData_, &a);
617     OH_IPCParcel_ReadInt32(this->currentData_, &b);
618 
619     OH_IPCParcel_WriteInt32(this->currentReply_, a + b);
620     return 0;
621 }
622 
ASyncAdd()623 int NativeRemoteStubTest::ASyncAdd()
624 {
625     int32_t a = 0;
626     int32_t b = 0;
627     OH_IPCParcel_ReadInt32(this->currentData_, &a);
628     OH_IPCParcel_ReadInt32(this->currentData_, &b);
629     auto proxyCallBack = OH_IPCParcel_ReadRemoteProxy(this->currentData_);
630     if (proxyCallBack == nullptr) {
631         return OH_IPC_PARCEL_READ_ERROR;
632     }
633     OHIPCParcel *dataParcel = OH_IPCParcel_Create();
634     if (dataParcel == nullptr) {
635         OH_IPCRemoteProxy_Destroy(proxyCallBack);
636         return OH_IPC_MEM_ALLOCATOR_ERROR;
637     }
638     OHIPCParcel *replyParcel = OH_IPCParcel_Create();
639     if (replyParcel == nullptr) {
640         OH_IPCRemoteProxy_Destroy(proxyCallBack);
641         OH_IPCParcel_Destroy(dataParcel);
642         return OH_IPC_MEM_ALLOCATOR_ERROR;
643     }
644     ZLOGI(LABEL, "start create sendCallback thread!");
645     std::thread th([proxyCallBack, dataParcel, replyParcel, a, b] {
646         std::this_thread::sleep_for(std::chrono::seconds(1));
647         OH_IPCParcel_WriteInt32(dataParcel, a + b);
648         OH_IPC_MessageOption option{ OH_IPC_REQUEST_MODE_ASYNC, 0 };
649         ZLOGI(LABEL, "thread start sendCallback!");
650         int ret = OH_IPCRemoteProxy_SendRequest(proxyCallBack, NATIVE_TEST_CMD_ASYNC_ADD,
651             dataParcel, replyParcel, &option);
652         if (ret != OH_IPC_SUCCESS) {
653             ZLOGE(LABEL, "ASyncAdd SendRequest failed! ret = %{public}d", ret);
654         }
655         OH_IPCRemoteProxy_Destroy(proxyCallBack);
656         OH_IPCParcel_Destroy(dataParcel);
657         OH_IPCParcel_Destroy(replyParcel);
658     });
659     th.detach();
660     return OH_IPC_SUCCESS;
661 }
662 
663 template <typename T>
ReadAndEchoBaseType(const OHIPCParcel * data,OHIPCParcel * reply,int (* readFunc)(const OHIPCParcel * data,T * value),int (* writeFunc)(OHIPCParcel * reply,T value))664 static int ReadAndEchoBaseType(const OHIPCParcel *data, OHIPCParcel *reply,
665     int (*readFunc)(const OHIPCParcel *data, T *value), int (*writeFunc)(OHIPCParcel *reply, T value))
666 {
667     T value = 0;
668     int ret = readFunc(data, &value);
669     if (ret != OH_IPC_SUCCESS) {
670         return OH_IPC_PARCEL_READ_ERROR;
671     }
672     return writeFunc(reply, value);
673 }
674 
SendAndEchoBase()675 int NativeRemoteStubTest::SendAndEchoBase()
676 {
677     int ret = ReadAndEchoBaseType<int8_t>(this->currentData_, this->currentReply_,
678         OH_IPCParcel_ReadInt8, OH_IPCParcel_WriteInt8);
679     if (ret != OH_IPC_SUCCESS) {
680         ZLOGE(LABEL, "Read or Write Int8 failed! ret:%{public}d", ret);
681         return ret;
682     }
683     ret = ReadAndEchoBaseType<int16_t>(this->currentData_, this->currentReply_,
684         OH_IPCParcel_ReadInt16, OH_IPCParcel_WriteInt16);
685     if (ret != OH_IPC_SUCCESS) {
686         ZLOGE(LABEL, "Read or Write Int16 failed! ret:%{public}d", ret);
687         return ret;
688     }
689     ret = ReadAndEchoBaseType<int32_t>(this->currentData_, this->currentReply_,
690         OH_IPCParcel_ReadInt32, OH_IPCParcel_WriteInt32);
691     if (ret != OH_IPC_SUCCESS) {
692         ZLOGE(LABEL, "Read or Write Int32 failed! ret:%{public}d", ret);
693         return ret;
694     }
695     ret = ReadAndEchoBaseType<int64_t>(this->currentData_, this->currentReply_,
696         OH_IPCParcel_ReadInt64, OH_IPCParcel_WriteInt64);
697     if (ret != OH_IPC_SUCCESS) {
698         ZLOGE(LABEL, "Read or Write Int64 failed! ret:%{public}d", ret);
699         return ret;
700     }
701     ret = ReadAndEchoBaseType<float>(this->currentData_, this->currentReply_,
702         OH_IPCParcel_ReadFloat, OH_IPCParcel_WriteFloat);
703     if (ret != OH_IPC_SUCCESS) {
704         ZLOGE(LABEL, "Read or Write float failed! ret:%{public}d", ret);
705         return ret;
706     }
707     ret = ReadAndEchoBaseType<double>(this->currentData_, this->currentReply_,
708         OH_IPCParcel_ReadDouble, OH_IPCParcel_WriteDouble);
709     if (ret != OH_IPC_SUCCESS) {
710         ZLOGE(LABEL, "Read or Write double failed! ret:%{public}d", ret);
711     }
712     return ret;
713 }
714 
SendAndEchoString()715 int OHOS::NativeRemoteStubTest::SendAndEchoString()
716 {
717     const char *readString = OH_IPCParcel_ReadString(this->currentData_);
718     if (readString == nullptr) {
719         ZLOGE(LABEL, "OH_IPCParcel_ReadString failed!");
720         return OH_IPC_PARCEL_READ_ERROR;
721     }
722 
723     return OH_IPCParcel_WriteString(this->currentReply_, readString);
724 }
725 
SendAndEchoBuffer()726 int OHOS::NativeRemoteStubTest::SendAndEchoBuffer()
727 {
728     int32_t buffLen = 0;
729     int ret = OH_IPCParcel_ReadInt32(this->currentData_, &buffLen);
730     if (ret != OH_IPC_SUCCESS) {
731         ZLOGE(LABEL, "SendAndEchoBuffer read buffer len failed! ret:%{public}d", ret);
732         return OH_IPC_PARCEL_READ_ERROR;
733     }
734     const uint8_t *buffer = OH_IPCParcel_ReadBuffer(this->currentData_, buffLen);
735     if (buffer == nullptr) {
736         ZLOGE(LABEL, "OH_IPCParcel_ReadBuffer failed!");
737         return OH_IPC_PARCEL_READ_ERROR;
738     }
739 
740     return OH_IPCParcel_WriteBuffer(this->currentReply_, buffer, buffLen);
741 }
742 
SendAndEchoFileDescriptor()743 int OHOS::NativeRemoteStubTest::SendAndEchoFileDescriptor()
744 {
745     int32_t fd = INVALID_FD;
746     int ret = OH_IPCParcel_ReadFileDescriptor(this->currentData_, &fd);
747     if (ret != OH_IPC_SUCCESS || fd == INVALID_FD) {
748         ZLOGE(LABEL, "OH_IPCParcel_ReadFileDescriptor failed! ret:%{public}d", ret);
749         return OH_IPC_PARCEL_READ_ERROR;
750     }
751     (void)write(fd, TEST_VAL_STRING.c_str(), TEST_VAL_STRING.length());
752     close(fd);
753     return OH_IPC_SUCCESS;
754 }
755 
SendErrorCode()756 int NativeRemoteStubTest::SendErrorCode()
757 {
758     int32_t valInt32 = 0;
759     int ret = OH_IPCParcel_ReadInt32(this->currentData_, &valInt32);
760     return ret == OH_IPC_SUCCESS ? valInt32 : OH_IPC_PARCEL_READ_ERROR;
761 }
762 }
763