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 <fcntl.h>
17#include <gtest/gtest.h>
18
19#include "libinput_adapter.h"
20#include "mmi_log.h"
21#include "unique_fd.h"
22
23#undef MMI_LOG_TAG
24#define MMI_LOG_TAG "LibinputAdapterTest"
25namespace OHOS {
26namespace MMI {
27namespace {
28using namespace testing;
29using namespace testing::ext;
30constexpr int32_t WAIT_TIME_FOR_INPUT { 10 };
31constexpr int32_t MAX_RETRY_COUNT { 5 };
32
33constexpr static libinput_interface LIBINPUT_INTERFACE = {
34    .open_restricted = [](const char *path, int32_t flags, void *user_data)->int32_t {
35        if (path == nullptr) {
36            MMI_HILOGWK("Input device path is nullptr");
37            return RET_ERR;
38        }
39        char realPath[PATH_MAX] = {};
40        if (realpath(path, realPath) == nullptr) {
41            std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME_FOR_INPUT));
42            MMI_HILOGWK("The error path is %{public}s", path);
43            return RET_ERR;
44        }
45        int32_t fd = 0;
46        for (int32_t i = 0; i < MAX_RETRY_COUNT; i++) {
47            fd = open(realPath, flags);
48            if (fd >= 0) {
49                break;
50            }
51            std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME_FOR_INPUT));
52        }
53        int32_t errNo = errno;
54        MMI_HILOGWK("Libinput .open_restricted path:%{private}s,fd:%{public}d,errno:%{public}d", path, fd, errNo);
55        return fd < 0 ? RET_ERR : fd;
56    },
57    .close_restricted = [](int32_t fd, void *user_data)
58    {
59        if (fd < 0) {
60            return;
61        }
62        MMI_HILOGI("Libinput .close_restricted fd:%{public}d", fd);
63        close(fd);
64    },
65};
66} // namespace
67
68class LibinputAdapterTest : public testing::Test {
69public:
70    static void SetUpTestCase(void) {}
71    static void TearDownTestCase(void) {}
72};
73
74/**
75 * @tc.name: LibinputAdapterTest_EventDispatch
76 * @tc.desc: Cover if (fd == fd_) branch
77 * @tc.type: FUNC
78 * @tc.require:
79 */
80HWTEST_F(LibinputAdapterTest, LibinputAdapterTest_EventDispatch, TestSize.Level1)
81{
82    CALL_TEST_DEBUG;
83    LibinputAdapter libinputAdapter;
84    int32_t fd = 10;
85    libinputAdapter.fd_ = 10;
86    libinputAdapter.input_ = libinput_path_create_context(&LIBINPUT_INTERFACE, nullptr);
87    ASSERT_NO_FATAL_FAILURE(libinputAdapter.EventDispatch(fd));
88}
89
90/**
91 * @tc.name: LibinputAdapterTest_EventDispatch_001
92 * @tc.desc: Cover else if (fd == hotplugDetector_.GetFd()) branch
93 * @tc.type: FUNC
94 * @tc.require:
95 */
96HWTEST_F(LibinputAdapterTest, LibinputAdapterTest_EventDispatch_001, TestSize.Level1)
97{
98    CALL_TEST_DEBUG;
99    LibinputAdapter libinputAdapter;
100    int32_t fd = 10;
101    libinputAdapter.fd_ = 15;
102    libinputAdapter.hotplugDetector_.inotifyFd_ = UniqueFd{ 10 };
103    ASSERT_NO_FATAL_FAILURE(libinputAdapter.EventDispatch(fd));
104}
105
106/**
107 * @tc.name: LibinputAdapterTest_EventDispatch_002
108 * @tc.desc: Cover the else branch of if (fd == fd_)
109 * @tc.type: FUNC
110 * @tc.require:
111 */
112HWTEST_F(LibinputAdapterTest, LibinputAdapterTest_EventDispatch_002, TestSize.Level1)
113{
114    CALL_TEST_DEBUG;
115    LibinputAdapter libinputAdapter;
116    int32_t fd = 10;
117    libinputAdapter.fd_ = 15;
118    libinputAdapter.hotplugDetector_.inotifyFd_ = UniqueFd{ 15 };
119    ASSERT_NO_FATAL_FAILURE(libinputAdapter.EventDispatch(fd));
120}
121
122/**
123 * @tc.name: LibinputAdapterTest_Stop
124 * @tc.desc: Cover if (fd_ >= 0) branch
125 * @tc.type: FUNC
126 * @tc.require:
127 */
128HWTEST_F(LibinputAdapterTest, LibinputAdapterTest_Stop, TestSize.Level1)
129{
130    CALL_TEST_DEBUG;
131    LibinputAdapter libinputAdapter;
132    libinputAdapter.fd_ = 0;
133    libinputAdapter.input_ = nullptr;
134    ASSERT_NO_FATAL_FAILURE(libinputAdapter.Stop());
135}
136
137/**
138 * @tc.name: LibinputAdapterTest_Stop_001
139 * @tc.desc: Cover if (input_ != nullptr) branch
140 * @tc.type: FUNC
141 * @tc.require:
142 */
143HWTEST_F(LibinputAdapterTest, LibinputAdapterTest_Stop_001, TestSize.Level1)
144{
145    CALL_TEST_DEBUG;
146    LibinputAdapter libinputAdapter;
147    libinputAdapter.fd_ = -1;
148    libinputAdapter.input_ = libinput_path_create_context(&LIBINPUT_INTERFACE, nullptr);
149    ASSERT_NO_FATAL_FAILURE(libinputAdapter.Stop());
150}
151} // namespace MMI
152} // namespace OHOS