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