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