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