1 /*
2 * Copyright (c) 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 "key_auto_repeat.h"
17
18 #include <array>
19
20 #include "define_multimodal.h"
21 #include "error_multimodal.h"
22 #include "input_device_manager.h"
23 #include "input_event_handler.h"
24 #include "mmi_log.h"
25 #include "timer_manager.h"
26 #include "multimodal_input_preferences_manager.h"
27
28 namespace OHOS {
29 namespace MMI {
30 namespace {
31 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "KeyAutoRepeat" };
32 constexpr int32_t INVALID_DEVICE_ID = -1;
33 constexpr int32_t OPEN_AUTO_REPEAT = 1;
34 constexpr int32_t DEFAULT_KEY_REPEAT_DELAY = 500;
35 constexpr int32_t MIN_KEY_REPEAT_DELAY = 300;
36 constexpr int32_t MAX_KEY_REPEAT_DELAY = 1000;
37 constexpr int32_t DEFAULT_KEY_REPEAT_RATE = 50;
38 constexpr int32_t MIN_KEY_REPEAT_RATE = 36;
39 constexpr int32_t MAX_KEY_REPEAT_RATE = 100;
40 const std::string KEYBOARD_FILE_NAME = "keyboard_settings.xml";
41 } // namespace
42
KeyAutoRepeat()43 KeyAutoRepeat::KeyAutoRepeat() {}
~KeyAutoRepeat()44 KeyAutoRepeat::~KeyAutoRepeat() {}
45
GetDeviceConfig() const46 std::map<int32_t, DeviceConfig> KeyAutoRepeat::GetDeviceConfig() const
47 {
48 return deviceConfig_;
49 }
50
AddDeviceConfig(struct libinput_device * device)51 int32_t KeyAutoRepeat::AddDeviceConfig(struct libinput_device *device)
52 {
53 CALL_DEBUG_ENTER;
54 CHKPR(device, ERROR_NULL_POINTER);
55 std::string fileName = KeyMapMgr->GetKeyEventFileName(device);
56 DeviceConfig devConf;
57 auto ret = ReadTomlFile(GetTomlFilePath(fileName), devConf);
58 if (ret == RET_ERR) {
59 MMI_HILOGI("Can not read device config file");
60 return RET_ERR;
61 }
62 int32_t deviceId = InputDevMgr->FindInputDeviceId(device);
63 if (deviceId == INVALID_DEVICE_ID) {
64 MMI_HILOGE("Find to device failed");
65 return RET_ERR;
66 }
67 deviceConfig_[deviceId] = devConf;
68 return RET_OK;
69 }
70
SelectAutoRepeat(const std::shared_ptr<KeyEvent> & keyEvent)71 void KeyAutoRepeat::SelectAutoRepeat(const std::shared_ptr<KeyEvent>& keyEvent)
72 {
73 CALL_DEBUG_ENTER;
74 CHKPV(keyEvent);
75 DeviceConfig devConf = GetAutoSwitch(keyEvent->GetDeviceId());
76 if (devConf.autoSwitch != OPEN_AUTO_REPEAT) {
77 return;
78 }
79 keyEvent_ = keyEvent;
80 if (keyEvent_->GetKeyAction() == KeyEvent::KEY_ACTION_DOWN) {
81 if (TimerMgr->IsExist(timerId_)) {
82 MMI_HILOGI("Keyboard down but timer exists, timerId:%{public}d, keyCode:%{public}d",
83 timerId_, keyEvent_->GetKeyCode());
84 TimerMgr->RemoveTimer(timerId_);
85 timerId_ = -1;
86 }
87 int32_t delayTime = GetDelayTime();
88 AddHandleTimer(delayTime);
89 repeatKeyCode_ = keyEvent_->GetKeyCode();
90 MMI_HILOGI("Add a timer, keyCode:%{public}d", keyEvent_->GetKeyCode());
91 }
92 if (keyEvent_->GetKeyAction() == KeyEvent::KEY_ACTION_UP && TimerMgr->IsExist(timerId_)) {
93 TimerMgr->RemoveTimer(timerId_);
94 timerId_ = -1;
95 MMI_HILOGI("Stop keyboard autorepeat, keyCode:%{public}d", keyEvent_->GetKeyCode());
96 }
97 }
98
AddHandleTimer(int32_t timeout)99 void KeyAutoRepeat::AddHandleTimer(int32_t timeout)
100 {
101 CALL_DEBUG_ENTER;
102 timerId_ = TimerMgr->AddTimer(timeout, 1, [this]() {
103 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
104 auto inputEventNormalizeHandler = InputHandler->GetEventNormalizeHandler();
105 CHKPV(inputEventNormalizeHandler);
106 inputEventNormalizeHandler->HandleKeyEvent(this->keyEvent_);
107 this->keyEvent_->UpdateId();
108 #endif // OHOS_BUILD_ENABLE_KEYBOARD
109 int32_t triggertime = KeyRepeat->GetIntervalTime(keyEvent_->GetDeviceId());
110 this->AddHandleTimer(triggertime);
111 });
112 }
113
GetTomlFilePath(const std::string & fileName) const114 std::string KeyAutoRepeat::GetTomlFilePath(const std::string &fileName) const
115 {
116 return "/vendor/etc/keymap/" + fileName + ".TOML";
117 }
118
GetIntervalTime(int32_t deviceId)119 int32_t KeyAutoRepeat::GetIntervalTime(int32_t deviceId)
120 {
121 int32_t triggertime = DEFAULT_KEY_REPEAT_RATE;
122 GetKeyboardRepeatRate(triggertime);
123 return triggertime;
124 }
125
GetDelayTime()126 int32_t KeyAutoRepeat::GetDelayTime()
127 {
128 int32_t delaytime = DEFAULT_KEY_REPEAT_DELAY;
129 GetKeyboardRepeatDelay(delaytime);
130 return delaytime;
131 }
132
GetKeyboardRepeatTime(int32_t deviceId,bool isDelay)133 int32_t KeyAutoRepeat::GetKeyboardRepeatTime(int32_t deviceId, bool isDelay)
134 {
135 CALL_DEBUG_ENTER;
136 auto iter = deviceConfig_.find(deviceId);
137 int32_t repeatTime = isDelay ? DEFAULT_KEY_REPEAT_DELAY : DEFAULT_KEY_REPEAT_RATE;
138 if (iter != deviceConfig_.end()) {
139 repeatTime = isDelay ? iter->second.delayTime : iter->second.intervalTime;
140 }
141 return repeatTime;
142 }
143
GetAutoSwitch(int32_t deviceId)144 DeviceConfig KeyAutoRepeat::GetAutoSwitch(int32_t deviceId)
145 {
146 auto iter = deviceConfig_.find(deviceId);
147 if (iter == deviceConfig_.end()) {
148 return {};
149 }
150 MMI_HILOGD("Open autorepeat:%{public}d", iter->second.autoSwitch);
151 return iter->second;
152 }
153
RemoveDeviceConfig(struct libinput_device * device)154 void KeyAutoRepeat::RemoveDeviceConfig(struct libinput_device *device)
155 {
156 CALL_DEBUG_ENTER;
157 CHKPV(device);
158 int32_t deviceId = InputDevMgr->FindInputDeviceId(device);
159 auto iter = deviceConfig_.find(deviceId);
160 if (iter == deviceConfig_.end()) {
161 MMI_HILOGI("Can not remove device config file");
162 return;
163 }
164 deviceConfig_.erase(iter);
165 }
166
RemoveTimer()167 void KeyAutoRepeat::RemoveTimer()
168 {
169 CALL_DEBUG_ENTER;
170 TimerMgr->RemoveTimer(timerId_);
171 }
172
SetKeyboardRepeatDelay(int32_t delay)173 int32_t KeyAutoRepeat::SetKeyboardRepeatDelay(int32_t delay)
174 {
175 CALL_DEBUG_ENTER;
176 int32_t repeatDelayTime = delay;
177 if (delay < MIN_KEY_REPEAT_DELAY) {
178 repeatDelayTime = MIN_KEY_REPEAT_DELAY;
179 }
180 if (delay > MAX_KEY_REPEAT_DELAY) {
181 repeatDelayTime = MAX_KEY_REPEAT_DELAY;
182 }
183 std::string name = "keyboardRepeatDelay";
184 if (PutConfigDataToDatabase(name, repeatDelayTime) != RET_OK) {
185 MMI_HILOGE("Failed to set keyboard repeat delay.");
186 return RET_ERR;
187 }
188 MMI_HILOGD("Set keyboard repeat delay delay:%{public}d", repeatDelayTime);
189 return RET_OK;
190 }
191
SetKeyboardRepeatRate(int32_t rate)192 int32_t KeyAutoRepeat::SetKeyboardRepeatRate(int32_t rate)
193 {
194 CALL_DEBUG_ENTER;
195 int32_t repeatRateTime = rate;
196 if (rate < MIN_KEY_REPEAT_RATE) {
197 repeatRateTime = MIN_KEY_REPEAT_RATE;
198 }
199 if (rate > MAX_KEY_REPEAT_RATE) {
200 repeatRateTime = MAX_KEY_REPEAT_RATE;
201 }
202 std::string name = "keyboardRepeatRate";
203 if (PutConfigDataToDatabase(name, repeatRateTime) != RET_OK) {
204 MMI_HILOGE("Failed to set keyboard repeat rate.");
205 return RET_ERR;
206 }
207 MMI_HILOGD("Set keyboard repeat rate rate:%{public}d", repeatRateTime);
208 return RET_OK;
209 }
210
GetKeyboardRepeatDelay(int32_t & delay)211 int32_t KeyAutoRepeat::GetKeyboardRepeatDelay(int32_t &delay)
212 {
213 CALL_DEBUG_ENTER;
214 std::string name = "keyboardRepeatDelay";
215 if (GetConfigDataFromDatabase(name, delay) != RET_OK) {
216 MMI_HILOGE("Failed to get keyboard repeat delay.");
217 return RET_ERR;
218 }
219 if (delay == 0) {
220 delay = DEFAULT_KEY_REPEAT_DELAY;
221 if (keyEvent_ != nullptr) {
222 delay = GetKeyboardRepeatTime(keyEvent_->GetDeviceId(), true);
223 }
224 }
225 MMI_HILOGD("Get keyboard repeat delay delay:%{public}d", delay);
226 return RET_OK;
227 }
228
GetKeyboardRepeatRate(int32_t & rate)229 int32_t KeyAutoRepeat::GetKeyboardRepeatRate(int32_t &rate)
230 {
231 CALL_DEBUG_ENTER;
232 std::string name = "keyboardRepeatRate";
233 if (GetConfigDataFromDatabase(name, rate) != RET_OK) {
234 MMI_HILOGE("Failed to get keyboard repeat rate.");
235 return RET_ERR;
236 }
237 if (rate == 0) {
238 rate = DEFAULT_KEY_REPEAT_RATE;
239 if (keyEvent_ != nullptr) {
240 rate = GetKeyboardRepeatTime(keyEvent_->GetDeviceId(), false);
241 }
242 }
243 MMI_HILOGD("Get keyboard repeat rate rate:%{public}d", rate);
244 return RET_OK;
245 }
246
PutConfigDataToDatabase(std::string & key,int32_t value)247 int32_t KeyAutoRepeat::PutConfigDataToDatabase(std::string &key, int32_t value)
248 {
249 return PreferencesMgr->SetIntValue(key, KEYBOARD_FILE_NAME, value);
250 }
251
GetConfigDataFromDatabase(std::string & key,int32_t & value)252 int32_t KeyAutoRepeat::GetConfigDataFromDatabase(std::string &key, int32_t &value)
253 {
254 value = PreferencesMgr->GetIntValue(key, value);
255 return RET_OK;
256 }
257 } // namespace MMI
258 } // namespace OHOS