1 /*
2  * Copyright (c) 2022-2023 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 
16 #include "adapter/preview/entrance/event_dispatcher.h"
17 
18 #include <map>
19 
20 #include "adapter/preview/entrance/ace_container.h"
21 #include "adapter/preview/entrance/ace_view_preview.h"
22 #include "adapter/preview/entrance/editing/text_input_client_mgr.h"
23 #include "base/log/ace_trace.h"
24 #include "base/log/log.h"
25 #include "core/common/container_scope.h"
26 #include "core/event/key_event.h"
27 #include "core/event/touch_event.h"
28 
29 namespace OHOS::Ace::Platform {
30 namespace {
31 
32 const wchar_t UPPER_CASE_A = L'A';
33 const wchar_t LOWER_CASE_A = L'a';
34 const wchar_t CASE_0 = L'0';
35 const std::wstring NUM_SYMBOLS = L")!@#$%^&*(";
36 const std::map<MMI::KeyCode, wchar_t> PRINTABEL_SYMBOLS = {
37     { MMI::KeyCode::KEY_GRAVE, L'`' },
38     { MMI::KeyCode::KEY_MINUS, L'-' },
39     { MMI::KeyCode::KEY_EQUALS, L'=' },
40     { MMI::KeyCode::KEY_LEFT_BRACKET, L'[' },
41     { MMI::KeyCode::KEY_RIGHT_BRACKET, L']' },
42     { MMI::KeyCode::KEY_BACKSLASH, L'\\' },
43     { MMI::KeyCode::KEY_SEMICOLON, L';' },
44     { MMI::KeyCode::KEY_APOSTROPHE, L'\'' },
45     { MMI::KeyCode::KEY_COMMA, L',' },
46     { MMI::KeyCode::KEY_PERIOD, L'.' },
47     { MMI::KeyCode::KEY_SLASH, L'/' },
48     { MMI::KeyCode::KEY_SPACE, L' ' },
49     { MMI::KeyCode::KEY_NUMPAD_DIVIDE, L'/' },
50     { MMI::KeyCode::KEY_NUMPAD_MULTIPLY, L'*' },
51     { MMI::KeyCode::KEY_NUMPAD_SUBTRACT, L'-' },
52     { MMI::KeyCode::KEY_NUMPAD_ADD, L'+' },
53     { MMI::KeyCode::KEY_NUMPAD_DOT, L'.' },
54     { MMI::KeyCode::KEY_NUMPAD_COMMA, L',' },
55     { MMI::KeyCode::KEY_NUMPAD_EQUALS, L'=' },
56 };
57 
58 const std::map<MMI::KeyCode, wchar_t> SHIFT_PRINTABEL_SYMBOLS = {
59     { MMI::KeyCode::KEY_GRAVE, L'~' },
60     { MMI::KeyCode::KEY_MINUS, L'_' },
61     { MMI::KeyCode::KEY_EQUALS, L'+' },
62     { MMI::KeyCode::KEY_LEFT_BRACKET, L'{' },
63     { MMI::KeyCode::KEY_RIGHT_BRACKET, L'}' },
64     { MMI::KeyCode::KEY_BACKSLASH, L'|' },
65     { MMI::KeyCode::KEY_SEMICOLON, L':' },
66     { MMI::KeyCode::KEY_APOSTROPHE, L'\"' },
67     { MMI::KeyCode::KEY_COMMA, L'<' },
68     { MMI::KeyCode::KEY_PERIOD, L'>' },
69     { MMI::KeyCode::KEY_SLASH, L'?' },
70 };
71 
ConvertTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,TouchEvent & event)72 void ConvertTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, TouchEvent& event)
73 {
74     event.id = pointerEvent->id;
75     event.x = pointerEvent->x;
76     event.y = pointerEvent->y;
77     event.screenX = pointerEvent->screenX;
78     event.screenY = pointerEvent->screenY;
79     event.type = static_cast<TouchType>(static_cast<size_t>(pointerEvent->type));
80     event.pullType = static_cast<TouchType>(static_cast<size_t>(pointerEvent->pullType));
81     event.time = pointerEvent->time;
82     event.size = pointerEvent->size;
83     event.force = pointerEvent->force;
84     event.tiltX = pointerEvent->tiltX;
85     event.tiltY = pointerEvent->tiltY;
86     event.deviceId = pointerEvent->deviceId;
87     event.sourceType = static_cast<SourceType>(static_cast<int32_t>(pointerEvent->sourceType));
88     event.sourceTool = static_cast<SourceTool>(static_cast<int32_t>(pointerEvent->sourceTool));
89     event.pointerEvent = pointerEvent;
90     TouchPoint pointer { .id = event.id,
91         .x = event.x,
92         .y = event.y,
93         .screenX = event.screenX,
94         .screenY = event.screenY,
95         .downTime = event.time,
96         .size = event.size,
97         .force = event.force,
98         .isPressed = (event.type == TouchType::DOWN) };
99     event.pointers.emplace_back(pointer);
100 }
101 
ConvertKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent,KeyEvent & event)102 void ConvertKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent, KeyEvent& event)
103 {
104     event.code = static_cast<KeyCode>(static_cast<int32_t>(keyEvent->code));
105     event.key = keyEvent->key;
106     event.action = static_cast<KeyAction>(static_cast<int32_t>(keyEvent->action));
107     for (auto& item : keyEvent->pressedCodes) {
108         event.pressedCodes.push_back(static_cast<KeyCode>(static_cast<int32_t>(item)));
109     }
110     event.repeatTime = keyEvent->repeatTime;
111     event.timeStamp = keyEvent->timeStamp;
112     event.metaKey = keyEvent->metaKey;
113     event.deviceId = keyEvent->deviceId;
114     event.sourceType = static_cast<SourceType>(static_cast<int32_t>(keyEvent->sourceType));
115     event.rawKeyEvent = keyEvent;
116     event.enableCapsLock = keyEvent->enableCapsLock_;
117 }
118 
119 } // namespace
120 
GetTouchEventOriginOffset(const TouchEvent & event)121 Offset GetTouchEventOriginOffset(const TouchEvent& event)
122 {
123     if (event.pointerEvent) {
124         for (auto& item : event.pointerEvent->pointers) {
125             return Offset(item.x, item.y);
126         }
127     }
128     return Offset();
129 }
130 
GetTouchEventOriginTimeStamp(const TouchEvent & event)131 TimeStamp GetTouchEventOriginTimeStamp(const TouchEvent& event)
132 {
133     if (event.pointerEvent) {
134         return event.pointerEvent->time;
135     }
136     return event.time;
137 }
138 
UpdatePressedKeyCodes(std::vector<KeyCode> & pressedKeyCodes)139 void UpdatePressedKeyCodes(std::vector<KeyCode>& pressedKeyCodes) {}
140 
EventDispatcher()141 EventDispatcher::EventDispatcher() {}
142 
143 EventDispatcher::~EventDispatcher() = default;
144 
Initialize()145 void EventDispatcher::Initialize()
146 {
147     LOGI("Initialize event dispatcher");
148     // Initial the proxy of Input method
149     TextInputClientMgr::GetInstance().InitTextInputProxy();
150     // Register the idle event callback function.
151 #ifndef ENABLE_ROSEN_BACKEND
152     IdleCallback idleNoticeCallback = [](int64_t deadline) {
153         EventDispatcher::GetInstance().DispatchIdleEvent(deadline);
154     };
155     FlutterDesktopSetIdleCallback(controller_, idleNoticeCallback);
156 #else
157     // rosen process idle
158 #endif
159 }
160 
DispatchIdleEvent(int64_t deadline)161 void EventDispatcher::DispatchIdleEvent(int64_t deadline)
162 {
163     ACE_SCOPED_TRACE("DispatchIdleEvent");
164     auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
165     if (!container) {
166         return;
167     }
168 
169     auto aceView = AceType::DynamicCast<AceViewPreview>(container->GetAceView());
170     if (!aceView) {
171         return;
172     }
173 
174     aceView->ProcessIdleEvent(deadline);
175 }
176 
GetMouseEventAction(int32_t action,OHOS::Ace::MouseEvent & mouseEvent)177 static void GetMouseEventAction(int32_t action, OHOS::Ace::MouseEvent& mouseEvent)
178 {
179     switch (action) {
180         case OHOS::MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN:
181             mouseEvent.action = MouseAction::PRESS;
182             break;
183         case OHOS::MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
184             mouseEvent.action = MouseAction::RELEASE;
185             break;
186         case OHOS::MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW:
187             mouseEvent.action = MouseAction::WINDOW_ENTER;
188             break;
189         case OHOS::MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW:
190             mouseEvent.action = MouseAction::WINDOW_LEAVE;
191             break;
192         case OHOS::MMI::PointerEvent::POINTER_ACTION_MOVE:
193             mouseEvent.action = MouseAction::MOVE;
194             break;
195         case OHOS::MMI::PointerEvent::POINTER_ACTION_PULL_DOWN:
196             mouseEvent.action = MouseAction::PRESS;
197             break;
198         case OHOS::MMI::PointerEvent::POINTER_ACTION_PULL_MOVE:
199             mouseEvent.action = MouseAction::MOVE;
200             break;
201         case OHOS::MMI::PointerEvent::POINTER_ACTION_PULL_UP:
202             mouseEvent.action = MouseAction::RELEASE;
203             break;
204         default:
205             mouseEvent.action = MouseAction::NONE;
206             break;
207     }
208 }
209 
GetMouseEventButton(int32_t button,Ace::MouseEvent & mouseEvent)210 static void GetMouseEventButton(int32_t button, Ace::MouseEvent& mouseEvent)
211 {
212     switch (button) {
213         case MMI::PointerEvent::MOUSE_BUTTON_LEFT:
214             mouseEvent.button = MouseButton::LEFT_BUTTON;
215             break;
216         case MMI::PointerEvent::MOUSE_BUTTON_RIGHT:
217             mouseEvent.button = MouseButton::RIGHT_BUTTON;
218             break;
219         case MMI::PointerEvent::MOUSE_BUTTON_MIDDLE:
220             mouseEvent.button = MouseButton::MIDDLE_BUTTON;
221             break;
222         case MMI::PointerEvent::MOUSE_BUTTON_SIDE:
223             mouseEvent.button = MouseButton::BACK_BUTTON;
224             break;
225         case MMI::PointerEvent::MOUSE_BUTTON_EXTRA:
226             mouseEvent.button = MouseButton::SIDE_BUTTON;
227             break;
228         case MMI::PointerEvent::MOUSE_BUTTON_FORWARD:
229             mouseEvent.button = MouseButton::FORWARD_BUTTON;
230             break;
231         case MMI::PointerEvent::MOUSE_BUTTON_BACK:
232             mouseEvent.button = MouseButton::BACK_BUTTON;
233             break;
234         case MMI::PointerEvent::MOUSE_BUTTON_TASK:
235             mouseEvent.button = MouseButton::TASK_BUTTON;
236             break;
237         default:
238             mouseEvent.button = MouseButton::NONE_BUTTON;
239             break;
240     }
241 }
242 
ConvertMouseEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,Ace::MouseEvent & mouseEvent)243 static void ConvertMouseEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, Ace::MouseEvent& mouseEvent)
244 {
245     mouseEvent.id = pointerEvent->id;
246     mouseEvent.x = pointerEvent->x;
247     mouseEvent.y = pointerEvent->y;
248     mouseEvent.screenX = pointerEvent->screenX;
249     mouseEvent.screenY = pointerEvent->screenY;
250     GetMouseEventAction(pointerEvent->pointerAction_, mouseEvent);
251     GetMouseEventButton(pointerEvent->buttonId_, mouseEvent);
252     mouseEvent.sourceType = SourceType::MOUSE;
253     mouseEvent.targetDisplayId = pointerEvent->targetDisplayId_;
254     mouseEvent.deviceId = pointerEvent->deviceId;
255     std::set<int32_t> buttonSet = pointerEvent->pressedButtons_;
256     if (pointerEvent->pressedButtons_.empty()) {
257         pointerEvent->pressedButtons_.insert(pointerEvent->buttonId_);
258     }
259     uint32_t buttons = 0;
260     if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_LEFT)) {
261         buttons &= static_cast<uint32_t>(MouseButton::LEFT_BUTTON);
262     }
263     if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_RIGHT)) {
264         buttons &= static_cast<uint32_t>(MouseButton::RIGHT_BUTTON);
265     }
266     if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_MIDDLE)) {
267         buttons &= static_cast<uint32_t>(MouseButton::MIDDLE_BUTTON);
268     }
269     if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_SIDE)) {
270         buttons &= static_cast<uint32_t>(MouseButton::SIDE_BUTTON);
271     }
272     if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_EXTRA)) {
273         buttons &= static_cast<uint32_t>(MouseButton::EXTRA_BUTTON);
274     }
275     if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_FORWARD)) {
276         buttons &= static_cast<uint32_t>(MouseButton::FORWARD_BUTTON);
277     }
278     if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_BACK)) {
279         buttons &= static_cast<uint32_t>(MouseButton::BACK_BUTTON);
280     }
281     if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_TASK)) {
282         buttons &= static_cast<uint32_t>(MouseButton::TASK_BUTTON);
283     }
284     mouseEvent.pressedButtons = static_cast<int32_t>(buttons);
285 }
286 
GetAxisEventAction(int32_t action,Ace::AxisEvent & event)287 static void GetAxisEventAction(int32_t action, Ace::AxisEvent& event)
288 {
289     switch (action) {
290         case MMI::PointerEvent::POINTER_ACTION_AXIS_BEGIN:
291             event.action = Ace::AxisAction::BEGIN;
292             break;
293         case MMI::PointerEvent::POINTER_ACTION_AXIS_UPDATE:
294             event.action = Ace::AxisAction::UPDATE;
295             break;
296         case MMI::PointerEvent::POINTER_ACTION_AXIS_END:
297             event.action = Ace::AxisAction::END;
298             break;
299         default:
300             event.action = Ace::AxisAction::NONE;
301             break;
302     }
303 }
304 
GetAxisValue(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::AxisType axis)305 static double GetAxisValue(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, MMI::PointerEvent::AxisType axis)
306 {
307     double axisValue {};
308     if ((axis >= MMI::PointerEvent::AXIS_TYPE_UNKNOWN) && (axis < MMI::PointerEvent::AXIS_TYPE_MAX)) {
309         axisValue = pointerEvent->axisValues_[axis];
310     }
311     return axisValue;
312 }
313 
ConvertAxisEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,Ace::AxisEvent & event)314 static void ConvertAxisEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, Ace::AxisEvent& event)
315 {
316     event.id = pointerEvent->id;
317     event.x = pointerEvent->x;
318     event.y = pointerEvent->y;
319     event.screenX = pointerEvent->screenX;
320     event.screenY = pointerEvent->screenY;
321     event.horizontalAxis = GetAxisValue(pointerEvent, MMI::PointerEvent::AxisType::AXIS_TYPE_SCROLL_HORIZONTAL);
322     event.verticalAxis = GetAxisValue(pointerEvent, MMI::PointerEvent::AxisType::AXIS_TYPE_SCROLL_VERTICAL);
323     event.pinchAxisScale = GetAxisValue(pointerEvent, MMI::PointerEvent::AxisType::AXIS_TYPE_PINCH);
324     event.rotateAxisAngle = GetAxisValue(pointerEvent, MMI::PointerEvent::AxisType::AXIS_TYPE_ROTATE);
325     GetAxisEventAction(pointerEvent->pointerAction_, event);
326     event.isRotationEvent = (pointerEvent->pointerAction_ >= MMI::PointerEvent::POINTER_ACTION_ROTATE_BEGIN) &&
327                             (pointerEvent->pointerAction_ <= MMI::PointerEvent::POINTER_ACTION_ROTATE_END);
328     event.sourceType = SourceType::MOUSE;
329     event.sourceTool = SourceTool::MOUSE;
330     event.pointerEvent = pointerEvent;
331 }
332 
DispatchTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)333 bool EventDispatcher::DispatchTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
334 {
335     ACE_SCOPED_TRACE("DispatchTouchEvent");
336     auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
337     CHECK_NULL_RETURN(container, false);
338     auto aceView = AceType::DynamicCast<AceViewPreview>(container->GetAceView());
339     CHECK_NULL_RETURN(aceView, false);
340     if (pointerEvent->sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
341         if (pointerEvent->pointerAction_ >= MMI::PointerEvent::POINTER_ACTION_AXIS_BEGIN &&
342             pointerEvent->pointerAction_ <= MMI::PointerEvent::POINTER_ACTION_AXIS_END) {
343             OHOS::Ace::AxisEvent axisEvent;
344             ConvertAxisEvent(pointerEvent, axisEvent);
345             return aceView->HandleAxisEvent(axisEvent);
346         } else {
347             OHOS::Ace::MouseEvent mouseEvent;
348             ConvertMouseEvent(pointerEvent, mouseEvent);
349             return aceView->HandleMouseEvent(mouseEvent);
350         }
351     }
352 
353     TouchEvent touchEvent;
354     ConvertTouchEvent(pointerEvent, touchEvent);
355     return aceView->HandleTouchEvent(touchEvent);
356 }
357 
DispatchBackPressedEvent()358 bool EventDispatcher::DispatchBackPressedEvent()
359 {
360     ACE_SCOPED_TRACE("DispatchBackPressedEvent");
361     auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
362     CHECK_NULL_RETURN(container, false);
363     auto context = container->GetPipelineContext();
364     CHECK_NULL_RETURN(context, false);
365 
366     std::promise<bool> backPromise;
367     std::future<bool> backFuture = backPromise.get_future();
368     auto weak = AceType::WeakClaim(AceType::RawPtr(context));
369     container->GetTaskExecutor()->PostTask(
370         [weak, &backPromise]() {
371             auto context = weak.Upgrade();
372             if (context == nullptr) {
373                 return;
374             }
375             bool canBack = false;
376             if (!context->IsLastPage()) {
377                 canBack = context->CallRouterBackToPopPage();
378             }
379             backPromise.set_value(canBack);
380         },
381         TaskExecutor::TaskType::PLATFORM, "ArkUICallRouterBackToPopPage");
382     return backFuture.get();
383 }
384 
DispatchInputMethodEvent(unsigned int codePoint)385 bool EventDispatcher::DispatchInputMethodEvent(unsigned int codePoint)
386 {
387     ACE_SCOPED_TRACE("DispatchInputMethodEvent");
388     return TextInputClientMgr::GetInstance().AddCharacter(static_cast<wchar_t>(codePoint));
389 }
390 
DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)391 bool EventDispatcher::DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
392 {
393     ACE_SCOPED_TRACE("DispatchKeyEvent");
394     if (HandleTextKeyEvent(keyEvent)) {
395         return true;
396     }
397     auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
398     CHECK_NULL_RETURN(container, false);
399     auto aceView = AceType::DynamicCast<AceViewPreview>(container->GetAceView());
400     CHECK_NULL_RETURN(aceView, false);
401 
402     KeyEvent event;
403     ConvertKeyEvent(keyEvent, event);
404     event.isPreIme = true;
405     if (!aceView->HandleKeyEvent(event)) {
406         event.isPreIme = false;
407         return aceView->HandleKeyEvent(event);
408     }
409     return true;
410 }
411 
HandleTextKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)412 bool EventDispatcher::HandleTextKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
413 {
414     // Only the keys involved in the input component are processed here, and the other keys will be forwarded.
415     if (!TextInputClientMgr::GetInstance().IsValidClientId()) {
416         return false;
417     }
418 
419     const static size_t maxKeySizes = 2;
420     wchar_t keyChar;
421     if (keyEvent->pressedCodes.size() == 1) {
422         auto iterCode = PRINTABEL_SYMBOLS.find(keyEvent->code);
423         if (iterCode != PRINTABEL_SYMBOLS.end()) {
424             keyChar = iterCode->second;
425         } else if (MMI::KeyCode::KEY_0 <= keyEvent->code && keyEvent->code <= MMI::KeyCode::KEY_9) {
426             keyChar = static_cast<wchar_t>(keyEvent->code) - static_cast<wchar_t>(MMI::KeyCode::KEY_0) + CASE_0;
427         } else if (MMI::KeyCode::KEY_NUMPAD_0 <= keyEvent->code && keyEvent->code <= MMI::KeyCode::KEY_NUMPAD_9) {
428             if (!keyEvent->enableNumLock_) {
429                 return true;
430             }
431             keyChar = static_cast<wchar_t>(keyEvent->code) - static_cast<wchar_t>(MMI::KeyCode::KEY_NUMPAD_0) + CASE_0;
432         } else if (MMI::KeyCode::KEY_A <= keyEvent->code && keyEvent->code <= MMI::KeyCode::KEY_Z) {
433             keyChar = static_cast<wchar_t>(keyEvent->code) - static_cast<wchar_t>(MMI::KeyCode::KEY_A);
434             keyChar += (keyEvent->enableCapsLock_ ? UPPER_CASE_A : LOWER_CASE_A);
435         } else {
436             return false;
437         }
438     } else if (keyEvent->pressedCodes.size() == maxKeySizes &&
439                keyEvent->pressedCodes[0] == MMI::KeyCode::KEY_SHIFT_LEFT) {
440         auto iterCode = SHIFT_PRINTABEL_SYMBOLS.find(keyEvent->code);
441         if (iterCode != SHIFT_PRINTABEL_SYMBOLS.end()) {
442             keyChar = iterCode->second;
443         } else if (MMI::KeyCode::KEY_A <= keyEvent->code && keyEvent->code <= MMI::KeyCode::KEY_Z) {
444             keyChar = static_cast<wchar_t>(keyEvent->code) - static_cast<wchar_t>(MMI::KeyCode::KEY_A);
445             keyChar += (keyEvent->enableCapsLock_ ? LOWER_CASE_A : UPPER_CASE_A);
446         } else if (MMI::KeyCode::KEY_0 <= keyEvent->code && keyEvent->code <= MMI::KeyCode::KEY_9) {
447             keyChar = NUM_SYMBOLS[static_cast<int32_t>(keyEvent->code) - static_cast<int32_t>(MMI::KeyCode::KEY_0)];
448         } else {
449             return false;
450         }
451     } else {
452         return false;
453     }
454     if (keyEvent->action != MMI::KeyAction::DOWN) {
455         return true;
456     }
457     return TextInputClientMgr::GetInstance().AddCharacter(keyChar);
458 }
459 
460 } // namespace OHOS::Ace::Platform
461