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