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