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 "event_log_helper.h"
23 #include "input_device_manager.h"
24 #include "input_event_handler.h"
25 #include "i_preference_manager.h"
26 #include "mmi_log.h"
27 #include "timer_manager.h"
28
29 #undef MMI_LOG_DOMAIN
30 #define MMI_LOG_DOMAIN MMI_LOG_HANDLER
31 #undef MMI_LOG_TAG
32 #define MMI_LOG_TAG "KeyAutoRepeat"
33
34 namespace OHOS {
35 namespace MMI {
36 namespace {
37 constexpr int32_t INVALID_DEVICE_ID { -1 };
38 constexpr int32_t OPEN_AUTO_REPEAT { 1 };
39 constexpr int32_t DEFAULT_KEY_REPEAT_DELAY { 500 };
40 constexpr int32_t MIN_KEY_REPEAT_DELAY { 300 };
41 constexpr int32_t MAX_KEY_REPEAT_DELAY { 1000 };
42 constexpr int32_t DEFAULT_KEY_REPEAT_RATE { 50 };
43 constexpr int32_t MIN_KEY_REPEAT_RATE { 36 };
44 constexpr int32_t MAX_KEY_REPEAT_RATE { 100 };
45 const std::string KEYBOARD_FILE_NAME { "keyboard_settings.xml" };
46 } // namespace
47
KeyAutoRepeat()48 KeyAutoRepeat::KeyAutoRepeat() {}
~KeyAutoRepeat()49 KeyAutoRepeat::~KeyAutoRepeat() {}
50
GetDeviceConfig() const51 std::map<int32_t, DeviceConfig> KeyAutoRepeat::GetDeviceConfig() const
52 {
53 return deviceConfig_;
54 }
55
AddDeviceConfig(struct libinput_device * device)56 int32_t KeyAutoRepeat::AddDeviceConfig(struct libinput_device *device)
57 {
58 CALL_DEBUG_ENTER;
59 CHKPR(device, ERROR_NULL_POINTER);
60 std::string fileName = KeyMapMgr->GetKeyEventFileName(device);
61 DeviceConfig devConf;
62 if (ReadTomlFile(GetTomlFilePath(fileName), devConf) != RET_OK) {
63 MMI_HILOGI("Can not read device config file");
64 return RET_ERR;
65 }
66 int32_t deviceId = INPUT_DEV_MGR->FindInputDeviceId(device);
67 if (deviceId == INVALID_DEVICE_ID) {
68 MMI_HILOGE("Find to device failed");
69 return RET_ERR;
70 }
71 deviceConfig_[deviceId] = devConf;
72 return RET_OK;
73 }
74
JudgeKeyEvent(const std::shared_ptr<KeyEvent> & keyEvent)75 bool KeyAutoRepeat::JudgeKeyEvent(const std::shared_ptr<KeyEvent>& keyEvent)
76 {
77 return (keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) || (keyEvent->GetKeyAction() ==
78 KeyEvent::KEY_ACTION_CANCEL);
79 }
80
JudgeLimitPrint(const std::shared_ptr<KeyEvent> & keyEvent)81 bool KeyAutoRepeat::JudgeLimitPrint(const std::shared_ptr<KeyEvent>& keyEvent)
82 {
83 return !EventLogHelper::IsBetaVersion() || keyEvent->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE);
84 }
85
SelectAutoRepeat(const std::shared_ptr<KeyEvent> & keyEvent)86 void KeyAutoRepeat::SelectAutoRepeat(const std::shared_ptr<KeyEvent>& keyEvent)
87 {
88 CALL_DEBUG_ENTER;
89 CHKPV(keyEvent);
90 DeviceConfig devConf = GetAutoSwitch(keyEvent->GetDeviceId());
91 MMI_HILOGD("AutoRepeatSwitch:%{public}d, keyEvent flag:%{public}x", devConf.autoSwitch, keyEvent->GetFlag());
92 if (devConf.autoSwitch != OPEN_AUTO_REPEAT && !keyEvent->HasFlag(InputEvent::EVENT_FLAG_SIMULATE)) {
93 MMI_HILOGI("AutoRepeatSwitch not open and is not simulate event");
94 return;
95 }
96 keyEvent_ = keyEvent;
97 if (keyEvent_->GetKeyAction() == KeyEvent::KEY_ACTION_DOWN) {
98 if (TimerMgr->IsExist(timerId_)) {
99 if (!EventLogHelper::IsBetaVersion()) {
100 MMI_HILOGI("Keyboard down but timer exists, timerId:%{public}d", timerId_);
101 } else {
102 if (keyEvent_->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) {
103 MMI_HILOGI("Keyboard down but timer exists, timerId:%{public}d, keyCode:%d",
104 timerId_, keyEvent_->GetKeyCode());
105 } else {
106 MMI_HILOGI("Keyboard down but timer exists, timerId:%{public}d, keyCode:%d",
107 timerId_, keyEvent_->GetKeyCode());
108 }
109 }
110 TimerMgr->RemoveTimer(timerId_);
111 timerId_ = -1;
112 }
113 int32_t delayTime = GetDelayTime();
114 AddHandleTimer(delayTime);
115 repeatKeyCode_ = keyEvent_->GetKeyCode();
116 }
117 if (JudgeKeyEvent(keyEvent_) && TimerMgr->IsExist(timerId_)) {
118 TimerMgr->RemoveTimer(timerId_);
119 if (!JudgeLimitPrint(keyEvent_)) {
120 MMI_HILOGI("Stop autorepeat, keyCode:%{private}d, repeatKeyCode:%{private}d, keyAction: %{public}d,"
121 "timeId:%{public}d",
122 keyEvent_->GetKeyCode(), repeatKeyCode_, keyEvent_->GetKeyAction(), timerId_);
123 } else {
124 MMI_HILOGI("Stop autorepeat, keyCode:%d, repeatKeyCode:%d, keyAction: %d, timeId:%d",
125 keyEvent_->GetKeyCode(), repeatKeyCode_, keyEvent_->GetKeyAction(), timerId_);
126 }
127 timerId_ = -1;
128 if (keyEvent_->GetKeyAction() == KeyEvent::KEY_ACTION_UP && repeatKeyCode_ != keyEvent_->GetKeyCode()) {
129 std::optional<KeyEvent::KeyItem> pressedKeyItem = keyEvent_->GetKeyItem(keyEvent_->GetKeyCode());
130 if (pressedKeyItem) {
131 keyEvent_->RemoveReleasedKeyItems(*pressedKeyItem);
132 } else {
133 MMI_HILOGW("The pressedKeyItem is nullopt");
134 }
135 pressedKeyItem = keyEvent_->GetKeyItem(repeatKeyCode_);
136 if (!pressedKeyItem) {
137 return;
138 }
139 keyEvent_->SetKeyCode(repeatKeyCode_);
140 keyEvent_->SetAction(KeyEvent::KEY_ACTION_DOWN);
141 keyEvent_->SetKeyAction(KeyEvent::KEY_ACTION_DOWN);
142 int32_t delayTime = GetDelayTime();
143 AddHandleTimer(delayTime);
144 if (!JudgeLimitPrint(keyEvent_)) {
145 MMI_HILOGD("The end keyboard autorepeat, keyCode:%{private}d", keyEvent_->GetKeyCode());
146 } else {
147 MMI_HILOGD("The end keyboard autorepeat, keyCode:%d", keyEvent_->GetKeyCode());
148 }
149 }
150 }
151 }
152
AddHandleTimer(int32_t timeout)153 void KeyAutoRepeat::AddHandleTimer(int32_t timeout)
154 {
155 CALL_DEBUG_ENTER;
156 timerId_ = TimerMgr->AddTimer(timeout, 1, [this]() {
157 timerId_ = -1;
158 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
159 auto inputEventNormalizeHandler = InputHandler->GetEventNormalizeHandler();
160 CHKPV(inputEventNormalizeHandler);
161 LogTracer lt(this->keyEvent_->GetId(), this->keyEvent_->GetEventType(), this->keyEvent_->GetKeyAction());
162 inputEventNormalizeHandler->HandleKeyEvent(this->keyEvent_);
163 this->keyEvent_->UpdateId();
164 #endif // OHOS_BUILD_ENABLE_KEYBOARD
165 int32_t triggertime = KeyRepeat->GetIntervalTime(keyEvent_->GetDeviceId());
166 this->AddHandleTimer(triggertime);
167 });
168 }
169
GetTomlFilePath(const std::string & fileName) const170 std::string KeyAutoRepeat::GetTomlFilePath(const std::string &fileName) const
171 {
172 return "/vendor/etc/keymap/" + fileName + ".TOML";
173 }
174
GetIntervalTime(int32_t deviceId)175 int32_t KeyAutoRepeat::GetIntervalTime(int32_t deviceId)
176 {
177 int32_t triggertime = DEFAULT_KEY_REPEAT_RATE;
178 GetKeyboardRepeatRate(triggertime);
179 return triggertime;
180 }
181
GetDelayTime()182 int32_t KeyAutoRepeat::GetDelayTime()
183 {
184 int32_t delaytime = DEFAULT_KEY_REPEAT_DELAY;
185 GetKeyboardRepeatDelay(delaytime);
186 return delaytime;
187 }
188
GetKeyboardRepeatTime(int32_t deviceId,bool isDelay)189 int32_t KeyAutoRepeat::GetKeyboardRepeatTime(int32_t deviceId, bool isDelay)
190 {
191 CALL_DEBUG_ENTER;
192 auto iter = deviceConfig_.find(deviceId);
193 int32_t repeatTime = isDelay ? DEFAULT_KEY_REPEAT_DELAY : DEFAULT_KEY_REPEAT_RATE;
194 if (iter != deviceConfig_.end()) {
195 repeatTime = isDelay ? iter->second.delayTime : iter->second.intervalTime;
196 }
197 return repeatTime;
198 }
199
GetAutoSwitch(int32_t deviceId)200 DeviceConfig KeyAutoRepeat::GetAutoSwitch(int32_t deviceId)
201 {
202 auto iter = deviceConfig_.find(deviceId);
203 if (iter == deviceConfig_.end()) {
204 return {};
205 }
206 MMI_HILOGD("Open autorepeat:%{public}d", iter->second.autoSwitch);
207 return iter->second;
208 }
209
RemoveDeviceConfig(struct libinput_device * device)210 void KeyAutoRepeat::RemoveDeviceConfig(struct libinput_device *device)
211 {
212 CALL_DEBUG_ENTER;
213 CHKPV(device);
214 int32_t deviceId = INPUT_DEV_MGR->FindInputDeviceId(device);
215 auto iter = deviceConfig_.find(deviceId);
216 if (iter == deviceConfig_.end()) {
217 MMI_HILOGI("Can not remove device config file");
218 return;
219 }
220 deviceConfig_.erase(iter);
221 }
222
RemoveTimer()223 void KeyAutoRepeat::RemoveTimer()
224 {
225 CALL_DEBUG_ENTER;
226 TimerMgr->RemoveTimer(timerId_);
227 timerId_ = -1;
228 }
229
SetKeyboardRepeatDelay(int32_t delay)230 int32_t KeyAutoRepeat::SetKeyboardRepeatDelay(int32_t delay)
231 {
232 CALL_DEBUG_ENTER;
233 int32_t repeatDelayTime = delay;
234 if (delay < MIN_KEY_REPEAT_DELAY) {
235 repeatDelayTime = MIN_KEY_REPEAT_DELAY;
236 }
237 if (delay > MAX_KEY_REPEAT_DELAY) {
238 repeatDelayTime = MAX_KEY_REPEAT_DELAY;
239 }
240 std::string name = "keyboardRepeatDelay";
241 if (PutConfigDataToDatabase(name, repeatDelayTime) != RET_OK) {
242 MMI_HILOGE("Failed to set keyboard repeat delay");
243 return RET_ERR;
244 }
245 MMI_HILOGD("Set keyboard repeat delay:%{public}d", repeatDelayTime);
246 return RET_OK;
247 }
248
SetKeyboardRepeatRate(int32_t rate)249 int32_t KeyAutoRepeat::SetKeyboardRepeatRate(int32_t rate)
250 {
251 CALL_DEBUG_ENTER;
252 int32_t repeatRateTime = rate;
253 if (rate < MIN_KEY_REPEAT_RATE) {
254 repeatRateTime = MIN_KEY_REPEAT_RATE;
255 }
256 if (rate > MAX_KEY_REPEAT_RATE) {
257 repeatRateTime = MAX_KEY_REPEAT_RATE;
258 }
259 std::string name = "keyboardRepeatRate";
260 if (PutConfigDataToDatabase(name, repeatRateTime) != RET_OK) {
261 MMI_HILOGE("Failed to set keyboard repeat rate");
262 return RET_ERR;
263 }
264 MMI_HILOGD("Successfully set keyboard repeat for rate:%{public}d", repeatRateTime);
265 return RET_OK;
266 }
267
GetKeyboardRepeatDelay(int32_t & delay)268 int32_t KeyAutoRepeat::GetKeyboardRepeatDelay(int32_t &delay)
269 {
270 CALL_DEBUG_ENTER;
271 std::string name = "keyboardRepeatDelay";
272 if (GetConfigDataFromDatabase(name, delay) != RET_OK) {
273 MMI_HILOGE("Failed to get keyboard repeat delay");
274 return RET_ERR;
275 }
276 if (delay == 0) {
277 delay = DEFAULT_KEY_REPEAT_DELAY;
278 if (keyEvent_ != nullptr) {
279 delay = GetKeyboardRepeatTime(keyEvent_->GetDeviceId(), true);
280 }
281 }
282 MMI_HILOGD("Get keyboard repeat delay:%{public}d", delay);
283 return RET_OK;
284 }
285
GetKeyboardRepeatRate(int32_t & rate)286 int32_t KeyAutoRepeat::GetKeyboardRepeatRate(int32_t &rate)
287 {
288 CALL_DEBUG_ENTER;
289 std::string name = "keyboardRepeatRate";
290 if (GetConfigDataFromDatabase(name, rate) != RET_OK) {
291 MMI_HILOGE("Failed to get keyboard repeat rate");
292 return RET_ERR;
293 }
294 if (rate == 0) {
295 rate = DEFAULT_KEY_REPEAT_RATE;
296 if (keyEvent_ != nullptr) {
297 rate = GetKeyboardRepeatTime(keyEvent_->GetDeviceId(), false);
298 }
299 }
300 MMI_HILOGD("Get keyboard repeat rate:%{public}d", rate);
301 return RET_OK;
302 }
303
PutConfigDataToDatabase(std::string & key,int32_t value)304 int32_t KeyAutoRepeat::PutConfigDataToDatabase(std::string &key, int32_t value)
305 {
306 return PREFERENCES_MGR->SetIntValue(key, KEYBOARD_FILE_NAME, value);
307 }
308
GetConfigDataFromDatabase(std::string & key,int32_t & value)309 int32_t KeyAutoRepeat::GetConfigDataFromDatabase(std::string &key, int32_t &value)
310 {
311 value = PREFERENCES_MGR->GetIntValue(key, value);
312 return RET_OK;
313 }
314 } // namespace MMI
315 } // namespace OHOS