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