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