1 /*
2 * Copyright (c) 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 <complex>
17 #include <cstdint>
18 #include <hilog/log.h>
19 #include <js_native_api.h>
20 #include <js_native_api_types.h>
21 #include <string>
22 #include "common.h"
23 #include "../common/common.h"
24 #include "../manager/plugin_manager.h"
25 #include "libavutil/pixdesc.h"
26 #include "plugin_render.h"
27 #include "libavformat/avformat.h"
28 #include "libavcodec/avcodec.h"
29 #include "libavutil/timestamp.h"
30
31 extern "C" {
32 // 自定义 avio_read_packet 函数
CustomAvioReadPacket(void * opaque,uint8_t * buf,int bufSize)33 int CustomAvioReadPacket(void *opaque, uint8_t *buf, int bufSize)
34 {
35 FILE *file = ((FILE *)opaque); // 将 void 指针转换为 int 指针,并取得文件描述符
36 if (!file) {
37 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "PluginRender", "CustomAvioReadPacket file is null");
38 return AVERROR_EOF;
39 }
40 OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "PluginRender", "read_packet %{public}d", bufSize);
41 size_t bytesRead = fread(buf, 1, bufSize, file); // 从文件描述符中读取数据
42 if (bytesRead <= 0) {
43 if (feof(file)) {
44 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "PluginRender", "CustomAvioReadPacket file eof %{public}zu",
45 bytesRead);
46 return AVERROR_EOF;
47 } else {
48 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "PluginRender", "CustomAvioReadPacket file eio");
49 return AVERROR_EOF;
50 }
51 }
52
53 if (bufSize > bytesRead) {
54 OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "PluginRender", "read end %{public}zu", bytesRead);
55 return 0;
56 }
57 OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "PluginRender", "read_packet bytes[%{public}zu],bufsize[%{public}d]",
58 bytesRead, bufSize);
59 return static_cast<int>(bytesRead);
60 }
61
open_codec_context(int * streamIdx,AVCodecContext ** decCtx,AVFormatContext * fmtCtx,enum AVMediaType type)62 int open_codec_context(int *streamIdx, AVCodecContext **decCtx, AVFormatContext *fmtCtx,
63 enum AVMediaType type)
64 {
65 int ret = 0;
66 int streamIndex = 0;
67 AVStream *st;
68 const AVCodec *dec = nullptr;
69
70 ret = av_find_best_stream(fmtCtx, type, -1, -1, nullptr, 0);
71 if (ret < 0) {
72 fprintf(stderr, "Could not find %s stream in input file '%s'\n", av_get_media_type_string(type),
73 "srcfile");
74 return ret;
75 } else {
76 streamIndex = ret;
77 st = fmtCtx->streams[streamIndex];
78
79 /* find decoder for the stream */
80 dec = avcodec_find_decoder(st->codecpar->codec_id);
81 if (!dec) {
82 fprintf(stderr, "Failed to find %s codec\n", av_get_media_type_string(type));
83 return AVERROR(EINVAL);
84 }
85
86 /* Allocate a codec context for the decoder */
87 *decCtx = avcodec_alloc_context3(dec);
88 if (!*decCtx) {
89 fprintf(stderr, "Failed to allocate the %s codec context\n", av_get_media_type_string(type));
90 return AVERROR(ENOMEM);
91 }
92
93 /* Copy codec parameters from input stream to output codec context */
94 if ((ret = avcodec_parameters_to_context(*decCtx, st->codecpar)) < 0) {
95 fprintf(stderr, "Failed to copy %s codec parameters to decoder context\n",
96 av_get_media_type_string(type));
97 return ret;
98 }
99
100 /* Init the decoders */
101 if ((ret = avcodec_open2(*decCtx, dec, nullptr)) < 0) {
102 fprintf(stderr, "Failed to open %s codec\n", av_get_media_type_string(type));
103 return ret;
104 }
105 *streamIdx = streamIndex;
106 }
107
108 return 0;
109 }
110
decode_packet(AVCodecContext * dec,AVFrame * frame,const AVPacket * pkt)111 int decode_packet(AVCodecContext *dec, AVFrame *frame, const AVPacket *pkt)
112 {
113 int ret = 0;
114
115 // submit the packet to the decoder
116 ret = avcodec_send_packet(dec, pkt);
117 if (ret < 0) {
118 fprintf(stderr, "Error submitting a packet for decoding (%s)\n", av_err2str(ret));
119 return ret;
120 }
121
122 // get all the available frames from the decoder
123 while (ret >= 0) {
124 ret = avcodec_receive_frame(dec, frame);
125 if (ret < 0) {
126 // those two return values are special and mean there is no output
127 // frame available, but there were no errors during decoding
128 if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) {
129 return 0;
130 }
131
132 fprintf(stderr, "Error during decoding (%s)\n", av_err2str(ret));
133 return ret;
134 }
135
136 // write the frame data to output file
137 if (dec->codec->type == AVMEDIA_TYPE_VIDEO) {
138 OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "PluginRender",
139 "decode video format = [%{public}d]", frame->format,
140 "w[%{public}d]:h[%{public}d] w[%{public}d]:h[%{public}d]\n",
141 frame->width, frame->height, dec->width, dec->height);
142 } else {
143 OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "PluginRender",
144 "decode audio nbs[%{public}d] pts[%{public}s]\n",
145 frame->nb_samples, av_ts2timestr(frame->pts, &dec->time_base));
146 }
147
148 av_frame_unref(frame);
149 if (ret < 0) {
150 return ret;
151 }
152 }
153
154 return 0;
155 }
156 }
157
158 namespace NativeXComponentSample {
159 namespace {
160 constexpr int32_t NUM_9 = 9;
161 constexpr int32_t NUM_8 = 8;
162 constexpr int32_t NUM_7 = 7;
163 constexpr int32_t NUM_6 = 6;
164 constexpr int32_t NUM_5 = 5;
165 constexpr int32_t NUM_4 = 4;
166 constexpr int32_t NUM_3 = 3;
167 constexpr int32_t NUM_2 = 2;
168 constexpr int32_t NUM_1 = 1;
169 constexpr int32_t NUM_1024 = 1024;
170 constexpr int32_t NUM_180 = 180;
171 constexpr int32_t NUM_72 = 72;
172 constexpr int32_t NUM_54 = 54;
173 constexpr int32_t NUM_18 = 18;
OnSurfaceCreatedCB(OH_NativeXComponent * component,void * window)174 void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window)
175 {
176 OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "Callback", "OnSurfaceCreatedCB");
177 if ((component == nullptr) || (window == nullptr)) {
178 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback",
179 "OnSurfaceCreatedCB: component or window is null");
180 return;
181 }
182
183 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
184 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
185 if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
186 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback",
187 "OnSurfaceCreatedCB: Unable to get XComponent id");
188 return;
189 }
190
191 std::string id(idStr);
192 auto render = PluginRender::GetInstance(id);
193 uint64_t width;
194 uint64_t height;
195 int32_t xSize = OH_NativeXComponent_GetXComponentSize(component, window, &width, &height);
196 if ((xSize == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) && (render != nullptr)) {
197 if (render->eglCore_->EglContextInit(window, width, height)) {
198 render->eglCore_->Background();
199 }
200 }
201 }
202
OnSurfaceChangedCB(OH_NativeXComponent * component,void * window)203 void OnSurfaceChangedCB(OH_NativeXComponent* component, void* window)
204 {
205 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceChangedCB");
206 if ((component == nullptr) || (window == nullptr)) {
207 OH_LOG_Print(
208 LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceChangedCB: component or window is null");
209 return;
210 }
211
212 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
213 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
214 if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
215 OH_LOG_Print(
216 LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceChangedCB: Unable to get XComponent id");
217 return;
218 }
219
220 std::string id(idStr);
221 auto render = PluginRender::GetInstance(id);
222 if (render != nullptr) {
223 render->OnSurfaceChanged(component, window);
224 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "surface changed");
225 }
226 }
227
OnSurfaceDestroyedCB(OH_NativeXComponent * component,void * window)228 void OnSurfaceDestroyedCB(OH_NativeXComponent* component, void* window)
229 {
230 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceDestroyedCB");
231 if ((component == nullptr) || (window == nullptr)) {
232 OH_LOG_Print(
233 LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceDestroyedCB: component or window is null");
234 return;
235 }
236
237 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
238 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
239 if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
240 OH_LOG_Print(
241 LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceDestroyedCB: Unable to get XComponent id");
242 return;
243 }
244
245 std::string id(idStr);
246 PluginRender::Release(id);
247 }
248
DispatchTouchEventCB(OH_NativeXComponent * component,void * window)249 void DispatchTouchEventCB(OH_NativeXComponent* component, void* window)
250 {
251 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "DispatchTouchEventCB");
252 if ((component == nullptr) || (window == nullptr)) {
253 OH_LOG_Print(
254 LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "DispatchTouchEventCB: component or window is null");
255 return;
256 }
257
258 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
259 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
260 if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
261 OH_LOG_Print(
262 LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "DispatchTouchEventCB: Unable to get XComponent id");
263 return;
264 }
265
266 std::string id(idStr);
267 PluginRender* render = PluginRender::GetInstance(id);
268 if (render != nullptr) {
269 render->OnTouchEvent(component, window);
270 }
271 }
272
DispatchMouseEventCB(OH_NativeXComponent * component,void * window)273 void DispatchMouseEventCB(OH_NativeXComponent* component, void* window)
274 {
275 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "DispatchMouseEventCB");
276 int32_t ret;
277 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
278 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
279 ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
280 if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
281 return;
282 }
283
284 std::string id(idStr);
285 auto render = PluginRender::GetInstance(id);
286 if (render != nullptr) {
287 render->OnMouseEvent(component, window);
288 }
289 }
290
DispatchHoverEventCB(OH_NativeXComponent * component,bool isHover)291 void DispatchHoverEventCB(OH_NativeXComponent* component, bool isHover)
292 {
293 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "DispatchHoverEventCB");
294 int32_t ret;
295 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
296 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
297 ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
298 if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
299 return;
300 }
301
302 std::string id(idStr);
303 auto render = PluginRender::GetInstance(id);
304 if (render != nullptr) {
305 render->OnHoverEvent(component, isHover);
306 }
307 }
308
OnFocusEventCB(OH_NativeXComponent * component,void * window)309 void OnFocusEventCB(OH_NativeXComponent* component, void* window)
310 {
311 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnFocusEventCB");
312 int32_t ret;
313 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
314 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
315 ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
316 if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
317 return;
318 }
319
320 std::string id(idStr);
321 auto render = PluginRender::GetInstance(id);
322 if (render != nullptr) {
323 render->OnFocusEvent(component, window);
324 }
325 }
326
OnBlurEventCB(OH_NativeXComponent * component,void * window)327 void OnBlurEventCB(OH_NativeXComponent* component, void* window)
328 {
329 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnBlurEventCB");
330 int32_t ret;
331 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
332 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
333 ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
334 if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
335 return;
336 }
337
338 std::string id(idStr);
339 auto render = PluginRender::GetInstance(id);
340 if (render != nullptr) {
341 render->OnBlurEvent(component, window);
342 }
343 }
344
OnKeyEventCB(OH_NativeXComponent * component,void * window)345 void OnKeyEventCB(OH_NativeXComponent* component, void* window)
346 {
347 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnKeyEventCB");
348 int32_t ret;
349 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
350 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
351 ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
352 if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
353 return;
354 }
355 std::string id(idStr);
356 auto render = PluginRender::GetInstance(id);
357 if (render != nullptr) {
358 render->OnKeyEvent(component, window);
359 }
360 }
361 } // namespace
362
363 std::unordered_map<std::string, PluginRender*> PluginRender::instance_;
364 int32_t PluginRender::hasDraw_ = 0;
365 int32_t PluginRender::hasChangeColor_ = 0;
366
PluginRender(std::string & id)367 PluginRender::PluginRender(std::string& id)
368 {
369 this->id_ = id;
370 this->eglCore_ = new EGLCore();
371 }
372
GetInstance(std::string & id)373 PluginRender* PluginRender::GetInstance(std::string& id)
374 {
375 if (instance_.find(id) == instance_.end()) {
376 PluginRender* instance = new PluginRender(id);
377 instance_[id] = instance;
378 return instance;
379 } else {
380 return instance_[id];
381 }
382 }
383
Export(napi_env env,napi_value exports)384 void PluginRender::Export(napi_env env, napi_value exports)
385 {
386 if ((env == nullptr) || (exports == nullptr)) {
387 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "Export: env or exports is null");
388 return;
389 }
390
391 napi_property_descriptor desc[] = {
392 {"drawPattern", nullptr, PluginRender::NapiDrawPattern, nullptr, nullptr, nullptr, napi_default, nullptr},
393 {"getStatus", nullptr, PluginRender::TestGetXComponentStatus, nullptr, nullptr, nullptr, napi_default, nullptr},
394 {"play", nullptr, PluginRender::NapiPlay, nullptr, nullptr, nullptr, napi_default, nullptr},
395 {"stop", nullptr, PluginRender::NapiStop, nullptr, nullptr, nullptr, napi_default, nullptr},
396 {"getInfo", nullptr, PluginRender::NapiGetInfo, nullptr, nullptr, nullptr, napi_default, nullptr},
397 };
398 if (napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc) != napi_ok) {
399 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "Export: napi_define_properties failed");
400 }
401 }
402
403 // NAPI registration method type napi_callback. If no value is returned, nullptr is returned.
NapiPlay(napi_env env,napi_callback_info info)404 napi_value PluginRender::NapiPlay(napi_env env, napi_callback_info info)
405 {
406 size_t argc = NUM_3;
407 napi_value args[NUM_3];
408 uint32_t fd = 0;
409 uint32_t foff = 0;
410 uint32_t flen = 0;
411
412 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern");
413 if ((env == nullptr) || (info == nullptr)) {
414 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: env or info is null");
415 return nullptr;
416 }
417
418 napi_value thisArg;
419 if (napi_get_cb_info(env, info, &argc, args, &thisArg, nullptr) != napi_ok) {
420 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: napi_get_cb_info fail");
421 return nullptr;
422 }
423
424 napi_get_value_uint32(env, args[0], &fd);
425 napi_get_value_uint32(env, args[1], &foff);
426 napi_get_value_uint32(env, args[NUM_2], &flen);
427 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender",
428 "fd:%{public}d, foff:%{public}d, flen:%{public}d!", fd, foff, flen);
429
430 napi_value exportInstance;
431 if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
432 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender",
433 "NapiDrawPattern: napi_get_named_property fail");
434 return nullptr;
435 }
436
437 OH_NativeXComponent *nativeXComponent = nullptr;
438 if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
439 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: napi_unwrap fail");
440 return nullptr;
441 }
442
443 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
444 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
445 if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
446 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender",
447 "NapiDrawPattern: Unable to get XComponent id");
448 return nullptr;
449 }
450
451 std::string id(idStr);
452 PluginRender *render = PluginRender::GetInstance(id);
453 if (render != nullptr) {
454 render->eglCore_->fd_ = fd;
455 render->eglCore_->foff_ = foff;
456 render->eglCore_->flen_ = flen;
457 render->eglCore_->DrawBmp(fd, foff, flen, hasDraw_);
458 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "render->eglCore_->Draw() executed");
459 }
460 return nullptr;
461 }
462
463 // NAPI registration method type napi_callback. If no value is returned, nullptr is returned.
NapiStop(napi_env env,napi_callback_info info)464 napi_value PluginRender::NapiStop(napi_env env, napi_callback_info info)
465 {
466 size_t argc = NUM_3;
467 napi_value args[NUM_3];
468 uint32_t fd = 0;
469 uint32_t foff = 0;
470 uint32_t flen = 0;
471
472 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern");
473 if ((env == nullptr) || (info == nullptr)) {
474 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: env or info is null");
475 return nullptr;
476 }
477
478 napi_value thisArg;
479 if (napi_get_cb_info(env, info, &argc, args, &thisArg, nullptr) != napi_ok) {
480 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: napi_get_cb_info fail");
481 return nullptr;
482 }
483
484 napi_get_value_uint32(env, args[0], &fd);
485 napi_get_value_uint32(env, args[1], &foff);
486 napi_get_value_uint32(env, args[NUM_2], &flen);
487 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender",
488 "fd:%{public}d, foff:%{public}d, flen:%{public}d!", fd, foff, flen);
489
490 napi_value exportInstance;
491 if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
492 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender",
493 "NapiDrawPattern: napi_get_named_property fail");
494 return nullptr;
495 }
496
497 OH_NativeXComponent *nativeXComponent = nullptr;
498 if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
499 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: napi_unwrap fail");
500 return nullptr;
501 }
502
503 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
504 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
505 if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
506 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender",
507 "NapiDrawPattern: Unable to get XComponent id");
508 return nullptr;
509 }
510
511 std::string id(idStr);
512 PluginRender *render = PluginRender::GetInstance(id);
513 if (render != nullptr) {
514 render->eglCore_->fd_ = fd;
515 render->eglCore_->foff_ = foff;
516 render->eglCore_->flen_ = flen;
517 render->eglCore_->DrawBmp(fd, foff, flen, hasDraw_);
518 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "render->eglCore_->Draw() executed");
519 }
520 return nullptr;
521 }
522
523 struct RescontCallbackData {
524 napi_async_work asyncWork = nullptr;
525 napi_deferred deferred = nullptr;
526 napi_ref callback = nullptr;
527 unsigned char *buffer = nullptr;
528 uint32_t fd = 0;
529 uint32_t foff = 0;
530 uint32_t flen = 0;
531 uint32_t blen = 0;
532 napi_value result = nullptr;
533 };
534
RescontExecuteCB(napi_env env,void * data)535 static void RescontExecuteCB(napi_env env, void *data)
536 {
537 RescontCallbackData *callbackData = reinterpret_cast<RescontCallbackData *>(data);
538 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender",
539 "RescontExecuteCB blen:%{public}d", callbackData->fd);
540
541 int ret = 0;
542 uint32_t fbufLen = 8192;
543 unsigned char *fbuf = static_cast<unsigned char *>(av_malloc(fbufLen));
544 char dumpBuf[256];
545
546 uint32_t fd = callbackData->fd;
547 uint32_t foff = callbackData->foff;
548 uint32_t flen = callbackData->flen;
549
550 AVFormatContext *formatContext = nullptr;
551 AVIOContext *avioContext = nullptr;
552 AVCodecContext *videoDecCtx = nullptr;
553 AVCodecContext *audioDecCtx = nullptr;
554 AVFrame *frame = nullptr;
555 AVPacket *pkt = nullptr;
556 int videoFrameCount = 0;
557 int audioFrameCount = 0;
558
559 int videoStreamIdx = -1;
560 int audioStreamIdx = -1;
561
562 FILE *file = fdopen(fd, "r");
563 if (file == nullptr) {
564 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "NapiGetInfo fdopen failed!");
565 free(fbuf);
566 return;
567 }
568 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "fdopen ");
569 // 取文件
570 if (fseek(file, foff, SEEK_SET) != 0) {
571 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiGetInfo fseek failed!");
572 fclose(file);
573 free(fbuf);
574 return;
575 }
576 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "fseek %{public}ld", foff);
577 avioContext = avio_alloc_context(fbuf, fbufLen, 0, (void *)file, &CustomAvioReadPacket, nullptr, nullptr);
578 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "avio_alloc_context");
579 if (!avioContext) {
580 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "avio_alloc_context failed");
581 av_free(avioContext->buffer);
582 avio_context_free(&avioContext);
583 fclose(file);
584 return;
585 }
586
587 formatContext = avformat_alloc_context();
588 if (!formatContext) {
589 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "avformat_alloc_context failed");
590 av_free(avioContext->buffer);
591 avio_context_free(&avioContext);
592 fclose(file);
593 return;
594 }
595 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "avformat_alloc_context");
596 formatContext->pb = avioContext;
597 ret = avformat_open_input(&formatContext, nullptr, nullptr, nullptr);
598 if (ret < 0) {
599 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "avformat_open_input err %{public}d", ret);
600 avformat_free_context(formatContext);
601 av_free(avioContext->buffer);
602 avio_context_free(&avioContext);
603 fclose(file);
604 return;
605 }
606 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "avformat_open_input");
607 // 获取流信息
608 ret = avformat_find_stream_info(formatContext, nullptr);
609 if (ret < 0) {
610 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "avformat_find_stream_info err %{public}d",
611 ret);
612 avformat_close_input(&formatContext);
613 fclose(file);
614 return;
615 }
616
617 napi_value videoRes;
618 napi_value audioRes;
619 if (open_codec_context(&videoStreamIdx, &videoDecCtx, formatContext, AVMEDIA_TYPE_VIDEO) >= 0) {
620 avcodec_string(dumpBuf, sizeof(dumpBuf), videoDecCtx, 0);
621 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "video[%{public}s]", dumpBuf);
622 napi_create_string_utf8(env, dumpBuf, strlen(dumpBuf), &videoRes);
623 }
624 if (open_codec_context(&audioStreamIdx, &audioDecCtx, formatContext, AVMEDIA_TYPE_AUDIO) >= 0) {
625 avcodec_string(dumpBuf, sizeof(dumpBuf), audioDecCtx, 0);
626 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "audio[%{public}s]", dumpBuf);
627 napi_create_string_utf8(env, dumpBuf, strlen(dumpBuf), &audioRes);
628 }
629
630 int64_t hours = 0;
631 int64_t mins = 0;
632 int64_t secs = 0;
633 int64_t us = 0;
634 int64_t duration = formatContext->duration + (formatContext->duration <= INT64_MAX - 5000 ? 5000 : 0);
635 secs = duration / AV_TIME_BASE;
636 us = duration % AV_TIME_BASE;
637 mins = secs / PARAM60;
638 secs %= PARAM60;
639 hours = mins / PARAM60;
640 mins %= PARAM60;
641 int ssecs = 0;
642 int sus = 0;
643 av_log(nullptr, AV_LOG_INFO, ", start: ");
644 ssecs = llabs(formatContext->start_time / AV_TIME_BASE);
645 sus = llabs(formatContext->start_time % AV_TIME_BASE);
646
647 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender",
648 "duration[%{public}02d:%{public}02d:%{public}02d.%{public}2d],"
649 " start[%{public}d:%{public}06d], bitrate[%{public}d]",
650 hours, mins, secs, (PARAM100 * us) / AV_TIME_BASE,
651 ssecs, (int) av_rescale(sus, PARAM100W, AV_TIME_BASE), formatContext->bit_rate / PARAM1000);
652
653 frame = av_frame_alloc();
654 if (!frame) {
655 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "Could not allocate frame\n");
656 ret = AVERROR(ENOMEM);
657 goto end;
658 }
659
660 pkt = av_packet_alloc();
661 if (!pkt) {
662 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "Could not allocate packet\n");
663 ret = AVERROR(ENOMEM);
664 goto end;
665 }
666
667 /* read frames from the file */
668 while (av_read_frame(formatContext, pkt) >= 0) {
669 // check if the packet belongs to a stream we are interested in, otherwise
670 // skip it
671 if (pkt->stream_index == videoStreamIdx) {
672 ret = decode_packet(videoDecCtx, frame, pkt);
673 if (0 && ret == 0) {
674 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "decode video "
675 "w[%{public}d]:h[%{public}d] pict_type[%{public}d]]]\n", frame->width, frame->height, frame->pict_type);
676 }
677 } else if (pkt->stream_index == audioStreamIdx) {
678 ret = decode_packet(audioDecCtx, frame, pkt);
679 if (0 && ret == 0) {
680 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender",
681 "decode audio "
682 "nbs[%{public}d]:pts[%{public}d] duration[%{public}d]]]\n",
683 frame->nb_samples, av_ts2timestr(frame->pts, &audioDecCtx->time_base), frame->duration);
684 }
685 }
686
687 av_packet_unref(pkt);
688 if (ret < 0) {
689 break;
690 }
691 }
692 end:
693 napi_value instance;
694 napi_create_object(env, &instance);
695 napi_set_named_property(env, instance, "videoDec", videoRes);
696 napi_set_named_property(env, instance, "audioDec", audioRes);
697 callbackData->result = instance;
698
699 avcodec_free_context(&videoDecCtx);
700 avcodec_free_context(&audioDecCtx);
701 avformat_close_input(&formatContext);
702 av_packet_free(&pkt);
703 av_frame_free(&frame);
704 }
705
RescontCompleteCB(napi_env env,napi_status status,void * data)706 static void RescontCompleteCB(napi_env env, napi_status status, void *data)
707 {
708 RescontCallbackData *callbackData = reinterpret_cast<RescontCallbackData *>(data);
709 napi_value result = callbackData->result;
710 if (callbackData->result != nullptr) {
711 napi_resolve_deferred(env, callbackData->deferred, result);
712 } else {
713 napi_reject_deferred(env, callbackData->deferred, result);
714 }
715
716 napi_delete_async_work(env, callbackData->asyncWork);
717 delete callbackData;
718 }
719
720 // NAPI registration method type napi_callback. If no value is returned, nullptr is returned.
NapiGetInfo(napi_env env,napi_callback_info info)721 napi_value PluginRender::NapiGetInfo(napi_env env, napi_callback_info info)
722 {
723 size_t argc = NUM_3;
724 napi_value args[NUM_3];
725 uint32_t fd = 0;
726 uint32_t foff = 0;
727 uint32_t flen = 0;
728
729 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "NapiGetInfo");
730 if ((env == nullptr) || (info == nullptr)) {
731 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiGetInfo: env or info is null");
732 return nullptr;
733 }
734
735 napi_value thisArg;
736 if (napi_get_cb_info(env, info, &argc, args, &thisArg, nullptr) != napi_ok) {
737 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiGetInfo: napi_get_cb_info fail");
738 return nullptr;
739 }
740
741 napi_get_value_uint32(env, args[0], &fd);
742 napi_get_value_uint32(env, args[1], &foff);
743 napi_get_value_uint32(env, args[NUM_2], &flen);
744 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender",
745 "fd:%{public}d, foff:%{public}d, flen:%{public}d!", fd, foff, flen);
746
747 napi_value exportInstance;
748 if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
749 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender",
750 "NapiGetInfo: napi_get_named_property fail");
751 return nullptr;
752 }
753
754 OH_NativeXComponent *nativeXComponent = nullptr;
755 if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
756 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiGetInfo: napi_unwrap fail");
757 return nullptr;
758 }
759
760 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
761 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
762 if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
763 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender",
764 "NapiGetInfo: Unable to get XComponent id");
765 return nullptr;
766 }
767
768 std::string id(idStr);
769 PluginRender *render = PluginRender::GetInstance(id);
770 if (render != nullptr) {
771 render->eglCore_->fd_ = fd;
772 render->eglCore_->foff_ = foff;
773 render->eglCore_->flen_ = flen;
774
775 napi_value promise = nullptr;
776 napi_deferred deferred = nullptr;
777 napi_create_promise(env, &deferred, &promise);
778
779 auto callbackData = new RescontCallbackData();
780 callbackData->deferred = deferred;
781
782 void *arrayData = nullptr;
783 size_t length = 0;
784 napi_valuetype result = napi_undefined;
785 napi_typeof(env, args[0], &result);
786 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "napi_valuetype :%{public}d", result);
787 napi_typedarray_type type = napi_int8_array;
788
789 napi_value arraybuffer = nullptr;
790 size_t byteOffset = 0;
791 napi_get_typedarray_info(env, args[0], &type, &length, &arrayData, &arraybuffer, &byteOffset);
792
793 callbackData->buffer = (unsigned char *)arrayData;
794 callbackData->fd = fd;
795 callbackData->foff = foff;
796 callbackData->flen = flen;
797 callbackData->blen = length;
798 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender",
799 "AsyncRescont buffer:%{public}p", callbackData->buffer);
800 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender",
801 "AsyncRescont blen:%{public}d", callbackData->blen);
802
803 napi_value resourceName = nullptr;
804 napi_create_string_utf8(env, "RescontAsyncCallback", NAPI_AUTO_LENGTH, &resourceName);
805 // 创建异步任务
806 napi_create_async_work(env, nullptr, resourceName, RescontExecuteCB, RescontCompleteCB, callbackData,
807 &callbackData->asyncWork);
808 // 将异步任务加入队列
809 napi_queue_async_work(env, callbackData->asyncWork);
810
811 return promise;
812 }
813 return nullptr;
814 }
815
816 // NAPI registration method type napi_callback. If no value is returned, nullptr is returned.
NapiDrawPattern(napi_env env,napi_callback_info info)817 napi_value PluginRender::NapiDrawPattern(napi_env env, napi_callback_info info)
818 {
819 size_t argc = NUM_3;
820 napi_value args[NUM_3];
821 uint32_t fd = 0;
822 uint32_t foff = 0;
823 uint32_t flen = 0;
824
825 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern");
826 if ((env == nullptr) || (info == nullptr)) {
827 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: env or info is null");
828 return nullptr;
829 }
830
831 napi_value thisArg;
832 if (napi_get_cb_info(env, info, &argc, args, &thisArg, nullptr) != napi_ok) {
833 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: napi_get_cb_info fail");
834 return nullptr;
835 }
836
837 napi_get_value_uint32(env, args[0], &fd);
838 napi_get_value_uint32(env, args[1], &foff);
839 napi_get_value_uint32(env, args[NUM_2], &flen);
840 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN,
841 "PluginRender", "fd:%{public}d, foff:%{public}d, flen:%{public}d!", fd, foff, flen);
842
843 napi_value exportInstance;
844 if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
845 OH_LOG_Print(
846 LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender",
847 "NapiDrawPattern: napi_get_named_property fail");
848 return nullptr;
849 }
850
851 OH_NativeXComponent* nativeXComponent = nullptr;
852 if (napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent)) != napi_ok) {
853 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: napi_unwrap fail");
854 return nullptr;
855 }
856
857 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
858 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
859 if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
860 OH_LOG_Print(
861 LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "NapiDrawPattern: Unable to get XComponent id");
862 return nullptr;
863 }
864
865 std::string id(idStr);
866 PluginRender* render = PluginRender::GetInstance(id);
867 if (render != nullptr) {
868 render->eglCore_->fd_ = fd;
869 render->eglCore_->foff_ = foff;
870 render->eglCore_->flen_ = flen;
871 render->eglCore_->DrawBmp(fd, foff, flen, hasDraw_);
872 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "render->eglCore_->Draw() executed");
873 }
874 return nullptr;
875 }
876
Release(std::string & id)877 void PluginRender::Release(std::string& id)
878 {
879 PluginRender* render = PluginRender::GetInstance(id);
880 if (render != nullptr) {
881 render->eglCore_->Release();
882 delete render->eglCore_;
883 render->eglCore_ = nullptr;
884 delete render;
885 render = nullptr;
886 instance_.erase(instance_.find(id));
887 }
888 }
889
OnSurfaceChanged(OH_NativeXComponent * component,void * window)890 void PluginRender::OnSurfaceChanged(OH_NativeXComponent* component, void* window)
891 {
892 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
893 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
894 if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
895 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceChanged: Unable to get XComponent id");
896 return;
897 }
898
899 std::string id(idStr);
900 PluginRender* render = PluginRender::GetInstance(id);
901 double offsetX;
902 double offsetY;
903 OH_NativeXComponent_GetXComponentOffset(component, window, &offsetX, &offsetY);
904 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "OH_NativeXComponent_GetXComponentOffset",
905 "offsetX = %{public}lf, offsetY = %{public}lf", offsetX, offsetY);
906 uint64_t width;
907 uint64_t height;
908 OH_NativeXComponent_GetXComponentSize(component, window, &width, &height);
909 if (render != nullptr) {
910 render->eglCore_->UpdateSize(width, height);
911 }
912 }
913
OnTouchEvent(OH_NativeXComponent * component,void * window)914 void PluginRender::OnTouchEvent(OH_NativeXComponent* component, void* window)
915 {
916 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
917 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
918 if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
919 OH_LOG_Print(
920 LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "DispatchTouchEventCB: Unable to get XComponent id");
921 return;
922 }
923 OH_NativeXComponent_TouchEvent touchEvent;
924 OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent);
925 std::string id(idStr);
926 PluginRender* render = PluginRender::GetInstance(id);
927 if (render != nullptr && touchEvent.type == OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UP) {
928 render->eglCore_->ChangeColor(hasChangeColor_);
929 }
930 float tiltX = 0.0f;
931 float tiltY = 0.0f;
932 OH_NativeXComponent_TouchPointToolType toolType =
933 OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_UNKNOWN;
934 OH_NativeXComponent_GetTouchPointToolType(component, 0, &toolType);
935 OH_NativeXComponent_GetTouchPointTiltX(component, 0, &tiltX);
936 OH_NativeXComponent_GetTouchPointTiltY(component, 0, &tiltY);
937 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "OnTouchEvent",
938 "touch info: toolType = %{public}d, tiltX = %{public}lf, tiltY = %{public}lf", toolType, tiltX, tiltY);
939 }
940
RegisterCallback(OH_NativeXComponent * nativeXComponent)941 void PluginRender::RegisterCallback(OH_NativeXComponent* nativeXComponent)
942 {
943 renderCallback_.OnSurfaceCreated = OnSurfaceCreatedCB;
944 renderCallback_.OnSurfaceChanged = OnSurfaceChangedCB;
945 renderCallback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
946 renderCallback_.DispatchTouchEvent = DispatchTouchEventCB;
947 OH_NativeXComponent_RegisterCallback(nativeXComponent, &renderCallback_);
948
949 mouseCallback_.DispatchMouseEvent = DispatchMouseEventCB;
950 mouseCallback_.DispatchHoverEvent = DispatchHoverEventCB;
951 OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent, &mouseCallback_);
952
953 OH_NativeXComponent_RegisterFocusEventCallback(nativeXComponent, OnFocusEventCB);
954 OH_NativeXComponent_RegisterKeyEventCallback(nativeXComponent, OnKeyEventCB);
955 OH_NativeXComponent_RegisterBlurEventCallback(nativeXComponent, OnBlurEventCB);
956 }
957
OnMouseEvent(OH_NativeXComponent * component,void * window)958 void PluginRender::OnMouseEvent(OH_NativeXComponent* component, void* window)
959 {
960 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnMouseEvent");
961 OH_NativeXComponent_MouseEvent mouseEvent;
962 int32_t ret = OH_NativeXComponent_GetMouseEvent(component, window, &mouseEvent);
963 if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
964 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender",
965 "MouseEvent Info: x = %{public}f, y = %{public}f, action = %{public}d, button = %{public}d", mouseEvent.x,
966 mouseEvent.y, mouseEvent.action, mouseEvent.button);
967 } else {
968 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "GetMouseEvent error");
969 }
970 }
971
OnHoverEvent(OH_NativeXComponent * component,bool isHover)972 void PluginRender::OnHoverEvent(OH_NativeXComponent* component, bool isHover)
973 {
974 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnHoverEvent isHover_ = %{public}d", isHover);
975 }
976
OnFocusEvent(OH_NativeXComponent * component,void * window)977 void PluginRender::OnFocusEvent(OH_NativeXComponent* component, void* window)
978 {
979 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnFocusEvent");
980 }
981
OnBlurEvent(OH_NativeXComponent * component,void * window)982 void PluginRender::OnBlurEvent(OH_NativeXComponent* component, void* window)
983 {
984 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnBlurEvent");
985 }
986
OnKeyEvent(OH_NativeXComponent * component,void * window)987 void PluginRender::OnKeyEvent(OH_NativeXComponent* component, void* window)
988 {
989 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender", "OnKeyEvent");
990
991 OH_NativeXComponent_KeyEvent* keyEvent = nullptr;
992 if (OH_NativeXComponent_GetKeyEvent(component, &keyEvent) >= 0) {
993 OH_NativeXComponent_KeyAction action;
994 OH_NativeXComponent_GetKeyEventAction(keyEvent, &action);
995 OH_NativeXComponent_KeyCode code;
996 OH_NativeXComponent_GetKeyEventCode(keyEvent, &code);
997 OH_NativeXComponent_EventSourceType sourceType;
998 OH_NativeXComponent_GetKeyEventSourceType(keyEvent, &sourceType);
999 int64_t deviceId;
1000 OH_NativeXComponent_GetKeyEventDeviceId(keyEvent, &deviceId);
1001 int64_t timeStamp;
1002 OH_NativeXComponent_GetKeyEventTimestamp(keyEvent, &timeStamp);
1003 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "PluginRender",
1004 "KeyEvent Info: action=%{public}d, code=%{public}d, sourceType=%{public}d, deviceId=%{public}ld, "
1005 "timeStamp=%{public}ld",
1006 action, code, sourceType, deviceId, timeStamp);
1007 } else {
1008 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginRender", "GetKeyEvent error");
1009 }
1010 }
1011
TestGetXComponentStatus(napi_env env,napi_callback_info info)1012 napi_value PluginRender::TestGetXComponentStatus(napi_env env, napi_callback_info info)
1013 {
1014 napi_value hasDraw;
1015 napi_value hasChangeColor;
1016
1017 napi_status ret = napi_create_int32(env, hasDraw_, &(hasDraw));
1018 if (ret != napi_ok) {
1019 OH_LOG_Print(
1020 LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus", "napi_create_int32 hasDraw_ error");
1021 return nullptr;
1022 }
1023 ret = napi_create_int32(env, hasChangeColor_, &(hasChangeColor));
1024 if (ret != napi_ok) {
1025 OH_LOG_Print(
1026 LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus", "napi_create_int32 hasChangeColor_ error");
1027 return nullptr;
1028 }
1029
1030 napi_value obj;
1031 ret = napi_create_object(env, &obj);
1032 if (ret != napi_ok) {
1033 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus", "napi_create_object error");
1034 return nullptr;
1035 }
1036 ret = napi_set_named_property(env, obj, "hasDraw", hasDraw);
1037 if (ret != napi_ok) {
1038 OH_LOG_Print(
1039 LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus", "napi_set_named_property hasDraw error");
1040 return nullptr;
1041 }
1042 ret = napi_set_named_property(env, obj, "hasChangeColor", hasChangeColor);
1043 if (ret != napi_ok) {
1044 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "TestGetXComponentStatus",
1045 "napi_set_named_property hasChangeColor error");
1046 return nullptr;
1047 }
1048 return obj;
1049 }
1050 } // namespace NativeXComponentSample
1051