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