1 /*
2 * Copyright (c) 2024-2025 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 "render/EGLRender.h"
17 #include "napi/native_api.h"
18 #include <native_window/external_window.h>
19 #include <unordered_map>
20 #include <hilog/log.h>
21 #include <ace/xcomponent/native_interface_xcomponent.h>
22 #include <native_buffer/native_buffer.h>
23 #include <arkui/native_node_napi.h>
24 #include <arkui/native_node.h>
25 #include <arkui/native_interface.h>
26 #include "AccessibilityManagerTest.h"
27
28 #include <arkui/native_node.h>
29 #include <arkui/native_gesture.h>
30 #include <arkui/native_interface.h>
31
32 #include "XComponent/XComponentCrossLanguageTest.h"
33
34 static int NUMBER_200 = 200;
35
36 // libraryname模式不要使用xcomponentId区分组件
37 static std::unordered_map<std::string, ArkUI_NodeHandle> nodeHandleMap;
38 static std::unordered_map<std::string, AccessibilityManager*> accessibilityProviderMap;
39 static std::unordered_map<void*, EGLRender*> rendererMap;
40 static std::unordered_map<void*, OH_ArkUI_SurfaceCallback*> callbackMap;
41 static std::unordered_map<void*, OH_ArkUI_SurfaceHolder*> surfaceHolderMap;
42
43 std::string indicatorStateString = "";
44 std::string keyStateString = "";
45 std::string mouseStateString = "";
46 std::unordered_map<int, std::string> keyStrings = {
47 {-1, "UNKNOWN"},
48 {0, "FN"},
49 {1, "HOME"},
50 {2, "BACK"},
51 {10, "MEDIA_PLAY_PAUSE"},
52 {11, "MEDIA_STOP"},
53 {12, "MEDIA_NEXT"},
54 {13, "MEDIA_PREVIOUS"},
55 {14, "MEDIA_REWIND"},
56 {15, "MEDIA_FAST_FORWARD"},
57 {16, "VOLUME_UP"},
58 {17, "VOLUME_DOWN"},
59 {18, "POWER"},
60 {19, "CAMERA"},
61 {22, "VOLUME_MUTE"},
62 {23, "MUTE"},
63 {40, "BRIGHTNESS_UP"},
64 {41, "BRIGHTNESS_DOWN"},
65 {2000, "0"},
66 {2001, "1"},
67 {2002, "2"},
68 {2003, "3"},
69 {2004, "4"},
70 {2005, "5"},
71 {2006, "6"},
72 {2007, "7"},
73 {2008, "8"},
74 {2009, "9"},
75 {2010, "STAR"},
76 {2011, "POUND"},
77 {2012, "DPAD_UP"},
78 {2013, "DPAD_DOWN"},
79 {2014, "DPAD_LEFT"},
80 {2015, "DPAD_RIGHT"},
81 {2016, "DPAD_CENTER"},
82 {2017, "A"},
83 {2018, "B"},
84 {2019, "C"},
85 {2020, "D"},
86 {2021, "E"},
87 {2022, "F"},
88 {2023, "G"},
89 {2024, "H"},
90 {2025, "I"},
91 {2026, "J"},
92 {2027, "K"},
93 {2028, "L"},
94 {2029, "M"},
95 {2030, "N"},
96 {2031, "O"},
97 {2032, "P"},
98 {2033, "Q"},
99 {2034, "R"},
100 {2035, "S"},
101 {2036, "T"},
102 {2037, "U"},
103 {2038, "V"},
104 {2039, "W"},
105 {2040, "X"},
106 {2041, "Y"},
107 {2042, "Z"},
108 {2043, "COMMA"},
109 {2044, "PERIOD"},
110 {2045, "ALT_LEFT"},
111 {2046, "ALT_RIGHT"},
112 {2047, "SHIFT_LEFT"},
113 {2048, "SHIFT_RIGHT"},
114 {2049, "TAB"},
115 {2050, "SPACE"},
116 {2051, "SYM"},
117 {2052, "EXPLORER"},
118 {2053, "ENVELOPE"},
119 {2054, "ENTER"},
120 {2055, "DEL"},
121 {2056, "GRAVE"},
122 {2057, "MINUS"},
123 {2058, "EQUALS"},
124 {2059, "LEFT_BRACKET"},
125 {2060, "RIGHT_BRACKET"},
126 {2061, "BACKSLASH"},
127 {2062, "SEMICOLON"},
128 {2063, "APOSTROPHE"},
129 {2064, "SLASH"},
130 {2065, "AT"},
131 {2066, "PLUS"},
132 {2067, "MENU"},
133 {2068, "PAGE_UP"},
134 {2069, "PAGE_DOWN"},
135 {2070, "ESCAPE"},
136 {2071, "FORWARD_DEL"},
137 {2072, "CTRL_LEFT"},
138 {2073, "CTRL_RIGHT"},
139 {2074, "CAPS_LOCK"},
140 {2075, "SCROLL_LOCK"},
141 {2076, "META_LEFT"},
142 {2077, "META_RIGHT"},
143 {2078, "FUNCTION"},
144 {2079, "SYSRQ"},
145 {2080, "BREAK"},
146 {2081, "MOVE_HOME"},
147 {2082, "MOVE_END"},
148 {2083, "INSERT"},
149 {2084, "FORWARD"},
150 {2085, "MEDIA_PLAY"},
151 {2086, "MEDIA_PAUSE"},
152 {2087, "MEDIA_CLOSE"},
153 {2088, "MEDIA_EJECT"},
154 {2089, "MEDIA_RECORD"},
155 {2090, "F1"},
156 {2091, "F2"},
157 {2092, "F3"},
158 {2093, "F4"},
159 {2094, "F5"},
160 {2095, "F6"},
161 {2096, "F7"},
162 {2097, "F8"},
163 {2098, "F9"},
164 {2099, "F10"},
165 {2100, "F11"},
166 {2101, "F12"},
167 {2102, "NUM_LOCK"},
168 {2103, "NUMPAD_0"},
169 {2104, "NUMPAD_1"},
170 {2105, "NUMPAD_2"},
171 {2106, "NUMPAD_3"},
172 {2107, "NUMPAD_4"},
173 {2108, "NUMPAD_5"},
174 {2109, "NUMPAD_6"},
175 {2110, "NUMPAD_7"},
176 {2111, "NUMPAD_8"},
177 {2112, "NUMPAD_9"},
178 {2113, "NUMPAD_DIVIDE"},
179 {2114, "NUMPAD_MULTIPLY"},
180 {2115, "NUMPAD_SUBTRACT"},
181 {2116, "NUMPAD_ADD"},
182 {2117, "NUMPAD_DOT"},
183 {2118, "NUMPAD_COMMA"},
184 {2119, "NUMPAD_ENTER"},
185 {2120, "NUMPAD_EQUALS"},
186 {2121, "NUMPAD_LEFT_PAREN"},
187 {2122, "NUMPAD_RIGHT_PAREN"},
188 {2210, "VIRTUAL_MULTITASK"},
189 {2600, "SLEEP"},
190 {2601, "ZENKAKU_HANKAKU"},
191 {2602, "102ND"},
192 {2603, "RO"},
193 {2604, "KATAKANA"},
194 {2605, "HIRAGANA"},
195 {2606, "HENKAN"},
196 {2607, "KATAKANA_HIRAGANA"},
197 {2608, "MUHENKAN"},
198 {2609, "LINEFEED"},
199 {2610, "MACRO"},
200 {2611, "NUMPAD_PLUSMINUS"},
201 {2612, "SCALE"},
202 {2613, "HANGUEL"},
203 {2614, "HANJA"},
204 {2615, "YEN"},
205 {2616, "STOP"},
206 {2617, "AGAIN"},
207 {2618, "PROPS"},
208 {2619, "UNDO"},
209 {2620, "COPY"},
210 {2621, "OPEN"},
211 {2622, "PASTE"},
212 {2623, "FIND"},
213 {2624, "CUT"},
214 {2625, "HELP"},
215 {2626, "CALC"},
216 {2627, "FILE"},
217 {2628, "BOOKMARKS"},
218 {2629, "NEXT"},
219 {2630, "PLAYPAUSE"},
220 {2631, "PREVIOUS"},
221 {2632, "STOPCD"},
222 {2634, "CONFIG"},
223 {2635, "REFRESH"},
224 {2636, "EXIT"},
225 {2637, "EDIT"},
226 {2638, "SCROLLUP"},
227 {2639, "SCROLLDOWN"},
228 {2640, "NEW"},
229 {2641, "REDO"},
230 {2642, "CLOSE"},
231 {2643, "PLAY"},
232 {2644, "BASSBOOST"},
233 {2645, "PRINT"},
234 {2646, "CHAT"},
235 {2647, "FINANCE"},
236 {2648, "CANCEL"},
237 {2649, "KBDILLUM_TOGGLE"},
238 {2650, "KBDILLUM_DOWN"},
239 {2651, "KBDILLUM_UP"},
240 {2652, "SEND"},
241 {2653, "REPLY"},
242 {2654, "FORWARDMAIL"},
243 {2655, "SAVE"},
244 {2656, "DOCUMENTS"},
245 {2657, "VIDEO_NEXT"},
246 {2658, "VIDEO_PREV"},
247 {2659, "BRIGHTNESS_CYCLE"},
248 {2660, "BRIGHTNESS_ZERO"},
249 {2661, "DISPLAY_OFF"},
250 {2662, "BTN_MISC"},
251 {2663, "GOTO"},
252 {2664, "INFO"},
253 {2665, "PROGRAM"},
254 {2666, "PVR"},
255 {2667, "SUBTITLE"},
256 {2668, "FULL_SCREEN"},
257 {2669, "KEYBOARD"},
258 {2670, "ASPECT_RATIO"},
259 {2671, "PC"},
260 {2672, "TV"},
261 {2673, "TV2"},
262 {2674, "VCR"},
263 {2675, "VCR2"},
264 {2676, "SAT"},
265 {2677, "CD"},
266 {2678, "TAPE"},
267 {2679, "TUNER"},
268 {2680, "PLAYER"},
269 {2681, "DVD"},
270 {2682, "AUDIO"},
271 {2683, "VIDEO"},
272 {2684, "MEMO"},
273 {2685, "CALENDAR"},
274 {2686, "RED"},
275 {2687, "GREEN"},
276 {2688, "YELLOW"},
277 {2689, "BLUE"},
278 {2690, "CHANNELUP"},
279 {2691, "CHANNELDOWN"},
280 {2692, "LAST"},
281 {2693, "RESTART"},
282 {2694, "SLOW"},
283 {2695, "SHUFFLE"},
284 {2696, "VIDEOPHONE"},
285 {2697, "GAMES"},
286 {2698, "ZOOMIN"},
287 {2699, "ZOOMOUT"},
288 {2700, "ZOOMRESET"},
289 {2701, "WORDPROCESSOR"},
290 {2702, "EDITOR"},
291 {2703, "SPREADSHEET"},
292 {2704, "GRAPHICSEDITOR"},
293 {2705, "PRESENTATION"},
294 {2706, "DATABASE"},
295 {2707, "NEWS"},
296 {2708, "VOICEMAIL"},
297 {2709, "ADDRESSBOOK"},
298 {2710, "MESSENGER"},
299 {2711, "BRIGHTNESS_TOGGLE"},
300 {2712, "SPELLCHECK"},
301 {2713, "COFFEE"},
302 {2714, "MEDIA_REPEAT"},
303 {2715, "IMAGES"},
304 {2716, "BUTTONCONFIG"},
305 {2717, "TASKMANAGER"},
306 {2718, "JOURNAL"},
307 {2719, "CONTROLPANEL"},
308 {2720, "APPSELECT"},
309 {2721, "SCREENSAVER"},
310 {2722, "ASSISTANT"},
311 {2723, "KBD_LAYOUT_NEXT"},
312 {2724, "BRIGHTNESS_MIN"},
313 {2725, "BRIGHTNESS_MAX"},
314 {2726, "KBDINPUTASSIST_PREV"},
315 {2727, "KBDINPUTASSIST_NEXT"},
316 {2728, "KBDINPUTASSIST_PREVGROUP"},
317 {2729, "KBDINPUTASSIST_NEXTGROUP"},
318 {2730, "KBDINPUTASSIST_ACCEPT"},
319 {2731, "KBDINPUTASSIST_CANCEL"},
320 {2800, "FRONT"},
321 {2801, "SETUP"},
322 {2802, "WAKEUP"},
323 {2803, "SENDFILE"},
324 {2804, "DELETEFILE"},
325 {2805, "XFER"},
326 {2806, "PROG1"},
327 {2807, "PROG2"},
328 {2808, "MSDOS"},
329 {2809, "SCREENLOCK"},
330 {2810, "DIRECTION_ROTATE_DISPLAY"},
331 {2811, "CYCLEWINDOWS"},
332 {2812, "COMPUTER"},
333 {2813, "EJECTCLOSECD"},
334 {2814, "ISO"},
335 {2815, "MOVE"},
336 {2816, "F13"},
337 {2817, "F14"},
338 {2818, "F15"},
339 {2819, "F16"},
340 {2820, "F17"},
341 {2821, "F18"},
342 {2822, "F19"},
343 {2823, "F20"},
344 {2824, "F21"},
345 {2825, "F22"},
346 {2826, "F23"},
347 {2827, "F24"},
348 {2828, "PROG3"},
349 {2829, "PROG4"},
350 {2830, "DASHBOARD"},
351 {2831, "SUSPEND"},
352 {2832, "HP"},
353 {2833, "SOUND"},
354 {2834, "QUESTION"},
355 {2836, "CONNECT"},
356 {2837, "SPORT"},
357 {2838, "SHOP"},
358 {2839, "ALTERASE"},
359 {2841, "SWITCHVIDEOMODE"},
360 {2842, "BATTERY"},
361 {2843, "BLUETOOTH"},
362 {2844, "WLAN"},
363 {2845, "UWB"},
364 {2846, "WWAN_WIMAX"},
365 {2847, "RFKILL"},
366 {3001, "CHANNEL"},
367 {3100, "BTN_0"},
368 {3101, "BTN_1"},
369 {3102, "BTN_2"},
370 {3103, "BTN_3"},
371 {3104, "BTN_4"},
372 {3105, "BTN_5"},
373 {3106, "BTN_6"},
374 {3107, "BTN_7"},
375 {3108, "BTN_8"},
376 {3109, "BTN_9"},
377 };
378
379 ArkUI_NativeNodeAPI_1 * nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1*>(
380 OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1")
381 );
382
value2String(napi_env env,napi_value value)383 std::string value2String(napi_env env, napi_value value)
384 {
385 size_t stringSize = 0;
386 napi_get_value_string_utf8(env, value, nullptr, 0, &stringSize);
387 std::string valueString;
388 valueString.resize(stringSize);
389 napi_get_value_string_utf8(env, value, &valueString[0], stringSize+1, &stringSize);
390 if (valueString.size() == 9) valueString.pop_back();
391 return valueString;
392 }
393
OnSurfaceCreated(OH_ArkUI_SurfaceHolder * holder)394 void OnSurfaceCreated(OH_ArkUI_SurfaceHolder* holder)
395 {
396 auto window = OH_ArkUI_XComponent_GetNativeWindow(holder);
397 auto render = new EGLRender();
398 rendererMap[holder] = render;
399 render->SetUpEGLContext(window, 0);
400 }
401
OnSurfaceChanged(OH_ArkUI_SurfaceHolder * holder,uint64_t width,uint64_t height)402 void OnSurfaceChanged(OH_ArkUI_SurfaceHolder* holder, uint64_t width, uint64_t height)
403 {
404 auto window = OH_ArkUI_XComponent_GetNativeWindow(holder);
405 uint64_t sid;
406 OH_NativeWindow_GetSurfaceId(window, &sid);
407 if (rendererMap.count(holder)) {
408 auto render = rendererMap[holder];
409 render->SetEGLWindowSize(width, height);
410 }
411 }
412
OnSurfaceDestroyed(OH_ArkUI_SurfaceHolder * holder)413 void OnSurfaceDestroyed(OH_ArkUI_SurfaceHolder* holder)
414 {
415 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "wds", "on destroyed");
416 auto window = OH_ArkUI_XComponent_GetNativeWindow(holder);
417 if (rendererMap.count(holder)) {
418 auto render = rendererMap[holder];
419 delete render;
420 rendererMap.erase(holder);
421 }
422 if (callbackMap.count(holder)) {
423 OH_ArkUI_SurfaceCallback_Dispose(callbackMap[holder]);
424 callbackMap.erase(holder);
425 }
426 OH_ArkUI_SurfaceHolder_Dispose(holder);
427 }
428
OnFrameCallback(ArkUI_NodeHandle node,uint64_t a,uint64_t b)429 void OnFrameCallback(ArkUI_NodeHandle node, uint64_t a, uint64_t b)
430 {
431 if (!surfaceHolderMap.count(node)) {
432 return;
433 }
434 auto holder = surfaceHolderMap[node];
435 auto render = rendererMap[holder];
436 render->DrawOnFrame();
437 }
438
OnSurfaceShow(OH_ArkUI_SurfaceHolder * holder)439 void OnSurfaceShow(OH_ArkUI_SurfaceHolder* holder)
440 {
441 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "wds", "on surface show");
442 }
443
OnSurfaceHide(OH_ArkUI_SurfaceHolder * holder)444 void OnSurfaceHide(OH_ArkUI_SurfaceHolder* holder)
445 {
446 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "wds", "on surface hide");
447 }
448
SetXComponentID(ArkUI_NodeHandle node,const char * id)449 void SetXComponentID(ArkUI_NodeHandle node, const char* id)
450 {
451 ArkUI_AttributeItem item = {nullptr, 0, id};
452 nodeAPI->setAttribute(node, NODE_XCOMPONENT_ID, &item);
453 return;
454 }
455
SetHeight(ArkUI_NodeHandle node,float height)456 void SetHeight(ArkUI_NodeHandle node, float height)
457 {
458 ArkUI_NumberValue value[] = {{.f32 = height}};
459 ArkUI_AttributeItem item = {value, 1};
460 nodeAPI->setAttribute(node, NODE_HEIGHT, &item);
461 return;
462 }
SetWidth(ArkUI_NodeHandle node,float width)463 void SetWidth(ArkUI_NodeHandle node, float width)
464 {
465 ArkUI_NumberValue value[] = {{.f32 = width}};
466 ArkUI_AttributeItem item = {value, 1};
467 nodeAPI->setAttribute(node, NODE_WIDTH, &item);
468 return;
469 }
470
focusable(ArkUI_NodeHandle handle,bool focusable)471 void focusable(ArkUI_NodeHandle handle, bool focusable)
472 {
473 ArkUI_NumberValue value[] = {{.i32 = static_cast<int>(focusable)}};
474 ArkUI_AttributeItem item = {value, 1};
475 nodeAPI->setAttribute(handle, NODE_FOCUSABLE, &item);
476 }
477
defaultFocus(ArkUI_NodeHandle handle,bool defaultFocus)478 void defaultFocus(ArkUI_NodeHandle handle, bool defaultFocus)
479 {
480 ArkUI_NumberValue value[] = {{.i32 = static_cast<int>(defaultFocus)}};
481 ArkUI_AttributeItem item = {value, 1};
482 nodeAPI->setAttribute(handle, NODE_DEFAULT_FOCUS, &item);
483 }
484
focusOnTouch(ArkUI_NodeHandle handle,bool focusOnTouch)485 void focusOnTouch(ArkUI_NodeHandle handle, bool focusOnTouch)
486 {
487 ArkUI_NumberValue value[] = {{.i32 = static_cast<int>(focusOnTouch)}};
488 ArkUI_AttributeItem item = {value, 1};
489 nodeAPI->setAttribute(handle, NODE_FOCUS_ON_TOUCH, &item);
490 }
491
setBackgroundColor(ArkUI_NodeHandle handle)492 void setBackgroundColor(ArkUI_NodeHandle handle)
493 {
494 ArkUI_NumberValue value[] = { {.u32=0xFFFF0000} };
495 ArkUI_AttributeItem item = { value, sizeof(value)/sizeof(ArkUI_NumberValue) };
496 nodeAPI->setAttribute(handle, NODE_BACKGROUND_COLOR, &item);
497 }
498
DispatchMouseEventCB(OH_NativeXComponent * component,void * window)499 void DispatchMouseEventCB(OH_NativeXComponent *component, void *window)
500 {
501 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "wds", "DispatchMouseEventCB");
502 OH_NativeXComponent_ExtraMouseEventInfo *extMouseEvent = nullptr;
503 OH_NativeXComponent_MouseEvent mouseEvent;
504 OH_NativeXComponent_GetMouseEvent(component, window, &mouseEvent);
505 int32_t ret = OH_NativeXComponent_GetExtraMouseEventInfo(component, &extMouseEvent);
506 if (ret != ARKUI_ERROR_CODE_NO_ERROR) {
507 // 错误处理
508 }
509 uint64_t keys = 0u;
510 ret = OH_NativeXComponent_GetMouseEventModifierKeyStates(extMouseEvent, &keys);
511 if (ret != ARKUI_ERROR_CODE_NO_ERROR) {
512 // 错误处理
513 }
514
515 mouseStateString = "mouse:";
516 if ((keys & ArkUI_ModifierKeyName::ARKUI_MODIFIER_KEY_CTRL) > 0) {
517 mouseStateString += " ctrl: down";
518 }
519 if ((keys & ArkUI_ModifierKeyName::ARKUI_MODIFIER_KEY_SHIFT) > 0) {
520 // Shift键被按下
521 mouseStateString += " shift: down";
522 }
523 if ((keys & ArkUI_ModifierKeyName::ARKUI_MODIFIER_KEY_ALT) > 0) {
524 // Alt键被按下
525 mouseStateString += " alt: down";
526 }
527 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "wds", "mouse: %{public}s", mouseStateString.c_str());
528 }
529
DispatchKeyEventCB(OH_NativeXComponent * component,void * window)530 void DispatchKeyEventCB(OH_NativeXComponent *component, void *window)
531 {
532 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "wds", "DispatchKeyEventCB");
533 OH_NativeXComponent_KeyEvent *keyEvent = nullptr;
534 int ret = OH_NativeXComponent_GetKeyEvent(component, &keyEvent);
535 OH_NativeXComponent_KeyCode keycode;
536 OH_NativeXComponent_GetKeyEventCode(keyEvent, &keycode);
537 std::string keyname = keyStrings[static_cast<int>(keycode)];
538 std::string stateString = "key: " + keyname;
539
540 // 修饰键
541 uint64_t keys = 0u;
542 ret = OH_NativeXComponent_GetKeyEventModifierKeyStates(keyEvent, &keys);
543 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "wds",
544 "OH_NativeXComponent_GetKeyEventModifierKeyStates: %{public}d", ret);
545
546 if ((keys & ArkUI_ModifierKeyName::ARKUI_MODIFIER_KEY_CTRL) > 0) {
547 // Ctrl键被按下
548 stateString += " ctrl: down;";
549 keyStateString = "key: " + keyname + " ctrl: down";
550 }
551 if ((keys & ArkUI_ModifierKeyName::ARKUI_MODIFIER_KEY_SHIFT) > 0) {
552 // Shift键被按下
553 stateString += " shift: down;";
554 keyStateString = "key: " + keyname + " shift: down";
555 }
556 if ((keys & ArkUI_ModifierKeyName::ARKUI_MODIFIER_KEY_ALT) > 0) {
557 // Alt键被按下
558 stateString += " alt: down;";
559 keyStateString = "key: " + keyname + " alt: down";
560 }
561
562 // 键盘指示灯键
563 bool isCapsLockOn = false;
564 ret = OH_NativeXComponent_GetKeyEventCapsLockState(keyEvent, &isCapsLockOn);
565 if (ret != ARKUI_ERROR_CODE_NO_ERROR) {
566 // 错误处理
567 }
568 if (isCapsLockOn) {
569 stateString += " capslock: on;";
570 indicatorStateString = "key: " + keyname + " capslock: on";
571 } else {
572 // 大写未被锁定
573 }
574
575 bool isNumLockOn = false;
576 ret = OH_NativeXComponent_GetKeyEventNumLockState(keyEvent, &isNumLockOn);
577 if (ret != ARKUI_ERROR_CODE_NO_ERROR) {
578 // 错误处理
579 }
580 if (isNumLockOn) {
581 stateString += " numlock: on;";
582 indicatorStateString = "key: " + keyname + " numlock: on";
583 } else {
584 // 未开启小键盘锁
585 }
586
587 bool isScrollLockOn = false;
588 ret = OH_NativeXComponent_GetKeyEventScrollLockState(keyEvent, &isScrollLockOn);
589 if (ret != ARKUI_ERROR_CODE_NO_ERROR) {
590 // 错误处理
591 }
592 if (isScrollLockOn) {
593 stateString += " scrolllock: on;";
594 indicatorStateString = "key: " + keyname + " scrolllock: on";
595 } else {
596 // 未打开滚动锁定键
597 }
598 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "wds", "key: %{public}s", stateString.c_str());
599 }
600
GetKeyString(napi_env env,napi_callback_info info)601 napi_value GetKeyString(napi_env env, napi_callback_info info)
602 {
603 napi_value cppStr;
604 napi_create_string_latin1(env, keyStateString.c_str(), keyStateString.size(), &(cppStr));
605 return cppStr;
606 }
607
GetIndicatorString(napi_env env,napi_callback_info info)608 napi_value GetIndicatorString(napi_env env, napi_callback_info info)
609 {
610 napi_value cppStr;
611 napi_create_string_latin1(env, indicatorStateString.c_str(), indicatorStateString.size(), &(cppStr));
612 return cppStr;
613 }
614
GetMouseString(napi_env env,napi_callback_info info)615 napi_value GetMouseString(napi_env env, napi_callback_info info)
616 {
617 napi_value cppStr;
618 napi_create_string_latin1(env, mouseStateString.c_str(), mouseStateString.size(), &(cppStr));
619 return cppStr;
620 }
621
createNativeNode(napi_env env,napi_callback_info info)622 napi_value createNativeNode(napi_env env, napi_callback_info info)
623 {
624 if ((env == nullptr) || (info == nullptr)) {
625 return nullptr;
626 }
627
628 size_t argCnt = 1;
629 napi_value args[1] = { nullptr};
630 if (napi_get_cb_info(env, info, &argCnt, args, nullptr, nullptr) != napi_ok) {
631 return nullptr;
632 }
633
634 if (argCnt != 1) {
635 napi_throw_type_error(env, NULL, "Wrong number of arguments");
636 return nullptr;
637 }
638
639 ArkUI_NodeContentHandle nodeContentHandle_ = nullptr;
640 OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &nodeContentHandle_);
641 if (OH_ArkUI_NodeContent_GetUserData(nodeContentHandle_)) {
642 return nullptr;
643 }
644
645 ArkUI_NodeHandle xcNode = nullptr;
646 xcNode = nodeAPI->createNode(ARKUI_NODE_XCOMPONENT);
647 SetXComponentID(xcNode, "surfaceRect");
648 SetWidth(xcNode, NUMBER_200);
649 SetHeight(xcNode, NUMBER_200);
650 setBackgroundColor(xcNode);
651 focusable(xcNode, true);
652 defaultFocus(xcNode, true);
653 focusOnTouch(xcNode, true);
654
655 auto *nativeXComponent = OH_NativeXComponent_GetNativeXComponent(xcNode);
656
657 OH_NativeXComponent_RegisterKeyEventCallback(nativeXComponent, DispatchKeyEventCB);
658 static OH_NativeXComponent_MouseEvent_Callback mouseCallback = {
659 .DispatchMouseEvent = DispatchMouseEventCB,
660 };
661 OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent, &mouseCallback);
662
663 OH_ArkUI_NodeContent_SetUserData(nodeContentHandle_, xcNode);
664
665 auto nodeContentEvent = [](ArkUI_NodeContentEvent *event) {
666 ArkUI_NodeContentHandle handle = OH_ArkUI_NodeContentEvent_GetNodeContentHandle(event);
667 auto xc = reinterpret_cast<ArkUI_NodeHandle>(OH_ArkUI_NodeContent_GetUserData(handle));
668 if (xc == nullptr) return;
669
670 if (OH_ArkUI_NodeContentEvent_GetEventType(event) == NODE_CONTENT_EVENT_ON_ATTACH_TO_WINDOW) {
671 OH_ArkUI_NodeContent_AddNode(handle, xc);
672 } else {
673 OH_ArkUI_NodeContent_RemoveNode(handle, xc);
674 nodeAPI->disposeNode(xc);
675 OH_ArkUI_NodeContent_SetUserData(handle, nullptr);
676 }
677 };
678 OH_ArkUI_NodeContent_RegisterCallback(nodeContentHandle_, nodeContentEvent);
679
680 return nullptr;
681 }
682
bindNode(napi_env env,napi_callback_info info)683 napi_value bindNode(napi_env env, napi_callback_info info)
684 {
685 size_t argc = 2;
686 napi_value args[2] = {nullptr};
687 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
688 std::string nodeId = value2String(env, args[0]);
689 ArkUI_NodeHandle handle;
690
691 OH_ArkUI_GetNodeHandleFromNapiValue(env, args[1], &handle);
692 OH_ArkUI_SurfaceHolder* holder = OH_ArkUI_SurfaceHolder_Create(handle);
693 nodeHandleMap[nodeId] = handle;
694 surfaceHolderMap[handle] = holder;
695 auto callback = OH_ArkUI_SurfaceCallback_Create();
696 OH_ArkUI_SurfaceCallback_SetSurfaceCreatedEvent(callback, OnSurfaceCreated);
697 OH_ArkUI_SurfaceCallback_SetSurfaceChangedEvent(callback, OnSurfaceChanged);
698 OH_ArkUI_SurfaceCallback_SetSurfaceDestroyedEvent(callback, OnSurfaceDestroyed);
699 OH_ArkUI_SurfaceCallback_SetSurfaceShowEvent(callback, OnSurfaceShow);
700 OH_ArkUI_SurfaceCallback_SetSurfaceHideEvent(callback, OnSurfaceHide);
701 OH_ArkUI_XComponent_RegisterOnFrameCallback(handle, OnFrameCallback);
702 OH_ArkUI_SurfaceHolder_AddSurfaceCallback(holder, callback);
703
704 return nullptr;
705 }
706
unbindNode(napi_env env,napi_callback_info info)707 napi_value unbindNode(napi_env env, napi_callback_info info)
708 {
709 size_t argc = 1;
710 napi_value args[1] = {nullptr};
711 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
712 std::string nodeId = value2String(env, args[0]);
713 auto node = nodeHandleMap[nodeId];
714 nodeAPI->disposeNode(node);
715 nodeHandleMap.erase(nodeId);
716 return nullptr;
717 }
718
setFrameRate(napi_env env,napi_callback_info info)719 napi_value setFrameRate(napi_env env, napi_callback_info info)
720 {
721 size_t argc = 4;
722 napi_value args[4] = {nullptr};
723 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
724 std::string nodeId = value2String(env, args[0]);
725 auto node = nodeHandleMap[nodeId];
726
727 int32_t min = 0;
728 napi_get_value_int32(env, args[1], &min);
729
730 int32_t max = 0;
731 napi_get_value_int32(env, args[2], &max);
732
733 int32_t expected = 0;
734 napi_get_value_int32(env, args[3], &expected);
735 OH_NativeXComponent_ExpectedRateRange range = {
736 .min = min,
737 .max = max,
738 .expected = expected
739 };
740 int32_t status = OH_ArkUI_XComponent_SetExpectedFrameRateRange(node, range);
741 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "wds", "setFrameRate %{public}d", status);
742
743 napi_value statusCode;
744 napi_status ret = napi_create_int32(env, status, &(statusCode));
745
746 return statusCode;
747 }
748
setNeedSoftKeyboard(napi_env env,napi_callback_info info)749 napi_value setNeedSoftKeyboard(napi_env env, napi_callback_info info)
750 {
751 size_t argc = 2;
752 napi_value args[2] = {nullptr};
753 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
754 std::string nodeId = value2String(env, args[0]);
755 auto node = nodeHandleMap[nodeId];
756
757 bool needSoftKeyboard = false;
758 napi_get_value_bool(env, args[1], &needSoftKeyboard);
759 int32_t status = OH_ArkUI_XComponent_SetNeedSoftKeyboard(node, needSoftKeyboard);
760
761 napi_value statusCode;
762 napi_status ret = napi_create_int32(env, status, &(statusCode));
763 return statusCode;
764 }
765
disposeProvider(napi_env env,napi_callback_info info)766 napi_value disposeProvider(napi_env env, napi_callback_info info)
767 {
768 size_t argc = 1;
769 napi_value args[1] = {nullptr};
770 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
771 std::string nodeId = value2String(env, args[0]);
772 if (accessibilityProviderMap.count(nodeId)) {
773 OH_ArkUI_AccessibilityProvider_Dispose(accessibilityProviderMap[nodeId]->getProvider());
774 delete accessibilityProviderMap[nodeId];
775 accessibilityProviderMap.erase(nodeId);
776 }
777 return nullptr;
778 }
779
createProvider(napi_env env,napi_callback_info info)780 napi_value createProvider(napi_env env, napi_callback_info info)
781 {
782 size_t argc = 1;
783 napi_value args[1] = {nullptr};
784 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
785 std::string nodeId = value2String(env, args[0]);
786 auto node = nodeHandleMap[nodeId];
787 accessibilityProviderMap[nodeId] = new AccessibilityManager();
788 accessibilityProviderMap[nodeId]->Initialize(nodeId, node);
789 return nullptr;
790 }
791
registerFrameCallback(napi_env env,napi_callback_info info)792 napi_value registerFrameCallback(napi_env env, napi_callback_info info)
793 {
794 size_t argc = 1;
795 napi_value args[1] = {nullptr};
796 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
797 std::string nodeId = value2String(env, args[0]);
798 auto node = nodeHandleMap[nodeId];
799 int32_t status = OH_ArkUI_XComponent_RegisterOnFrameCallback(node, OnFrameCallback);
800
801 napi_value statusCode;
802 napi_status ret = napi_create_int32(env, status, &(statusCode));
803
804 return statusCode;
805 }
806
unregisterFrameCallback(napi_env env,napi_callback_info info)807 napi_value unregisterFrameCallback(napi_env env, napi_callback_info info)
808 {
809 size_t argc = 1;
810 napi_value args[1] = {nullptr};
811 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
812 std::string nodeId = value2String(env, args[0]);
813 auto node = nodeHandleMap[nodeId];
814 int32_t status = OH_ArkUI_XComponent_UnregisterOnFrameCallback(node);
815
816 napi_value statusCode;
817 napi_status ret = napi_create_int32(env, status, &(statusCode));
818
819 return statusCode;
820 }
821
822 EXTERN_C_START
Init(napi_env env,napi_value exports)823 static napi_value Init(napi_env env, napi_value exports)
824 {
825 napi_property_descriptor desc[] = {
826 {"bindNode", nullptr, bindNode, nullptr, nullptr, nullptr, napi_default, nullptr},
827 {"unbindNode", nullptr, unbindNode, nullptr, nullptr, nullptr, napi_default, nullptr},
828 {"setFrameRate", nullptr, setFrameRate, nullptr, nullptr, nullptr, napi_default, nullptr},
829 {"setNeedSoftKeyboard", nullptr, setNeedSoftKeyboard, nullptr, nullptr, nullptr, napi_default, nullptr},
830 {"disposeProvider", nullptr, disposeProvider, nullptr, nullptr, nullptr, napi_default, nullptr},
831 {"createProvider", nullptr, createProvider, nullptr, nullptr, nullptr, napi_default, nullptr},
832 {"registerFrameCallback", nullptr, registerFrameCallback, nullptr, nullptr, nullptr, napi_default, nullptr},
833 {"unregisterFrameCallback", nullptr, unregisterFrameCallback, nullptr, nullptr, nullptr, napi_default, nullptr},
834
835 {"createNativeNode", nullptr, createNativeNode, nullptr, nullptr, nullptr, napi_default, nullptr },
836 {"getKeyStr", nullptr, GetKeyString, nullptr, nullptr, nullptr, napi_default, nullptr},
837 {"getIndicatorStr", nullptr, GetIndicatorString, nullptr, nullptr, nullptr, napi_default, nullptr},
838 {"getMouseStr", nullptr, GetMouseString, nullptr, nullptr, nullptr, napi_default, nullptr},
839
840 {"createCrossLanguageXComponentNativeNode", nullptr, XComponentCrossLanguageTest::createCrossLanguageXComponentNativeNode,
841 nullptr, nullptr, nullptr, napi_default, nullptr},
842 {"crossLanguageSetXComponentAttribute", nullptr, XComponentCrossLanguageTest::crossLanguageSetXComponentAttribute,
843 nullptr, nullptr, nullptr, napi_default, nullptr},
844 };
845 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
846
847 return exports;
848 }
849 EXTERN_C_END
850
851 static napi_module demoModule = {
852 .nm_version = 1,
853 .nm_flags = 0,
854 .nm_filename = nullptr,
855 .nm_register_func = Init,
856 .nm_modname = "entry",
857 .nm_priv = ((void*)0),
858 .reserved = { 0 },
859 };
860
RegisterEntryModule(void)861 extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
862 {
863 napi_module_register(&demoModule);
864 }
865