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 "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:%{private}d",
107                         timerId_, keyEvent_->GetKeyCode());
108                 }
109             }
110             TimerMgr->RemoveTimer(timerId_);
111             keyEvent_->SetRepeatKey(false);
112             timerId_ = -1;
113             repeatKeyCode_ = -1;
114         }
115         int32_t delayTime = GetDelayTime();
116         keyEvent_->SetRepeatKey(true);
117         AddHandleTimer(delayTime);
118         repeatKeyCode_ = keyEvent_->GetKeyCode();
119     }
120     if (JudgeKeyEvent(keyEvent_) && TimerMgr->IsExist(timerId_)) {
121         TimerMgr->RemoveTimer(timerId_);
122         keyEvent_->SetRepeatKey(false);
123         timerId_ = -1;
124         if (!JudgeLimitPrint(keyEvent_)) {
125             MMI_HILOGI("Stop autorepeat, keyCode:%{private}d, repeatKeyCode:%{private}d, keyAction:%{public}d",
126                 keyEvent_->GetKeyCode(), repeatKeyCode_, keyEvent_->GetKeyAction());
127         } else {
128             MMI_HILOGI("Stop autorepeat, keyCode:%d, repeatKeyCode:%d, keyAction: %d",
129                 keyEvent_->GetKeyCode(), repeatKeyCode_, keyEvent_->GetKeyAction());
130         }
131         if (keyEvent_->GetKeyAction() == KeyEvent::KEY_ACTION_UP && repeatKeyCode_ != keyEvent_->GetKeyCode()) {
132             std::optional<KeyEvent::KeyItem> pressedKeyItem = keyEvent_->GetKeyItem(keyEvent_->GetKeyCode());
133             if (pressedKeyItem) {
134                 keyEvent_->RemoveReleasedKeyItems(*pressedKeyItem);
135             } else {
136                 MMI_HILOGW("The pressedKeyItem is nullopt");
137             }
138             pressedKeyItem = keyEvent_->GetKeyItem(repeatKeyCode_);
139             if (!pressedKeyItem) {
140                 return;
141             }
142             keyEvent_->SetKeyCode(repeatKeyCode_);
143             keyEvent_->SetAction(KeyEvent::KEY_ACTION_DOWN);
144             keyEvent_->SetKeyAction(KeyEvent::KEY_ACTION_DOWN);
145             int32_t delayTime = GetDelayTime();
146             keyEvent_->SetRepeatKey(true);
147             AddHandleTimer(delayTime);
148             if (!JudgeLimitPrint(keyEvent_)) {
149                 MMI_HILOGD("The end keyboard autorepeat, keyCode:%{private}d", keyEvent_->GetKeyCode());
150             } else {
151                 MMI_HILOGD("The end keyboard autorepeat, keyCode:%d", keyEvent_->GetKeyCode());
152             }
153         } else {
154             repeatKeyCode_ = -1;
155         }
156     }
157 }
158 
AddHandleTimer(int32_t timeout)159 void KeyAutoRepeat::AddHandleTimer(int32_t timeout)
160 {
161     CALL_DEBUG_ENTER;
162     timerId_ = TimerMgr->AddTimer(timeout, 1, [this]() {
163 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
164         auto inputEventNormalizeHandler = InputHandler->GetEventNormalizeHandler();
165         CHKPV(inputEventNormalizeHandler);
166         LogTracer lt(this->keyEvent_->GetId(), this->keyEvent_->GetEventType(), this->keyEvent_->GetKeyAction());
167         inputEventNormalizeHandler->HandleKeyEvent(this->keyEvent_);
168         this->keyEvent_->UpdateId();
169 #endif // OHOS_BUILD_ENABLE_KEYBOARD
170         int32_t triggertime = KeyRepeat->GetIntervalTime(keyEvent_->GetDeviceId());
171         this->AddHandleTimer(triggertime);
172     });
173 }
174 
GetTomlFilePath(const std::string &fileName) const175 std::string KeyAutoRepeat::GetTomlFilePath(const std::string &fileName) const
176 {
177     return "/vendor/etc/keymap/" + fileName + ".TOML";
178 }
179 
GetIntervalTime(int32_t deviceId)180 int32_t KeyAutoRepeat::GetIntervalTime(int32_t deviceId)
181 {
182     int32_t triggertime = DEFAULT_KEY_REPEAT_RATE;
183     GetKeyboardRepeatRate(triggertime);
184     return triggertime;
185 }
186 
GetDelayTime()187 int32_t KeyAutoRepeat::GetDelayTime()
188 {
189     int32_t delaytime = DEFAULT_KEY_REPEAT_DELAY;
190     GetKeyboardRepeatDelay(delaytime);
191     return delaytime;
192 }
193 
GetKeyboardRepeatTime(int32_t deviceId, bool isDelay)194 int32_t KeyAutoRepeat::GetKeyboardRepeatTime(int32_t deviceId, bool isDelay)
195 {
196     CALL_DEBUG_ENTER;
197     auto iter = deviceConfig_.find(deviceId);
198     int32_t repeatTime = isDelay ? DEFAULT_KEY_REPEAT_DELAY : DEFAULT_KEY_REPEAT_RATE;
199     if (iter != deviceConfig_.end()) {
200         repeatTime = isDelay ? iter->second.delayTime : iter->second.intervalTime;
201     }
202     return repeatTime;
203 }
204 
GetAutoSwitch(int32_t deviceId)205 DeviceConfig KeyAutoRepeat::GetAutoSwitch(int32_t deviceId)
206 {
207     auto iter = deviceConfig_.find(deviceId);
208     if (iter == deviceConfig_.end()) {
209         return {};
210     }
211     MMI_HILOGD("Open autorepeat:%{public}d", iter->second.autoSwitch);
212     return iter->second;
213 }
214 
RemoveDeviceConfig(struct libinput_device *device)215 void KeyAutoRepeat::RemoveDeviceConfig(struct libinput_device *device)
216 {
217     CALL_DEBUG_ENTER;
218     CHKPV(device);
219     int32_t deviceId = INPUT_DEV_MGR->FindInputDeviceId(device);
220     auto iter = deviceConfig_.find(deviceId);
221     if (iter == deviceConfig_.end()) {
222         MMI_HILOGI("Can not remove device config file");
223         return;
224     }
225     deviceConfig_.erase(iter);
226 }
227 
RemoveTimer()228 void KeyAutoRepeat::RemoveTimer()
229 {
230     CALL_DEBUG_ENTER;
231     TimerMgr->RemoveTimer(timerId_);
232 }
233 
SetKeyboardRepeatDelay(int32_t delay)234 int32_t KeyAutoRepeat::SetKeyboardRepeatDelay(int32_t delay)
235 {
236     CALL_DEBUG_ENTER;
237     int32_t repeatDelayTime = delay;
238     if (delay < MIN_KEY_REPEAT_DELAY) {
239         repeatDelayTime = MIN_KEY_REPEAT_DELAY;
240     }
241     if (delay > MAX_KEY_REPEAT_DELAY) {
242         repeatDelayTime = MAX_KEY_REPEAT_DELAY;
243     }
244     std::string name = "keyboardRepeatDelay";
245     if (PutConfigDataToDatabase(name, repeatDelayTime) != RET_OK) {
246         MMI_HILOGE("Failed to set keyboard repeat delay");
247         return RET_ERR;
248     }
249     MMI_HILOGD("Set keyboard repeat delay:%{public}d", repeatDelayTime);
250     return RET_OK;
251 }
252 
SetKeyboardRepeatRate(int32_t rate)253 int32_t KeyAutoRepeat::SetKeyboardRepeatRate(int32_t rate)
254 {
255     CALL_DEBUG_ENTER;
256     int32_t repeatRateTime = rate;
257     if (rate < MIN_KEY_REPEAT_RATE) {
258         repeatRateTime = MIN_KEY_REPEAT_RATE;
259     }
260     if (rate > MAX_KEY_REPEAT_RATE) {
261         repeatRateTime = MAX_KEY_REPEAT_RATE;
262     }
263     std::string name = "keyboardRepeatRate";
264     if (PutConfigDataToDatabase(name, repeatRateTime) != RET_OK) {
265         MMI_HILOGE("Failed to set keyboard repeat rate");
266         return RET_ERR;
267     }
268     MMI_HILOGD("Successfully set keyboard repeat for rate:%{public}d", repeatRateTime);
269     return RET_OK;
270 }
271 
GetKeyboardRepeatDelay(int32_t &delay)272 int32_t KeyAutoRepeat::GetKeyboardRepeatDelay(int32_t &delay)
273 {
274     CALL_DEBUG_ENTER;
275     std::string name = "keyboardRepeatDelay";
276     if (GetConfigDataFromDatabase(name, delay) != RET_OK) {
277         MMI_HILOGE("Failed to get keyboard repeat delay");
278         return RET_ERR;
279     }
280     if (delay == 0) {
281         delay = DEFAULT_KEY_REPEAT_DELAY;
282         if (keyEvent_ != nullptr) {
283             delay = GetKeyboardRepeatTime(keyEvent_->GetDeviceId(), true);
284         }
285     }
286     MMI_HILOGD("Get keyboard repeat delay:%{public}d", delay);
287     return RET_OK;
288 }
289 
GetKeyboardRepeatRate(int32_t &rate)290 int32_t KeyAutoRepeat::GetKeyboardRepeatRate(int32_t &rate)
291 {
292     CALL_DEBUG_ENTER;
293     std::string name = "keyboardRepeatRate";
294     if (GetConfigDataFromDatabase(name, rate) != RET_OK) {
295         MMI_HILOGE("Failed to get keyboard repeat rate");
296         return RET_ERR;
297     }
298     if (rate == 0) {
299         rate = DEFAULT_KEY_REPEAT_RATE;
300         if (keyEvent_ != nullptr) {
301             rate = GetKeyboardRepeatTime(keyEvent_->GetDeviceId(), false);
302         }
303     }
304     MMI_HILOGD("Get keyboard repeat rate:%{public}d", rate);
305     return RET_OK;
306 }
307 
GetRepeatKeyCode() const308 int32_t KeyAutoRepeat::GetRepeatKeyCode() const
309 {
310     return repeatKeyCode_;
311 }
312 
PutConfigDataToDatabase(std::string &key, int32_t value)313 int32_t KeyAutoRepeat::PutConfigDataToDatabase(std::string &key, int32_t value)
314 {
315     return PREFERENCES_MGR->SetIntValue(key, KEYBOARD_FILE_NAME, value);
316 }
317 
GetConfigDataFromDatabase(std::string &key, int32_t &value)318 int32_t KeyAutoRepeat::GetConfigDataFromDatabase(std::string &key, int32_t &value)
319 {
320     value = PREFERENCES_MGR->GetIntValue(key, value);
321     return RET_OK;
322 }
323 } // namespace MMI
324 } // namespace OHOS