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 "virtual_device.h"
17
18 #include <fcntl.h>
19 #include <securec.h>
20 #include <unistd.h>
21
22 #include "mmi_log.h"
23
24 namespace OHOS {
25 namespace MMI {
26 namespace {
27 using namespace OHOS::HiviewDFX;
28 constexpr HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "VirtualDevice" };
29 constexpr uint32_t MAX_NAME_LENGTH = 80;
30
DoIoctl(int32_t fd,int32_t request,const uint32_t value)31 bool DoIoctl(int32_t fd, int32_t request, const uint32_t value)
32 {
33 int32_t rc = ioctl(fd, request, value);
34 if (rc < 0) {
35 MMI_HILOGE("Failed to ioctl");
36 return false;
37 }
38 return true;
39 }
40 } // namespace
41
VirtualDevice(const char * deviceName,uint16_t productId)42 VirtualDevice::VirtualDevice(const char *deviceName, uint16_t productId)
43 : deviceName_(deviceName),
44 busType_(BUS_USB),
45 vendorId_(0x6006),
46 productId_(productId),
47 version_(1) {}
48
~VirtualDevice()49 VirtualDevice::~VirtualDevice()
50 {
51 if (fd_ >= 0) {
52 ioctl(fd_, UI_DEV_DESTROY);
53 close(fd_);
54 fd_ = -1;
55 }
56 }
57
SetUp()58 bool VirtualDevice::SetUp()
59 {
60 fd_ = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
61 if (fd_ < 0) {
62 MMI_HILOGE("Failed to open uinput");
63 return false;
64 }
65 for (const auto &item : GetEventTypes()) {
66 if (!DoIoctl(fd_, UI_SET_EVBIT, item)) {
67 MMI_HILOGE("Error setting event type:%{public}u", item);
68 return false;
69 }
70 }
71 for (const auto &item : GetKeys()) {
72 if (!DoIoctl(fd_, UI_SET_KEYBIT, item)) {
73 MMI_HILOGE("Error setting key:%{public}u", item);
74 return false;
75 }
76 }
77 for (const auto &item : GetProperties()) {
78 if (!DoIoctl(fd_, UI_SET_PROPBIT, item)) {
79 MMI_HILOGE("Error setting property:%{public}u", item);
80 return false;
81 }
82 }
83 for (const auto &item : GetAbs()) {
84 if (!DoIoctl(fd_, UI_SET_ABSBIT, item)) {
85 MMI_HILOGE("Error setting property:%{public}u", item);
86 return false;
87 }
88 }
89 for (const auto &item : GetRelBits()) {
90 if (!DoIoctl(fd_, UI_SET_RELBIT, item)) {
91 MMI_HILOGE("Error setting rel:%{public}u", item);
92 return false;
93 }
94 }
95
96 errno_t ret = strncpy_s(dev_.name, MAX_NAME_LENGTH, deviceName_, sizeof(dev_.name));
97 if (ret != EOK) {
98 MMI_HILOGE("Failed to copy deviceName");
99 return false;
100 }
101 dev_.id.bustype = busType_;
102 dev_.id.vendor = vendorId_;
103 dev_.id.product = productId_;
104 dev_.id.version = version_;
105 if (write(fd_, &dev_, sizeof(dev_)) < 0) {
106 MMI_HILOGE("Unable to set input device info");
107 return false;
108 }
109 if (ioctl(fd_, UI_DEV_CREATE) < 0) {
110 MMI_HILOGE("Unable to create input device");
111 return false;
112 }
113 return true;
114 }
115
EmitEvent(uint16_t type,uint16_t code,uint32_t value) const116 bool VirtualDevice::EmitEvent(uint16_t type, uint16_t code, uint32_t value) const
117 {
118 struct input_event event {};
119 event.type = type;
120 event.code = code;
121 event.value = value;
122 #ifndef __MUSL__
123 gettimeofday(&event.time, nullptr);
124 #endif
125 if (write(fd_, &event, sizeof(event)) < static_cast<ssize_t>(sizeof(event))) {
126 MMI_HILOGE("Event write failed");
127 return false;
128 }
129 return true;
130 }
131
GetEventTypes() const132 const std::vector<uint32_t> &VirtualDevice::GetEventTypes() const
133 {
134 static const std::vector<uint32_t> evtTypes {};
135 return evtTypes;
136 }
137
GetKeys() const138 const std::vector<uint32_t> &VirtualDevice::GetKeys() const
139 {
140 static const std::vector<uint32_t> keys {};
141 return keys;
142 }
143
GetProperties() const144 const std::vector<uint32_t> &VirtualDevice::GetProperties() const
145 {
146 static const std::vector<uint32_t> properties {};
147 return properties;
148 }
149
GetAbs() const150 const std::vector<uint32_t> &VirtualDevice::GetAbs() const
151 {
152 static const std::vector<uint32_t> abs {};
153 return abs;
154 }
155
GetRelBits() const156 const std::vector<uint32_t> &VirtualDevice::GetRelBits() const
157 {
158 static const std::vector<uint32_t> relBits {};
159 return relBits;
160 }
161 }
162 }
163