• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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