1 /*
2 * Copyright (c) 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 #include "key_event_manager.h"
16
17 #include "base/input_manager/input_manager.h"
18 #include "base/ressched/ressched_report.h"
19 #include "core/common/container.h"
20 #include "core/components_ng/base/frame_node.h"
21 #include "core/components_ng/pattern/overlay/sheet_manager.h"
22 #include "core/pipeline_ng/pipeline_context.h"
23
24 namespace OHOS::Ace::NG {
25 namespace {
26 constexpr uint8_t KEYS_MAX_VALUE = 3;
27
28 enum CtrlKeysBit : uint8_t {
29 CTRL = 1,
30 SHIFT = 2,
31 ALT = 4,
32 };
33
GetPipelineContext(int32_t instanceId)34 RefPtr<NG::PipelineContext> GetPipelineContext(int32_t instanceId)
35 {
36 auto container = Container::GetContainer(instanceId);
37 CHECK_NULL_RETURN(container, nullptr);
38 return AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
39 }
40
GetFocusManager(int32_t instanceId)41 RefPtr<FocusManager> GetFocusManager(int32_t instanceId)
42 {
43 auto pipeline = GetPipelineContext(instanceId);
44 CHECK_NULL_RETURN(pipeline, nullptr);
45 return pipeline->GetOrCreateFocusManager();
46 }
47
GetOverlayManager(int32_t instanceId)48 RefPtr<OverlayManager> GetOverlayManager(int32_t instanceId)
49 {
50 auto pipeline = GetPipelineContext(instanceId);
51 CHECK_NULL_RETURN(pipeline, nullptr);
52 return pipeline->GetOverlayManager();
53 }
54
GetDragDropManager(int32_t instanceId)55 RefPtr<DragDropManager> GetDragDropManager(int32_t instanceId)
56 {
57 auto pipeline = GetPipelineContext(instanceId);
58 CHECK_NULL_RETURN(pipeline, nullptr);
59 return pipeline->GetDragDropManager();
60 }
61 } // namespace
62
AddKeyboardShortcutNode(const WeakPtr<FrameNode> & node)63 void KeyEventManager::AddKeyboardShortcutNode(const WeakPtr<FrameNode>& node)
64 {
65 auto frameNode = node.Upgrade();
66 CHECK_NULL_VOID(frameNode);
67 auto iter = keyboardShortcutNode_.begin();
68 while (iter != keyboardShortcutNode_.end()) {
69 auto keyboardShortcutNode = (*iter).Upgrade();
70 if (!keyboardShortcutNode) {
71 keyboardShortcutNode_.erase(iter++);
72 continue;
73 }
74 if (keyboardShortcutNode->GetId() == frameNode->GetId()) {
75 return;
76 }
77 ++iter;
78 }
79 keyboardShortcutNode_.emplace_back(node);
80 }
81
GetKeyboardShortcutKeys(const std::vector<ModifierKey> & keys)82 uint8_t KeyEventManager::GetKeyboardShortcutKeys(const std::vector<ModifierKey>& keys)
83 {
84 uint8_t keyValue = 0;
85 uint8_t ctrlTimes = 0;
86 uint8_t shiftTimes = 0;
87 uint8_t altTimes = 0;
88 if (keys.size() > KEYS_MAX_VALUE) {
89 return 0;
90 }
91 for (const auto& key : keys) {
92 switch (static_cast<uint8_t>(key)) {
93 case static_cast<uint8_t>(ModifierKey::CTRL): {
94 keyValue |= CtrlKeysBit::CTRL;
95 ++ctrlTimes;
96 break;
97 }
98 case static_cast<uint8_t>(ModifierKey::SHIFT): {
99 keyValue |= CtrlKeysBit::SHIFT;
100 ++shiftTimes;
101 break;
102 }
103 case static_cast<uint8_t>(ModifierKey::ALT): {
104 keyValue |= CtrlKeysBit::ALT;
105 ++altTimes;
106 break;
107 }
108 default:
109 keyValue |= 0;
110 }
111 }
112 if (ctrlTimes > 1 || shiftTimes > 1 || altTimes > 1) {
113 return 0;
114 }
115 return keyValue;
116 }
117
IsSystemKeyboardShortcut(const KeyEvent & event)118 bool KeyEventManager::IsSystemKeyboardShortcut(const KeyEvent& event)
119 {
120 static std::vector<HotKey> systemHotKeys;
121 static std::once_flag initFlag;
122
123 std::call_once(initFlag, []() {
124 std::vector<HotKey> initHotKeys;
125 InputManager::GetSystemHotkeys(systemHotKeys);
126 });
127 if (systemHotKeys.empty()) {
128 return false;
129 }
130
131 for (const auto& [prekey, finalkey] : systemHotKeys) {
132 if (static_cast<int32_t>(event.code) != finalkey || (event.pressedCodes.size() != prekey.size() + 1)) {
133 continue;
134 }
135 bool matchPreKey = std::all_of(event.pressedCodes.begin(), event.pressedCodes.end(),
136 [&prekeySet = prekey, keycode = event.code](const KeyCode& item) {
137 return (item == keycode) ? true : prekeySet.count(static_cast<int32_t>(item)) != 0;
138 });
139 if (matchPreKey) {
140 TAG_LOGI(AceLogTag::ACE_KEYBOARD, "Match system hot key. Cannot trigger keyboard shortcut.");
141 return true;
142 }
143 }
144 return false;
145 }
146
IsSameKeyboardShortcutNode(const std::string & value,uint8_t keys)147 bool KeyEventManager::IsSameKeyboardShortcutNode(const std::string& value, uint8_t keys)
148 {
149 for (auto& weakNode : keyboardShortcutNode_) {
150 auto frameNode = weakNode.Upgrade();
151 if (!frameNode) {
152 continue;
153 }
154 auto eventHub = frameNode->GetOrCreateEventHub<EventHub>();
155 if (!eventHub) {
156 continue;
157 }
158 auto keyboardShortcuts = eventHub->GetKeyboardShortcut();
159 for (auto& keyboardShortcut : keyboardShortcuts) {
160 if (keyboardShortcut.value == value && keyboardShortcut.keys == keys) {
161 return true;
162 }
163 }
164 }
165 return false;
166 }
167
AddKeyboardShortcutSingleKey(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)168 void AddKeyboardShortcutSingleKey(
169 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
170 {
171 uint8_t index = 0;
172 std::vector<KeyCode> keyCode1;
173 std::vector<KeyCode> keyCode2;
174 if (keys & CtrlKeysBit::CTRL) {
175 keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
176 keyCode2.emplace_back(KeyCode::KEY_CTRL_RIGHT);
177 permutation.emplace_back(++index);
178 }
179 if (keys & CtrlKeysBit::SHIFT) {
180 keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
181 keyCode2.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
182 permutation.emplace_back(++index);
183 }
184 if (keys & CtrlKeysBit::ALT) {
185 keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
186 keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
187 permutation.emplace_back(++index);
188 }
189 keyCodes.emplace_back(keyCode1);
190 keyCodes.emplace_back(keyCode2);
191 }
192
AddKeyboardShortcutDoubleKeysWithCtrlShift(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)193 void AddKeyboardShortcutDoubleKeysWithCtrlShift(
194 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
195 {
196 uint8_t index = 0;
197 std::vector<KeyCode> keyCode1;
198 std::vector<KeyCode> keyCode2;
199 std::vector<KeyCode> keyCode3;
200 std::vector<KeyCode> keyCode4;
201
202 keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
203 keyCode2.emplace_back(KeyCode::KEY_CTRL_LEFT);
204 keyCode3.emplace_back(KeyCode::KEY_CTRL_RIGHT);
205 keyCode4.emplace_back(KeyCode::KEY_CTRL_RIGHT);
206 permutation.emplace_back(++index);
207
208 keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
209 keyCode2.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
210 keyCode3.emplace_back(KeyCode::KEY_SHIFT_LEFT);
211 keyCode4.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
212 permutation.emplace_back(++index);
213
214 keyCodes.emplace_back(keyCode1);
215 keyCodes.emplace_back(keyCode2);
216 keyCodes.emplace_back(keyCode3);
217 keyCodes.emplace_back(keyCode4);
218 }
219
AddKeyboardShortcutDoubleKeysWithCtrlAlt(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)220 void AddKeyboardShortcutDoubleKeysWithCtrlAlt(
221 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
222 {
223 uint8_t index = 0;
224 std::vector<KeyCode> keyCode1;
225 std::vector<KeyCode> keyCode2;
226 std::vector<KeyCode> keyCode3;
227 std::vector<KeyCode> keyCode4;
228
229 keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
230 keyCode2.emplace_back(KeyCode::KEY_CTRL_LEFT);
231 keyCode3.emplace_back(KeyCode::KEY_CTRL_RIGHT);
232 keyCode4.emplace_back(KeyCode::KEY_CTRL_RIGHT);
233 permutation.emplace_back(++index);
234
235 keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
236 keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
237 keyCode3.emplace_back(KeyCode::KEY_ALT_LEFT);
238 keyCode4.emplace_back(KeyCode::KEY_ALT_RIGHT);
239 permutation.emplace_back(++index);
240
241 keyCodes.emplace_back(keyCode1);
242 keyCodes.emplace_back(keyCode2);
243 keyCodes.emplace_back(keyCode3);
244 keyCodes.emplace_back(keyCode4);
245 }
246
AddKeyboardShortcutDoubleKeysWithShiftAlt(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)247 void AddKeyboardShortcutDoubleKeysWithShiftAlt(
248 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
249 {
250 uint8_t index = 0;
251 std::vector<KeyCode> keyCode1;
252 std::vector<KeyCode> keyCode2;
253 std::vector<KeyCode> keyCode3;
254 std::vector<KeyCode> keyCode4;
255
256 keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
257 keyCode2.emplace_back(KeyCode::KEY_SHIFT_LEFT);
258 keyCode3.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
259 keyCode4.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
260 permutation.emplace_back(++index);
261
262 keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
263 keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
264 keyCode3.emplace_back(KeyCode::KEY_ALT_LEFT);
265 keyCode4.emplace_back(KeyCode::KEY_ALT_RIGHT);
266 permutation.emplace_back(++index);
267
268 keyCodes.emplace_back(keyCode1);
269 keyCodes.emplace_back(keyCode2);
270 keyCodes.emplace_back(keyCode3);
271 keyCodes.emplace_back(keyCode4);
272 }
273
AddKeyboardShortcutDoubleKeys(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)274 void AddKeyboardShortcutDoubleKeys(
275 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
276 {
277 if (keys == CtrlKeysBit::CTRL + CtrlKeysBit::SHIFT) {
278 AddKeyboardShortcutDoubleKeysWithCtrlShift(keys, keyCodes, permutation);
279 }
280 if (keys == CtrlKeysBit::CTRL + CtrlKeysBit::ALT) {
281 AddKeyboardShortcutDoubleKeysWithCtrlAlt(keys, keyCodes, permutation);
282 }
283 if (keys == CtrlKeysBit::SHIFT + CtrlKeysBit::ALT) {
284 AddKeyboardShortcutDoubleKeysWithShiftAlt(keys, keyCodes, permutation);
285 }
286 }
287
AddKeyboardShortcutTripleKeys(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)288 void AddKeyboardShortcutTripleKeys(
289 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
290 {
291 uint8_t index = 0;
292 std::vector<KeyCode> keyCode1;
293 std::vector<KeyCode> keyCode2;
294 std::vector<KeyCode> keyCode3;
295 std::vector<KeyCode> keyCode4;
296 std::vector<KeyCode> keyCode5;
297 std::vector<KeyCode> keyCode6;
298 std::vector<KeyCode> keyCode7;
299 std::vector<KeyCode> keyCode8;
300
301 keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
302 keyCode2.emplace_back(KeyCode::KEY_CTRL_LEFT);
303 keyCode3.emplace_back(KeyCode::KEY_CTRL_LEFT);
304 keyCode4.emplace_back(KeyCode::KEY_CTRL_LEFT);
305 keyCode5.emplace_back(KeyCode::KEY_CTRL_RIGHT);
306 keyCode6.emplace_back(KeyCode::KEY_CTRL_RIGHT);
307 keyCode7.emplace_back(KeyCode::KEY_CTRL_RIGHT);
308 keyCode8.emplace_back(KeyCode::KEY_CTRL_RIGHT);
309 permutation.emplace_back(++index);
310
311 keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
312 keyCode2.emplace_back(KeyCode::KEY_SHIFT_LEFT);
313 keyCode3.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
314 keyCode4.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
315 keyCode5.emplace_back(KeyCode::KEY_SHIFT_LEFT);
316 keyCode6.emplace_back(KeyCode::KEY_SHIFT_LEFT);
317 keyCode7.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
318 keyCode8.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
319 permutation.emplace_back(++index);
320
321 keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
322 keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
323 keyCode3.emplace_back(KeyCode::KEY_ALT_LEFT);
324 keyCode4.emplace_back(KeyCode::KEY_ALT_RIGHT);
325 keyCode5.emplace_back(KeyCode::KEY_ALT_LEFT);
326 keyCode6.emplace_back(KeyCode::KEY_ALT_RIGHT);
327 keyCode7.emplace_back(KeyCode::KEY_ALT_LEFT);
328 keyCode8.emplace_back(KeyCode::KEY_ALT_RIGHT);
329 permutation.emplace_back(++index);
330
331 keyCodes.emplace_back(keyCode1);
332 keyCodes.emplace_back(keyCode2);
333 keyCodes.emplace_back(keyCode3);
334 keyCodes.emplace_back(keyCode4);
335 keyCodes.emplace_back(keyCode5);
336 keyCodes.emplace_back(keyCode6);
337 keyCodes.emplace_back(keyCode7);
338 keyCodes.emplace_back(keyCode8);
339 }
340
AddKeyboardShortcutKeys(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)341 void AddKeyboardShortcutKeys(
342 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
343 {
344 // single FunctionKey
345 if (keys == 0) {
346 keyCodes.emplace_back(std::vector<KeyCode>());
347 }
348 // single key
349 if (keys == CtrlKeysBit::CTRL || keys == CtrlKeysBit::SHIFT || keys == CtrlKeysBit::ALT) {
350 TAG_LOGD(AceLogTag::ACE_KEYBOARD, "AddKeyboardShortcutKeys single key");
351 AddKeyboardShortcutSingleKey(keys, keyCodes, permutation);
352 }
353 // double keys
354 if (keys == CtrlKeysBit::CTRL + CtrlKeysBit::SHIFT || keys == CtrlKeysBit::CTRL + CtrlKeysBit::ALT ||
355 keys == CtrlKeysBit::SHIFT + CtrlKeysBit::ALT) {
356 TAG_LOGI(AceLogTag::ACE_KEYBOARD, "AddKeyboardShortcutKeys double keys");
357 AddKeyboardShortcutDoubleKeys(keys, keyCodes, permutation);
358 }
359 // triple keys
360 if (keys == CtrlKeysBit::CTRL + CtrlKeysBit::SHIFT + CtrlKeysBit::ALT) {
361 TAG_LOGI(AceLogTag::ACE_KEYBOARD, "AddKeyboardShortcutKeys triple keys");
362 AddKeyboardShortcutTripleKeys(keys, keyCodes, permutation);
363 }
364 }
365
TriggerKeyboardShortcut(const KeyEvent & event,const std::vector<KeyboardShortcut> & keyboardShortcuts,const WeakPtr<FrameNode> & node,const RefPtr<EventHub> & eventHub)366 bool TriggerKeyboardShortcut(const KeyEvent& event, const std::vector<KeyboardShortcut>& keyboardShortcuts,
367 const WeakPtr<FrameNode>& node, const RefPtr<EventHub>& eventHub)
368 {
369 CHECK_NULL_RETURN(eventHub, false);
370 for (auto& keyboardShortcut : keyboardShortcuts) {
371 if (keyboardShortcut.value.empty()) {
372 continue;
373 }
374
375 std::vector<std::vector<KeyCode>> keyCodes;
376 std::vector<uint8_t> permutation;
377 AddKeyboardShortcutKeys(keyboardShortcut.keys, keyCodes, permutation);
378 if (event.IsFunctionKey() || event.IsEscapeKey()) {
379 if (event.ConvertInputCodeToString() != keyboardShortcut.value) {
380 continue;
381 }
382 } else if (event.ConvertInputCodeToString().find(keyboardShortcut.value) == std::string::npos) {
383 continue;
384 }
385 // Handle left and right the keys problem.
386 std::vector<uint8_t> perm;
387 for (auto& keyCode : keyCodes) {
388 perm.assign(permutation.begin(), permutation.end());
389 // Handle the keys order problem.
390 do {
391 keyCode.emplace_back(event.code);
392 if (!event.IsExactlyKey(keyCode)) {
393 keyCode.pop_back();
394 std::next_permutation(keyCode.begin(), keyCode.end());
395 continue;
396 }
397
398 if (keyboardShortcut.onKeyboardShortcutAction) {
399 keyboardShortcut.onKeyboardShortcutAction();
400 TAG_LOGI(AceLogTag::ACE_KEYBOARD, "TriggerKeyboardShortcut :%{public}d action done.",
401 static_cast<int32_t>(event.pressedCodes.size()));
402 return true;
403 } else {
404 auto gestureEventHub = eventHub->GetGestureEventHub();
405 if (gestureEventHub && gestureEventHub->IsClickable()) {
406 gestureEventHub->KeyBoardShortCutClick(event, node);
407 TAG_LOGI(AceLogTag::ACE_KEYBOARD, "TriggerKeyboardShortcut :%{public}d click done.",
408 static_cast<int32_t>(event.pressedCodes.size()));
409 return true;
410 }
411 }
412 keyCode.pop_back();
413 std::next_permutation(keyCode.begin(), keyCode.end());
414 } while (std::next_permutation(perm.begin(), perm.end()));
415 perm.clear();
416 }
417 keyCodes.clear();
418 permutation.clear();
419 }
420 return false;
421 }
422
DispatchKeyboardShortcut(const KeyEvent & event)423 bool KeyEventManager::DispatchKeyboardShortcut(const KeyEvent& event)
424 {
425 auto container = Container::GetContainer(GetInstanceId());
426 if (container && container->GetUIContentType() == UIContentType::SECURITY_UI_EXTENSION) {
427 TAG_LOGD(AceLogTag::ACE_KEYBOARD, "Do not dispatch keyboard shortcut because in security UEC");
428 return false;
429 }
430 if (event.action != KeyAction::DOWN) {
431 return false;
432 }
433 if (keyboardShortcutNode_.empty() || IsSystemKeyboardShortcut(event)) {
434 return false;
435 }
436 for (auto& node : keyboardShortcutNode_) {
437 auto frameNode = node.Upgrade();
438 if (!frameNode || !(frameNode->IsActive())) {
439 continue;
440 }
441 auto eventHub = frameNode->GetOrCreateEventHub<EventHub>();
442 if (!eventHub || !(eventHub->IsEnabled())) {
443 continue;
444 }
445
446 auto keyboardShortcuts = eventHub->GetKeyboardShortcut();
447 if (TriggerKeyboardShortcut(event, keyboardShortcuts, node, eventHub)) {
448 return true;
449 }
450 }
451 return false;
452 }
453
DelKeyboardShortcutNode(int32_t nodeId)454 void KeyEventManager::DelKeyboardShortcutNode(int32_t nodeId)
455 {
456 auto iter = keyboardShortcutNode_.begin();
457 while (iter != keyboardShortcutNode_.end()) {
458 auto frameNode = (*iter).Upgrade();
459 if (!frameNode) {
460 iter = keyboardShortcutNode_.erase(iter);
461 continue;
462 }
463 if (frameNode->GetId() == nodeId) {
464 keyboardShortcutNode_.erase(iter);
465 break;
466 }
467 ++iter;
468 }
469 }
470
DispatchTabIndexEventNG(const KeyEvent & event,const RefPtr<FrameNode> & mainView)471 bool KeyEventManager::DispatchTabIndexEventNG(const KeyEvent& event, const RefPtr<FrameNode>& mainView)
472 {
473 CHECK_NULL_RETURN(mainView, false);
474 TAG_LOGD(AceLogTag::ACE_FOCUS,
475 "Dispatch tab index event: code:%{private}d/action:%{public}d on node: %{public}s/%{public}d.", event.code,
476 event.action, mainView->GetTag().c_str(), mainView->GetId());
477 auto mainViewFocusHub = mainView->GetFocusHub();
478 CHECK_NULL_RETURN(mainViewFocusHub, false);
479 if (mainViewFocusHub->HandleFocusByTabIndex(event)) {
480 TAG_LOGD(AceLogTag::ACE_FOCUS,
481 "Tab index handled the key event: code:" SEC_PLD(%{private}d) "/action:%{public}d",
482 SEC_PARAM(event.code), event.action);
483 return true;
484 }
485 return false;
486 }
487
DispatchKeyEventNG(const KeyEvent & event,const RefPtr<FrameNode> & focusNode)488 bool KeyEventManager::DispatchKeyEventNG(const KeyEvent& event, const RefPtr<FrameNode>& focusNode)
489 {
490 if (!focusNode) {
491 TAG_LOGD(AceLogTag::ACE_FOCUS,
492 "Cannot dispatch key event: code:" SEC_PLD(%{private}d)
493 "/action:%{public}d/isPreIme:%{public}d on node: nullptr",
494 SEC_PARAM(event.code), event.action, event.isPreIme);
495 return false;
496 }
497 TAG_LOGD(AceLogTag::ACE_FOCUS,
498 "Dispatch key event: code:" SEC_PLD(%{private}d)
499 "/action:%{public}d/isPreIme:%{public}d on node: %{public}s/%{public}d.",
500 SEC_PARAM(event.code), event.action, event.isPreIme, focusNode->GetTag().c_str(), focusNode->GetId());
501 isKeyConsumed_ = false;
502 auto focusNodeHub = focusNode->GetFocusHub();
503 CHECK_NULL_RETURN(focusNodeHub, false);
504 if (focusNodeHub->HandleEvent(event)) {
505 TAG_LOGI(AceLogTag::ACE_FOCUS, "Focus system handled the key event: code:" SEC_PLD(%{private}d)
506 "/action:%{public}d", SEC_PARAM(event.code), event.action);
507 return true;
508 }
509 if (!isKeyConsumed_) {
510 TAG_LOGD(AceLogTag::ACE_FOCUS, "Focus system do not handled the key event: code:"
511 SEC_PLD(%{private}d) "/action:%{public}d", SEC_PARAM(event.code), event.action);
512 }
513 return isKeyConsumed_;
514 }
515
SetIsKeyConsumed(bool value)516 void KeyEventManager::SetIsKeyConsumed(bool value)
517 {
518 // Once consumed, isKeyConsumed_ keeps true
519 if (!isKeyConsumed_ && value) {
520 isKeyConsumed_ = true;
521 }
522 }
523
OnKeyEvent(const KeyEvent & event)524 bool KeyEventManager::OnKeyEvent(const KeyEvent& event)
525 {
526 SetPressedKeyCodes(event.pressedCodes);
527
528 // onKeyPreIme
529 if (event.isPreIme) {
530 ResSchedReport::GetInstance().OnKeyEvent(event);
531 if (TriggerKeyEventDispatch(event)) {
532 return true;
533 }
534 if (!IsSkipShortcutAndFocusMove()) {
535 return DispatchKeyboardShortcut(event);
536 } else {
537 TAG_LOGD(AceLogTag::ACE_KEYBOARD, "Do not dispatch keyboard shortcut because Web is current focus");
538 }
539 return false;
540 }
541
542 // process drag cancel
543 if (event.code == KeyCode::KEY_ESCAPE) {
544 auto dragDropMgr = GetDragDropManager(GetInstanceId());
545 if (dragDropMgr && dragDropMgr->IsMSDPDragging()) {
546 return true;
547 }
548 }
549
550 // OnKeyEvent
551 if (TriggerKeyEventDispatch(event)) {
552 return true;
553 }
554
555 return RemoveOverlayByESC(event);
556 }
557
OnFocusAxisEvent(const FocusAxisEvent & event)558 bool KeyEventManager::OnFocusAxisEvent(const FocusAxisEvent& event)
559 {
560 auto container = Container::GetContainer(GetInstanceId());
561 CHECK_NULL_RETURN(container, false);
562 auto pipeline = DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
563 CHECK_NULL_RETURN(pipeline, false);
564 auto rootNode = pipeline->GetRootElement();
565 CHECK_NULL_RETURN(rootNode, false);
566 auto focusNodeHub = rootNode->GetFocusHub();
567 CHECK_NULL_RETURN(focusNodeHub, false);
568 focusNodeHub->HandleEvent(event);
569 return true;
570 }
571
OnCrownEvent(const CrownEvent & event)572 bool KeyEventManager::OnCrownEvent(const CrownEvent& event)
573 {
574 auto container = Container::GetContainer(GetInstanceId());
575 CHECK_NULL_RETURN(container, false);
576 auto pipeline = DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
577 CHECK_NULL_RETURN(pipeline, false);
578 auto rootNode = pipeline->GetRootElement();
579 CHECK_NULL_RETURN(rootNode, false);
580 auto focusNodeHub = rootNode->GetFocusHub();
581 CHECK_NULL_RETURN(focusNodeHub, false);
582 focusNodeHub->HandleEvent(event);
583 return true;
584 }
585
TriggerKeyEventDispatch(const KeyEvent & event)586 bool KeyEventManager::TriggerKeyEventDispatch(const KeyEvent& event)
587 {
588 auto focusManager = GetFocusManager(GetInstanceId());
589 auto curFocusView = focusManager ? focusManager->GetLastFocusView().Upgrade() : nullptr;
590 auto curEntryFocusView = curFocusView ? curFocusView->GetEntryFocusView() : nullptr;
591 auto curEntryFocusViewFrame = curEntryFocusView ? curEntryFocusView->GetFrameNode() : nullptr;
592 if (event.isPreIme) {
593 return DispatchKeyEventNG(event, curEntryFocusViewFrame);
594 }
595
596 if (IsSkipShortcutAndFocusMove()) {
597 TAG_LOGD(AceLogTag::ACE_FOCUS, "Skip dispatching tab key because Web is current focus");
598 } else if (DispatchTabKey(event, curFocusView)) {
599 return true;
600 }
601 return DispatchKeyEventNG(event, curEntryFocusViewFrame) || isTabJustTriggerOnKeyEvent_;
602 }
603
IsSkipShortcutAndFocusMove()604 bool KeyEventManager::IsSkipShortcutAndFocusMove()
605 {
606 auto focusManager = GetFocusManager(GetInstanceId());
607 CHECK_NULL_RETURN(focusManager, false);
608
609 // Web component will NOT dispatch shortcut during the first event dispatch process.
610 // Web component will NOT trigger focus move during the third event dispatch process.
611 auto focusHub = focusManager->GetCurrentFocus();
612 auto curFrameNode = focusHub ? focusHub->GetFrameNode() : nullptr;
613 CHECK_NULL_RETURN(curFrameNode, false);
614 return curFrameNode->GetTag() == V2::WEB_ETS_TAG;
615 }
616
DispatchTabKey(const KeyEvent & event,const RefPtr<FocusView> & curFocusView)617 bool KeyEventManager::DispatchTabKey(const KeyEvent& event, const RefPtr<FocusView>& curFocusView)
618 {
619 auto focusManager = GetFocusManager(GetInstanceId());
620 CHECK_NULL_RETURN(focusManager, false);
621 isTabJustTriggerOnKeyEvent_ = focusManager->HandleKeyForExtendOrActivateFocus(event, curFocusView);
622 auto curEntryFocusView = curFocusView ? curFocusView->GetEntryFocusView() : nullptr;
623 auto curEntryFocusViewFrame = curEntryFocusView ? curEntryFocusView->GetFrameNode() : nullptr;
624 if (DispatchTabIndexEventNG(event, curEntryFocusViewFrame)) {
625 return true;
626 }
627 return false;
628 }
629
ReDispatch(KeyEvent & keyEvent)630 void KeyEventManager::ReDispatch(KeyEvent& keyEvent)
631 {
632 // Set keyEvent coming from Redispatch
633 keyEvent.isRedispatch = true;
634
635 if (DispatchKeyboardShortcut(keyEvent)) {
636 return;
637 }
638 auto focusManager = GetFocusManager(GetInstanceId());
639 auto curFocusView = focusManager ? focusManager->GetLastFocusView().Upgrade() : nullptr;
640 auto curEntryFocusView = curFocusView ? curFocusView->GetEntryFocusView() : nullptr;
641 auto curEntryFocusViewFrame = curEntryFocusView ? curEntryFocusView->GetFrameNode() : nullptr;
642 if (DispatchTabKey(keyEvent, curFocusView)) {
643 return;
644 }
645 if (DispatchKeyEventNG(keyEvent, curEntryFocusViewFrame)) {
646 return;
647 }
648 RemoveOverlayByESC(keyEvent);
649 }
650
RemoveOverlayByESC(const KeyEvent & keyEvent)651 bool KeyEventManager::RemoveOverlayByESC(const KeyEvent& keyEvent)
652 {
653 if (keyEvent.code == KeyCode::KEY_ESCAPE && keyEvent.action == KeyAction::DOWN) {
654 auto overlayManager = GetOverlayManager(GetInstanceId());
655 CHECK_NULL_RETURN(overlayManager, false);
656 auto currentContainer = Container::Current();
657 CHECK_NULL_RETURN(currentContainer, false);
658 if (currentContainer->IsSubContainer() || currentContainer->IsDialogContainer()) {
659 return overlayManager->RemoveOverlayInSubwindow();
660 } else {
661 return overlayManager->RemoveOverlay(false) || SheetManager::GetInstance().RemoveSheetByESC();
662 }
663 }
664 return false;
665 }
666 } // namespace OHOS::Ace::NG