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