• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
27 namespace OHOS {
28 namespace MMI {
29 namespace {
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "KeyAutoRepeat" };
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 std::string KEYBOARD_FILE_NAME = "/data/service/el1/public/multimodalinput/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     auto ret = ReadTomlFile(GetTomlFilePath(fileName), devConf);
57     if (ret == RET_ERR) {
58         MMI_HILOGI("Can not read device config file");
59         return RET_ERR;
60     }
61     int32_t deviceId = InputDevMgr->FindInputDeviceId(device);
62     if (deviceId == INVALID_DEVICE_ID) {
63         MMI_HILOGE("Find to device failed");
64         return RET_ERR;
65     }
66     deviceConfig_[deviceId] = devConf;
67     return RET_OK;
68 }
69 
SelectAutoRepeat(std::shared_ptr<KeyEvent> & keyEvent)70 void KeyAutoRepeat::SelectAutoRepeat(std::shared_ptr<KeyEvent>& keyEvent)
71 {
72     CALL_DEBUG_ENTER;
73     CHKPV(keyEvent);
74     DeviceConfig devConf = GetAutoSwitch(keyEvent->GetDeviceId());
75     if (devConf.autoSwitch != OPEN_AUTO_REPEAT) {
76         return;
77     }
78     keyEvent_ = keyEvent;
79     if (keyEvent_->GetKeyAction() == KeyEvent::KEY_ACTION_DOWN) {
80         if (TimerMgr->IsExist(timerId_)) {
81             MMI_HILOGI("Keyboard down but timer exists, timerId:%{public}d, keyCode:%{public}d",
82                 timerId_, keyEvent_->GetKeyCode());
83             TimerMgr->RemoveTimer(timerId_);
84             timerId_ = -1;
85         }
86         int32_t delayTime = GetDelayTime();
87         AddHandleTimer(delayTime);
88         repeatKeyCode_ = keyEvent_->GetKeyCode();
89         MMI_HILOGI("Add a timer, keyCode:%{public}d", keyEvent_->GetKeyCode());
90     }
91     if (keyEvent_->GetKeyAction() == KeyEvent::KEY_ACTION_UP && TimerMgr->IsExist(timerId_)) {
92         TimerMgr->RemoveTimer(timerId_);
93         timerId_ = -1;
94         MMI_HILOGI("Stop keyboard autorepeat, keyCode:%{public}d", keyEvent_->GetKeyCode());
95         if (repeatKeyCode_ != keyEvent_->GetKeyCode()) {
96             std::optional<KeyEvent::KeyItem> pressedKeyItem = keyEvent_->GetKeyItem(keyEvent_->GetKeyCode());
97             if (pressedKeyItem) {
98                 keyEvent_->RemoveReleasedKeyItems(*pressedKeyItem);
99             } else {
100                 MMI_HILOGW("The pressedKeyItem is nullopt");
101             }
102             keyEvent_->SetKeyCode(repeatKeyCode_);
103             keyEvent_->SetAction(KeyEvent::KEY_ACTION_DOWN);
104             keyEvent_->SetKeyAction(KeyEvent::KEY_ACTION_DOWN);
105             int32_t delayTime = GetDelayTime();
106             AddHandleTimer(delayTime);
107             MMI_HILOGD("The end keyboard autorepeat, keyCode:%{public}d", keyEvent_->GetKeyCode());
108         }
109     }
110 }
111 
AddHandleTimer(int32_t timeout)112 void KeyAutoRepeat::AddHandleTimer(int32_t timeout)
113 {
114     CALL_DEBUG_ENTER;
115     timerId_ = TimerMgr->AddTimer(timeout, 1, [this]() {
116 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
117         auto inputEventNormalizeHandler = InputHandler->GetEventNormalizeHandler();
118         CHKPV(inputEventNormalizeHandler);
119         this->keyEvent_->UpdateId();
120         inputEventNormalizeHandler->HandleKeyEvent(this->keyEvent_);
121 #endif // OHOS_BUILD_ENABLE_KEYBOARD
122         int32_t triggertime = KeyRepeat->GetIntervalTime(keyEvent_->GetDeviceId());
123         this->AddHandleTimer(triggertime);
124     });
125 }
126 
GetTomlFilePath(const std::string & fileName) const127 std::string KeyAutoRepeat::GetTomlFilePath(const std::string &fileName) const
128 {
129     return "/vendor/etc/keymap/" + fileName + ".TOML";
130 }
131 
GetIntervalTime(int32_t deviceId)132 int32_t KeyAutoRepeat::GetIntervalTime(int32_t deviceId)
133 {
134     int32_t triggertime = DEFAULT_KEY_REPEAT_RATE;
135     GetKeyboardRepeatRate(triggertime);
136     return triggertime;
137 }
138 
GetDelayTime()139 int32_t KeyAutoRepeat::GetDelayTime()
140 {
141     int32_t delaytime = DEFAULT_KEY_REPEAT_DELAY;
142     GetKeyboardRepeatDelay(delaytime);
143     return delaytime;
144 }
145 
GetKeyboardRepeatTime(int32_t deviceId,bool isDelay)146 int32_t KeyAutoRepeat::GetKeyboardRepeatTime(int32_t deviceId, bool isDelay)
147 {
148     CALL_DEBUG_ENTER;
149     auto iter = deviceConfig_.find(deviceId);
150     int32_t repeatTime = isDelay ? DEFAULT_KEY_REPEAT_DELAY : DEFAULT_KEY_REPEAT_RATE;
151     if (iter != deviceConfig_.end()) {
152         repeatTime = isDelay ? iter->second.delayTime : iter->second.intervalTime;
153     }
154     return repeatTime;
155 }
156 
GetAutoSwitch(int32_t deviceId)157 DeviceConfig KeyAutoRepeat::GetAutoSwitch(int32_t deviceId)
158 {
159     auto iter = deviceConfig_.find(deviceId);
160     if (iter == deviceConfig_.end()) {
161         return {};
162     }
163     MMI_HILOGD("Open autorepeat:%{public}d", iter->second.autoSwitch);
164     return iter->second;
165 }
166 
RemoveDeviceConfig(struct libinput_device * device)167 void KeyAutoRepeat::RemoveDeviceConfig(struct libinput_device *device)
168 {
169     CALL_DEBUG_ENTER;
170     CHKPV(device);
171     int32_t deviceId = InputDevMgr->FindInputDeviceId(device);
172     auto iter = deviceConfig_.find(deviceId);
173     if (iter == deviceConfig_.end()) {
174         MMI_HILOGI("Can not remove device config file");
175         return;
176     }
177     deviceConfig_.erase(iter);
178 }
179 
RemoveTimer()180 void KeyAutoRepeat::RemoveTimer()
181 {
182     CALL_DEBUG_ENTER;
183     TimerMgr->RemoveTimer(timerId_);
184 }
185 
SetKeyboardRepeatDelay(int32_t delay)186 int32_t KeyAutoRepeat::SetKeyboardRepeatDelay(int32_t delay)
187 {
188     CALL_DEBUG_ENTER;
189     int32_t repeatDelayTime = delay;
190     if (delay < MIN_KEY_REPEAT_DELAY) {
191         repeatDelayTime = MIN_KEY_REPEAT_DELAY;
192     }
193     if (delay > MAX_KEY_REPEAT_DELAY) {
194         repeatDelayTime = MAX_KEY_REPEAT_DELAY;
195     }
196     std::string name = "keyboardRepeatDelay";
197     if (PutConfigDataToDatabase(name, repeatDelayTime) != RET_OK) {
198         MMI_HILOGE("Failed to set keyboard repeat delay.");
199         return RET_ERR;
200     }
201     MMI_HILOGD("Set keyboard repeat delay delay:%{public}d", repeatDelayTime);
202     return RET_OK;
203 }
204 
SetKeyboardRepeatRate(int32_t rate)205 int32_t KeyAutoRepeat::SetKeyboardRepeatRate(int32_t rate)
206 {
207     CALL_DEBUG_ENTER;
208     int32_t repeatRateTime = rate;
209     if (rate < MIN_KEY_REPEAT_RATE) {
210         repeatRateTime = MIN_KEY_REPEAT_RATE;
211     }
212     if (rate > MAX_KEY_REPEAT_RATE) {
213         repeatRateTime = MAX_KEY_REPEAT_RATE;
214     }
215     std::string name = "keyboardRepeatRate";
216     if (PutConfigDataToDatabase(name, repeatRateTime) != RET_OK) {
217         MMI_HILOGE("Failed to set keyboard repeat rate.");
218         return RET_ERR;
219     }
220     MMI_HILOGD("Set keyboard repeat rate rate:%{public}d", repeatRateTime);
221     return RET_OK;
222 }
223 
GetKeyboardRepeatDelay(int32_t & delay)224 int32_t KeyAutoRepeat::GetKeyboardRepeatDelay(int32_t &delay)
225 {
226     CALL_DEBUG_ENTER;
227     std::string name = "keyboardRepeatDelay";
228     if (GetConfigDataFromDatabase(name, delay) != RET_OK) {
229         MMI_HILOGE("Failed to get keyboard repeat delay.");
230         return RET_ERR;
231     }
232     if (delay == 0) {
233         delay = DEFAULT_KEY_REPEAT_DELAY;
234         if (keyEvent_ != nullptr) {
235             delay = GetKeyboardRepeatTime(keyEvent_->GetDeviceId(), true);
236         }
237     }
238     MMI_HILOGD("Get keyboard repeat delay delay:%{public}d", delay);
239     return RET_OK;
240 }
241 
GetKeyboardRepeatRate(int32_t & rate)242 int32_t KeyAutoRepeat::GetKeyboardRepeatRate(int32_t &rate)
243 {
244     CALL_DEBUG_ENTER;
245     std::string name = "keyboardRepeatRate";
246     if (GetConfigDataFromDatabase(name, rate) != RET_OK) {
247         MMI_HILOGE("Failed to get keyboard repeat rate.");
248         return RET_ERR;
249     }
250     if (rate == 0) {
251         rate = DEFAULT_KEY_REPEAT_RATE;
252         if (keyEvent_ != nullptr) {
253             rate = GetKeyboardRepeatTime(keyEvent_->GetDeviceId(), false);
254         }
255     }
256     MMI_HILOGD("Get keyboard repeat rate rate:%{public}d", rate);
257     return RET_OK;
258 }
259 
PutConfigDataToDatabase(std::string & key,int32_t value)260 int32_t KeyAutoRepeat::PutConfigDataToDatabase(std::string &key, int32_t value)
261 {
262     int32_t errCode = RET_OK;
263     std::shared_ptr<NativePreferences::Preferences> pref =
264         NativePreferences::PreferencesHelper::GetPreferences(KEYBOARD_FILE_NAME, errCode);
265     if (pref == nullptr) {
266         MMI_HILOGE("pref is nullptr, errCode: %{public}d", errCode);
267         return RET_ERR;
268     }
269     int32_t ret = pref->PutInt(key, value);
270     if (ret != RET_OK) {
271         MMI_HILOGE("Put value is failed, ret:%{public}d", ret);
272         return RET_ERR;
273     }
274     ret = pref->FlushSync();
275     if (ret != RET_OK) {
276         MMI_HILOGE("Flush sync is failed, ret:%{public}d", ret);
277         return RET_ERR;
278     }
279     NativePreferences::PreferencesHelper::RemovePreferencesFromCache(KEYBOARD_FILE_NAME);
280     return RET_OK;
281 }
282 
GetConfigDataFromDatabase(std::string & key,int32_t & value)283 int32_t KeyAutoRepeat::GetConfigDataFromDatabase(std::string &key, int32_t &value)
284 {
285     int32_t errCode = RET_OK;
286     std::shared_ptr<NativePreferences::Preferences> pref =
287         NativePreferences::PreferencesHelper::GetPreferences(KEYBOARD_FILE_NAME, errCode);
288     if (pref == nullptr) {
289         MMI_HILOGE("pref is nullptr, errCode: %{public}d", errCode);
290         return RET_ERR;
291     }
292     value = pref->GetInt(key, 0);
293     NativePreferences::PreferencesHelper::RemovePreferencesFromCache(KEYBOARD_FILE_NAME);
294     return RET_OK;
295 }
296 } // namespace MMI
297 } // namespace OHOS
298