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