1 /*
2  * Copyright (c) 2021-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_command_handler.h"
17 
18 #include <ostream>
19 #include <sstream>
20 
21 #include "cJSON.h"
22 #include "config_policy_utils.h"
23 #include "file_ex.h"
24 #include "system_ability_definition.h"
25 
26 #include "ability_manager_client.h"
27 #include "bytrace_adapter.h"
28 #include "define_multimodal.h"
29 #include "dfx_hisysevent.h"
30 #include "display_event_monitor.h"
31 #include "error_multimodal.h"
32 #include "event_log_helper.h"
33 #include "gesturesense_wrapper.h"
34 #include "input_event_data_transformation.h"
35 #include "input_event_handler.h"
36 #include "i_input_windows_manager.h"
37 #include "i_preference_manager.h"
38 #ifdef SHORTCUT_KEY_MANAGER_ENABLED
39 #include "key_shortcut_manager.h"
40 #endif // SHORTCUT_KEY_MANAGER_ENABLED
41 #include "key_command_handler_util.h"
42 #include "mmi_log.h"
43 #include "nap_process.h"
44 #include "net_packet.h"
45 #include "pointer_drawing_manager.h"
46 #include "proto.h"
47 #include "setting_datashare.h"
48 #include "stylus_key_handler.h"
49 #include "table_dump.h"
50 #include "timer_manager.h"
51 #include "util_ex.h"
52 
53 #undef MMI_LOG_DOMAIN
54 #define MMI_LOG_DOMAIN MMI_LOG_HANDLER
55 #undef MMI_LOG_TAG
56 #define MMI_LOG_TAG "KeyCommandHandler"
57 
58 namespace OHOS {
59 namespace MMI {
60 namespace {
61 constexpr float MOVE_TOLERANCE { 3.0f };
62 constexpr float MIN_GESTURE_STROKE_LENGTH { 200.0f };
63 constexpr float MIN_LETTER_GESTURE_SQUARENESS { 0.15f };
64 constexpr float MIN_START_GESTURE { 60.0f };
65 constexpr int32_t POINTER_NUMBER { 2 };
66 constexpr int32_t EVEN_NUMBER { 2 };
67 constexpr int64_t NO_DELAY { 0 };
68 constexpr int64_t FREQUENCY { 1000 };
69 constexpr int64_t TAP_DOWN_INTERVAL_MILLIS { 550000 };
70 constexpr int64_t SOS_INTERVAL_TIMES { 300000 };
71 constexpr int64_t SOS_DELAY_TIMES { 1000000 };
72 constexpr int64_t SOS_COUNT_DOWN_TIMES { 4000000 };
73 constexpr int32_t MAX_TAP_COUNT { 2 };
74 const std::string AIBASE_BUNDLE_NAME { "com.hmos.aibase" };
75 const std::string WAKEUP_ABILITY_NAME { "WakeUpExtAbility" };
76 const std::string SCREENSHOT_BUNDLE_NAME { "com.hmos.screenshot" };
77 const std::string SCREENSHOT_ABILITY_NAME { "com.hmos.screenshot.ServiceExtAbility" };
78 const std::string SCREENRECORDER_BUNDLE_NAME { "com.hmos.screenrecorder" };
79 const std::string SOS_BUNDLE_NAME { "com.hmos.emergencycommunication" };
80 constexpr int32_t DEFAULT_VALUE { -1 };
81 const std::string HARDEN_SCREENSHOT_BUNDLE_NAME { "com.hmos.screenshot" };
82 const std::string HARDEN_SCREENSHOT_ABILITY_NAME { "com.hmos.screenshot.ServiceExtAbility" };
83 const std::string HARDEN_SCREENRECORDER_BUNDLE_NAME { "com.hmos.screenrecorder" };
84 const std::string HARDEN_SCREENRECORDER_ABILITY_NAME { "com.hmos.screenrecorder.ServiceExtAbility" };
85 } // namespace
86 
87 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)88 void KeyCommandHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
89 {
90     CHKPV(keyEvent);
91     if (TouchPadKnuckleDoubleClickHandle(keyEvent)) {
92         return;
93     }
94     if (OnHandleEvent(keyEvent)) {
95         MMI_HILOGD("The keyEvent start launch an ability, keyCode:%{private}d", keyEvent->GetKeyCode());
96         BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::KEY_LAUNCH_EVENT);
97         return;
98     }
99     CHKPV(nextHandler_);
100     nextHandler_->HandleKeyEvent(keyEvent);
101 }
102 #endif // OHOS_BUILD_ENABLE_KEYBOARD
103 
104 #ifdef OHOS_BUILD_ENABLE_POINTER
HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)105 void KeyCommandHandler::HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)
106 {
107     CHKPV(pointerEvent);
108     if (OnHandleEvent(pointerEvent)) {
109         if (EventLogHelper::IsBetaVersion() && !pointerEvent->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) {
110             MMI_HILOGD("The pointerEvent start launch an ability, pointAction:%{public}s",
111                 pointerEvent->DumpPointerAction());
112         } else {
113             MMI_HILOGD("The pointerEvent start launch an ability, pointAction:%s", pointerEvent->DumpPointerAction());
114         }
115     }
116     CHKPV(nextHandler_);
117     nextHandler_->HandlePointerEvent(pointerEvent);
118 }
119 #endif // OHOS_BUILD_ENABLE_POINTER
120 
121 #ifdef OHOS_BUILD_ENABLE_TOUCH
HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)122 void KeyCommandHandler::HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)
123 {
124     CHKPV(pointerEvent);
125     CHKPV(nextHandler_);
126     OnHandleTouchEvent(pointerEvent);
127     int32_t id = pointerEvent->GetPointerId();
128     PointerEvent::PointerItem item;
129     pointerEvent->GetPointerItem(id, item);
130     int32_t toolType = item.GetToolType();
131     if (toolType == PointerEvent::TOOL_TYPE_KNUCKLE) {
132         pointerEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT);
133     }
134     nextHandler_->HandleTouchEvent(pointerEvent);
135 }
136 #endif // OHOS_BUILD_ENABLE_TOUCH
137 
GetKnuckleSwitchValue()138 bool KeyCommandHandler::GetKnuckleSwitchValue()
139 {
140     return knuckleSwitch_.statusConfigValue;
141 }
142 
143 #ifdef OHOS_BUILD_ENABLE_TOUCH
OnHandleTouchEvent(const std::shared_ptr<PointerEvent> touchEvent)144 void KeyCommandHandler::OnHandleTouchEvent(const std::shared_ptr<PointerEvent> touchEvent)
145 {
146     CALL_DEBUG_ENTER;
147     CHKPV(touchEvent);
148     STYLUS_HANDLER->SetLastEventState(false);
149     if (!isParseConfig_) {
150         if (!ParseConfig()) {
151             MMI_HILOGE("Parse configFile failed");
152             return;
153         }
154         isParseConfig_ = true;
155     }
156     if (!isTimeConfig_) {
157         SetKnuckleDoubleTapIntervalTime(DOUBLE_CLICK_INTERVAL_TIME_DEFAULT);
158         isTimeConfig_ = true;
159     }
160     if (!isDistanceConfig_) {
161         distanceDefaultConfig_ = DOUBLE_CLICK_DISTANCE_DEFAULT_CONFIG * VPR_CONFIG;
162         distanceLongConfig_ = DOUBLE_CLICK_DISTANCE_LONG_CONFIG * VPR_CONFIG;
163         SetKnuckleDoubleTapDistance(distanceDefaultConfig_);
164         isDistanceConfig_ = true;
165     }
166 
167     switch (touchEvent->GetPointerAction()) {
168         case PointerEvent::POINTER_ACTION_CANCEL:
169         case PointerEvent::POINTER_ACTION_UP: {
170             HandlePointerActionUpEvent(touchEvent);
171             break;
172         }
173         case PointerEvent::POINTER_ACTION_MOVE: {
174             HandlePointerActionMoveEvent(touchEvent);
175             break;
176         }
177         case PointerEvent::POINTER_ACTION_DOWN: {
178             HandlePointerActionDownEvent(touchEvent);
179             break;
180         }
181         default:
182             MMI_HILOGD("Unknown pointer action:%{public}d", touchEvent->GetPointerAction());
183             break;
184     }
185 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
186     HandleKnuckleGestureEvent(touchEvent);
187 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
188 }
189 
HandlePointerActionDownEvent(const std::shared_ptr<PointerEvent> touchEvent)190 void KeyCommandHandler::HandlePointerActionDownEvent(const std::shared_ptr<PointerEvent> touchEvent)
191 {
192     CALL_DEBUG_ENTER;
193     CHKPV(touchEvent);
194     int32_t id = touchEvent->GetPointerId();
195     PointerEvent::PointerItem item;
196     touchEvent->GetPointerItem(id, item);
197     int32_t toolType = item.GetToolType();
198     MMI_HILOGD("Pointer tool type:%{public}d", toolType);
199     singleKnuckleGesture_.state = false;
200     doubleKnuckleGesture_.state = false;
201     switch (toolType) {
202 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
203         case PointerEvent::TOOL_TYPE_FINGER: {
204             HandleFingerGestureDownEvent(touchEvent);
205             break;
206         }
207         case PointerEvent::TOOL_TYPE_KNUCKLE: {
208             DfxHisysevent::ReportKnuckleClickEvent();
209             HandleKnuckleGestureDownEvent(touchEvent);
210             break;
211         }
212 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
213         default: {
214             MMI_HILOGD("Current touch event tool type:%{public}d", toolType);
215             break;
216         }
217     }
218     CheckAndUpdateTappingCountAtDown(touchEvent);
219 }
220 
HandlePointerActionMoveEvent(const std::shared_ptr<PointerEvent> touchEvent)221 void KeyCommandHandler::HandlePointerActionMoveEvent(const std::shared_ptr<PointerEvent> touchEvent)
222 {
223     CALL_DEBUG_ENTER;
224     CHKPV(touchEvent);
225     int32_t id = touchEvent->GetPointerId();
226     PointerEvent::PointerItem item;
227     touchEvent->GetPointerItem(id, item);
228     if (!twoFingerGesture_.active) {
229         return;
230     }
231     if (twoFingerGesture_.timerId == -1) {
232         MMI_HILOGD("Two finger gesture timer id is -1");
233         return;
234     }
235     auto pos = std::find_if(std::begin(twoFingerGesture_.touches), std::end(twoFingerGesture_.touches),
236         [id](const auto& item) { return item.id == id; });
237     if (pos == std::end(twoFingerGesture_.touches)) {
238         return;
239     }
240     auto dx = std::abs(pos->x - item.GetDisplayX());
241     auto dy = std::abs(pos->y - item.GetDisplayY());
242     auto moveDistance = sqrt(pow(dx, 2) + pow(dy, 2));
243     if (moveDistance > ConvertVPToPX(TOUCH_MAX_THRESHOLD)) {
244 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
245         MMI_HILOGI("Finger movement distance greater than 20VP, defaultDistance:%{public}d, moveDistance:%{public}f",
246             ConvertVPToPX(TOUCH_MAX_THRESHOLD), moveDistance);
247         StopTwoFingerGesture();
248 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
249     }
250 }
251 
HandlePointerActionUpEvent(const std::shared_ptr<PointerEvent> touchEvent)252 void KeyCommandHandler::HandlePointerActionUpEvent(const std::shared_ptr<PointerEvent> touchEvent)
253 {
254     CALL_DEBUG_ENTER;
255     CHKPV(touchEvent);
256     int32_t id = touchEvent->GetPointerId();
257     PointerEvent::PointerItem item;
258     touchEvent->GetPointerItem(id, item);
259     int32_t toolType = item.GetToolType();
260     switch (toolType) {
261 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
262         case PointerEvent::TOOL_TYPE_FINGER: {
263             HandleFingerGestureUpEvent(touchEvent);
264             break;
265         }
266         case PointerEvent::TOOL_TYPE_KNUCKLE: {
267             HandleKnuckleGestureUpEvent(touchEvent);
268             break;
269         }
270 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
271         default: {
272             MMI_HILOGW("Current touch event tool type:%{public}d", toolType);
273             break;
274         }
275     }
276 }
277 #endif // OHOS_BUILD_ENABLE_TOUCH
278 
279 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
HandleFingerGestureDownEvent(const std::shared_ptr<PointerEvent> touchEvent)280 void KeyCommandHandler::HandleFingerGestureDownEvent(const std::shared_ptr<PointerEvent> touchEvent)
281 {
282     CALL_DEBUG_ENTER;
283     if (!twoFingerGesture_.active) {
284         MMI_HILOGD("Two finger gesture is not active");
285         return;
286     }
287     auto num = touchEvent->GetPointerIds().size();
288     if (num == TwoFingerGesture::MAX_TOUCH_NUM) {
289         StartTwoFingerGesture();
290     } else {
291         StopTwoFingerGesture();
292     }
293     if (num > 0 && num <= TwoFingerGesture::MAX_TOUCH_NUM) {
294         int32_t id = touchEvent->GetPointerId();
295         PointerEvent::PointerItem item;
296         touchEvent->GetPointerItem(id, item);
297         twoFingerGesture_.touches[num - 1].id = id;
298         twoFingerGesture_.touches[num - 1].x = item.GetDisplayX();
299         twoFingerGesture_.touches[num - 1].y = item.GetDisplayY();
300         twoFingerGesture_.touches[num - 1].downTime = item.GetDownTime();
301     }
302 }
303 
HandleFingerGestureUpEvent(const std::shared_ptr<PointerEvent> touchEvent)304 void KeyCommandHandler::HandleFingerGestureUpEvent(const std::shared_ptr<PointerEvent> touchEvent)
305 {
306     CALL_DEBUG_ENTER;
307     CHKPV(touchEvent);
308     if (!twoFingerGesture_.active) {
309         MMI_HILOGD("Two finger gesture is not active");
310         return;
311     }
312     StopTwoFingerGesture();
313 }
314 
HandleKnuckleGestureDownEvent(const std::shared_ptr<PointerEvent> touchEvent)315 void KeyCommandHandler::HandleKnuckleGestureDownEvent(const std::shared_ptr<PointerEvent> touchEvent)
316 {
317     CALL_DEBUG_ENTER;
318     CHKPV(touchEvent);
319     int32_t id = touchEvent->GetPointerId();
320     PointerEvent::PointerItem item;
321     touchEvent->GetPointerItem(id, item);
322     if (!lastPointerDownTime_.empty()) {
323         int64_t lastPointerDownTime = touchEvent->HasFlag(InputEvent::EVENT_FLAG_SIMULATE) ?
324             lastPointerDownTime_[SIMULATE_POINTER_ID] : lastPointerDownTime_[0];
325         int64_t diffTime = item.GetDownTime() - lastPointerDownTime;
326         if (diffTime > TWO_FINGERS_TIME_LIMIT) {
327             MMI_HILOGE("Invalid double knuckle event, diffTime:%{public}" PRId64, diffTime);
328             return;
329         }
330     }
331     lastPointerDownTime_[id] = item.GetDownTime();
332 
333     if (item.GetToolType() != PointerEvent::TOOL_TYPE_KNUCKLE) {
334         MMI_HILOGW("Touch event tool type:%{public}d not knuckle", item.GetToolType());
335         return;
336     }
337     if (knuckleSwitch_.statusConfigValue) {
338         MMI_HILOGI("Knuckle switch closed");
339         return;
340     }
341     if (CheckInputMethodArea(touchEvent)) {
342         MMI_HILOGI("In input method area, skip");
343         return;
344     }
345     size_t pointercnt = touchEvent->GetPointerIds().size();
346     if (pointercnt == SINGLE_KNUCKLE_SIZE) {
347         SingleKnuckleGestureProcesser(touchEvent);
348         isDoubleClick_ = false;
349         knuckleCount_++;
350     } else if (pointercnt == DOUBLE_KNUCKLE_SIZE) {
351         DoubleKnuckleGestureProcesser(touchEvent);
352         isDoubleClick_ = true;
353     } else {
354         MMI_HILOGW("Other kunckle pointercnt not process, pointercnt:%{public}zu", pointercnt);
355     }
356 }
357 
HandleKnuckleGestureUpEvent(const std::shared_ptr<PointerEvent> touchEvent)358 void KeyCommandHandler::HandleKnuckleGestureUpEvent(const std::shared_ptr<PointerEvent> touchEvent)
359 {
360     CALL_DEBUG_ENTER;
361     CHKPV(touchEvent);
362     int32_t id = touchEvent->GetPointerId();
363     auto it = lastPointerDownTime_.find(id);
364     if (it != lastPointerDownTime_.end()) {
365         lastPointerDownTime_.erase(it);
366     }
367 
368     previousUpTime_ = touchEvent->GetActionTime();
369     size_t pointercnt = touchEvent->GetPointerIds().size();
370     if ((pointercnt == SINGLE_KNUCKLE_SIZE) && (!isDoubleClick_)) {
371         singleKnuckleGesture_.lastPointerUpTime = touchEvent->GetActionTime();
372     } else if (pointercnt == DOUBLE_KNUCKLE_SIZE) {
373         doubleKnuckleGesture_.lastPointerUpTime = touchEvent->GetActionTime();
374     } else {
375         MMI_HILOGW("Other kunckle pointercnt not process, pointercnt:%{public}zu", pointercnt);
376     }
377 }
378 
SingleKnuckleGestureProcesser(const std::shared_ptr<PointerEvent> touchEvent)379 void KeyCommandHandler::SingleKnuckleGestureProcesser(const std::shared_ptr<PointerEvent> touchEvent)
380 {
381     CALL_DEBUG_ENTER;
382     CHKPV(touchEvent);
383     singleKnuckleGesture_.state = false;
384     KnuckleGestureProcessor(touchEvent, singleKnuckleGesture_, KnuckleType::KNUCKLE_TYPE_SINGLE);
385 }
386 
DoubleKnuckleGestureProcesser(const std::shared_ptr<PointerEvent> touchEvent)387 void KeyCommandHandler::DoubleKnuckleGestureProcesser(const std::shared_ptr<PointerEvent> touchEvent)
388 {
389     CALL_DEBUG_ENTER;
390     CHKPV(touchEvent);
391     doubleKnuckleGesture_.state = false;
392     KnuckleGestureProcessor(touchEvent, doubleKnuckleGesture_, KnuckleType::KNUCKLE_TYPE_DOUBLE);
393 }
394 
KnuckleGestureProcessor(std::shared_ptr<PointerEvent> touchEvent, KnuckleGesture &knuckleGesture, KnuckleType type)395 void KeyCommandHandler::KnuckleGestureProcessor(std::shared_ptr<PointerEvent> touchEvent,
396     KnuckleGesture &knuckleGesture, KnuckleType type)
397 {
398     CALL_DEBUG_ENTER;
399     CHKPV(touchEvent);
400     if (knuckleGesture.lastPointerDownEvent == nullptr) {
401         MMI_HILOGI("Knuckle gesture first down Event");
402         knuckleGesture.lastPointerDownEvent = touchEvent;
403         UpdateKnuckleGestureInfo(touchEvent, knuckleGesture);
404         return;
405     }
406     int64_t intervalTime = touchEvent->GetActionTime() - knuckleGesture.lastPointerUpTime;
407     bool isTimeIntervalReady = intervalTime > 0 && intervalTime <= downToPrevUpTimeConfig_;
408     float downToPrevDownDistance = AbsDiff(knuckleGesture, touchEvent);
409     bool isDistanceReady = downToPrevDownDistance < downToPrevDownDistanceConfig_;
410     knuckleGesture.downToPrevUpTime = intervalTime;
411     knuckleGesture.doubleClickDistance = downToPrevDownDistance;
412     UpdateKnuckleGestureInfo(touchEvent, knuckleGesture);
413     if (isTimeIntervalReady && (type == KnuckleType::KNUCKLE_TYPE_DOUBLE || isDistanceReady)) {
414         MMI_HILOGI("Knuckle gesture start launch ability");
415         knuckleCount_ = 0;
416         DfxHisysevent::ReportSingleKnuckleDoubleClickEvent(intervalTime, downToPrevDownDistance);
417         BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_FINGERSCENE, knuckleGesture.ability.bundleName);
418         LaunchAbility(knuckleGesture.ability, NO_DELAY);
419         BytraceAdapter::StopLaunchAbility();
420         knuckleGesture.state = true;
421         if (knuckleGesture.ability.bundleName == SCREENRECORDER_BUNDLE_NAME) {
422             DfxHisysevent::ReportScreenRecorderGesture(intervalTime);
423         }
424         ReportKnuckleScreenCapture(touchEvent);
425     } else {
426         if (knuckleCount_ > KNUCKLE_KNOCKS) {
427             knuckleCount_ = 0;
428             MMI_HILOGW("Time ready:%{public}d, distance ready:%{public}d", isTimeIntervalReady, isDistanceReady);
429             if (!isTimeIntervalReady) {
430                 DfxHisysevent::ReportFailIfInvalidTime(touchEvent, intervalTime);
431             }
432             if (!isDistanceReady) {
433                 DfxHisysevent::ReportFailIfInvalidDistance(touchEvent, downToPrevDownDistance);
434             }
435         }
436     }
437     AdjustTimeIntervalConfigIfNeed(intervalTime);
438     AdjustDistanceConfigIfNeed(downToPrevDownDistance);
439 }
440 
UpdateKnuckleGestureInfo(const std::shared_ptr<PointerEvent> touchEvent, KnuckleGesture &knuckleGesture)441 void KeyCommandHandler::UpdateKnuckleGestureInfo(const std::shared_ptr<PointerEvent> touchEvent,
442     KnuckleGesture &knuckleGesture)
443 {
444     int32_t id = touchEvent->GetPointerId();
445     PointerEvent::PointerItem item;
446     touchEvent->GetPointerItem(id, item);
447     knuckleGesture.lastDownPointer.x = item.GetDisplayX();
448     knuckleGesture.lastDownPointer.y = item.GetDisplayY();
449     knuckleGesture.lastDownPointer.id = touchEvent->GetId();
450 }
451 
AdjustTimeIntervalConfigIfNeed(int64_t intervalTime)452 void KeyCommandHandler::AdjustTimeIntervalConfigIfNeed(int64_t intervalTime)
453 {
454     CALL_DEBUG_ENTER;
455     int64_t newTimeConfig;
456     MMI_HILOGI("Down to prev up interval time:%{public}" PRId64 ",config time:%{public}" PRId64"",
457         intervalTime, downToPrevUpTimeConfig_);
458     if (downToPrevUpTimeConfig_ == DOUBLE_CLICK_INTERVAL_TIME_DEFAULT) {
459         if (intervalTime < DOUBLE_CLICK_INTERVAL_TIME_DEFAULT || intervalTime > DOUBLE_CLICK_INTERVAL_TIME_SLOW) {
460             return;
461         }
462         newTimeConfig = DOUBLE_CLICK_INTERVAL_TIME_SLOW;
463     } else if (downToPrevUpTimeConfig_ == DOUBLE_CLICK_INTERVAL_TIME_SLOW) {
464         if (intervalTime > DOUBLE_CLICK_INTERVAL_TIME_DEFAULT) {
465             return;
466         }
467         newTimeConfig = DOUBLE_CLICK_INTERVAL_TIME_DEFAULT;
468     } else {
469         return;
470     }
471     checkAdjustIntervalTimeCount_++;
472     if (checkAdjustIntervalTimeCount_ < MAX_TIME_FOR_ADJUST_CONFIG) {
473         return;
474     }
475     MMI_HILOGI("Adjust new double click interval time:%{public}" PRId64 "", newTimeConfig);
476     downToPrevUpTimeConfig_ = newTimeConfig;
477     checkAdjustIntervalTimeCount_ = 0;
478 }
479 
AdjustDistanceConfigIfNeed(float distance)480 void KeyCommandHandler::AdjustDistanceConfigIfNeed(float distance)
481 {
482     CALL_DEBUG_ENTER;
483     float newDistanceConfig;
484     MMI_HILOGI("Down to prev down distance:%{public}f, config distance:%{public}f",
485         distance, downToPrevDownDistanceConfig_);
486     if (IsEqual(downToPrevDownDistanceConfig_, distanceDefaultConfig_)) {
487         if (distance < distanceDefaultConfig_ || distance > distanceLongConfig_) {
488             return;
489         }
490         newDistanceConfig = distanceLongConfig_;
491     } else if (IsEqual(downToPrevDownDistanceConfig_, distanceLongConfig_)) {
492         if (distance > distanceDefaultConfig_) {
493             return;
494         }
495         newDistanceConfig = distanceDefaultConfig_;
496     } else {
497         return;
498     }
499     checkAdjustDistanceCount_++;
500     if (checkAdjustDistanceCount_ < MAX_TIME_FOR_ADJUST_CONFIG) {
501         return;
502     }
503     MMI_HILOGI("Adjust new double click distance:%{public}f", newDistanceConfig);
504     downToPrevDownDistanceConfig_ = newDistanceConfig;
505     checkAdjustDistanceCount_ = 0;
506 }
507 
ReportKnuckleScreenCapture(const std::shared_ptr<PointerEvent> touchEvent)508 void KeyCommandHandler::ReportKnuckleScreenCapture(const std::shared_ptr<PointerEvent> touchEvent)
509 {
510     CHKPV(touchEvent);
511     size_t pointercnt = touchEvent->GetPointerIds().size();
512     if (pointercnt == SINGLE_KNUCKLE_SIZE) {
513         DfxHisysevent::ReportScreenCaptureGesture();
514         return;
515     }
516     MMI_HILOGW("Current touch event pointercnt:%{public}zu", pointercnt);
517 }
518 
StartTwoFingerGesture()519 void KeyCommandHandler::StartTwoFingerGesture()
520 {
521     CALL_DEBUG_ENTER;
522     twoFingerGesture_.timerId = TimerMgr->AddTimer(twoFingerGesture_.abilityStartDelay, 1, [this]() {
523         twoFingerGesture_.timerId = -1;
524         if (!CheckTwoFingerGestureAction()) {
525             return;
526         }
527         twoFingerGesture_.ability.params["displayX1"] = std::to_string(twoFingerGesture_.touches[0].x);
528         twoFingerGesture_.ability.params["displayY1"] = std::to_string(twoFingerGesture_.touches[0].y);
529         twoFingerGesture_.ability.params["displayX2"] = std::to_string(twoFingerGesture_.touches[1].x);
530         twoFingerGesture_.ability.params["displayY2"] = std::to_string(twoFingerGesture_.touches[1].y);
531         MMI_HILOGI("Start launch ability immediately");
532         BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_MULTI_FINGERS, twoFingerGesture_.ability.bundleName);
533         LaunchAbility(twoFingerGesture_.ability, twoFingerGesture_.abilityStartDelay);
534         BytraceAdapter::StopLaunchAbility();
535     });
536 }
537 
StopTwoFingerGesture()538 void KeyCommandHandler::StopTwoFingerGesture()
539 {
540     CALL_DEBUG_ENTER;
541     if (twoFingerGesture_.timerId != -1) {
542         TimerMgr->RemoveTimer(twoFingerGesture_.timerId);
543         twoFingerGesture_.timerId = -1;
544     }
545 }
546 
CheckTwoFingerGestureAction() const547 bool KeyCommandHandler::CheckTwoFingerGestureAction() const
548 {
549     if (!twoFingerGesture_.active) {
550         return false;
551     }
552 
553     auto firstFinger = twoFingerGesture_.touches[0];
554     auto secondFinger = twoFingerGesture_.touches[1];
555 
556     auto pressTimeInterval = fabs(firstFinger.downTime - secondFinger.downTime);
557     if (pressTimeInterval > TWO_FINGERS_TIME_LIMIT) {
558         return false;
559     }
560 
561 #ifdef OHOS_BUILD_ENABLE_TOUCH
562     auto devX = firstFinger.x - secondFinger.x;
563     auto devY = firstFinger.y - secondFinger.y;
564     auto distance = sqrt(pow(devX, 2) + pow(devY, 2));
565     if (distance < ConvertVPToPX(TWO_FINGERS_DISTANCE_LIMIT)) {
566         MMI_HILOGI("Two fingers distance:%{public}f too small", distance);
567         return false;
568     }
569 
570     auto displayInfo = WIN_MGR->GetDefaultDisplayInfo();
571     CHKPR(displayInfo, false);
572     auto leftLimit = ConvertVPToPX(TOUCH_LIFT_LIMIT);
573     auto rightLimit = displayInfo->width - ConvertVPToPX(TOUCH_RIGHT_LIMIT);
574     auto topLimit = ConvertVPToPX(TOUCH_TOP_LIMIT);
575     auto bottomLimit = displayInfo->height - ConvertVPToPX(TOUCH_BOTTOM_LIMIT);
576     if (firstFinger.x <= leftLimit || firstFinger.x >= rightLimit ||
577         firstFinger.y <= topLimit || firstFinger.y >= bottomLimit ||
578         secondFinger.x <= leftLimit || secondFinger.x >= rightLimit ||
579         secondFinger.y <= topLimit || secondFinger.y >= bottomLimit) {
580         MMI_HILOGI("Any finger out of region");
581         return false;
582     }
583 #endif // OHOS_BUILD_ENABLE_TOUCH
584 
585     return true;
586 }
587 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
588 
589 #ifdef OHOS_BUILD_ENABLE_TOUCH
ConvertVPToPX(int32_t vp) const590 int32_t KeyCommandHandler::ConvertVPToPX(int32_t vp) const
591 {
592     if (vp <= 0) {
593         return 0;
594     }
595     auto displayInfo = WIN_MGR->GetDefaultDisplayInfo();
596     CHKPR(displayInfo, 0);
597     int32_t dpi = displayInfo->dpi;
598     if (dpi <= 0) {
599         return 0;
600     }
601     const int32_t base = 160;
602     return vp * (dpi / base);
603 }
604 #endif // OHOS_BUILD_ENABLE_TOUCH
605 
606 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
HandleKnuckleGestureEvent(std::shared_ptr<PointerEvent> touchEvent)607 void KeyCommandHandler::HandleKnuckleGestureEvent(std::shared_ptr<PointerEvent> touchEvent)
608 {
609     CALL_DEBUG_ENTER;
610     if (!CheckKnuckleCondition(touchEvent)) {
611         return;
612     }
613     CHKPV(touchEvent);
614     int32_t touchAction = touchEvent->GetPointerAction();
615     if (IsValidAction(touchAction)) {
616         switch (touchAction) {
617             case PointerEvent::POINTER_ACTION_CANCEL:
618             case PointerEvent::POINTER_ACTION_UP: {
619                 HandleKnuckleGestureTouchUp(touchEvent);
620                 break;
621             }
622             case PointerEvent::POINTER_ACTION_MOVE: {
623                 HandleKnuckleGestureTouchMove(touchEvent);
624                 break;
625             }
626             case PointerEvent::POINTER_ACTION_DOWN: {
627                 HandleKnuckleGestureTouchDown(touchEvent);
628                 break;
629             }
630             default:
631                 MMI_HILOGD("Unknown pointer action:%{public}d", touchAction);
632                 break;
633         }
634     }
635 }
636 
CheckKnuckleCondition(std::shared_ptr<PointerEvent> touchEvent)637 bool KeyCommandHandler::CheckKnuckleCondition(std::shared_ptr<PointerEvent> touchEvent)
638 {
639     CHKPF(touchEvent);
640     PointerEvent::PointerItem item;
641     touchEvent->GetPointerItem(touchEvent->GetPointerId(), item);
642     if (item.GetToolType() != PointerEvent::TOOL_TYPE_KNUCKLE ||
643         touchEvent->GetPointerIds().size() != SINGLE_KNUCKLE_SIZE || singleKnuckleGesture_.state) {
644         MMI_HILOGD("Touch tool type is:%{public}d", item.GetToolType());
645         ResetKnuckleGesture();
646         return false;
647     }
648     auto physicDisplayInfo = WIN_MGR->GetPhysicalDisplay(touchEvent->GetTargetDisplayId());
649     if (physicDisplayInfo != nullptr && physicDisplayInfo->direction != lastDirection_) {
650         lastDirection_ = physicDisplayInfo->direction;
651         if (touchEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_MOVE && !gesturePoints_.empty()) {
652             MMI_HILOGW("The screen has been rotated while knuckle is moving");
653             ResetKnuckleGesture();
654             return false;
655         }
656     }
657     if (knuckleSwitch_.statusConfigValue) {
658         MMI_HILOGI("Knuckle switch closed");
659         return false;
660     }
661     if (CheckInputMethodArea(touchEvent)) {
662         if (touchEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_DOWN ||
663             touchEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_UP) {
664             MMI_HILOGI("In input method area, skip");
665         }
666         return false;
667     }
668     return true;
669 }
670 
IsValidAction(int32_t action)671 bool KeyCommandHandler::IsValidAction(int32_t action)
672 {
673     CALL_DEBUG_ENTER;
674     if (action == PointerEvent::POINTER_ACTION_DOWN ||
675         ((action == PointerEvent::POINTER_ACTION_MOVE || action == PointerEvent::POINTER_ACTION_UP ||
676         action == PointerEvent::POINTER_ACTION_CANCEL) && !gesturePoints_.empty())) {
677         return true;
678     }
679     return false;
680 }
681 
CalcDrawCoordinate(const DisplayInfo& displayInfo, PointerEvent::PointerItem pointerItem)682 std::pair<int32_t, int32_t> KeyCommandHandler::CalcDrawCoordinate(const DisplayInfo& displayInfo,
683     PointerEvent::PointerItem pointerItem)
684 {
685     CALL_DEBUG_ENTER;
686     double physicalX = pointerItem.GetRawDisplayX();
687     double physicalY = pointerItem.GetRawDisplayY();
688     if (!displayInfo.transform.empty()) {
689         auto displayXY = WIN_MGR->TransformDisplayXY(displayInfo, physicalX, physicalY);
690         physicalX = displayXY.first;
691         physicalY = displayXY.second;
692     }
693     return {static_cast<int32_t>(physicalX), static_cast<int32_t>(physicalY)};
694 }
695 
HandleKnuckleGestureTouchDown(std::shared_ptr<PointerEvent> touchEvent)696 void KeyCommandHandler::HandleKnuckleGestureTouchDown(std::shared_ptr<PointerEvent> touchEvent)
697 {
698     CALL_DEBUG_ENTER;
699     CHKPV(touchEvent);
700     ResetKnuckleGesture();
701     isStartBase_ = false;
702     int32_t id = touchEvent->GetPointerId();
703     PointerEvent::PointerItem item;
704     touchEvent->GetPointerItem(id, item);
705     sessionKey_ = "Base" + std::to_string(item.GetDownTime());
706     auto displayInfo = WIN_MGR->GetPhysicalDisplay(touchEvent->GetTargetDisplayId());
707     CHKPV(displayInfo);
708     auto displayXY = CalcDrawCoordinate(*displayInfo, item);
709     gestureLastX_ = displayXY.first;
710     gestureLastY_ = displayXY.second;
711 
712     gesturePoints_.emplace_back(gestureLastX_);
713     gesturePoints_.emplace_back(gestureLastY_);
714     gestureTimeStamps_.emplace_back(touchEvent->GetActionTime());
715 }
716 
HandleKnuckleGestureTouchMove(std::shared_ptr<PointerEvent> touchEvent)717 void KeyCommandHandler::HandleKnuckleGestureTouchMove(std::shared_ptr<PointerEvent> touchEvent)
718 {
719     CALL_DEBUG_ENTER;
720     CHKPV(touchEvent);
721     PointerEvent::PointerItem item;
722     touchEvent->GetPointerItem(touchEvent->GetPointerId(), item);
723     auto displayInfo = WIN_MGR->GetPhysicalDisplay(touchEvent->GetTargetDisplayId());
724     CHKPV(displayInfo);
725     auto displayXY = CalcDrawCoordinate(*displayInfo, item);
726     float eventX = displayXY.first;
727     float eventY = displayXY.second;
728     float dx = std::abs(eventX - gestureLastX_);
729     float dy = std::abs(eventY - gestureLastY_);
730     if (dx >= MOVE_TOLERANCE || dy >= MOVE_TOLERANCE) {
731         gestureLastX_ = eventX;
732         gestureLastY_ = eventY;
733         gesturePoints_.emplace_back(gestureLastX_);
734         gesturePoints_.emplace_back(gestureLastY_);
735         gestureTimeStamps_.emplace_back(touchEvent->GetActionTime());
736         if (!isStartBase_ && IsMatchedAbility(gesturePoints_, gestureLastX_, gestureLastY_)) {
737             MMI_HILOGI("First time start aility, size:%{public}zu", gesturePoints_.size());
738             ProcessKnuckleGestureTouchUp(NotifyType::REGIONGESTURE);
739             isStartBase_ = true;
740         }
741         if (!isGesturing_) {
742             gestureTrackLength_ += sqrt(dx * dx + dy * dy);
743             if (gestureTrackLength_ > MIN_GESTURE_STROKE_LENGTH) {
744                 isGesturing_ = true;
745             }
746         }
747         if (isGesturing_ && !isLetterGesturing_) {
748             auto GetBoundingSquareness = GESTURESENSE_WRAPPER->getBoundingSquareness_;
749             CHKPV(GetBoundingSquareness);
750             auto boundingSquareness = GetBoundingSquareness(gesturePoints_);
751             if (boundingSquareness > MIN_LETTER_GESTURE_SQUARENESS) {
752                 isLetterGesturing_ = true;
753             }
754         }
755     }
756 }
757 
HandleKnuckleGestureTouchUp(std::shared_ptr<PointerEvent> touchEvent)758 void KeyCommandHandler::HandleKnuckleGestureTouchUp(std::shared_ptr<PointerEvent> touchEvent)
759 {
760     CALL_DEBUG_ENTER;
761     CHKPV(touchEvent);
762     auto touchUp = GESTURESENSE_WRAPPER->touchUp_;
763     CHKPV(touchUp);
764     MMI_HILOGI("Knuckle gesturePoints size:%{public}zu, isGesturing:%{public}d, isLetterGesturing:%{public}d",
765         gesturePoints_.size(), isGesturing_, isLetterGesturing_);
766     NotifyType notifyType = static_cast<NotifyType>(touchUp(gesturePoints_, gestureTimeStamps_,
767         isGesturing_, isLetterGesturing_));
768     switch (notifyType) {
769         case NotifyType::REGIONGESTURE: {
770             ProcessKnuckleGestureTouchUp(notifyType);
771             drawOSuccTimestamp_ = touchEvent->GetActionTime();
772             ReportRegionGesture();
773             break;
774         }
775         case NotifyType::LETTERGESTURE: {
776             ProcessKnuckleGestureTouchUp(notifyType);
777             drawOFailTimestamp_ = touchEvent->GetActionTime();
778             ReportLetterGesture();
779             break;
780         }
781         default: {
782             MMI_HILOGW("Not a region gesture or letter gesture, notifyType:%{public}d", notifyType);
783             drawOFailTimestamp_ = touchEvent->GetActionTime();
784             ReportIfNeed();
785             break;
786         }
787     }
788     ResetKnuckleGesture();
789 }
790 
ProcessKnuckleGestureTouchUp(NotifyType type)791 void KeyCommandHandler::ProcessKnuckleGestureTouchUp(NotifyType type)
792 {
793     Ability ability;
794     ability.abilityType = EXTENSION_ABILITY;
795     if (type == NotifyType::REGIONGESTURE) {
796         ability.abilityName = WAKEUP_ABILITY_NAME;
797         ability.bundleName = AIBASE_BUNDLE_NAME;
798         ability.params.emplace(std::make_pair("shot_type", "smart-shot"));
799         MMI_HILOGI("isStartBase_:%{public}d, sessionKey_:%{public}s", isStartBase_, sessionKey_.c_str());
800         if (!isStartBase_) {
801             ability.params.emplace(std::make_pair("fingerPath", ""));
802             ability.params.emplace(std::make_pair("launch_type", "knuckle_gesture_pre"));
803         } else {
804             ability.params.emplace(std::make_pair("fingerPath", GesturePointsToStr()));
805             ability.params.emplace(std::make_pair("launch_type", "knuckle_gesture"));
806         }
807         ability.params.emplace(std::make_pair("session_id", sessionKey_));
808     } else if (type == NotifyType::LETTERGESTURE) {
809         ability.abilityName = SCREENSHOT_ABILITY_NAME;
810         ability.bundleName = SCREENSHOT_BUNDLE_NAME;
811         ability.params.emplace(std::make_pair("shot_type", "scroll-shot"));
812         ability.params.emplace(std::make_pair("trigger_type", "knuckle"));
813     }
814     LaunchAbility(ability, NO_DELAY);
815 }
816 
ResetKnuckleGesture()817 void KeyCommandHandler::ResetKnuckleGesture()
818 {
819     gestureLastX_ = 0.0f;
820     gestureLastY_ = 0.0f;
821     isGesturing_ = false;
822     isLetterGesturing_ = false;
823     gestureTrackLength_ = 0.0f;
824     gesturePoints_.clear();
825     gestureTimeStamps_.clear();
826 }
827 
GesturePointsToStr() const828 std::string KeyCommandHandler::GesturePointsToStr() const
829 {
830     int32_t count = static_cast<int32_t>(gesturePoints_.size());
831     if (count % EVEN_NUMBER != 0 || count == 0) {
832         MMI_HILOGE("Invalid gesturePoints_ size");
833         return {};
834     }
835     cJSON *jsonArray = cJSON_CreateArray();
836     for (int32_t i = 0; i < count; i += EVEN_NUMBER) {
837         cJSON *jsonData = cJSON_CreateObject();
838         cJSON_AddItemToObject(jsonData, "x", cJSON_CreateNumber(gesturePoints_[i]));
839         cJSON_AddItemToObject(jsonData, "y", cJSON_CreateNumber(gesturePoints_[i + 1]));
840         cJSON_AddItemToArray(jsonArray, jsonData);
841     }
842     char *jsonString = cJSON_Print(jsonArray);
843     std::string result = std::string(jsonString);
844     cJSON_Delete(jsonArray);
845     cJSON_free(jsonString);
846     return result;
847 }
848 
ReportIfNeed()849 void KeyCommandHandler::ReportIfNeed()
850 {
851     if (!isGesturing_) {
852         return;
853     }
854     DfxHisysevent::ReportKnuckleGestureFaildTimes();
855     DfxHisysevent::ReportKnuckleGestureTrackLength(gestureTrackLength_);
856     DfxHisysevent::ReportKnuckleGestureTrackTime(gestureTimeStamps_);
857     if (isLastGestureSucceed_) {
858         DfxHisysevent::ReportKnuckleGestureFromSuccessToFailTime(drawOFailTimestamp_ - drawOSuccTimestamp_);
859     }
860     isLastGestureSucceed_ = false;
861 }
862 
ReportRegionGesture()863 void KeyCommandHandler::ReportRegionGesture()
864 {
865     DfxHisysevent::ReportSmartShotSuccTimes();
866     ReportGestureInfo();
867 }
868 
ReportLetterGesture()869 void KeyCommandHandler::ReportLetterGesture()
870 {
871     DfxHisysevent::ReportKnuckleDrawSSuccessTimes();
872     ReportGestureInfo();
873 }
874 
ReportGestureInfo()875 void KeyCommandHandler::ReportGestureInfo()
876 {
877     DfxHisysevent::ReportKnuckleGestureTrackLength(gestureTrackLength_);
878     DfxHisysevent::ReportKnuckleGestureTrackTime(gestureTimeStamps_);
879     if (!isLastGestureSucceed_) {
880         DfxHisysevent::ReportKnuckleGestureFromFailToSuccessTime(drawOSuccTimestamp_ - drawOFailTimestamp_);
881     }
882     isLastGestureSucceed_ = true;
883 }
884 
IsMatchedAbility(std::vector<float> gesturePoints, float gestureLastX, float gestureLastY)885 bool KeyCommandHandler::IsMatchedAbility(std::vector<float> gesturePoints,
886     float gestureLastX, float gestureLastY)
887 {
888     if (gesturePoints.size() < POINTER_NUMBER) {
889         MMI_HILOGI("The gesturePoints_ is empty");
890         return false;
891     }
892     float gestureFirstX = gesturePoints[0];
893     float gestureFirstY = gesturePoints[1];
894     float distance = std::min(std::abs(gestureLastX - gestureFirstX), std::abs(gestureLastY - gestureFirstY));
895     return distance >= MIN_START_GESTURE;
896 }
897 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
898 
ParseConfig()899 bool KeyCommandHandler::ParseConfig()
900 {
901 #ifndef UNIT_TEST
902     const char *testPathSuffix = "/etc/multimodalinput/ability_launch_config.json";
903 #else
904     const char *testPathSuffix = "/data/test/test.json";
905 #endif // UNIT_TEST
906     char buf[MAX_PATH_LEN] = { 0 };
907     char *filePath = GetOneCfgFile(testPathSuffix, buf, MAX_PATH_LEN);
908 #ifndef UNIT_TEST
909     std::string defaultConfig = "/system/etc/multimodalinput/ability_launch_config.json";
910 #else
911     std::string defaultConfig = "/data/test/test.json";
912 #endif // UNIT_TEST
913     if (filePath == nullptr || filePath[0] == '\0' || strlen(filePath) > MAX_PATH_LEN) {
914         MMI_HILOGD("Can not get customization config file");
915         return ParseJson(defaultConfig);
916     }
917     std::string customConfig = filePath;
918     MMI_HILOGD("The configuration file path:%{private}s", customConfig.c_str());
919     return ParseJson(customConfig) || ParseJson(defaultConfig);
920 }
921 
ParseExcludeConfig()922 bool KeyCommandHandler::ParseExcludeConfig()
923 {
924 #ifndef UNIT_TEST
925     const char *testPathSuffix = "/etc/multimodalinput/exclude_keys_config.json";
926 #else
927     const char *testPathSuffix = "/data/test/exclude_keys_config.json";
928 #endif // UNIT_TEST
929     char buf[MAX_PATH_LEN] = { 0 };
930     char *filePath = GetOneCfgFile(testPathSuffix, buf, MAX_PATH_LEN);
931 #ifndef UNIT_TEST
932     std::string defaultConfig = "/system/etc/multimodalinput/exclude_keys_config.json";
933 #else
934     std::string defaultConfig = "/data/test/exclude_keys_config.json";
935 #endif // UNIT_TEST
936     if (filePath == nullptr || filePath[0] == '\0' || strlen(filePath) > MAX_PATH_LEN) {
937         MMI_HILOGD("Can not get customization exclude_keys_config.json file");
938         return ParseExcludeJson(defaultConfig);
939     }
940     std::string customConfig = filePath;
941     MMI_HILOGD("The exclude_keys_config.json file path:%s", customConfig.c_str());
942     return ParseExcludeJson(customConfig) || ParseExcludeJson(defaultConfig);
943 }
944 
ParseRepeatKeyMaxCount()945 void KeyCommandHandler::ParseRepeatKeyMaxCount()
946 {
947     if (repeatKeys_.empty()) {
948         maxCount_ = 0;
949     }
950     int32_t tempCount = 0;
951     int32_t tempDelay = 0;
952     for (RepeatKey& item : repeatKeys_) {
953         if (item.times > tempCount) {
954             tempCount = item.times;
955         }
956         if (item.delay > tempDelay) {
957             tempDelay = item.delay;
958         }
959     }
960     maxCount_ = tempCount;
961     intervalTime_ = tempDelay;
962 }
963 
CheckSpecialRepeatKey(RepeatKey& item, const std::shared_ptr<KeyEvent> keyEvent)964 bool KeyCommandHandler::CheckSpecialRepeatKey(RepeatKey& item, const std::shared_ptr<KeyEvent> keyEvent)
965 {
966     if (item.keyCode != keyEvent->GetKeyCode()) {
967         return false;
968     }
969     if (item.keyCode != KeyEvent::KEYCODE_VOLUME_DOWN) {
970         return false;
971     }
972     std::string bundleName = item.ability.bundleName;
973     std::string matchName = ".camera";
974     if (bundleName.find(matchName) == std::string::npos) {
975         return false;
976     }
977     std::string screenStatus = DISPLAY_MONITOR->GetScreenStatus();
978     bool isScreenLocked = DISPLAY_MONITOR->GetScreenLocked();
979     MMI_HILOGI("ScreenStatus: %{public}s, isScreenLocked: %{public}d", screenStatus.c_str(), isScreenLocked);
980     if (screenStatus == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF || isScreenLocked) {
981         return false;
982     }
983     return true;
984 }
985 
ParseJson(const std::string &configFile)986 bool KeyCommandHandler::ParseJson(const std::string &configFile)
987 {
988     CALL_DEBUG_ENTER;
989     std::string jsonStr = ReadJsonFile(configFile);
990     if (jsonStr.empty()) {
991         MMI_HILOGE("Read configFile failed");
992         return false;
993     }
994     JsonParser parser;
995     parser.json_ = cJSON_Parse(jsonStr.c_str());
996     if (!cJSON_IsObject(parser.json_)) {
997         MMI_HILOGE("Parser.json_ is not object");
998         return false;
999     }
1000 
1001     bool isParseShortKeys = ParseShortcutKeys(parser, shortcutKeys_, businessIds_);
1002     bool isParseSequences = ParseSequences(parser, sequences_);
1003     bool isParseTwoFingerGesture = ParseTwoFingerGesture(parser, twoFingerGesture_);
1004     bool isParseSingleKnuckleGesture = IsParseKnuckleGesture(parser, SINGLE_KNUCKLE_ABILITY, singleKnuckleGesture_);
1005     bool isParseDoubleKnuckleGesture = IsParseKnuckleGesture(parser, DOUBLE_KNUCKLE_ABILITY, doubleKnuckleGesture_);
1006     bool isParseMultiFingersTap = ParseMultiFingersTap(parser, TOUCHPAD_TRIP_TAP_ABILITY, threeFingersTap_);
1007     bool isParseRepeatKeys = ParseRepeatKeys(parser, repeatKeys_, repeatKeyMaxTimes_);
1008     knuckleSwitch_.statusConfig = SETTING_KNUCKLE_SWITCH;
1009     if (!isParseShortKeys && !isParseSequences && !isParseTwoFingerGesture && !isParseSingleKnuckleGesture &&
1010         !isParseDoubleKnuckleGesture && !isParseMultiFingersTap && !isParseRepeatKeys) {
1011         MMI_HILOGE("Parse configFile failed");
1012         return false;
1013     }
1014 
1015     Print();
1016     PrintSeq();
1017     return true;
1018 }
1019 
ParseExcludeJson(const std::string &configFile)1020 bool KeyCommandHandler::ParseExcludeJson(const std::string &configFile)
1021 {
1022     CALL_DEBUG_ENTER;
1023     std::string jsonStr = ReadJsonFile(configFile);
1024     if (jsonStr.empty()) {
1025         MMI_HILOGE("Read excludeKey configFile failed");
1026         return false;
1027     }
1028     JsonParser parser;
1029     parser.json_ = cJSON_Parse(jsonStr.c_str());
1030     if (!cJSON_IsObject(parser.json_)) {
1031         MMI_HILOGE("Parser.json_ of excludeKey is not object");
1032         return false;
1033     }
1034     bool isParseExcludeKeys = ParseExcludeKeys(parser, excludeKeys_);
1035     if (!isParseExcludeKeys) {
1036         MMI_HILOGE("Parse ExcludeKeys configFile failed");
1037         return false;
1038     }
1039     PrintExcludeKeys();
1040     return true;
1041 }
1042 
Print()1043 void KeyCommandHandler::Print()
1044 {
1045     MMI_HILOGI("ShortcutKey count:%{public}zu", shortcutKeys_.size());
1046     int32_t row = 0;
1047     for (const auto &item : shortcutKeys_) {
1048         MMI_HILOGI("row:%{public}d", row++);
1049         auto &shortcutKey = item.second;
1050         for (const auto &prekey : shortcutKey.preKeys) {
1051             MMI_HILOGI("preKey:%d", prekey);
1052         }
1053         MMI_HILOGI("finalKey:%d, keyDownDuration:%{public}d, triggerType:%{public}d,"
1054                    " bundleName:%{public}s, abilityName:%{public}s", shortcutKey.finalKey,
1055                    shortcutKey.keyDownDuration, shortcutKey.triggerType,
1056                    shortcutKey.ability.bundleName.c_str(), shortcutKey.ability.abilityName.c_str());
1057     }
1058 }
1059 
PrintExcludeKeys()1060 void KeyCommandHandler::PrintExcludeKeys()
1061 {
1062     size_t keysSize = excludeKeys_.size();
1063     for (size_t i = 0; i < keysSize; i++) {
1064         MMI_HILOGD("keyCode:%d, keyAction:%{public}d, delay:%{public}" PRId64,
1065                    excludeKeys_[i].keyCode, excludeKeys_[i].keyAction, excludeKeys_[i].delay);
1066     }
1067 }
1068 
PrintSeq()1069 void KeyCommandHandler::PrintSeq()
1070 {
1071     MMI_HILOGI("Sequences count:%{public}zu", sequences_.size());
1072     int32_t row = 0;
1073     for (const auto &item : sequences_) {
1074         MMI_HILOGI("row:%{public}d", row++);
1075         for (const auto& sequenceKey : item.sequenceKeys) {
1076             MMI_HILOGI("keyCode:%d, keyAction:%{public}d, delay:%{public}" PRId64,
1077                        sequenceKey.keyCode, sequenceKey.keyAction, sequenceKey.delay);
1078         }
1079         MMI_HILOGI("bundleName:%{public}s, abilityName:%{public}s",
1080                    item.ability.bundleName.c_str(), item.ability.abilityName.c_str());
1081     }
1082 }
1083 
IsExcludeKey(const std::shared_ptr<KeyEvent> key)1084 bool KeyCommandHandler::IsExcludeKey(const std::shared_ptr<KeyEvent> key)
1085 {
1086     size_t keysSize = excludeKeys_.size();
1087     for (size_t i = 0; i < keysSize; i++) {
1088         if (key->GetKeyCode() == excludeKeys_[i].keyCode) {
1089             if (key->GetKeyAction() == excludeKeys_[i].keyAction) {
1090                 return true;
1091             }
1092         }
1093     }
1094     return false;
1095 }
1096 
IsEnableCombineKey(const std::shared_ptr<KeyEvent> key)1097 bool KeyCommandHandler::IsEnableCombineKey(const std::shared_ptr<KeyEvent> key)
1098 {
1099     CHKPF(key);
1100     if (enableCombineKey_) {
1101         return true;
1102     }
1103 
1104     if (!isParseExcludeConfig_) {
1105         if (!ParseExcludeConfig()) {
1106             MMI_HILOGE("Parse Exclude configFile failed");
1107             return false;
1108         }
1109         isParseExcludeConfig_ = true;
1110     }
1111 
1112     if (IsExcludeKey(key)) {
1113         if (EventLogHelper::IsBetaVersion() && !key->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) {
1114             MMI_HILOGD("ExcludekeyCode:%{private}d,ExcludekeyAction:%{public}d",
1115                 key->GetKeyCode(), key->GetKeyAction());
1116         } else {
1117             MMI_HILOGD("ExcludekeyCode:%d, ExcludekeyAction:%{public}d", key->GetKeyCode(), key->GetKeyAction());
1118         }
1119         auto items = key->GetKeyItems();
1120         MMI_HILOGD("KeyItemsSize:%{public}zu", items.size());
1121         if (items.size() != 1) {
1122             return enableCombineKey_;
1123         }
1124         return true;
1125     }
1126     if (key->GetKeyCode() == KeyEvent::KEYCODE_L) {
1127         for (const auto &item : key->GetKeyItems()) {
1128             int32_t keyCode = item.GetKeyCode();
1129             if (keyCode != KeyEvent::KEYCODE_L && keyCode != KeyEvent::KEYCODE_META_LEFT &&
1130                 keyCode != KeyEvent::KEYCODE_META_RIGHT) {
1131                 return enableCombineKey_;
1132             }
1133         }
1134         return true;
1135     }
1136     return enableCombineKey_;
1137 }
1138 
EnableCombineKey(bool enable)1139 int32_t KeyCommandHandler::EnableCombineKey(bool enable)
1140 {
1141     enableCombineKey_ = enable;
1142     MMI_HILOGI("Enable combineKey is successful in keyCommand handler, enable:%{public}d", enable);
1143     return RET_OK;
1144 }
1145 
ParseStatusConfigObserver()1146 void KeyCommandHandler::ParseStatusConfigObserver()
1147 {
1148     CALL_DEBUG_ENTER;
1149     for (Sequence& item : sequences_) {
1150         if (item.statusConfig.empty()) {
1151             continue;
1152         }
1153         CreateStatusConfigObserver<Sequence>(item);
1154     }
1155 
1156     for (auto& item : shortcutKeys_) {
1157         ShortcutKey &shortcutKey = item.second;
1158         if (shortcutKey.statusConfig.empty()) {
1159             continue;
1160         }
1161         CreateStatusConfigObserver<ShortcutKey>(shortcutKey);
1162     }
1163 }
1164 
1165 template <class T>
CreateStatusConfigObserver(T& item)1166 void KeyCommandHandler::CreateStatusConfigObserver(T& item)
1167 {
1168     CALL_DEBUG_ENTER;
1169     SettingObserver::UpdateFunc updateFunc = [&item](const std::string& key) {
1170         bool statusValue = true;
1171         auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
1172             .GetBoolValue(key, statusValue);
1173         if (ret != RET_OK) {
1174             MMI_HILOGE("Get value from setting date fail");
1175             return;
1176         }
1177         MMI_HILOGI("Config changed key:%s, value:%{public}d", key.c_str(), statusValue);
1178         item.statusConfigValue = statusValue;
1179     };
1180     sptr<SettingObserver> statusObserver = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
1181         .CreateObserver(item.statusConfig, updateFunc);
1182     ErrCode ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).RegisterObserver(statusObserver);
1183     if (ret != ERR_OK) {
1184         MMI_HILOGE("Register setting observer failed, ret:%{public}d", ret);
1185         statusObserver = nullptr;
1186     }
1187     bool configVlaue = true;
1188     ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
1189         .GetBoolValue(item.statusConfig, configVlaue);
1190     if (ret != RET_OK) {
1191         MMI_HILOGE("Get value from setting date fail");
1192         return;
1193     }
1194     MMI_HILOGI("Get value success key:%s, value:%{public}d", item.statusConfig.c_str(), configVlaue);
1195     item.statusConfigValue = configVlaue;
1196 }
1197 
CreateKeyEvent(int32_t keyCode, int32_t keyAction, bool isPressed)1198 std::shared_ptr<KeyEvent> KeyCommandHandler::CreateKeyEvent(int32_t keyCode, int32_t keyAction, bool isPressed)
1199 {
1200     CALL_DEBUG_ENTER;
1201     std::shared_ptr<KeyEvent> keyEvent = KeyEvent::Create();
1202     CHKPP(keyEvent);
1203     KeyEvent::KeyItem item;
1204     item.SetKeyCode(keyCode);
1205     item.SetPressed(isPressed);
1206     keyEvent->SetKeyCode(keyCode);
1207     keyEvent->SetKeyAction(keyAction);
1208     keyEvent->AddPressedKeyItems(item);
1209     return keyEvent;
1210 }
1211 
PreHandleEvent(const std::shared_ptr<KeyEvent> key)1212 bool KeyCommandHandler::PreHandleEvent(const std::shared_ptr<KeyEvent> key)
1213 {
1214     CHKPF(key);
1215     if (EventLogHelper::IsBetaVersion() && !key->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) {
1216         MMI_HILOGD("KeyEvent occured. keyCode:%{private}d, keyAction:%{public}d",
1217             key->GetKeyCode(), key->GetKeyAction());
1218     } else {
1219         MMI_HILOGD("KeyEvent occured. keyCode:%d, keyAction:%{public}d", key->GetKeyCode(), key->GetKeyAction());
1220     }
1221     if (!IsEnableCombineKey(key)) {
1222         MMI_HILOGI("Combine key is taken over in key command");
1223         return false;
1224     }
1225     if (!isParseConfig_) {
1226         if (!ParseConfig()) {
1227             MMI_HILOGE("Parse configFile failed");
1228             return false;
1229         }
1230         isParseConfig_ = true;
1231     }
1232     if (!isParseMaxCount_) {
1233         ParseRepeatKeyMaxCount();
1234         isParseMaxCount_ = true;
1235     }
1236     if (key->GetKeyCode() == KeyEvent::KEYCODE_VOLUME_DOWN || key->GetKeyCode() == KeyEvent::KEYCODE_VOLUME_UP) {
1237         lastVolumeDownActionTime_ = key->GetActionTime();
1238     }
1239     return true;
1240 }
1241 
HandleEvent(const std::shared_ptr<KeyEvent> key)1242 bool KeyCommandHandler::HandleEvent(const std::shared_ptr<KeyEvent> key)
1243 {
1244     CALL_DEBUG_ENTER;
1245     CHKPF(key);
1246     if (!PreHandleEvent(key)) {
1247         return false;
1248     }
1249 
1250     if (STYLUS_HANDLER->HandleStylusKey(key)) {
1251         return true;
1252     }
1253 
1254     bool isHandled = HandleShortKeys(key);
1255     if (key->GetKeyCode() == KeyEvent::KEYCODE_POWER && isFreezePowerKey_) {
1256         MMI_HILOGI("Freeze power key");
1257         return true;
1258     }
1259     isHandled = HandleSequences(key) || isHandled;
1260     if (isHandled) {
1261         if (isKeyCancel_) {
1262             isHandleSequence_ = false;
1263             isKeyCancel_ = false;
1264         } else {
1265             isHandleSequence_ = true;
1266         }
1267         return true;
1268     }
1269     if (key->GetKeyCode() == KeyEvent::KEYCODE_POWER) {
1270         MMI_HILOGI("Handle power key DownStart:%{public}d", isDownStart_);
1271     }
1272     if (!isDownStart_) {
1273         HandleRepeatKeys(key);
1274         return false;
1275     } else {
1276         if (HandleRepeatKeys(key)) {
1277             MMI_HILOGI("Handle power key lifting event");
1278             return true;
1279         }
1280     }
1281     count_ = 0;
1282     repeatKeyCountMap_.clear();
1283     isDownStart_ = false;
1284     return false;
1285 }
1286 
InitKeyObserver()1287 void KeyCommandHandler::InitKeyObserver()
1288 {
1289     if (!isParseStatusConfig_) {
1290         ParseStatusConfigObserver();
1291         isParseStatusConfig_ = true;
1292     }
1293     if (!isKnuckleSwitchConfig_) {
1294         CreateStatusConfigObserver(knuckleSwitch_);
1295         isKnuckleSwitchConfig_ = true;
1296     }
1297 }
1298 
1299 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
OnHandleEvent(const std::shared_ptr<KeyEvent> key)1300 bool KeyCommandHandler::OnHandleEvent(const std::shared_ptr<KeyEvent> key)
1301 {
1302     CALL_DEBUG_ENTER;
1303     CHKPF(key);
1304     HandlePointerVisibleKeys(key);
1305     if (HandleEvent(key)) {
1306         return true;
1307     }
1308 
1309     if (specialKeys_.find(key->GetKeyCode()) != specialKeys_.end()) {
1310         HandleSpecialKeys(key->GetKeyCode(), key->GetAction());
1311         return true;
1312     }
1313 
1314     if (IsSpecialType(key->GetKeyCode(), SpecialType::SUBSCRIBER_BEFORE_DELAY)) {
1315         auto tmpKey = KeyEvent::Clone(key);
1316         int32_t timerId = TimerMgr->AddTimer(SPECIAL_KEY_DOWN_DELAY, 1, [this, tmpKey] () {
1317             MMI_HILOGD("Timer callback");
1318             auto it = specialTimers_.find(tmpKey->GetKeyCode());
1319             if (it != specialTimers_.end() && !it->second.empty()) {
1320                 it->second.pop_front();
1321             }
1322             InputHandler->GetSubscriberHandler()->HandleKeyEvent(tmpKey);
1323         });
1324         if (timerId < 0) {
1325             MMI_HILOGE("Add timer failed");
1326             return false;
1327         }
1328 
1329         auto it = specialTimers_.find(key->GetKeyCode());
1330         if (it == specialTimers_.end()) {
1331             std::list<int32_t> timerIds;
1332             timerIds.push_back(timerId);
1333             auto it = specialTimers_.emplace(key->GetKeyCode(), timerIds);
1334             if (!it.second) {
1335                 MMI_HILOGE("Keycode duplicated");
1336                 return false;
1337             }
1338         } else {
1339             it->second.push_back(timerId);
1340         }
1341         MMI_HILOGD("Add timer success");
1342         return true;
1343     }
1344     return false;
1345 }
1346 #endif // OHOS_BUILD_ENABLE_KEYBOARD
1347 
1348 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
OnHandleEvent(const std::shared_ptr<PointerEvent> pointer)1349 bool KeyCommandHandler::OnHandleEvent(const std::shared_ptr<PointerEvent> pointer)
1350 {
1351     CALL_DEBUG_ENTER;
1352     CHKPF(pointer);
1353     STYLUS_HANDLER->SetLastEventState(false);
1354     if (!isParseConfig_) {
1355         if (!ParseConfig()) {
1356             MMI_HILOGE("Parse configFile failed");
1357             return false;
1358         }
1359         isParseConfig_ = true;
1360     }
1361     return HandleMulFingersTap(pointer);
1362 }
1363 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
1364 
HandleRepeatKeys(const std::shared_ptr<KeyEvent> keyEvent)1365 bool KeyCommandHandler::HandleRepeatKeys(const std::shared_ptr<KeyEvent> keyEvent)
1366 {
1367     CALL_DEBUG_ENTER;
1368     CHKPF(keyEvent);
1369     if (repeatKeys_.empty()) {
1370         MMI_HILOGD("No sequences configuration data");
1371         return false;
1372     }
1373 
1374     bool isLaunched = false;
1375     bool waitRepeatKey = false;
1376 
1377     for (RepeatKey& item : repeatKeys_) {
1378         if (CheckSpecialRepeatKey(item, keyEvent)) {
1379             MMI_HILOGI("Skip repeatKey");
1380             return false;
1381         }
1382         if (HandleKeyUpCancel(item, keyEvent)) {
1383             MMI_HILOGI("Cancel repeatKey");
1384             return false;
1385         }
1386         if (HandleRepeatKeyCount(item, keyEvent)) {
1387             break;
1388         }
1389     }
1390 
1391     for (RepeatKey& item : repeatKeys_) {
1392         bool isRepeatKey = HandleRepeatKey(item, isLaunched, keyEvent);
1393         if (isRepeatKey) {
1394             waitRepeatKey = true;
1395         }
1396     }
1397     MMI_HILOGI("Handle repeat key, isLaunched:%{public}d, waitRepeatKey:%{public}d",
1398         isLaunched, waitRepeatKey);
1399     return isLaunched || waitRepeatKey;
1400 }
1401 
HandleRepeatKeyOwnCount(const RepeatKey &item)1402 void KeyCommandHandler::HandleRepeatKeyOwnCount(const RepeatKey &item)
1403 {
1404     if (item.ability.bundleName == SOS_BUNDLE_NAME) {
1405         if (repeatKeyCountMap_[item.ability.bundleName] == 1) {
1406             if (downActionTime_ - lastVolumeDownActionTime_ > SOS_INTERVAL_TIMES) {
1407                 repeatKeyCountMap_[item.ability.bundleName]++;
1408             }
1409         } else if (downActionTime_ - lastDownActionTime_ < item.delay) {
1410             repeatKeyCountMap_[item.ability.bundleName]++;
1411         }
1412     } else if (downActionTime_ - upActionTime_ < item.delay) {
1413         repeatKeyCountMap_[item.ability.bundleName]++;
1414     }
1415 }
1416 
HandleRepeatKey(const RepeatKey &item, bool &isLaunched, const std::shared_ptr<KeyEvent> keyEvent)1417 bool KeyCommandHandler::HandleRepeatKey(const RepeatKey &item, bool &isLaunched,
1418     const std::shared_ptr<KeyEvent> keyEvent)
1419 {
1420     CALL_DEBUG_ENTER;
1421     CHKPF(keyEvent);
1422 
1423     if (keyEvent->GetKeyCode() != item.keyCode) {
1424         return false;
1425     }
1426     if (keyEvent->GetKeyAction() != KeyEvent::KEY_ACTION_DOWN ||
1427         (count_ > maxCount_ && keyEvent->GetKeyCode() == KeyEvent::KEYCODE_POWER)) {
1428         return true;
1429     }
1430     auto it = repeatKeyCountMap_.find(item.ability.bundleName);
1431     if (it == repeatKeyCountMap_.end()) {
1432         repeatKeyCountMap_.emplace(item.ability.bundleName, 1);
1433         lastDownActionTime_ = downActionTime_;
1434         return true;
1435     }
1436     HandleRepeatKeyOwnCount(item);
1437     lastDownActionTime_ = downActionTime_;
1438     if (repeatKeyCountMap_[item.ability.bundleName] == item.times) {
1439         if (!item.statusConfig.empty()) {
1440             bool statusValue = true;
1441             auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
1442                 .GetBoolValue(item.statusConfig, statusValue);
1443             if (ret != RET_OK) {
1444                 MMI_HILOGE("Get value from setting data fail");
1445                 return false;
1446             }
1447             if (!statusValue) {
1448                 MMI_HILOGE("Get value from setting data, result is false");
1449                 return false;
1450             }
1451         }
1452         if (repeatKeyMaxTimes_.find(item.keyCode) != repeatKeyMaxTimes_.end()) {
1453             launchAbilityCount_ = count_;
1454             if (item.times < repeatKeyMaxTimes_[item.keyCode]) {
1455                 return HandleRepeatKeyAbility(item, isLaunched, keyEvent, false);
1456             }
1457             return HandleRepeatKeyAbility(item, isLaunched, keyEvent, true);
1458         }
1459     }
1460     if (count_ > item.times && repeatKeyMaxTimes_.find(item.keyCode) != repeatKeyMaxTimes_.end() &&
1461         repeatKeyTimerIds_.find(item.ability.bundleName) != repeatKeyTimerIds_.end()) {
1462         if (count_ < repeatKeyMaxTimes_[item.keyCode] && repeatKeyTimerIds_[item.ability.bundleName] >= 0) {
1463             TimerMgr->RemoveTimer(repeatKeyTimerIds_[item.ability.bundleName]);
1464             repeatKeyTimerIds_.erase(item.ability.bundleName);
1465             return true;
1466         }
1467     }
1468     return true;
1469 }
1470 
HandleRepeatKeyAbility(const RepeatKey &item, bool &isLaunched, const std::shared_ptr<KeyEvent> keyEvent, bool isMaxTimes)1471 bool KeyCommandHandler::HandleRepeatKeyAbility(const RepeatKey &item, bool &isLaunched,
1472     const std::shared_ptr<KeyEvent> keyEvent, bool isMaxTimes)
1473 {
1474     if (!isMaxTimes) {
1475         int64_t delaytime = intervalTime_ - (downActionTime_ - upActionTime_);
1476         int32_t timerId = TimerMgr->AddTimer(
1477             delaytime / SECONDS_SYSTEM, 1, [this, item, &isLaunched, keyEvent] () {
1478             LaunchRepeatKeyAbility(item, isLaunched, keyEvent);
1479             auto it = repeatKeyTimerIds_.find(item.ability.bundleName);
1480             if (it != repeatKeyTimerIds_.end()) {
1481                 repeatKeyTimerIds_.erase(it);
1482             }
1483         });
1484         if (timerId < 0) {
1485             return false;
1486         }
1487         if (repeatTimerId_ >= 0) {
1488             TimerMgr->RemoveTimer(repeatTimerId_);
1489             repeatTimerId_ = DEFAULT_VALUE;
1490         }
1491         if (repeatKeyTimerIds_.find(item.ability.bundleName) == repeatKeyTimerIds_.end()) {
1492             repeatKeyTimerIds_.emplace(item.ability.bundleName, timerId);
1493             return true;
1494         }
1495         repeatKeyTimerIds_[item.ability.bundleName] = timerId;
1496         return true;
1497     }
1498     LaunchRepeatKeyAbility(item, isLaunched, keyEvent);
1499     return true;
1500 }
1501 
LaunchRepeatKeyAbility(const RepeatKey &item, bool &isLaunched, const std::shared_ptr<KeyEvent> keyEvent)1502 void KeyCommandHandler::LaunchRepeatKeyAbility(const RepeatKey &item, bool &isLaunched,
1503     const std::shared_ptr<KeyEvent> keyEvent)
1504 {
1505     BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_REPEAT_KEY, item.ability.bundleName);
1506     LaunchAbility(item.ability);
1507     BytraceAdapter::StopLaunchAbility();
1508     repeatKeyCountMap_.clear();
1509     isLaunched = true;
1510     if (InputHandler->GetSubscriberHandler() != nullptr) {
1511         auto keyEventCancel = std::make_shared<KeyEvent>(*keyEvent);
1512         keyEventCancel->SetKeyAction(KeyEvent::KEY_ACTION_CANCEL);
1513         InputHandler->GetSubscriberHandler()->HandleKeyEvent(keyEventCancel);
1514     }
1515 }
1516 
SetIsFreezePowerKey(const std::string pageName)1517 int32_t KeyCommandHandler::SetIsFreezePowerKey(const std::string pageName)
1518 {
1519     std::lock_guard<std::mutex> lock(mutex_);
1520     if (pageName != "SosCountdown") {
1521         isFreezePowerKey_ = false;
1522         return RET_OK;
1523     }
1524     isFreezePowerKey_ = true;
1525     count_ = 0;
1526     launchAbilityCount_ = 0;
1527     repeatKeyCountMap_.clear();
1528     if (sosDelayTimerId_ >= 0) {
1529         TimerMgr->RemoveTimer(sosDelayTimerId_);
1530         sosDelayTimerId_ = DEFAULT_VALUE;
1531     }
1532     int32_t timerId = TimerMgr->AddTimer(
1533         SOS_COUNT_DOWN_TIMES / SECONDS_SYSTEM, 1, [this] () {
1534         MMI_HILOGW("Timeout, restore the power button");
1535         isFreezePowerKey_ = false;
1536     });
1537     if (timerId < 0) {
1538         MMI_HILOGE("Add timer failed");
1539         return RET_ERR;
1540     }
1541     return RET_OK;
1542 }
1543 
HandleKeyUpCancel(const RepeatKey &item, const std::shared_ptr<KeyEvent> keyEvent)1544 bool KeyCommandHandler::HandleKeyUpCancel(const RepeatKey &item, const std::shared_ptr<KeyEvent> keyEvent)
1545 {
1546     CALL_DEBUG_ENTER;
1547     CHKPF(keyEvent);
1548     if (keyEvent->GetKeyCode() == item.keyCode && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_CANCEL) {
1549         isKeyCancel_ = true;
1550         isDownStart_ = false;
1551         return true;
1552     }
1553     return false;
1554 }
1555 
HandleRepeatKeyCount(const RepeatKey &item, const std::shared_ptr<KeyEvent> keyEvent)1556 bool KeyCommandHandler::HandleRepeatKeyCount(const RepeatKey &item, const std::shared_ptr<KeyEvent> keyEvent)
1557 {
1558     CALL_DEBUG_ENTER;
1559     CHKPF(keyEvent);
1560 
1561     if (keyEvent->GetKeyCode() == item.keyCode && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) {
1562         upActionTime_ = keyEvent->GetActionTime();
1563         repeatTimerId_ = TimerMgr->AddTimer(intervalTime_ / SECONDS_SYSTEM, 1, [this] () {
1564             SendKeyEvent();
1565         });
1566         if (repeatTimerId_ < 0) {
1567             return false;
1568         }
1569         return true;
1570     }
1571 
1572     if (keyEvent->GetKeyCode() == item.keyCode && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_DOWN) {
1573         if (repeatKey_.keyCode != item.keyCode) {
1574             count_ = 1;
1575             repeatKey_.keyCode = item.keyCode;
1576         } else {
1577             count_++;
1578         }
1579         isDownStart_ = true;
1580 
1581         downActionTime_ = keyEvent->GetActionTime();
1582         if ((downActionTime_ - upActionTime_) < intervalTime_) {
1583             if (repeatTimerId_ >= 0) {
1584                 TimerMgr->RemoveTimer(repeatTimerId_);
1585                 repeatTimerId_ = -1;
1586             }
1587         }
1588         return true;
1589     }
1590     return false;
1591 }
1592 
SendKeyEvent()1593 void KeyCommandHandler::SendKeyEvent()
1594 {
1595     CALL_DEBUG_ENTER;
1596     if (!isHandleSequence_) {
1597         for (int32_t i = launchAbilityCount_; i < count_; i++) {
1598             int32_t keycode = repeatKey_.keyCode;
1599             if (IsSpecialType(keycode, SpecialType::KEY_DOWN_ACTION)) {
1600                 HandleSpecialKeys(keycode, KeyEvent::KEY_ACTION_UP);
1601             }
1602             if (count_ == repeatKeyMaxTimes_[keycode] - 1 && keycode == KeyEvent::KEYCODE_POWER) {
1603                 auto keyEventCancel = CreateKeyEvent(keycode, KeyEvent::KEY_ACTION_CANCEL, false);
1604                 CHKPV(keyEventCancel);
1605                 InputHandler->GetSubscriberHandler()->HandleKeyEvent(keyEventCancel);
1606                 continue;
1607             }
1608             if (i != 0) {
1609                 auto keyEventDown = CreateKeyEvent(keycode, KeyEvent::KEY_ACTION_DOWN, true);
1610                 CHKPV(keyEventDown);
1611                 InputHandler->GetSubscriberHandler()->HandleKeyEvent(keyEventDown);
1612             }
1613 
1614             auto keyEventUp = CreateKeyEvent(keycode, KeyEvent::KEY_ACTION_UP, false);
1615             CHKPV(keyEventUp);
1616             InputHandler->GetSubscriberHandler()->HandleKeyEvent(keyEventUp);
1617         }
1618     }
1619     count_ = 0;
1620     repeatKeyCountMap_.clear();
1621     isDownStart_ = false;
1622     isHandleSequence_ = false;
1623     launchAbilityCount_ = 0;
1624 }
1625 
HandleShortKeys(const std::shared_ptr<KeyEvent> keyEvent)1626 bool KeyCommandHandler::HandleShortKeys(const std::shared_ptr<KeyEvent> keyEvent)
1627 {
1628     CALL_DEBUG_ENTER;
1629     CHKPF(keyEvent);
1630     if (shortcutKeys_.empty()) {
1631         MMI_HILOGD("No shortkeys configuration data");
1632         return false;
1633     }
1634     if (IsKeyMatch(lastMatchedKey_, keyEvent)) {
1635         MMI_HILOGD("The same key is waiting timeout, skip");
1636         return true;
1637     }
1638     if (currentLaunchAbilityKey_.timerId >= 0 && IsKeyMatch(currentLaunchAbilityKey_, keyEvent)) {
1639         if (EventLogHelper::IsBetaVersion() && !keyEvent->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) {
1640             MMI_HILOGD("Repeat, current key %{public}d has launched ability", currentLaunchAbilityKey_.finalKey);
1641         } else {
1642             MMI_HILOGD("Repeat, current key %d has launched ability", currentLaunchAbilityKey_.finalKey);
1643         }
1644         return true;
1645     }
1646     DfxHisysevent::GetComboStartTime();
1647     if (lastMatchedKey_.timerId >= 0) {
1648         MMI_HILOGD("Remove timer:%{public}d", lastMatchedKey_.timerId);
1649         TimerMgr->RemoveTimer(lastMatchedKey_.timerId);
1650     }
1651     ResetLastMatchedKey();
1652     if (MatchShortcutKeys(keyEvent)) {
1653         return true;
1654     }
1655     return HandleConsumedKeyEvent(keyEvent);
1656 }
1657 
MatchShortcutKeys(const std::shared_ptr<KeyEvent> keyEvent)1658 bool KeyCommandHandler::MatchShortcutKeys(const std::shared_ptr<KeyEvent> keyEvent)
1659 {
1660 #ifdef SHORTCUT_KEY_RULES_ENABLED
1661     if ((keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) &&
1662         KEY_SHORTCUT_MGR->HaveShortcutConsumed(keyEvent)) {
1663         return false;
1664     }
1665 #endif // SHORTCUT_KEY_RULES_ENABLED
1666     bool result = false;
1667     std::vector<ShortcutKey> upAbilities;
1668 
1669     for (auto &item : shortcutKeys_) {
1670         result = MatchShortcutKey(keyEvent, item.second, upAbilities) || result;
1671     }
1672     if (!upAbilities.empty()) {
1673         std::sort(upAbilities.begin(), upAbilities.end(),
1674             [](const ShortcutKey &lShortcutKey, const ShortcutKey &rShortcutKey) -> bool {
1675             return lShortcutKey.keyDownDuration > rShortcutKey.keyDownDuration;
1676         });
1677         ShortcutKey tmpShorteKey = upAbilities.front();
1678         MMI_HILOGI("Start launch ability immediately");
1679 #ifdef SHORTCUT_KEY_RULES_ENABLED
1680         KEY_SHORTCUT_MGR->MarkShortcutConsumed(tmpShorteKey);
1681 #endif // SHORTCUT_KEY_RULES_ENABLED
1682         BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_SHORTKEY, tmpShorteKey.ability.bundleName);
1683         LaunchAbility(tmpShorteKey);
1684         BytraceAdapter::StopLaunchAbility();
1685     }
1686     if (result) {
1687         if (currentLaunchAbilityKey_.finalKey == keyEvent->GetKeyCode()
1688             && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) {
1689             ResetCurrentLaunchAbilityKey();
1690         }
1691     }
1692     return result;
1693 }
1694 
MatchShortcutKey(std::shared_ptr<KeyEvent> keyEvent, ShortcutKey &shortcutKey, std::vector<ShortcutKey> &upAbilities)1695 bool KeyCommandHandler::MatchShortcutKey(std::shared_ptr<KeyEvent> keyEvent,
1696     ShortcutKey &shortcutKey, std::vector<ShortcutKey> &upAbilities)
1697 {
1698     if (!shortcutKey.statusConfigValue) {
1699         return false;
1700     }
1701     if (!IsKeyMatch(shortcutKey, keyEvent)) {
1702         MMI_HILOGD("Not key matched, next");
1703         return false;
1704     }
1705     int32_t delay = GetKeyDownDurationFromXml(shortcutKey.businessId);
1706     if (delay >= MIN_SHORT_KEY_DOWN_DURATION && delay <= MAX_SHORT_KEY_DOWN_DURATION) {
1707         MMI_HILOGD("User defined new short key down duration:%{public}d", delay);
1708         shortcutKey.keyDownDuration = delay;
1709     }
1710     shortcutKey.Print();
1711 
1712     if (shortcutKey.triggerType == KeyEvent::KEY_ACTION_DOWN) {
1713         return HandleKeyDown(shortcutKey);
1714     } else if (shortcutKey.triggerType == KeyEvent::KEY_ACTION_UP) {
1715         bool handleResult = HandleKeyUp(keyEvent, shortcutKey);
1716         if (handleResult && shortcutKey.keyDownDuration > 0) {
1717             upAbilities.push_back(shortcutKey);
1718         }
1719         return handleResult;
1720     } else {
1721         return HandleKeyCancel(shortcutKey);
1722     }
1723 }
1724 
HandleConsumedKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)1725 bool KeyCommandHandler::HandleConsumedKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
1726 {
1727     CALL_DEBUG_ENTER;
1728     CHKPF(keyEvent);
1729     if (currentLaunchAbilityKey_.finalKey == keyEvent->GetKeyCode()
1730         && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) {
1731         MMI_HILOGI("Handle consumed key event, cancel opration");
1732         ResetCurrentLaunchAbilityKey();
1733         auto keyEventCancel = std::make_shared<KeyEvent>(*keyEvent);
1734         keyEventCancel->SetKeyAction(KeyEvent::KEY_ACTION_CANCEL);
1735         auto inputEventNormalizeHandler = InputHandler->GetEventNormalizeHandler();
1736         CHKPF(inputEventNormalizeHandler);
1737         inputEventNormalizeHandler->HandleKeyEvent(keyEventCancel);
1738         return true;
1739     }
1740     return false;
1741 }
1742 
IsRepeatKeyEvent(const SequenceKey &sequenceKey)1743 bool KeyCommandHandler::IsRepeatKeyEvent(const SequenceKey &sequenceKey)
1744 {
1745     for (size_t i = keys_.size(); i > 0; --i) {
1746         if (keys_[i-1].keyCode == sequenceKey.keyCode) {
1747             if (keys_[i-1].keyAction == sequenceKey.keyAction) {
1748                 MMI_HILOGI("Is repeat key, keyCode:%d", sequenceKey.keyCode);
1749                 return true;
1750             }
1751             MMI_HILOGI("Is not repeat key");
1752             return false;
1753         }
1754     }
1755     return false;
1756 }
1757 
IsActiveSequenceRepeating(std::shared_ptr<KeyEvent> keyEvent) const1758 bool KeyCommandHandler::IsActiveSequenceRepeating(std::shared_ptr<KeyEvent> keyEvent) const
1759 {
1760     return (sequenceOccurred_ && !keys_.empty() &&
1761             (keys_.back().keyCode == keyEvent->GetKeyCode()) &&
1762             (keys_.back().keyAction == KeyEvent::KEY_ACTION_DOWN) &&
1763             (keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_DOWN));
1764 }
1765 
MarkActiveSequence(bool active)1766 void KeyCommandHandler::MarkActiveSequence(bool active)
1767 {
1768     sequenceOccurred_ = active;
1769 }
1770 
HandleSequences(const std::shared_ptr<KeyEvent> keyEvent)1771 bool KeyCommandHandler::HandleSequences(const std::shared_ptr<KeyEvent> keyEvent)
1772 {
1773     CALL_DEBUG_ENTER;
1774     CHKPF(keyEvent);
1775     if (IsActiveSequenceRepeating(keyEvent)) {
1776         MMI_HILOGD("Skip repeating key(%{public}d) in active sequence", keyEvent->GetKeyCode());
1777         return true;
1778     }
1779     MarkActiveSequence(false);
1780     if (matchedSequence_.timerId >= 0 && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) {
1781         MMI_HILOGI("screen locked, remove matchedSequence timer:%{public}d", matchedSequence_.timerId);
1782         TimerMgr->RemoveTimer(matchedSequence_.timerId);
1783         matchedSequence_.timerId = -1;
1784     }
1785     if (sequences_.empty()) {
1786         MMI_HILOGD("No sequences configuration data");
1787         return false;
1788     }
1789 
1790     if (!AddSequenceKey(keyEvent)) {
1791         MMI_HILOGD("Add new sequence key failed");
1792         return false;
1793     }
1794 
1795     if (filterSequences_.empty()) {
1796         filterSequences_ = sequences_;
1797     }
1798 
1799     bool isLaunchAbility = false;
1800     for (auto iter = filterSequences_.begin(); iter != filterSequences_.end();) {
1801         if (!HandleSequence((*iter), isLaunchAbility)) {
1802             filterSequences_.erase(iter);
1803             continue;
1804         }
1805         ++iter;
1806     }
1807 
1808     if (filterSequences_.empty()) {
1809         MMI_HILOGD("No sequences matched");
1810         keys_.clear();
1811         return false;
1812     }
1813 
1814     if (isLaunchAbility) {
1815         MarkActiveSequence(true);
1816         for (const auto& item : keys_) {
1817             if (IsSpecialType(item.keyCode, SpecialType::KEY_DOWN_ACTION)) {
1818                 HandleSpecialKeys(item.keyCode, item.keyAction);
1819             }
1820             InputHandler->GetSubscriberHandler()->RemoveSubscriberKeyUpTimer(item.keyCode);
1821             RemoveSubscribedTimer(item.keyCode);
1822         }
1823     }
1824     return isLaunchAbility;
1825 }
1826 
AddSequenceKey(const std::shared_ptr<KeyEvent> keyEvent)1827 bool KeyCommandHandler::AddSequenceKey(const std::shared_ptr<KeyEvent> keyEvent)
1828 {
1829     CALL_DEBUG_ENTER;
1830     CHKPF(keyEvent);
1831     SequenceKey sequenceKey;
1832     sequenceKey.keyCode = keyEvent->GetKeyCode();
1833     sequenceKey.keyAction = keyEvent->GetKeyAction();
1834     sequenceKey.actionTime = keyEvent->GetActionTime();
1835     size_t size = keys_.size();
1836     if (size > 0) {
1837         if (keys_[size - 1].actionTime > sequenceKey.actionTime) {
1838             MMI_HILOGE("The current event time is greater than the last event time");
1839             ResetSequenceKeys();
1840             return false;
1841         }
1842         if ((sequenceKey.actionTime - keys_[size - 1].actionTime) > MAX_DELAY_TIME) {
1843             MMI_HILOGD("The delay time is greater than the maximum delay time");
1844             ResetSequenceKeys();
1845         } else {
1846             if (IsRepeatKeyEvent(sequenceKey)) {
1847                 MMI_HILOGD("This is a repeat key event, don't add");
1848                 return false;
1849             }
1850             keys_[size - 1].delay = sequenceKey.actionTime - keys_[size - 1].actionTime;
1851             InterruptTimers();
1852         }
1853     }
1854     if (size > MAX_SEQUENCEKEYS_NUM) {
1855         MMI_HILOGD("The save key size more than the max size");
1856         return false;
1857     }
1858     keys_.push_back(sequenceKey);
1859     return true;
1860 }
1861 
HandleScreenLocked(Sequence& sequence, bool &isLaunchAbility)1862 bool KeyCommandHandler::HandleScreenLocked(Sequence& sequence, bool &isLaunchAbility)
1863 {
1864     sequence.timerId = TimerMgr->AddTimer(LONG_ABILITY_START_DELAY, 1, [this, sequence] () {
1865         MMI_HILOGI("Timer callback");
1866         BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_SEQUENCE, sequence.ability.bundleName);
1867         LaunchAbility(sequence);
1868         BytraceAdapter::StopLaunchAbility();
1869     });
1870     if (sequence.timerId < 0) {
1871         MMI_HILOGE("Add Timer failed");
1872         return false;
1873     }
1874     MMI_HILOGI("Add timer success");
1875     matchedSequence_ = sequence;
1876     isLaunchAbility = true;
1877     return true;
1878 }
1879 
HandleNormalSequence(Sequence& sequence, bool &isLaunchAbility)1880 bool KeyCommandHandler::HandleNormalSequence(Sequence& sequence, bool &isLaunchAbility)
1881 {
1882     if (sequence.abilityStartDelay == 0) {
1883         MMI_HILOGI("Start launch ability immediately");
1884         BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_SEQUENCE, sequence.ability.bundleName);
1885         LaunchAbility(sequence);
1886         BytraceAdapter::StopLaunchAbility();
1887         isLaunchAbility = true;
1888         return true;
1889     }
1890     sequence.timerId = TimerMgr->AddTimer(sequence.abilityStartDelay, 1, [this, sequence] () {
1891         MMI_HILOGI("Timer callback");
1892         BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_SEQUENCE, sequence.ability.bundleName);
1893         LaunchAbility(sequence);
1894         BytraceAdapter::StopLaunchAbility();
1895     });
1896     if (sequence.timerId < 0) {
1897         MMI_HILOGE("Add Timer failed");
1898         return false;
1899     }
1900     MMI_HILOGI("Add timer success");
1901     isLaunchAbility = true;
1902     return true;
1903 }
1904 
HandleMatchedSequence(Sequence& sequence, bool &isLaunchAbility)1905 bool KeyCommandHandler::HandleMatchedSequence(Sequence& sequence, bool &isLaunchAbility)
1906 {
1907     std::string screenStatus = DISPLAY_MONITOR->GetScreenStatus();
1908     bool isScreenLocked = DISPLAY_MONITOR->GetScreenLocked();
1909     MMI_HILOGI("screenStatus: %{public}s, isScreenLocked: %{public}d", screenStatus.c_str(), isScreenLocked);
1910     std::string bundleName = sequence.ability.bundleName;
1911     std::string matchName = ".screenshot";
1912     if (bundleName.find(matchName) != std::string::npos) {
1913         bundleName = bundleName.substr(bundleName.size() - matchName.size());
1914     }
1915     if (screenStatus == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
1916         if (bundleName == matchName) {
1917             MMI_HILOGI("Screen off, screenshot invalid");
1918             return false;
1919         }
1920     } else {
1921         if (bundleName == matchName && isScreenLocked) {
1922             MMI_HILOGI("Screen locked, screenshot delay 2000 milisecond");
1923             return HandleScreenLocked(sequence, isLaunchAbility);
1924         }
1925     }
1926     return HandleNormalSequence(sequence, isLaunchAbility);
1927 }
1928 
HandleSequence(Sequence &sequence, bool &isLaunchAbility)1929 bool KeyCommandHandler::HandleSequence(Sequence &sequence, bool &isLaunchAbility)
1930 {
1931     CALL_DEBUG_ENTER;
1932     size_t keysSize = keys_.size();
1933     size_t sequenceKeysSize = sequence.sequenceKeys.size();
1934     if (!sequence.statusConfigValue) {
1935         return false;
1936     }
1937     if (keysSize > sequenceKeysSize) {
1938         MMI_HILOGI("The save sequence not matching ability sequence");
1939         return false;
1940     }
1941     for (size_t i = 0; i < keysSize; ++i) {
1942         if (keys_[i] != sequence.sequenceKeys[i]) {
1943             MMI_HILOGD("The keyCode or keyAction not matching");
1944             return false;
1945         }
1946         int64_t delay = sequence.sequenceKeys[i].delay;
1947         if (((i + 1) != keysSize) && (delay != 0) && (keys_[i].delay >= delay)) {
1948             MMI_HILOGD("Delay is not matching");
1949             return false;
1950         }
1951     }
1952     if (keysSize == sequenceKeysSize) {
1953         std::ostringstream oss;
1954         oss << sequence;
1955         MMI_HILOGI("SequenceKey matched: %{public}s", oss.str().c_str());
1956         return HandleMatchedSequence(sequence, isLaunchAbility);
1957     }
1958     return true;
1959 }
1960 
HandleMulFingersTap(const std::shared_ptr<PointerEvent> pointerEvent)1961 bool KeyCommandHandler::HandleMulFingersTap(const std::shared_ptr<PointerEvent> pointerEvent)
1962 {
1963     CALL_DEBUG_ENTER;
1964     if (pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_TRIPTAP) {
1965         MMI_HILOGI("The touchpad trip tap will launch ability");
1966         BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_MULTI_FINGERS, threeFingersTap_.ability.bundleName);
1967         LaunchAbility(threeFingersTap_.ability, NO_DELAY);
1968         BytraceAdapter::StopLaunchAbility();
1969         return true;
1970     }
1971     return false;
1972 }
1973 
IsKeyMatch(const ShortcutKey &shortcutKey, const std::shared_ptr<KeyEvent> &key)1974 bool KeyCommandHandler::IsKeyMatch(const ShortcutKey &shortcutKey, const std::shared_ptr<KeyEvent> &key)
1975 {
1976     CALL_DEBUG_ENTER;
1977     CHKPF(key);
1978     if ((key->GetKeyCode() != shortcutKey.finalKey) || (shortcutKey.triggerType != key->GetKeyAction())) {
1979         return false;
1980     }
1981     if ((shortcutKey.preKeys.size() + 1) != key->GetKeyItems().size()) {
1982         return false;
1983     }
1984     for (const auto &item : key->GetKeyItems()) {
1985         int32_t keyCode = item.GetKeyCode();
1986         if (SkipFinalKey(keyCode, key)) {
1987             continue;
1988         }
1989         if (shortcutKey.preKeys.find(keyCode) == shortcutKey.preKeys.end()) {
1990             return false;
1991         }
1992     }
1993     MMI_HILOGD("Leave, key matched");
1994     return true;
1995 }
1996 
SkipFinalKey(const int32_t keyCode, const std::shared_ptr<KeyEvent> &key)1997 bool KeyCommandHandler::SkipFinalKey(const int32_t keyCode, const std::shared_ptr<KeyEvent> &key)
1998 {
1999     CHKPF(key);
2000     return keyCode == key->GetKeyCode();
2001 }
2002 
HandleKeyDown(ShortcutKey &shortcutKey)2003 bool KeyCommandHandler::HandleKeyDown(ShortcutKey &shortcutKey)
2004 {
2005     CALL_DEBUG_ENTER;
2006     if (shortcutKey.keyDownDuration == 0) {
2007         MMI_HILOGI("Start launch ability immediately");
2008 #ifdef SHORTCUT_KEY_RULES_ENABLED
2009         KEY_SHORTCUT_MGR->MarkShortcutConsumed(shortcutKey);
2010 #endif // SHORTCUT_KEY_RULES_ENABLED
2011         BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_SHORTKEY, shortcutKey.ability.bundleName);
2012         LaunchAbility(shortcutKey);
2013         BytraceAdapter::StopLaunchAbility();
2014         return true;
2015     }
2016     shortcutKey.timerId = TimerMgr->AddTimer(shortcutKey.keyDownDuration, 1, [this, shortcutKey] () {
2017         MMI_HILOGI("Timer callback");
2018 #ifdef SHORTCUT_KEY_RULES_ENABLED
2019         KEY_SHORTCUT_MGR->MarkShortcutConsumed(shortcutKey);
2020 #endif // SHORTCUT_KEY_RULES_ENABLED
2021         currentLaunchAbilityKey_ = shortcutKey;
2022         BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_SHORTKEY, shortcutKey.ability.bundleName);
2023         LaunchAbility(shortcutKey);
2024         BytraceAdapter::StopLaunchAbility();
2025     });
2026     if (shortcutKey.timerId < 0) {
2027         MMI_HILOGE("Add Timer failed");
2028         return false;
2029     }
2030     MMI_HILOGI("Add timer success");
2031     lastMatchedKey_ = shortcutKey;
2032     if (InputHandler->GetSubscriberHandler()->IsKeyEventSubscribed(shortcutKey.finalKey, shortcutKey.triggerType)) {
2033         MMI_HILOGI("current shortcutKey %d is subSubcribed", shortcutKey.finalKey);
2034         return false;
2035     }
2036     return true;
2037 }
2038 
GetKeyDownDurationFromXml(const std::string &businessId)2039 int32_t KeyCommandHandler::GetKeyDownDurationFromXml(const std::string &businessId)
2040 {
2041     CALL_DEBUG_ENTER;
2042     return PREFERENCES_MGR->GetShortKeyDuration(businessId);
2043 }
2044 
HandleKeyUp(const std::shared_ptr<KeyEvent> &keyEvent, const ShortcutKey &shortcutKey)2045 bool KeyCommandHandler::HandleKeyUp(const std::shared_ptr<KeyEvent> &keyEvent, const ShortcutKey &shortcutKey)
2046 {
2047     CALL_DEBUG_ENTER;
2048     CHKPF(keyEvent);
2049     if (shortcutKey.keyDownDuration == 0) {
2050         MMI_HILOGI("Start launch ability immediately");
2051         BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_SHORTKEY, shortcutKey.ability.bundleName);
2052         LaunchAbility(shortcutKey);
2053         BytraceAdapter::StopLaunchAbility();
2054         return true;
2055     }
2056     std::optional<KeyEvent::KeyItem> keyItem = keyEvent->GetKeyItem();
2057     if (!keyItem) {
2058         MMI_HILOGE("The keyItem is nullopt");
2059         return false;
2060     }
2061     auto upTime = keyEvent->GetActionTime();
2062     auto downTime = keyItem->GetDownTime();
2063     MMI_HILOGI("upTime:%{public}" PRId64 ",downTime:%{public}" PRId64 ",keyDownDuration:%{public}d",
2064         upTime, downTime, shortcutKey.keyDownDuration);
2065 
2066     if (upTime - downTime <= static_cast<int64_t>(shortcutKey.keyDownDuration) * FREQUENCY) {
2067         MMI_HILOGI("Skip, upTime - downTime <= duration");
2068         return false;
2069     }
2070     return true;
2071 }
2072 
HandleKeyCancel(ShortcutKey &shortcutKey)2073 bool KeyCommandHandler::HandleKeyCancel(ShortcutKey &shortcutKey)
2074 {
2075     CALL_DEBUG_ENTER;
2076     if (shortcutKey.timerId < 0) {
2077         MMI_HILOGE("Skip, timerid less than 0");
2078     }
2079     auto timerId = shortcutKey.timerId;
2080     shortcutKey.timerId = -1;
2081     TimerMgr->RemoveTimer(timerId);
2082     MMI_HILOGI("timerId:%{public}d", timerId);
2083     return false;
2084 }
2085 
LaunchAbility(const Ability &ability, int64_t delay)2086 void KeyCommandHandler::LaunchAbility(const Ability &ability, int64_t delay)
2087 {
2088     CALL_DEBUG_ENTER;
2089     if (ability.bundleName.empty()) {
2090         MMI_HILOGW("BundleName is empty");
2091         return;
2092     }
2093     AAFwk::Want want;
2094     want.SetElementName(ability.deviceId, ability.bundleName, ability.abilityName);
2095     want.SetAction(ability.action);
2096     want.SetUri(ability.uri);
2097     want.SetType(ability.type);
2098     for (const auto &entity : ability.entities) {
2099         want.AddEntity(entity);
2100     }
2101     for (const auto &item : ability.params) {
2102         want.SetParam(item.first, item.second);
2103     }
2104     DfxHisysevent::CalcComboStartTimes(delay);
2105     DfxHisysevent::ReportComboStartTimes();
2106     MMI_HILOGI("Start launch ability, bundleName:%{public}s", ability.bundleName.c_str());
2107     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
2108     if (err != ERR_OK) {
2109         MMI_HILOGE("LaunchAbility failed, bundleName:%{public}s, err:%{public}d", ability.bundleName.c_str(), err);
2110         return;
2111     }
2112     int32_t state = NapProcess::GetInstance()->GetNapClientPid();
2113     if (state == REMOVE_OBSERVER) {
2114         MMI_HILOGW("nap client status:%{public}d", state);
2115         return;
2116     }
2117     OHOS::MMI::NapProcess::NapStatusData napData;
2118     napData.pid = -1;
2119     napData.uid = -1;
2120     napData.bundleName = ability.bundleName;
2121     int32_t syncState = ACTIVE_EVENT;
2122     NapProcess::GetInstance()->AddMmiSubscribedEventData(napData, syncState);
2123     NapProcess::GetInstance()->NotifyBundleName(napData, syncState);
2124     MMI_HILOGI("End launch ability, bundleName:%{public}s", ability.bundleName.c_str());
2125     return;
2126 }
2127 
LaunchAbility(const Ability &ability)2128 void KeyCommandHandler::LaunchAbility(const Ability &ability)
2129 {
2130     CALL_DEBUG_ENTER;
2131     AAFwk::Want want;
2132     want.SetElementName(ability.deviceId, ability.bundleName, ability.abilityName);
2133     want.SetAction(ability.action);
2134     want.SetUri(ability.uri);
2135     want.SetType(ability.uri);
2136     for (const auto &entity : ability.entities) {
2137         want.AddEntity(entity);
2138     }
2139     for (const auto &item : ability.params) {
2140         want.SetParam(item.first, item.second);
2141     }
2142 
2143     MMI_HILOGI("Start launch ability, bundleName:%{public}s", ability.bundleName.c_str());
2144     if (ability.abilityType == EXTENSION_ABILITY) {
2145         ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartExtensionAbility(want, nullptr);
2146         if (err != ERR_OK) {
2147             MMI_HILOGE("LaunchAbility failed, bundleName:%{public}s, err:%{public}d", ability.bundleName.c_str(), err);
2148         }
2149     } else {
2150         ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
2151         if (err != ERR_OK) {
2152             MMI_HILOGE("LaunchAbility failed, bundleName:%{public}s, err:%{public}d", ability.bundleName.c_str(), err);
2153         }
2154         if (err == ERR_OK && ability.bundleName == SOS_BUNDLE_NAME) {
2155             isFreezePowerKey_ = true;
2156             count_ = 0;
2157             launchAbilityCount_ = 0;
2158             repeatKeyCountMap_.clear();
2159             sosDelayTimerId_ = TimerMgr->AddTimer(SOS_DELAY_TIMES / SECONDS_SYSTEM, 1, [this] () {
2160                 isFreezePowerKey_ = false;
2161                 MMI_HILOGW("Timeout, restore the power button");
2162             });
2163             if (sosDelayTimerId_ < 0) {
2164                 MMI_HILOGE("Add timer failed");
2165             }
2166         }
2167     }
2168 
2169     MMI_HILOGI("End launch ability, bundleName:%{public}s", ability.bundleName.c_str());
2170 }
2171 
LaunchAbility(const ShortcutKey &key)2172 void KeyCommandHandler::LaunchAbility(const ShortcutKey &key)
2173 {
2174     CALL_INFO_TRACE;
2175     LaunchAbility(key.ability, lastMatchedKey_.keyDownDuration);
2176     ResetLastMatchedKey();
2177 }
2178 
LaunchAbility(const Sequence &sequence)2179 void KeyCommandHandler::LaunchAbility(const Sequence &sequence)
2180 {
2181     CALL_INFO_TRACE;
2182     LaunchAbility(sequence.ability, sequence.abilityStartDelay);
2183 }
2184 
Print() const2185 void ShortcutKey::Print() const
2186 {
2187     for (const auto &prekey: preKeys) {
2188         MMI_HILOGI("Eventkey matched, preKey:%d", prekey);
2189     }
2190     MMI_HILOGI("Eventkey matched, finalKey:%d, bundleName:%{public}s",
2191         finalKey, ability.bundleName.c_str());
2192 }
2193 
RemoveSubscribedTimer(int32_t keyCode)2194 void KeyCommandHandler::RemoveSubscribedTimer(int32_t keyCode)
2195 {
2196     CALL_DEBUG_ENTER;
2197     auto iter = specialTimers_.find(keyCode);
2198     if (iter != specialTimers_.end()) {
2199         for (auto& item : iter->second) {
2200             TimerMgr->RemoveTimer(item);
2201         }
2202         specialTimers_.erase(keyCode);
2203         MMI_HILOGI("Remove timer success");
2204     }
2205 }
2206 
HandleSpecialKeys(int32_t keyCode, int32_t keyAction)2207 void KeyCommandHandler::HandleSpecialKeys(int32_t keyCode, int32_t keyAction)
2208 {
2209     CALL_DEBUG_ENTER;
2210     auto iter = specialKeys_.find(keyCode);
2211     if (keyAction == KeyEvent::KEY_ACTION_UP) {
2212         if (iter != specialKeys_.end()) {
2213             specialKeys_.erase(iter);
2214             return;
2215         }
2216     }
2217 
2218     if (keyAction == KeyEvent::KEY_ACTION_DOWN) {
2219         if (iter == specialKeys_.end()) {
2220             auto it = specialKeys_.emplace(keyCode, keyAction);
2221             if (!it.second) {
2222                 MMI_HILOGD("KeyCode duplicated");
2223                 return;
2224             }
2225         }
2226     }
2227 }
2228 
InterruptTimers()2229 void KeyCommandHandler::InterruptTimers()
2230 {
2231     for (Sequence& item : filterSequences_) {
2232         if (item.timerId >= 0) {
2233             MMI_HILOGD("The key sequence change, close the timer");
2234             TimerMgr->RemoveTimer(item.timerId);
2235             item.timerId = -1;
2236         }
2237     }
2238 }
2239 
HandlePointerVisibleKeys(const std::shared_ptr<KeyEvent> &keyEvent)2240 void KeyCommandHandler::HandlePointerVisibleKeys(const std::shared_ptr<KeyEvent> &keyEvent)
2241 {
2242     CALL_DEBUG_ENTER;
2243     CHKPV(keyEvent);
2244     if (keyEvent->GetKeyCode() == KeyEvent::KEYCODE_F9 && lastKeyEventCode_ == KeyEvent::KEYCODE_CTRL_LEFT) {
2245         MMI_HILOGI("Force make pointer visible");
2246 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
2247         IPointerDrawingManager::GetInstance()->ForceClearPointerVisiableStatus();
2248 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
2249     }
2250     lastKeyEventCode_ = keyEvent->GetKeyCode();
2251 }
2252 
2253 
UpdateSettingsXml(const std::string &businessId, int32_t delay)2254 int32_t KeyCommandHandler::UpdateSettingsXml(const std::string &businessId, int32_t delay)
2255 {
2256     CALL_DEBUG_ENTER;
2257     if (businessId.empty() || businessIds_.empty()) {
2258         MMI_HILOGE("businessId or businessIds_ is empty");
2259         return PARAMETER_ERROR;
2260     }
2261     if (std::find(businessIds_.begin(), businessIds_.end(), businessId) == businessIds_.end()) {
2262         MMI_HILOGE("%{public}s not in the config file", businessId.c_str());
2263         return PARAMETER_ERROR;
2264     }
2265     if (delay < MIN_SHORT_KEY_DOWN_DURATION || delay > MAX_SHORT_KEY_DOWN_DURATION) {
2266         MMI_HILOGE("Delay is not in valid range");
2267         return PARAMETER_ERROR;
2268     }
2269     return PREFERENCES_MGR->SetShortKeyDuration(businessId, delay);
2270 }
2271 
GetSingleKnuckleGesture() const2272 KnuckleGesture KeyCommandHandler::GetSingleKnuckleGesture() const
2273 {
2274     return singleKnuckleGesture_;
2275 }
2276 
GetDoubleKnuckleGesture() const2277 KnuckleGesture KeyCommandHandler::GetDoubleKnuckleGesture() const
2278 {
2279     return doubleKnuckleGesture_;
2280 }
2281 
SetKnuckleDoubleTapIntervalTime(int64_t interval)2282 void KeyCommandHandler::SetKnuckleDoubleTapIntervalTime(int64_t interval)
2283 {
2284     CALL_DEBUG_ENTER;
2285     if (interval < 0) {
2286         MMI_HILOGE("invalid interval time:%{public}" PRId64 "", interval);
2287         return;
2288     }
2289     downToPrevUpTimeConfig_ = interval;
2290 }
2291 
SetKnuckleDoubleTapDistance(float distance)2292 void KeyCommandHandler::SetKnuckleDoubleTapDistance(float distance)
2293 {
2294     CALL_DEBUG_ENTER;
2295     if (distance <= std::numeric_limits<float>::epsilon()) {
2296         MMI_HILOGE("invalid distance:%{public}f", distance);
2297         return;
2298     }
2299     downToPrevDownDistanceConfig_ = distance;
2300 }
2301 
CheckInputMethodArea(const std::shared_ptr<PointerEvent> touchEvent)2302 bool KeyCommandHandler::CheckInputMethodArea(const std::shared_ptr<PointerEvent> touchEvent)
2303 {
2304     CALL_DEBUG_ENTER;
2305     CHKPF(touchEvent);
2306     int32_t id = touchEvent->GetPointerId();
2307     PointerEvent::PointerItem item;
2308     touchEvent->GetPointerItem(id, item);
2309     int32_t displayX = item.GetDisplayX();
2310     int32_t displayY = item.GetDisplayY();
2311     int32_t displayId = touchEvent->GetTargetDisplayId();
2312     auto windows = WIN_MGR->GetWindowGroupInfoByDisplayId(displayId);
2313     int32_t tragetWindowId = touchEvent->GetTargetWindowId();
2314     for (auto window : windows) {
2315         if (window.windowType != WINDOW_INPUT_METHOD_TYPE) {
2316             continue;
2317         }
2318         if (window.id != tragetWindowId) {
2319             return false;
2320         }
2321         int32_t rightDownX;
2322         int32_t rightDownY;
2323         if (!AddInt32(window.area.x, window.area.width, rightDownX)) {
2324             MMI_HILOGE("The addition of displayMaxX overflows");
2325             return false;
2326         }
2327         if (!AddInt32(window.area.y, window.area.height, rightDownY)) {
2328             MMI_HILOGE("The addition of displayMaxX overflows");
2329             return false;
2330         }
2331         if (displayX >= window.area.x && displayX <= rightDownX &&
2332             displayY >= window.area.y && displayY <= rightDownY) {
2333             if (touchEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_DOWN ||
2334                 touchEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_UP) {
2335                 MMI_HILOGI("In input method area, windowId:%{public}d, windowType:%{public}d",
2336                     window.id, window.windowType);
2337                 return true;
2338             }
2339         }
2340     }
2341     return false;
2342 }
2343 
Dump(int32_t fd, const std::vector<std::string> &args)2344 void KeyCommandHandler::Dump(int32_t fd, const std::vector<std::string> &args)
2345 {
2346     static const std::unordered_map<int32_t, std::string> actionMap = { {0, "UNKNOWN"},
2347         {1, "CANCEL"}, {2, "DOWN"}, {3, "UP"} };
2348     CALL_DEBUG_ENTER;
2349     mprintf(fd, "----------------------------- ShortcutKey information ----------------------------\t");
2350     mprintf(fd, "ShortcutKey: count = %zu", shortcutKeys_.size());
2351     for (const auto &item : shortcutKeys_) {
2352         auto &shortcutKey = item.second;
2353         for (const auto &prekey : shortcutKey.preKeys) {
2354             mprintf(fd, "PreKey:%d", prekey);
2355         }
2356         mprintf(fd,
2357             "BusinessId: %s | StatusConfig: %s | StatusConfigValue: %s "
2358             "| FinalKey: %d | keyDownDuration: %d | TriggerType: %d | BundleName: %s | AbilityName: %s "
2359             "| Action: %s \t", shortcutKey.businessId.c_str(), shortcutKey.statusConfig.c_str(),
2360             shortcutKey.statusConfigValue ? "true" : "false", shortcutKey.finalKey, shortcutKey.keyDownDuration,
2361             shortcutKey.triggerType, shortcutKey.ability.bundleName.c_str(), shortcutKey.ability.abilityName.c_str(),
2362             shortcutKey.ability.action.c_str());
2363     }
2364     mprintf(fd, "-------------------------- Sequence information ----------------------------------\t");
2365     mprintf(fd, "Sequence: count = %zu", sequences_.size());
2366     for (const auto &item : sequences_) {
2367         for (const auto& sequenceKey : item.sequenceKeys) {
2368             mprintf(fd, "keyCode: %d | keyAction: %s",
2369                 sequenceKey.keyCode, ConvertKeyActionToString(sequenceKey.keyAction).c_str());
2370         }
2371         mprintf(fd, "BundleName: %s | AbilityName: %s | Action: %s ",
2372             item.ability.bundleName.c_str(), item.ability.abilityName.c_str(), item.ability.action.c_str());
2373     }
2374     mprintf(fd, "-------------------------- ExcludeKey information --------------------------------\t");
2375     mprintf(fd, "ExcludeKey: count = %zu", excludeKeys_.size());
2376     for (const auto &item : excludeKeys_) {
2377         mprintf(fd, "keyCode: %d | keyAction: %s", item.keyCode, ConvertKeyActionToString(item.keyAction).c_str());
2378     }
2379     mprintf(fd, "-------------------------- RepeatKey information ---------------------------------\t");
2380     mprintf(fd, "RepeatKey: count = %zu", repeatKeys_.size());
2381     for (const auto &item : repeatKeys_) {
2382         mprintf(fd,
2383             "KeyCode: %d | KeyAction: %s | Times: %d"
2384             "| StatusConfig: %s | StatusConfigValue: %s | BundleName: %s | AbilityName: %s"
2385             "| Action:%s \t", item.keyCode, ConvertKeyActionToString(item.keyAction).c_str(), item.times,
2386             item.statusConfig.c_str(), item.statusConfigValue ? "true" : "false",
2387             item.ability.bundleName.c_str(), item.ability.abilityName.c_str(), item.ability.action.c_str());
2388     }
2389     PrintGestureInfo(fd);
2390 }
2391 
PrintGestureInfo(int32_t fd)2392 void KeyCommandHandler::PrintGestureInfo(int32_t fd)
2393 {
2394     mprintf(fd, "-------------------------- TouchPad Two Fingers Gesture --------------------------\t");
2395     mprintf(fd,
2396         "GestureActive: %s | GestureBundleName: %s | GestureAbilityName: %s"
2397         "| GestureAction: %s \t", twoFingerGesture_.active ? "true" : "false",
2398         twoFingerGesture_.ability.bundleName.c_str(), twoFingerGesture_.ability.abilityName.c_str(),
2399         twoFingerGesture_.ability.action.c_str());
2400     mprintf(fd, "-------------------------- TouchPad Three Fingers Tap Gesture --------------------\t");
2401     mprintf(fd,
2402         "TapBundleName: %s | TapAbilityName: %s"
2403         "| TapAction: %s \t", threeFingersTap_.ability.bundleName.c_str(),
2404         threeFingersTap_.ability.abilityName.c_str(), threeFingersTap_.ability.action.c_str());
2405     mprintf(fd, "-------------------------- Knuckle Single Finger Gesture -------------------------\t");
2406     mprintf(fd,
2407         "GestureState: %s | GestureBundleName: %s | GestureAbilityName: %s"
2408         "| GestureAction: %s \t", singleKnuckleGesture_.state ? "true" : "false",
2409         singleKnuckleGesture_.ability.bundleName.c_str(), singleKnuckleGesture_.ability.abilityName.c_str(),
2410         singleKnuckleGesture_.ability.action.c_str());
2411     mprintf(fd, "-------------------------- Knuckle Two Fingers Gesture ---------------------------\t");
2412     mprintf(fd,
2413         "GestureState: %s | GestureBundleName: %s | GestureAbilityName: %s"
2414         "| GestureAction:%s \t", doubleKnuckleGesture_.state ? "true" : "false",
2415         doubleKnuckleGesture_.ability.bundleName.c_str(), doubleKnuckleGesture_.ability.abilityName.c_str(),
2416         doubleKnuckleGesture_.ability.action.c_str());
2417 }
ConvertKeyActionToString(int32_t keyAction)2418 std::string KeyCommandHandler::ConvertKeyActionToString(int32_t keyAction)
2419 {
2420     static const std::unordered_map<int32_t, std::string> actionMap = {
2421         {0, "UNKNOWN"},
2422         {1, "CANCEL"},
2423         {2, "DOWN"},
2424         {3, "UP"}
2425     };
2426     auto it = actionMap.find(keyAction);
2427     if (it != actionMap.end()) {
2428         return it->second;
2429     } else {
2430         return "UNKNOWN_ACTION";
2431     }
2432 }
operator <<(std::ostream& os, const Sequence& seq)2433 std::ostream& operator<<(std::ostream& os, const Sequence& seq)
2434 {
2435     os << "keys: [";
2436     for (const SequenceKey &singleKey: seq.sequenceKeys) {
2437         os << "(kc:" << singleKey.keyCode << ",ka:" << singleKey.keyAction << ",d:" << singleKey.delay << "),";
2438     }
2439     os << "]: " << seq.ability.bundleName << ":" << seq.ability.abilityName;
2440     return os;
2441 }
2442 
CheckAndUpdateTappingCountAtDown(std::shared_ptr<PointerEvent> touchEvent)2443 void KeyCommandHandler::CheckAndUpdateTappingCountAtDown(std::shared_ptr<PointerEvent> touchEvent)
2444 {
2445     CHKPV(touchEvent);
2446     int64_t currentDownTime = touchEvent->GetActionTime();
2447     int64_t downIntervalTime = currentDownTime - lastDownTime_;
2448     lastDownTime_ = currentDownTime;
2449     if (downIntervalTime <= 0 || downIntervalTime >= TAP_DOWN_INTERVAL_MILLIS) {
2450         tappingCount_ = 1;
2451         return;
2452     }
2453     tappingCount_++;
2454     int64_t timeDiffToPrevKnuckleUpTime = currentDownTime - previousUpTime_;
2455     if (timeDiffToPrevKnuckleUpTime <= downToPrevUpTimeConfig_) {
2456         if (tappingCount_ == MAX_TAP_COUNT) {
2457             DfxHisysevent::ReportFailIfOneSuccTwoFail(touchEvent);
2458         }
2459         if (tappingCount_ > MAX_TAP_COUNT) {
2460             DfxHisysevent::ReportFailIfKnockTooFast();
2461         }
2462     }
2463 }
2464 
TouchPadKnuckleDoubleClickHandle(std::shared_ptr<KeyEvent> event)2465 bool KeyCommandHandler::TouchPadKnuckleDoubleClickHandle(std::shared_ptr<KeyEvent> event)
2466 {
2467     CHKPF(event);
2468     auto actionType = event->GetKeyAction();
2469     if (actionType == KNUCKLE_1F_DOUBLE_CLICK) {
2470         TouchPadKnuckleDoubleClickProcess(HARDEN_SCREENSHOT_BUNDLE_NAME,
2471             HARDEN_SCREENSHOT_ABILITY_NAME, "single_knuckle");
2472         return true;
2473     }
2474     if (actionType == KNUCKLE_2F_DOUBLE_CLICK) {
2475         TouchPadKnuckleDoubleClickProcess(HARDEN_SCREENRECORDER_BUNDLE_NAME,
2476             HARDEN_SCREENRECORDER_ABILITY_NAME, "double_knuckle");
2477         return true;
2478     }
2479     return false;
2480 }
2481 
TouchPadKnuckleDoubleClickProcess(const std::string bundleName, const std::string abilityName, const std::string action)2482 void KeyCommandHandler::TouchPadKnuckleDoubleClickProcess(const std::string bundleName,
2483     const std::string abilityName, const std::string action)
2484 {
2485     std::string screenStatus = DISPLAY_MONITOR->GetScreenStatus();
2486     bool isScreenLocked = DISPLAY_MONITOR->GetScreenLocked();
2487     if (screenStatus == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF || isScreenLocked) {
2488         MMI_HILOGI("The current screen is not in the unlocked state with the screen on");
2489         return;
2490     }
2491     Ability ability;
2492     ability.bundleName = bundleName;
2493     ability.abilityName = abilityName;
2494     ability.params.emplace(std::make_pair("trigger_type", action));
2495     LaunchAbility(ability, NO_DELAY);
2496 }
2497 } // namespace MMI
2498 } // namespace OHOS