1c29fa5a6Sopenharmony_ci/* 2c29fa5a6Sopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3c29fa5a6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4c29fa5a6Sopenharmony_ci * you may not use this file except in compliance with the License. 5c29fa5a6Sopenharmony_ci * You may obtain a copy of the License at 6c29fa5a6Sopenharmony_ci * 7c29fa5a6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8c29fa5a6Sopenharmony_ci * 9c29fa5a6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10c29fa5a6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11c29fa5a6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12c29fa5a6Sopenharmony_ci * See the License for the specific language governing permissions and 13c29fa5a6Sopenharmony_ci * limitations under the License. 14c29fa5a6Sopenharmony_ci */ 15c29fa5a6Sopenharmony_ci 16c29fa5a6Sopenharmony_ci#include "device.h" 17c29fa5a6Sopenharmony_ci 18c29fa5a6Sopenharmony_ci#include <fcntl.h> 19c29fa5a6Sopenharmony_ci#include <unistd.h> 20c29fa5a6Sopenharmony_ci#include <sys/ioctl.h> 21c29fa5a6Sopenharmony_ci 22c29fa5a6Sopenharmony_ci#include <cstring> 23c29fa5a6Sopenharmony_ci#include <fstream> 24c29fa5a6Sopenharmony_ci#include <map> 25c29fa5a6Sopenharmony_ci#include <regex> 26c29fa5a6Sopenharmony_ci#include <sstream> 27c29fa5a6Sopenharmony_ci 28c29fa5a6Sopenharmony_ci#include <openssl/sha.h> 29c29fa5a6Sopenharmony_ci#include <securec.h> 30c29fa5a6Sopenharmony_ci 31c29fa5a6Sopenharmony_ci#include "devicestatus_define.h" 32c29fa5a6Sopenharmony_ci#include "devicestatus_errors.h" 33c29fa5a6Sopenharmony_ci#include "fi_log.h" 34c29fa5a6Sopenharmony_ci#include "if_stream_wrap.h" 35c29fa5a6Sopenharmony_ci#include "napi_constants.h" 36c29fa5a6Sopenharmony_ci#include "utility.h" 37c29fa5a6Sopenharmony_ci 38c29fa5a6Sopenharmony_ci#undef LOG_TAG 39c29fa5a6Sopenharmony_ci#define LOG_TAG "Device" 40c29fa5a6Sopenharmony_ci 41c29fa5a6Sopenharmony_cinamespace OHOS { 42c29fa5a6Sopenharmony_cinamespace Msdp { 43c29fa5a6Sopenharmony_cinamespace DeviceStatus { 44c29fa5a6Sopenharmony_cistruct Range { 45c29fa5a6Sopenharmony_ci size_t start { 0 }; 46c29fa5a6Sopenharmony_ci size_t end { 0 }; 47c29fa5a6Sopenharmony_ci}; 48c29fa5a6Sopenharmony_ci 49c29fa5a6Sopenharmony_cinamespace { 50c29fa5a6Sopenharmony_ciconstexpr int32_t COMMENT_SUBSCRIPT { 0 }; 51c29fa5a6Sopenharmony_ciconstexpr ssize_t MAX_FILE_SIZE_ALLOWED { 0x5000 }; 52c29fa5a6Sopenharmony_ci 53c29fa5a6Sopenharmony_ciconst struct Range KEY_BLOCKS[] { 54c29fa5a6Sopenharmony_ci { KEY_ESC, BTN_MISC }, 55c29fa5a6Sopenharmony_ci { KEY_OK, BTN_DPAD_UP }, 56c29fa5a6Sopenharmony_ci { KEY_ALS_TOGGLE, BTN_TRIGGER_HAPPY } 57c29fa5a6Sopenharmony_ci}; 58c29fa5a6Sopenharmony_ci} // namespace 59c29fa5a6Sopenharmony_ci 60c29fa5a6Sopenharmony_ciDevice::Device(int32_t deviceId) 61c29fa5a6Sopenharmony_ci : deviceId_(deviceId) 62c29fa5a6Sopenharmony_ci{} 63c29fa5a6Sopenharmony_ci 64c29fa5a6Sopenharmony_ciDevice::~Device() 65c29fa5a6Sopenharmony_ci{ 66c29fa5a6Sopenharmony_ci Close(); 67c29fa5a6Sopenharmony_ci} 68c29fa5a6Sopenharmony_ci 69c29fa5a6Sopenharmony_ciint32_t Device::Open() 70c29fa5a6Sopenharmony_ci{ 71c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 72c29fa5a6Sopenharmony_ci char buf[PATH_MAX] {}; 73c29fa5a6Sopenharmony_ci if (realpath(devPath_.c_str(), buf) == nullptr) { 74c29fa5a6Sopenharmony_ci FI_HILOGE("Not real path:%{private}s", devPath_.c_str()); 75c29fa5a6Sopenharmony_ci return RET_ERR; 76c29fa5a6Sopenharmony_ci } 77c29fa5a6Sopenharmony_ci 78c29fa5a6Sopenharmony_ci int32_t nRetries { 6 }; 79c29fa5a6Sopenharmony_ci for (;;) { 80c29fa5a6Sopenharmony_ci Utility::ShowUserAndGroup(); 81c29fa5a6Sopenharmony_ci Utility::ShowFileAttributes(buf); 82c29fa5a6Sopenharmony_ci 83c29fa5a6Sopenharmony_ci fd_ = open(buf, O_RDWR | O_NONBLOCK | O_CLOEXEC); 84c29fa5a6Sopenharmony_ci if (fd_ < 0) { 85c29fa5a6Sopenharmony_ci FI_HILOGE("Open device \'%{public}s\':%{public}s failed", buf, strerror(errno)); 86c29fa5a6Sopenharmony_ci if (nRetries-- > 0) { 87c29fa5a6Sopenharmony_ci static constexpr int32_t DEFAULT_WAIT_TIME { 500 }; 88c29fa5a6Sopenharmony_ci std::this_thread::sleep_for(std::chrono::milliseconds(DEFAULT_WAIT_TIME)); 89c29fa5a6Sopenharmony_ci FI_HILOGI("Retry opening the device \'%{public}s\'", buf); 90c29fa5a6Sopenharmony_ci } else { 91c29fa5a6Sopenharmony_ci return RET_ERR; 92c29fa5a6Sopenharmony_ci } 93c29fa5a6Sopenharmony_ci } else { 94c29fa5a6Sopenharmony_ci FI_HILOGD("Successful opening \'%{public}s\'", buf); 95c29fa5a6Sopenharmony_ci break; 96c29fa5a6Sopenharmony_ci } 97c29fa5a6Sopenharmony_ci } 98c29fa5a6Sopenharmony_ci QueryDeviceInfo(); 99c29fa5a6Sopenharmony_ci QuerySupportedEvents(); 100c29fa5a6Sopenharmony_ci UpdateCapability(); 101c29fa5a6Sopenharmony_ci LoadDeviceConfig(); 102c29fa5a6Sopenharmony_ci return RET_OK; 103c29fa5a6Sopenharmony_ci} 104c29fa5a6Sopenharmony_ci 105c29fa5a6Sopenharmony_civoid Device::Close() 106c29fa5a6Sopenharmony_ci{ 107c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 108c29fa5a6Sopenharmony_ci if (fd_ >= 0) { 109c29fa5a6Sopenharmony_ci if (close(fd_) < 0) { 110c29fa5a6Sopenharmony_ci FI_HILOGE("Close fd failed, error:%{public}s, fd_:%{public}d", strerror(errno), fd_); 111c29fa5a6Sopenharmony_ci } 112c29fa5a6Sopenharmony_ci fd_ = -1; 113c29fa5a6Sopenharmony_ci } 114c29fa5a6Sopenharmony_ci} 115c29fa5a6Sopenharmony_ci 116c29fa5a6Sopenharmony_civoid Device::Dispatch(const struct epoll_event &ev) 117c29fa5a6Sopenharmony_ci{ 118c29fa5a6Sopenharmony_ci if ((ev.events & EPOLLIN) == EPOLLIN) { 119c29fa5a6Sopenharmony_ci FI_HILOGD("Input data received"); 120c29fa5a6Sopenharmony_ci } else if ((ev.events & (EPOLLHUP | EPOLLERR)) != 0) { 121c29fa5a6Sopenharmony_ci FI_HILOGE("Epoll hangup, errno:%{public}s", strerror(errno)); 122c29fa5a6Sopenharmony_ci } 123c29fa5a6Sopenharmony_ci} 124c29fa5a6Sopenharmony_ci 125c29fa5a6Sopenharmony_civoid Device::QueryDeviceInfo() 126c29fa5a6Sopenharmony_ci{ 127c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 128c29fa5a6Sopenharmony_ci char buffer[PATH_MAX] = { 0 }; 129c29fa5a6Sopenharmony_ci int32_t rc = ioctl(fd_, EVIOCGNAME(sizeof(buffer) - 1), &buffer); 130c29fa5a6Sopenharmony_ci if (rc < 0) { 131c29fa5a6Sopenharmony_ci FI_HILOGE("Could not get device name, errno:%{public}s", strerror(errno)); 132c29fa5a6Sopenharmony_ci } else { 133c29fa5a6Sopenharmony_ci name_.assign(buffer); 134c29fa5a6Sopenharmony_ci } 135c29fa5a6Sopenharmony_ci 136c29fa5a6Sopenharmony_ci struct input_id inputId; 137c29fa5a6Sopenharmony_ci rc = ioctl(fd_, EVIOCGID, &inputId); 138c29fa5a6Sopenharmony_ci if (rc < 0) { 139c29fa5a6Sopenharmony_ci FI_HILOGE("Could not get device input id, errno:%{public}s", strerror(errno)); 140c29fa5a6Sopenharmony_ci } else { 141c29fa5a6Sopenharmony_ci bus_ = inputId.bustype; 142c29fa5a6Sopenharmony_ci product_ = inputId.product; 143c29fa5a6Sopenharmony_ci vendor_ = inputId.vendor; 144c29fa5a6Sopenharmony_ci version_ = inputId.version; 145c29fa5a6Sopenharmony_ci } 146c29fa5a6Sopenharmony_ci 147c29fa5a6Sopenharmony_ci errno_t ret = memset_s(buffer, sizeof(buffer), 0, sizeof(buffer)); 148c29fa5a6Sopenharmony_ci if (ret != EOK) { 149c29fa5a6Sopenharmony_ci FI_HILOGE("Call memset_s failed"); 150c29fa5a6Sopenharmony_ci return; 151c29fa5a6Sopenharmony_ci } 152c29fa5a6Sopenharmony_ci rc = ioctl(fd_, EVIOCGPHYS(sizeof(buffer) - 1), &buffer); 153c29fa5a6Sopenharmony_ci if (rc < 0) { 154c29fa5a6Sopenharmony_ci FI_HILOGE("Could not get location:%{public}s", strerror(errno)); 155c29fa5a6Sopenharmony_ci } else { 156c29fa5a6Sopenharmony_ci phys_.assign(buffer); 157c29fa5a6Sopenharmony_ci } 158c29fa5a6Sopenharmony_ci ret = memset_s(buffer, sizeof(buffer), 0, sizeof(buffer)); 159c29fa5a6Sopenharmony_ci if (ret != EOK) { 160c29fa5a6Sopenharmony_ci FI_HILOGE("Call memset_s failed"); 161c29fa5a6Sopenharmony_ci return; 162c29fa5a6Sopenharmony_ci } 163c29fa5a6Sopenharmony_ci rc = ioctl(fd_, EVIOCGUNIQ(sizeof(buffer) - 1), &buffer); 164c29fa5a6Sopenharmony_ci if (rc < 0) { 165c29fa5a6Sopenharmony_ci FI_HILOGE("Could not get uniq, errno:%{public}s", strerror(errno)); 166c29fa5a6Sopenharmony_ci } else { 167c29fa5a6Sopenharmony_ci uniq_.assign(buffer); 168c29fa5a6Sopenharmony_ci } 169c29fa5a6Sopenharmony_ci} 170c29fa5a6Sopenharmony_ci 171c29fa5a6Sopenharmony_civoid Device::GetEventMask(const std::string &eventName, uint32_t type, 172c29fa5a6Sopenharmony_ci std::size_t arrayLength, uint8_t *whichBitMask) const 173c29fa5a6Sopenharmony_ci{ 174c29fa5a6Sopenharmony_ci int32_t rc = ioctl(fd_, EVIOCGBIT(type, arrayLength), whichBitMask); 175c29fa5a6Sopenharmony_ci if (rc < 0) { 176c29fa5a6Sopenharmony_ci FI_HILOGE("Could not get %{public}s events mask:%{public}s", eventName.c_str(), strerror(errno)); 177c29fa5a6Sopenharmony_ci } 178c29fa5a6Sopenharmony_ci} 179c29fa5a6Sopenharmony_ci 180c29fa5a6Sopenharmony_civoid Device::GetPropMask(const std::string &eventName, std::size_t arrayLength, uint8_t *whichBitMask) const 181c29fa5a6Sopenharmony_ci{ 182c29fa5a6Sopenharmony_ci int32_t rc = ioctl(fd_, EVIOCGPROP(arrayLength), whichBitMask); 183c29fa5a6Sopenharmony_ci if (rc < 0) { 184c29fa5a6Sopenharmony_ci FI_HILOGE("Could not get %{public}s mask:%{public}s", eventName.c_str(), strerror(errno)); 185c29fa5a6Sopenharmony_ci } 186c29fa5a6Sopenharmony_ci} 187c29fa5a6Sopenharmony_ci 188c29fa5a6Sopenharmony_civoid Device::QuerySupportedEvents() 189c29fa5a6Sopenharmony_ci{ 190c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 191c29fa5a6Sopenharmony_ci GetEventMask("", 0, sizeof(evBitmask_), evBitmask_); 192c29fa5a6Sopenharmony_ci GetEventMask("key", EV_KEY, sizeof(keyBitmask_), keyBitmask_); 193c29fa5a6Sopenharmony_ci GetEventMask("abs", EV_ABS, sizeof(absBitmask_), absBitmask_); 194c29fa5a6Sopenharmony_ci GetEventMask("rel", EV_REL, sizeof(relBitmask_), relBitmask_); 195c29fa5a6Sopenharmony_ci GetPropMask("properties", sizeof(propBitmask_), propBitmask_); 196c29fa5a6Sopenharmony_ci} 197c29fa5a6Sopenharmony_ci 198c29fa5a6Sopenharmony_civoid Device::UpdateCapability() 199c29fa5a6Sopenharmony_ci{ 200c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 201c29fa5a6Sopenharmony_ci CheckPointers(); 202c29fa5a6Sopenharmony_ci CheckPencilMouse(); 203c29fa5a6Sopenharmony_ci CheckKeys(); 204c29fa5a6Sopenharmony_ci} 205c29fa5a6Sopenharmony_ci 206c29fa5a6Sopenharmony_cibool Device::HasAxesOrButton(size_t start, size_t end, const uint8_t* whichBitMask) const 207c29fa5a6Sopenharmony_ci{ 208c29fa5a6Sopenharmony_ci for (size_t type = start; type < end; ++type) { 209c29fa5a6Sopenharmony_ci if (TestBit(type, whichBitMask)) { 210c29fa5a6Sopenharmony_ci return true; 211c29fa5a6Sopenharmony_ci } 212c29fa5a6Sopenharmony_ci } 213c29fa5a6Sopenharmony_ci return false; 214c29fa5a6Sopenharmony_ci} 215c29fa5a6Sopenharmony_ci 216c29fa5a6Sopenharmony_cibool Device::HasJoystickAxesOrButtons() const 217c29fa5a6Sopenharmony_ci{ 218c29fa5a6Sopenharmony_ci if (!TestBit(BTN_JOYSTICK - 1, keyBitmask_)) { 219c29fa5a6Sopenharmony_ci if (HasAxesOrButton(BTN_JOYSTICK, BTN_DIGI, keyBitmask_) || 220c29fa5a6Sopenharmony_ci // BTN_TRIGGER_HAPPY40 + 1 : loop boundary 221c29fa5a6Sopenharmony_ci HasAxesOrButton(BTN_TRIGGER_HAPPY1, BTN_TRIGGER_HAPPY40 + 1, keyBitmask_) || 222c29fa5a6Sopenharmony_ci HasAxesOrButton(BTN_DPAD_UP, BTN_DPAD_RIGHT + 1, keyBitmask_)) { // BTN_DPAD_RIGHT + 1 : loop boundary 223c29fa5a6Sopenharmony_ci return true; 224c29fa5a6Sopenharmony_ci } 225c29fa5a6Sopenharmony_ci } 226c29fa5a6Sopenharmony_ci return HasAxesOrButton(ABS_RX, ABS_PRESSURE, absBitmask_); 227c29fa5a6Sopenharmony_ci} 228c29fa5a6Sopenharmony_ci 229c29fa5a6Sopenharmony_cibool Device::HasAbsCoord() const 230c29fa5a6Sopenharmony_ci{ 231c29fa5a6Sopenharmony_ci return (HasAbs(ABS_X) && HasAbs(ABS_Y)); 232c29fa5a6Sopenharmony_ci} 233c29fa5a6Sopenharmony_ci 234c29fa5a6Sopenharmony_cibool Device::HasMtCoord() const 235c29fa5a6Sopenharmony_ci{ 236c29fa5a6Sopenharmony_ci return (HasAbs(ABS_MT_POSITION_X) && HasAbs(ABS_MT_POSITION_Y)); 237c29fa5a6Sopenharmony_ci} 238c29fa5a6Sopenharmony_ci 239c29fa5a6Sopenharmony_cibool Device::HasRelCoord() const 240c29fa5a6Sopenharmony_ci{ 241c29fa5a6Sopenharmony_ci return (HasRel(REL_X) && HasRel(REL_Y)); 242c29fa5a6Sopenharmony_ci} 243c29fa5a6Sopenharmony_ci 244c29fa5a6Sopenharmony_civoid Device::PrintCapsDevice() const 245c29fa5a6Sopenharmony_ci{ 246c29fa5a6Sopenharmony_ci const std::map<std::size_t, std::string> deviceComparisonTable { 247c29fa5a6Sopenharmony_ci { DEVICE_CAP_KEYBOARD, "keyboard" }, 248c29fa5a6Sopenharmony_ci { DEVICE_CAP_TOUCH, "touch device" }, 249c29fa5a6Sopenharmony_ci { DEVICE_CAP_POINTER, "pointer" }, 250c29fa5a6Sopenharmony_ci { DEVICE_CAP_TABLET_TOOL, "tablet tool" }, 251c29fa5a6Sopenharmony_ci { DEVICE_CAP_TABLET_PAD, "pad" }, 252c29fa5a6Sopenharmony_ci { DEVICE_CAP_GESTURE, "gesture" }, 253c29fa5a6Sopenharmony_ci { DEVICE_CAP_SWITCH, "switch" }, 254c29fa5a6Sopenharmony_ci { DEVICE_CAP_JOYSTICK, "joystick" } 255c29fa5a6Sopenharmony_ci }; 256c29fa5a6Sopenharmony_ci for (const auto &[cap, name]: deviceComparisonTable) { 257c29fa5a6Sopenharmony_ci if (caps_.test(cap)) { 258c29fa5a6Sopenharmony_ci FI_HILOGD("This is %{public}s", name.c_str()); 259c29fa5a6Sopenharmony_ci } 260c29fa5a6Sopenharmony_ci } 261c29fa5a6Sopenharmony_ci} 262c29fa5a6Sopenharmony_ci 263c29fa5a6Sopenharmony_civoid Device::CheckPointers() 264c29fa5a6Sopenharmony_ci{ 265c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 266c29fa5a6Sopenharmony_ci if (HasAbsCoord()) { 267c29fa5a6Sopenharmony_ci CheckAbs(); 268c29fa5a6Sopenharmony_ci } else { 269c29fa5a6Sopenharmony_ci CheckJoystick(); 270c29fa5a6Sopenharmony_ci } 271c29fa5a6Sopenharmony_ci if (HasMtCoord()) { 272c29fa5a6Sopenharmony_ci CheckMt(); 273c29fa5a6Sopenharmony_ci } 274c29fa5a6Sopenharmony_ci CheckAdditional(); 275c29fa5a6Sopenharmony_ci PrintCapsDevice(); 276c29fa5a6Sopenharmony_ci} 277c29fa5a6Sopenharmony_ci 278c29fa5a6Sopenharmony_civoid Device::CheckAbs() 279c29fa5a6Sopenharmony_ci{ 280c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 281c29fa5a6Sopenharmony_ci if (HasKey(BTN_STYLUS) || HasKey(BTN_TOOL_PEN)) { 282c29fa5a6Sopenharmony_ci caps_.set(DEVICE_CAP_TABLET_TOOL); 283c29fa5a6Sopenharmony_ci } else if (HasKey(BTN_TOOL_FINGER) && !HasKey(BTN_TOOL_PEN) && !HasProperty(INPUT_PROP_DIRECT)) { 284c29fa5a6Sopenharmony_ci caps_.set(DEVICE_CAP_POINTER); 285c29fa5a6Sopenharmony_ci } else if (HasAxesOrButton(BTN_MOUSE, BTN_JOYSTICK, keyBitmask_)) { 286c29fa5a6Sopenharmony_ci caps_.set(DEVICE_CAP_POINTER); 287c29fa5a6Sopenharmony_ci } else if (HasKey(BTN_TOUCH) || HasProperty(INPUT_PROP_DIRECT)) { 288c29fa5a6Sopenharmony_ci caps_.set(DEVICE_CAP_TOUCH); 289c29fa5a6Sopenharmony_ci } else if (HasJoystickAxesOrButtons()) { 290c29fa5a6Sopenharmony_ci caps_.set(DEVICE_CAP_JOYSTICK); 291c29fa5a6Sopenharmony_ci } 292c29fa5a6Sopenharmony_ci} 293c29fa5a6Sopenharmony_ci 294c29fa5a6Sopenharmony_civoid Device::CheckJoystick() 295c29fa5a6Sopenharmony_ci{ 296c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 297c29fa5a6Sopenharmony_ci if (HasJoystickAxesOrButtons()) { 298c29fa5a6Sopenharmony_ci caps_.set(DEVICE_CAP_JOYSTICK); 299c29fa5a6Sopenharmony_ci } 300c29fa5a6Sopenharmony_ci} 301c29fa5a6Sopenharmony_ci 302c29fa5a6Sopenharmony_civoid Device::CheckMt() 303c29fa5a6Sopenharmony_ci{ 304c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 305c29fa5a6Sopenharmony_ci if (HasKey(BTN_STYLUS) || HasKey(BTN_TOOL_PEN)) { 306c29fa5a6Sopenharmony_ci caps_.set(DEVICE_CAP_TABLET_TOOL); 307c29fa5a6Sopenharmony_ci } else if (HasKey(BTN_TOOL_FINGER) && !HasKey(BTN_TOOL_PEN) && !HasProperty(INPUT_PROP_DIRECT)) { 308c29fa5a6Sopenharmony_ci caps_.set(DEVICE_CAP_POINTER); 309c29fa5a6Sopenharmony_ci } else if (HasKey(BTN_TOUCH) || HasProperty(INPUT_PROP_DIRECT)) { 310c29fa5a6Sopenharmony_ci caps_.set(DEVICE_CAP_TOUCH); 311c29fa5a6Sopenharmony_ci } 312c29fa5a6Sopenharmony_ci} 313c29fa5a6Sopenharmony_ci 314c29fa5a6Sopenharmony_civoid Device::CheckAdditional() 315c29fa5a6Sopenharmony_ci{ 316c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 317c29fa5a6Sopenharmony_ci if (!HasCapability(DEVICE_CAP_TABLET_TOOL) && 318c29fa5a6Sopenharmony_ci !HasCapability(DEVICE_CAP_POINTER) && 319c29fa5a6Sopenharmony_ci !HasCapability(DEVICE_CAP_JOYSTICK) && 320c29fa5a6Sopenharmony_ci HasAxesOrButton(BTN_MOUSE, BTN_JOYSTICK, keyBitmask_) && 321c29fa5a6Sopenharmony_ci (HasRelCoord() || !HasAbsCoord())) { 322c29fa5a6Sopenharmony_ci caps_.set(DEVICE_CAP_POINTER); 323c29fa5a6Sopenharmony_ci } 324c29fa5a6Sopenharmony_ci} 325c29fa5a6Sopenharmony_ci 326c29fa5a6Sopenharmony_civoid Device::CheckPencilMouse() 327c29fa5a6Sopenharmony_ci{ 328c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 329c29fa5a6Sopenharmony_ci if (name_ == "M-Pencil Mouse") { 330c29fa5a6Sopenharmony_ci caps_.set(DEVICE_CAP_POINTER, 0); 331c29fa5a6Sopenharmony_ci } 332c29fa5a6Sopenharmony_ci} 333c29fa5a6Sopenharmony_ci 334c29fa5a6Sopenharmony_civoid Device::CheckKeys() 335c29fa5a6Sopenharmony_ci{ 336c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 337c29fa5a6Sopenharmony_ci if (!TestBit(EV_KEY, evBitmask_)) { 338c29fa5a6Sopenharmony_ci FI_HILOGD("No EV_KEY capability"); 339c29fa5a6Sopenharmony_ci return; 340c29fa5a6Sopenharmony_ci } 341c29fa5a6Sopenharmony_ci size_t length = sizeof(KEY_BLOCKS) / sizeof(struct Range); 342c29fa5a6Sopenharmony_ci for (size_t block { 0U }; block < length; ++block) { 343c29fa5a6Sopenharmony_ci for (size_t key = KEY_BLOCKS[block].start; key < KEY_BLOCKS[block].end; ++key) { 344c29fa5a6Sopenharmony_ci if (TestBit(key, keyBitmask_)) { 345c29fa5a6Sopenharmony_ci FI_HILOGD("Found key:%{public}zx", key); 346c29fa5a6Sopenharmony_ci caps_.set(DEVICE_CAP_KEYBOARD); 347c29fa5a6Sopenharmony_ci return; 348c29fa5a6Sopenharmony_ci } 349c29fa5a6Sopenharmony_ci } 350c29fa5a6Sopenharmony_ci } 351c29fa5a6Sopenharmony_ci} 352c29fa5a6Sopenharmony_ci 353c29fa5a6Sopenharmony_cistd::string Device::MakeConfigFileName() const 354c29fa5a6Sopenharmony_ci{ 355c29fa5a6Sopenharmony_ci std::ostringstream ss; 356c29fa5a6Sopenharmony_ci ss << GetVendor() << "_" << GetProduct() << "_" << GetVersion() << "_" << GetName(); 357c29fa5a6Sopenharmony_ci std::string fname { ss.str() }; 358c29fa5a6Sopenharmony_ci Utility::RemoveSpace(fname); 359c29fa5a6Sopenharmony_ci 360c29fa5a6Sopenharmony_ci std::ostringstream sp; 361c29fa5a6Sopenharmony_ci sp << "/vendor/etc/keymap/" << fname << ".TOML"; 362c29fa5a6Sopenharmony_ci return sp.str(); 363c29fa5a6Sopenharmony_ci} 364c29fa5a6Sopenharmony_ci 365c29fa5a6Sopenharmony_ciint32_t Device::ReadConfigFile(const std::string &filePath) 366c29fa5a6Sopenharmony_ci{ 367c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 368c29fa5a6Sopenharmony_ci char realPath[PATH_MAX] = { 0 }; 369c29fa5a6Sopenharmony_ci if (realpath(filePath.c_str(), realPath) == nullptr) { 370c29fa5a6Sopenharmony_ci FI_HILOGE("Path is error, path is %{pubilc}s", filePath.c_str()); 371c29fa5a6Sopenharmony_ci return RET_ERR; 372c29fa5a6Sopenharmony_ci } 373c29fa5a6Sopenharmony_ci IfStreamWrap cfgFile; 374c29fa5a6Sopenharmony_ci cfgFile.ifStream = std::ifstream(filePath); 375c29fa5a6Sopenharmony_ci if (!cfgFile.IsOpen()) { 376c29fa5a6Sopenharmony_ci FI_HILOGE("Failed to open config file"); 377c29fa5a6Sopenharmony_ci return FILE_OPEN_FAIL; 378c29fa5a6Sopenharmony_ci } 379c29fa5a6Sopenharmony_ci std::string tmp; 380c29fa5a6Sopenharmony_ci while (std::getline(cfgFile.ifStream, tmp)) { 381c29fa5a6Sopenharmony_ci Utility::RemoveSpace(tmp); 382c29fa5a6Sopenharmony_ci size_t pos = tmp.find('#'); 383c29fa5a6Sopenharmony_ci if ((pos != tmp.npos) && (pos != COMMENT_SUBSCRIPT)) { 384c29fa5a6Sopenharmony_ci FI_HILOGE("File format is error"); 385c29fa5a6Sopenharmony_ci return RET_ERR; 386c29fa5a6Sopenharmony_ci } 387c29fa5a6Sopenharmony_ci if (tmp.empty() || (tmp.front() == '#')) { 388c29fa5a6Sopenharmony_ci continue; 389c29fa5a6Sopenharmony_ci } 390c29fa5a6Sopenharmony_ci pos = tmp.find('='); 391c29fa5a6Sopenharmony_ci if (tmp.size() == 0) { 392c29fa5a6Sopenharmony_ci FI_HILOGE("Invalid size, pos will overflow"); 393c29fa5a6Sopenharmony_ci return RET_ERR; 394c29fa5a6Sopenharmony_ci } else if ((pos == (tmp.size() - 1)) || (pos == tmp.npos)) { 395c29fa5a6Sopenharmony_ci FI_HILOGE("Find config item error"); 396c29fa5a6Sopenharmony_ci return RET_ERR; 397c29fa5a6Sopenharmony_ci } 398c29fa5a6Sopenharmony_ci std::string configItem = tmp.substr(0, pos); 399c29fa5a6Sopenharmony_ci std::string value = tmp.substr(pos + 1); 400c29fa5a6Sopenharmony_ci if (ConfigItemSwitch(configItem, value) == RET_ERR) { 401c29fa5a6Sopenharmony_ci FI_HILOGE("Configuration item error"); 402c29fa5a6Sopenharmony_ci return RET_ERR; 403c29fa5a6Sopenharmony_ci } 404c29fa5a6Sopenharmony_ci } 405c29fa5a6Sopenharmony_ci return RET_OK; 406c29fa5a6Sopenharmony_ci} 407c29fa5a6Sopenharmony_ci 408c29fa5a6Sopenharmony_ciint32_t Device::ConfigItemSwitch(const std::string &configItem, const std::string &value) 409c29fa5a6Sopenharmony_ci{ 410c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 411c29fa5a6Sopenharmony_ci const std::string CONFIG_ITEM_KEYBOARD_TYPE { "Key.keyboard.type" }; 412c29fa5a6Sopenharmony_ci if (configItem.empty() || value.empty() || !Utility::IsInteger(value)) { 413c29fa5a6Sopenharmony_ci FI_HILOGE("Invalid configuration encountered"); 414c29fa5a6Sopenharmony_ci return RET_ERR; 415c29fa5a6Sopenharmony_ci } 416c29fa5a6Sopenharmony_ci if (configItem == CONFIG_ITEM_KEYBOARD_TYPE) { 417c29fa5a6Sopenharmony_ci keyboardType_ = static_cast<IDevice::KeyboardType>(stoi(value)); 418c29fa5a6Sopenharmony_ci } 419c29fa5a6Sopenharmony_ci return RET_OK; 420c29fa5a6Sopenharmony_ci} 421c29fa5a6Sopenharmony_ci 422c29fa5a6Sopenharmony_ciint32_t Device::ReadTomlFile(const std::string &filePath) 423c29fa5a6Sopenharmony_ci{ 424c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 425c29fa5a6Sopenharmony_ci char temp[PATH_MAX] {}; 426c29fa5a6Sopenharmony_ci if (realpath(filePath.c_str(), temp) == nullptr) { 427c29fa5a6Sopenharmony_ci FI_HILOGE("Not real path (\'%{public}s\'):%{public}s", filePath.c_str(), strerror(errno)); 428c29fa5a6Sopenharmony_ci return RET_ERR; 429c29fa5a6Sopenharmony_ci } 430c29fa5a6Sopenharmony_ci FI_HILOGD("Config file path:%{private}s", temp); 431c29fa5a6Sopenharmony_ci 432c29fa5a6Sopenharmony_ci if (!Utility::DoesFileExist(temp)) { 433c29fa5a6Sopenharmony_ci FI_HILOGE("File does not exist:%{public}s", temp); 434c29fa5a6Sopenharmony_ci return RET_ERR; 435c29fa5a6Sopenharmony_ci } 436c29fa5a6Sopenharmony_ci if (Utility::GetFileSize(temp) > MAX_FILE_SIZE_ALLOWED) { 437c29fa5a6Sopenharmony_ci FI_HILOGE("File size is out of range"); 438c29fa5a6Sopenharmony_ci return RET_ERR; 439c29fa5a6Sopenharmony_ci } 440c29fa5a6Sopenharmony_ci if (ReadConfigFile(std::string(temp)) != RET_OK) { 441c29fa5a6Sopenharmony_ci FI_HILOGE("ReadConfigFile failed"); 442c29fa5a6Sopenharmony_ci return RET_ERR; 443c29fa5a6Sopenharmony_ci } 444c29fa5a6Sopenharmony_ci return RET_OK; 445c29fa5a6Sopenharmony_ci} 446c29fa5a6Sopenharmony_ci 447c29fa5a6Sopenharmony_civoid Device::JudgeKeyboardType() 448c29fa5a6Sopenharmony_ci{ 449c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 450c29fa5a6Sopenharmony_ci if (TestBit(KEY_Q, keyBitmask_)) { 451c29fa5a6Sopenharmony_ci keyboardType_ = IDevice::KEYBOARD_TYPE_ALPHABETICKEYBOARD; 452c29fa5a6Sopenharmony_ci FI_HILOGD("The keyboard type is standard"); 453c29fa5a6Sopenharmony_ci } else if (TestBit(KEY_HOME, keyBitmask_) && (GetBus() == BUS_BLUETOOTH)) { 454c29fa5a6Sopenharmony_ci keyboardType_ = IDevice::KEYBOARD_TYPE_REMOTECONTROL; 455c29fa5a6Sopenharmony_ci FI_HILOGD("The keyboard type is remote control"); 456c29fa5a6Sopenharmony_ci } else if (TestBit(KEY_KP1, keyBitmask_)) { 457c29fa5a6Sopenharmony_ci keyboardType_ = IDevice::KEYBOARD_TYPE_DIGITALKEYBOARD; 458c29fa5a6Sopenharmony_ci FI_HILOGD("The keyboard type is digital keyboard"); 459c29fa5a6Sopenharmony_ci } else if (TestBit(KEY_LEFTCTRL, keyBitmask_) && 460c29fa5a6Sopenharmony_ci TestBit(KEY_RIGHTCTRL, keyBitmask_) && 461c29fa5a6Sopenharmony_ci TestBit(KEY_F20, keyBitmask_)) { 462c29fa5a6Sopenharmony_ci keyboardType_ = IDevice::KEYBOARD_TYPE_HANDWRITINGPEN; 463c29fa5a6Sopenharmony_ci FI_HILOGD("The keyboard type is handwriting pen"); 464c29fa5a6Sopenharmony_ci } else { 465c29fa5a6Sopenharmony_ci keyboardType_ = IDevice::KEYBOARD_TYPE_UNKNOWN; 466c29fa5a6Sopenharmony_ci FI_HILOGD("Undefined keyboard type"); 467c29fa5a6Sopenharmony_ci } 468c29fa5a6Sopenharmony_ci} 469c29fa5a6Sopenharmony_ci 470c29fa5a6Sopenharmony_civoid Device::LoadDeviceConfig() 471c29fa5a6Sopenharmony_ci{ 472c29fa5a6Sopenharmony_ci CALL_DEBUG_ENTER; 473c29fa5a6Sopenharmony_ci if (ReadTomlFile(MakeConfigFileName()) != RET_OK) { 474c29fa5a6Sopenharmony_ci FI_HILOGE("ReadTomlFile failed"); 475c29fa5a6Sopenharmony_ci keyboardType_ = IDevice::KEYBOARD_TYPE_NONE; 476c29fa5a6Sopenharmony_ci } 477c29fa5a6Sopenharmony_ci if (IsKeyboard()) { 478c29fa5a6Sopenharmony_ci if ((keyboardType_ <= IDevice::KEYBOARD_TYPE_NONE) || 479c29fa5a6Sopenharmony_ci (keyboardType_ >= IDevice::KEYBOARD_TYPE_MAX)) { 480c29fa5a6Sopenharmony_ci JudgeKeyboardType(); 481c29fa5a6Sopenharmony_ci } 482c29fa5a6Sopenharmony_ci } else { 483c29fa5a6Sopenharmony_ci keyboardType_ = IDevice::KEYBOARD_TYPE_NONE; 484c29fa5a6Sopenharmony_ci } 485c29fa5a6Sopenharmony_ci FI_HILOGD("keyboard type:%{public}d", keyboardType_); 486c29fa5a6Sopenharmony_ci} 487c29fa5a6Sopenharmony_ci 488c29fa5a6Sopenharmony_ci} // namespace DeviceStatus 489c29fa5a6Sopenharmony_ci} // namespace Msdp 490c29fa5a6Sopenharmony_ci} // namespace OHOS 491