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