1 /*
2  * Copyright (C) 2022 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 <map>
17 #include <iostream>
18 #include <sstream>
19 #include <iomanip>
20 #include <uv.h>
21 #include "avplayer_napi.h"
22 #include "media_errors.h"
23 #include "media_log.h"
24 #include "player.h"
25 #include "scope_guard.h"
26 #include "event_queue.h"
27 #include "avplayer_callback.h"
28 
29 namespace {
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_PLAYER, "AVPlayerCallback" };
31 }
32 
33 namespace OHOS {
34 namespace Media {
35 class NapiCallback {
36 public:
37     struct Base {
38         std::weak_ptr<AutoRef> callback;
39         std::string callbackName = "unknown";
40         Base() = default;
41         virtual ~Base() = default;
UvWorkOHOS::Media::NapiCallback::Base42         virtual void UvWork()
43         {
44             std::shared_ptr<AutoRef> ref = callback.lock();
45             CHECK_AND_RETURN_LOG(ref != nullptr,
46                 "%{public}s AutoRef is nullptr", callbackName.c_str());
47 
48             napi_handle_scope scope = nullptr;
49             napi_open_handle_scope(ref->env_, &scope);
50             CHECK_AND_RETURN_LOG(scope != nullptr,
51                 "%{public}s scope is nullptr", callbackName.c_str());
52             ON_SCOPE_EXIT(0) {
53                 napi_close_handle_scope(ref->env_, scope);
54             };
55 
56             napi_value jsCallback = nullptr;
57             napi_status status = napi_get_reference_value(ref->env_, ref->cb_, &jsCallback);
58             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
59                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
60 
61             // Call back function
62             napi_value result = nullptr;
63             status = napi_call_function(ref->env_, nullptr, jsCallback, 0, nullptr, &result);
64             CHECK_AND_RETURN_LOG(status == napi_ok,
65                 "%{public}s failed to napi_call_function", callbackName.c_str());
66         }
JsCallbackOHOS::Media::NapiCallback::Base67         virtual void JsCallback()
68         {
69             UvWork();
70             delete this;
71         }
72     };
73 
74     struct Error : public Base {
75         std::string errorMsg = "unknown";
76         MediaServiceExtErrCodeAPI9 errorCode = MSERR_EXT_API9_UNSUPPORT_FORMAT;
UvWorkOHOS::Media::NapiCallback::Error77         void UvWork() override
78         {
79             std::shared_ptr<AutoRef> errorRef = callback.lock();
80             CHECK_AND_RETURN_LOG(errorRef != nullptr,
81                 "%{public}s AutoRef is nullptr", callbackName.c_str());
82 
83             napi_handle_scope scope = nullptr;
84             napi_open_handle_scope(errorRef->env_, &scope);
85             CHECK_AND_RETURN_LOG(scope != nullptr,
86                 "%{public}s scope is nullptr", callbackName.c_str());
87             ON_SCOPE_EXIT(0) {
88                 napi_close_handle_scope(errorRef->env_, scope);
89             };
90 
91             napi_value jsCallback = nullptr;
92             napi_status napiStatus = napi_get_reference_value(errorRef->env_, errorRef->cb_, &jsCallback);
93             CHECK_AND_RETURN_LOG(napiStatus == napi_ok && jsCallback != nullptr,
94                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
95 
96             napi_value args[1] = {nullptr};
97             (void)CommonNapi::CreateError(errorRef->env_, errorCode, errorMsg, args[0]);
98 
99             // Call back function
100             napi_value result = nullptr;
101             napiStatus = napi_call_function(errorRef->env_, nullptr, jsCallback, 1, args, &result);
102             CHECK_AND_RETURN_LOG(napiStatus == napi_ok,
103                 "%{public}s failed to napi_call_function", callbackName.c_str());
104         }
105     };
106 
107     struct Int : public Base {
108         int32_t value = 0;
UvWorkOHOS::Media::NapiCallback::Int109         void UvWork() override
110         {
111             std::shared_ptr<AutoRef> intRef = callback.lock();
112             CHECK_AND_RETURN_LOG(intRef != nullptr,
113                 "%{public}s AutoRef is nullptr", callbackName.c_str());
114 
115             napi_handle_scope scope = nullptr;
116             napi_open_handle_scope(intRef->env_, &scope);
117             CHECK_AND_RETURN_LOG(scope != nullptr,
118                 "%{public}s scope is nullptr", callbackName.c_str());
119             ON_SCOPE_EXIT(0) {
120                 napi_close_handle_scope(intRef->env_, scope);
121             };
122 
123             napi_value jsCallback = nullptr;
124             napi_status status = napi_get_reference_value(intRef->env_, intRef->cb_, &jsCallback);
125             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
126                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
127 
128             napi_value args[1] = {nullptr}; // callback: (int)
129             (void)napi_create_int32(intRef->env_, value, &args[0]);
130 
131             napi_value result = nullptr;
132             status = napi_call_function(intRef->env_, nullptr, jsCallback, 1, args, &result);
133             CHECK_AND_RETURN_LOG(status == napi_ok,
134                 "%{public}s failed to napi_call_function", callbackName.c_str());
135         }
136     };
137 
138     struct IntVec : public Base {
139         std::vector<int32_t> valueVec;
UvWorkOHOS::Media::NapiCallback::IntVec140         void UvWork() override
141         {
142             std::shared_ptr<AutoRef> intVecRef = callback.lock();
143             CHECK_AND_RETURN_LOG(intVecRef != nullptr,
144                 "%{public}s AutoRef is nullptr", callbackName.c_str());
145 
146             napi_handle_scope scope = nullptr;
147             napi_open_handle_scope(intVecRef->env_, &scope);
148             CHECK_AND_RETURN_LOG(scope != nullptr,
149                 "%{public}s scope is nullptr", callbackName.c_str());
150             ON_SCOPE_EXIT(0) {
151                 napi_close_handle_scope(intVecRef->env_, scope);
152             };
153 
154             napi_value jsCallback = nullptr;
155             napi_status status = napi_get_reference_value(intVecRef->env_, intVecRef->cb_, &jsCallback);
156             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
157                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
158 
159             napi_value args[2] = {nullptr}; // callback: (int, int)
160             (void)napi_create_int32(intVecRef->env_, valueVec[0], &args[0]);
161             (void)napi_create_int32(intVecRef->env_, valueVec[1], &args[1]);
162 
163             const int32_t argCount = static_cast<int32_t>(valueVec.size());
164             napi_value result = nullptr;
165             status = napi_call_function(intVecRef->env_, nullptr, jsCallback, argCount, args, &result);
166             CHECK_AND_RETURN_LOG(status == napi_ok,
167                 "%{public}s failed to napi_call_function", callbackName.c_str());
168         }
169     };
170 
171     struct IntArray : public Base {
172         std::vector<int32_t> valueVec;
UvWorkOHOS::Media::NapiCallback::IntArray173         void UvWork() override
174         {
175             std::shared_ptr<AutoRef> intArrayRef = callback.lock();
176             CHECK_AND_RETURN_LOG(intArrayRef != nullptr,
177                 "%{public}s AutoRef is nullptr", callbackName.c_str());
178 
179             napi_handle_scope scope = nullptr;
180             napi_open_handle_scope(intArrayRef->env_, &scope);
181             CHECK_AND_RETURN_LOG(scope != nullptr,
182                 "%{public}s scope is nullptr", callbackName.c_str());
183             ON_SCOPE_EXIT(0) {
184                 napi_close_handle_scope(intArrayRef->env_, scope);
185             };
186 
187             napi_value jsCallback = nullptr;
188             napi_status status = napi_get_reference_value(intArrayRef->env_, intArrayRef->cb_, &jsCallback);
189             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
190                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
191 
192             napi_value array = nullptr;
193             (void)napi_create_array_with_length(intArrayRef->env_, valueVec.size(), &array);
194 
195             for (uint32_t i = 0; i < valueVec.size(); i++) {
196                 napi_value number = nullptr;
197                 (void)napi_create_int32(intArrayRef->env_, valueVec.at(i), &number);
198                 (void)napi_set_element(intArrayRef->env_, array, i, number);
199             }
200 
201             napi_value result = nullptr;
202             napi_value args[1] = {array};
203             status = napi_call_function(intArrayRef->env_, nullptr, jsCallback, 1, args, &result);
204             CHECK_AND_RETURN_LOG(status == napi_ok,
205                 "%{public}s failed to napi_call_function", callbackName.c_str());
206         }
207     };
208 
209     struct Double : public Base {
210         double value = 0.0;
UvWorkOHOS::Media::NapiCallback::Double211         void UvWork() override
212         {
213             std::shared_ptr<AutoRef> doubleRef = callback.lock();
214             CHECK_AND_RETURN_LOG(doubleRef != nullptr,
215                 "%{public}s AutoRef is nullptr", callbackName.c_str());
216 
217             napi_handle_scope scope = nullptr;
218             napi_open_handle_scope(doubleRef->env_, &scope);
219             CHECK_AND_RETURN_LOG(scope != nullptr,
220                 "%{public}s scope is nullptr", callbackName.c_str());
221             ON_SCOPE_EXIT(0) {
222                 napi_close_handle_scope(doubleRef->env_, scope);
223             };
224 
225             napi_value jsCallback = nullptr;
226             napi_status status = napi_get_reference_value(doubleRef->env_, doubleRef->cb_, &jsCallback);
227             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
228                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
229 
230             napi_value args[1] = {nullptr};
231             (void)napi_create_double(doubleRef->env_, value, &args[0]);
232 
233             napi_value result = nullptr;
234             status = napi_call_function(doubleRef->env_, nullptr, jsCallback, 1, args, &result);
235             CHECK_AND_RETURN_LOG(status == napi_ok,
236                 "%{public}s failed to napi_call_function", callbackName.c_str());
237         }
238     };
239 
240     struct FloatArray : public Base {
241         std::vector<float>valueVec;
UvWorkOHOS::Media::NapiCallback::FloatArray242         void UvWork() override
243         {
244             std::shared_ptr<AutoRef> floatArrayRef = callback.lock();
245             CHECK_AND_RETURN_LOG(floatArrayRef != nullptr,
246                 "%{public}s AutoRef is nullptr", callbackName.c_str());
247 
248             napi_handle_scope scope = nullptr;
249             napi_open_handle_scope(floatArrayRef->env_, &scope);
250             CHECK_AND_RETURN_LOG(scope != nullptr,
251                 "%{public}s scope is nullptr", callbackName.c_str());
252             ON_SCOPE_EXIT(0) {
253                 napi_close_handle_scope(floatArrayRef->env_, scope);
254             };
255 
256             napi_value jsCallback = nullptr;
257             napi_status status = napi_get_reference_value(floatArrayRef->env_, floatArrayRef->cb_, &jsCallback);
258             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
259                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
260 
261             napi_value array = nullptr;
262             (void)napi_create_array_with_length(floatArrayRef->env_, valueVec.size(), &array);
263 
264             for (uint32_t i = 0; i < valueVec.size(); i++) {
265                 napi_value number = nullptr;
266                 (void)napi_create_double(floatArrayRef->env_, valueVec.at(i), &number);
267                 (void)napi_set_element(floatArrayRef->env_, array, i, number);
268             }
269 
270             napi_value result = nullptr;
271             napi_value args[1] = {array};
272             status = napi_call_function(floatArrayRef->env_, nullptr, jsCallback, 1, args, &result);
273             CHECK_AND_RETURN_LOG(status == napi_ok,
274                 "%{public}s failed to napi_call_function", callbackName.c_str());
275         }
276     };
277 
278     struct SubtitleProperty : public Base {
279         std::string text;
UvWorkOHOS::Media::NapiCallback::SubtitleProperty280         void UvWork() override
281         {
282             std::shared_ptr<AutoRef> subtitleRef = callback.lock();
283             CHECK_AND_RETURN_LOG(subtitleRef != nullptr,
284                 "%{public}s AutoRef is nullptr", callbackName.c_str());
285 
286             napi_handle_scope scope = nullptr;
287             napi_open_handle_scope(subtitleRef->env_, &scope);
288             CHECK_AND_RETURN_LOG(scope != nullptr,
289                 "%{public}s scope is nullptr", callbackName.c_str());
290             ON_SCOPE_EXIT(0) {
291                 napi_close_handle_scope(subtitleRef->env_, scope);
292             };
293 
294             napi_value jsCallback = nullptr;
295             napi_status status = napi_get_reference_value(subtitleRef->env_, subtitleRef->cb_, &jsCallback);
296             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
297                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
298 
299             // callback: (textInfo: TextInfoDescriptor)
300             napi_value args[1] = {nullptr};
301             napi_create_object(subtitleRef->env_, &args[0]);
302             (void)CommonNapi::SetPropertyString(subtitleRef->env_, args[0], "text", text);
303             napi_value result = nullptr;
304             status = napi_call_function(subtitleRef->env_, nullptr, jsCallback, 1, args, &result);
305             CHECK_AND_RETURN_LOG(status == napi_ok,
306                 "%{public}s fail to napi_call_function", callbackName.c_str());
307         }
308     };
309 
310     struct ObjectArray : public Base {
311         std::multimap<std::string, std::vector<uint8_t>> infoMap;
UvWorkOHOS::Media::NapiCallback::ObjectArray312         void UvWork() override
313         {
314             std::shared_ptr<AutoRef> mapRef = callback.lock();
315             CHECK_AND_RETURN_LOG(mapRef != nullptr,
316                 "%{public}s AutoRef is nullptr", callbackName.c_str());
317 
318             napi_handle_scope scope = nullptr;
319             napi_open_handle_scope(mapRef->env_, &scope);
320             CHECK_AND_RETURN_LOG(scope != nullptr,
321                 "%{public}s scope is nullptr", callbackName.c_str());
322             ON_SCOPE_EXIT(0) {
323                 napi_close_handle_scope(mapRef->env_, scope);
324             };
325 
326             napi_value jsCallback = nullptr;
327             napi_status status = napi_get_reference_value(mapRef->env_, mapRef->cb_, &jsCallback);
328             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
329                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
330 
331             uint32_t index = 0;
332             napi_value napiMap;
333             napi_create_array_with_length(mapRef->env_, infoMap.size(), &napiMap);
334             for (auto item : infoMap) {
335                 napi_value jsObject;
336                 napi_value jsUuid;
337                 napi_value jsPssh;
338                 napi_create_object(mapRef->env_, &jsObject);
339                 napi_create_string_utf8(mapRef->env_, item.first.c_str(), NAPI_AUTO_LENGTH, &jsUuid);
340                 napi_set_named_property(mapRef->env_, jsObject, "uuid", jsUuid);
341 
342                 status = napi_create_array_with_length(mapRef->env_, item.second.size(), &jsPssh);
343                 for (uint32_t i = 0; i < item.second.size(); i++) {
344                     napi_value number = nullptr;
345                     (void)napi_create_uint32(mapRef->env_, item.second[i], &number);
346                     (void)napi_set_element(mapRef->env_, jsPssh, i, number);
347                 }
348                 napi_set_named_property(mapRef->env_, jsObject, "pssh", jsPssh);
349                 napi_set_element(mapRef->env_, napiMap, index, jsObject);
350                 index++;
351             }
352 
353             const int32_t argCount = 1;
354             napi_value args[argCount] = { napiMap };
355             napi_value result = nullptr;
356             status = napi_call_function(mapRef->env_, nullptr, jsCallback, argCount, args, &result);
357             CHECK_AND_RETURN_LOG(status == napi_ok,
358                 "%{public}s failed to napi_call_function", callbackName.c_str());
359         }
360     };
361 
362     struct PropertyInt : public Base {
363         std::map<std::string, int32_t> valueMap;
UvWorkOHOS::Media::NapiCallback::PropertyInt364         void UvWork() override
365         {
366             std::shared_ptr<AutoRef> propertyIntRef = callback.lock();
367             CHECK_AND_RETURN_LOG(propertyIntRef != nullptr,
368                 "%{public}s AutoRef is nullptr", callbackName.c_str());
369 
370             napi_handle_scope scope = nullptr;
371             napi_open_handle_scope(propertyIntRef->env_, &scope);
372             CHECK_AND_RETURN_LOG(scope != nullptr,
373                 "%{public}s scope is nullptr", callbackName.c_str());
374             ON_SCOPE_EXIT(0) {
375                 napi_close_handle_scope(propertyIntRef->env_, scope);
376             };
377 
378             napi_value jsCallback = nullptr;
379             napi_status status = napi_get_reference_value(propertyIntRef->env_, propertyIntRef->cb_, &jsCallback);
380             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
381                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
382 
383             napi_value args[1] = {nullptr};
384             napi_create_object(propertyIntRef->env_, &args[0]);
385             for (auto &it : valueMap) {
386                 CommonNapi::SetPropertyInt32(propertyIntRef->env_, args[0], it.first, it.second);
387             }
388 
389             napi_value result = nullptr;
390             status = napi_call_function(propertyIntRef->env_, nullptr, jsCallback, 1, args, &result);
391             CHECK_AND_RETURN_LOG(status == napi_ok,
392                 "%{public}s fail to napi_call_function", callbackName.c_str());
393         }
394     };
395 
396     struct StateChange : public Base {
397         std::string state = "";
398         int32_t reason = 0;
UvWorkOHOS::Media::NapiCallback::StateChange399         void UvWork() override
400         {
401             std::shared_ptr<AutoRef> stateChangeRef = callback.lock();
402             CHECK_AND_RETURN_LOG(stateChangeRef != nullptr,
403                 "%{public}s AutoRef is nullptr", callbackName.c_str());
404 
405             napi_handle_scope scope = nullptr;
406             napi_open_handle_scope(stateChangeRef->env_, &scope);
407             CHECK_AND_RETURN_LOG(scope != nullptr,
408                 "%{public}s scope is nullptr", callbackName.c_str());
409             ON_SCOPE_EXIT(0) {
410                 napi_close_handle_scope(stateChangeRef->env_, scope);
411             };
412 
413             napi_value jsCallback = nullptr;
414             napi_status status = napi_get_reference_value(stateChangeRef->env_, stateChangeRef->cb_, &jsCallback);
415             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
416                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
417 
418             const int32_t argCount = 2;
419             // callback: (state: AVPlayerState, reason: StateChangeReason)
420             napi_value args[argCount] = {nullptr};
421             (void)napi_create_string_utf8(stateChangeRef->env_, state.c_str(), NAPI_AUTO_LENGTH, &args[0]);
422             (void)napi_create_int32(stateChangeRef->env_, reason, &args[1]);
423 
424             napi_value result = nullptr;
425             status = napi_call_function(stateChangeRef->env_, nullptr, jsCallback, argCount, args, &result);
426             CHECK_AND_RETURN_LOG(status == napi_ok,
427                 "%{public}s fail to napi_call_function", callbackName.c_str());
428         }
429     };
430 
CompleteCallback(napi_env env,NapiCallback::Base * jsCb)431     static void CompleteCallback(napi_env env, NapiCallback::Base *jsCb)
432     {
433         ON_SCOPE_EXIT(0) {
434             delete jsCb;
435         };
436 
437         if (jsCb != nullptr && jsCb->callbackName == AVPlayerEvent::EVENT_BUFFERING_UPDATE) {
438             napi_status ret = napi_send_event(env, [jsCb] () {
439                 CHECK_AND_RETURN_LOG(jsCb != nullptr, "Work thread is nullptr");
440                 MEDIA_LOGD("JsCallBack %{public}s start", jsCb->callbackName.c_str());
441                 jsCb->UvWork();
442                 delete jsCb;
443             }, napi_eprio_immediate);
444             if (ret != napi_ok) {
445                 MEDIA_LOGE("Failed to execute libuv work queue");
446                 delete jsCb;
447             }
448         } else {
449             uv_loop_s *loop = nullptr;
450             napi_get_uv_event_loop(env, &loop);
451             CHECK_AND_RETURN_LOG(loop != nullptr, "Fail to napi_get_uv_event_loop");
452 
453             uv_work_t *work = new(std::nothrow) uv_work_t;
454             CHECK_AND_RETURN_LOG(work != nullptr, "Fail to new uv_work_t");
455 
456             work->data = reinterpret_cast<void *>(jsCb);
457             // async callback, jsWork and jsWork->data should be heap object.
458             int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {}, [] (uv_work_t *work, int status) {
459                 CHECK_AND_RETURN_LOG(work != nullptr, "Work thread is nullptr");
460                 (void)status;
461                 NapiCallback::Base *cb = reinterpret_cast<NapiCallback::Base *>(work->data);
462                 if (cb != nullptr) {
463                     MEDIA_LOGD("JsCallBack %{public}s, uv_queue_work_with_qos start", cb->callbackName.c_str());
464                     cb->UvWork();
465                     delete cb;
466                 }
467                 delete work;
468             }, uv_qos_user_initiated);
469             if (ret != 0) {
470                 MEDIA_LOGE("Failed to execute libuv work queue");
471                 delete jsCb;
472                 delete work;
473             }
474         }
475         CANCEL_SCOPE_EXIT_GUARD(0);
476     }
477 
478     struct TrackChange : public Base {
479         int32_t number = 0;
480         bool isSelect = false;
UvWorkOHOS::Media::NapiCallback::TrackChange481         void UvWork() override
482         {
483             std::shared_ptr<AutoRef> trackChangeRef = callback.lock();
484             CHECK_AND_RETURN_LOG(trackChangeRef != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
485 
486             napi_handle_scope scope = nullptr;
487             napi_open_handle_scope(trackChangeRef->env_, &scope);
488             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
489             ON_SCOPE_EXIT(0) {
490                 napi_close_handle_scope(trackChangeRef->env_, scope);
491             };
492 
493             napi_value jsCallback = nullptr;
494             napi_status status = napi_get_reference_value(trackChangeRef->env_, trackChangeRef->cb_, &jsCallback);
495             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
496                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
497 
498             const int32_t argCount = 2; // 2 prapm, callback: (index: number, isSelect: boolean)
499             napi_value args[argCount] = {nullptr};
500             (void)napi_create_int32(trackChangeRef->env_, number, &args[0]);
501             (void)napi_get_boolean(trackChangeRef->env_, isSelect, &args[1]);
502 
503             napi_value result = nullptr;
504             status = napi_call_function(trackChangeRef->env_, nullptr, jsCallback, argCount, args, &result);
505             CHECK_AND_RETURN_LOG(status == napi_ok, "%{public}s fail to napi_call_function", callbackName.c_str());
506         }
507     };
508 
509     struct SubtitleInfo : public Base {
510         struct SubtitleParam {
511             std::string text;
512             int32_t pts;
513             int32_t duration;
514         } valueMap;
UvWorkOHOS::Media::NapiCallback::SubtitleInfo515         void UvWork() override
516         {
517             std::shared_ptr<AutoRef> subtitleRef = callback.lock();
518             CHECK_AND_RETURN_LOG(subtitleRef != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
519 
520             napi_handle_scope scope = nullptr;
521             napi_open_handle_scope(subtitleRef->env_, &scope);
522             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
523             ON_SCOPE_EXIT(0) {
524                 napi_close_handle_scope(subtitleRef->env_, scope);
525             };
526 
527             napi_value jsCallback = nullptr;
528             napi_status status = napi_get_reference_value(subtitleRef->env_, subtitleRef->cb_, &jsCallback);
529             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
530                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
531 
532             napi_value args[1] = {nullptr};
533             napi_create_object(subtitleRef->env_, &args[0]);
534             CommonNapi::SetPropertyString(subtitleRef->env_, args[0], "text", valueMap.text);
535             CommonNapi::SetPropertyInt32(subtitleRef->env_, args[0], "startTime", valueMap.pts);
536             CommonNapi::SetPropertyInt32(subtitleRef->env_, args[0], "duration", valueMap.duration);
537             napi_value result = nullptr;
538             status = napi_call_function(subtitleRef->env_, nullptr, jsCallback, 1, args, &result);
539             CHECK_AND_RETURN_LOG(status == napi_ok, "%{public}s fail to napi_call_function", callbackName.c_str());
540         }
541     };
542 
543     struct DeviceChangeNapi : public Base {
544         AudioStandard::DeviceInfo deviceInfo;
545         int32_t reason;
UvWorkOHOS::Media::NapiCallback::DeviceChangeNapi546         void UvWork() override
547         {
548             std::shared_ptr<AutoRef> deviceChangeRef = callback.lock();
549             CHECK_AND_RETURN_LOG(deviceChangeRef != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
550 
551             napi_handle_scope scope = nullptr;
552             napi_open_handle_scope(deviceChangeRef->env_, &scope);
553             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
554             ON_SCOPE_EXIT(0) {
555                 napi_close_handle_scope(deviceChangeRef->env_, scope);
556             };
557 
558             napi_value jsCallback = nullptr;
559             napi_status status = napi_get_reference_value(deviceChangeRef->env_, deviceChangeRef->cb_, &jsCallback);
560             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
561                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
562 
563             constexpr size_t argCount = 1;
564             napi_value args[argCount] = {};
565             napi_create_object(deviceChangeRef->env_, &args[0]);
566             napi_value deviceObj = nullptr;
567             status = CommonNapi::SetValueDeviceInfo(deviceChangeRef->env_, deviceInfo, deviceObj);
568             CHECK_AND_RETURN_LOG(status == napi_ok && deviceObj != nullptr,
569                 " fail to convert to jsobj");
570             napi_set_named_property(deviceChangeRef->env_, args[0], "devices", deviceObj);
571 
572             bool res = CommonNapi::SetPropertyInt32(deviceChangeRef->env_, args[0], "changeReason",
573                 static_cast<const int32_t> (reason));
574             CHECK_AND_RETURN_LOG(res && deviceObj != nullptr,
575                 " fail to convert to jsobj");
576 
577             napi_value result = nullptr;
578             status = napi_call_function(deviceChangeRef->env_, nullptr, jsCallback, argCount, args, &result);
579             CHECK_AND_RETURN_LOG(status == napi_ok, "%{public}s fail to napi_call_function", callbackName.c_str());
580         }
581     };
582 
583     struct TrackInfoUpdate : public Base {
584         std::vector<Format> trackInfo;
UvWorkOHOS::Media::NapiCallback::TrackInfoUpdate585         void UvWork() override
586         {
587             std::shared_ptr<AutoRef> trackInfoRef = callback.lock();
588             CHECK_AND_RETURN_LOG(trackInfoRef != nullptr, "%{public}s AutoRef is nullptr", callbackName.c_str());
589 
590             napi_handle_scope scope = nullptr;
591             napi_open_handle_scope(trackInfoRef->env_, &scope);
592             CHECK_AND_RETURN_LOG(scope != nullptr, "%{public}s scope is nullptr", callbackName.c_str());
593             ON_SCOPE_EXIT(0) {
594                 napi_close_handle_scope(trackInfoRef->env_, scope);
595             };
596 
597             napi_value jsCallback = nullptr;
598             napi_status status = napi_get_reference_value(trackInfoRef->env_, trackInfoRef->cb_, &jsCallback);
599             CHECK_AND_RETURN_LOG(status == napi_ok && jsCallback != nullptr,
600                 "%{public}s failed to napi_get_reference_value", callbackName.c_str());
601 
602             napi_value array = nullptr;
603             (void)napi_create_array_with_length(trackInfoRef->env_, trackInfo.size(), &array);
604 
605             for (uint32_t i = 0; i < trackInfo.size(); i++) {
606                 napi_value trackDescription = nullptr;
607                 trackDescription = CommonNapi::CreateFormatBuffer(trackInfoRef->env_, trackInfo[i]);
608                 (void)napi_set_element(trackInfoRef->env_, array, i, trackDescription);
609             }
610 
611             napi_value result = nullptr;
612             napi_value args[1] = {array};
613             status = napi_call_function(trackInfoRef->env_, nullptr, jsCallback, 1, args, &result);
614             CHECK_AND_RETURN_LOG(status == napi_ok,
615                 "%{public}s failed to napi_call_function", callbackName.c_str());
616         }
617     };
618 };
619 
AVPlayerCallback(napi_env env,AVPlayerNotify * listener)620 AVPlayerCallback::AVPlayerCallback(napi_env env, AVPlayerNotify *listener)
621     : env_(env), listener_(listener)
622 {
623     MEDIA_LOGI("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
624     onInfoFuncs_ = {
625         { INFO_TYPE_STATE_CHANGE,
626             [this](const int32_t extra, const Format &infoBody) { OnStateChangeCb(extra, infoBody); } },
627         { INFO_TYPE_VOLUME_CHANGE,
628             [this](const int32_t extra, const Format &infoBody) { OnVolumeChangeCb(extra, infoBody); } },
629         { INFO_TYPE_SEEKDONE,
630             [this](const int32_t extra, const Format &infoBody) { OnSeekDoneCb(extra, infoBody); } },
631         { INFO_TYPE_SPEEDDONE,
632             [this](const int32_t extra, const Format &infoBody) { OnSpeedDoneCb(extra, infoBody); } },
633         { INFO_TYPE_BITRATEDONE,
634             [this](const int32_t extra, const Format &infoBody) { OnBitRateDoneCb(extra, infoBody); } },
635         { INFO_TYPE_POSITION_UPDATE,
636             [this](const int32_t extra, const Format &infoBody) { OnPositionUpdateCb(extra, infoBody); } },
637         { INFO_TYPE_DURATION_UPDATE,
638             [this](const int32_t extra, const Format &infoBody) { OnDurationUpdateCb(extra, infoBody); } },
639         { INFO_TYPE_BUFFERING_UPDATE,
640             [this](const int32_t extra, const Format &infoBody) { OnBufferingUpdateCb(extra, infoBody); } },
641         { INFO_TYPE_MESSAGE,
642             [this](const int32_t extra, const Format &infoBody) { OnMessageCb(extra, infoBody);} },
643         { INFO_TYPE_RESOLUTION_CHANGE,
644             [this](const int32_t extra, const Format &infoBody) { OnVideoSizeChangedCb(extra, infoBody); } },
645         { INFO_TYPE_INTERRUPT_EVENT,
646             [this](const int32_t extra, const Format &infoBody) { OnAudioInterruptCb(extra, infoBody); } },
647         { INFO_TYPE_BITRATE_COLLECT,
648              [this](const int32_t extra, const Format &infoBody) { OnBitRateCollectedCb(extra, infoBody); } },
649         { INFO_TYPE_EOS,
650             [this](const int32_t extra, const Format &infoBody) { OnEosCb(extra, infoBody); } },
651         { INFO_TYPE_IS_LIVE_STREAM,
652             [this](const int32_t extra, const Format &infoBody) { NotifyIsLiveStream(extra, infoBody); } },
653         { INFO_TYPE_SUBTITLE_UPDATE,
654             [this](const int32_t extra, const Format &infoBody) { OnSubtitleUpdateCb(extra, infoBody); } },
655         { INFO_TYPE_TRACKCHANGE,
656             [this](const int32_t extra, const Format &infoBody) { OnTrackChangedCb(extra, infoBody); } },
657         { INFO_TYPE_TRACK_INFO_UPDATE,
658             [this](const int32_t extra, const Format &infoBody) { OnTrackInfoUpdate(extra, infoBody); } },
659         { INFO_TYPE_DRM_INFO_UPDATED,
660             [this](const int32_t extra, const Format &infoBody) { OnDrmInfoUpdatedCb(extra, infoBody); } },
661         { INFO_TYPE_SET_DECRYPT_CONFIG_DONE,
662             [this](const int32_t extra, const Format &infoBody) { OnSetDecryptConfigDoneCb(extra, infoBody); } },
663         { INFO_TYPE_SUBTITLE_UPDATE_INFO,
664             [this](const int32_t extra, const Format &infoBody) { OnSubtitleInfoCb(extra, infoBody); } },
665         { INFO_TYPE_AUDIO_DEVICE_CHANGE,
666             [this](const int32_t extra, const Format &infoBody) { OnAudioDeviceChangeCb(extra, infoBody); } },
667         { INFO_TYPE_MAX_AMPLITUDE_COLLECT,
668              [this](const int32_t extra, const Format &infoBody) { OnMaxAmplitudeCollectedCb(extra, infoBody); } },
669     };
670 }
671 
OnAudioDeviceChangeCb(const int32_t extra,const Format & infoBody)672 void AVPlayerCallback::OnAudioDeviceChangeCb(const int32_t extra, const Format &infoBody)
673 {
674     (void)extra;
675     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
676     if (refMap_.find(AVPlayerEvent::EVENT_AUDIO_DEVICE_CHANGE) == refMap_.end()) {
677         MEDIA_LOGD("0x%{public}06" PRIXPTR " can not find audio AudioDeviceChange callback!", FAKE_POINTER(this));
678         return;
679     }
680 
681     NapiCallback::DeviceChangeNapi *cb = new(std::nothrow) NapiCallback::DeviceChangeNapi();
682     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new DeviceChangeNapi");
683 
684     cb->callback = refMap_.at(AVPlayerEvent::EVENT_AUDIO_DEVICE_CHANGE);
685     cb->callbackName = AVPlayerEvent::EVENT_AUDIO_DEVICE_CHANGE;
686 
687     uint8_t *parcelBuffer = nullptr;
688     size_t parcelSize;
689     infoBody.GetBuffer(PlayerKeys::AUDIO_DEVICE_CHANGE, &parcelBuffer, parcelSize);
690     Parcel parcel;
691     parcel.WriteBuffer(parcelBuffer, parcelSize);
692     AudioStandard::DeviceInfo deviceInfo;
693     deviceInfo.Unmarshalling(parcel);
694 
695     int32_t reason;
696     infoBody.GetIntValue(PlayerKeys::AUDIO_DEVICE_CHANGE_REASON, reason);
697 
698     cb->deviceInfo = deviceInfo;
699     cb->reason = reason;
700 
701     NapiCallback::CompleteCallback(env_, cb);
702 }
703 
~AVPlayerCallback()704 AVPlayerCallback::~AVPlayerCallback()
705 {
706     MEDIA_LOGI("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
707 }
708 
OnError(int32_t errorCode,const std::string & errorMsg)709 void AVPlayerCallback::OnError(int32_t errorCode, const std::string &errorMsg)
710 {
711     MediaServiceExtErrCodeAPI9 errorCodeApi9 = MSErrorToExtErrorAPI9(static_cast<MediaServiceErrCode>(errorCode));
712     if (errorCodeApi9 == MSERR_EXT_API9_NO_PERMISSION ||
713         errorCodeApi9 == MSERR_EXT_API9_NO_MEMORY ||
714         errorCodeApi9 == MSERR_EXT_API9_TIMEOUT ||
715         errorCodeApi9 == MSERR_EXT_API9_SERVICE_DIED ||
716         errorCodeApi9 == MSERR_EXT_API9_UNSUPPORT_FORMAT) {
717         Format infoBody;
718         AVPlayerCallback::OnInfo(INFO_TYPE_STATE_CHANGE, PLAYER_STATE_ERROR, infoBody);
719     }
720     AVPlayerCallback::OnErrorCb(errorCodeApi9, errorMsg);
721 }
722 
OnErrorCb(MediaServiceExtErrCodeAPI9 errorCode,const std::string & errorMsg)723 void AVPlayerCallback::OnErrorCb(MediaServiceExtErrCodeAPI9 errorCode, const std::string &errorMsg)
724 {
725     std::string message = MSExtAVErrorToString(errorCode) + errorMsg;
726     MEDIA_LOGE("OnErrorCb:errorCode %{public}d, errorMsg %{public}s", errorCode, message.c_str());
727     std::lock_guard<std::mutex> lock(mutex_);
728     if (refMap_.find(AVPlayerEvent::EVENT_ERROR) == refMap_.end()) {
729         MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find error callback!", FAKE_POINTER(this));
730         return;
731     }
732 
733     NapiCallback::Error *cb = new(std::nothrow) NapiCallback::Error();
734     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Error");
735 
736     cb->callback = refMap_.at(AVPlayerEvent::EVENT_ERROR);
737     cb->callbackName = AVPlayerEvent::EVENT_ERROR;
738     cb->errorCode = errorCode;
739     cb->errorMsg = message;
740     NapiCallback::CompleteCallback(env_, cb);
741 }
742 
OnInfo(PlayerOnInfoType type,int32_t extra,const Format & infoBody)743 void AVPlayerCallback::OnInfo(PlayerOnInfoType type, int32_t extra, const Format &infoBody)
744 {
745     std::lock_guard<std::mutex> lock(mutex_);
746     MEDIA_LOGD("OnInfo is called, PlayerOnInfoType: %{public}d", type);
747     if (onInfoFuncs_.count(type) > 0) {
748         onInfoFuncs_[type](extra, infoBody);
749     } else {
750         MEDIA_LOGD("0x%{public}06" PRIXPTR " OnInfo: no member func supporting, %{public}d",
751             FAKE_POINTER(this), type);
752     }
753 }
754 
NotifyIsLiveStream(const int32_t extra,const Format & infoBody)755 void AVPlayerCallback::NotifyIsLiveStream(const int32_t extra, const Format &infoBody)
756 {
757     (void)extra;
758     (void)infoBody;
759     if (listener_ != nullptr) {
760         listener_->NotifyIsLiveStream();
761     }
762 }
763 
IsValidState(PlayerStates state,std::string & stateStr)764 bool AVPlayerCallback::IsValidState(PlayerStates state, std::string &stateStr)
765 {
766     switch (state) {
767         case PlayerStates::PLAYER_IDLE:
768             stateStr = AVPlayerState::STATE_IDLE;
769             break;
770         case PlayerStates::PLAYER_INITIALIZED:
771             stateStr = AVPlayerState::STATE_INITIALIZED;
772             break;
773         case PlayerStates::PLAYER_PREPARED:
774             stateStr = AVPlayerState::STATE_PREPARED;
775             break;
776         case PlayerStates::PLAYER_STARTED:
777             stateStr = AVPlayerState::STATE_PLAYING;
778             break;
779         case PlayerStates::PLAYER_PAUSED:
780             stateStr = AVPlayerState::STATE_PAUSED;
781             break;
782         case PlayerStates::PLAYER_STOPPED:
783             stateStr = AVPlayerState::STATE_STOPPED;
784             break;
785         case PlayerStates::PLAYER_PLAYBACK_COMPLETE:
786             stateStr = AVPlayerState::STATE_COMPLETED;
787             break;
788         case PlayerStates::PLAYER_RELEASED:
789             stateStr = AVPlayerState::STATE_RELEASED;
790             break;
791         case PlayerStates::PLAYER_STATE_ERROR:
792             stateStr = AVPlayerState::STATE_ERROR;
793             break;
794         default:
795             return false;
796     }
797     return true;
798 }
799 
OnStateChangeCb(const int32_t extra,const Format & infoBody)800 void AVPlayerCallback::OnStateChangeCb(const int32_t extra, const Format &infoBody)
801 {
802     PlayerStates state = static_cast<PlayerStates>(extra);
803     MEDIA_LOGI("0x%{public}06" PRIXPTR " Instance OnStateChanged is called, current state: %{public}d",
804         FAKE_POINTER(this), state);
805 
806     if (listener_ != nullptr) {
807         listener_->NotifyState(state);
808     }
809 
810     if (state_ != state) {
811         state_ = state;
812         std::string stateStr;
813         if (IsValidState(state, stateStr)) {
814             if (refMap_.find(AVPlayerEvent::EVENT_STATE_CHANGE) == refMap_.end()) {
815                 MEDIA_LOGW("can not find state change callback!");
816                 return;
817             }
818             NapiCallback::StateChange *cb = new(std::nothrow) NapiCallback::StateChange();
819             CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new StateChange");
820 
821             int32_t reason = StateChangeReason::USER;
822             if (infoBody.ContainKey(PlayerKeys::PLAYER_STATE_CHANGED_REASON)) {
823                 (void)infoBody.GetIntValue(PlayerKeys::PLAYER_STATE_CHANGED_REASON, reason);
824             }
825             cb->callback = refMap_.at(AVPlayerEvent::EVENT_STATE_CHANGE);
826             cb->callbackName = AVPlayerEvent::EVENT_STATE_CHANGE;
827             cb->state = stateStr;
828             cb->reason = reason;
829             NapiCallback::CompleteCallback(env_, cb);
830         }
831     }
832 }
833 
OnVolumeChangeCb(const int32_t extra,const Format & infoBody)834 void AVPlayerCallback::OnVolumeChangeCb(const int32_t extra, const Format &infoBody)
835 {
836     (void)extra;
837     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
838     float volumeLevel = 0.0;
839     (void)infoBody.GetFloatValue(PlayerKeys::PLAYER_VOLUME_LEVEL, volumeLevel);
840 
841     isSetVolume_ = false;
842     MEDIA_LOGD("OnVolumeChangeCb in volume=%{public}f", volumeLevel);
843     if (refMap_.find(AVPlayerEvent::EVENT_VOLUME_CHANGE) == refMap_.end()) {
844         MEDIA_LOGD("can not find vol change callback!");
845         return;
846     }
847 
848     NapiCallback::Double *cb = new(std::nothrow) NapiCallback::Double();
849     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Double");
850     cb->callback = refMap_.at(AVPlayerEvent::EVENT_VOLUME_CHANGE);
851     cb->callbackName = AVPlayerEvent::EVENT_VOLUME_CHANGE;
852     cb->value = static_cast<double>(volumeLevel);
853     NapiCallback::CompleteCallback(env_, cb);
854 }
855 
OnSeekDoneCb(const int32_t extra,const Format & infoBody)856 void AVPlayerCallback::OnSeekDoneCb(const int32_t extra, const Format &infoBody)
857 {
858     (void)infoBody;
859     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
860     int32_t currentPositon = extra;
861     MEDIA_LOGI("0x%{public}06" PRIXPTR " OnSeekDone is called, currentPositon: %{public}d",
862         FAKE_POINTER(this), currentPositon);
863     if (refMap_.find(AVPlayerEvent::EVENT_SEEK_DONE) == refMap_.end()) {
864         MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find seekdone callback!", FAKE_POINTER(this));
865         return;
866     }
867     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
868     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
869 
870     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SEEK_DONE);
871     cb->callbackName = AVPlayerEvent::EVENT_SEEK_DONE;
872     cb->value = currentPositon;
873     NapiCallback::CompleteCallback(env_, cb);
874 }
875 
OnSpeedDoneCb(const int32_t extra,const Format & infoBody)876 void AVPlayerCallback::OnSpeedDoneCb(const int32_t extra, const Format &infoBody)
877 {
878     (void)infoBody;
879     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
880     int32_t speedMode = extra;
881     MEDIA_LOGI("OnSpeedDoneCb is called, speedMode: %{public}d", speedMode);
882     if (refMap_.find(AVPlayerEvent::EVENT_SPEED_DONE) == refMap_.end()) {
883         MEDIA_LOGW("can not find speeddone callback!");
884         return;
885     }
886 
887     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
888     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
889 
890     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SPEED_DONE);
891     cb->callbackName = AVPlayerEvent::EVENT_SPEED_DONE;
892     cb->value = speedMode;
893     NapiCallback::CompleteCallback(env_, cb);
894 }
895 
OnBitRateDoneCb(const int32_t extra,const Format & infoBody)896 void AVPlayerCallback::OnBitRateDoneCb(const int32_t extra, const Format &infoBody)
897 {
898     (void)infoBody;
899     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
900     int32_t bitRate = extra;
901     MEDIA_LOGI("OnBitRateDoneCb is called, bitRate: %{public}d", bitRate);
902     if (refMap_.find(AVPlayerEvent::EVENT_BITRATE_DONE) == refMap_.end()) {
903         MEDIA_LOGW("can not find bitrate callback!");
904         return;
905     }
906 
907     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
908     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
909 
910     cb->callback = refMap_.at(AVPlayerEvent::EVENT_BITRATE_DONE);
911     cb->callbackName = AVPlayerEvent::EVENT_BITRATE_DONE;
912     cb->value = bitRate;
913     NapiCallback::CompleteCallback(env_, cb);
914 }
915 
OnPositionUpdateCb(const int32_t extra,const Format & infoBody)916 void AVPlayerCallback::OnPositionUpdateCb(const int32_t extra, const Format &infoBody)
917 {
918     (void)infoBody;
919     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
920     int32_t position = extra;
921     MEDIA_LOGD("OnPositionUpdateCb is called, position: %{public}d", position);
922 
923     if (listener_ != nullptr) {
924         listener_->NotifyPosition(position);
925     }
926 
927     if (refMap_.find(AVPlayerEvent::EVENT_TIME_UPDATE) == refMap_.end()) {
928         MEDIA_LOGD("can not find timeupdate callback!");
929         return;
930     }
931     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
932     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
933 
934     cb->callback = refMap_.at(AVPlayerEvent::EVENT_TIME_UPDATE);
935     cb->callbackName = AVPlayerEvent::EVENT_TIME_UPDATE;
936     cb->value = position;
937     NapiCallback::CompleteCallback(env_, cb);
938 }
939 
OnDurationUpdateCb(const int32_t extra,const Format & infoBody)940 void AVPlayerCallback::OnDurationUpdateCb(const int32_t extra, const Format &infoBody)
941 {
942     (void)infoBody;
943     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
944     int32_t duration = extra;
945     MEDIA_LOGI("0x%{public}06" PRIXPTR " OnDurationUpdateCb is called, duration: %{public}d",
946         FAKE_POINTER(this), duration);
947 
948     if (listener_ != nullptr) {
949         listener_->NotifyDuration(duration);
950     }
951 
952     if (refMap_.find(AVPlayerEvent::EVENT_DURATION_UPDATE) == refMap_.end()) {
953         MEDIA_LOGD("0x%{public}06" PRIXPTR " can not find duration update callback!", FAKE_POINTER(this));
954         return;
955     }
956 
957     NapiCallback::Int *cb = new(std::nothrow) NapiCallback::Int();
958     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Int");
959 
960     cb->callback = refMap_.at(AVPlayerEvent::EVENT_DURATION_UPDATE);
961     cb->callbackName = AVPlayerEvent::EVENT_DURATION_UPDATE;
962     cb->value = duration;
963     NapiCallback::CompleteCallback(env_, cb);
964 }
965 
OnSubtitleUpdateCb(const int32_t extra,const Format & infoBody)966 void AVPlayerCallback::OnSubtitleUpdateCb(const int32_t extra, const Format &infoBody)
967 {
968     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
969     if (refMap_.find(AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE) == refMap_.end()) {
970         MEDIA_LOGW("can not find subtitle update callback!");
971         return;
972     }
973     NapiCallback::SubtitleProperty *cb = new(std::nothrow) NapiCallback::SubtitleProperty();
974     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new SubtitleProperty");
975     if (infoBody.ContainKey(PlayerKeys::SUBTITLE_TEXT)) {
976         (void)infoBody.GetStringValue(PlayerKeys::SUBTITLE_TEXT, cb->text);
977     }
978     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE);
979     cb->callbackName = AVPlayerEvent::EVENT_SUBTITLE_TEXT_UPDATE;
980     NapiCallback::CompleteCallback(env_, cb);
981 }
982 
OnBufferingUpdateCb(const int32_t extra,const Format & infoBody)983 void AVPlayerCallback::OnBufferingUpdateCb(const int32_t extra, const Format &infoBody)
984 {
985     (void)extra;
986     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
987     if (refMap_.find(AVPlayerEvent::EVENT_BUFFERING_UPDATE) == refMap_.end()) {
988         MEDIA_LOGD("can not find buffering update callback!");
989         return;
990     }
991 
992     int32_t val = 0;
993     int32_t bufferingType = -1;
994     if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_START))) {
995         bufferingType = BUFFERING_START;
996         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_START), val);
997     } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_END))) {
998         bufferingType = BUFFERING_END;
999         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_END), val);
1000     } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT))) {
1001         bufferingType = BUFFERING_PERCENT;
1002         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT), val);
1003     } else if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_CACHED_DURATION))) {
1004         bufferingType = CACHED_DURATION;
1005         (void)infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_CACHED_DURATION), val);
1006     } else {
1007         return;
1008     }
1009 
1010     MEDIA_LOGD("OnBufferingUpdateCb is called, buffering type: %{public}d value: %{public}d", bufferingType, val);
1011     NapiCallback::IntVec *cb = new(std::nothrow) NapiCallback::IntVec();
1012     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntVec");
1013 
1014     cb->callback = refMap_.at(AVPlayerEvent::EVENT_BUFFERING_UPDATE);
1015     cb->callbackName = AVPlayerEvent::EVENT_BUFFERING_UPDATE;
1016     cb->valueVec.push_back(bufferingType);
1017     cb->valueVec.push_back(val);
1018     NapiCallback::CompleteCallback(env_, cb);
1019 }
1020 
OnMessageCb(const int32_t extra,const Format & infoBody)1021 void AVPlayerCallback::OnMessageCb(const int32_t extra, const Format &infoBody)
1022 {
1023     (void)infoBody;
1024     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1025     MEDIA_LOGI("OnMessageCb is called, extra: %{public}d", extra);
1026     if (extra == PlayerMessageType::PLAYER_INFO_VIDEO_RENDERING_START) {
1027         AVPlayerCallback::OnStartRenderFrameCb();
1028     }
1029 }
1030 
OnStartRenderFrameCb() const1031 void AVPlayerCallback::OnStartRenderFrameCb() const
1032 {
1033     MEDIA_LOGI("OnStartRenderFrameCb is called");
1034     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1035     if (refMap_.find(AVPlayerEvent::EVENT_START_RENDER_FRAME) == refMap_.end()) {
1036         MEDIA_LOGW("can not find start render callback!");
1037         return;
1038     }
1039 
1040     NapiCallback::Base *cb = new(std::nothrow) NapiCallback::Base();
1041     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Base");
1042 
1043     cb->callback = refMap_.at(AVPlayerEvent::EVENT_START_RENDER_FRAME);
1044     cb->callbackName = AVPlayerEvent::EVENT_START_RENDER_FRAME;
1045     NapiCallback::CompleteCallback(env_, cb);
1046 }
1047 
OnVideoSizeChangedCb(const int32_t extra,const Format & infoBody)1048 void AVPlayerCallback::OnVideoSizeChangedCb(const int32_t extra, const Format &infoBody)
1049 {
1050     (void)extra;
1051     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1052     int32_t width = 0;
1053     int32_t height = 0;
1054     (void)infoBody.GetIntValue(PlayerKeys::PLAYER_WIDTH, width);
1055     (void)infoBody.GetIntValue(PlayerKeys::PLAYER_HEIGHT, height);
1056     MEDIA_LOGI("0x%{public}06" PRIXPTR " OnVideoSizeChangedCb is called, width = %{public}d, height = %{public}d",
1057         FAKE_POINTER(this), width, height);
1058 
1059     if (listener_ != nullptr) {
1060         listener_->NotifyVideoSize(width, height);
1061     }
1062 
1063     if (refMap_.find(AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE) == refMap_.end()) {
1064         MEDIA_LOGW("can not find video size changed callback!");
1065         return;
1066     }
1067     NapiCallback::IntVec *cb = new(std::nothrow) NapiCallback::IntVec();
1068     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntVec");
1069 
1070     cb->callback = refMap_.at(AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE);
1071     cb->callbackName = AVPlayerEvent::EVENT_VIDEO_SIZE_CHANGE;
1072     cb->valueVec.push_back(width);
1073     cb->valueVec.push_back(height);
1074     NapiCallback::CompleteCallback(env_, cb);
1075 }
1076 
OnAudioInterruptCb(const int32_t extra,const Format & infoBody)1077 void AVPlayerCallback::OnAudioInterruptCb(const int32_t extra, const Format &infoBody)
1078 {
1079     (void)extra;
1080     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1081     if (refMap_.find(AVPlayerEvent::EVENT_AUDIO_INTERRUPT) == refMap_.end()) {
1082         MEDIA_LOGW("can not find audio interrupt callback!");
1083         return;
1084     }
1085 
1086     NapiCallback::PropertyInt *cb = new(std::nothrow) NapiCallback::PropertyInt();
1087     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new PropertyInt");
1088 
1089     cb->callback = refMap_.at(AVPlayerEvent::EVENT_AUDIO_INTERRUPT);
1090     cb->callbackName = AVPlayerEvent::EVENT_AUDIO_INTERRUPT;
1091     int32_t eventType = 0;
1092     int32_t forceType = 0;
1093     int32_t hintType = 0;
1094     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_TYPE, eventType);
1095     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_FORCE, forceType);
1096     (void)infoBody.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_HINT, hintType);
1097     MEDIA_LOGI("OnAudioInterruptCb is called, eventType = %{public}d, forceType = %{public}d, hintType = %{public}d",
1098         eventType, forceType, hintType);
1099     // ohos.multimedia.audio.d.ts interface InterruptEvent
1100     cb->valueMap["eventType"] = eventType;
1101     cb->valueMap["forceType"] = forceType;
1102     cb->valueMap["hintType"] = hintType;
1103     NapiCallback::CompleteCallback(env_, cb);
1104 }
1105 
OnBitRateCollectedCb(const int32_t extra,const Format & infoBody)1106 void AVPlayerCallback::OnBitRateCollectedCb(const int32_t extra, const Format &infoBody)
1107 {
1108     (void)extra;
1109     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1110     if (refMap_.find(AVPlayerEvent::EVENT_AVAILABLE_BITRATES) == refMap_.end()) {
1111         MEDIA_LOGW("can not find bitrate collected callback!");
1112         return;
1113     }
1114 
1115     std::vector<int32_t> bitrateVec;
1116     if (infoBody.ContainKey(std::string(PlayerKeys::PLAYER_AVAILABLE_BITRATES))) {
1117         uint8_t *addr = nullptr;
1118         size_t size  = 0;
1119         infoBody.GetBuffer(std::string(PlayerKeys::PLAYER_AVAILABLE_BITRATES), &addr, size);
1120         CHECK_AND_RETURN_LOG(addr != nullptr, "bitrate addr is nullptr");
1121 
1122         MEDIA_LOGI("bitrate size = %{public}zu", size / sizeof(uint32_t));
1123         while (size > 0) {
1124             if (size < sizeof(uint32_t)) {
1125                 break;
1126             }
1127 
1128             uint32_t bitrate = *(static_cast<uint32_t *>(static_cast<void *>(addr)));
1129             MEDIA_LOGI("bitrate = %{public}u", bitrate);
1130             addr += sizeof(uint32_t);
1131             size -= sizeof(uint32_t);
1132             bitrateVec.push_back(static_cast<int32_t>(bitrate));
1133         }
1134     }
1135 
1136     NapiCallback::IntArray *cb = new(std::nothrow) NapiCallback::IntArray();
1137     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntArray");
1138 
1139     cb->callback = refMap_.at(AVPlayerEvent::EVENT_AVAILABLE_BITRATES);
1140     cb->callbackName = AVPlayerEvent::EVENT_AVAILABLE_BITRATES;
1141     cb->valueVec = bitrateVec;
1142     NapiCallback::CompleteCallback(env_, cb);
1143 }
1144 
OnMaxAmplitudeCollectedCb(const int32_t extra,const Format & infoBody)1145 void AVPlayerCallback::OnMaxAmplitudeCollectedCb(const int32_t extra, const Format &infoBody)
1146 {
1147     (void)extra;
1148     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1149     if (refMap_.find(AVPlayerEvent::EVENT_AMPLITUDE_UPDATE) == refMap_.end()) {
1150         MEDIA_LOGD("can not find max amplitude collected callback!");
1151         return;
1152     }
1153 
1154     std::vector<float> MaxAmplitudeVec;
1155     if (infoBody.ContainKey(std::string(PlayerKeys::AUDIO_MAX_AMPLITUDE))) {
1156         uint8_t *addr = nullptr;
1157         size_t size  = 0;
1158         infoBody.GetBuffer(std::string(PlayerKeys::AUDIO_MAX_AMPLITUDE), &addr, size);
1159         CHECK_AND_RETURN_LOG(addr != nullptr, "max amplitude addr is nullptr");
1160 
1161         MEDIA_LOGD("max amplitude size = %{public}zu", size / sizeof(float));
1162         while (size > 0) {
1163             if (size < sizeof(float)) {
1164                 break;
1165             }
1166 
1167             float maxAmplitude = *(static_cast<float *>(static_cast<void *>(addr)));
1168             MEDIA_LOGD("maxAmplitude = %{public}f", maxAmplitude);
1169             addr += sizeof(float);
1170             size -= sizeof(float);
1171             MaxAmplitudeVec.push_back(static_cast<float>(maxAmplitude));
1172         }
1173     }
1174 
1175     NapiCallback::FloatArray *cb = new(std::nothrow) NapiCallback::FloatArray();
1176     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new IntArray");
1177 
1178     cb->callback = refMap_.at(AVPlayerEvent::EVENT_AMPLITUDE_UPDATE);
1179     cb->callbackName = AVPlayerEvent::EVENT_AMPLITUDE_UPDATE;
1180     cb->valueVec = MaxAmplitudeVec;
1181     NapiCallback::CompleteCallback(env_, cb);
1182 }
1183 
SetDrmInfoData(const uint8_t * drmInfoAddr,int32_t infoCount,std::multimap<std::string,std::vector<uint8_t>> & drmInfoMap)1184 int32_t AVPlayerCallback::SetDrmInfoData(const uint8_t *drmInfoAddr, int32_t infoCount,
1185     std::multimap<std::string, std::vector<uint8_t>> &drmInfoMap)
1186 {
1187     DrmInfoItem *drmInfos = reinterpret_cast<DrmInfoItem*>(const_cast<uint8_t *>(drmInfoAddr));
1188     CHECK_AND_RETURN_RET_LOG(drmInfos != nullptr, MSERR_INVALID_VAL, "cast drmInfos nullptr");
1189     for (int32_t i = 0; i < infoCount; i++) {
1190         DrmInfoItem temp = drmInfos[i];
1191         std::stringstream ssConverter;
1192         std::string uuid;
1193         for (uint32_t index = 0; index < DrmConstant::DRM_MAX_M3U8_DRM_UUID_LEN; index++) {
1194             int32_t singleUuid = static_cast<int32_t>(temp.uuid[index]);
1195             ssConverter << std::hex << std::setfill('0') << std::setw(2) << singleUuid; // 2:w
1196             uuid = ssConverter.str();
1197         }
1198         std::vector<uint8_t> pssh(temp.pssh, temp.pssh + temp.psshLen);
1199         drmInfoMap.insert({ uuid, pssh });
1200     }
1201 
1202     if (listener_ != nullptr) {
1203         listener_->NotifyDrmInfoUpdated(drmInfoMap);
1204     }
1205     return MSERR_OK;
1206 }
1207 
OnDrmInfoUpdatedCb(const int32_t extra,const Format & infoBody)1208 void AVPlayerCallback::OnDrmInfoUpdatedCb(const int32_t extra, const Format &infoBody)
1209 {
1210     (void)extra;
1211     MEDIA_LOGI("AVPlayerCallback OnDrmInfoUpdatedCb is called");
1212     if (refMap_.find(AVPlayerEvent::EVENT_DRM_INFO_UPDATE) == refMap_.end()) {
1213         MEDIA_LOGW("can not find drm info updated callback!");
1214         return;
1215     }
1216     if (!infoBody.ContainKey(std::string(PlayerKeys::PLAYER_DRM_INFO_ADDR))) {
1217         MEDIA_LOGW("there's no drminfo-update drm_info_addr key");
1218         return;
1219     }
1220     if (!infoBody.ContainKey(std::string(PlayerKeys::PLAYER_DRM_INFO_COUNT))) {
1221         MEDIA_LOGW("there's no drminfo-update drm_info_count key");
1222         return;
1223     }
1224 
1225     uint8_t *drmInfoAddr = nullptr;
1226     size_t size  = 0;
1227     int32_t infoCount = 0;
1228     infoBody.GetBuffer(std::string(PlayerKeys::PLAYER_DRM_INFO_ADDR), &drmInfoAddr, size);
1229     CHECK_AND_RETURN_LOG(drmInfoAddr != nullptr && size > 0, "get drminfo buffer failed");
1230     infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_DRM_INFO_COUNT), infoCount);
1231     CHECK_AND_RETURN_LOG(infoCount > 0, "get drminfo count is illegal");
1232 
1233     std::multimap<std::string, std::vector<uint8_t>> drmInfoMap;
1234     int32_t ret = SetDrmInfoData(drmInfoAddr, infoCount, drmInfoMap);
1235     CHECK_AND_RETURN_LOG(ret == MSERR_OK, "SetDrmInfoData err");
1236     NapiCallback::ObjectArray *cb = new(std::nothrow) NapiCallback::ObjectArray();
1237     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new ObjectArray");
1238     cb->callback = refMap_.at(AVPlayerEvent::EVENT_DRM_INFO_UPDATE);
1239     cb->callbackName = AVPlayerEvent::EVENT_DRM_INFO_UPDATE;
1240     cb->infoMap = drmInfoMap;
1241     NapiCallback::CompleteCallback(env_, cb);
1242 }
1243 
OnSetDecryptConfigDoneCb(const int32_t extra,const Format & infoBody)1244 void AVPlayerCallback::OnSetDecryptConfigDoneCb(const int32_t extra, const Format &infoBody)
1245 {
1246     (void)extra;
1247     MEDIA_LOGI("AVPlayerCallback OnSetDecryptConfigDoneCb is called");
1248     if (refMap_.find(AVPlayerEvent::EVENT_SET_DECRYPT_CONFIG_DONE) == refMap_.end()) {
1249         MEDIA_LOGW("can not find SetDecryptConfig Done callback!");
1250         return;
1251     }
1252 
1253     NapiCallback::Base *cb = new(std::nothrow) NapiCallback::Base();
1254     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Base");
1255 
1256     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SET_DECRYPT_CONFIG_DONE);
1257     cb->callbackName = AVPlayerEvent::EVENT_SET_DECRYPT_CONFIG_DONE;
1258     NapiCallback::CompleteCallback(env_, cb);
1259 }
1260 
OnSubtitleInfoCb(const int32_t extra,const Format & infoBody)1261 void AVPlayerCallback::OnSubtitleInfoCb(const int32_t extra, const Format &infoBody)
1262 {
1263     (void)infoBody;
1264     int32_t pts = -1;
1265     int32_t duration = -1;
1266     std::string text;
1267     infoBody.GetStringValue(PlayerKeys::SUBTITLE_TEXT, text);
1268     infoBody.GetIntValue(std::string(PlayerKeys::SUBTITLE_PTS), pts);
1269     infoBody.GetIntValue(std::string(PlayerKeys::SUBTITLE_DURATION), duration);
1270     MEDIA_LOGI("OnSubtitleInfoCb pts %{public}d, duration = %{public}d", pts, duration);
1271 
1272     CHECK_AND_RETURN_LOG(refMap_.find(AVPlayerEvent::EVENT_SUBTITLE_UPDATE) != refMap_.end(),
1273         "can not find Subtitle callback!");
1274 
1275     NapiCallback::SubtitleInfo *cb = new(std::nothrow) NapiCallback::SubtitleInfo();
1276     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Subtitle");
1277 
1278     cb->callback = refMap_.at(AVPlayerEvent::EVENT_SUBTITLE_UPDATE);
1279     cb->callbackName = AVPlayerEvent::EVENT_SUBTITLE_UPDATE;
1280     cb->valueMap.text = text;
1281     cb->valueMap.pts = pts;
1282     cb->valueMap.duration = duration;
1283 
1284     NapiCallback::CompleteCallback(env_, cb);
1285 }
1286 
OnEosCb(const int32_t extra,const Format & infoBody)1287 void AVPlayerCallback::OnEosCb(const int32_t extra, const Format &infoBody)
1288 {
1289     (void)infoBody;
1290     CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready");
1291     int32_t isLooping = extra;
1292     MEDIA_LOGI("0x%{public}06" PRIXPTR " OnEndOfStream is called, isloop: %{public}d", FAKE_POINTER(this), isLooping);
1293     if (refMap_.find(AVPlayerEvent::EVENT_END_OF_STREAM) == refMap_.end()) {
1294         MEDIA_LOGW("0x%{public}06" PRIXPTR " can not find EndOfStream callback!", FAKE_POINTER(this));
1295         return;
1296     }
1297 
1298     NapiCallback::Base *cb = new(std::nothrow) NapiCallback::Base();
1299     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new Base");
1300 
1301     cb->callback = refMap_.at(AVPlayerEvent::EVENT_END_OF_STREAM);
1302     cb->callbackName = AVPlayerEvent::EVENT_END_OF_STREAM;
1303     NapiCallback::CompleteCallback(env_, cb);
1304 }
1305 
OnTrackChangedCb(const int32_t extra,const Format & infoBody)1306 void AVPlayerCallback::OnTrackChangedCb(const int32_t extra, const Format &infoBody)
1307 {
1308     (void)extra;
1309     int32_t index = -1;
1310     int32_t isSelect = -1;
1311     infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_TRACK_INDEX), index);
1312     infoBody.GetIntValue(std::string(PlayerKeys::PLAYER_IS_SELECT), isSelect);
1313     MEDIA_LOGI("OnTrackChangedCb index %{public}d, isSelect = %{public}d", index, isSelect);
1314 
1315     CHECK_AND_RETURN_LOG(refMap_.find(AVPlayerEvent::EVENT_TRACKCHANGE) != refMap_.end(),
1316         "can not find trackChange callback!");
1317 
1318     NapiCallback::TrackChange *cb = new(std::nothrow) NapiCallback::TrackChange();
1319     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new TrackChange");
1320 
1321     cb->callback = refMap_.at(AVPlayerEvent::EVENT_TRACKCHANGE);
1322     cb->callbackName = AVPlayerEvent::EVENT_TRACKCHANGE;
1323     cb->number = index;
1324     cb->isSelect = isSelect ? true : false;
1325     NapiCallback::CompleteCallback(env_, cb);
1326 }
1327 
OnTrackInfoUpdate(const int32_t extra,const Format & infoBody)1328 void AVPlayerCallback::OnTrackInfoUpdate(const int32_t extra, const Format &infoBody)
1329 {
1330     (void)extra;
1331     std::vector<Format> trackInfo;
1332     (void)infoBody.GetFormatVector(std::string(PlayerKeys::PLAYER_TRACK_INFO), trackInfo);
1333     MEDIA_LOGI("OnTrackInfoUpdate callback");
1334 
1335     CHECK_AND_RETURN_LOG(refMap_.find(AVPlayerEvent::EVENT_TRACK_INFO_UPDATE) != refMap_.end(),
1336         "can not find trackInfoUpdate callback!");
1337 
1338     NapiCallback::TrackInfoUpdate *cb = new(std::nothrow) NapiCallback::TrackInfoUpdate();
1339     CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new TrackInfoUpdate");
1340 
1341     cb->callback = refMap_.at(AVPlayerEvent::EVENT_TRACK_INFO_UPDATE);
1342     cb->callbackName = AVPlayerEvent::EVENT_TRACK_INFO_UPDATE;
1343     cb->trackInfo = trackInfo;
1344     NapiCallback::CompleteCallback(env_, cb);
1345 }
1346 
SaveCallbackReference(const std::string & name,std::weak_ptr<AutoRef> ref)1347 void AVPlayerCallback::SaveCallbackReference(const std::string &name, std::weak_ptr<AutoRef> ref)
1348 {
1349     std::lock_guard<std::mutex> lock(mutex_);
1350     refMap_[name] = ref;
1351 }
1352 
ClearCallbackReference()1353 void AVPlayerCallback::ClearCallbackReference()
1354 {
1355     std::lock_guard<std::mutex> lock(mutex_);
1356     refMap_.clear();
1357 }
1358 
ClearCallbackReference(const std::string & name)1359 void AVPlayerCallback::ClearCallbackReference(const std::string &name)
1360 {
1361     std::lock_guard<std::mutex> lock(mutex_);
1362     refMap_.erase(name);
1363 }
1364 
Start()1365 void AVPlayerCallback::Start()
1366 {
1367     isloaded_ = true;
1368 }
1369 
Pause()1370 void AVPlayerCallback::Pause()
1371 {
1372     isloaded_ = false;
1373 }
1374 
Release()1375 void AVPlayerCallback::Release()
1376 {
1377     std::lock_guard<std::mutex> lock(mutex_);
1378 
1379     Format infoBody;
1380     AVPlayerCallback::OnStateChangeCb(PlayerStates::PLAYER_RELEASED, infoBody);
1381     listener_ = nullptr;
1382 }
1383 } // namespace Media
1384 } // namespace OHOS
1385