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