1 /*
2 * Copyright (c) 2022-2024 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 "device_config_file_parser.h"
17
18 #include <fstream>
19 #include <regex>
20
21 #include "error_multimodal.h"
22 #include "input_device.h"
23 #include "libinput.h"
24 #include "util.h"
25
26 #undef MMI_LOG_DOMAIN
27 #define MMI_LOG_DOMAIN MMI_LOG_SERVER
28 #undef MMI_LOG_TAG
29 #define MMI_LOG_TAG "DeviceConfigManagement"
30
31 namespace OHOS {
32 namespace MMI {
33 namespace {
34 constexpr int32_t COMMENT_SUBSCRIPT { 0 };
35 } // namespace
36
37 enum evdev_device_udev_tags {
38 EVDEV_UDEV_TAG_INPUT = 1 << 0,
39 EVDEV_UDEV_TAG_KEYBOARD = 1 << 1,
40 EVDEV_UDEV_TAG_MOUSE = 1 << 2,
41 EVDEV_UDEV_TAG_TOUCHPAD = 1 << 3,
42 EVDEV_UDEV_TAG_TOUCHSCREEN = 1 << 4,
43 EVDEV_UDEV_TAG_TABLET = 1 << 5,
44 EVDEV_UDEV_TAG_JOYSTICK = 1 << 6,
45 EVDEV_UDEV_TAG_ACCELEROMETER = 1 << 7,
46 EVDEV_UDEV_TAG_TABLET_PAD = 1 << 8,
47 EVDEV_UDEV_TAG_POINTINGSTICK = 1 << 9,
48 EVDEV_UDEV_TAG_TRACKBALL = 1 << 10,
49 EVDEV_UDEV_TAG_SWITCH = 1 << 11,
50 };
51
CombDeviceFileName(struct libinput_device * device) const52 std::string DeviceConfigManagement::CombDeviceFileName(struct libinput_device *device) const
53 {
54 CALL_DEBUG_ENTER;
55 CHKPS(device);
56 uint32_t vendor = libinput_device_get_id_vendor(device);
57 uint32_t product = libinput_device_get_id_product(device);
58 uint32_t version = libinput_device_get_id_version(device);
59 const char *name = libinput_device_get_name(device);
60 CHKPS(name);
61 std::string fileName =
62 std::to_string(vendor) + "_" + std::to_string(product) + "_" + std::to_string(version) + "_" + name;
63 RemoveSpace(fileName);
64 return fileName;
65 }
66
ConfigItemName2Id(const std::string & name) const67 ConfigFileItem DeviceConfigManagement::ConfigItemName2Id(const std::string &name) const
68 {
69 static const std::map<const std::string, ConfigFileItem> configList = {
70 { "speed", ConfigFileItem::POINTER_SPEED },
71 };
72
73 auto iter = configList.find(name);
74 if (iter == configList.end()) {
75 MMI_HILOGE("Device name failed");
76 return ConfigFileItem::INVALID;
77 }
78 return configList.at(name);
79 }
80
ReadConfigFile(const std::string & filePath) const81 std::map<ConfigFileItem, int32_t> DeviceConfigManagement::ReadConfigFile(const std::string &filePath) const
82 {
83 std::map<ConfigFileItem, int32_t> configList;
84 std::ifstream cfgFile(filePath);
85 if (!cfgFile.is_open()) {
86 MMI_HILOGE("Failed to open config file");
87 return configList;
88 }
89 std::string tmp;
90
91 while (std::getline(cfgFile, tmp)) {
92 RemoveSpace(tmp);
93 size_t pos = tmp.find('#');
94 if (pos != tmp.npos && pos != COMMENT_SUBSCRIPT) {
95 continue;
96 }
97 if (tmp.empty() || tmp.front() == '#') {
98 continue;
99 }
100 pos = tmp.find('=');
101 if ((pos == std::string::npos) || (tmp.back() == '=')) {
102 continue;
103 }
104 std::string key = tmp.substr(0, pos);
105
106 std::smatch match;
107 bool isNumber = std::regex_search(tmp, match, std::regex("\\d+"));
108 if (!isNumber) {
109 continue;
110 }
111 configList[ConfigItemName2Id(key)] = std::stoi(match[0]);
112 }
113 cfgFile.close();
114 return configList;
115 }
116
GetVendorConfig(struct libinput_device * device) const117 VendorConfig DeviceConfigManagement::GetVendorConfig(struct libinput_device *device) const
118 {
119 CALL_DEBUG_ENTER;
120 CHKPO(device);
121 std::string filePath = "/vendor/etc/pointer/" + CombDeviceFileName(device) + ".TOML";
122 VendorConfig vendorConfigTmp = {};
123 auto path = FileVerification(filePath, "TOML");
124 if (path.empty()) {
125 MMI_HILOGE("File validation failed");
126 return vendorConfigTmp;
127 }
128 auto configList = ReadConfigFile(path);
129 if (configList.empty()) {
130 MMI_HILOGE("configList is empty");
131 return vendorConfigTmp;
132 }
133 if (configList.find(ConfigFileItem::POINTER_SPEED) == configList.end()) {
134 MMI_HILOGE("configList not find POINTER_SPEED");
135 return vendorConfigTmp;
136 }
137 vendorConfigTmp.pointerSpeed = configList[ConfigFileItem::POINTER_SPEED];
138 return vendorConfigTmp;
139 }
140 } // namespace MMI
141 } // namespace OHOS