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