1 /*
2 * Copyright (C) 2025 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
16 #include <gtest/gtest.h>
17
18 #include <cstring>
19 #include <securec.h>
20 #include <mutex>
21 #include <condition_variable>
22
23 #include "if_system_ability_manager.h"
24 #include "ipc_inner_object.h"
25 #include "ipc_kit.h"
26 #include "ipc_test_helper.h"
27 #include "iservice_registry.h"
28 #include "system_ability_definition.h"
29 #include "test_capi_skeleton.h"
30 #include "test_service_command.h"
31 #include "test_service_client.h"
32
33 using namespace testing::ext;
34 using namespace OHOS;
35 using namespace OHOS::HiviewDFX;
36
37 static constexpr uint32_t ON_CALLBACK_REPLIED_INT = 1598311760;
38
39 namespace OHOS {
40 class IpcCApiRemoteObjectModuleTest : public testing::Test {
41 public:
42 static void SetUpTestCase(void);
43 static void TearDownTestCase(void);
44 void SetUp();
45 void TearDown();
46 static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_ID_TEST, "IpcCApiModuleTest" };
47
48 void ResetCallbackReply();
49 [[nodiscard]] int GetCallbackReply() const;
50
51 static void OnDeathRecipientCallback(void *userData);
52 static void OnDeathRecipientDestroyCallback(void *userData);
53 static OHIPCRemoteProxy* IpcCreateIPCRemoteProxy(IPCTestHelper &helper);
54 static void* MemAllocator(int32_t len);
55
56 private:
57 int callBackReply_{ 0 };
58 static inline IPCTestHelper *globalHelper_ = { nullptr };
59 };
60
SetUpTestCase()61 void IpcCApiRemoteObjectModuleTest::SetUpTestCase()
62 {
63 if (globalHelper_ == nullptr) {
64 globalHelper_ = new IPCTestHelper();
65 bool res = globalHelper_->PrepareTestSuite();
66 ASSERT_TRUE(res);
67 }
68 }
69
TearDownTestCase()70 void IpcCApiRemoteObjectModuleTest::TearDownTestCase()
71 {
72 if (globalHelper_ != nullptr) {
73 bool res = globalHelper_->TearDownTestSuite();
74 ASSERT_TRUE(res);
75 delete globalHelper_;
76 globalHelper_ = nullptr;
77 }
78 }
79
SetUp()80 void IpcCApiRemoteObjectModuleTest::SetUp()
81 {
82 callBackReply_ = 0;
83 }
84
TearDown()85 void IpcCApiRemoteObjectModuleTest::TearDown()
86 {}
87
ResetCallbackReply()88 void IpcCApiRemoteObjectModuleTest::ResetCallbackReply()
89 {
90 callBackReply_ = 0;
91 }
92
GetCallbackReply() const93 int IpcCApiRemoteObjectModuleTest::GetCallbackReply() const
94 {
95 return callBackReply_;
96 }
97
98
OnDeathRecipientCallback(void * userData)99 void IpcCApiRemoteObjectModuleTest::OnDeathRecipientCallback(void *userData)
100 {
101 ZLOGI(LABEL, "OnDeathRecipientCallback modify callBackReply_");
102 if (userData != nullptr) {
103 auto *test = static_cast<IpcCApiRemoteObjectModuleTest *>(userData);
104 test->callBackReply_ = ON_CALLBACK_REPLIED_INT;
105 }
106 }
107
OnDeathRecipientDestroyCallback(void * userData)108 void IpcCApiRemoteObjectModuleTest::OnDeathRecipientDestroyCallback(void *userData)
109 {
110 if (userData != nullptr) {
111 auto *test = static_cast<IpcCApiRemoteObjectModuleTest *>(userData);
112 test->callBackReply_ = ON_CALLBACK_REPLIED_INT;
113 }
114 }
115
116
MemAllocator(int32_t len)117 void* IpcCApiRemoteObjectModuleTest::MemAllocator(int32_t len)
118 {
119 if (len <= 0) {
120 ZLOGE(LABEL, "Invalid length passed to MemAllocator: %d", len);
121 return nullptr;
122 }
123 void *buffer = malloc(len);
124 if (buffer == nullptr) {
125 ZLOGE(LABEL, "Failed to allocate memory of size: %d", len);
126 return nullptr;
127 }
128 (void)memset_s(buffer, len, 0, len);
129 return buffer;
130 }
131
IpcCreateIPCRemoteProxy(IPCTestHelper & helper)132 OHIPCRemoteProxy* IpcCApiRemoteObjectModuleTest::IpcCreateIPCRemoteProxy(IPCTestHelper &helper)
133 {
134 bool res = helper.StartTestApp(IPCTestHelper::IPC_TEST_SERVER);
135 if (!res) {
136 ZLOGE(LABEL, "Failed to start test app");
137 return nullptr;
138 }
139
140 auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
141 if (saMgr == nullptr) {
142 ZLOGE(LABEL, "Failed to get system ability manager");
143 return nullptr;
144 }
145
146 sptr<IRemoteObject> object = saMgr->GetSystemAbility(IPC_TEST_SERVICE);
147 if (object == nullptr) {
148 ZLOGE(LABEL, "Failed to get system ability object");
149 return nullptr;
150 }
151
152 OHIPCRemoteProxy *remoteProxy = CreateIPCRemoteProxy(object);
153 return remoteProxy;
154 }
155
156 /**
157 * @tc.name: RemoteProxy_Destroy_001
158 * @tc.desc: Test destory the remote proxy.
159 * @tc.type: FUNC
160 */
161 HWTEST_F(IpcCApiRemoteObjectModuleTest, RemoteProxy_Destroy_001, TestSize.Level1)
162 {
163 IPCTestHelper helper;
164 OHIPCRemoteProxy *remoteProxy = IpcCreateIPCRemoteProxy(helper);
165 ASSERT_NE(remoteProxy, nullptr);
166 OH_IPCRemoteProxy_Destroy(remoteProxy);
167 }
168
169 /**
170 * @tc.name: SendRequestSync_001
171 * @tc.desc: Test use proxy to send sync request message.
172 * @tc.type: FUNC
173 */
174 HWTEST_F(IpcCApiRemoteObjectModuleTest, SendRequestSync_001, TestSize.Level1)
175 {
176 IPCTestHelper helper;
177 auto *remoteProxy = IpcCreateIPCRemoteProxy(helper);
178 ASSERT_NE(remoteProxy, nullptr);
179
180 OHIPCParcel *dataParcel = OH_IPCParcel_Create();
181 OHIPCParcel *replyParcel = OH_IPCParcel_Create();
182 OH_IPC_MessageOption option = {OH_IPC_REQUEST_MODE_SYNC, 0};
183
184 int ret = OH_IPCRemoteProxy_SendRequest(nullptr, TestCommand::TEST_CMD_GET_FOO_SERVICE,
185 dataParcel, replyParcel, &option);
186 EXPECT_EQ(ret, OH_IPC_CHECK_PARAM_ERROR);
187
188 ret = OH_IPCRemoteProxy_SendRequest(remoteProxy, TestCommand::TEST_CMD_GET_FOO_SERVICE,
189 nullptr, replyParcel, &option);
190 EXPECT_EQ(ret, OH_IPC_CHECK_PARAM_ERROR);
191
192 ret = OH_IPCRemoteProxy_SendRequest(remoteProxy, TestCommand::TEST_CMD_GET_FOO_SERVICE,
193 dataParcel, nullptr, &option);
194 EXPECT_EQ(ret, OH_IPC_CHECK_PARAM_ERROR);
195
196 ret = OH_IPCRemoteProxy_SendRequest(remoteProxy, TestCommand::TEST_CMD_GET_FOO_SERVICE,
197 dataParcel, replyParcel, &option);
198 EXPECT_EQ(ret, OH_IPC_SUCCESS);
199 auto *fooProxy = OH_IPCParcel_ReadRemoteProxy(replyParcel);
200 EXPECT_NE(fooProxy, nullptr);
201 OH_IPCParcel_Destroy(dataParcel);
202 OH_IPCParcel_Destroy(replyParcel);
203 OH_IPCRemoteProxy_Destroy(fooProxy);
204 OH_IPCRemoteProxy_Destroy(remoteProxy);
205 }
206
207 /**
208 * @tc.name: SendRequestAsync_001
209 * @tc.desc: Test use proxy to send async request message.
210 * @tc.type: FUNC
211 */
212 HWTEST_F(IpcCApiRemoteObjectModuleTest, SendRequestAsync_001, TestSize.Level1)
213 {
214 IPCTestHelper helper;
215 bool res = helper.StartTestApp(IPCTestHelper::IPC_TEST_SERVER);
216 ASSERT_TRUE(res);
217 std::unique_ptr<TestServiceClient> testClient = std::make_unique<TestServiceClient>();
218 ASSERT_NE(testClient, nullptr);
219 res = testClient->ConnectService();
220 ASSERT_TRUE(res);
221
222 res = testClient->TestRegisterRemoteStub();
223 ASSERT_TRUE(res);
224
225 auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
226 ASSERT_NE(saMgr, nullptr);
227
228 sptr<IRemoteObject> object = saMgr->GetSystemAbility(IPC_TEST_SERVICE);
229 ASSERT_NE(object, nullptr);
230 auto testService = iface_cast<ITestService>(object);
231 ASSERT_NE(testService, nullptr);
232 auto remoteProxyTest = std::make_shared<NativeRemoteProxyTest>(testService);
233 ASSERT_NE(remoteProxyTest, nullptr);
234 EXPECT_EQ(remoteProxyTest->ASyncAdd(), 0);
235
236 res = testClient->TestUnRegisterRemoteStub();
237 ASSERT_TRUE(res);
238 }
239
240 /**
241 * @tc.name: RemoteProxy_AddDeathRecipient_001
242 * @tc.desc: Test add death recipient.
243 * @tc.type: FUNC
244 */
245 HWTEST_F(IpcCApiRemoteObjectModuleTest, RemoteProxy_AddDeathRecipient_001, TestSize.Level1)
246 {
247 IPCTestHelper helper;
248 auto *remoteProxy = IpcCreateIPCRemoteProxy(helper);
249 ASSERT_NE(remoteProxy, nullptr);
250
251 auto deathRecipient = OH_IPCDeathRecipient_Create(OnDeathRecipientCallback, OnDeathRecipientDestroyCallback, this);
252 ASSERT_NE(deathRecipient, nullptr);
253 int ret = OH_IPCRemoteProxy_AddDeathRecipient(remoteProxy, deathRecipient);
254 EXPECT_EQ(ret, 0);
255
256 ResetCallbackReply();
257 bool res = helper.StopTestApp(IPCTestHelper::IPC_TEST_SERVER);
258 ASSERT_TRUE(res);
259 EXPECT_EQ(GetCallbackReply(), ON_CALLBACK_REPLIED_INT);
260 OH_IPCDeathRecipient_Destroy(deathRecipient);
261 OH_IPCRemoteProxy_Destroy(remoteProxy);
262 }
263
264 /**
265 * @tc.name: RemoteProxy_RemoveDeathRecipient_001
266 * @tc.desc: Test add death recipient.
267 * @tc.type: FUNC
268 */
269 HWTEST_F(IpcCApiRemoteObjectModuleTest, RemoteProxy_RemoveDeathRecipient_001, TestSize.Level1)
270 {
271 IPCTestHelper helper;
272 auto *remoteProxy = IpcCreateIPCRemoteProxy(helper);
273 ASSERT_NE(remoteProxy, nullptr);
274
275 auto deathRecipient = OH_IPCDeathRecipient_Create(OnDeathRecipientCallback, OnDeathRecipientDestroyCallback,
276 this);
277 ASSERT_NE(deathRecipient, nullptr);
278
279 int ret = OH_IPCRemoteProxy_AddDeathRecipient(remoteProxy, deathRecipient);
280 ASSERT_EQ(ret, 0);
281
282 ret = OH_IPCRemoteProxy_RemoveDeathRecipient(remoteProxy, deathRecipient);
283 EXPECT_EQ(ret, 0);
284
285 ResetCallbackReply();
286 bool res = helper.StopTestApp(IPCTestHelper::IPC_TEST_SERVER);
287 ASSERT_TRUE(res);
288 EXPECT_NE(GetCallbackReply(), ON_CALLBACK_REPLIED_INT);
289 OH_IPCDeathRecipient_Destroy(deathRecipient);
290 OH_IPCRemoteProxy_Destroy(remoteProxy);
291 }
292
293 /**
294 * @tc.name: IsRemoteDead_001
295 * @tc.desc: Test the IsRemoteDead function.
296 * @tc.type: FUNC
297 */
298 HWTEST_F(IpcCApiRemoteObjectModuleTest, IsRemoteDead_001, TestSize.Level1)
299 {
300 IPCTestHelper helper;
301 auto *remoteProxy = IpcCreateIPCRemoteProxy(helper);
302 ASSERT_NE(remoteProxy, nullptr);
303
304 int ret = OH_IPCRemoteProxy_IsRemoteDead(remoteProxy);
305 EXPECT_FALSE(ret);
306 bool res = helper.StopTestApp(IPCTestHelper::IPC_TEST_SERVER);
307 ASSERT_TRUE(res);
308 ret = OH_IPCRemoteProxy_IsRemoteDead(remoteProxy);
309 EXPECT_TRUE(ret);
310
311 OH_IPCRemoteProxy_Destroy(remoteProxy);
312 }
313
314 /**
315 * @tc.name: GetInterfaceDescriptor_001
316 * @tc.desc: Test the GetInterfaceDescriptor function.
317 * @tc.type: FUNC
318 */
319 HWTEST_F(IpcCApiRemoteObjectModuleTest, GetInterfaceDescriptor_001, TestSize.Level1)
320 {
321 IPCTestHelper helper;
322 auto *remoteProxy = IpcCreateIPCRemoteProxy(helper);
323 ASSERT_NE(remoteProxy, nullptr);
324
325 char *descriptor = nullptr;
326 int32_t len = 0;
327
328 int ret = OH_IPCRemoteProxy_GetInterfaceDescriptor(remoteProxy, &descriptor, &len, MemAllocator);
329 EXPECT_EQ(ret, 0);
330 EXPECT_EQ(strlen(descriptor) + 1, len);
331 EXPECT_GE(len, 0);
332
333 if (descriptor != nullptr) {
334 free(descriptor);
335 }
336 OH_IPCRemoteProxy_Destroy(remoteProxy);
337 }
338
339 /**
340 * @tc.name: OH_IPCParcel_TestReadWriteRemoteProxy_001
341 * @tc.desc: Test the Write and Read RemoteProxy function.
342 * @tc.type: FUNC
343 */
344 HWTEST_F(IpcCApiRemoteObjectModuleTest, OH_IPCParcel_TestReadWriteRemoteProxy_001, TestSize.Level1)
345 {
346 OHIPCParcel *parcel = OH_IPCParcel_Create();
347 EXPECT_NE(parcel, nullptr);
348 OHIPCRemoteProxy *remoteProxy = OH_IPCParcel_ReadRemoteProxy(nullptr);
349 EXPECT_EQ(remoteProxy, nullptr);
350
351 IPCTestHelper helper;
352 auto *proxy = IpcCreateIPCRemoteProxy(helper);
353 ASSERT_NE(proxy, nullptr);
354 EXPECT_EQ(OH_IPCParcel_WriteRemoteProxy(nullptr, proxy), OH_IPC_CHECK_PARAM_ERROR);
355 EXPECT_EQ(OH_IPCParcel_WriteRemoteProxy(parcel, nullptr), OH_IPC_CHECK_PARAM_ERROR);
356 EXPECT_EQ(OH_IPCParcel_WriteRemoteProxy(parcel, proxy), OH_IPC_SUCCESS);
357 remoteProxy = OH_IPCParcel_ReadRemoteProxy(parcel);
358 EXPECT_NE(remoteProxy, nullptr);
359 // destroy the objects
360 OH_IPCParcel_Destroy(parcel);
361 OH_IPCRemoteProxy_Destroy(proxy);
362 OH_IPCRemoteProxy_Destroy(remoteProxy);
363 bool res = helper.StopTestApp(IPCTestHelper::IPC_TEST_SERVER);
364 ASSERT_TRUE(res);
365 }
366 } // namespace OHOS