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
16 #include "device_manager_test.h"
17
18 #include <unistd.h>
19
20 #undef LOG_TAG
21 #define LOG_TAG "IntentionDeviceManagerTest"
22
23 namespace OHOS {
24 namespace Msdp {
25 namespace DeviceStatus {
26
27 using namespace testing::ext;
28 namespace {
29 struct device_status_epoll_event {
30 int32_t fd { -1 };
31 EpollEventType event_type { EPOLL_EVENT_BEGIN };
32 };
33
34 ContextService *g_instance = nullptr;
35 constexpr int32_t TIME_WAIT_FOR_OP_MS { 100 };
36 constexpr int32_t DEFAULT_WAIT_TIME_MS { 1000 };
37 constexpr int32_t WAIT_FOR_ONCE { 1 };
38 constexpr int32_t MAX_N_RETRIES { 100 };
39 const std::string TEST_DEV_NODE { "/dev/input/TestDeviceNode" };
40 } // namespace
41
ContextService()42 ContextService::ContextService()
43 {
44 FI_HILOGI("OHOS_BUILD_ENABLE_INTENTION_FRAMEWORK is on");
45 OnStart();
46 }
47
~ContextService()48 ContextService::~ContextService()
49 {
50 OnStop();
51 }
52
GetDelegateTasks()53 IDelegateTasks& ContextService::GetDelegateTasks()
54 {
55 return delegateTasks_;
56 }
57
GetDeviceManager()58 IDeviceManager& ContextService::GetDeviceManager()
59 {
60 return devMgr_;
61 }
62
GetTimerManager()63 ITimerManager& ContextService::GetTimerManager()
64 {
65 return timerMgr_;
66 }
67
GetDragManager()68 IDragManager& ContextService::GetDragManager()
69 {
70 return dragMgr_;
71 }
72
GetInstance()73 ContextService* ContextService::GetInstance()
74 {
75 static std::once_flag flag;
76 std::call_once(flag, [&]() {
77 ContextService *cooContext = new (std::nothrow) ContextService();
78 CHKPL(cooContext);
79 g_instance = cooContext;
80 });
81 return g_instance;
82 }
83
GetSocketSessionManager()84 ISocketSessionManager& ContextService::GetSocketSessionManager()
85 {
86 return socketSessionMgr_;
87 }
88
GetPluginManager()89 IPluginManager& ContextService::GetPluginManager()
90 {
91 return *pluginMgr_;
92 }
93
GetInput()94 IInputAdapter& ContextService::GetInput()
95 {
96 return *input_;
97 }
98
GetDSoftbus()99 IDSoftbusAdapter& ContextService::GetDSoftbus()
100 {
101 return *dsoftbusAda_;
102 }
103
Init()104 bool ContextService::Init()
105 {
106 CALL_DEBUG_ENTER;
107 if (EpollCreate() != RET_OK) {
108 FI_HILOGE("Create epoll failed");
109 return false;
110 }
111 if (InitDelegateTasks() != RET_OK) {
112 FI_HILOGE("Delegate tasks init failed");
113 goto INIT_FAIL;
114 }
115 if (InitTimerMgr() != RET_OK) {
116 FI_HILOGE("TimerMgr init failed");
117 goto INIT_FAIL;
118 }
119 if (InitDevMgr() != RET_OK) {
120 FI_HILOGE("DevMgr init failed");
121 goto INIT_FAIL;
122 }
123
124 return true;
125
126 INIT_FAIL:
127 EpollClose();
128 return false;
129 }
InitDevMgr()130 int32_t ContextService::InitDevMgr()
131 {
132 CALL_DEBUG_ENTER;
133 int32_t ret = devMgr_.Init(this);
134 if (ret != RET_OK) {
135 FI_HILOGE("DevMgr init failed");
136 return ret;
137 }
138 return ret;
139 }
140
InitTimerMgr()141 int32_t ContextService::InitTimerMgr()
142 {
143 CALL_DEBUG_ENTER;
144 int32_t ret = timerMgr_.Init(this);
145 if (ret != RET_OK) {
146 FI_HILOGE("TimerMgr init failed");
147 return ret;
148 }
149
150 ret = AddEpoll(EPOLL_EVENT_TIMER, timerMgr_.GetTimerFd());
151 if (ret != RET_OK) {
152 FI_HILOGE("AddEpoll for timer failed");
153 }
154 return ret;
155 }
156
InitDelegateTasks()157 int32_t ContextService::InitDelegateTasks()
158 {
159 CALL_DEBUG_ENTER;
160 if (!delegateTasks_.Init()) {
161 FI_HILOGE("The delegate task init failed");
162 return RET_ERR;
163 }
164 int32_t ret = AddEpoll(EPOLL_EVENT_ETASK, delegateTasks_.GetReadFd());
165 if (ret != RET_OK) {
166 FI_HILOGE("AddEpoll error ret:%{public}d", ret);
167 }
168 FI_HILOGI("AddEpoll, epollfd:%{public}d, fd:%{public}d", epollFd_, delegateTasks_.GetReadFd());
169 return ret;
170 }
171
EpollCreate()172 int32_t ContextService::EpollCreate()
173 {
174 CALL_DEBUG_ENTER;
175 epollFd_ = ::epoll_create1(EPOLL_CLOEXEC);
176 if (epollFd_ < 0) {
177 FI_HILOGE("epoll_create1 failed:%{public}s", ::strerror(errno));
178 return RET_ERR;
179 }
180 return RET_OK;
181 }
182
AddEpoll(EpollEventType type,int32_t fd)183 int32_t ContextService::AddEpoll(EpollEventType type, int32_t fd)
184 {
185 CALL_DEBUG_ENTER;
186 if (!(type >= EPOLL_EVENT_BEGIN && type < EPOLL_EVENT_END)) {
187 FI_HILOGE("Invalid type:%{public}d", type);
188 return RET_ERR;
189 }
190 if (fd < 0) {
191 FI_HILOGE("Invalid fd:%{public}d", fd);
192 return RET_ERR;
193 }
194 auto eventData = static_cast<device_status_epoll_event*>(malloc(sizeof(device_status_epoll_event)));
195 if (!eventData) {
196 FI_HILOGE("Malloc failed");
197 return RET_ERR;
198 }
199 eventData->fd = fd;
200 eventData->event_type = type;
201 FI_HILOGD("EventData:[fd:%{public}d, type:%{public}d]", eventData->fd, eventData->event_type);
202
203 struct epoll_event ev {};
204 ev.events = EPOLLIN;
205 ev.data.ptr = eventData;
206 if (EpollCtl(fd, EPOLL_CTL_ADD, ev) != RET_OK) {
207 free(eventData);
208 eventData = nullptr;
209 ev.data.ptr = nullptr;
210 FI_HILOGE("EpollCtl failed");
211 return RET_ERR;
212 }
213 return RET_OK;
214 }
215
DelEpoll(EpollEventType type,int32_t fd)216 int32_t ContextService::DelEpoll(EpollEventType type, int32_t fd)
217 {
218 CALL_DEBUG_ENTER;
219 if (!(type >= EPOLL_EVENT_BEGIN && type < EPOLL_EVENT_END)) {
220 FI_HILOGE("Invalid type:%{public}d", type);
221 return RET_ERR;
222 }
223 if (fd < 0) {
224 FI_HILOGE("Invalid fd:%{public}d", fd);
225 return RET_ERR;
226 }
227 struct epoll_event ev {};
228 if (EpollCtl(fd, EPOLL_CTL_DEL, ev) != RET_OK) {
229 FI_HILOGE("DelEpoll failed");
230 return RET_ERR;
231 }
232 return RET_OK;
233 }
234
EpollClose()235 void ContextService::EpollClose()
236 {
237 CALL_DEBUG_ENTER;
238 if (epollFd_ >= 0) {
239 if (close(epollFd_) < 0) {
240 FI_HILOGE("Close epoll fd failed, error:%{public}s, epollFd_:%{public}d", strerror(errno), epollFd_);
241 }
242 epollFd_ = -1;
243 }
244 }
245
EpollCtl(int32_t fd,int32_t op,struct epoll_event & event)246 int32_t ContextService::EpollCtl(int32_t fd, int32_t op, struct epoll_event &event)
247 {
248 CALL_DEBUG_ENTER;
249 if (fd < 0) {
250 FI_HILOGE("Invalid fd:%{public}d", fd);
251 return RET_ERR;
252 }
253 if (epollFd_ < 0) {
254 FI_HILOGE("Invalid epollFd:%{public}d", epollFd_);
255 return RET_ERR;
256 }
257 if (::epoll_ctl(epollFd_, op, fd, &event) != 0) {
258 FI_HILOGE("epoll_ctl(%{public}d,%{public}d,%{public}d) failed:%{public}s", epollFd_, op, fd, ::strerror(errno));
259 return RET_ERR;
260 }
261 return RET_OK;
262 }
263
EpollWait(int32_t maxevents,int32_t timeout,struct epoll_event & events)264 int32_t ContextService::EpollWait(int32_t maxevents, int32_t timeout, struct epoll_event &events)
265 {
266 if (epollFd_ < 0) {
267 FI_HILOGE("Invalid epollFd:%{public}d", epollFd_);
268 return RET_ERR;
269 }
270 return epoll_wait(epollFd_, &events, maxevents, timeout);
271 }
272
OnTimeout(const struct epoll_event & ev)273 void ContextService::OnTimeout(const struct epoll_event &ev)
274 {
275 CALL_DEBUG_ENTER;
276 if ((ev.events & EPOLLIN) == EPOLLIN) {
277 uint64_t expiration {};
278 ssize_t ret = read(timerMgr_.GetTimerFd(), &expiration, sizeof(expiration));
279 if (ret < 0) {
280 FI_HILOGE("Read expiration failed:%{public}s", strerror(errno));
281 }
282 timerMgr_.ProcessTimers();
283 } else if ((ev.events & (EPOLLHUP | EPOLLERR)) != 0) {
284 FI_HILOGE("Epoll hangup:%{public}s", strerror(errno));
285 }
286 }
287
OnDeviceMgr(const struct epoll_event & ev)288 void ContextService::OnDeviceMgr(const struct epoll_event &ev)
289 {
290 CALL_DEBUG_ENTER;
291 if ((ev.events & EPOLLIN) == EPOLLIN) {
292 devMgr_.Dispatch(ev);
293 } else if ((ev.events & (EPOLLHUP | EPOLLERR)) != 0) {
294 FI_HILOGE("Epoll hangup:%{public}s", strerror(errno));
295 }
296 }
297
EnableDevMgr(int32_t nRetries)298 int32_t ContextService::EnableDevMgr(int32_t nRetries)
299 {
300 CALL_INFO_TRACE;
301 static int32_t timerId { -1 };
302 int32_t ret = devMgr_.Enable();
303 if (ret != RET_OK) {
304 FI_HILOGE("Failed to enable device manager");
305 if (nRetries > 0) {
306 timerId = timerMgr_.AddTimer(DEFAULT_WAIT_TIME_MS, WAIT_FOR_ONCE,
307 [this, nRetries] { return this->EnableDevMgr(nRetries - 1); });
308 if (timerId < 0) {
309 FI_HILOGE("AddTimer failed, Failed to enable device manager");
310 }
311 } else {
312 FI_HILOGE("Maximum number of retries exceeded, Failed to enable device manager");
313 }
314 return ret;
315 }
316 AddEpoll(EPOLL_EVENT_DEVICE_MGR, devMgr_.GetFd());
317 if (timerId >= 0) {
318 timerMgr_.RemoveTimer(timerId);
319 timerId = -1;
320 }
321 return RET_OK;
322 }
323
DisableDevMgr()324 void ContextService::DisableDevMgr()
325 {
326 DelEpoll(EPOLL_EVENT_DEVICE_MGR, devMgr_.GetFd());
327 devMgr_.Disable();
328 }
329
OnStart()330 void ContextService::OnStart()
331 {
332 CALL_DEBUG_ENTER;
333 uint64_t tid = GetThisThreadId();
334 delegateTasks_.SetWorkerThreadId(tid);
335
336 if (!Init()) {
337 FI_HILOGE("On start call init failed");
338 return;
339 }
340 state_ = ServiceRunningState::STATE_RUNNING;
341 ready_ = true;
342
343 worker_ = std::thread(std::bind(&ContextService::OnThread, this));
344 }
345
OnStop()346 void ContextService::OnStop()
347 {
348 CALL_DEBUG_ENTER;
349 if (timerMgr_.GetTimerFd() >= 0) {
350 if (close(timerMgr_.GetTimerFd()) < 0) {
351 FI_HILOGE("Close timer fd failed, error:%{public}s", strerror(errno));
352 }
353 }
354 if (!ready_) {
355 FI_HILOGI("ready state is false");
356 return;
357 }
358 ready_ = false;
359 state_ = ServiceRunningState::STATE_EXIT;
360
361 delegateTasks_.PostAsyncTask([]() -> int32_t {
362 FI_HILOGD("No asynchronous operations");
363 return RET_OK;
364 });
365 if (worker_.joinable()) {
366 worker_.join();
367 }
368 DisableDevMgr();
369 EpollClose();
370 FI_HILOGI("OnStop leave");
371 }
372
OnThread()373 void ContextService::OnThread()
374 {
375 CALL_DEBUG_ENTER;
376 SetThreadName(std::string("os_ds_service"));
377 uint64_t tid = GetThisThreadId();
378 delegateTasks_.SetWorkerThreadId(tid);
379 EnableDevMgr(MAX_N_RETRIES);
380 FI_HILOGD("Main worker thread start, tid:%{public}" PRId64 "", tid);
381
382 while (state_ == ServiceRunningState::STATE_RUNNING) {
383 struct epoll_event ev[MAX_EVENT_SIZE] {};
384 int32_t count = EpollWait(MAX_EVENT_SIZE, -1, ev[0]);
385 for (int32_t i = 0; i < count && state_ == ServiceRunningState::STATE_RUNNING; i++) {
386 auto epollEvent = reinterpret_cast<device_status_epoll_event*>(ev[i].data.ptr);
387 CHKPC(epollEvent);
388 if (epollEvent->event_type == EPOLL_EVENT_TIMER) {
389 OnTimeout(ev[i]);
390 } else if (epollEvent->event_type == EPOLL_EVENT_ETASK) {
391 OnDelegateTask(ev[i]);
392 } else if (epollEvent->event_type == EPOLL_EVENT_DEVICE_MGR) {
393 OnDeviceMgr(ev[i]);
394 } else {
395 FI_HILOGW("Unknown epoll event type:%{public}d", epollEvent->event_type);
396 }
397 }
398 }
399 FI_HILOGD("Main worker thread stop, tid:%{public}" PRId64 "", tid);
400 }
401
OnDelegateTask(const struct epoll_event & ev)402 void ContextService::OnDelegateTask(const struct epoll_event &ev)
403 {
404 if ((ev.events & EPOLLIN) == 0) {
405 FI_HILOGW("Not epollin");
406 return;
407 }
408 DelegateTasks::TaskData data {};
409 ssize_t res = read(delegateTasks_.GetReadFd(), &data, sizeof(data));
410 if (res == -1) {
411 FI_HILOGW("Read failed erron:%{public}d", errno);
412 }
413 FI_HILOGD("RemoteRequest notify td:%{public}" PRId64 ", std:%{public}" PRId64 ""
414 ", taskId:%{public}d", GetThisThreadId(), data.tid, data.taskId);
415 delegateTasks_.ProcessTasks();
416 }
417
SetUpTestCase()418 void IntentionDeviceManagerTest::SetUpTestCase() {}
419
TearDownTestCase()420 void IntentionDeviceManagerTest::TearDownTestCase()
421 {
422 std::this_thread::sleep_for(std::chrono::milliseconds(TIME_WAIT_FOR_OP_MS));
423 }
424
SetUp()425 void IntentionDeviceManagerTest::SetUp() {}
426
TearDown()427 void IntentionDeviceManagerTest::TearDown() {}
428
429 /**
430 * @tc.name: IntentionDeviceManagerTest01
431 * @tc.desc: Test the founction AddDevice
432 * @tc.type: FUNC
433 */
434 HWTEST_F(IntentionDeviceManagerTest, IntentionDeviceManagerTest01, TestSize.Level1)
435 {
436 CALL_TEST_DEBUG;
437 auto env = ContextService::GetInstance();
438 ASSERT_NE(env, nullptr);
439 env->devMgr_.RemoveDevice(TEST_DEV_NODE);
440 env->devMgr_.FindDevice(TEST_DEV_NODE);
441 auto ret = env->devMgr_.AddDevice(TEST_DEV_NODE);
442 ASSERT_EQ(ret, nullptr);
443 ret = env->devMgr_.FindDevice(TEST_DEV_NODE);
444 ASSERT_EQ(ret, nullptr);
445 ret = env->devMgr_.RemoveDevice(TEST_DEV_NODE);
446 ASSERT_EQ(ret, nullptr);
447 }
448
449 /**
450 * @tc.name: IntentionDeviceManagerTest02
451 * @tc.desc: Test the founction Dispatch
452 * @tc.type: FUNC
453 */
454 HWTEST_F(IntentionDeviceManagerTest, IntentionDeviceManagerTest02, TestSize.Level1)
455 {
456 CALL_TEST_DEBUG;
457 auto env = ContextService::GetInstance();
458 ASSERT_NE(env, nullptr);
459 auto eventData = static_cast<device_status_epoll_event*>(malloc(sizeof(device_status_epoll_event)));
460 eventData->fd = 1;
461 eventData->event_type = EPOLL_EVENT_BEGIN;
462 struct epoll_event ev {};
463 ev.events = EPOLLIN;
464 ev.data.ptr = eventData;
465 ASSERT_NO_FATAL_FAILURE(env->devMgr_.Dispatch(ev));
466 }
467
468 /**
469 * @tc.name: IntentionDeviceManagerTest03
470 * @tc.desc: Test the founction GetDevice
471 * @tc.type: FUNC
472 */
473 HWTEST_F(IntentionDeviceManagerTest, IntentionDeviceManagerTest03, TestSize.Level1)
474 {
475 CALL_TEST_DEBUG;
476 auto env = ContextService::GetInstance();
477 ASSERT_NE(env, nullptr);
478 ASSERT_NO_FATAL_FAILURE(env->GetDeviceManager().GetDevice(1));
479 }
480
481
482 /**
483 * @tc.name: IntentionDeviceManagerTest04
484 * @tc.desc: Test the founction RetriggerHotplug
485 * @tc.type: FUNC
486 */
487 HWTEST_F(IntentionDeviceManagerTest, IntentionDeviceManagerTest04, TestSize.Level1)
488 {
489 CALL_TEST_DEBUG;
490 auto env = ContextService::GetInstance();
491 ASSERT_NE(env, nullptr);
492 std::weak_ptr<IDeviceObserver> weakObserver = std::weak_ptr<IDeviceObserver>();
493 ASSERT_NO_FATAL_FAILURE(env->GetDeviceManager().RetriggerHotplug(weakObserver));
494 }
495
496 /**
497 * @tc.name: IntentionDeviceManagerTest05
498 * @tc.desc: Test the founction AddDeviceObserver
499 * @tc.type: FUNC
500 */
501 HWTEST_F(IntentionDeviceManagerTest, IntentionDeviceManagerTest05, TestSize.Level1)
502 {
503 CALL_TEST_DEBUG;
504 auto env = ContextService::GetInstance();
505 ASSERT_NE(env, nullptr);
506 std::weak_ptr<IDeviceObserver> weakObserver = std::weak_ptr<IDeviceObserver>();
507 int32_t ret = env->GetDeviceManager().AddDeviceObserver(weakObserver);
508 EXPECT_EQ(ret, RET_ERR);
509 ASSERT_NO_FATAL_FAILURE(env->GetDeviceManager().RemoveDeviceObserver(weakObserver));
510 }
511
512 /**
513 * @tc.name: IntentionDeviceManagerTest06
514 * @tc.desc: Test the founction GetKeyboard
515 * @tc.type: FUNC
516 */
517 HWTEST_F(IntentionDeviceManagerTest, IntentionDeviceManagerTest06, TestSize.Level1)
518 {
519 CALL_TEST_DEBUG;
520 auto env = ContextService::GetInstance();
521 ASSERT_NE(env, nullptr);
522 env->devMgr_.AddDevice(TEST_DEV_NODE);
523 std::vector<std::shared_ptr<IDevice>> keyboards;
524 keyboards = env->devMgr_.GetKeyboard();
525 bool ret = env->devMgr_.HasKeyboard();
526 ASSERT_FALSE(ret);
527 }
528
529 /**
530 * @tc.name: IntentionDeviceManagerTest07
531 * @tc.desc: Test the founction Disable
532 * @tc.type: FUNC
533 */
534 HWTEST_F(IntentionDeviceManagerTest, IntentionDeviceManagerTest07, TestSize.Level1)
535 {
536 CALL_TEST_DEBUG;
537 auto env = ContextService::GetInstance();
538 ASSERT_NE(env, nullptr);
539 ASSERT_NO_FATAL_FAILURE(env->devMgr_.Disable());
540 }
541
542 /**
543 * @tc.name: IntentionDeviceManagerTest08
544 * @tc.desc: Test the founction OnRetriggerHotplug
545 * @tc.type: FUNC
546 */
547 HWTEST_F(IntentionDeviceManagerTest, IntentionDeviceManagerTest08, TestSize.Level1)
548 {
549 CALL_TEST_DEBUG;
550 auto env = ContextService::GetInstance();
551 ASSERT_NE(env, nullptr);
552 std::shared_ptr<DeviceObserverTest> observer = std::make_shared<DeviceObserverTest>();
553 std::weak_ptr<DeviceObserverTest> weakObserver = observer;
554 auto ret = env->devMgr_.AddDevice(TEST_DEV_NODE);
555 ASSERT_EQ(ret, nullptr);
556 ASSERT_NO_FATAL_FAILURE(env->devMgr_.OnRetriggerHotplug(weakObserver));
557 }
558
559 /**
560 * @tc.name: IntentionDeviceManagerTest08
561 * @tc.desc: Test the founction OnAddDeviceObserver
562 * @tc.type: FUNC
563 */
564 HWTEST_F(IntentionDeviceManagerTest, IntentionDeviceManagerTest09, TestSize.Level1)
565 {
566 CALL_TEST_DEBUG;
567 auto env = ContextService::GetInstance();
568 ASSERT_NE(env, nullptr);
569 std::shared_ptr<DeviceObserverTest> observer = std::make_shared<DeviceObserverTest>();
570 std::weak_ptr<DeviceObserverTest> weakObserver = observer;
571 ASSERT_NO_FATAL_FAILURE(env->devMgr_.OnAddDeviceObserver(weakObserver));
572 }
573
574 /**
575 * @tc.name: IntentionDeviceManagerTest08
576 * @tc.desc: Test the founction OnRemoveDeviceObserver
577 * @tc.type: FUNC
578 */
579 HWTEST_F(IntentionDeviceManagerTest, IntentionDeviceManagerTest010, TestSize.Level1)
580 {
581 CALL_TEST_DEBUG;
582 auto env = ContextService::GetInstance();
583 ASSERT_NE(env, nullptr);
584 std::shared_ptr<DeviceObserverTest> observer = std::make_shared<DeviceObserverTest>();
585 std::weak_ptr<DeviceObserverTest> weakObserver = observer;
586 env->devMgr_.OnAddDeviceObserver(weakObserver);
587 ASSERT_NO_FATAL_FAILURE(env->devMgr_.OnRemoveDeviceObserver(weakObserver));
588 }
589 } // namespace DeviceStatus
590 } // namespace Msdp
591 } // namespace OHOS