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.assign(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 event.numLock = keyEvent->enableNumLock_;
118 }
119
120 } // namespace
121
GetTouchEventOriginOffset(const TouchEvent & event)122 Offset GetTouchEventOriginOffset(const TouchEvent& event)
123 {
124 if (event.pointerEvent) {
125 for (auto& item : event.pointerEvent->pointers) {
126 return Offset(item.x, item.y);
127 }
128 }
129 return Offset();
130 }
131
GetTouchEventOriginTimeStamp(const TouchEvent & event)132 TimeStamp GetTouchEventOriginTimeStamp(const TouchEvent& event)
133 {
134 if (event.pointerEvent) {
135 return event.pointerEvent->time;
136 }
137 return event.time;
138 }
139
UpdatePressedKeyCodes(std::vector<KeyCode> & pressedKeyCodes)140 void UpdatePressedKeyCodes(std::vector<KeyCode>& pressedKeyCodes) {}
141
EventDispatcher()142 EventDispatcher::EventDispatcher() {}
143
144 EventDispatcher::~EventDispatcher() = default;
145
Initialize()146 void EventDispatcher::Initialize()
147 {
148 LOGI("Initialize event dispatcher");
149 // Initial the proxy of Input method
150 TextInputClientMgr::GetInstance().InitTextInputProxy();
151 // Register the idle event callback function.
152 #ifndef ENABLE_ROSEN_BACKEND
153 IdleCallback idleNoticeCallback = [](int64_t deadline) {
154 EventDispatcher::GetInstance().DispatchIdleEvent(deadline);
155 };
156 FlutterDesktopSetIdleCallback(controller_, idleNoticeCallback);
157 #else
158 // rosen process idle
159 #endif
160 }
161
DispatchIdleEvent(int64_t deadline)162 void EventDispatcher::DispatchIdleEvent(int64_t deadline)
163 {
164 ACE_SCOPED_TRACE("DispatchIdleEvent");
165 auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
166 if (!container) {
167 return;
168 }
169
170 auto aceView = AceType::DynamicCast<AceViewPreview>(container->GetAceView());
171 if (!aceView) {
172 return;
173 }
174
175 aceView->ProcessIdleEvent(deadline);
176 }
177
GetMouseEventAction(int32_t action,OHOS::Ace::MouseEvent & mouseEvent)178 static void GetMouseEventAction(int32_t action, OHOS::Ace::MouseEvent& mouseEvent)
179 {
180 switch (action) {
181 case OHOS::MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN:
182 mouseEvent.action = MouseAction::PRESS;
183 break;
184 case OHOS::MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
185 mouseEvent.action = MouseAction::RELEASE;
186 break;
187 case OHOS::MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW:
188 mouseEvent.action = MouseAction::WINDOW_ENTER;
189 break;
190 case OHOS::MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW:
191 mouseEvent.action = MouseAction::WINDOW_LEAVE;
192 break;
193 case OHOS::MMI::PointerEvent::POINTER_ACTION_MOVE:
194 mouseEvent.action = MouseAction::MOVE;
195 break;
196 case OHOS::MMI::PointerEvent::POINTER_ACTION_PULL_DOWN:
197 mouseEvent.action = MouseAction::PRESS;
198 break;
199 case OHOS::MMI::PointerEvent::POINTER_ACTION_PULL_MOVE:
200 mouseEvent.action = MouseAction::MOVE;
201 break;
202 case OHOS::MMI::PointerEvent::POINTER_ACTION_PULL_UP:
203 mouseEvent.action = MouseAction::RELEASE;
204 break;
205 default:
206 mouseEvent.action = MouseAction::NONE;
207 break;
208 }
209 }
210
GetMouseEventButton(int32_t button,Ace::MouseEvent & mouseEvent)211 static void GetMouseEventButton(int32_t button, Ace::MouseEvent& mouseEvent)
212 {
213 switch (button) {
214 case MMI::PointerEvent::MOUSE_BUTTON_LEFT:
215 mouseEvent.button = MouseButton::LEFT_BUTTON;
216 break;
217 case MMI::PointerEvent::MOUSE_BUTTON_RIGHT:
218 mouseEvent.button = MouseButton::RIGHT_BUTTON;
219 break;
220 case MMI::PointerEvent::MOUSE_BUTTON_MIDDLE:
221 mouseEvent.button = MouseButton::MIDDLE_BUTTON;
222 break;
223 case MMI::PointerEvent::MOUSE_BUTTON_SIDE:
224 mouseEvent.button = MouseButton::BACK_BUTTON;
225 break;
226 case MMI::PointerEvent::MOUSE_BUTTON_EXTRA:
227 mouseEvent.button = MouseButton::SIDE_BUTTON;
228 break;
229 case MMI::PointerEvent::MOUSE_BUTTON_FORWARD:
230 mouseEvent.button = MouseButton::FORWARD_BUTTON;
231 break;
232 case MMI::PointerEvent::MOUSE_BUTTON_BACK:
233 mouseEvent.button = MouseButton::BACK_BUTTON;
234 break;
235 case MMI::PointerEvent::MOUSE_BUTTON_TASK:
236 mouseEvent.button = MouseButton::TASK_BUTTON;
237 break;
238 default:
239 mouseEvent.button = MouseButton::NONE_BUTTON;
240 break;
241 }
242 }
243
ConvertMouseEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,Ace::MouseEvent & mouseEvent)244 static void ConvertMouseEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, Ace::MouseEvent& mouseEvent)
245 {
246 mouseEvent.id = pointerEvent->id;
247 mouseEvent.x = pointerEvent->x;
248 mouseEvent.y = pointerEvent->y;
249 mouseEvent.screenX = pointerEvent->screenX;
250 mouseEvent.screenY = pointerEvent->screenY;
251 GetMouseEventAction(pointerEvent->pointerAction_, mouseEvent);
252 GetMouseEventButton(pointerEvent->buttonId_, mouseEvent);
253 mouseEvent.sourceType = SourceType::MOUSE;
254 mouseEvent.targetDisplayId = pointerEvent->targetDisplayId_;
255 mouseEvent.deviceId = pointerEvent->deviceId;
256 std::set<int32_t> buttonSet = pointerEvent->pressedButtons_;
257 if (pointerEvent->pressedButtons_.empty()) {
258 pointerEvent->pressedButtons_.insert(pointerEvent->buttonId_);
259 }
260 uint32_t buttons = 0;
261 if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_LEFT)) {
262 buttons &= static_cast<uint32_t>(MouseButton::LEFT_BUTTON);
263 }
264 if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_RIGHT)) {
265 buttons &= static_cast<uint32_t>(MouseButton::RIGHT_BUTTON);
266 }
267 if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_MIDDLE)) {
268 buttons &= static_cast<uint32_t>(MouseButton::MIDDLE_BUTTON);
269 }
270 if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_SIDE)) {
271 buttons &= static_cast<uint32_t>(MouseButton::SIDE_BUTTON);
272 }
273 if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_EXTRA)) {
274 buttons &= static_cast<uint32_t>(MouseButton::EXTRA_BUTTON);
275 }
276 if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_FORWARD)) {
277 buttons &= static_cast<uint32_t>(MouseButton::FORWARD_BUTTON);
278 }
279 if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_BACK)) {
280 buttons &= static_cast<uint32_t>(MouseButton::BACK_BUTTON);
281 }
282 if (buttonSet.end() != buttonSet.find(MMI::PointerEvent::MOUSE_BUTTON_TASK)) {
283 buttons &= static_cast<uint32_t>(MouseButton::TASK_BUTTON);
284 }
285 mouseEvent.pressedButtons = static_cast<int32_t>(buttons);
286 }
287
GetAxisEventAction(int32_t action,Ace::AxisEvent & event)288 static void GetAxisEventAction(int32_t action, Ace::AxisEvent& event)
289 {
290 switch (action) {
291 case MMI::PointerEvent::POINTER_ACTION_AXIS_BEGIN:
292 event.action = Ace::AxisAction::BEGIN;
293 break;
294 case MMI::PointerEvent::POINTER_ACTION_AXIS_UPDATE:
295 event.action = Ace::AxisAction::UPDATE;
296 break;
297 case MMI::PointerEvent::POINTER_ACTION_AXIS_END:
298 event.action = Ace::AxisAction::END;
299 break;
300 default:
301 event.action = Ace::AxisAction::NONE;
302 break;
303 }
304 }
305
GetAxisValue(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::AxisType axis)306 static double GetAxisValue(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, MMI::PointerEvent::AxisType axis)
307 {
308 double axisValue {};
309 if ((axis >= MMI::PointerEvent::AXIS_TYPE_UNKNOWN) && (axis < MMI::PointerEvent::AXIS_TYPE_MAX)) {
310 axisValue = pointerEvent->axisValues_[axis];
311 }
312 return axisValue;
313 }
314
ConvertAxisEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,Ace::AxisEvent & event)315 static void ConvertAxisEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, Ace::AxisEvent& event)
316 {
317 event.id = pointerEvent->id;
318 event.x = pointerEvent->x;
319 event.y = pointerEvent->y;
320 event.screenX = pointerEvent->screenX;
321 event.screenY = pointerEvent->screenY;
322 event.horizontalAxis = GetAxisValue(pointerEvent, MMI::PointerEvent::AxisType::AXIS_TYPE_SCROLL_HORIZONTAL);
323 event.verticalAxis = GetAxisValue(pointerEvent, MMI::PointerEvent::AxisType::AXIS_TYPE_SCROLL_VERTICAL);
324 event.pinchAxisScale = GetAxisValue(pointerEvent, MMI::PointerEvent::AxisType::AXIS_TYPE_PINCH);
325 event.rotateAxisAngle = GetAxisValue(pointerEvent, MMI::PointerEvent::AxisType::AXIS_TYPE_ROTATE);
326 GetAxisEventAction(pointerEvent->pointerAction_, event);
327 event.isRotationEvent = (pointerEvent->pointerAction_ >= MMI::PointerEvent::POINTER_ACTION_ROTATE_BEGIN) &&
328 (pointerEvent->pointerAction_ <= MMI::PointerEvent::POINTER_ACTION_ROTATE_END);
329 event.sourceType = SourceType::MOUSE;
330 event.sourceTool = SourceTool::MOUSE;
331 event.pointerEvent = pointerEvent;
332 }
333
DispatchTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)334 bool EventDispatcher::DispatchTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
335 {
336 ACE_SCOPED_TRACE("DispatchTouchEvent");
337 auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
338 CHECK_NULL_RETURN(container, false);
339 auto aceView = AceType::DynamicCast<AceViewPreview>(container->GetAceView());
340 CHECK_NULL_RETURN(aceView, false);
341 if (pointerEvent->sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
342 if (pointerEvent->pointerAction_ >= MMI::PointerEvent::POINTER_ACTION_AXIS_BEGIN &&
343 pointerEvent->pointerAction_ <= MMI::PointerEvent::POINTER_ACTION_AXIS_END) {
344 OHOS::Ace::AxisEvent axisEvent;
345 ConvertAxisEvent(pointerEvent, axisEvent);
346 return aceView->HandleAxisEvent(axisEvent);
347 } else {
348 OHOS::Ace::MouseEvent mouseEvent;
349 ConvertMouseEvent(pointerEvent, mouseEvent);
350 return aceView->HandleMouseEvent(mouseEvent);
351 }
352 }
353
354 TouchEvent touchEvent;
355 ConvertTouchEvent(pointerEvent, touchEvent);
356 return aceView->HandleTouchEvent(touchEvent);
357 }
358
DispatchBackPressedEvent()359 bool EventDispatcher::DispatchBackPressedEvent()
360 {
361 ACE_SCOPED_TRACE("DispatchBackPressedEvent");
362 auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
363 CHECK_NULL_RETURN(container, false);
364 auto context = container->GetPipelineContext();
365 CHECK_NULL_RETURN(context, false);
366
367 std::promise<bool> backPromise;
368 std::future<bool> backFuture = backPromise.get_future();
369 auto weak = AceType::WeakClaim(AceType::RawPtr(context));
370 container->GetTaskExecutor()->PostTask(
371 [weak, &backPromise]() {
372 auto context = weak.Upgrade();
373 if (context == nullptr) {
374 return;
375 }
376 bool canBack = false;
377 if (!context->IsLastPage()) {
378 canBack = context->CallRouterBackToPopPage();
379 }
380 backPromise.set_value(canBack);
381 },
382 TaskExecutor::TaskType::PLATFORM, "ArkUICallRouterBackToPopPage");
383 return backFuture.get();
384 }
385
DispatchInputMethodEvent(unsigned int codePoint)386 bool EventDispatcher::DispatchInputMethodEvent(unsigned int codePoint)
387 {
388 ACE_SCOPED_TRACE("DispatchInputMethodEvent");
389 return TextInputClientMgr::GetInstance().AddCharacter(static_cast<wchar_t>(codePoint));
390 }
391
DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)392 bool EventDispatcher::DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
393 {
394 ACE_SCOPED_TRACE("DispatchKeyEvent");
395 if (HandleTextKeyEvent(keyEvent)) {
396 return true;
397 }
398 auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
399 CHECK_NULL_RETURN(container, false);
400 auto aceView = AceType::DynamicCast<AceViewPreview>(container->GetAceView());
401 CHECK_NULL_RETURN(aceView, false);
402
403 KeyEvent event;
404 ConvertKeyEvent(keyEvent, event);
405 event.isPreIme = true;
406 if (!aceView->HandleKeyEvent(event)) {
407 event.isPreIme = false;
408 return aceView->HandleKeyEvent(event);
409 }
410 return true;
411 }
412
HandleTextKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)413 bool EventDispatcher::HandleTextKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
414 {
415 // Only the keys involved in the input component are processed here, and the other keys will be forwarded.
416 if (!TextInputClientMgr::GetInstance().IsValidClientId()) {
417 return false;
418 }
419
420 const static size_t maxKeySizes = 2;
421 wchar_t keyChar;
422 if (keyEvent->pressedCodes.size() == 1) {
423 auto iterCode = PRINTABEL_SYMBOLS.find(keyEvent->code);
424 if (iterCode != PRINTABEL_SYMBOLS.end()) {
425 keyChar = iterCode->second;
426 } else if (MMI::KeyCode::KEY_0 <= keyEvent->code && keyEvent->code <= MMI::KeyCode::KEY_9) {
427 keyChar = static_cast<wchar_t>(keyEvent->code) - static_cast<wchar_t>(MMI::KeyCode::KEY_0) + CASE_0;
428 } else if (MMI::KeyCode::KEY_NUMPAD_0 <= keyEvent->code && keyEvent->code <= MMI::KeyCode::KEY_NUMPAD_9) {
429 if (!keyEvent->enableNumLock_) {
430 return true;
431 }
432 keyChar = static_cast<wchar_t>(keyEvent->code) - static_cast<wchar_t>(MMI::KeyCode::KEY_NUMPAD_0) + CASE_0;
433 } else if (MMI::KeyCode::KEY_A <= keyEvent->code && keyEvent->code <= MMI::KeyCode::KEY_Z) {
434 keyChar = static_cast<wchar_t>(keyEvent->code) - static_cast<wchar_t>(MMI::KeyCode::KEY_A);
435 keyChar += (keyEvent->enableCapsLock_ ? UPPER_CASE_A : LOWER_CASE_A);
436 } else {
437 return false;
438 }
439 } else if (keyEvent->pressedCodes.size() == maxKeySizes &&
440 keyEvent->pressedCodes[0] == MMI::KeyCode::KEY_SHIFT_LEFT) {
441 auto iterCode = SHIFT_PRINTABEL_SYMBOLS.find(keyEvent->code);
442 if (iterCode != SHIFT_PRINTABEL_SYMBOLS.end()) {
443 keyChar = iterCode->second;
444 } else if (MMI::KeyCode::KEY_A <= keyEvent->code && keyEvent->code <= MMI::KeyCode::KEY_Z) {
445 keyChar = static_cast<wchar_t>(keyEvent->code) - static_cast<wchar_t>(MMI::KeyCode::KEY_A);
446 keyChar += (keyEvent->enableCapsLock_ ? LOWER_CASE_A : UPPER_CASE_A);
447 } else if (MMI::KeyCode::KEY_0 <= keyEvent->code && keyEvent->code <= MMI::KeyCode::KEY_9) {
448 keyChar = NUM_SYMBOLS[static_cast<int32_t>(keyEvent->code) - static_cast<int32_t>(MMI::KeyCode::KEY_0)];
449 } else {
450 return false;
451 }
452 } else {
453 return false;
454 }
455 if (keyEvent->action != MMI::KeyAction::DOWN) {
456 return true;
457 }
458 return TextInputClientMgr::GetInstance().AddCharacter(keyChar);
459 }
460
461 } // namespace OHOS::Ace::Platform
462