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