• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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