1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "system_tone_player_napi.h"
17
18 #include "system_sound_log.h"
19 #include "common_napi.h"
20
21 namespace {
22 /* Constants for array index */
23 const int32_t PARAM0 = 0;
24 const int32_t PARAM1 = 1;
25
26 /* Constants for array size */
27 const int32_t ARGS_ONE = 1;
28 const int32_t ARGS_TWO = 2;
29
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO_NAPI, "SystemTonePlayerNapi"};
31 }
32
33 namespace OHOS {
34 namespace Media {
35 thread_local napi_ref SystemTonePlayerNapi::sConstructor_ = nullptr;
36 std::shared_ptr<SystemTonePlayer> SystemTonePlayerNapi::sSystemTonePlayer_ = nullptr;
37
SystemTonePlayerNapi()38 SystemTonePlayerNapi::SystemTonePlayerNapi() : env_(nullptr) {}
39
40 SystemTonePlayerNapi::~SystemTonePlayerNapi() = default;
41
Init(napi_env env,napi_value exports)42 napi_value SystemTonePlayerNapi::Init(napi_env env, napi_value exports)
43 {
44 napi_status status;
45 napi_value ctorObj;
46 int32_t refCount = 1;
47
48 napi_property_descriptor system_tone_player_prop[] = {
49 DECLARE_NAPI_FUNCTION("getTitle", GetTitle),
50 DECLARE_NAPI_FUNCTION("prepare", Prepare),
51 DECLARE_NAPI_FUNCTION("start", Start),
52 DECLARE_NAPI_FUNCTION("stop", Stop),
53 DECLARE_NAPI_FUNCTION("release", Release),
54 };
55
56 status = napi_define_class(env, SYSTEM_TONE_PLAYER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
57 SystemTonePlayerNapiConstructor, nullptr, sizeof(system_tone_player_prop) / sizeof(system_tone_player_prop[0]),
58 system_tone_player_prop, &ctorObj);
59 if (status == napi_ok) {
60 if (napi_create_reference(env, ctorObj, refCount, &sConstructor_) == napi_ok) {
61 status = napi_set_named_property(env, exports, SYSTEM_TONE_PLAYER_NAPI_CLASS_NAME.c_str(), ctorObj);
62 if (status == napi_ok) {
63 return exports;
64 }
65 }
66 }
67
68 return nullptr;
69 }
70
SystemTonePlayerNapiConstructor(napi_env env,napi_callback_info info)71 napi_value SystemTonePlayerNapi::SystemTonePlayerNapiConstructor(napi_env env, napi_callback_info info)
72 {
73 napi_status status;
74 napi_value result = nullptr;
75 napi_value thisVar = nullptr;
76
77 napi_get_undefined(env, &result);
78 status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
79 if (status == napi_ok && thisVar != nullptr) {
80 std::unique_ptr<SystemTonePlayerNapi> obj = std::make_unique<SystemTonePlayerNapi>();
81 if (obj != nullptr) {
82 ObjectRefMap<SystemTonePlayerNapi>::Insert(obj.get());
83 obj->env_ = env;
84 if (obj->sSystemTonePlayer_ != nullptr) {
85 obj->systemTonePlayer_ = move(obj->sSystemTonePlayer_);
86 } else {
87 MEDIA_LOGE("Failed to create sSystemTonePlayer_ instance.");
88 return result;
89 }
90
91 status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
92 SystemTonePlayerNapi::SystemTonePlayerNapiDestructor, nullptr, nullptr);
93 if (status == napi_ok) {
94 obj.release();
95 return thisVar;
96 } else {
97 ObjectRefMap<SystemTonePlayerNapi>::Erase(obj.get());
98 MEDIA_LOGE("Failed to wrap the native system tone player object with JS.");
99 }
100 }
101 }
102
103 return result;
104 }
105
SystemTonePlayerNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)106 void SystemTonePlayerNapi::SystemTonePlayerNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
107 {
108 SystemTonePlayerNapi *systemTonePlayerHelper = reinterpret_cast<SystemTonePlayerNapi*>(nativeObject);
109 if (systemTonePlayerHelper != nullptr) {
110 ObjectRefMap<SystemTonePlayerNapi>::DecreaseRef(systemTonePlayerHelper);
111 }
112 }
113
GetSystemTonePlayerInstance(napi_env env,std::shared_ptr<SystemTonePlayer> & systemTonePlayer)114 napi_value SystemTonePlayerNapi::GetSystemTonePlayerInstance(napi_env env,
115 std::shared_ptr<SystemTonePlayer> &systemTonePlayer)
116 {
117 napi_status status;
118 napi_value result = nullptr;
119 napi_value ctor;
120
121 status = napi_get_reference_value(env, sConstructor_, &ctor);
122 if (status == napi_ok) {
123 sSystemTonePlayer_ = systemTonePlayer;
124 status = napi_new_instance(env, ctor, 0, nullptr, &result);
125 if (status == napi_ok) {
126 return result;
127 } else {
128 MEDIA_LOGE("GetSystemTonePlayerInstance: New instance could not be obtained.");
129 }
130 }
131
132 napi_get_undefined(env, &result);
133 return result;
134 }
135
CommonAsyncCallbackComplete(napi_env env,napi_status status,void * data)136 void SystemTonePlayerNapi::CommonAsyncCallbackComplete(napi_env env, napi_status status, void* data)
137 {
138 auto context = static_cast<SystemTonePlayerAsyncContext *>(data);
139 napi_value callback = nullptr;
140 napi_value retVal = nullptr;
141 napi_value result[2] = {};
142
143 napi_get_undefined(env, &result[PARAM1]);
144 if (!context->status) {
145 napi_get_undefined(env, &result[PARAM0]);
146 } else {
147 napi_value message = nullptr;
148 napi_create_string_utf8(env, "Error: Operation is not supported or failed", NAPI_AUTO_LENGTH, &message);
149 napi_create_error(env, nullptr, message, &result[PARAM0]);
150 }
151
152 if (context->deferred) {
153 if (!context->status) {
154 napi_resolve_deferred(env, context->deferred, result[PARAM1]);
155 } else {
156 napi_reject_deferred(env, context->deferred, result[PARAM0]);
157 }
158 } else {
159 napi_get_reference_value(env, context->callbackRef, &callback);
160 napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
161 napi_delete_reference(env, context->callbackRef);
162 }
163 napi_delete_async_work(env, context->work);
164
165 delete context;
166 context = nullptr;
167 }
168
GetTitleAsyncCallbackComplete(napi_env env,napi_status status,void * data)169 void SystemTonePlayerNapi::GetTitleAsyncCallbackComplete(napi_env env, napi_status status, void *data)
170 {
171 auto context = static_cast<SystemTonePlayerAsyncContext *>(data);
172 napi_value getTitleCallback = nullptr;
173 napi_value retVal = nullptr;
174 napi_value result[2] = {};
175
176 if (!context->status) {
177 napi_get_undefined(env, &result[PARAM0]);
178 napi_create_string_utf8(env, context->title.c_str(), NAPI_AUTO_LENGTH, &result[PARAM1]);
179 } else {
180 napi_value message = nullptr;
181 napi_create_string_utf8(env, "GetTitle Error: Operation is not supported or failed",
182 NAPI_AUTO_LENGTH, &message);
183 napi_create_error(env, nullptr, message, &result[PARAM0]);
184 napi_get_undefined(env, &result[PARAM1]);
185 }
186
187 if (context->deferred) {
188 if (!context->status) {
189 napi_resolve_deferred(env, context->deferred, result[PARAM1]);
190 } else {
191 napi_reject_deferred(env, context->deferred, result[PARAM0]);
192 }
193 } else {
194 napi_get_reference_value(env, context->callbackRef, &getTitleCallback);
195 napi_call_function(env, nullptr, getTitleCallback, ARGS_TWO, result, &retVal);
196 napi_delete_reference(env, context->callbackRef);
197 }
198 napi_delete_async_work(env, context->work);
199
200 delete context;
201 context = nullptr;
202 }
203
GetTitle(napi_env env,napi_callback_info info)204 napi_value SystemTonePlayerNapi::GetTitle(napi_env env, napi_callback_info info)
205 {
206 napi_value result = nullptr;
207 napi_value resource = nullptr;
208 size_t argc = ARGS_ONE;
209 napi_value argv[ARGS_ONE] = {0};
210 napi_value thisVar = nullptr;
211 const int32_t refCount = 1;
212
213 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
214 napi_get_undefined(env, &result);
215 CHECK_AND_RETURN_RET_LOG(status == napi_ok && thisVar != nullptr, result, "GetTitle: napi_get_cb_info failed");
216
217 NAPI_ASSERT(env, argc <= ARGS_ONE, "GetTitle: requires 1 parameter maximum");
218 std::unique_ptr<SystemTonePlayerAsyncContext> asyncContext = std::make_unique<SystemTonePlayerAsyncContext>();
219 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
220 if (status == napi_ok && asyncContext->objectInfo != nullptr) {
221 if (argc == ARGS_ONE) {
222 napi_valuetype valueType = napi_undefined;
223 napi_typeof(env, argv[PARAM0], &valueType);
224 CHECK_AND_RETURN_RET_LOG(valueType == napi_function, result,
225 "GetTitle: the param type is not napi_function");
226 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
227 } else {
228 napi_create_promise(env, &asyncContext->deferred, &result);
229 }
230
231 napi_create_string_utf8(env, "GetTitle", NAPI_AUTO_LENGTH, &resource);
232 status = napi_create_async_work(env, nullptr, resource,
233 [](napi_env env, void *data) {
234 SystemTonePlayerAsyncContext *context = static_cast<SystemTonePlayerAsyncContext *>(data);
235 auto obj = reinterpret_cast<SystemTonePlayerNapi*>(context->objectInfo);
236 ObjectRefMap objectGuard(obj);
237 auto *napiSystemTonePlayer = objectGuard.GetPtr();
238 if (napiSystemTonePlayer == nullptr || napiSystemTonePlayer->systemTonePlayer_ == nullptr) {
239 MEDIA_LOGE("The system tone player is nullptr!");
240 context->status = MSERR_INVALID_STATE;
241 return;
242 }
243 context->title = napiSystemTonePlayer->systemTonePlayer_->GetTitle();
244 context->status = MSERR_OK;
245 },
246 GetTitleAsyncCallbackComplete, static_cast<void *>(asyncContext.get()), &asyncContext->work);
247 if (status != napi_ok) {
248 MEDIA_LOGE("GetTitle: Failed to get create async work");
249 napi_get_undefined(env, &result);
250 } else {
251 napi_queue_async_work(env, asyncContext->work);
252 asyncContext.release();
253 }
254 }
255
256 return result;
257 }
258
Prepare(napi_env env,napi_callback_info info)259 napi_value SystemTonePlayerNapi::Prepare(napi_env env, napi_callback_info info)
260 {
261 napi_status status;
262 napi_value result = nullptr;
263 napi_value resource = nullptr;
264 size_t argc = ARGS_ONE;
265 napi_value argv[ARGS_ONE] = {0};
266 napi_value thisVar = nullptr;
267 const int32_t refCount = 1;
268
269 status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
270 napi_get_undefined(env, &result);
271 CHECK_AND_RETURN_RET_LOG(status == napi_ok && thisVar != nullptr, result,
272 "Prepare: Failed to retrieve details about the callback");
273
274 NAPI_ASSERT(env, argc <= ARGS_ONE, "Prepare: requires 1 parameter maximum");
275 std::unique_ptr<SystemTonePlayerAsyncContext> asyncContext = std::make_unique<SystemTonePlayerAsyncContext>();
276 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
277 if (status == napi_ok && asyncContext->objectInfo != nullptr) {
278 if (argc == ARGS_ONE) {
279 napi_valuetype valueType = napi_undefined;
280 napi_typeof(env, argv[PARAM0], &valueType);
281 CHECK_AND_RETURN_RET_LOG(valueType == napi_function, result,
282 "Prepare: the param type is not napi_function");
283 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
284 } else {
285 napi_create_promise(env, &asyncContext->deferred, &result);
286 }
287
288 napi_create_string_utf8(env, "Prepare", NAPI_AUTO_LENGTH, &resource);
289 status = napi_create_async_work(env, nullptr, resource,
290 [](napi_env env, void* data) {
291 SystemTonePlayerAsyncContext *context = static_cast<SystemTonePlayerAsyncContext *>(data);
292 auto obj = reinterpret_cast<SystemTonePlayerNapi *>(context->objectInfo);
293 ObjectRefMap objectGuard(obj);
294 auto *napiSystemTonePlayer = objectGuard.GetPtr();
295 if (napiSystemTonePlayer == nullptr || napiSystemTonePlayer->systemTonePlayer_ == nullptr) {
296 MEDIA_LOGE("The system tone player is nullptr!");
297 context->status = MSERR_INVALID_STATE;
298 return;
299 }
300 context->status = napiSystemTonePlayer->systemTonePlayer_->Prepare();
301 },
302 CommonAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
303 if (status != napi_ok) {
304 MEDIA_LOGE("Prepare: Failed to get create async work");
305 napi_get_undefined(env, &result);
306 } else {
307 napi_queue_async_work(env, asyncContext->work);
308 asyncContext.release();
309 }
310 }
311
312 return result;
313 }
314
StartAsyncCallbackComplete(napi_env env,napi_status status,void * data)315 void SystemTonePlayerNapi::StartAsyncCallbackComplete(napi_env env, napi_status status, void *data)
316 {
317 auto context = static_cast<SystemTonePlayerAsyncContext *>(data);
318 napi_value getTitleCallback = nullptr;
319 napi_value retVal = nullptr;
320 napi_value result[2] = {};
321
322 if (!context->status) {
323 napi_get_undefined(env, &result[PARAM0]);
324 napi_create_int32(env, context->streamID, &result[PARAM1]);
325 } else {
326 napi_value message = nullptr;
327 napi_create_string_utf8(env, "GetTitle Error: Operation is not supported or failed",
328 NAPI_AUTO_LENGTH, &message);
329 napi_create_error(env, nullptr, message, &result[PARAM0]);
330 napi_get_undefined(env, &result[PARAM1]);
331 }
332
333 if (context->deferred) {
334 if (!context->status) {
335 napi_resolve_deferred(env, context->deferred, result[PARAM1]);
336 } else {
337 napi_reject_deferred(env, context->deferred, result[PARAM0]);
338 }
339 } else {
340 napi_get_reference_value(env, context->callbackRef, &getTitleCallback);
341 napi_call_function(env, nullptr, getTitleCallback, ARGS_TWO, result, &retVal);
342 napi_delete_reference(env, context->callbackRef);
343 }
344 napi_delete_async_work(env, context->work);
345
346 delete context;
347 context = nullptr;
348 }
349
Start(napi_env env,napi_callback_info info)350 napi_value SystemTonePlayerNapi::Start(napi_env env, napi_callback_info info)
351 {
352 napi_value result = nullptr;
353 napi_value resource = nullptr;
354 napi_value property = nullptr;
355 size_t argc = ARGS_ONE;
356 napi_value argv[ARGS_TWO] = {0};
357 napi_value thisVar = nullptr;
358 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
359 napi_get_undefined(env, &result);
360 CHECK_AND_RETURN_RET_LOG(status == napi_ok && thisVar != nullptr, result, "Start: napi_get_cb_info failed");
361 NAPI_ASSERT(env, argc <= ARGS_TWO, "Start: requires 2 parameter maximum");
362
363 std::unique_ptr<SystemTonePlayerAsyncContext> asyncContext = std::make_unique<SystemTonePlayerAsyncContext>();
364 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
365 CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
366 "Start: napi_unwrap failed or objectInfo is nullptr.");
367
368 if (argc == 0) {
369 napi_create_promise(env, &asyncContext->deferred, &result);
370 }
371 for (size_t i = PARAM0; i < argc; i++) {
372 napi_valuetype valueType = napi_undefined;
373 napi_typeof(env, argv[i], &valueType);
374 if (i == PARAM0 && valueType == napi_object) {
375 if (napi_get_named_property(env, argv[PARAM0], "muteAudio", &property) == napi_ok) {
376 napi_get_value_bool(env, property, &(asyncContext->systemToneOptions.muteAudio));
377 }
378 if (napi_get_named_property(env, argv[PARAM0], "muteHaptics", &property) == napi_ok) {
379 napi_get_value_bool(env, property, &(asyncContext->systemToneOptions.muteHaptics));
380 }
381 if (argc == ARGS_ONE) {
382 napi_create_promise(env, &asyncContext->deferred, &result);
383 }
384 } else if ((i == PARAM0 || i == PARAM1) && valueType == napi_function) {
385 napi_create_reference(env, argv[PARAM0], 1, &asyncContext->callbackRef);
386 } else {
387 NAPI_ASSERT(env, false, "Start: type mismatch");
388 }
389 }
390
391 napi_create_string_utf8(env, "Start", NAPI_AUTO_LENGTH, &resource);
392 status = napi_create_async_work(env, nullptr, resource, AsyncStart,
393 StartAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
394 if (status != napi_ok) {
395 napi_get_undefined(env, &result);
396 } else {
397 napi_queue_async_work(env, asyncContext->work);
398 asyncContext.release();
399 }
400 return result;
401 }
402
AsyncStart(napi_env env,void * data)403 void SystemTonePlayerNapi::AsyncStart(napi_env env, void *data)
404 {
405 SystemTonePlayerAsyncContext *context = static_cast<SystemTonePlayerAsyncContext *>(data);
406 auto obj = reinterpret_cast<SystemTonePlayerNapi *>(context->objectInfo);
407 ObjectRefMap objectGuard(obj);
408 auto *napiSystemTonePlayer = objectGuard.GetPtr();
409 if (napiSystemTonePlayer == nullptr || napiSystemTonePlayer->systemTonePlayer_ == nullptr) {
410 MEDIA_LOGE("The system tone player is nullptr!");
411 context->status = MSERR_INVALID_STATE;
412 return;
413 }
414 context->streamID = napiSystemTonePlayer->systemTonePlayer_->Start(context->systemToneOptions);
415 context->status = MSERR_OK;
416 }
417
Stop(napi_env env,napi_callback_info info)418 napi_value SystemTonePlayerNapi::Stop(napi_env env, napi_callback_info info)
419 {
420 napi_status status;
421 napi_value result = nullptr;
422 napi_value resource = nullptr;
423 size_t argc = ARGS_ONE;
424 napi_value argv[ARGS_TWO] = {0};
425 napi_value thisVar = nullptr;
426 const int32_t refCount = 1;
427
428 status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
429 napi_get_undefined(env, &result);
430 if (status != napi_ok || thisVar == nullptr) {
431 MEDIA_LOGE("Stop: Failed to retrieve details about the callback");
432 return result;
433 }
434
435 NAPI_ASSERT(env, argc == ARGS_ONE || argc == ARGS_TWO, "Stop: requires 1 or 2 parameter");
436 std::unique_ptr<SystemTonePlayerAsyncContext> asyncContext = std::make_unique<SystemTonePlayerAsyncContext>();
437 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
438 if (status == napi_ok && asyncContext->objectInfo != nullptr) {
439 napi_valuetype valueType = napi_undefined;
440 napi_typeof(env, argv[PARAM0], &valueType);
441 if (valueType == napi_number) {
442 napi_get_value_int32(env, argv[PARAM0], &(asyncContext->streamID));
443 napi_create_promise(env, &asyncContext->deferred, &result);
444 } else {
445 NAPI_ASSERT(env, false, "Stop: type mismatch");
446 }
447 if (argc == ARGS_TWO) {
448 napi_typeof(env, argv[PARAM1], &valueType);
449 CHECK_AND_RETURN_RET_LOG(valueType == napi_function, result, "Stop: the param type is not napi_function");
450 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
451 } else {
452 napi_create_promise(env, &asyncContext->deferred, &result);
453 }
454
455 napi_create_string_utf8(env, "Stop", NAPI_AUTO_LENGTH, &resource);
456 status = napi_create_async_work(env, nullptr, resource, AsyncStop,
457 CommonAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
458 if (status != napi_ok) {
459 MEDIA_LOGE("Stop: Failed to get create async work");
460 napi_get_undefined(env, &result);
461 } else {
462 napi_queue_async_work(env, asyncContext->work);
463 asyncContext.release();
464 }
465 }
466
467 return result;
468 }
469
AsyncStop(napi_env env,void * data)470 void SystemTonePlayerNapi::AsyncStop(napi_env env, void *data)
471 {
472 SystemTonePlayerAsyncContext *context = static_cast<SystemTonePlayerAsyncContext *>(data);
473 auto obj = reinterpret_cast<SystemTonePlayerNapi *>(context->objectInfo);
474 ObjectRefMap objectGuard(obj);
475 auto *napiSystemTonePlayer = objectGuard.GetPtr();
476 if (napiSystemTonePlayer == nullptr || napiSystemTonePlayer->systemTonePlayer_ == nullptr) {
477 MEDIA_LOGE("The system tone player is nullptr!");
478 context->status = MSERR_INVALID_STATE;
479 return;
480 }
481 context->status = napiSystemTonePlayer->systemTonePlayer_->Stop(context->streamID);
482 }
483
Release(napi_env env,napi_callback_info info)484 napi_value SystemTonePlayerNapi::Release(napi_env env, napi_callback_info info)
485 {
486 napi_status status;
487 napi_value result = nullptr;
488 napi_value resource = nullptr;
489 size_t argc = ARGS_ONE;
490 napi_value argv[ARGS_ONE] = {0};
491 napi_value thisVar = nullptr;
492 const int32_t refCount = 1;
493
494 status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
495 napi_get_undefined(env, &result);
496 if (status != napi_ok || thisVar == nullptr) {
497 MEDIA_LOGE("Release: Failed to retrieve details about the callback");
498 return result;
499 }
500
501 NAPI_ASSERT(env, argc <= ARGS_ONE, "Release: requires 1 parameter maximum");
502 std::unique_ptr<SystemTonePlayerAsyncContext> asyncContext = std::make_unique<SystemTonePlayerAsyncContext>();
503 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
504 if (status == napi_ok && asyncContext->objectInfo != nullptr) {
505 if (argc == ARGS_ONE) {
506 napi_valuetype valueType = napi_undefined;
507 napi_typeof(env, argv[PARAM0], &valueType);
508 CHECK_AND_RETURN_RET_LOG(valueType == napi_function, result,
509 "Release: the param type is not napi_function");
510 napi_create_reference(env, argv[PARAM0], refCount, &asyncContext->callbackRef);
511 } else {
512 napi_create_promise(env, &asyncContext->deferred, &result);
513 }
514
515 napi_create_string_utf8(env, "Release", NAPI_AUTO_LENGTH, &resource);
516 status = napi_create_async_work(env, nullptr, resource, AsyncRelease,
517 CommonAsyncCallbackComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
518 if (status != napi_ok) {
519 MEDIA_LOGE("Release: Failed to get create async work");
520 napi_get_undefined(env, &result);
521 } else {
522 napi_queue_async_work(env, asyncContext->work);
523 asyncContext.release();
524 }
525 }
526
527 return result;
528 }
529
AsyncRelease(napi_env env,void * data)530 void SystemTonePlayerNapi::AsyncRelease(napi_env env, void *data)
531 {
532 SystemTonePlayerAsyncContext *context = static_cast<SystemTonePlayerAsyncContext *>(data);
533 auto obj = reinterpret_cast<SystemTonePlayerNapi *>(context->objectInfo);
534 ObjectRefMap objectGuard(obj);
535 auto *napiSystemTonePlayer = objectGuard.GetPtr();
536 if (napiSystemTonePlayer == nullptr || napiSystemTonePlayer->systemTonePlayer_ == nullptr) {
537 MEDIA_LOGE("The system tone player is nullptr!");
538 context->status = MSERR_INVALID_STATE;
539 return;
540 }
541 context->status = napiSystemTonePlayer->systemTonePlayer_->Release();
542 }
543 } // namespace Media
544 } // namespace OHOS