1 /*
2 * Copyright (c) 2021-2022 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 "s_input.h"
17 #include <climits>
18 #include <fcntl.h>
19 #include <cinttypes>
20 #include <sys/epoll.h>
21 #include <unistd.h>
22 #include "libmmi_util.h"
23 #include "safe_keeper.h"
24 #include "util.h"
25 #include "input_windows_manager.h"
26 namespace OHOS {
27 namespace MMI {
28 namespace {
29 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "SInput" };
30 }
31
HiLogFunc(struct libinput * input,enum libinput_log_priority priority,const char * fmt,va_list args)32 static void HiLogFunc(struct libinput* input, enum libinput_log_priority priority, const char* fmt, va_list args)
33 {
34 char buffer[256];
35 int ret = vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, fmt, args);
36 if (ret == -1) {
37 MMI_LOGE("call vsnprintf_s fail, ret:%{public}d", ret);
38 va_end(args);
39 return;
40 }
41 MMI_LOGE("PrintLog_Info:%{public}s", buffer);
42 va_end(args);
43 }
44
InitHiLogFunc(struct libinput * input)45 static void InitHiLogFunc(struct libinput* input)
46 {
47 CHKPV(input);
48 static bool initFlag = false;
49 if (initFlag) {
50 return;
51 }
52 libinput_log_set_handler(input, &OHOS::MMI::HiLogFunc);
53 initFlag = true;
54 }
55 } // namespace MMI
56 } // namespace OHOS
57
LoginfoPackagingTool(struct libinput_event * event)58 void OHOS::MMI::SInput::LoginfoPackagingTool(struct libinput_event *event)
59 {
60 CHKPV(event);
61 auto context = libinput_event_get_context(event);
62 InitHiLogFunc(context);
63 }
64
65 constexpr static libinput_interface LIBINPUT_INTERFACE = {
__anon6d307b2a0202()66 .open_restricted = [](const char *path, int32_t flags, void *user_data)->int32_t {
67 using namespace OHOS::MMI;
68 CHKPR(path, errno);
69 char realPath[PATH_MAX] = {};
70 if (realpath(path, realPath) == nullptr) {
71 MMI_LOGE("path is error, path:%{public}s", path);
72 return RET_ERR;
73 }
74 int32_t fd = open(realPath, flags);
75 MMI_LOGD("libinput .open_restricted path:%{public}s,fd:%{public}d", path, fd);
76 return fd < 0 ? -errno : fd;
77 },
78 .close_restricted = [](int32_t fd, void *user_data)
__anon6d307b2a0302() 79 {
80 using namespace OHOS::MMI;
81 MMI_LOGI("libinput .close_restricted fd:%{public}d", fd);
82 close(fd);
83 },
84 };
85
SInput()86 OHOS::MMI::SInput::SInput() {}
87
~SInput()88 OHOS::MMI::SInput::~SInput() {}
89
Init(FunInputEvent funInputEvent,const std::string & seat_id)90 bool OHOS::MMI::SInput::Init(FunInputEvent funInputEvent, const std::string& seat_id)
91 {
92 MMI_LOGD("enter");
93 CHKPF(funInputEvent);
94 funInputEvent_ = funInputEvent;
95 seat_id_ = seat_id;
96 if (seat_id_.empty()) {
97 seat_id_ = DEF_SEAT_ID;
98 }
99 udev_ = udev_new();
100 CHKPF(udev_);
101 input_ = libinput_udev_create_context(&LIBINPUT_INTERFACE, nullptr, udev_);
102 CHKPF(input_);
103 auto rt = libinput_udev_assign_seat(input_, seat_id_.c_str());
104 if (rt != 0) {
105 libinput_unref(input_);
106 udev_unref(udev_);
107 MMI_LOGE("rt is not 0");
108 return false;
109 }
110 fd_ = libinput_get_fd(input_);
111 if (fd_ < 0) {
112 libinput_unref(input_);
113 udev_unref(udev_);
114 fd_ = -1;
115 MMI_LOGE("fd_ is less than 0");
116 return false;
117 }
118 MMI_LOGD("leave");
119 return true;
120 }
121
EventDispatch(struct epoll_event & ev)122 void OHOS::MMI::SInput::EventDispatch(struct epoll_event& ev)
123 {
124 MMI_LOGD("enter");
125 CHKPV(ev.data.ptr);
126 auto fd = *static_cast<int*>(ev.data.ptr);
127 if ((ev.events & EPOLLERR) || (ev.events & EPOLLHUP)) {
128 MMI_LOGF("SInput::OnEventDispatch epoll unrecoverable error,"
129 "The service must be restarted. fd:%{public}d", fd);
130 free(ev.data.ptr);
131 ev.data.ptr = nullptr;
132 return;
133 }
134 if (libinput_dispatch(input_) != 0) {
135 MMI_LOGE("libinput: Failed to dispatch libinput");
136 return;
137 }
138 OnEventHandler();
139 MMI_LOGD("leave");
140 }
141
Stop()142 void OHOS::MMI::SInput::Stop()
143 {
144 MMI_LOGD("enter");
145 if (fd_ >= 0) {
146 close(fd_);
147 fd_ = -1;
148 }
149 libinput_unref(input_);
150 udev_unref(udev_);
151 MMI_LOGD("leave");
152 }
153
OnEventHandler()154 void OHOS::MMI::SInput::OnEventHandler()
155 {
156 MMI_LOGD("enter");
157 CHKPV(funInputEvent_);
158 multimodal_libinput_event ev = { nullptr, nullptr };
159 while ((ev.event = libinput_get_event(input_))) {
160 funInputEvent_(&ev);
161 libinput_event_destroy(ev.event);
162 }
163 MMI_LOGD("leave");
164 }
165