• 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 "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