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