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