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