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 "ability_manager_client.h"
19 #include "cursor_drawing_component.h"
20 #include "device_event_monitor.h"
21 #include "bundle_name_parser.h"
22 #include "product_type_parser.h"
23 #include "json_parser.h"
24 #include "product_name_definition.h"
25 #include "event_log_helper.h"
26 #include "gesturesense_wrapper.h"
27 #include "input_screen_capture_agent.h"
28 #ifdef SHORTCUT_KEY_MANAGER_ENABLED
29 #include "key_shortcut_manager.h"
30 #endif // SHORTCUT_KEY_MANAGER_ENABLED
31 #include "key_command_handler_util.h"
32 #include "key_event_normalize.h"
33 #include "long_press_subscriber_handler.h"
34 #include "pointer_device_manager.h"
35 #include "pull_throw_subscriber_handler.h"
36 #include "sensor_agent.h"
37 #include "sensor_agent_type.h"
38 #include "stylus_key_handler.h"
39 #include "timer_manager.h"
40 #include <dlfcn.h>
41 #include <iostream>
42
43 #undef MMI_LOG_DOMAIN
44 #define MMI_LOG_DOMAIN MMI_LOG_HANDLER
45 #undef MMI_LOG_TAG
46 #define MMI_LOG_TAG "KeyCommandHandler"
47
48 namespace OHOS {
49 namespace MMI {
50 namespace {
51 constexpr float MOVE_TOLERANCE { 3.0f };
52 constexpr float MIN_GESTURE_STROKE_LENGTH { 200.0f };
53 constexpr float MIN_LETTER_GESTURE_SQUARENESS { 0.15f };
54 constexpr float MIN_START_GESTURE { 60.0f };
55 constexpr int32_t POINTER_NUMBER { 2 };
56 constexpr int32_t EVEN_NUMBER { 2 };
57 constexpr int64_t NO_DELAY { 0 };
58 constexpr int64_t FREQUENCY { 1000 };
59 constexpr int64_t TAP_DOWN_INTERVAL_MILLIS { 550000 };
60 constexpr int64_t SOS_INTERVAL_TIMES { 300000 };
61 constexpr int64_t SOS_DELAY_TIMES { 1000000 };
62 constexpr int64_t SOS_COUNT_DOWN_TIMES { 4000000 };
63 constexpr int32_t MAX_TAP_COUNT { 2 };
64 constexpr int32_t ANCO_KNUCKLE_POINTER_ID { 15000 };
65 constexpr int64_t SCREEN_TIME_OUT { 100 };
66 const char* WAKEUP_ABILITY_NAME { "WakeUpExtAbility" };
67 constexpr int32_t DEFAULT_VALUE { -1 };
68 constexpr int64_t POWER_ACTION_INTERVAL { 600 };
69 constexpr int64_t SOS_WAIT_TIME { 3000 };
70 const char* KEY_ENABLE { "enable" };
71 const char* KEY_STATUS { "status" };
72 constexpr size_t DEFAULT_BUFFER_LENGTH { 512 };
73 const std::string SECURE_SETTING_URI_PROXY {
74 "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_%d?Proxy=true" };
75 const char *TV_MENU_BUNDLE_NAME = "com.ohos.sceneboard";
76 const char *TV_MENU_ABILITY_NAME = "com.ohos.sceneboard.MultimodalInputService";
77 constexpr int32_t TIME_CONVERSION_UNIT { 1000 };
78 constexpr int32_t SENSOR_SAMPLING_INTERVAL = 100000000;
79 constexpr int32_t SENSOR_REPORT_INTERVAL = 100000000;
80 const std::string PRODUCT_TYPE = OHOS::system::GetParameter("const.build.product", "HYM");
81 struct SensorUser g_user = {.name = {0}, .callback = nullptr, .userData = nullptr};
82 std::atomic<int32_t> g_distance { 0 };
83 #ifdef OHOS_BUILD_ENABLE_MISTOUCH_PREVENTION
84 const char* LOADMISTOUCH_LIBPATH = "libmistouch_prevention.z.so";
85 #endif // OHOS_BUILD_ENABLE_MISTOUCH_PREVENTION
86 constexpr int32_t LIGHT_STAY_AWAY { 0 };
87 const std::string DEVICE_TYPE_TV = system::GetParameter("const.product.devicetype", "unknown");
88 const std::string PRODUCT_TYPE_TV = "tv";
89 } // namespace
90
SensorDataCallbackImpl(SensorEvent * event)91 static void SensorDataCallbackImpl(SensorEvent *event)
92 {
93 if (event == nullptr) {
94 MMI_HILOGE("Event is nullptr");
95 return;
96 }
97 if (event->sensorTypeId != SENSOR_TYPE_ID_PROXIMITY) {
98 MMI_HILOGE("Event sensorTypeId is not SENSOR_TYPE_ID_PROXIMITY");
99 return;
100 }
101 ProximityData* proximityData = reinterpret_cast<ProximityData*>(event->data);
102 CHKPV(proximityData);
103 int32_t distance = static_cast<int32_t>(proximityData->distance);
104 MMI_HILOGI("Proximity distance %{public}d", distance);
105 g_distance = distance;
106 }
107
108 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)109 void KeyCommandHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
110 {
111 CHKPV(keyEvent);
112 if (TouchPadKnuckleDoubleClickHandle(keyEvent)) {
113 return;
114 }
115 if (MenuClickHandle(keyEvent)) {
116 MMI_HILOGD("MenuClickHandle return true:%{private}d", keyEvent->GetKeyCode());
117 return;
118 }
119 if (OnHandleEvent(keyEvent)) {
120 if (DISPLAY_MONITOR->GetScreenStatus() == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
121 auto monitorHandler = InputHandler->GetMonitorHandler();
122 CHKPV(monitorHandler);
123 keyEvent->SetFourceMonitorFlag(true);
124 #ifndef OHOS_BUILD_EMULATOR
125 monitorHandler->OnHandleEvent(keyEvent);
126 #endif // OHOS_BUILD_EMULATOR
127 keyEvent->SetFourceMonitorFlag(false);
128 }
129 MMI_HILOGD("The keyEvent start launch an ability:%{private}d", keyEvent->GetKeyCode());
130 BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::KEY_LAUNCH_EVENT);
131 return;
132 }
133 CHKPV(nextHandler_);
134 nextHandler_->HandleKeyEvent(keyEvent);
135 }
136 #endif // OHOS_BUILD_ENABLE_KEYBOARD
137
138 #ifdef OHOS_BUILD_ENABLE_POINTER
HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)139 void KeyCommandHandler::HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)
140 {
141 CHKPV(pointerEvent);
142 if (OnHandleEvent(pointerEvent)) {
143 if (EventLogHelper::IsBetaVersion() && !pointerEvent->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) {
144 MMI_HILOGD("The pointerEvent start launch an ability, pointAction:%{public}s",
145 pointerEvent->DumpPointerAction());
146 } else {
147 MMI_HILOGD("The pointerEvent start launch an ability, pointAction:%s", pointerEvent->DumpPointerAction());
148 }
149 }
150 CHKPV(nextHandler_);
151 nextHandler_->HandlePointerEvent(pointerEvent);
152 }
153 #endif // OHOS_BUILD_ENABLE_POINTER
154
155 #ifdef OHOS_BUILD_ENABLE_TOUCH
HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)156 void KeyCommandHandler::HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)
157 {
158 CHKPV(pointerEvent);
159 CHKPV(nextHandler_);
160 OnHandleTouchEvent(pointerEvent);
161 int32_t id = pointerEvent->GetPointerId();
162 PointerEvent::PointerItem item;
163 pointerEvent->GetPointerItem(id, item);
164 int32_t toolType = item.GetToolType();
165 if (toolType == PointerEvent::TOOL_TYPE_KNUCKLE) {
166 pointerEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT);
167 }
168 nextHandler_->HandleTouchEvent(pointerEvent);
169 }
170 #endif // OHOS_BUILD_ENABLE_TOUCH
171
SkipKnuckleDetect()172 bool KeyCommandHandler::SkipKnuckleDetect()
173 {
174 return ((screenCapturePermission_ & (KNUCKLE_SCREENSHOT | KNUCKLE_SCROLL_SCREENSHOT | KNUCKLE_ENABLE_AI_BASE |
175 KNUCKLE_SCREEN_RECORDING)) == 0) ||
176 !(screenshotSwitch_.statusConfigValue || recordSwitch_.statusConfigValue) || gameForbidFingerKnuckle_;
177 }
178
179 #ifdef OHOS_BUILD_ENABLE_TOUCH
OnHandleTouchEvent(const std::shared_ptr<PointerEvent> touchEvent)180 void KeyCommandHandler::OnHandleTouchEvent(const std::shared_ptr<PointerEvent> touchEvent)
181 {
182 CALL_DEBUG_ENTER;
183 CHKPV(touchEvent);
184 STYLUS_HANDLER->SetLastEventState(false);
185 if (!isParseConfig_) {
186 if (!ParseConfig()) {
187 MMI_HILOGE("Parse configFile failed");
188 return;
189 }
190 isParseConfig_ = true;
191 }
192 twoFingerGesture_.touchEvent = touchEvent;
193 InitializeLongPressConfigurations();
194 switch (touchEvent->GetPointerAction()) {
195 case PointerEvent::POINTER_ACTION_PULL_MOVE:
196 if (PRODUCT_TYPE == DEVICE_TYPE_FOLD_PC) {
197 PULL_THROW_EVENT_HANDLER->HandleFingerGesturePullMoveEvent(touchEvent);
198 }
199 break;
200 case PointerEvent::POINTER_ACTION_CANCEL:
201 case PointerEvent::POINTER_ACTION_UP: {
202 HandlePointerActionUpEvent(touchEvent);
203 break;
204 }
205 case PointerEvent::POINTER_ACTION_MOVE: {
206 HandlePointerActionMoveEvent(touchEvent);
207 LONG_PRESS_EVENT_HANDLER->HandleFingerGestureMoveEvent(touchEvent);
208 if (PRODUCT_TYPE == DEVICE_TYPE_FOLD_PC) {
209 PULL_THROW_EVENT_HANDLER->HandleFingerGestureMoveEvent(touchEvent);
210 }
211 break;
212 }
213 case PointerEvent::POINTER_ACTION_DOWN: {
214 HandlePointerActionDownEvent(touchEvent);
215 break;
216 }
217 default:
218 MMI_HILOGD("Unknown pointer action:%{public}d", touchEvent->GetPointerAction());
219 break;
220 }
221 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
222 HandleKnuckleGestureEvent(touchEvent);
223 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
224 }
225
InitializeLongPressConfigurations()226 void KeyCommandHandler::InitializeLongPressConfigurations()
227 {
228 if (!isParseLongPressConfig_) {
229 if (!ParseLongPressConfig()) {
230 MMI_HILOGE("Parse long press configFile failed");
231 }
232 isParseLongPressConfig_ = true;
233 }
234 if (!isDistanceConfig_) {
235 distanceDefaultConfig_ = DOUBLE_CLICK_DISTANCE_DEFAULT_CONFIG * VPR_CONFIG;
236 distanceLongConfig_ = DOUBLE_CLICK_DISTANCE_LONG_CONFIG * VPR_CONFIG;
237 SetKnuckleDoubleTapDistance(distanceDefaultConfig_);
238 isDistanceConfig_ = true;
239 }
240 }
241
HandlePointerActionDownEvent(const std::shared_ptr<PointerEvent> touchEvent)242 void KeyCommandHandler::HandlePointerActionDownEvent(const std::shared_ptr<PointerEvent> touchEvent)
243 {
244 CALL_DEBUG_ENTER;
245 CHKPV(touchEvent);
246 int32_t id = touchEvent->GetPointerId();
247 PointerEvent::PointerItem item;
248 touchEvent->GetPointerItem(id, item);
249 int32_t toolType = item.GetToolType();
250 MMI_HILOGD("Pointer tool type:%{public}d", toolType);
251 singleKnuckleGesture_.state = false;
252 doubleKnuckleGesture_.state = false;
253 switch (toolType) {
254 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
255 case PointerEvent::TOOL_TYPE_FINGER: {
256 HandleFingerGestureDownEvent(touchEvent);
257 if (CheckBundleName(touchEvent)) {
258 LONG_PRESS_EVENT_HANDLER->HandleFingerGestureDownEvent(touchEvent);
259 }
260 if (PRODUCT_TYPE == DEVICE_TYPE_FOLD_PC) {
261 PULL_THROW_EVENT_HANDLER->HandleFingerGestureDownEvent(touchEvent);
262 }
263 break;
264 }
265 case PointerEvent::TOOL_TYPE_KNUCKLE: {
266 CheckAndUpdateTappingCountAtDown(touchEvent);
267 DfxHisysevent::ReportKnuckleClickEvent();
268 HandleKnuckleGestureDownEvent(touchEvent);
269 break;
270 }
271 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
272 default: {
273 MMI_HILOGD("Current touch event tool type:%{public}d", toolType);
274 break;
275 }
276 }
277 }
278
HandlePointerActionMoveEvent(const std::shared_ptr<PointerEvent> touchEvent)279 void KeyCommandHandler::HandlePointerActionMoveEvent(const std::shared_ptr<PointerEvent> touchEvent)
280 {
281 CALL_DEBUG_ENTER;
282 CHKPV(touchEvent);
283 int32_t id = touchEvent->GetPointerId();
284 PointerEvent::PointerItem item;
285 touchEvent->GetPointerItem(id, item);
286 if (!twoFingerGesture_.active) {
287 return;
288 }
289 if (twoFingerGesture_.timerId == -1) {
290 MMI_HILOGD("Two finger gesture timer id is -1");
291 return;
292 }
293 auto pos = std::find_if(std::begin(twoFingerGesture_.touches), std::end(twoFingerGesture_.touches),
294 [id](const auto& item) { return item.id == id; });
295 if (pos == std::end(twoFingerGesture_.touches)) {
296 return;
297 }
298 auto dx = std::abs(pos->x - item.GetDisplayX());
299 auto dy = std::abs(pos->y - item.GetDisplayY());
300 auto moveDistance = sqrt(pow(dx, 2) + pow(dy, 2));
301 if (moveDistance > ConvertVPToPX(TOUCH_MAX_THRESHOLD)) {
302 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
303 MMI_HILOGD("Finger movement distance greater than 20VP, defaultDistance:%{public}d, moveDistance:%{public}f",
304 ConvertVPToPX(TOUCH_MAX_THRESHOLD), moveDistance);
305 StopTwoFingerGesture();
306 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
307 }
308 }
309
HandlePointerActionUpEvent(const std::shared_ptr<PointerEvent> touchEvent)310 void KeyCommandHandler::HandlePointerActionUpEvent(const std::shared_ptr<PointerEvent> touchEvent)
311 {
312 CALL_DEBUG_ENTER;
313 CHKPV(touchEvent);
314 int32_t id = touchEvent->GetPointerId();
315 PointerEvent::PointerItem item;
316 touchEvent->GetPointerItem(id, item);
317 int32_t toolType = item.GetToolType();
318 switch (toolType) {
319 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
320 case PointerEvent::TOOL_TYPE_FINGER: {
321 HandleFingerGestureUpEvent(touchEvent);
322 LONG_PRESS_EVENT_HANDLER->HandleFingerGestureUpEvent(touchEvent);
323 if (PRODUCT_TYPE == DEVICE_TYPE_FOLD_PC) {
324 PULL_THROW_EVENT_HANDLER->HandleFingerGestureUpEvent(touchEvent);
325 }
326 break;
327 }
328 case PointerEvent::TOOL_TYPE_KNUCKLE: {
329 HandleKnuckleGestureUpEvent(touchEvent);
330 break;
331 }
332 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
333 default: {
334 MMI_HILOGW("Current touch event tool type:%{public}d", toolType);
335 break;
336 }
337 }
338 }
339 #endif // OHOS_BUILD_ENABLE_TOUCH
340
341 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
HandleFingerGestureDownEvent(const std::shared_ptr<PointerEvent> touchEvent)342 void KeyCommandHandler::HandleFingerGestureDownEvent(const std::shared_ptr<PointerEvent> touchEvent)
343 {
344 CALL_DEBUG_ENTER;
345 if (!twoFingerGesture_.active) {
346 MMI_HILOGD("Two finger gesture is not active");
347 return;
348 }
349 auto num = touchEvent->GetPointerIds().size();
350 if (num == TwoFingerGesture::MAX_TOUCH_NUM) {
351 StartTwoFingerGesture();
352 } else {
353 StopTwoFingerGesture();
354 }
355 if (num > 0 && num <= TwoFingerGesture::MAX_TOUCH_NUM) {
356 int32_t id = touchEvent->GetPointerId();
357 PointerEvent::PointerItem item;
358 touchEvent->GetPointerItem(id, item);
359 twoFingerGesture_.touches[num - 1].id = id;
360 twoFingerGesture_.touches[num - 1].x = item.GetDisplayX();
361 twoFingerGesture_.touches[num - 1].y = item.GetDisplayY();
362 twoFingerGesture_.touches[num - 1].downTime = item.GetDownTime();
363 }
364 }
365
HandleFingerGestureUpEvent(const std::shared_ptr<PointerEvent> touchEvent)366 void KeyCommandHandler::HandleFingerGestureUpEvent(const std::shared_ptr<PointerEvent> touchEvent)
367 {
368 CALL_DEBUG_ENTER;
369 CHKPV(touchEvent);
370 if (!twoFingerGesture_.active) {
371 MMI_HILOGD("Two finger gesture is not active");
372 return;
373 }
374 StopTwoFingerGesture();
375 }
376
HandleKnuckleGestureDownEvent(const std::shared_ptr<PointerEvent> touchEvent)377 void KeyCommandHandler::HandleKnuckleGestureDownEvent(const std::shared_ptr<PointerEvent> touchEvent)
378 {
379 CALL_DEBUG_ENTER;
380 CHKPV(touchEvent);
381 int32_t id = touchEvent->GetPointerId();
382 PointerEvent::PointerItem item;
383 touchEvent->GetPointerItem(id, item);
384 int64_t currentDownTime = item.GetDownTime();
385 if (!lastPointerDownTime_.empty()) {
386 int64_t firstDownTime = lastPointerDownTime_.begin()->second;
387 int64_t lastPointerDownTime = touchEvent->HasFlag(InputEvent::EVENT_FLAG_SIMULATE) ?
388 lastPointerDownTime_[SIMULATE_POINTER_ID] : firstDownTime;
389 int64_t diffTime = currentDownTime - lastPointerDownTime;
390 lastPointerDownTime_[id] = currentDownTime;
391 MMI_HILOGW("Size:%{public}zu, firstDownTime:%{public}" PRId64 ", "
392 "currentDownTime:%{public}" PRId64 ", diffTime:%{public}" PRId64,
393 lastPointerDownTime_.size(), firstDownTime, currentDownTime, diffTime);
394 if (diffTime > TWO_FINGERS_TIME_LIMIT) {
395 MMI_HILOGE("Invalid double knuckle event, pointerId:%{public}d", id);
396 return;
397 }
398 }
399
400 lastPointerDownTime_[id] = currentDownTime;
401 auto items = touchEvent->GetAllPointerItems();
402 MMI_HILOGI("The itemsSize:%{public}zu", items.size());
403 for (const auto &item : items) {
404 if (item.GetToolType() != PointerEvent::TOOL_TYPE_KNUCKLE) {
405 MMI_HILOGW("Touch event tool type:%{public}d not knuckle", item.GetToolType());
406 return;
407 }
408 }
409 if (CheckInputMethodArea(touchEvent)) {
410 MMI_HILOGW("Event skipping inputmethod area");
411 return;
412 }
413 size_t pointercnt = touchEvent->GetPointerIds().size();
414 if (pointercnt == SINGLE_KNUCKLE_SIZE) {
415 SingleKnuckleGestureProcesser(touchEvent);
416 isDoubleClick_ = false;
417 knuckleCount_++;
418 } else if (pointercnt == DOUBLE_KNUCKLE_SIZE) {
419 DoubleKnuckleGestureProcesser(touchEvent);
420 isDoubleClick_ = true;
421 } else {
422 MMI_HILOGW("Other kunckle pointercnt not process, pointercnt:%{public}zu", pointercnt);
423 }
424 }
425
HandleKnuckleGestureUpEvent(const std::shared_ptr<PointerEvent> touchEvent)426 void KeyCommandHandler::HandleKnuckleGestureUpEvent(const std::shared_ptr<PointerEvent> touchEvent)
427 {
428 CALL_DEBUG_ENTER;
429 CHKPV(touchEvent);
430 int32_t id = touchEvent->GetPointerId();
431 auto it = lastPointerDownTime_.find(id);
432 if (it != lastPointerDownTime_.end()) {
433 MMI_HILOGW("lastPointerDownTime_ has been erased, pointerId:%{public}d", id);
434 lastPointerDownTime_.erase(it);
435 }
436
437 previousUpTime_ = touchEvent->GetActionTime();
438 size_t pointercnt = touchEvent->GetPointerIds().size();
439 if ((pointercnt == SINGLE_KNUCKLE_SIZE) && (!isDoubleClick_)) {
440 singleKnuckleGesture_.lastPointerUpTime = touchEvent->GetActionTime();
441 } else if (pointercnt == DOUBLE_KNUCKLE_SIZE) {
442 doubleKnuckleGesture_.lastPointerUpTime = touchEvent->GetActionTime();
443 } else {
444 MMI_HILOGW("Other kunckle pointercnt not process, pointercnt:%{public}zu", pointercnt);
445 }
446 }
447
SingleKnuckleGestureProcesser(const std::shared_ptr<PointerEvent> touchEvent)448 void KeyCommandHandler::SingleKnuckleGestureProcesser(const std::shared_ptr<PointerEvent> touchEvent)
449 {
450 CALL_DEBUG_ENTER;
451 CHKPV(touchEvent);
452 singleKnuckleGesture_.state = false;
453 KnuckleGestureProcessor(touchEvent, singleKnuckleGesture_, KnuckleType::KNUCKLE_TYPE_SINGLE);
454 }
455
DoubleKnuckleGestureProcesser(const std::shared_ptr<PointerEvent> touchEvent)456 void KeyCommandHandler::DoubleKnuckleGestureProcesser(const std::shared_ptr<PointerEvent> touchEvent)
457 {
458 CALL_DEBUG_ENTER;
459 CHKPV(touchEvent);
460 doubleKnuckleGesture_.state = false;
461 KnuckleGestureProcessor(touchEvent, doubleKnuckleGesture_, KnuckleType::KNUCKLE_TYPE_DOUBLE);
462 }
463
KnuckleGestureProcessor(std::shared_ptr<PointerEvent> touchEvent,KnuckleGesture & knuckleGesture,KnuckleType type)464 void KeyCommandHandler::KnuckleGestureProcessor(std::shared_ptr<PointerEvent> touchEvent,
465 KnuckleGesture &knuckleGesture, KnuckleType type)
466 {
467 CALL_DEBUG_ENTER;
468 CHKPV(touchEvent);
469 if (tappingCount_ > MAX_TAP_COUNT) {
470 MMI_HILOGI("Knuckle tapping count more than twice:%{public}d", tappingCount_);
471 return;
472 }
473 if (knuckleGesture.lastPointerDownEvent == nullptr) {
474 MMI_HILOGI("Knuckle gesture first down Event");
475 knuckleGesture.lastPointerDownEvent = touchEvent;
476 UpdateKnuckleGestureInfo(touchEvent, knuckleGesture);
477 return;
478 }
479 int64_t intervalTime = touchEvent->GetActionTime() - knuckleGesture.lastPointerUpTime;
480 bool isTimeIntervalReady = intervalTime > 0 && intervalTime <= DOUBLE_CLICK_INTERVAL_TIME_SLOW;
481 float downToPrevDownDistance = AbsDiff(knuckleGesture, touchEvent);
482 bool isDistanceReady = downToPrevDownDistance < downToPrevDownDistanceConfig_;
483 knuckleGesture.downToPrevUpTime = intervalTime;
484 knuckleGesture.doubleClickDistance = downToPrevDownDistance;
485 UpdateKnuckleGestureInfo(touchEvent, knuckleGesture);
486 if (isTimeIntervalReady && (type == KnuckleType::KNUCKLE_TYPE_DOUBLE || isDistanceReady)) {
487 MMI_HILOGI("Knuckle gesture start launch ability");
488 knuckleCount_ = 0;
489 if ((type == KnuckleType::KNUCKLE_TYPE_SINGLE && HasScreenCapturePermission(KNUCKLE_SCREENSHOT)) ||
490 (type == KnuckleType::KNUCKLE_TYPE_DOUBLE && HasScreenCapturePermission(KNUCKLE_SCREEN_RECORDING))) {
491 DfxHisysevent::ReportSingleKnuckleDoubleClickEvent(intervalTime, downToPrevDownDistance);
492 BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_FINGERSCENE, knuckleGesture.ability.bundleName);
493 LaunchAbility(knuckleGesture.ability, NO_DELAY);
494 BytraceAdapter::StopLaunchAbility();
495 if (knuckleGesture.ability.bundleName == BUNDLE_NAME_PARSER.GetBundleName("SCREENRECORDER_BUNDLE_NAME")) {
496 DfxHisysevent::ReportScreenRecorderGesture(intervalTime);
497 }
498 ReportKnuckleScreenCapture(touchEvent);
499 }
500 knuckleGesture.state = true;
501 } else {
502 if (knuckleCount_ > KNUCKLE_KNOCKS) {
503 knuckleCount_ = 0;
504 MMI_HILOGW("Time ready:%{public}d, distance ready:%{public}d", isTimeIntervalReady, isDistanceReady);
505 if (!isTimeIntervalReady) {
506 DfxHisysevent::ReportFailIfInvalidTime(touchEvent, intervalTime);
507 }
508 if (!isDistanceReady) {
509 DfxHisysevent::ReportFailIfInvalidDistance(touchEvent, downToPrevDownDistance);
510 }
511 }
512 }
513 AdjustDistanceConfigIfNeed(downToPrevDownDistance);
514 }
515
SendNotSupportMsg(std::shared_ptr<PointerEvent> touchEvent)516 void KeyCommandHandler::SendNotSupportMsg(std::shared_ptr<PointerEvent> touchEvent)
517 {
518 CALL_DEBUG_ENTER;
519 CHKPV(touchEvent);
520 auto tempEvent = std::make_shared<PointerEvent>(*touchEvent);
521 std::list<PointerEvent::PointerItem> pointerItems = tempEvent->GetAllPointerItems();
522 tempEvent->RemoveAllPointerItems();
523 for (auto &pointerItem : pointerItems) {
524 pointerItem.SetPointerId(ANCO_KNUCKLE_POINTER_ID);
525 pointerItem.SetOriginPointerId(ANCO_KNUCKLE_POINTER_ID);
526 tempEvent->AddPointerItem(pointerItem);
527 }
528 tempEvent->SetPointerAction(PointerEvent::POINTER_ACTION_DOWN);
529 tempEvent->SetPointerId(ANCO_KNUCKLE_POINTER_ID);
530 tempEvent->SetAgentWindowId(tempEvent->GetTargetWindowId());
531 MMI_HILOGW("Event is %{private}s", tempEvent->ToString().c_str());
532 auto fd = WIN_MGR->GetClientFd(tempEvent);
533 auto udsServer = InputHandler->GetUDSServer();
534 CHKPV(udsServer);
535 NetPacket pkt(MmiMessageId::ON_POINTER_EVENT);
536 InputEventDataTransformation::Marshalling(tempEvent, pkt);
537 #ifdef OHOS_BUILD_ENABLE_SECURITY_COMPONENT
538 InputEventDataTransformation::MarshallingEnhanceData(tempEvent, pkt);
539 #endif // OHOS_BUILD_ENABLE_SECURITY_COMPONENT
540 udsServer->SendMsg(fd, pkt);
541
542 tempEvent->SetPointerAction(PointerEvent::POINTER_ACTION_UP);
543 std::list<PointerEvent::PointerItem> tmpPointerItems = tempEvent->GetAllPointerItems();
544 tempEvent->RemoveAllPointerItems();
545 for (auto &pointerItem : tmpPointerItems) {
546 pointerItem.SetPressed(false);
547 tempEvent->AddPointerItem(pointerItem);
548 }
549 NetPacket pktUp(MmiMessageId::ON_POINTER_EVENT);
550 InputEventDataTransformation::Marshalling(tempEvent, pktUp);
551 #ifdef OHOS_BUILD_ENABLE_SECURITY_COMPONENT
552 InputEventDataTransformation::MarshallingEnhanceData(tempEvent, pktUp);
553 #endif // OHOS_BUILD_ENABLE_SECURITY_COMPONENT
554 udsServer->SendMsg(fd, pktUp);
555 }
556
UpdateKnuckleGestureInfo(const std::shared_ptr<PointerEvent> touchEvent,KnuckleGesture & knuckleGesture)557 void KeyCommandHandler::UpdateKnuckleGestureInfo(const std::shared_ptr<PointerEvent> touchEvent,
558 KnuckleGesture &knuckleGesture)
559 {
560 int32_t id = touchEvent->GetPointerId();
561 PointerEvent::PointerItem item;
562 touchEvent->GetPointerItem(id, item);
563 knuckleGesture.lastDownPointer.x = item.GetDisplayX();
564 knuckleGesture.lastDownPointer.y = item.GetDisplayY();
565 knuckleGesture.lastDownPointer.id = touchEvent->GetId();
566 }
567
AdjustDistanceConfigIfNeed(float distance)568 void KeyCommandHandler::AdjustDistanceConfigIfNeed(float distance)
569 {
570 CALL_DEBUG_ENTER;
571 float newDistanceConfig;
572 MMI_HILOGI("Down to prev down distance:%{public}f, config distance:%{public}f",
573 distance, downToPrevDownDistanceConfig_);
574 if (IsEqual(downToPrevDownDistanceConfig_, distanceDefaultConfig_)) {
575 if (distance < distanceDefaultConfig_ || distance > distanceLongConfig_) {
576 return;
577 }
578 newDistanceConfig = distanceLongConfig_;
579 } else if (IsEqual(downToPrevDownDistanceConfig_, distanceLongConfig_)) {
580 if (distance > distanceDefaultConfig_) {
581 return;
582 }
583 newDistanceConfig = distanceDefaultConfig_;
584 } else {
585 return;
586 }
587 checkAdjustDistanceCount_++;
588 if (checkAdjustDistanceCount_ < MAX_TIME_FOR_ADJUST_CONFIG) {
589 return;
590 }
591 MMI_HILOGI("Adjust new double click distance:%{public}f", newDistanceConfig);
592 downToPrevDownDistanceConfig_ = newDistanceConfig;
593 checkAdjustDistanceCount_ = 0;
594 }
595
ReportKnuckleScreenCapture(const std::shared_ptr<PointerEvent> touchEvent)596 void KeyCommandHandler::ReportKnuckleScreenCapture(const std::shared_ptr<PointerEvent> touchEvent)
597 {
598 CHKPV(touchEvent);
599 size_t pointercnt = touchEvent->GetPointerIds().size();
600 if (pointercnt == SINGLE_KNUCKLE_SIZE) {
601 DfxHisysevent::ReportScreenCaptureGesture();
602 return;
603 }
604 MMI_HILOGW("Current touch event pointercnt:%{public}zu", pointercnt);
605 }
606
StartTwoFingerGesture()607 void KeyCommandHandler::StartTwoFingerGesture()
608 {
609 CALL_DEBUG_ENTER;
610 twoFingerGesture_.startTime = 0;
611 twoFingerGesture_.longPressFlag = false;
612 twoFingerGesture_.windowId = -1;
613 twoFingerGesture_.windowPid = -1;
614 twoFingerGesture_.timerId = TimerMgr->AddTimer(twoFingerGesture_.abilityStartDelay, 1, [this]() {
615 twoFingerGesture_.timerId = -1;
616 if (!CheckTwoFingerGestureAction()) {
617 return;
618 }
619 twoFingerGesture_.ability.params["displayX1"] = std::to_string(twoFingerGesture_.touches[0].x);
620 twoFingerGesture_.ability.params["displayY1"] = std::to_string(twoFingerGesture_.touches[0].y);
621 twoFingerGesture_.ability.params["displayX2"] = std::to_string(twoFingerGesture_.touches[1].x);
622 twoFingerGesture_.ability.params["displayY2"] = std::to_string(twoFingerGesture_.touches[1].y);
623 MMI_HILOGI("Dual-finger long press capability information saving");
624 twoFingerGesture_.longPressFlag = true;
625 twoFingerGesture_.windowId = twoFingerGesture_.touchEvent->GetTargetWindowId();
626 twoFingerGesture_.windowPid = WIN_MGR->GetWindowPid(twoFingerGesture_.windowId);
627 auto now = std::chrono::high_resolution_clock::now();
628 auto duration = now.time_since_epoch();
629 twoFingerGesture_.startTime = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
630 }, "KeyCommandHandler-StartTwoFingerGesture");
631 }
632
StopTwoFingerGesture()633 void KeyCommandHandler::StopTwoFingerGesture()
634 {
635 CALL_DEBUG_ENTER;
636 if (twoFingerGesture_.timerId != -1) {
637 TimerMgr->RemoveTimer(twoFingerGesture_.timerId);
638 twoFingerGesture_.timerId = -1;
639 }
640 }
641
CheckTwoFingerGestureAction() const642 bool KeyCommandHandler::CheckTwoFingerGestureAction() const
643 {
644 if (!twoFingerGesture_.active) {
645 return false;
646 }
647
648 auto firstFinger = twoFingerGesture_.touches[0];
649 auto secondFinger = twoFingerGesture_.touches[1];
650
651 auto pressTimeInterval = fabs(firstFinger.downTime - secondFinger.downTime);
652 if (pressTimeInterval > TWO_FINGERS_TIME_LIMIT) {
653 return false;
654 }
655
656 #ifdef OHOS_BUILD_ENABLE_TOUCH
657 auto devX = firstFinger.x - secondFinger.x;
658 auto devY = firstFinger.y - secondFinger.y;
659 auto distance = sqrt(pow(devX, 2) + pow(devY, 2));
660 if (distance < ConvertVPToPX(TWO_FINGERS_DISTANCE_LIMIT)) {
661 MMI_HILOGI("Two fingers distance:%{public}f too small", distance);
662 return false;
663 }
664
665 auto displayInfo = WIN_MGR->GetDefaultDisplayInfo();
666 CHKPR(displayInfo, false);
667 auto leftLimit = ConvertVPToPX(TOUCH_LIFT_LIMIT);
668 auto rightLimit = displayInfo->width - ConvertVPToPX(TOUCH_RIGHT_LIMIT);
669 auto topLimit = ConvertVPToPX(TOUCH_TOP_LIMIT);
670 auto bottomLimit = displayInfo->height - ConvertVPToPX(TOUCH_BOTTOM_LIMIT);
671 if (firstFinger.x <= leftLimit || firstFinger.x >= rightLimit ||
672 firstFinger.y <= topLimit || firstFinger.y >= bottomLimit ||
673 secondFinger.x <= leftLimit || secondFinger.x >= rightLimit ||
674 secondFinger.y <= topLimit || secondFinger.y >= bottomLimit) {
675 MMI_HILOGI("Any finger out of region");
676 return false;
677 }
678 #endif // OHOS_BUILD_ENABLE_TOUCH
679
680 return true;
681 }
682 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
683
684 #ifdef OHOS_BUILD_ENABLE_TOUCH
ConvertVPToPX(int32_t vp) const685 int32_t KeyCommandHandler::ConvertVPToPX(int32_t vp) const
686 {
687 if (vp <= 0) {
688 return 0;
689 }
690 auto displayInfo = WIN_MGR->GetDefaultDisplayInfo();
691 CHKPR(displayInfo, 0);
692 int32_t dpi = displayInfo->dpi;
693 if (dpi <= 0) {
694 return 0;
695 }
696 const int32_t base = 160;
697 return vp * (dpi / base);
698 }
699 #endif // OHOS_BUILD_ENABLE_TOUCH
700
701 #ifdef OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
HandleKnuckleGestureEvent(std::shared_ptr<PointerEvent> touchEvent)702 void KeyCommandHandler::HandleKnuckleGestureEvent(std::shared_ptr<PointerEvent> touchEvent)
703 {
704 CALL_DEBUG_ENTER;
705 if (!CheckKnuckleCondition(touchEvent)) {
706 return;
707 }
708 CHKPV(touchEvent);
709 int32_t touchAction = touchEvent->GetPointerAction();
710 if (IsValidAction(touchAction)) {
711 switch (touchAction) {
712 case PointerEvent::POINTER_ACTION_CANCEL:
713 case PointerEvent::POINTER_ACTION_UP: {
714 HandleKnuckleGestureTouchUp(touchEvent);
715 break;
716 }
717 case PointerEvent::POINTER_ACTION_MOVE: {
718 HandleKnuckleGestureTouchMove(touchEvent);
719 break;
720 }
721 case PointerEvent::POINTER_ACTION_DOWN: {
722 HandleKnuckleGestureTouchDown(touchEvent);
723 break;
724 }
725 default:
726 MMI_HILOGD("Unknown pointer action:%{public}d", touchAction);
727 break;
728 }
729 }
730 }
731
CheckKnuckleCondition(std::shared_ptr<PointerEvent> touchEvent)732 bool KeyCommandHandler::CheckKnuckleCondition(std::shared_ptr<PointerEvent> touchEvent)
733 {
734 CHKPF(touchEvent);
735 PointerEvent::PointerItem item;
736 touchEvent->GetPointerItem(touchEvent->GetPointerId(), item);
737 if (item.GetToolType() != PointerEvent::TOOL_TYPE_KNUCKLE ||
738 touchEvent->GetPointerIds().size() != SINGLE_KNUCKLE_SIZE || singleKnuckleGesture_.state) {
739 MMI_HILOGD("Touch tool type is:%{public}d", item.GetToolType());
740 ResetKnuckleGesture();
741 return false;
742 }
743 auto physicDisplayInfo = WIN_MGR->GetPhysicalDisplay(touchEvent->GetTargetDisplayId());
744 if (physicDisplayInfo != nullptr && physicDisplayInfo->direction != lastDirection_) {
745 lastDirection_ = physicDisplayInfo->direction;
746 if (touchEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_MOVE && !gesturePoints_.empty()) {
747 MMI_HILOGW("The screen has been rotated while knuckle is moving");
748 ResetKnuckleGesture();
749 return false;
750 }
751 }
752 if (CheckInputMethodArea(touchEvent)) {
753 if (touchEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_DOWN ||
754 touchEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_UP) {
755 MMI_HILOGI("In input method area, skip");
756 }
757 return false;
758 }
759 return true;
760 }
761
IsValidAction(int32_t action)762 bool KeyCommandHandler::IsValidAction(int32_t action)
763 {
764 CALL_DEBUG_ENTER;
765 if (action == PointerEvent::POINTER_ACTION_DOWN ||
766 ((action == PointerEvent::POINTER_ACTION_MOVE || action == PointerEvent::POINTER_ACTION_UP ||
767 action == PointerEvent::POINTER_ACTION_CANCEL) && !gesturePoints_.empty())) {
768 return true;
769 }
770 return false;
771 }
772
CalcDrawCoordinate(const OLD::DisplayInfo & displayInfo,PointerEvent::PointerItem pointerItem)773 std::pair<int32_t, int32_t> KeyCommandHandler::CalcDrawCoordinate(const OLD::DisplayInfo& displayInfo,
774 PointerEvent::PointerItem pointerItem)
775 {
776 CALL_DEBUG_ENTER;
777 double physicalX = pointerItem.GetRawDisplayX();
778 double physicalY = pointerItem.GetRawDisplayY();
779 if (!displayInfo.transform.empty()) {
780 auto displayXY = WIN_MGR->TransformDisplayXY(displayInfo, physicalX, physicalY);
781 physicalX = displayXY.first;
782 physicalY = displayXY.second;
783 }
784 return {static_cast<int32_t>(physicalX), static_cast<int32_t>(physicalY)};
785 }
786
HandleKnuckleGestureTouchDown(std::shared_ptr<PointerEvent> touchEvent)787 void KeyCommandHandler::HandleKnuckleGestureTouchDown(std::shared_ptr<PointerEvent> touchEvent)
788 {
789 CALL_DEBUG_ENTER;
790 CHKPV(touchEvent);
791 ResetKnuckleGesture();
792 isStartBase_ = false;
793 int32_t id = touchEvent->GetPointerId();
794 PointerEvent::PointerItem item;
795 touchEvent->GetPointerItem(id, item);
796 sessionKey_ = "Base" + std::to_string(item.GetDownTime());
797 auto displayInfo = WIN_MGR->GetPhysicalDisplay(touchEvent->GetTargetDisplayId());
798 CHKPV(displayInfo);
799 auto displayXY = CalcDrawCoordinate(*displayInfo, item);
800 gestureLastX_ = displayXY.first;
801 gestureLastY_ = displayXY.second;
802
803 gesturePoints_.emplace_back(gestureLastX_);
804 gesturePoints_.emplace_back(gestureLastY_);
805 gestureTimeStamps_.emplace_back(touchEvent->GetActionTime());
806 }
807
HandleKnuckleGestureTouchMove(std::shared_ptr<PointerEvent> touchEvent)808 void KeyCommandHandler::HandleKnuckleGestureTouchMove(std::shared_ptr<PointerEvent> touchEvent)
809 {
810 CALL_DEBUG_ENTER;
811 CHKPV(touchEvent);
812 PointerEvent::PointerItem item;
813 touchEvent->GetPointerItem(touchEvent->GetPointerId(), item);
814 auto displayInfo = WIN_MGR->GetPhysicalDisplay(touchEvent->GetTargetDisplayId());
815 CHKPV(displayInfo);
816 auto displayXY = CalcDrawCoordinate(*displayInfo, item);
817 float eventX = displayXY.first;
818 float eventY = displayXY.second;
819 float dx = std::abs(eventX - gestureLastX_);
820 float dy = std::abs(eventY - gestureLastY_);
821 if (dx >= MOVE_TOLERANCE || dy >= MOVE_TOLERANCE) {
822 gestureLastX_ = eventX;
823 gestureLastY_ = eventY;
824 gesturePoints_.emplace_back(gestureLastX_);
825 gesturePoints_.emplace_back(gestureLastY_);
826 gestureTimeStamps_.emplace_back(touchEvent->GetActionTime());
827 if (!isStartBase_ && IsMatchedAbility(gesturePoints_, gestureLastX_, gestureLastY_)) {
828 MMI_HILOGI("First time start aility, size:%{public}zu", gesturePoints_.size());
829 ProcessKnuckleGestureTouchUp(NotifyType::REGIONGESTURE);
830 isStartBase_ = true;
831 }
832 if (!isGesturing_) {
833 gestureTrackLength_ += sqrt(dx * dx + dy * dy);
834 if (gestureTrackLength_ > MIN_GESTURE_STROKE_LENGTH) {
835 isGesturing_ = true;
836 }
837 }
838 if (isGesturing_ && !isLetterGesturing_) {
839 auto GetBoundingSquareness = GESTURESENSE_WRAPPER->getBoundingSquareness_;
840 CHKPV(GetBoundingSquareness);
841 auto boundingSquareness = GetBoundingSquareness(gesturePoints_);
842 if (boundingSquareness > MIN_LETTER_GESTURE_SQUARENESS) {
843 isLetterGesturing_ = true;
844 }
845 }
846 }
847 }
848
HandleKnuckleGestureTouchUp(std::shared_ptr<PointerEvent> touchEvent)849 void KeyCommandHandler::HandleKnuckleGestureTouchUp(std::shared_ptr<PointerEvent> touchEvent)
850 {
851 CALL_DEBUG_ENTER;
852 CHKPV(touchEvent);
853 auto touchUp = GESTURESENSE_WRAPPER->touchUp_;
854 CHKPV(touchUp);
855 MMI_HILOGI("Knuckle gesturePoints size:%{public}zu, isGesturing:%{public}d, isLetterGesturing:%{public}d",
856 gesturePoints_.size(), isGesturing_, isLetterGesturing_);
857 NotifyType notifyType = static_cast<NotifyType>(touchUp(gesturePoints_, gestureTimeStamps_,
858 isGesturing_, isLetterGesturing_));
859 switch (notifyType) {
860 case NotifyType::REGIONGESTURE: {
861 if (HasScreenCapturePermission(KNUCKLE_ENABLE_AI_BASE)) {
862 ProcessKnuckleGestureTouchUp(notifyType);
863 } else {
864 MMI_HILOGI("knuckle_enable_ai_base is skipped in HandleKnuckleGestureTouchUp, "
865 "screenCapturePermission_:%{public}d",
866 screenCapturePermission_);
867 }
868 drawOSuccTimestamp_ = touchEvent->GetActionTime();
869 ReportRegionGesture();
870 break;
871 }
872 case NotifyType::LETTERGESTURE: {
873 if (HasScreenCapturePermission(KNUCKLE_SCROLL_SCREENSHOT)) {
874 ProcessKnuckleGestureTouchUp(notifyType);
875 } else {
876 MMI_HILOGI("knuckle_scroll_screenshot is skipped in HandleKnuckleGestureTouchUp, "
877 "screenCapturePermission_:%{public}d",
878 screenCapturePermission_);
879 }
880 drawOFailTimestamp_ = touchEvent->GetActionTime();
881 ReportLetterGesture();
882 break;
883 }
884 default: {
885 MMI_HILOGW("Not a region gesture or letter gesture, notifyType:%{public}d", notifyType);
886 drawOFailTimestamp_ = touchEvent->GetActionTime();
887 ReportIfNeed();
888 break;
889 }
890 }
891 ResetKnuckleGesture();
892 }
893
ProcessKnuckleGestureTouchUp(NotifyType type)894 void KeyCommandHandler::ProcessKnuckleGestureTouchUp(NotifyType type)
895 {
896 Ability ability;
897 ability.abilityType = EXTENSION_ABILITY;
898 if (type == NotifyType::REGIONGESTURE) {
899 ability.abilityName = WAKEUP_ABILITY_NAME;
900 ability.bundleName = BUNDLE_NAME_PARSER.GetBundleName("AIBASE_BUNDLE_NAME");
901 ability.params.emplace(std::make_pair("shot_type", "smart-shot"));
902 MMI_HILOGI("The isStartBase_:%{public}d, sessionKey_:%{public}s", isStartBase_, sessionKey_.c_str());
903 if (!isStartBase_) {
904 ability.params.emplace(std::make_pair("fingerPath", ""));
905 ability.params.emplace(std::make_pair("launch_type", "knuckle_gesture_pre"));
906 } else {
907 ability.params.emplace(std::make_pair("fingerPath", GesturePointsToStr()));
908 ability.params.emplace(std::make_pair("launch_type", "knuckle_gesture"));
909 }
910 ability.params.emplace(std::make_pair("session_id", sessionKey_));
911 } else if (type == NotifyType::LETTERGESTURE) {
912 ability.abilityName = BUNDLE_NAME_PARSER.GetBundleName("SCREENSHOT_ABILITY_NAME");
913 ability.bundleName = BUNDLE_NAME_PARSER.GetBundleName("SCREENSHOT_BUNDLE_NAME");
914 ability.params.emplace(std::make_pair("shot_type", "scroll-shot"));
915 ability.params.emplace(std::make_pair("trigger_type", "knuckle"));
916 }
917 LaunchAbility(ability, NO_DELAY);
918 }
919
ResetKnuckleGesture()920 void KeyCommandHandler::ResetKnuckleGesture()
921 {
922 gestureLastX_ = 0.0f;
923 gestureLastY_ = 0.0f;
924 isGesturing_ = false;
925 isLetterGesturing_ = false;
926 gestureTrackLength_ = 0.0f;
927 gesturePoints_.clear();
928 gestureTimeStamps_.clear();
929 }
930
GesturePointsToStr() const931 std::string KeyCommandHandler::GesturePointsToStr() const
932 {
933 int32_t count = static_cast<int32_t>(gesturePoints_.size());
934 if (count % EVEN_NUMBER != 0 || count == 0) {
935 MMI_HILOGE("Invalid gesturePoints_ size");
936 return {};
937 }
938 cJSON *jsonArray = cJSON_CreateArray();
939 CHKFR(jsonArray, {}, "Invalid jsonArray");
940 for (int32_t i = 0; i < count; i += EVEN_NUMBER) {
941 cJSON *jsonData = cJSON_CreateObject();
942 CHKPC(jsonData);
943 cJSON_AddItemToObject(jsonData, "x", cJSON_CreateNumber(gesturePoints_[i]));
944 cJSON_AddItemToObject(jsonData, "y", cJSON_CreateNumber(gesturePoints_[i + 1]));
945 cJSON_AddItemToArray(jsonArray, jsonData);
946 }
947 char *jsonString = cJSON_Print(jsonArray);
948 std::string result = std::string(jsonString);
949 cJSON_Delete(jsonArray);
950 cJSON_free(jsonString);
951 return result;
952 }
953
ReportIfNeed()954 void KeyCommandHandler::ReportIfNeed()
955 {
956 if (!isGesturing_) {
957 return;
958 }
959 DfxHisysevent::ReportKnuckleGestureFaildTimes();
960 DfxHisysevent::ReportKnuckleGestureTrackLength(gestureTrackLength_);
961 DfxHisysevent::ReportKnuckleGestureTrackTime(gestureTimeStamps_);
962 if (isLastGestureSucceed_) {
963 DfxHisysevent::ReportKnuckleGestureFromSuccessToFailTime(drawOFailTimestamp_ - drawOSuccTimestamp_);
964 }
965 isLastGestureSucceed_ = false;
966 }
967
ReportRegionGesture()968 void KeyCommandHandler::ReportRegionGesture()
969 {
970 DfxHisysevent::ReportSmartShotSuccTimes();
971 ReportGestureInfo();
972 }
973
ReportLetterGesture()974 void KeyCommandHandler::ReportLetterGesture()
975 {
976 DfxHisysevent::ReportKnuckleDrawSSuccessTimes();
977 ReportGestureInfo();
978 }
979
ReportGestureInfo()980 void KeyCommandHandler::ReportGestureInfo()
981 {
982 DfxHisysevent::ReportKnuckleGestureTrackLength(gestureTrackLength_);
983 DfxHisysevent::ReportKnuckleGestureTrackTime(gestureTimeStamps_);
984 if (!isLastGestureSucceed_) {
985 DfxHisysevent::ReportKnuckleGestureFromFailToSuccessTime(drawOSuccTimestamp_ - drawOFailTimestamp_);
986 }
987 isLastGestureSucceed_ = true;
988 }
989
IsMatchedAbility(std::vector<float> gesturePoints,float gestureLastX,float gestureLastY)990 bool KeyCommandHandler::IsMatchedAbility(std::vector<float> gesturePoints,
991 float gestureLastX, float gestureLastY)
992 {
993 if (gesturePoints.size() < POINTER_NUMBER) {
994 MMI_HILOGI("The gesturePoints_ is empty");
995 return false;
996 }
997 float gestureFirstX = gesturePoints[0];
998 float gestureFirstY = gesturePoints[1];
999 float distance = std::min(std::abs(gestureLastX - gestureFirstX), std::abs(gestureLastY - gestureFirstY));
1000 return distance >= MIN_START_GESTURE;
1001 }
1002 #endif // OHOS_BUILD_ENABLE_GESTURESENSE_WRAPPER
1003
ParseConfig()1004 bool KeyCommandHandler::ParseConfig()
1005 {
1006 const std::string defaultConfig { "/system/etc/multimodalinput/ability_launch_config.json" };
1007 const char configName[] { "/etc/multimodalinput/ability_launch_config.json" };
1008 char buf[MAX_PATH_LEN] {};
1009
1010 char *filePath = ::GetOneCfgFile(configName, buf, sizeof(buf));
1011 if (filePath == nullptr || filePath[0] == '\0' || strlen(filePath) > MAX_PATH_LEN) {
1012 MMI_HILOGD("Can not get customization config file");
1013 return ParseJson(defaultConfig);
1014 }
1015 std::string customConfig = filePath;
1016 MMI_HILOGD("The configuration file path:%{private}s", customConfig.c_str());
1017 return ParseJson(customConfig) || ParseJson(defaultConfig);
1018 }
1019
ParseExcludeConfig()1020 bool KeyCommandHandler::ParseExcludeConfig()
1021 {
1022 const std::string defaultConfig { "/system/etc/multimodalinput/exclude_keys_config.json" };
1023 const char configName[] { "/etc/multimodalinput/exclude_keys_config.json" };
1024 char buf[MAX_PATH_LEN] {};
1025
1026 char *filePath = ::GetOneCfgFile(configName, buf, sizeof(buf));
1027 if (filePath == nullptr || filePath[0] == '\0' || strlen(filePath) > MAX_PATH_LEN) {
1028 MMI_HILOGD("Can not get customization exclude_keys_config.json file");
1029 return ParseExcludeJson(defaultConfig);
1030 }
1031 std::string customConfig = filePath;
1032 MMI_HILOGD("The exclude_keys_config.json file path:%s", customConfig.c_str());
1033 return ParseExcludeJson(customConfig) || ParseExcludeJson(defaultConfig);
1034 }
1035
ParseRepeatKeyMaxCount()1036 void KeyCommandHandler::ParseRepeatKeyMaxCount()
1037 {
1038 if (repeatKeys_.empty()) {
1039 maxCount_ = 0;
1040 }
1041 int32_t tempCount = 0;
1042 int32_t tempDelay = 0;
1043 for (RepeatKey& item : repeatKeys_) {
1044 if (item.times > tempCount) {
1045 tempCount = item.times;
1046 }
1047 if (item.delay > tempDelay) {
1048 tempDelay = item.delay;
1049 }
1050 if (item.ability.bundleName == BUNDLE_NAME_PARSER.GetBundleName("WALLET_BUNDLE_NAME")) {
1051 walletLaunchDelayTimes_ = item.delay;
1052 }
1053 }
1054 maxCount_ = tempCount;
1055 intervalTime_ = tempDelay;
1056 }
1057
CheckSpecialRepeatKey(RepeatKey & item,const std::shared_ptr<KeyEvent> keyEvent)1058 bool KeyCommandHandler::CheckSpecialRepeatKey(RepeatKey& item, const std::shared_ptr<KeyEvent> keyEvent)
1059 {
1060 if (item.keyCode != keyEvent->GetKeyCode()) {
1061 return false;
1062 }
1063 if (item.keyCode != KeyEvent::KEYCODE_VOLUME_DOWN) {
1064 return false;
1065 }
1066 std::string bundleName = item.ability.bundleName;
1067 std::string matchName = ".camera";
1068 if (bundleName.find(matchName) == std::string::npos) {
1069 return false;
1070 }
1071 std::string screenStatus = DISPLAY_MONITOR->GetScreenStatus();
1072 bool isScreenLocked = DISPLAY_MONITOR->GetScreenLocked();
1073 if (keyEvent->GetKeyCode() == item.keyCode && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) {
1074 repeatKey_.keyCode = item.keyCode;
1075 repeatKey_.keyAction = keyEvent->GetKeyAction();
1076 MMI_HILOGI("Update repeatkey status");
1077 }
1078 if (WIN_MGR->JudgeCameraInFore() &&
1079 (screenStatus != EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF && isScreenLocked)) {
1080 return true;
1081 }
1082 auto callState = DEVICE_MONITOR->GetCallState();
1083 if (callState == StateType::CALL_STATUS_ACTIVE || callState == StateType::CALL_STATUS_HOLDING ||
1084 callState == StateType::CALL_STATUS_INCOMING || callState == StateType::CALL_STATUS_ANSWERED) {
1085 return true;
1086 }
1087 MMI_HILOGI("ScreenStatus:%{public}s, isScreenLocked:%{public}d", screenStatus.c_str(), isScreenLocked);
1088 if ((screenStatus == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF || isScreenLocked) &&
1089 !IsMusicActivate()) {
1090 if (keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_DOWN) {
1091 MMI_HILOGD("lzc 0, PRODUCT_TYPE:%{public}s", PRODUCT_TYPE.c_str());
1092 #ifdef OHOS_BUILD_ENABLE_MISTOUCH_PREVENTION
1093 CallMistouchPrevention();
1094 #endif // OHOS_BUILD_ENABLE_MISTOUCH_PREVENTION
1095 MMI_HILOGI("CheckSpecialRepeatKey yes");
1096 }
1097 return false;
1098 }
1099 return true;
1100 }
1101
ParseJson(const std::string & configFile)1102 bool KeyCommandHandler::ParseJson(const std::string &configFile)
1103 {
1104 CALL_DEBUG_ENTER;
1105 std::string jsonStr = ReadJsonFile(configFile);
1106 if (jsonStr.empty()) {
1107 MMI_HILOGE("Read configFile failed");
1108 return false;
1109 }
1110 JsonParser parser(jsonStr.c_str());
1111 if (parser.Get() == nullptr) {
1112 MMI_HILOGE("parser is nullptr");
1113 return false;
1114 }
1115 if (!cJSON_IsObject(parser.Get())) {
1116 MMI_HILOGE("Parser.Get() is not object");
1117 return false;
1118 }
1119
1120 bool isParseShortKeys = ParseShortcutKeys(parser, shortcutKeys_, businessIds_);
1121 bool isParseSequences = ParseSequences(parser, sequences_);
1122 bool isParseTwoFingerGesture = ParseTwoFingerGesture(parser, twoFingerGesture_);
1123 bool isParseSingleKnuckleGesture = IsParseKnuckleGesture(parser, SINGLE_KNUCKLE_ABILITY, singleKnuckleGesture_);
1124 bool isParseDoubleKnuckleGesture = IsParseKnuckleGesture(parser, DOUBLE_KNUCKLE_ABILITY, doubleKnuckleGesture_);
1125 bool isParseMultiFingersTap = ParseMultiFingersTap(parser, TOUCHPAD_TRIP_TAP_ABILITY, threeFingersTap_);
1126 bool isParseRepeatKeys = ParseRepeatKeys(parser, repeatKeys_, repeatKeyMaxTimes_);
1127 screenshotSwitch_.statusConfig = SNAPSHOT_KNUCKLE_SWITCH;
1128 screenshotSwitch_.statusConfigValue = true;
1129 recordSwitch_.statusConfig = RECORD_KNUCKLE_SWITCH;
1130 recordSwitch_.statusConfigValue = true;
1131 if (!isParseShortKeys && !isParseSequences && !isParseTwoFingerGesture && !isParseSingleKnuckleGesture &&
1132 !isParseDoubleKnuckleGesture && !isParseMultiFingersTap && !isParseRepeatKeys) {
1133 MMI_HILOGE("Parse configFile failed");
1134 return false;
1135 }
1136
1137 Print();
1138 PrintSeq();
1139 return true;
1140 }
1141
ParseExcludeJson(const std::string & configFile)1142 bool KeyCommandHandler::ParseExcludeJson(const std::string &configFile)
1143 {
1144 CALL_DEBUG_ENTER;
1145 std::string jsonStr = ReadJsonFile(configFile);
1146 if (jsonStr.empty()) {
1147 MMI_HILOGE("Read excludeKey configFile failed");
1148 return false;
1149 }
1150 JsonParser parser(jsonStr.c_str());
1151 if (parser.Get() == nullptr) {
1152 MMI_HILOGE("parser is nullptr");
1153 return false;
1154 }
1155 if (!cJSON_IsObject(parser.Get())) {
1156 MMI_HILOGE("Parser.Get() of excludeKey is not object");
1157 return false;
1158 }
1159 bool isParseExcludeKeys = ParseExcludeKeys(parser, excludeKeys_);
1160 if (!isParseExcludeKeys) {
1161 MMI_HILOGE("Parse ExcludeKeys configFile failed");
1162 return false;
1163 }
1164 PrintExcludeKeys();
1165 return true;
1166 }
1167
Print()1168 void KeyCommandHandler::Print()
1169 {
1170 MMI_HILOGI("ShortcutKey count:%{public}zu", shortcutKeys_.size());
1171 int32_t row = 0;
1172 for (const auto &item : shortcutKeys_) {
1173 MMI_HILOGI("The row:%{public}d", row++);
1174 auto &shortcutKey = item.second;
1175 for (const auto &prekey : shortcutKey.preKeys) {
1176 MMI_HILOGI("The preKey:%d", prekey);
1177 }
1178 MMI_HILOGI("The finalKey:%d, keyDownDuration:%{public}d, triggerType:%{public}d,"
1179 " bundleName:%{public}s, abilityName:%{public}s", shortcutKey.finalKey,
1180 shortcutKey.keyDownDuration, shortcutKey.triggerType,
1181 shortcutKey.ability.bundleName.c_str(), shortcutKey.ability.abilityName.c_str());
1182 }
1183 }
1184
PrintExcludeKeys()1185 void KeyCommandHandler::PrintExcludeKeys()
1186 {
1187 size_t keysSize = excludeKeys_.size();
1188 for (size_t i = 0; i < keysSize; i++) {
1189 MMI_HILOGD("code:%{private}d, keyAction:%{public}d, delay:%{public}" PRId64,
1190 excludeKeys_[i].keyCode, excludeKeys_[i].keyAction, excludeKeys_[i].delay);
1191 }
1192 }
1193
PrintSeq()1194 void KeyCommandHandler::PrintSeq()
1195 {
1196 MMI_HILOGI("Sequences count:%{public}zu", sequences_.size());
1197 int32_t row = 0;
1198 for (const auto &item : sequences_) {
1199 MMI_HILOGI("The row:%{public}d", row++);
1200 for (const auto& sequenceKey : item.sequenceKeys) {
1201 MMI_HILOGI("code:%{private}d, keyAction:%{public}d, delay:%{public}" PRId64,
1202 sequenceKey.keyCode, sequenceKey.keyAction, sequenceKey.delay);
1203 }
1204 MMI_HILOGI("Ability bundleName:%{public}s, abilityName:%{public}s",
1205 item.ability.bundleName.c_str(), item.ability.abilityName.c_str());
1206 }
1207 }
1208
IsExcludeKey(const std::shared_ptr<KeyEvent> key)1209 bool KeyCommandHandler::IsExcludeKey(const std::shared_ptr<KeyEvent> key)
1210 {
1211 size_t keysSize = excludeKeys_.size();
1212 for (size_t i = 0; i < keysSize; i++) {
1213 if (key->GetKeyCode() == excludeKeys_[i].keyCode) {
1214 if (key->GetKeyAction() == excludeKeys_[i].keyAction) {
1215 return true;
1216 }
1217 }
1218 }
1219 return false;
1220 }
1221
IsEnableCombineKey(const std::shared_ptr<KeyEvent> key)1222 bool KeyCommandHandler::IsEnableCombineKey(const std::shared_ptr<KeyEvent> key)
1223 {
1224 CHKPF(key);
1225 if (enableCombineKey_) {
1226 return true;
1227 }
1228
1229 if (!isParseExcludeConfig_) {
1230 if (!ParseExcludeConfig()) {
1231 DfxHisysevent::ReportFailHandleKey("IsEnableCombineKey", key->GetKeyCode(),
1232 DfxHisysevent::KEY_ERROR_CODE::FAILED_PARSE_CONFIG);
1233 MMI_HILOGE("Parse Exclude configFile failed");
1234 return false;
1235 }
1236 isParseExcludeConfig_ = true;
1237 }
1238
1239 if (IsExcludeKey(key)) {
1240 if (EventLogHelper::IsBetaVersion() && !key->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) {
1241 MMI_HILOGD("ExcludekeyCode:%{private}d,ExcludekeyAction:%{public}d",
1242 key->GetKeyCode(), key->GetKeyAction());
1243 } else {
1244 MMI_HILOGD("ExcludekeyCode:%{private}d, ExcludekeyAction:%{public}d",
1245 key->GetKeyCode(), key->GetKeyAction());
1246 }
1247 auto items = key->GetKeyItems();
1248 MMI_HILOGI("KeyItemsSize:%{public}zu", items.size());
1249 if (items.size() != 1) {
1250 return enableCombineKey_;
1251 }
1252 return true;
1253 }
1254 if (key->GetKeyCode() == KeyEvent::KEYCODE_L) {
1255 for (const auto &item : key->GetKeyItems()) {
1256 int32_t keyCode = item.GetKeyCode();
1257 if (keyCode != KeyEvent::KEYCODE_L && keyCode != KeyEvent::KEYCODE_META_LEFT &&
1258 keyCode != KeyEvent::KEYCODE_META_RIGHT) {
1259 MMI_HILOGI("GetKeyCode:%{private}d", keyCode);
1260 return enableCombineKey_;
1261 }
1262 }
1263 return true;
1264 }
1265 if (key->GetKeyCode() == KeyEvent::KEYCODE_SYSRQ) {
1266 auto iterms = key->GetKeyItems();
1267 MMI_HILOGI("Recording response VM");
1268 return iterms.size() != 1 ? enableCombineKey_ : true;
1269 }
1270 return enableCombineKey_;
1271 }
1272
EnableCombineKey(bool enable)1273 int32_t KeyCommandHandler::EnableCombineKey(bool enable)
1274 {
1275 enableCombineKey_ = enable;
1276 MMI_HILOGI("Enable combineKey is successful in keyCommand handler, enable:%{public}d", enable);
1277 return RET_OK;
1278 }
1279
ParseStatusConfigObserver()1280 void KeyCommandHandler::ParseStatusConfigObserver()
1281 {
1282 CALL_DEBUG_ENTER;
1283 for (Sequence& item : sequences_) {
1284 if (item.statusConfig.empty()) {
1285 continue;
1286 }
1287 CreateStatusConfigObserver<Sequence>(item);
1288 }
1289
1290 for (auto& item : shortcutKeys_) {
1291 ShortcutKey &shortcutKey = item.second;
1292 if (shortcutKey.statusConfig.empty()) {
1293 continue;
1294 }
1295 CreateStatusConfigObserver<ShortcutKey>(shortcutKey);
1296 }
1297 }
1298
1299 template <class T>
CreateStatusConfigObserver(T & item)1300 void KeyCommandHandler::CreateStatusConfigObserver(T& item)
1301 {
1302 CALL_DEBUG_ENTER;
1303 SettingObserver::UpdateFunc updateFunc = [weak = weak_from_this(), &item](const std::string& key) {
1304 auto ptr = weak.lock();
1305 if (ptr == nullptr) {
1306 return;
1307 }
1308 bool statusValue = true;
1309 auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
1310 .GetBoolValue(key, statusValue);
1311 if (ret != RET_OK) {
1312 MMI_HILOGE("Get value from setting date fail");
1313 return;
1314 }
1315 MMI_HILOGI("Config changed key:%s, value:%{public}d", key.c_str(), statusValue);
1316 item.statusConfigValue = statusValue;
1317 ptr->OnKunckleSwitchStatusChange(item.statusConfig);
1318 };
1319 sptr<SettingObserver> statusObserver = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
1320 .CreateObserver(item.statusConfig, updateFunc);
1321 ErrCode ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).RegisterObserver(statusObserver);
1322 if (ret != ERR_OK) {
1323 MMI_HILOGE("Register setting observer failed, ret:%{public}d", ret);
1324 statusObserver = nullptr;
1325 }
1326 bool configVlaue = true;
1327 ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
1328 .GetBoolValue(item.statusConfig, configVlaue);
1329 if (ret != RET_OK) {
1330 MMI_HILOGE("Get value from setting date fail");
1331 return;
1332 }
1333 MMI_HILOGI("Get value success key:%s, value:%{public}d", item.statusConfig.c_str(), configVlaue);
1334 item.statusConfigValue = configVlaue;
1335 }
1336
RegisterKnuckleSwitchByUserId(int32_t userId)1337 int32_t KeyCommandHandler::RegisterKnuckleSwitchByUserId(int32_t userId)
1338 {
1339 CALL_DEBUG_ENTER;
1340 currentUserId_ = userId;
1341 CreateKnuckleConfigObserver(screenshotSwitch_);
1342 CreateKnuckleConfigObserver(recordSwitch_);
1343 return RET_OK;
1344 }
1345
1346 template <class T>
CreateKnuckleConfigObserver(T & item)1347 void KeyCommandHandler::CreateKnuckleConfigObserver(T& item)
1348 {
1349 CALL_DEBUG_ENTER;
1350 char buf[DEFAULT_BUFFER_LENGTH] {};
1351 if (sprintf_s(buf, sizeof(buf), SECURE_SETTING_URI_PROXY.c_str(), currentUserId_) < 0) {
1352 MMI_HILOGE("Failed to format URI");
1353 return;
1354 }
1355 SettingObserver::UpdateFunc updateFunc = [weak = weak_from_this(), &item, buf](const std::string& key) {
1356 auto ptr = weak.lock();
1357 if (ptr == nullptr) {
1358 return;
1359 }
1360 bool statusValue = true;
1361 ErrCode ret = RET_ERR;
1362 MMI_HILOGI("The statusConfig:%s", item.statusConfig.c_str());
1363 ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).GetBoolValue(key, statusValue,
1364 std::string(buf));
1365 if (ret != RET_OK) {
1366 MMI_HILOGE("Get value from setting data fail");
1367 item.statusConfigValue = true;
1368 return;
1369 }
1370 MMI_HILOGI("Config changed key:%s, value:%{public}d", key.c_str(), statusValue);
1371 item.statusConfigValue = statusValue;
1372 ptr->OnKunckleSwitchStatusChange(item.statusConfig);
1373 };
1374 sptr<SettingObserver> statusObserver = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
1375 .CreateObserver(item.statusConfig, updateFunc);
1376 ErrCode ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).RegisterObserver(statusObserver,
1377 std::string(buf));
1378 if (ret != ERR_OK) {
1379 MMI_HILOGE("Register setting observer failed, ret:%{public}d", ret);
1380 statusObserver = nullptr;
1381 }
1382 bool configValue = true;
1383 ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
1384 .GetBoolValue(item.statusConfig, configValue, std::string(buf));
1385 if (ret != RET_OK) {
1386 MMI_HILOGE("Get value from setting data fail");
1387 item.statusConfigValue = true;
1388 return;
1389 }
1390 MMI_HILOGI("Get value success key:%s, value:%{public}d", item.statusConfig.c_str(), configValue);
1391 item.statusConfigValue = configValue;
1392 }
1393
CreateKeyEvent(int32_t keyCode,int32_t keyAction,bool isPressed)1394 std::shared_ptr<KeyEvent> KeyCommandHandler::CreateKeyEvent(int32_t keyCode, int32_t keyAction, bool isPressed)
1395 {
1396 CALL_DEBUG_ENTER;
1397 std::shared_ptr<KeyEvent> keyEvent = KeyEvent::Create();
1398 CHKPP(keyEvent);
1399 KeyEvent::KeyItem item;
1400 item.SetKeyCode(keyCode);
1401 item.SetPressed(isPressed);
1402 keyEvent->SetKeyCode(keyCode);
1403 keyEvent->SetKeyAction(keyAction);
1404 keyEvent->AddPressedKeyItems(item);
1405 return keyEvent;
1406 }
1407
PreHandleEvent(const std::shared_ptr<KeyEvent> key)1408 bool KeyCommandHandler::PreHandleEvent(const std::shared_ptr<KeyEvent> key)
1409 {
1410 CHKPF(key);
1411 if (EventLogHelper::IsBetaVersion() && !key->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) {
1412 MMI_HILOGD("KeyEvent occured. code:%{private}d, keyAction:%{public}d",
1413 key->GetKeyCode(), key->GetKeyAction());
1414 } else {
1415 MMI_HILOGD("KeyEvent occured. code:%{private}d, keyAction:%{public}d",
1416 key->GetKeyCode(), key->GetKeyAction());
1417 }
1418 if (key->GetKeyCode() == KeyEvent::KEYCODE_F1) {
1419 DfxHisysevent::ReportKeyEvent("screen on");
1420 }
1421 if (!IsEnableCombineKey(key)) {
1422 MMI_HILOGI("Combine key is taken over in key command");
1423 return false;
1424 }
1425 if (!isParseConfig_) {
1426 if (!ParseConfig()) {
1427 MMI_HILOGE("Parse configFile failed");
1428 DfxHisysevent::ReportFailHandleKey("PreHandleEvent", key->GetKeyCode(),
1429 DfxHisysevent::KEY_ERROR_CODE::FAILED_PARSE_CONFIG);
1430 return false;
1431 }
1432 isParseConfig_ = true;
1433 }
1434 if (!isParseLongPressConfig_) {
1435 if (!ParseLongPressConfig()) {
1436 MMI_HILOGE("Parse long press configFile failed");
1437 DfxHisysevent::ReportFailHandleKey("PreHandleEvent", key->GetKeyCode(),
1438 DfxHisysevent::KEY_ERROR_CODE::FAILED_PARSE_CONFIG);
1439 }
1440 isParseLongPressConfig_ = true;
1441 }
1442 if (!isParseMaxCount_) {
1443 ParseRepeatKeyMaxCount();
1444 isParseMaxCount_ = true;
1445 }
1446 if (key->GetKeyCode() == KeyEvent::KEYCODE_VOLUME_DOWN || key->GetKeyCode() == KeyEvent::KEYCODE_VOLUME_UP) {
1447 lastVolumeDownActionTime_ = key->GetActionTime();
1448 }
1449 return true;
1450 }
1451
PreHandleEvent()1452 bool KeyCommandHandler::PreHandleEvent()
1453 {
1454 CALL_INFO_TRACE;
1455 if (!isParseConfig_) {
1456 if (!ParseConfig()) {
1457 MMI_HILOGE("Parse configFile failed");
1458 return false;
1459 }
1460 isParseConfig_ = true;
1461 }
1462 if (!isParseLongPressConfig_) {
1463 if (!ParseLongPressConfig()) {
1464 MMI_HILOGE("Parse long press configFile failed");
1465 }
1466 isParseLongPressConfig_ = true;
1467 }
1468 if (!isParseMaxCount_) {
1469 ParseRepeatKeyMaxCount();
1470 isParseMaxCount_ = true;
1471 }
1472 return true;
1473 }
1474
HandleEvent(const std::shared_ptr<KeyEvent> key)1475 bool KeyCommandHandler::HandleEvent(const std::shared_ptr<KeyEvent> key)
1476 {
1477 CALL_DEBUG_ENTER;
1478 CHKPF(key);
1479 if (!PreHandleEvent(key)) {
1480 return false;
1481 }
1482
1483 if (STYLUS_HANDLER->HandleStylusKey(key)) {
1484 DfxHisysevent::ReportKeyEvent("stylus");
1485 return true;
1486 }
1487
1488 bool shortKeysHandleRet = HandleShortKeys(key);
1489 if (key->GetKeyCode() == KeyEvent::KEYCODE_POWER && key->GetKeyAction() == KeyEvent::KEY_ACTION_UP) {
1490 powerUpTime_ = key->GetActionTime();
1491 }
1492 if (key->GetKeyCode() == KeyEvent::KEYCODE_POWER && key->GetKeyAction() == KeyEvent::KEY_ACTION_DOWN) {
1493 if ((key->GetActionTime() - powerUpTime_) > POWER_ACTION_INTERVAL * FREQUENCY &&
1494 (key->GetActionTime() - sosLaunchTime_) > SOS_WAIT_TIME * FREQUENCY) {
1495 MMI_HILOGI("Set isFreezePowerKey as false");
1496 isFreezePowerKey_ = false;
1497 }
1498 }
1499 if (key->GetKeyCode() == KeyEvent::KEYCODE_POWER && isFreezePowerKey_) {
1500 MMI_HILOGI("Freeze power key");
1501 return true;
1502 }
1503 bool sequencesHandleRet = HandleSequences(key);
1504 if (shortKeysHandleRet) {
1505 launchAbilityCount_ = 0;
1506 isHandleSequence_ = false;
1507 return true;
1508 }
1509 if (sequencesHandleRet) {
1510 isHandleSequence_ = true;
1511 return true;
1512 }
1513 if (key->GetKeyCode() == KeyEvent::KEYCODE_POWER) {
1514 MMI_HILOGI("Handle power key DownStart:%{public}d", isDownStart_);
1515 }
1516 if (key->GetKeyCode() != repeatKey_.keyCode && key->GetKeyAction() == KeyEvent::KEY_ACTION_DOWN) {
1517 isDownStart_ = false;
1518 }
1519 if (!isDownStart_) {
1520 HandleRepeatKeys(key);
1521 return false;
1522 } else {
1523 if (HandleRepeatKeys(key)) {
1524 MMI_HILOGI("Handle power key lifting event");
1525 return true;
1526 }
1527 }
1528 count_ = 0;
1529 repeatKeyCountMap_.clear();
1530 isDownStart_ = false;
1531 return false;
1532 }
1533
InitKeyObserver()1534 void KeyCommandHandler::InitKeyObserver()
1535 {
1536 if (!isParseStatusConfig_) {
1537 ParseStatusConfigObserver();
1538 isParseStatusConfig_ = true;
1539 }
1540 if (!isKnuckleSwitchConfig_) {
1541 CreateKnuckleConfigObserver(screenshotSwitch_);
1542 CreateKnuckleConfigObserver(recordSwitch_);
1543 isKnuckleSwitchConfig_ = true;
1544 }
1545 }
1546
1547 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
OnHandleEvent(const std::shared_ptr<KeyEvent> key)1548 bool KeyCommandHandler::OnHandleEvent(const std::shared_ptr<KeyEvent> key)
1549 {
1550 CALL_DEBUG_ENTER;
1551 CHKPF(key);
1552 HandlePointerVisibleKeys(key);
1553 if (HandleEvent(key)) {
1554 return true;
1555 }
1556
1557 if (specialKeys_.find(key->GetKeyCode()) != specialKeys_.end()) {
1558 HandleSpecialKeys(key->GetKeyCode(), key->GetKeyAction());
1559 return true;
1560 }
1561
1562 if (IsSpecialType(key->GetKeyCode(), SpecialType::SUBSCRIBER_BEFORE_DELAY)) {
1563 auto tmpKey = KeyEvent::Clone(key);
1564 int32_t timerId = TimerMgr->AddTimer(SPECIAL_KEY_DOWN_DELAY, 1, [this, tmpKey] () {
1565 MMI_HILOGD("Timer callback");
1566 auto it = specialTimers_.find(tmpKey->GetKeyCode());
1567 if (it != specialTimers_.end() && !it->second.empty()) {
1568 it->second.pop_front();
1569 }
1570 auto handler = InputHandler->GetSubscriberHandler();
1571 CHKPV(handler);
1572 handler->HandleKeyEvent(tmpKey);
1573 }, "KeyCommandHandler-OnHandleEvent");
1574 if (timerId < 0) {
1575 DfxHisysevent::ReportFailHandleKey("OnHandleEvent", key->GetKeyCode(),
1576 DfxHisysevent::KEY_ERROR_CODE::FAILED_TIMER);
1577 MMI_HILOGE("Add timer failed");
1578 return false;
1579 }
1580
1581 auto it = specialTimers_.find(key->GetKeyCode());
1582 if (it == specialTimers_.end()) {
1583 std::list<int32_t> timerIds;
1584 timerIds.push_back(timerId);
1585 auto it = specialTimers_.emplace(key->GetKeyCode(), timerIds);
1586 if (!it.second) {
1587 MMI_HILOGE("Keycode duplicated");
1588 return false;
1589 }
1590 } else {
1591 it->second.push_back(timerId);
1592 }
1593 MMI_HILOGD("Add timer success");
1594 return true;
1595 }
1596 return false;
1597 }
1598 #endif // OHOS_BUILD_ENABLE_KEYBOARD
1599
1600 #if defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)
OnHandleEvent(const std::shared_ptr<PointerEvent> pointer)1601 bool KeyCommandHandler::OnHandleEvent(const std::shared_ptr<PointerEvent> pointer)
1602 {
1603 CALL_DEBUG_ENTER;
1604 CHKPF(pointer);
1605 STYLUS_HANDLER->SetLastEventState(false);
1606 if (!isParseConfig_) {
1607 if (!ParseConfig()) {
1608 MMI_HILOGE("Parse configFile failed");
1609 return false;
1610 }
1611 isParseConfig_ = true;
1612 }
1613 if (!isParseLongPressConfig_) {
1614 if (!ParseLongPressConfig()) {
1615 MMI_HILOGE("Parse long press configFile failed");
1616 }
1617 isParseLongPressConfig_ = true;
1618 }
1619 return HandleMulFingersTap(pointer);
1620 }
1621 #endif // OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH
1622
HandleRepeatKeys(const std::shared_ptr<KeyEvent> keyEvent)1623 bool KeyCommandHandler::HandleRepeatKeys(const std::shared_ptr<KeyEvent> keyEvent)
1624 {
1625 CALL_DEBUG_ENTER;
1626 CHKPF(keyEvent);
1627 if (repeatKeys_.empty()) {
1628 MMI_HILOGD("No sequences configuration data");
1629 return false;
1630 }
1631
1632 bool waitRepeatKey = false;
1633
1634 for (RepeatKey& item : repeatKeys_) {
1635 if (CheckSpecialRepeatKey(item, keyEvent)) {
1636 launchAbilityCount_ = 0;
1637 MMI_HILOGI("Skip repeatKey");
1638 return false;
1639 }
1640 if (HandleKeyUpCancel(item, keyEvent)) {
1641 MMI_HILOGI("Cancel repeatKey");
1642 DfxHisysevent::ReportKeyEvent("cancel");
1643 return false;
1644 }
1645 if (HandleRepeatKeyCount(item, keyEvent)) {
1646 break;
1647 }
1648 }
1649
1650 for (RepeatKey& item : repeatKeys_) {
1651 bool isRepeatKey = HandleRepeatKey(item, keyEvent);
1652 if (isRepeatKey) {
1653 waitRepeatKey = true;
1654 }
1655 }
1656 MMI_HILOGI("Handle repeat key, waitRepeatKey:%{public}d", waitRepeatKey);
1657 return waitRepeatKey;
1658 }
1659
IsMusicActivate()1660 bool KeyCommandHandler::IsMusicActivate()
1661 {
1662 return InputScreenCaptureAgent::GetInstance().IsMusicActivate();
1663 }
1664
HandleRepeatKeyOwnCount(const RepeatKey & item)1665 void KeyCommandHandler::HandleRepeatKeyOwnCount(const RepeatKey &item)
1666 {
1667 if (item.ability.bundleName == BUNDLE_NAME_PARSER.GetBundleName("SOS_BUNDLE_NAME")) {
1668 if (downActionTime_ - lastDownActionTime_ < item.delay) {
1669 repeatKeyCountMap_[item.ability.bundleName]++;
1670 }
1671 } else if (downActionTime_ - upActionTime_ < item.delay) {
1672 repeatKeyCountMap_[item.ability.bundleName]++;
1673 }
1674 }
1675
HandleRepeatKey(const RepeatKey & item,const std::shared_ptr<KeyEvent> keyEvent)1676 bool KeyCommandHandler::HandleRepeatKey(const RepeatKey &item, const std::shared_ptr<KeyEvent> keyEvent)
1677 {
1678 CALL_DEBUG_ENTER;
1679 auto powerKeyLogger = [keyEvent, &item] () {
1680 if (keyEvent->GetKeyCode() == KeyEvent::KEYCODE_POWER) {
1681 MMI_HILOGI("Add ability, bundleName:%{public}s", item.ability.bundleName.c_str());
1682 }
1683 };
1684 CHKPF(keyEvent);
1685 if (keyEvent->GetKeyCode() != item.keyCode) {
1686 return false;
1687 }
1688 if (!isDownStart_) {
1689 return false;
1690 }
1691 if (keyEvent->GetKeyAction() != KeyEvent::KEY_ACTION_DOWN ||
1692 (count_ > maxCount_ && keyEvent->GetKeyCode() == KeyEvent::KEYCODE_POWER)) {
1693 MMI_HILOGI("The isDownStart:%{public}d", isDownStart_);
1694 if (isDownStart_) {
1695 HandleSpecialKeys(keyEvent->GetKeyCode(), keyEvent->GetKeyAction());
1696 }
1697 return true;
1698 }
1699 auto it = repeatKeyCountMap_.find(item.ability.bundleName);
1700 if (it == repeatKeyCountMap_.end()) {
1701 lastDownActionTime_ = downActionTime_;
1702 if (item.ability.bundleName != BUNDLE_NAME_PARSER.GetBundleName("SOS_BUNDLE_NAME") ||
1703 downActionTime_ - lastVolumeDownActionTime_ > SOS_INTERVAL_TIMES) {
1704 repeatKeyCountMap_.emplace(item.ability.bundleName, 1);
1705 powerKeyLogger();
1706 return true;
1707 }
1708 return false;
1709 }
1710 HandleRepeatKeyOwnCount(item);
1711 lastDownActionTime_ = downActionTime_;
1712 if (repeatKeyCountMap_[item.ability.bundleName] == item.times) {
1713 powerKeyLogger();
1714 if (!item.statusConfig.empty()) {
1715 bool statusValue = true;
1716 auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
1717 .GetBoolValue(item.statusConfig, statusValue);
1718 if (ret != RET_OK) {
1719 MMI_HILOGE("Get value from setting data fail");
1720 DfxHisysevent::ReportFailHandleKey("HandleRepeatKey", keyEvent->GetKeyCode(),
1721 DfxHisysevent::KEY_ERROR_CODE::ERROR_RETURN_VALUE);
1722 return false;
1723 }
1724 if (!statusValue) {
1725 MMI_HILOGE("Get value from setting data, result is false");
1726 return false;
1727 }
1728 }
1729 if (repeatKeyMaxTimes_.find(item.keyCode) != repeatKeyMaxTimes_.end()) {
1730 launchAbilityCount_ = count_;
1731 if (item.times < repeatKeyMaxTimes_[item.keyCode]) {
1732 return HandleRepeatKeyAbility(item, keyEvent, false);
1733 }
1734 return HandleRepeatKeyAbility(item, keyEvent, true);
1735 }
1736 }
1737 if (count_ > item.times && repeatKeyMaxTimes_.find(item.keyCode) != repeatKeyMaxTimes_.end() &&
1738 repeatKeyTimerIds_.find(item.ability.bundleName) != repeatKeyTimerIds_.end()) {
1739 if (count_ < repeatKeyMaxTimes_[item.keyCode] && repeatKeyTimerIds_[item.ability.bundleName] >= 0) {
1740 TimerMgr->RemoveTimer(repeatKeyTimerIds_[item.ability.bundleName]);
1741 repeatKeyTimerIds_.erase(item.ability.bundleName);
1742 powerKeyLogger();
1743 return true;
1744 }
1745 }
1746 return true;
1747 }
1748
HandleRepeatKeyAbility(const RepeatKey & item,const std::shared_ptr<KeyEvent> keyEvent,bool isMaxTimes)1749 bool KeyCommandHandler::HandleRepeatKeyAbility(const RepeatKey &item,
1750 const std::shared_ptr<KeyEvent> keyEvent, bool isMaxTimes)
1751 {
1752 if (!isMaxTimes) {
1753 int64_t delaytime = intervalTime_ - (downActionTime_ - upActionTime_);
1754 int32_t timerId = TimerMgr->AddTimer(
1755 delaytime / SECONDS_SYSTEM, 1, [this, item, keyEvent] () {
1756 LaunchRepeatKeyAbility(item, keyEvent);
1757 auto it = repeatKeyTimerIds_.find(item.ability.bundleName);
1758 if (it != repeatKeyTimerIds_.end()) {
1759 repeatKeyTimerIds_.erase(it);
1760 }
1761 }, "KeyCommandHandler-HandleRepeatKeyAbility");
1762 if (timerId < 0) {
1763 DfxHisysevent::ReportFailHandleKey("HandleRepeatKeyAbility", keyEvent->GetKeyCode(),
1764 DfxHisysevent::KEY_ERROR_CODE::FAILED_TIMER);
1765 return false;
1766 }
1767 if (repeatTimerId_ >= 0) {
1768 TimerMgr->RemoveTimer(repeatTimerId_);
1769 repeatTimerId_ = DEFAULT_VALUE;
1770 isHandleSequence_ = false;
1771 }
1772 if (repeatKeyTimerIds_.find(item.ability.bundleName) == repeatKeyTimerIds_.end()) {
1773 repeatKeyTimerIds_.emplace(item.ability.bundleName, timerId);
1774 return true;
1775 }
1776 repeatKeyTimerIds_[item.ability.bundleName] = timerId;
1777 return true;
1778 }
1779 LaunchRepeatKeyAbility(item, keyEvent);
1780 return true;
1781 }
1782
LaunchRepeatKeyAbility(const RepeatKey & item,const std::shared_ptr<KeyEvent> keyEvent)1783 void KeyCommandHandler::LaunchRepeatKeyAbility(const RepeatKey &item, const std::shared_ptr<KeyEvent> keyEvent)
1784 {
1785 BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_REPEAT_KEY, item.ability.bundleName);
1786 DfxHisysevent::ReportKeyEvent(item.ability.bundleName);
1787 std::string bundleName = item.ability.bundleName;
1788 std::string matchName = ".camera";
1789 if (item.keyCode == KeyEvent::KEYCODE_VOLUME_DOWN && bundleName.find(matchName) != std::string::npos) {
1790 MMI_HILOGD("ret_ %{public}d", ret_.load());
1791 if (ret_ != LIGHT_STAY_AWAY) {
1792 LaunchAbility(item.ability);
1793 launchAbilityCount_ = 0;
1794 CHKPV(mistouchPrevention_);
1795 MMI_HILOGI("Launch yes");
1796 }
1797 #ifdef OHOS_BUILD_ENABLE_MISTOUCH_PREVENTION
1798 UnregisterMistouchPrevention();
1799 #endif // OHOS_BUILD_ENABLE_MISTOUCH_PREVENTION
1800 } else {
1801 LaunchAbility(item.ability);
1802 }
1803 BytraceAdapter::StopLaunchAbility();
1804 repeatKeyCountMap_.clear();
1805 auto subscriberHandler = InputHandler->GetSubscriberHandler();
1806 CHKPV(subscriberHandler);
1807 auto keyEventCancel = std::make_shared<KeyEvent>(*keyEvent);
1808 keyEventCancel->SetKeyAction(KeyEvent::KEY_ACTION_CANCEL);
1809 subscriberHandler->HandleKeyEvent(keyEventCancel);
1810 }
1811
SetIsFreezePowerKey(const std::string pageName)1812 int32_t KeyCommandHandler::SetIsFreezePowerKey(const std::string pageName)
1813 {
1814 CALL_INFO_TRACE;
1815 std::lock_guard<std::mutex> lock(mutex_);
1816 if (pageName != "SosCountdown") {
1817 isFreezePowerKey_ = false;
1818 return RET_OK;
1819 }
1820 isFreezePowerKey_ = true;
1821 sosLaunchTime_ = OHOS::MMI::GetSysClockTime();
1822 count_ = 0;
1823 launchAbilityCount_ = 0;
1824 repeatKeyCountMap_.clear();
1825 if (sosDelayTimerId_ >= 0) {
1826 TimerMgr->RemoveTimer(sosDelayTimerId_);
1827 sosDelayTimerId_ = DEFAULT_VALUE;
1828 }
1829 int32_t timerId = TimerMgr->AddTimer(
1830 SOS_COUNT_DOWN_TIMES / SECONDS_SYSTEM, 1, [this] () {
1831 MMI_HILOGW("Timeout, restore the power button");
1832 isFreezePowerKey_ = false;
1833 }, "KeyCommandHandler-SetIsFreezePowerKey");
1834 if (timerId < 0) {
1835 MMI_HILOGE("Add timer failed");
1836 isFreezePowerKey_ = false;
1837 return RET_ERR;
1838 }
1839 return RET_OK;
1840 }
1841
HandleKeyUpCancel(const RepeatKey & item,const std::shared_ptr<KeyEvent> keyEvent)1842 bool KeyCommandHandler::HandleKeyUpCancel(const RepeatKey &item, const std::shared_ptr<KeyEvent> keyEvent)
1843 {
1844 CALL_DEBUG_ENTER;
1845 CHKPF(keyEvent);
1846 if (keyEvent->GetKeyCode() == item.keyCode && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_CANCEL) {
1847 isKeyCancel_ = true;
1848 isDownStart_ = false;
1849 count_ = 0;
1850 repeatKeyCountMap_.clear();
1851 DfxHisysevent::ReportKeyEvent("cancel");
1852 return true;
1853 }
1854 return false;
1855 }
1856
HandleRepeatKeyCount(const RepeatKey & item,const std::shared_ptr<KeyEvent> keyEvent)1857 bool KeyCommandHandler::HandleRepeatKeyCount(const RepeatKey &item, const std::shared_ptr<KeyEvent> keyEvent)
1858 {
1859 CALL_DEBUG_ENTER;
1860 CHKPF(keyEvent);
1861
1862 if (keyEvent->GetKeyCode() == item.keyCode && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) {
1863 upActionTime_ = keyEvent->GetActionTime();
1864 repeatKey_.keyCode = item.keyCode;
1865 repeatKey_.keyAction = keyEvent->GetKeyAction();
1866 int64_t intervalTime = intervalTime_;
1867 if (item.keyCode == KeyEvent::KEYCODE_POWER) {
1868 intervalTime = intervalTime_ - (upActionTime_ - downActionTime_);
1869 if (walletLaunchDelayTimes_ != 0) {
1870 intervalTime = walletLaunchDelayTimes_;
1871 }
1872 }
1873 repeatTimerId_ = TimerMgr->AddTimer(intervalTime / SECONDS_SYSTEM, 1, [this] () {
1874 SendKeyEvent();
1875 repeatTimerId_ = -1;
1876 }, "KeyCommandHandler-HandleRepeatKeyCount");
1877 if (repeatTimerId_ < 0) {
1878 return false;
1879 }
1880 return true;
1881 }
1882
1883 if (keyEvent->GetKeyCode() == item.keyCode && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_DOWN) {
1884 if (repeatKey_.keyCode != item.keyCode) {
1885 count_ = 1;
1886 repeatKey_.keyCode = item.keyCode;
1887 repeatKey_.keyAction = keyEvent->GetKeyAction();
1888 } else {
1889 if (repeatKey_.keyAction == keyEvent->GetKeyAction()) {
1890 MMI_HILOGD("Repeat key, reset down status");
1891 count_ = 0;
1892 isDownStart_ = false;
1893 repeatKeyCountMap_.clear();
1894 return true;
1895 } else {
1896 repeatKey_.keyAction = keyEvent->GetKeyAction();
1897 count_++;
1898 MMI_HILOGD("Repeat count:%{public}d", count_);
1899 }
1900 }
1901 isDownStart_ = true;
1902 downActionTime_ = keyEvent->GetActionTime();
1903 if ((downActionTime_ - upActionTime_) < intervalTime_) {
1904 if (repeatTimerId_ >= 0) {
1905 TimerMgr->RemoveTimer(repeatTimerId_);
1906 repeatTimerId_ = -1;
1907 isHandleSequence_ = false;
1908 }
1909 }
1910 return true;
1911 }
1912 return false;
1913 }
1914
SendKeyEvent()1915 void KeyCommandHandler::SendKeyEvent()
1916 {
1917 CALL_DEBUG_ENTER;
1918 if (!isHandleSequence_) {
1919 MMI_HILOGD("Launch ability count:%{public}d count:%{public}d", launchAbilityCount_, count_);
1920 for (int32_t i = launchAbilityCount_; i < count_; i++) {
1921 int32_t keycode = repeatKey_.keyCode;
1922 if (IsSpecialType(keycode, SpecialType::KEY_DOWN_ACTION)) {
1923 HandleSpecialKeys(keycode, KeyEvent::KEY_ACTION_UP);
1924 }
1925 if (count_ == repeatKeyMaxTimes_[keycode] - 1 && keycode == KeyEvent::KEYCODE_POWER) {
1926 auto keyEventCancel = CreateKeyEvent(keycode, KeyEvent::KEY_ACTION_CANCEL, false);
1927 CHKPV(keyEventCancel);
1928 auto handler = InputHandler->GetSubscriberHandler();
1929 CHKPV(handler);
1930 handler->HandleKeyEvent(keyEventCancel);
1931 continue;
1932 }
1933 if (i != 0) {
1934 auto keyEventDown = CreateKeyEvent(keycode, KeyEvent::KEY_ACTION_DOWN, true);
1935 CHKPV(keyEventDown);
1936 auto handler = InputHandler->GetSubscriberHandler();
1937 CHKPV(handler);
1938 handler->HandleKeyEvent(keyEventDown);
1939 }
1940
1941 auto keyEventUp = CreateKeyEvent(keycode, KeyEvent::KEY_ACTION_UP, false);
1942 CHKPV(keyEventUp);
1943 auto handler = InputHandler->GetSubscriberHandler();
1944 CHKPV(handler);
1945 handler->HandleKeyEvent(keyEventUp);
1946 }
1947 }
1948 count_ = 0;
1949 repeatKeyCountMap_.clear();
1950 isDownStart_ = false;
1951 isHandleSequence_ = false;
1952 launchAbilityCount_ = 0;
1953 }
1954
HandleShortKeys(const std::shared_ptr<KeyEvent> keyEvent)1955 bool KeyCommandHandler::HandleShortKeys(const std::shared_ptr<KeyEvent> keyEvent)
1956 {
1957 CALL_DEBUG_ENTER;
1958 CHKPF(keyEvent);
1959 if (shortcutKeys_.empty()) {
1960 MMI_HILOGD("No shortkeys configuration data");
1961 return false;
1962 }
1963 if (IsKeyMatch(lastMatchedKey_, keyEvent)) {
1964 MMI_HILOGD("The same key is waiting timeout, skip");
1965 return true;
1966 }
1967 if (keyEvent->GetKeyCode() == KeyEvent::KEYCODE_VCR2 && WIN_MGR->JudgeCameraInFore()) {
1968 MMI_HILOGD("The camera has been activated");
1969 return false;
1970 }
1971 if (currentLaunchAbilityKey_.timerId >= 0 && IsKeyMatch(currentLaunchAbilityKey_, keyEvent)) {
1972 if (EventLogHelper::IsBetaVersion() && !keyEvent->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) {
1973 MMI_HILOGD("Repeat, current key %{public}d has launched ability", currentLaunchAbilityKey_.finalKey);
1974 } else {
1975 MMI_HILOGD("Repeat, current key %d has launched ability", currentLaunchAbilityKey_.finalKey);
1976 }
1977 return true;
1978 }
1979 DfxHisysevent::GetComboStartTime();
1980 if (lastMatchedKey_.timerId >= 0) {
1981 MMI_HILOGD("Remove timer:%{public}d", lastMatchedKey_.timerId);
1982 TimerMgr->RemoveTimer(lastMatchedKey_.timerId);
1983 lastMatchedKey_.timerId = -1;
1984 }
1985 ResetLastMatchedKey();
1986 if (MatchShortcutKeys(keyEvent)) {
1987 return true;
1988 }
1989 return HandleConsumedKeyEvent(keyEvent);
1990 }
1991
MatchShortcutKeys(const std::shared_ptr<KeyEvent> keyEvent)1992 bool KeyCommandHandler::MatchShortcutKeys(const std::shared_ptr<KeyEvent> keyEvent)
1993 {
1994 #ifdef SHORTCUT_KEY_RULES_ENABLED
1995 if ((keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) &&
1996 KEY_SHORTCUT_MGR->HaveShortcutConsumed(keyEvent)) {
1997 return false;
1998 }
1999 #endif // SHORTCUT_KEY_RULES_ENABLED
2000 bool result = false;
2001 std::vector<ShortcutKey> upAbilities;
2002
2003 for (auto &item : shortcutKeys_) {
2004 result = MatchShortcutKey(keyEvent, item.second, upAbilities) || result;
2005 }
2006 if (!upAbilities.empty()) {
2007 std::sort(upAbilities.begin(), upAbilities.end(),
2008 [](const ShortcutKey &lShortcutKey, const ShortcutKey &rShortcutKey) -> bool {
2009 return lShortcutKey.keyDownDuration > rShortcutKey.keyDownDuration;
2010 });
2011 ShortcutKey tmpShorteKey = upAbilities.front();
2012 MMI_HILOGI("Start launch ability immediately");
2013 #ifdef SHORTCUT_KEY_RULES_ENABLED
2014 KEY_SHORTCUT_MGR->MarkShortcutConsumed(tmpShorteKey);
2015 #endif // SHORTCUT_KEY_RULES_ENABLED
2016 BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_SHORTKEY, tmpShorteKey.ability.bundleName);
2017 LaunchAbility(tmpShorteKey);
2018 DfxHisysevent::ReportKeyEvent(tmpShorteKey.ability.bundleName);
2019 BytraceAdapter::StopLaunchAbility();
2020 }
2021 if (result) {
2022 if (currentLaunchAbilityKey_.finalKey == keyEvent->GetKeyCode()
2023 && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) {
2024 ResetCurrentLaunchAbilityKey();
2025 }
2026 }
2027 return result;
2028 }
2029
MatchShortcutKey(std::shared_ptr<KeyEvent> keyEvent,ShortcutKey & shortcutKey,std::vector<ShortcutKey> & upAbilities)2030 bool KeyCommandHandler::MatchShortcutKey(std::shared_ptr<KeyEvent> keyEvent,
2031 ShortcutKey &shortcutKey, std::vector<ShortcutKey> &upAbilities)
2032 {
2033 if (!shortcutKey.statusConfigValue) {
2034 return false;
2035 }
2036 if (!IsKeyMatch(shortcutKey, keyEvent)) {
2037 MMI_HILOGD("Not key matched, next");
2038 return false;
2039 }
2040 int32_t delay = GetKeyDownDurationFromXml(shortcutKey.businessId);
2041 if (delay >= MIN_SHORT_KEY_DOWN_DURATION && delay <= MAX_SHORT_KEY_DOWN_DURATION) {
2042 MMI_HILOGD("User defined new short key down duration:%{public}d", delay);
2043 shortcutKey.keyDownDuration = delay;
2044 }
2045 shortcutKey.Print();
2046
2047 if (shortcutKey.triggerType == KeyEvent::KEY_ACTION_DOWN) {
2048 return HandleKeyDown(shortcutKey);
2049 } else if (shortcutKey.triggerType == KeyEvent::KEY_ACTION_UP) {
2050 bool handleResult = HandleKeyUp(keyEvent, shortcutKey);
2051 if (handleResult && shortcutKey.keyDownDuration > 0) {
2052 upAbilities.push_back(shortcutKey);
2053 }
2054 return handleResult;
2055 } else {
2056 return HandleKeyCancel(shortcutKey);
2057 }
2058 }
2059
HandleConsumedKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)2060 bool KeyCommandHandler::HandleConsumedKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
2061 {
2062 CALL_DEBUG_ENTER;
2063 CHKPF(keyEvent);
2064 if (currentLaunchAbilityKey_.finalKey == keyEvent->GetKeyCode()
2065 && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) {
2066 MMI_HILOGI("Handle consumed key event, cancel opration");
2067 ResetCurrentLaunchAbilityKey();
2068 repeatKey_.keyCode = -1;
2069 repeatKey_.keyAction = -1;
2070 auto keyEventCancel = std::make_shared<KeyEvent>(*keyEvent);
2071 keyEventCancel->SetKeyAction(KeyEvent::KEY_ACTION_CANCEL);
2072 auto inputEventNormalizeHandler = InputHandler->GetEventNormalizeHandler();
2073 CHKPF(inputEventNormalizeHandler);
2074 inputEventNormalizeHandler->HandleKeyEvent(keyEventCancel);
2075 return true;
2076 }
2077 return false;
2078 }
2079
IsRepeatKeyEvent(const SequenceKey & sequenceKey)2080 bool KeyCommandHandler::IsRepeatKeyEvent(const SequenceKey &sequenceKey)
2081 {
2082 for (size_t i = keys_.size(); i > 0; --i) {
2083 if (keys_[i - 1].keyCode == sequenceKey.keyCode) {
2084 if (keys_[i - 1].keyAction == sequenceKey.keyAction) {
2085 MMI_HILOGI("Is repeat key:%{private}d", sequenceKey.keyCode);
2086 return true;
2087 }
2088 MMI_HILOGI("Is not repeat key");
2089 return false;
2090 }
2091 }
2092 return false;
2093 }
2094
IsActiveSequenceRepeating(std::shared_ptr<KeyEvent> keyEvent) const2095 bool KeyCommandHandler::IsActiveSequenceRepeating(std::shared_ptr<KeyEvent> keyEvent) const
2096 {
2097 return (sequenceOccurred_ && !keys_.empty() &&
2098 (keys_.back().keyCode == keyEvent->GetKeyCode()) &&
2099 (keys_.back().keyAction == KeyEvent::KEY_ACTION_DOWN) &&
2100 (keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_DOWN));
2101 }
2102
MarkActiveSequence(bool active)2103 void KeyCommandHandler::MarkActiveSequence(bool active)
2104 {
2105 sequenceOccurred_ = active;
2106 }
2107
HandleSequences(const std::shared_ptr<KeyEvent> keyEvent)2108 bool KeyCommandHandler::HandleSequences(const std::shared_ptr<KeyEvent> keyEvent)
2109 {
2110 CALL_DEBUG_ENTER;
2111 CHKPF(keyEvent);
2112 std::string screenStatus = DISPLAY_MONITOR->GetScreenStatus();
2113 if (screenStatus == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
2114 if (keyEvent->GetKeyCode() == KeyEvent::KEYCODE_POWER) {
2115 MMI_HILOGI("The screen is currently off and the power button needs to respond");
2116 return false;
2117 }
2118 }
2119 if (IsActiveSequenceRepeating(keyEvent)) {
2120 MMI_HILOGD("Skip repeating key(%{private}d) in active sequence", keyEvent->GetKeyCode());
2121 return true;
2122 }
2123 MarkActiveSequence(false);
2124 if (matchedSequence_.timerId >= 0 && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) {
2125 MMI_HILOGI("Screen locked, remove matchedSequence timer:%{public}d", matchedSequence_.timerId);
2126 TimerMgr->RemoveTimer(matchedSequence_.timerId);
2127 matchedSequence_.timerId = -1;
2128 }
2129 if (sequences_.empty()) {
2130 MMI_HILOGD("No sequences configuration data");
2131 return false;
2132 }
2133
2134 if (!AddSequenceKey(keyEvent)) {
2135 MMI_HILOGD("Add new sequence key failed");
2136 return false;
2137 }
2138
2139 if (filterSequences_.empty()) {
2140 filterSequences_ = sequences_;
2141 }
2142
2143 bool isLaunchAbility = false;
2144 for (auto iter = filterSequences_.begin(); iter != filterSequences_.end();) {
2145 if (!HandleSequence((*iter), isLaunchAbility)) {
2146 filterSequences_.erase(iter);
2147 continue;
2148 }
2149 ++iter;
2150 }
2151
2152 if (filterSequences_.empty()) {
2153 MMI_HILOGD("No sequences matched");
2154 keys_.clear();
2155 return false;
2156 }
2157
2158 if (isLaunchAbility) {
2159 MarkActiveSequence(true);
2160 for (const auto& item : keys_) {
2161 if (IsSpecialType(item.keyCode, SpecialType::KEY_DOWN_ACTION)) {
2162 HandleSpecialKeys(item.keyCode, item.keyAction);
2163 }
2164 auto handler = InputHandler->GetSubscriberHandler();
2165 CHKPF(handler);
2166 handler->RemoveSubscriberKeyUpTimer(item.keyCode);
2167 RemoveSubscribedTimer(item.keyCode);
2168 }
2169 }
2170 return isLaunchAbility;
2171 }
2172
AddSequenceKey(const std::shared_ptr<KeyEvent> keyEvent)2173 bool KeyCommandHandler::AddSequenceKey(const std::shared_ptr<KeyEvent> keyEvent)
2174 {
2175 CALL_DEBUG_ENTER;
2176 CHKPF(keyEvent);
2177 SequenceKey sequenceKey;
2178 sequenceKey.keyCode = keyEvent->GetKeyCode();
2179 sequenceKey.keyAction = keyEvent->GetKeyAction();
2180 sequenceKey.actionTime = keyEvent->GetActionTime();
2181 size_t size = keys_.size();
2182 if (size > 0) {
2183 if (keys_[size - 1].actionTime > sequenceKey.actionTime) {
2184 MMI_HILOGE("The current event time is greater than the last event time");
2185 ResetSequenceKeys();
2186 return false;
2187 }
2188 if ((sequenceKey.actionTime - keys_[size - 1].actionTime) > MAX_DELAY_TIME) {
2189 MMI_HILOGD("The delay time is greater than the maximum delay time");
2190 ResetSequenceKeys();
2191 } else {
2192 if (IsRepeatKeyEvent(sequenceKey)) {
2193 MMI_HILOGD("This is a repeat key event, don't add");
2194 return false;
2195 }
2196 keys_[size - 1].delay = sequenceKey.actionTime - keys_[size - 1].actionTime;
2197 InterruptTimers();
2198 }
2199 }
2200 if (size > MAX_SEQUENCEKEYS_NUM) {
2201 DfxHisysevent::ReportFailHandleKey("AddSequenceKey", keyEvent->GetKeyCode(),
2202 DfxHisysevent::KEY_ERROR_CODE::INVALID_PARAMETER);
2203 MMI_HILOGD("The save key size more than the max size");
2204 return false;
2205 }
2206 keys_.push_back(sequenceKey);
2207 return true;
2208 }
2209
HandleScreenLocked(Sequence & sequence,bool & isLaunchAbility)2210 bool KeyCommandHandler::HandleScreenLocked(Sequence& sequence, bool &isLaunchAbility)
2211 {
2212 std::string bundleName = sequence.ability.bundleName;
2213 std::string matchName = ".screenshot";
2214 if (bundleName.find(matchName) != std::string::npos && !HasScreenCapturePermission(SHORTCUT_KEY_SCREENSHOT)) {
2215 MMI_HILOGI("shortcut_key_screenshot is skipped in HandleNormalSequence, "
2216 "screenCapturePermission_:%{public}d",
2217 screenCapturePermission_);
2218 isLaunchAbility = true;
2219 return true;
2220 }
2221 sequence.timerId = TimerMgr->AddTimer(LONG_ABILITY_START_DELAY, 1, [this, &sequence] () {
2222 MMI_HILOGI("Timer callback");
2223 BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_SEQUENCE, sequence.ability.bundleName);
2224 DfxHisysevent::ReportKeyEvent(sequence.ability.bundleName);
2225 LaunchAbility(sequence);
2226 sequence.timerId = -1;
2227 BytraceAdapter::StopLaunchAbility();
2228 }, "KeyCommandHandler-HandleScreenLocked");
2229 if (sequence.timerId < 0) {
2230 MMI_HILOGE("Add Timer failed");
2231 return false;
2232 }
2233 MMI_HILOGI("Add timer success");
2234 matchedSequence_ = sequence;
2235 isLaunchAbility = true;
2236 return true;
2237 }
2238
HandleNormalSequence(Sequence & sequence,bool & isLaunchAbility)2239 bool KeyCommandHandler::HandleNormalSequence(Sequence& sequence, bool &isLaunchAbility)
2240 {
2241 std::string bundleName = sequence.ability.bundleName;
2242 std::string matchName = ".screenshot";
2243 if (bundleName.find(matchName) != std::string::npos && !HasScreenCapturePermission(SHORTCUT_KEY_SCREENSHOT)) {
2244 MMI_HILOGI("shortcut_key_screenshot is skipped in HandleNormalSequence, "
2245 "screenCapturePermission_:%{public}d",
2246 screenCapturePermission_);
2247 isLaunchAbility = true;
2248 return true;
2249 }
2250 matchName = ".screenrecorder";
2251 if (bundleName.find(matchName) != std::string::npos && !HasScreenCapturePermission(SHORTCUT_KEY_SCREEN_RECORDING)) {
2252 MMI_HILOGI("shortcut_key_screen_recording is skipped in HandleNormalSequence, "
2253 "screenCapturePermission_:%{public}d",
2254 screenCapturePermission_);
2255 isLaunchAbility = true;
2256 return true;
2257 }
2258 if (sequence.abilityStartDelay == 0) {
2259 MMI_HILOGI("Start launch ability immediately");
2260 BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_SEQUENCE, sequence.ability.bundleName);
2261 LaunchAbility(sequence);
2262 DfxHisysevent::ReportKeyEvent(sequence.ability.bundleName);
2263 BytraceAdapter::StopLaunchAbility();
2264 isLaunchAbility = true;
2265 return true;
2266 }
2267 sequence.timerId = TimerMgr->AddTimer(sequence.abilityStartDelay, 1, [this, &sequence] () {
2268 MMI_HILOGI("Timer callback");
2269 BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_SEQUENCE, sequence.ability.bundleName);
2270 LaunchAbility(sequence);
2271 DfxHisysevent::ReportKeyEvent(sequence.ability.bundleName);
2272 sequence.timerId = -1;
2273 BytraceAdapter::StopLaunchAbility();
2274 }, "KeyCommandHandler-HandleNormalSequence");
2275 if (sequence.timerId < 0) {
2276 MMI_HILOGE("Add Timer failed");
2277 DfxHisysevent::ReportFailLaunchAbility(sequence.ability.bundleName,
2278 DfxHisysevent::KEY_ERROR_CODE::FAILED_TIMER);
2279 return false;
2280 }
2281 MMI_HILOGI("Add timer success");
2282 isLaunchAbility = true;
2283 return true;
2284 }
2285
HandleMatchedSequence(Sequence & sequence,bool & isLaunchAbility)2286 bool KeyCommandHandler::HandleMatchedSequence(Sequence& sequence, bool &isLaunchAbility)
2287 {
2288 std::string screenStatus = DISPLAY_MONITOR->GetScreenStatus();
2289 bool isScreenLocked = DISPLAY_MONITOR->GetScreenLocked();
2290 MMI_HILOGI("The screenStatus:%{public}s, isScreenLocked:%{public}d", screenStatus.c_str(), isScreenLocked);
2291 std::string bundleName = sequence.ability.bundleName;
2292 std::string matchName = ".screenshot";
2293 if (bundleName.find(matchName) != std::string::npos) {
2294 bundleName = bundleName.substr(bundleName.size() - matchName.size());
2295 }
2296 if (screenStatus == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
2297 if (bundleName == matchName) {
2298 MMI_HILOGI("Screen off, screenshot invalid");
2299 return false;
2300 }
2301 } else {
2302 if (bundleName == matchName && isScreenLocked) {
2303 MMI_HILOGI("Screen locked, screenshot delay 2000 milisecond");
2304 return HandleScreenLocked(sequence, isLaunchAbility);
2305 }
2306 }
2307 return HandleNormalSequence(sequence, isLaunchAbility);
2308 }
2309
HandleSequence(Sequence & sequence,bool & isLaunchAbility)2310 bool KeyCommandHandler::HandleSequence(Sequence &sequence, bool &isLaunchAbility)
2311 {
2312 CALL_DEBUG_ENTER;
2313 size_t keysSize = keys_.size();
2314 size_t sequenceKeysSize = sequence.sequenceKeys.size();
2315 if (!sequence.statusConfigValue) {
2316 return false;
2317 }
2318 if (keysSize > sequenceKeysSize) {
2319 MMI_HILOGI("The save sequence not matching ability sequence");
2320 return false;
2321 }
2322 for (size_t i = 0; i < keysSize; ++i) {
2323 if (keys_[i] != sequence.sequenceKeys[i]) {
2324 MMI_HILOGD("KeyAction not matching");
2325 return false;
2326 }
2327 int64_t delay = sequence.sequenceKeys[i].delay;
2328 if (((i + 1) != keysSize) && (delay != 0) && (keys_[i].delay >= delay)) {
2329 MMI_HILOGD("Delay is not matching");
2330 return false;
2331 }
2332 }
2333 if (keysSize == sequenceKeysSize) {
2334 std::ostringstream oss;
2335 oss << sequence;
2336 MMI_HILOGI("SequenceKey matched:%{private}s", oss.str().c_str());
2337 return HandleMatchedSequence(sequence, isLaunchAbility);
2338 }
2339 return true;
2340 }
2341
HandleMulFingersTap(const std::shared_ptr<PointerEvent> pointerEvent)2342 bool KeyCommandHandler::HandleMulFingersTap(const std::shared_ptr<PointerEvent> pointerEvent)
2343 {
2344 CALL_DEBUG_ENTER;
2345 if (pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_TRIPTAP) {
2346 MMI_HILOGI("The touchpad trip tap will launch ability");
2347 BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_MULTI_FINGERS, threeFingersTap_.ability.bundleName);
2348 LaunchAbility(threeFingersTap_.ability, NO_DELAY);
2349 BytraceAdapter::StopLaunchAbility();
2350 return true;
2351 }
2352 return false;
2353 }
2354
IsKeyMatch(const ShortcutKey & shortcutKey,const std::shared_ptr<KeyEvent> & key)2355 bool KeyCommandHandler::IsKeyMatch(const ShortcutKey &shortcutKey, const std::shared_ptr<KeyEvent> &key)
2356 {
2357 CALL_DEBUG_ENTER;
2358 CHKPF(key);
2359 if ((key->GetKeyCode() != shortcutKey.finalKey) || (shortcutKey.triggerType != key->GetKeyAction())) {
2360 DfxHisysevent::ReportFailHandleKey("IsKeyMatch", key->GetKeyCode(),
2361 DfxHisysevent::KEY_ERROR_CODE::INVALID_PARAMETER);
2362 return false;
2363 }
2364 if ((shortcutKey.preKeys.size() + 1) != key->GetKeyItems().size()) {
2365 return false;
2366 }
2367 for (const auto &item : key->GetKeyItems()) {
2368 int32_t keyCode = item.GetKeyCode();
2369 if (SkipFinalKey(keyCode, key)) {
2370 continue;
2371 }
2372 if (shortcutKey.preKeys.find(keyCode) == shortcutKey.preKeys.end()) {
2373 return false;
2374 }
2375 }
2376 MMI_HILOGD("Leave, key matched");
2377 return true;
2378 }
2379
SkipFinalKey(const int32_t keyCode,const std::shared_ptr<KeyEvent> & key)2380 bool KeyCommandHandler::SkipFinalKey(const int32_t keyCode, const std::shared_ptr<KeyEvent> &key)
2381 {
2382 CHKPF(key);
2383 return keyCode == key->GetKeyCode();
2384 }
2385
HandleKeyDown(ShortcutKey & shortcutKey)2386 bool KeyCommandHandler::HandleKeyDown(ShortcutKey &shortcutKey)
2387 {
2388 CALL_DEBUG_ENTER;
2389 if (shortcutKey.keyDownDuration == 0) {
2390 MMI_HILOGI("Start launch ability immediately");
2391 #ifdef SHORTCUT_KEY_RULES_ENABLED
2392 KEY_SHORTCUT_MGR->MarkShortcutConsumed(shortcutKey);
2393 #endif // SHORTCUT_KEY_RULES_ENABLED
2394 BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_SHORTKEY, shortcutKey.ability.bundleName);
2395 LaunchAbility(shortcutKey);
2396 DfxHisysevent::ReportKeyEvent(shortcutKey.ability.bundleName);
2397 BytraceAdapter::StopLaunchAbility();
2398 return true;
2399 }
2400 shortcutKey.timerId = TimerMgr->AddTimer(shortcutKey.keyDownDuration, 1, [this, &shortcutKey] () {
2401 MMI_HILOGI("Timer callback");
2402 #ifdef SHORTCUT_KEY_RULES_ENABLED
2403 KEY_SHORTCUT_MGR->MarkShortcutConsumed(shortcutKey);
2404 #endif // SHORTCUT_KEY_RULES_ENABLED
2405 currentLaunchAbilityKey_ = shortcutKey;
2406 shortcutKey.timerId = -1;
2407 BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_SHORTKEY, shortcutKey.ability.bundleName);
2408 LaunchAbility(shortcutKey);
2409 DfxHisysevent::ReportKeyEvent(shortcutKey.ability.bundleName);
2410 BytraceAdapter::StopLaunchAbility();
2411 }, "KeyCommandHandler-HandleKeyDown");
2412 if (shortcutKey.timerId < 0) {
2413 MMI_HILOGE("Add Timer failed");
2414 DfxHisysevent::ReportFailLaunchAbility(shortcutKey.ability.bundleName,
2415 DfxHisysevent::KEY_ERROR_CODE::FAILED_TIMER);
2416 return false;
2417 }
2418 MMI_HILOGI("Add timer success");
2419 lastMatchedKey_ = shortcutKey;
2420 auto handler = InputHandler->GetSubscriberHandler();
2421 CHKPF(handler);
2422 if (handler->IsKeyEventSubscribed(shortcutKey.finalKey, shortcutKey.triggerType)) {
2423 MMI_HILOGI("Current shortcutKey %d is subSubcribed", shortcutKey.finalKey);
2424 return false;
2425 }
2426 return true;
2427 }
2428
GetKeyDownDurationFromXml(const std::string & businessId)2429 int32_t KeyCommandHandler::GetKeyDownDurationFromXml(const std::string &businessId)
2430 {
2431 CALL_DEBUG_ENTER;
2432 return PREFERENCES_MGR->GetShortKeyDuration(businessId);
2433 }
2434
HandleKeyUp(const std::shared_ptr<KeyEvent> & keyEvent,const ShortcutKey & shortcutKey)2435 bool KeyCommandHandler::HandleKeyUp(const std::shared_ptr<KeyEvent> &keyEvent, const ShortcutKey &shortcutKey)
2436 {
2437 CALL_DEBUG_ENTER;
2438 CHKPF(keyEvent);
2439 if (shortcutKey.keyDownDuration == 0) {
2440 MMI_HILOGI("Start launch ability immediately");
2441 BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_SHORTKEY, shortcutKey.ability.bundleName);
2442 LaunchAbility(shortcutKey);
2443 DfxHisysevent::ReportKeyEvent(shortcutKey.ability.bundleName);
2444 BytraceAdapter::StopLaunchAbility();
2445 return true;
2446 }
2447 std::optional<KeyEvent::KeyItem> keyItem = keyEvent->GetKeyItem();
2448 if (!keyItem) {
2449 MMI_HILOGE("The keyItem is nullopt");
2450 return false;
2451 }
2452 auto upTime = keyEvent->GetActionTime();
2453 auto downTime = keyItem->GetDownTime();
2454 MMI_HILOGI("The upTime:%{public}" PRId64 ",downTime:%{public}" PRId64 ",keyDownDuration:%{public}d",
2455 upTime, downTime, shortcutKey.keyDownDuration);
2456
2457 if (upTime - downTime <= static_cast<int64_t>(shortcutKey.keyDownDuration) * FREQUENCY) {
2458 MMI_HILOGI("Skip, upTime - downTime <= duration");
2459 return false;
2460 }
2461 return true;
2462 }
2463
HandleKeyCancel(ShortcutKey & shortcutKey)2464 bool KeyCommandHandler::HandleKeyCancel(ShortcutKey &shortcutKey)
2465 {
2466 CALL_DEBUG_ENTER;
2467 if (shortcutKey.timerId < 0) {
2468 DfxHisysevent::ReportFailHandleKey("HandleKeyCancel", shortcutKey.finalKey,
2469 DfxHisysevent::KEY_ERROR_CODE::INVALID_PARAMETER);
2470 MMI_HILOGE("Skip, timerid less than 0");
2471 }
2472 auto timerId = shortcutKey.timerId;
2473 shortcutKey.timerId = -1;
2474 TimerMgr->RemoveTimer(timerId);
2475 MMI_HILOGI("The timerId:%{public}d", timerId);
2476 return false;
2477 }
2478
LaunchAbility(const Ability & ability,int64_t delay)2479 void KeyCommandHandler::LaunchAbility(const Ability &ability, int64_t delay)
2480 {
2481 CALL_DEBUG_ENTER;
2482 if (ability.bundleName.empty()) {
2483 MMI_HILOGW("BundleName is empty");
2484 return;
2485 }
2486 AAFwk::Want want;
2487 want.SetElementName(ability.deviceId, ability.bundleName, ability.abilityName);
2488 want.SetAction(ability.action);
2489 want.SetUri(ability.uri);
2490 want.SetType(ability.type);
2491 for (const auto &entity : ability.entities) {
2492 want.AddEntity(entity);
2493 }
2494 for (const auto &item : ability.params) {
2495 want.SetParam(item.first, item.second);
2496 }
2497 DfxHisysevent::CalcComboStartTimes(delay);
2498 DfxHisysevent::ReportComboStartTimes();
2499 MMI_HILOGW("Start launch ability, bundleName:%{public}s", ability.bundleName.c_str());
2500 auto begin = std::chrono::high_resolution_clock::now();
2501 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
2502 auto durationMS = std::chrono::duration_cast<std::chrono::milliseconds>(
2503 std::chrono::high_resolution_clock::now() - begin).count();
2504 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
2505 DfxHisysevent::ReportApiCallTimes(ApiDurationStatistics::Api::ABILITY_MGR_CLIENT_START_ABILITY, durationMS);
2506 #endif // OHOS_BUILD_ENABLE_DFX_RADAR
2507 if (err != ERR_OK) {
2508 MMI_HILOGE("LaunchAbility failed, bundleName:%{public}s, err:%{public}d", ability.bundleName.c_str(), err);
2509 return;
2510 }
2511 int32_t state = NapProcess::GetInstance()->GetNapClientPid();
2512 if (state == REMOVE_OBSERVER) {
2513 MMI_HILOGW("nap client status:%{public}d", state);
2514 return;
2515 }
2516 OHOS::MMI::NapProcess::NapStatusData napData;
2517 napData.pid = -1;
2518 napData.uid = -1;
2519 napData.bundleName = ability.bundleName;
2520 int32_t syncState = ACTIVE_EVENT;
2521 NapProcess::GetInstance()->AddMmiSubscribedEventData(napData, syncState);
2522 NapProcess::GetInstance()->NotifyBundleName(napData, syncState);
2523 MMI_HILOGW("End launch ability, bundleName:%{public}s", ability.bundleName.c_str());
2524 return;
2525 }
2526
LaunchAbility(const Ability & ability)2527 void KeyCommandHandler::LaunchAbility(const Ability &ability)
2528 {
2529 CALL_DEBUG_ENTER;
2530 AAFwk::Want want;
2531 want.SetElementName(ability.deviceId, ability.bundleName, ability.abilityName);
2532 want.SetAction(ability.action);
2533 want.SetUri(ability.uri);
2534 want.SetType(ability.uri);
2535 for (const auto &entity : ability.entities) {
2536 want.AddEntity(entity);
2537 }
2538 for (const auto &item : ability.params) {
2539 want.SetParam(item.first, item.second);
2540 }
2541
2542 MMI_HILOGW("Start launch ability, bundleName:%{public}s", ability.bundleName.c_str());
2543 if (ability.abilityType == EXTENSION_ABILITY) {
2544 auto begin = std::chrono::high_resolution_clock::now();
2545 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartExtensionAbility(want, nullptr);
2546 auto durationMS = std::chrono::duration_cast<std::chrono::milliseconds>(
2547 std::chrono::high_resolution_clock::now() - begin).count();
2548 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
2549 DfxHisysevent::ReportApiCallTimes(ApiDurationStatistics::Api::ABILITY_MGR_START_EXT_ABILITY, durationMS);
2550 #endif // OHOS_BUILD_ENABLE_DFX_RADAR
2551 if (err != ERR_OK) {
2552 MMI_HILOGE("LaunchAbility failed, bundleName:%{public}s, err:%{public}d", ability.bundleName.c_str(), err);
2553 }
2554 } else {
2555 auto begin = std::chrono::high_resolution_clock::now();
2556 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
2557 auto durationMS = std::chrono::duration_cast<std::chrono::milliseconds>(
2558 std::chrono::high_resolution_clock::now() - begin).count();
2559 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
2560 DfxHisysevent::ReportApiCallTimes(ApiDurationStatistics::Api::ABILITY_MGR_CLIENT_START_ABILITY, durationMS);
2561 #endif // OHOS_BUILD_ENABLE_DFX_RADAR
2562 if (err != ERR_OK) {
2563 MMI_HILOGE("LaunchAbility failed, bundleName:%{public}s, err:%{public}d", ability.bundleName.c_str(), err);
2564 }
2565 if (err == ERR_OK && ability.bundleName == BUNDLE_NAME_PARSER.GetBundleName("SOS_BUNDLE_NAME")) {
2566 if (isDownStart_) {
2567 isDownStart_ = false;
2568 }
2569 isFreezePowerKey_ = true;
2570 sosLaunchTime_ = OHOS::MMI::GetSysClockTime();
2571 count_ = 0;
2572 launchAbilityCount_ = 0;
2573 repeatKeyCountMap_.clear();
2574 repeatKey_.keyCode = -1;
2575 repeatKey_.keyAction = -1;
2576 sosDelayTimerId_ = TimerMgr->AddTimer(SOS_DELAY_TIMES / SECONDS_SYSTEM, 1, [this] () {
2577 isFreezePowerKey_ = false;
2578 sosDelayTimerId_ = -1;
2579 MMI_HILOGW("Timeout, restore the power button");
2580 }, "KeyCommandHandler-LaunchAbility");
2581 if (sosDelayTimerId_ < 0) {
2582 isFreezePowerKey_ = false;
2583 MMI_HILOGE("Add timer failed");
2584 }
2585 }
2586 }
2587 MMI_HILOGW("End launch ability, bundleName:%{public}s", ability.bundleName.c_str());
2588 }
2589
LaunchAbility(const ShortcutKey & key)2590 void KeyCommandHandler::LaunchAbility(const ShortcutKey &key)
2591 {
2592 CALL_INFO_TRACE;
2593 LaunchAbility(key.ability, lastMatchedKey_.keyDownDuration);
2594 ResetLastMatchedKey();
2595 }
2596
LaunchAbility(const Sequence & sequence)2597 void KeyCommandHandler::LaunchAbility(const Sequence &sequence)
2598 {
2599 CALL_INFO_TRACE;
2600 LaunchAbility(sequence.ability, sequence.abilityStartDelay);
2601 }
2602
Print() const2603 void ShortcutKey::Print() const
2604 {
2605 for (const auto &prekey: preKeys) {
2606 MMI_HILOGI("Eventkey matched, preKey:%d", prekey);
2607 }
2608 MMI_HILOGI("Eventkey matched, finalKey:%d, bundleName:%{public}s",
2609 finalKey, ability.bundleName.c_str());
2610 }
2611
RemoveSubscribedTimer(int32_t keyCode)2612 void KeyCommandHandler::RemoveSubscribedTimer(int32_t keyCode)
2613 {
2614 CALL_DEBUG_ENTER;
2615 auto iter = specialTimers_.find(keyCode);
2616 if (iter != specialTimers_.end()) {
2617 for (auto& item : iter->second) {
2618 TimerMgr->RemoveTimer(item);
2619 }
2620 specialTimers_.erase(keyCode);
2621 MMI_HILOGI("Remove timer success");
2622 }
2623 }
2624
HandleSpecialKeys(int32_t keyCode,int32_t keyAction)2625 void KeyCommandHandler::HandleSpecialKeys(int32_t keyCode, int32_t keyAction)
2626 {
2627 CALL_INFO_TRACE;
2628 auto iter = specialKeys_.find(keyCode);
2629 if (keyAction == KeyEvent::KEY_ACTION_UP) {
2630 if (iter != specialKeys_.end()) {
2631 specialKeys_.erase(iter);
2632 return;
2633 }
2634 }
2635
2636 if (keyAction == KeyEvent::KEY_ACTION_DOWN) {
2637 if (iter == specialKeys_.end()) {
2638 auto it = specialKeys_.emplace(keyCode, keyAction);
2639 if (!it.second) {
2640 MMI_HILOGD("KeyCode duplicated");
2641 return;
2642 }
2643 }
2644 }
2645 }
2646
InterruptTimers()2647 void KeyCommandHandler::InterruptTimers()
2648 {
2649 for (Sequence& item : filterSequences_) {
2650 if (item.timerId >= 0) {
2651 MMI_HILOGD("The key sequence change, close the timer");
2652 TimerMgr->RemoveTimer(item.timerId);
2653 item.timerId = -1;
2654 }
2655 }
2656 }
2657
HandlePointerVisibleKeys(const std::shared_ptr<KeyEvent> & keyEvent)2658 void KeyCommandHandler::HandlePointerVisibleKeys(const std::shared_ptr<KeyEvent> &keyEvent)
2659 {
2660 CALL_DEBUG_ENTER;
2661 CHKPV(keyEvent);
2662 if (keyEvent->GetKeyCode() == KeyEvent::KEYCODE_F9 && lastKeyEventCode_ == KeyEvent::KEYCODE_CTRL_LEFT) {
2663 MMI_HILOGI("Force make pointer visible");
2664 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
2665 if (POINTER_DEV_MGR.isInit) {
2666 CursorDrawingComponent::GetInstance().ForceClearPointerVisiableStatus();
2667 }
2668 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
2669 }
2670 lastKeyEventCode_ = keyEvent->GetKeyCode();
2671 }
2672
2673
UpdateSettingsXml(const std::string & businessId,int32_t delay)2674 int32_t KeyCommandHandler::UpdateSettingsXml(const std::string &businessId, int32_t delay)
2675 {
2676 CALL_DEBUG_ENTER;
2677 if (businessId.empty() || businessIds_.empty()) {
2678 MMI_HILOGE("The business id or business ids is empty");
2679 return PARAMETER_ERROR;
2680 }
2681 if (std::find(businessIds_.begin(), businessIds_.end(), businessId) == businessIds_.end()) {
2682 MMI_HILOGE("%{public}s not in the config file", businessId.c_str());
2683 return PARAMETER_ERROR;
2684 }
2685 if (delay < MIN_SHORT_KEY_DOWN_DURATION || delay > MAX_SHORT_KEY_DOWN_DURATION) {
2686 MMI_HILOGE("Delay is not in valid range");
2687 return PARAMETER_ERROR;
2688 }
2689 return PREFERENCES_MGR->SetShortKeyDuration(businessId, delay);
2690 }
2691
GetSingleKnuckleGesture() const2692 KnuckleGesture KeyCommandHandler::GetSingleKnuckleGesture() const
2693 {
2694 return singleKnuckleGesture_;
2695 }
2696
GetDoubleKnuckleGesture() const2697 KnuckleGesture KeyCommandHandler::GetDoubleKnuckleGesture() const
2698 {
2699 return doubleKnuckleGesture_;
2700 }
2701
SetKnuckleDoubleTapDistance(float distance)2702 void KeyCommandHandler::SetKnuckleDoubleTapDistance(float distance)
2703 {
2704 CALL_DEBUG_ENTER;
2705 if (distance <= std::numeric_limits<float>::epsilon()) {
2706 MMI_HILOGE("Invalid distance:%{public}f", distance);
2707 return;
2708 }
2709 downToPrevDownDistanceConfig_ = distance;
2710 }
2711
CheckInputMethodArea(const std::shared_ptr<PointerEvent> touchEvent)2712 bool KeyCommandHandler::CheckInputMethodArea(const std::shared_ptr<PointerEvent> touchEvent)
2713 {
2714 CALL_DEBUG_ENTER;
2715 CHKPF(touchEvent);
2716 int32_t id = touchEvent->GetPointerId();
2717 PointerEvent::PointerItem item;
2718 touchEvent->GetPointerItem(id, item);
2719 int32_t targetWindowId = item.GetTargetWindowId();
2720 int32_t targetDisplayId = touchEvent->GetTargetDisplayId();
2721 auto window = WIN_MGR->GetWindowAndDisplayInfo(targetWindowId, targetDisplayId);
2722 if (!window || (window->windowType != WINDOW_INPUT_METHOD_TYPE && window->windowType != WINDOW_SCREENSHOT_TYPE)) {
2723 return false;
2724 }
2725 return true;
2726 }
2727
Dump(int32_t fd,const std::vector<std::string> & args)2728 void KeyCommandHandler::Dump(int32_t fd, const std::vector<std::string> &args)
2729 {
2730 static const std::unordered_map<int32_t, std::string> actionMap = { {0, "UNKNOWN"},
2731 {1, "CANCEL"}, {2, "DOWN"}, {3, "UP"} };
2732 CALL_DEBUG_ENTER;
2733 mprintf(fd, "----------------------------- ShortcutKey information ----------------------------\t");
2734 mprintf(fd, "ShortcutKey: count = %zu", shortcutKeys_.size());
2735 for (const auto &item : shortcutKeys_) {
2736 auto &shortcutKey = item.second;
2737 for (const auto &prekey : shortcutKey.preKeys) {
2738 mprintf(fd, "PreKey:%d", prekey);
2739 }
2740 mprintf(fd,
2741 "BusinessId: %s | StatusConfig: %s | StatusConfigValue: %s "
2742 "| FinalKey: %d | keyDownDuration: %d | TriggerType: %d | BundleName: %s | AbilityName: %s "
2743 "| Action: %s \t", shortcutKey.businessId.c_str(), shortcutKey.statusConfig.c_str(),
2744 shortcutKey.statusConfigValue ? "true" : "false", shortcutKey.finalKey, shortcutKey.keyDownDuration,
2745 shortcutKey.triggerType, shortcutKey.ability.bundleName.c_str(), shortcutKey.ability.abilityName.c_str(),
2746 shortcutKey.ability.action.c_str());
2747 }
2748 mprintf(fd, "-------------------------- Sequence information ----------------------------------\t");
2749 mprintf(fd, "Sequence: count = %zu", sequences_.size());
2750 for (const auto &item : sequences_) {
2751 for (const auto& sequenceKey : item.sequenceKeys) {
2752 mprintf(fd, "code: %{private}d | keyAction: %s",
2753 sequenceKey.keyCode, ConvertKeyActionToString(sequenceKey.keyAction).c_str());
2754 }
2755 mprintf(fd, "BundleName: %s | AbilityName: %s | Action: %s ",
2756 item.ability.bundleName.c_str(), item.ability.abilityName.c_str(), item.ability.action.c_str());
2757 }
2758 mprintf(fd, "-------------------------- ExcludeKey information --------------------------------\t");
2759 mprintf(fd, "ExcludeKey: count = %zu", excludeKeys_.size());
2760 for (const auto &item : excludeKeys_) {
2761 mprintf(fd, "code: %{private}d | keyAction: %s", item.keyCode,
2762 ConvertKeyActionToString(item.keyAction).c_str());
2763 }
2764 mprintf(fd, "-------------------------- RepeatKey information ---------------------------------\t");
2765 mprintf(fd, "RepeatKey: count = %zu", repeatKeys_.size());
2766 for (const auto &item : repeatKeys_) {
2767 mprintf(fd,
2768 "KeyCode: %{private}d | KeyAction: %s | Times: %d"
2769 "| StatusConfig: %s | StatusConfigValue: %s | BundleName: %s | AbilityName: %s"
2770 "| Action:%s \t", item.keyCode, ConvertKeyActionToString(item.keyAction).c_str(), item.times,
2771 item.statusConfig.c_str(), item.statusConfigValue ? "true" : "false",
2772 item.ability.bundleName.c_str(), item.ability.abilityName.c_str(), item.ability.action.c_str());
2773 }
2774 PrintGestureInfo(fd);
2775 }
2776
PrintGestureInfo(int32_t fd)2777 void KeyCommandHandler::PrintGestureInfo(int32_t fd)
2778 {
2779 mprintf(fd, "-------------------------- TouchPad Two Fingers Gesture --------------------------\t");
2780 mprintf(fd,
2781 "GestureActive: %s | GestureBundleName: %s | GestureAbilityName: %s"
2782 "| GestureAction: %s \t", twoFingerGesture_.active ? "true" : "false",
2783 twoFingerGesture_.ability.bundleName.c_str(), twoFingerGesture_.ability.abilityName.c_str(),
2784 twoFingerGesture_.ability.action.c_str());
2785 mprintf(fd, "-------------------------- TouchPad Three Fingers Tap Gesture --------------------\t");
2786 mprintf(fd,
2787 "TapBundleName: %s | TapAbilityName: %s"
2788 "| TapAction: %s \t", threeFingersTap_.ability.bundleName.c_str(),
2789 threeFingersTap_.ability.abilityName.c_str(), threeFingersTap_.ability.action.c_str());
2790 mprintf(fd, "-------------------------- Knuckle Single Finger Gesture -------------------------\t");
2791 mprintf(fd,
2792 "GestureState: %s | GestureBundleName: %s | GestureAbilityName: %s"
2793 "| GestureAction: %s \t", singleKnuckleGesture_.state ? "true" : "false",
2794 singleKnuckleGesture_.ability.bundleName.c_str(), singleKnuckleGesture_.ability.abilityName.c_str(),
2795 singleKnuckleGesture_.ability.action.c_str());
2796 mprintf(fd, "-------------------------- Knuckle Two Fingers Gesture ---------------------------\t");
2797 mprintf(fd,
2798 "GestureState: %s | GestureBundleName: %s | GestureAbilityName: %s"
2799 "| GestureAction:%s \t", doubleKnuckleGesture_.state ? "true" : "false",
2800 doubleKnuckleGesture_.ability.bundleName.c_str(), doubleKnuckleGesture_.ability.abilityName.c_str(),
2801 doubleKnuckleGesture_.ability.action.c_str());
2802 }
ConvertKeyActionToString(int32_t keyAction)2803 std::string KeyCommandHandler::ConvertKeyActionToString(int32_t keyAction)
2804 {
2805 static const std::unordered_map<int32_t, std::string> actionMap = {
2806 {0, "UNKNOWN"},
2807 {1, "CANCEL"},
2808 {2, "DOWN"},
2809 {3, "UP"}
2810 };
2811 auto it = actionMap.find(keyAction);
2812 if (it != actionMap.end()) {
2813 return it->second;
2814 } else {
2815 return "UNKNOWN_ACTION";
2816 }
2817 }
operator <<(std::ostream & os,const Sequence & seq)2818 std::ostream& operator<<(std::ostream& os, const Sequence& seq)
2819 {
2820 os << "keys: [";
2821 for (const SequenceKey &singleKey: seq.sequenceKeys) {
2822 os << "(kc:" << singleKey.keyCode << ",ka:" << singleKey.keyAction << ",d:" << singleKey.delay << "),";
2823 }
2824 os << "]: " << seq.ability.bundleName << ":" << seq.ability.abilityName;
2825 return os;
2826 }
2827
CheckAndUpdateTappingCountAtDown(std::shared_ptr<PointerEvent> touchEvent)2828 void KeyCommandHandler::CheckAndUpdateTappingCountAtDown(std::shared_ptr<PointerEvent> touchEvent)
2829 {
2830 CHKPV(touchEvent);
2831 int64_t currentDownTime = touchEvent->GetActionTime();
2832 int64_t downIntervalTime = currentDownTime - lastDownTime_;
2833 lastDownTime_ = currentDownTime;
2834 if (downIntervalTime <= 0 || downIntervalTime >= TAP_DOWN_INTERVAL_MILLIS) {
2835 tappingCount_ = 1;
2836 return;
2837 }
2838 tappingCount_++;
2839 int64_t timeDiffToPrevKnuckleUpTime = currentDownTime - previousUpTime_;
2840 if (timeDiffToPrevKnuckleUpTime <= DOUBLE_CLICK_INTERVAL_TIME_SLOW) {
2841 if (tappingCount_ == MAX_TAP_COUNT) {
2842 DfxHisysevent::ReportFailIfOneSuccTwoFail(touchEvent);
2843 } else if (tappingCount_ > MAX_TAP_COUNT) {
2844 DfxHisysevent::ReportFailIfKnockTooFast();
2845 }
2846 }
2847 }
2848
TouchPadKnuckleDoubleClickHandle(std::shared_ptr<KeyEvent> event)2849 bool KeyCommandHandler::TouchPadKnuckleDoubleClickHandle(std::shared_ptr<KeyEvent> event)
2850 {
2851 CHKPF(event);
2852 auto actionType = event->GetKeyAction();
2853 if (actionType == KNUCKLE_1F_DOUBLE_CLICK || actionType == KNUCKLE_2F_DOUBLE_CLICK) {
2854 MMI_HILOGI("Knuckle in TouchPadKnuckleDoubleClickHandle, actionType is %{public}d, "
2855 "screenCapturePermission_ is %{public}d",
2856 actionType,
2857 screenCapturePermission_);
2858 }
2859 if (actionType == KNUCKLE_1F_DOUBLE_CLICK && HasScreenCapturePermission(TOUCHPAD_KNUCKLE_SCREENSHOT)) {
2860 auto bundleName = BUNDLE_NAME_PARSER.GetBundleName("PC_PRO_SCREENSHOT_BUNDLE_NAME");
2861 auto abilityName = BUNDLE_NAME_PARSER.GetBundleName("PC_PRO_SCREENSHOT_ABILITY_NAME");
2862 TouchPadKnuckleDoubleClickProcess(bundleName, abilityName, "single_knuckle");
2863 return true;
2864 }
2865 if (actionType == KNUCKLE_2F_DOUBLE_CLICK && HasScreenCapturePermission(TOUCHPAD_KNUCKLE_SCREEN_RECORDING)) {
2866 auto bundleName = BUNDLE_NAME_PARSER.GetBundleName("PC_PRO_SCREENRECORDER_BUNDLE_NAME");
2867 auto abilityName = BUNDLE_NAME_PARSER.GetBundleName("PC_PRO_SCREENRECORDER_ABILITY_NAME");
2868 TouchPadKnuckleDoubleClickProcess(bundleName, abilityName, "double_knuckle");
2869 return true;
2870 }
2871 return false;
2872 }
2873
TouchPadKnuckleDoubleClickProcess(const std::string bundleName,const std::string abilityName,const std::string action)2874 void KeyCommandHandler::TouchPadKnuckleDoubleClickProcess(const std::string bundleName,
2875 const std::string abilityName, const std::string action)
2876 {
2877 std::string screenStatus = DISPLAY_MONITOR->GetScreenStatus();
2878 bool isScreenLocked = DISPLAY_MONITOR->GetScreenLocked();
2879 if (screenStatus == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF || isScreenLocked) {
2880 MMI_HILOGI("The current screen is not in the unlocked state with the screen on");
2881 return;
2882 }
2883 Ability ability;
2884 ability.bundleName = bundleName;
2885 ability.abilityName = abilityName;
2886 ability.params.emplace(std::make_pair("trigger_type", action));
2887 LaunchAbility(ability, NO_DELAY);
2888 }
2889
ParseLongPressConfig()2890 bool KeyCommandHandler::ParseLongPressConfig()
2891 {
2892 std::string configPath = "/system/variant/phone/base/etc/multimodalinput/universal_drag_app_whitelist.json";
2893 return ParseLongPressJson(configPath);
2894 }
2895
ParseLongPressJson(const std::string & configFile)2896 bool KeyCommandHandler::ParseLongPressJson(const std::string &configFile)
2897 {
2898 CALL_DEBUG_ENTER;
2899 std::string jsonStr = ReadJsonFile(configFile);
2900 if (jsonStr.empty()) {
2901 MMI_HILOGE("Read configFile failed");
2902 return false;
2903 }
2904 JsonParser parser(jsonStr.c_str());
2905 if (parser.Get() == nullptr) {
2906 MMI_HILOGE("parse is nullptr");
2907 return false;
2908 }
2909 if (!cJSON_IsArray(parser.Get())) {
2910 MMI_HILOGE("Parser.Get() is not object");
2911 return false;
2912 }
2913
2914 cJSON* item = nullptr;
2915 cJSON* enable = nullptr;
2916 cJSON* status = nullptr;
2917 cJSON_ArrayForEach(item, parser.Get()) {
2918 if (!cJSON_IsObject(item)) {
2919 continue;
2920 }
2921 enable = cJSON_GetObjectItem(item, KEY_ENABLE);
2922 status = cJSON_GetObjectItem(item, KEY_STATUS);
2923 if (enable == NULL || status == NULL) {
2924 continue;
2925 }
2926 if (enable->valueint == 1) {
2927 appWhiteList_.insert(item->string);
2928 }
2929 }
2930 return true;
2931 }
2932
CheckBundleName(const std::shared_ptr<PointerEvent> touchEvent)2933 bool KeyCommandHandler::CheckBundleName(const std::shared_ptr<PointerEvent> touchEvent)
2934 {
2935 CALL_DEBUG_ENTER;
2936 if (!isParseLongPressConfig_) {
2937 MMI_HILOGE("Parse configFile failed");
2938 return false;
2939 }
2940 int32_t windowPid = WIN_MGR->GetWindowPid(touchEvent->GetTargetWindowId());
2941 if (windowPid == RET_ERR) {
2942 MMI_HILOGE("Get window pid failed");
2943 return false;
2944 }
2945
2946 std::string bundleName;
2947 if (LONG_PRESS_EVENT_HANDLER->GetBundleName(bundleName, windowPid) == RET_ERR) {
2948 MMI_HILOGE("Failed to get bundle name, pid %{public}d", windowPid);
2949 return false;
2950 }
2951 if (appWhiteList_.find(bundleName) == appWhiteList_.end()) {
2952 MMI_HILOGD("%{public}s not support long-press drag", bundleName.c_str());
2953 return false;
2954 }
2955 return true;
2956 }
2957
OnKunckleSwitchStatusChange(const std::string switchName)2958 void KeyCommandHandler::OnKunckleSwitchStatusChange(const std::string switchName)
2959 {
2960 #ifdef OHOS_BUILD_ENABLE_ANCO
2961 if (switchName != SNAPSHOT_KNUCKLE_SWITCH && switchName != RECORD_KNUCKLE_SWITCH) {
2962 return;
2963 }
2964 bool isKnuckleEnable = !SkipKnuckleDetect();
2965 int32_t ret = WIN_MGR->SyncKnuckleStatus(isKnuckleEnable);
2966 if (ret != RET_OK) {
2967 MMI_HILOGE("sync knuckle status error., ret:%{public}d", ret);
2968 }
2969 #endif // OHOS_BUILD_ENABLE_ANCO
2970 }
2971
MenuClickHandle(std::shared_ptr<KeyEvent> event)2972 bool KeyCommandHandler::MenuClickHandle(std::shared_ptr<KeyEvent> event)
2973 {
2974 CALL_DEBUG_ENTER;
2975 if (DEVICE_TYPE_TV != PRODUCT_TYPE_TV) {
2976 MMI_HILOGD("In non-TV scenarios, the menu key does not support this feature");
2977 return false;
2978 }
2979 CHKPF(event);
2980 auto keycode = event->GetKeyCode();
2981 if (keycode != KeyEvent::KEYCODE_MENU) {
2982 return false;
2983 }
2984 auto actionType = event->GetKeyAction();
2985 if ((actionType == KeyEvent::KEY_ACTION_DOWN) && (!existMenuDown_)) {
2986 lastMenuDownTime_ = OHOS::MMI::GetSysClockTime();
2987 existMenuDown_ = true;
2988 tmpkeyEvent_ = KeyEvent::Clone(event);
2989 return true;
2990 } else if ((actionType == KeyEvent::KEY_ACTION_UP) && existMenuDown_) {
2991 auto time = OHOS::MMI::GetSysClockTime();
2992 auto duration = (time - lastMenuDownTime_);
2993 lastMenuDownTime_ = 0;
2994 existMenuDown_ = false;
2995 if (duration >= (MENU_KEY_DOWN_DELAY*TIME_CONVERSION_UNIT)) {
2996 MMI_HILOGD("Key menu long press, send bundlname to TV");
2997 tmpkeyEvent_.reset();
2998 MenuClickProcess(TV_MENU_BUNDLE_NAME, TV_MENU_ABILITY_NAME, "key_menu_longpress");
2999 return true;
3000 } else {
3001 MMI_HILOGD("Key menu short press.");
3002 if (tmpkeyEvent_) {
3003 SendSaveEvent(tmpkeyEvent_);
3004 }
3005 return false;
3006 }
3007 } else {
3008 MMI_HILOGI("Menu key is pressed and has not been lifted. This key will not be distributed for now");
3009 return true;
3010 }
3011 }
3012
SendSaveEvent(std::shared_ptr<KeyEvent> keyEvent)3013 void KeyCommandHandler::SendSaveEvent(std::shared_ptr<KeyEvent> keyEvent)
3014 {
3015 CALL_DEBUG_ENTER;
3016 if (OnHandleEvent(keyEvent)) {
3017 if (DISPLAY_MONITOR->GetScreenStatus() == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
3018 auto monitorHandler = InputHandler->GetMonitorHandler();
3019 CHKPV(monitorHandler);
3020 keyEvent->SetFourceMonitorFlag(true);
3021 #ifndef OHOS_BUILD_EMULATOR
3022 monitorHandler->OnHandleEvent(keyEvent);
3023 #endif // OHOS_BUILD_EMULATOR
3024 keyEvent->SetFourceMonitorFlag(false);
3025 }
3026 MMI_HILOGD("The keyEvent start launch an ability:%{private}d", keyEvent->GetKeyCode());
3027 BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::KEY_LAUNCH_EVENT);
3028 return;
3029 }
3030 CHKPV(nextHandler_);
3031 nextHandler_->HandleKeyEvent(keyEvent);
3032 }
3033
MenuClickProcess(const std::string bundleName,const std::string abilityName,const std::string action)3034 void KeyCommandHandler::MenuClickProcess(const std::string bundleName,
3035 const std::string abilityName, const std::string action)
3036 {
3037 CALL_DEBUG_ENTER;
3038 std::string screenStatus = DISPLAY_MONITOR->GetScreenStatus();
3039 bool isScreenLocked = DISPLAY_MONITOR->GetScreenLocked();
3040 if (screenStatus == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF || isScreenLocked) {
3041 MMI_HILOGE("The current screen is not in the unlocked state with the screen on");
3042 return;
3043 }
3044 Ability ability;
3045 ability.bundleName = bundleName;
3046 ability.abilityName = abilityName;
3047 ability.params.emplace(std::make_pair("trigger_type", action));
3048 LaunchAbility(ability, NO_DELAY);
3049 }
3050
RegisterProximitySensor()3051 void KeyCommandHandler::RegisterProximitySensor()
3052 {
3053 CALL_INFO_TRACE;
3054 if (hasRegisteredSensor_) {
3055 MMI_HILOGE("Has SubscribeSensor %{public}d", SENSOR_TYPE_ID_PROXIMITY);
3056 return;
3057 }
3058 if (!KeyEventHdr->IsScreenFold()) {
3059 MMI_HILOGD("Screen not fold");
3060 return;
3061 }
3062 g_user.callback = SensorDataCallbackImpl;
3063 int32_t ret = SubscribeSensor(SENSOR_TYPE_ID_PROXIMITY, &g_user);
3064 if (ret != 0) {
3065 MMI_HILOGE("Failed to SubscribeSensor: %{public}d ret:%{public}d", SENSOR_TYPE_ID_PROXIMITY, ret);
3066 return;
3067 }
3068 ret = SetBatch(SENSOR_TYPE_ID_PROXIMITY, &g_user, SENSOR_SAMPLING_INTERVAL, SENSOR_REPORT_INTERVAL);
3069 if (ret != 0) {
3070 MMI_HILOGE("Failed to SetBatch: %{public}d ret:%{public}d", SENSOR_TYPE_ID_PROXIMITY, ret);
3071 return;
3072 }
3073 ret = ActivateSensor(SENSOR_TYPE_ID_PROXIMITY, &g_user);
3074 if (ret != 0) {
3075 MMI_HILOGE("Failed to ActivateSensor: %{public}d ret:%{public}d", SENSOR_TYPE_ID_PROXIMITY, ret);
3076 return;
3077 }
3078 hasRegisteredSensor_ = true;
3079 }
3080
SetKnuckleSwitch(bool knuckleSwitch)3081 int32_t KeyCommandHandler::SetKnuckleSwitch(bool knuckleSwitch)
3082 {
3083 gameForbidFingerKnuckle_ = !knuckleSwitch;
3084 MMI_HILOGI("SetKnuckleSwitch is successful in keyCommand handler, knuckleSwitch:%{public}d", knuckleSwitch);
3085 return RET_OK;
3086 }
3087
CheckTwoFingerGesture(int32_t pid)3088 int32_t KeyCommandHandler::CheckTwoFingerGesture(int32_t pid)
3089 {
3090 auto now = std::chrono::high_resolution_clock::now();
3091 auto duration = now.time_since_epoch();
3092 int64_t milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
3093 int64_t timeOut = milliseconds - twoFingerGesture_.startTime;
3094 if (twoFingerGesture_.touchEvent == nullptr) {
3095 MMI_HILOGE("twoFingerGesture_.touchEvent == nullptr");
3096 return RET_ERR;
3097 }
3098 if (timeOut > SCREEN_TIME_OUT) {
3099 MMI_HILOGE("Start application timeout, startTime:%{public}" PRId64
3100 ", millisecond:%{public}" PRId64 ", timeOut:%{public}" PRId64,
3101 twoFingerGesture_.startTime, milliseconds, timeOut);
3102 return RET_ERR;
3103 }
3104
3105 if ((twoFingerGesture_.windowId < 0) || (twoFingerGesture_.touchEvent->GetTargetWindowId() !=
3106 twoFingerGesture_.windowId)) {
3107 MMI_HILOGE("Window changefocusWindowId:%{public}d, twoFingerGesture_.focusWindowId:%{public}d",
3108 twoFingerGesture_.touchEvent->GetTargetWindowId(), twoFingerGesture_.windowId);
3109 return RET_ERR;
3110 }
3111
3112 if (twoFingerGesture_.windowPid != pid) {
3113 MMI_HILOGE("twoFingerGesture_.windowPid:%{public}d, pid:%{public}d", twoFingerGesture_.windowPid, pid);
3114 return RET_ERR;
3115 }
3116
3117 if (!twoFingerGesture_.longPressFlag) {
3118 MMI_HILOGE("The long press state is not set");
3119 return RET_ERR;
3120 }
3121 return RET_OK;
3122 }
3123
LaunchAiScreenAbility(int32_t pid)3124 int32_t KeyCommandHandler::LaunchAiScreenAbility(int32_t pid)
3125 {
3126 if (CheckTwoFingerGesture(pid) != RET_OK) {
3127 twoFingerGesture_.startTime = 0;
3128 twoFingerGesture_.longPressFlag = false;
3129 twoFingerGesture_.windowId = -1;
3130 twoFingerGesture_.windowPid = -1;
3131 return RET_ERR;
3132 }
3133
3134 MMI_HILOGE("Start launch ai screen ability immediately");
3135 BytraceAdapter::StartLaunchAbility(KeyCommandType::TYPE_MULTI_FINGERS, twoFingerGesture_.ability.bundleName);
3136 LaunchAbility(twoFingerGesture_.ability, twoFingerGesture_.abilityStartDelay);
3137 BytraceAdapter::StopLaunchAbility();
3138
3139 twoFingerGesture_.startTime = 0;
3140 twoFingerGesture_.longPressFlag = false;
3141 twoFingerGesture_.windowId = -1;
3142 twoFingerGesture_.windowPid = -1;
3143 return RET_OK;
3144 }
3145
UnregisterProximitySensor()3146 void KeyCommandHandler::UnregisterProximitySensor()
3147 {
3148 if (!hasRegisteredSensor_) {
3149 MMI_HILOGI("Has registered sensor: %{public}d", SENSOR_TYPE_ID_PROXIMITY);
3150 return;
3151 }
3152 hasRegisteredSensor_ = false;
3153 int32_t ret = DeactivateSensor(SENSOR_TYPE_ID_PROXIMITY, &g_user);
3154 if (ret != 0) {
3155 MMI_HILOGE("Failed to DeactiveSensor: %{public}d ret:%{public}d", SENSOR_TYPE_ID_PROXIMITY, ret);
3156 }
3157 ret = UnsubscribeSensor(SENSOR_TYPE_ID_PROXIMITY, &g_user);
3158 if (ret != 0) {
3159 MMI_HILOGE("Failed to UnsubscribeSensor: %{public}d ret:%{public}d", SENSOR_TYPE_ID_PROXIMITY, ret);
3160 }
3161 }
3162
SwitchScreenCapturePermission(uint32_t permissionType,bool enable)3163 int32_t KeyCommandHandler::SwitchScreenCapturePermission(uint32_t permissionType, bool enable)
3164 {
3165 if (enable) {
3166 screenCapturePermission_ |= permissionType;
3167 } else {
3168 screenCapturePermission_ &= ~permissionType;
3169 }
3170 MMI_HILOGI("SwitchScreenCapturePermission is successful in keyCommand handler, "
3171 "screenCapturePermission_:%{public}d, permissionType:%{public}d, "
3172 "enable:%{public}d",
3173 screenCapturePermission_,
3174 permissionType,
3175 enable);
3176 return RET_OK;
3177 }
3178
HasScreenCapturePermission(uint32_t permissionType)3179 bool KeyCommandHandler::HasScreenCapturePermission(uint32_t permissionType)
3180 {
3181 bool hasScreenCapturePermission = ((screenCapturePermission_ & permissionType) == permissionType);
3182 if ((permissionType & (KNUCKLE_SCREENSHOT | KNUCKLE_SCROLL_SCREENSHOT | KNUCKLE_ENABLE_AI_BASE)) != 0) {
3183 hasScreenCapturePermission =
3184 hasScreenCapturePermission && !gameForbidFingerKnuckle_ && screenshotSwitch_.statusConfigValue;
3185 }
3186 if ((permissionType & KNUCKLE_SCREEN_RECORDING) != 0) {
3187 hasScreenCapturePermission =
3188 hasScreenCapturePermission && !gameForbidFingerKnuckle_ && recordSwitch_.statusConfigValue;
3189 }
3190 MMI_HILOGD("HasScreenCapturePermission is successful in keyCommand handler, screenCapturePermission_:%{public}d, "
3191 "permissionType:%{public}d, gameForbidFingerKnuckle_:%{public}d, screenshotSwitch_:%{public}d, "
3192 "recordSwitch_:%{public}d, "
3193 "hasScreenCapturePermission:%{public}d ",
3194 screenCapturePermission_,
3195 permissionType,
3196 gameForbidFingerKnuckle_,
3197 screenshotSwitch_.statusConfigValue,
3198 recordSwitch_.statusConfigValue,
3199 hasScreenCapturePermission);
3200 return hasScreenCapturePermission;
3201 }
3202
3203 #ifdef OHOS_BUILD_ENABLE_MISTOUCH_PREVENTION
CallMistouchPrevention()3204 void KeyCommandHandler::CallMistouchPrevention()
3205 {
3206 if (hasRegisteredSensor_) {
3207 MMI_HILOGE("Has SubscribeSensor %{public}d", SENSOR_TYPE_ID_PROXIMITY);
3208 return;
3209 }
3210 if (mistouchLibHandle_ == nullptr) {
3211 mistouchLibHandle_ = dlopen(LOADMISTOUCH_LIBPATH, RTLD_LAZY);
3212 if (!mistouchLibHandle_) {
3213 MMI_HILOGE("Failed to load library: %s", dlerror());
3214 return;
3215 }
3216 typedef IMistouchPrevention* (*funCreate_ptr) (void);
3217 funCreate_ptr fnCreate = nullptr;
3218 fnCreate = (funCreate_ptr)dlsym(mistouchLibHandle_, "ConsumerMpImplGetInstance");
3219 if (fnCreate == nullptr) {
3220 MMI_HILOGE("dlsym mistouchPrevention wrapper symbol failed, error:%{public}s", dlerror());
3221 dlclose(mistouchLibHandle_);
3222 return;
3223 }
3224 mistouchPrevention_ = (IMistouchPrevention*)fnCreate();
3225 if (mistouchPrevention_ == nullptr) {
3226 MMI_HILOGE("mistouchPrevention wrapper symbol failed, error:%{public}s", dlerror());
3227 dlclose(mistouchLibHandle_);
3228 return;
3229 }
3230 }
3231
3232 std::weak_ptr<KeyCommandHandler> weakPtr = shared_from_this();
3233 auto callback = [weakPtr](int32_t ret) -> void {
3234 if (auto sharedPtr = weakPtr.lock()) {
3235 sharedPtr->ret_ = ret;
3236 MMI_HILOGD("UserStatusDataCallback received data:ret_ %{public}d", sharedPtr->ret_.load());
3237 } else {
3238 MMI_HILOGE("callback fired, but object is already destroyed.");
3239 }
3240 };
3241 CHKPV(mistouchPrevention_);
3242 int ret = mistouchPrevention_->MistouchPreventionConnector(callback);
3243 hasRegisteredSensor_ = true;
3244 MMI_HILOGD("CallMistouchPrevention yes MistouchPreventionConnector:%{public}d", ret);
3245
3246 timerId_ = TimerMgr->AddTimer(FREQUENCY, 1, [weakPtr]() {
3247 if (auto sharedPtr = weakPtr.lock()) {
3248 sharedPtr->UnregisterMistouchPrevention();
3249 } else {
3250 MMI_HILOGE("Timer fired, but object is already destroyed.");
3251 }
3252 }, "KeyCommandHandler-CheckSpecialRepeatKey");
3253 if (timerId_ < 0) {
3254 MMI_HILOGE("Add timer failed");
3255 }
3256 }
3257 #endif // OHOS_BUILD_ENABLE_MISTOUCH_PREVENTION
3258
3259 #ifdef OHOS_BUILD_ENABLE_MISTOUCH_PREVENTION
UnregisterMistouchPrevention()3260 void KeyCommandHandler::UnregisterMistouchPrevention()
3261 {
3262 if (!hasRegisteredSensor_) {
3263 MMI_HILOGD("Has unregistered sensor: %{public}d", SENSOR_TYPE_ID_PROXIMITY);
3264 return;
3265 }
3266 CHKPV(mistouchPrevention_);
3267 mistouchPrevention_->MistouchPreventionClose();
3268 hasRegisteredSensor_ = false;
3269 ret_ = -1;
3270 MMI_HILOGD("UnregisterMistouchPrevention:ret_ %{public}d", ret_.load());
3271 if (timerId_ >= 0) {
3272 MMI_HILOGD("lzc RemoveTimer:%{public}d", timerId_);
3273 TimerMgr->RemoveTimer(timerId_);
3274 timerId_ = -1;
3275 }
3276 }
3277 #endif // OHOS_BUILD_ENABLE_MISTOUCH_PREVENTION
3278
~KeyCommandHandler()3279 KeyCommandHandler::~KeyCommandHandler()
3280 {
3281 #ifdef OHOS_BUILD_ENABLE_MISTOUCH_PREVENTION
3282 if (mistouchLibHandle_ != nullptr) {
3283 if (mistouchPrevention_ != nullptr) {
3284 typedef void (*funCreate_ptr) (IMistouchPrevention* mistouchPrevention);
3285 funCreate_ptr fnDestory = nullptr;
3286 fnDestory = (funCreate_ptr)dlsym(mistouchLibHandle_, "ConsumerMpImplDestoryInstance");
3287 if (fnDestory != nullptr) {
3288 fnDestory(mistouchPrevention_);
3289 }
3290 mistouchPrevention_ = nullptr;
3291 }
3292 dlclose(mistouchLibHandle_);
3293 mistouchLibHandle_ = nullptr;
3294 }
3295 #endif // OHOS_BUILD_ENABLE_MISTOUCH_PREVENTION
3296 }
3297 } // namespace MMI
3298 } // namespace OHOS