• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "system_sound_manager_napi.h"
17 #include "hilog/log.h"
18 
19 using namespace std;
20 using OHOS::HiviewDFX::HiLog;
21 using OHOS::HiviewDFX::HiLogLabel;
22 
23 namespace {
24     /* Constants for array index */
25     const int32_t PARAM0 = 0;
26     const int32_t PARAM1 = 1;
27     const int32_t PARAM2 = 2;
28     const int32_t PARAM3 = 3;
29 
30     /* Constants for array size */
31     const int32_t ARGS_ONE = 1;
32     const int32_t ARGS_TWO = 2;
33     const int32_t ARGS_THREE = 3;
34     const int32_t ARGS_FOUR = 4;
35     const int32_t SIZE = 100;
36 
37     const int ERROR = -1;
38     const int SUCCESS = 0;
39 
40     constexpr HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "SystemSoundManagerNapi"};
41 }
42 
43 namespace OHOS {
44 namespace AudioStandard {
45 napi_ref SystemSoundManagerNapi::sConstructor_ = nullptr;
46 napi_ref SystemSoundManagerNapi::ringtoneType_ = nullptr;
47 
SystemSoundManagerNapi()48 SystemSoundManagerNapi::SystemSoundManagerNapi()
49     : env_(nullptr), wrapper_(nullptr), sysSoundMgrClient_(nullptr) {}
50 
~SystemSoundManagerNapi()51 SystemSoundManagerNapi::~SystemSoundManagerNapi()
52 {
53     if (wrapper_ != nullptr) {
54         napi_delete_reference(env_, wrapper_);
55     }
56 }
57 
AddNamedProperty(napi_env env,napi_value object,const std::string name,int32_t enumValue)58 napi_status SystemSoundManagerNapi::AddNamedProperty(napi_env env, napi_value object,
59                                                      const std::string name, int32_t enumValue)
60 {
61     napi_status status;
62     napi_value enumNapiValue;
63 
64     status = napi_create_int32(env, enumValue, &enumNapiValue);
65     if (status == napi_ok) {
66         status = napi_set_named_property(env, object, name.c_str(), enumNapiValue);
67     }
68 
69     return status;
70 }
71 
CreateRingtoneTypeObject(napi_env env)72 napi_value SystemSoundManagerNapi::CreateRingtoneTypeObject(napi_env env)
73 {
74     napi_value result = nullptr;
75     napi_status status;
76     std::string propName;
77     int32_t refCount = 1;
78 
79     status = napi_create_object(env, &result);
80     if (status == napi_ok) {
81         for (auto &iter: ringtoneTypeMap) {
82             propName = iter.first;
83             status = AddNamedProperty(env, result, propName, iter.second);
84             if (status != napi_ok) {
85                 HiLog::Error(LABEL, "Failed to add named prop!");
86                 break;
87             }
88             propName.clear();
89         }
90         if (status == napi_ok) {
91             status = napi_create_reference(env, result, refCount, &ringtoneType_);
92             if (status == napi_ok) {
93                 return result;
94             }
95         }
96     }
97     napi_get_undefined(env, &result);
98 
99     return result;
100 }
101 
Init(napi_env env,napi_value exports)102 napi_value SystemSoundManagerNapi::Init(napi_env env, napi_value exports)
103 {
104     napi_status status;
105     napi_value ctorObj;
106     int32_t refCount = 1;
107 
108     napi_property_descriptor syssndmgr_prop[] = {
109         DECLARE_NAPI_FUNCTION("setSystemRingtoneUri", SetSystemRingtoneUri),
110         DECLARE_NAPI_FUNCTION("getSystemRingtoneUri", GetSystemRingtoneUri),
111         DECLARE_NAPI_FUNCTION("getSystemRingtonePlayer", GetSystemRingtonePlayer),
112         DECLARE_NAPI_FUNCTION("setSystemNotificationUri", SetSystemNotificationUri),
113         DECLARE_NAPI_FUNCTION("getSystemNotificationUri", GetSystemNotificationUri),
114         DECLARE_NAPI_FUNCTION("setSystemAlarmUri", SetSystemAlarmUri),
115         DECLARE_NAPI_FUNCTION("getSystemAlarmUri", GetSystemAlarmUri)
116     };
117 
118     napi_property_descriptor static_prop[] = {
119         DECLARE_NAPI_STATIC_FUNCTION("getSystemSoundManager", GetSystemSoundManager),
120         DECLARE_NAPI_PROPERTY("RingtoneType", CreateRingtoneTypeObject(env))
121     };
122 
123     status = napi_define_class(env, SYSTEM_SND_MNGR_NAPI_CLASS_NAME.c_str(),
124         NAPI_AUTO_LENGTH, Construct, nullptr, sizeof(syssndmgr_prop) / sizeof(syssndmgr_prop[0]),
125         syssndmgr_prop, &ctorObj);
126     if (status == napi_ok) {
127         if (napi_create_reference(env, ctorObj, refCount, &sConstructor_) == napi_ok) {
128             if (napi_set_named_property(env, exports,
129                 SYSTEM_SND_MNGR_NAPI_CLASS_NAME.c_str(), ctorObj) == napi_ok &&
130                 napi_define_properties(env, exports, sizeof(static_prop) / sizeof
131                 (static_prop[0]), static_prop) == napi_ok) {
132                     return exports;
133             }
134         }
135     }
136 
137     return nullptr;
138 }
139 
GetAbilityContext(napi_env env,napi_value contextArg)140 shared_ptr<AbilityRuntime::Context> SystemSoundManagerNapi::GetAbilityContext(napi_env env, napi_value contextArg)
141 {
142     HiLog::Error(LABEL, "GetAbilityContext");
143     bool stageMode = false;
144 
145     napi_status status = AbilityRuntime::IsStageContext(env, contextArg, stageMode);
146     if (status == napi_ok && stageMode) {
147         HiLog::Info(LABEL, "Getting context with stage model");
148         auto context = AbilityRuntime::GetStageModeContext(env, contextArg);
149         if (context == nullptr) {
150             HiLog::Error(LABEL, "Failed to obtain ability in STAGE mode");
151             return nullptr;
152         }
153 
154         return context;
155     } else {
156         HiLog::Info(LABEL, "Getting context with FA model");
157         auto ability = AbilityRuntime::GetCurrentAbility(env);
158         if (ability == nullptr) {
159             HiLog::Error(LABEL, "Failed to obtain ability in FA mode");
160             return nullptr;
161         }
162 
163         auto faContext = ability->GetAbilityContext();
164         if (faContext == nullptr) {
165             HiLog::Error(LABEL, "GetAbilityContext returned null in FA model");
166             return nullptr;
167         }
168 
169         return faContext;
170     }
171 }
172 
Construct(napi_env env,napi_callback_info info)173 napi_value SystemSoundManagerNapi::Construct(napi_env env, napi_callback_info info)
174 {
175     napi_status status;
176     napi_value result = nullptr;
177     napi_value thisVar = nullptr;
178 
179     napi_get_undefined(env, &result);
180     status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
181     if (status == napi_ok && thisVar != nullptr) {
182         std::unique_ptr<SystemSoundManagerNapi> obj = std::make_unique<SystemSoundManagerNapi>();
183         if (obj != nullptr) {
184             obj->env_ = env;
185             obj->sysSoundMgrClient_ = RingtoneFactory::CreateRingtoneManager();
186             if (obj->sysSoundMgrClient_ == nullptr) {
187                 HiLog::Error(LABEL, "Failed to create sysSoundMgrClient_ instance.");
188                 return result;
189             }
190 
191             status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
192                                SystemSoundManagerNapi::Destructor, nullptr, &(obj->wrapper_));
193             if (status == napi_ok) {
194                 obj.release();
195                 return thisVar;
196             } else {
197                 HiLog::Error(LABEL, "Failed to wrap the native syssndmngr object with JS.");
198             }
199         }
200     }
201 
202     return result;
203 }
204 
Destructor(napi_env env,void * nativeObject,void * finalize_hint)205 void SystemSoundManagerNapi::Destructor(napi_env env, void* nativeObject, void* finalize_hint)
206 {
207     SystemSoundManagerNapi *systemSoundManagerhelper = reinterpret_cast<SystemSoundManagerNapi*>(nativeObject);
208     if (systemSoundManagerhelper != nullptr) {
209         systemSoundManagerhelper->~SystemSoundManagerNapi();
210     }
211 }
212 
GetSystemSoundManager(napi_env env,napi_callback_info info)213 napi_value SystemSoundManagerNapi::GetSystemSoundManager(napi_env env, napi_callback_info info)
214 {
215     napi_status status;
216     napi_value result = nullptr;
217     napi_value ctor;
218 
219     status = napi_get_reference_value(env, sConstructor_, &ctor);
220     if (status == napi_ok) {
221         status = napi_new_instance(env, ctor, 0, nullptr, &result);
222         if (status == napi_ok) {
223             return result;
224         } else {
225             HiLog::Error(LABEL, "New instance could not be obtained.");
226         }
227     }
228 
229     napi_get_undefined(env, &result);
230     return result;
231 }
232 
SetSysRngUriAsyncCallbackComp(napi_env env,napi_status status,void * data)233 static void SetSysRngUriAsyncCallbackComp(napi_env env, napi_status status, void* data)
234 {
235     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
236     napi_value callback = nullptr;
237     napi_value retVal = nullptr;
238     napi_value result[2] = {};
239 
240     napi_get_undefined(env, &result[PARAM1]);
241     if (!context->status) {
242         napi_get_undefined(env, &result[PARAM0]);
243     } else {
244         napi_value message = nullptr;
245         napi_create_string_utf8(env, "Error, Operation not supported or Failed", NAPI_AUTO_LENGTH, &message);
246         napi_create_error(env, nullptr, message, &result[PARAM0]);
247     }
248 
249     if (context->deferred) {
250         if (!context->status) {
251             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
252         } else {
253             napi_reject_deferred(env, context->deferred, result[PARAM0]);
254         }
255     } else {
256         napi_get_reference_value(env, context->callbackRef, &callback);
257         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
258         napi_delete_reference(env, context->callbackRef);
259     }
260     napi_delete_async_work(env, context->work);
261 
262     delete context;
263     context = nullptr;
264 }
265 
SetSystemRingtoneUri(napi_env env,napi_callback_info info)266 napi_value SystemSoundManagerNapi::SetSystemRingtoneUri(napi_env env, napi_callback_info info)
267 {
268     napi_status status;
269     napi_value result = nullptr;
270     napi_value resource = nullptr;
271     size_t argc = ARGS_FOUR;
272     napi_value argv[ARGS_FOUR] = {0};
273     char buffer[SIZE];
274     napi_value thisVar = nullptr;
275     const int32_t refCount = 1;
276     size_t res = 0;
277 
278     status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
279     napi_get_undefined(env, &result);
280     if (status != napi_ok || thisVar == nullptr) {
281         HiLog::Error(LABEL, "Failed to retrieve details about the callback");
282         return result;
283     }
284 
285     NAPI_ASSERT(env, (argc == ARGS_THREE || argc == ARGS_FOUR), "requires 4 parameters maximum");
286     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
287     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
288     if (status != napi_ok || asyncContext->objectInfo == nullptr) {
289         HiLog::Error(LABEL, "Failed to unwrap object");
290         return result;
291     }
292 
293     for (size_t i = PARAM0; i < argc; i++) {
294         napi_valuetype valueType = napi_undefined;
295         napi_typeof(env, argv[i], &valueType);
296         if (i == PARAM0) {
297             asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
298         } else if (i == PARAM1 && valueType == napi_string) {
299             napi_get_value_string_utf8(env, argv[i], buffer, SIZE, &res);
300             asyncContext->uri = std::string(buffer);
301         } else if (i == PARAM2 && valueType == napi_number) {
302             napi_get_value_int32(env, argv[i], &asyncContext->ringtoneType);
303         } else if (i == PARAM3 && valueType == napi_function) {
304             napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
305             break;
306         } else {
307             if ((i == PARAM1) && (valueType == napi_null)) {
308                 HiLog::Error(LABEL, "string value type is null");
309                 continue;
310             }
311             NAPI_ASSERT(env, false, "type mismatch");
312         }
313     }
314 
315     if (asyncContext->callbackRef == nullptr) {
316         napi_create_promise(env, &asyncContext->deferred, &result);
317     }
318 
319     napi_create_string_utf8(env, "SetSystemRingtoneUri", NAPI_AUTO_LENGTH, &resource);
320     status = napi_create_async_work(env, nullptr, resource,
321         [](napi_env env, void* data) {
322             SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
323             if (context->uri.empty()) {
324                 context->status = ERROR;
325             } else {
326                 context->status = context->objectInfo->sysSoundMgrClient_->SetSystemRingtoneUri(
327                     context->abilityContext_, context->uri,
328                     static_cast<RingtoneType>(context->ringtoneType));
329             }
330         },
331         SetSysRngUriAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
332     if (status != napi_ok) {
333         HiLog::Error(LABEL, "Failed to get create async work");
334         napi_get_undefined(env, &result);
335     } else {
336         napi_queue_async_work(env, asyncContext->work);
337         asyncContext.release();
338     }
339 
340     return result;
341 }
342 
GetSysRngUriAsyncCallbackComp(napi_env env,napi_status status,void * data)343 static void GetSysRngUriAsyncCallbackComp(napi_env env, napi_status status, void* data)
344 {
345     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
346     napi_value callback = nullptr;
347     napi_value retVal = nullptr;
348     napi_value result[2] = {};
349 
350     if (!context->status) {
351         napi_get_undefined(env, &result[PARAM0]);
352         napi_create_string_utf8(env, context->uri.c_str(), NAPI_AUTO_LENGTH, &result[PARAM1]);
353     } else {
354         napi_value message = nullptr;
355         napi_create_string_utf8(env, "Error, Operation not supported or Failed", NAPI_AUTO_LENGTH, &message);
356         napi_create_error(env, nullptr, message, &result[PARAM0]);
357         napi_get_undefined(env, &result[PARAM1]);
358     }
359 
360     if (context->deferred) {
361         if (!context->status) {
362             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
363         } else {
364             napi_reject_deferred(env, context->deferred, result[PARAM0]);
365         }
366     } else {
367         napi_get_reference_value(env, context->callbackRef, &callback);
368         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
369         napi_delete_reference(env, context->callbackRef);
370     }
371     napi_delete_async_work(env, context->work);
372 
373     delete context;
374     context = nullptr;
375 }
376 
GetSystemRingtoneUri(napi_env env,napi_callback_info info)377 napi_value SystemSoundManagerNapi::GetSystemRingtoneUri(napi_env env, napi_callback_info info)
378 {
379     napi_status status;
380     napi_value result = nullptr;
381     napi_value resource = nullptr;
382     size_t argc = ARGS_THREE;
383     napi_value argv[ARGS_THREE] = {0};
384     napi_value thisVar = nullptr;
385     const int32_t refCount = 1;
386 
387     status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
388     napi_get_undefined(env, &result);
389     if (status != napi_ok || thisVar == nullptr) {
390         HiLog::Error(LABEL, "Failed to retrieve details about the callback");
391         return result;
392     }
393 
394     NAPI_ASSERT(env, (argc == ARGS_TWO || argc == ARGS_THREE), "requires 3 parameters maximum");
395     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext
396         = std::make_unique<SystemSoundManagerAsyncContext>();
397     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
398     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
399         for (size_t i = PARAM0; i < argc; i++) {
400             napi_valuetype valueType = napi_undefined;
401             napi_typeof(env, argv[i], &valueType);
402             if (i == PARAM0) {
403                 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
404             } else if (i == PARAM1 && valueType == napi_number) {
405                 napi_get_value_int32(env, argv[i], &asyncContext->ringtoneType);
406             } else if (i == PARAM2 && valueType == napi_function) {
407                 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
408                 break;
409             } else {
410                 NAPI_ASSERT(env, false, "type mismatch");
411             }
412         }
413 
414         if (asyncContext->callbackRef == nullptr) {
415             napi_create_promise(env, &asyncContext->deferred, &result);
416         }
417 
418         napi_create_string_utf8(env, "GetSystemRingtoneUri", NAPI_AUTO_LENGTH, &resource);
419         status = napi_create_async_work(env, nullptr, resource,
420             [](napi_env env, void* data) {
421                 SystemSoundManagerAsyncContext *context
422                     = static_cast<SystemSoundManagerAsyncContext *>(data);
423                 context->uri = context->objectInfo->sysSoundMgrClient_->GetSystemRingtoneUri(
424                     context->abilityContext_, static_cast<RingtoneType>(context->ringtoneType));
425                 context->status = SUCCESS;
426             },
427             GetSysRngUriAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
428         if (status != napi_ok) {
429             HiLog::Error(LABEL, "Failed to get create async work");
430             napi_get_undefined(env, &result);
431         } else {
432             napi_queue_async_work(env, asyncContext->work);
433             asyncContext.release();
434         }
435     }
436 
437     return result;
438 }
439 
GetSysRngPlayerAsyncCallbackComp(napi_env env,napi_status status,void * data)440 static void GetSysRngPlayerAsyncCallbackComp(napi_env env, napi_status status, void* data)
441 {
442     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
443     napi_value callback = nullptr;
444     napi_value retVal = nullptr;
445     napi_value result[2] = {};
446     napi_value rngplrResult = nullptr;
447 
448     if (context->ringtonePlayer != nullptr) {
449         rngplrResult = RingtonePlayerNapi::GetRingtonePlayerInstance(env, context->ringtonePlayer);
450         if (rngplrResult == nullptr) {
451             napi_value message = nullptr;
452             napi_create_string_utf8(env, "Error, Operation not supported or Failed", NAPI_AUTO_LENGTH, &message);
453             napi_create_error(env, nullptr, message, &result[PARAM0]);
454             napi_get_undefined(env, &result[PARAM1]);
455         } else {
456             napi_get_undefined(env, &result[0]);
457             result[PARAM1] = rngplrResult;
458         }
459     } else {
460         HiLog::Error(LABEL, "No get ringtoneplayer found!");
461         napi_value message = nullptr;
462         napi_create_string_utf8(env, "Error, Operation not supported or Failed", NAPI_AUTO_LENGTH, &message);
463         napi_create_error(env, nullptr, message, &result[PARAM0]);
464         napi_get_undefined(env, &result[PARAM1]);
465     }
466 
467     if (context->deferred) {
468         if (!context->status) {
469             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
470         } else {
471             napi_reject_deferred(env, context->deferred, result[PARAM0]);
472         }
473     } else {
474         napi_get_reference_value(env, context->callbackRef, &callback);
475         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
476         napi_delete_reference(env, context->callbackRef);
477     }
478     napi_delete_async_work(env, context->work);
479 
480     delete context;
481     context = nullptr;
482 }
483 
GetSystemRingtonePlayer(napi_env env,napi_callback_info info)484 napi_value SystemSoundManagerNapi::GetSystemRingtonePlayer(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_THREE;
490     napi_value argv[ARGS_THREE] = {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         HiLog::Error(LABEL, "Failed to retrieve details about the callback");
498         return result;
499     }
500 
501     NAPI_ASSERT(env, (argc == ARGS_TWO || argc == ARGS_THREE), "requires 3 parameters maximum");
502     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext
503         = std::make_unique<SystemSoundManagerAsyncContext>();
504     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
505     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
506         for (size_t i = PARAM0; i < argc; i++) {
507             napi_valuetype valueType = napi_undefined;
508             napi_typeof(env, argv[i], &valueType);
509             if (i == PARAM0) {
510                 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
511             } else if (i == PARAM1 && valueType == napi_number) {
512                 napi_get_value_int32(env, argv[i], &asyncContext->ringtoneType);
513             } else if (i == PARAM2 && valueType == napi_function) {
514                 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
515                 break;
516             } else {
517                 NAPI_ASSERT(env, false, "type mismatch");
518             }
519         }
520 
521         if (asyncContext->callbackRef == nullptr) {
522             napi_create_promise(env, &asyncContext->deferred, &result);
523         }
524 
525         napi_create_string_utf8(env, "GetSystemRingtonePlayer", NAPI_AUTO_LENGTH, &resource);
526         status = napi_create_async_work(env, nullptr, resource,
527             [](napi_env env, void* data) {
528                 SystemSoundManagerAsyncContext *context
529                     = static_cast<SystemSoundManagerAsyncContext *>(data);
530                 std::shared_ptr<IRingtonePlayer> ringtonePlayer
531                     = context->objectInfo->sysSoundMgrClient_->
532                           GetRingtonePlayer(context->abilityContext_,
533                                             static_cast<RingtoneType>(context->ringtoneType));
534                 if (ringtonePlayer != nullptr) {
535                     context->ringtonePlayer = ringtonePlayer;
536                     context->status = SUCCESS;
537                 } else {
538                     context->status = ERROR;
539                 }
540             },
541             GetSysRngPlayerAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
542         if (status != napi_ok) {
543             HiLog::Error(LABEL, "Failed to get create async work");
544             napi_get_undefined(env, &result);
545         } else {
546             napi_queue_async_work(env, asyncContext->work);
547             asyncContext.release();
548         }
549     }
550 
551     return result;
552 }
553 
SetSysNotUriAsyncCallbackComp(napi_env env,napi_status status,void * data)554 static void SetSysNotUriAsyncCallbackComp(napi_env env, napi_status status, void* data)
555 {
556     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
557     napi_value callback = nullptr;
558     napi_value retVal = nullptr;
559     napi_value result[2] = {};
560 
561     napi_get_undefined(env, &result[PARAM1]);
562     if (!context->status) {
563         napi_get_undefined(env, &result[PARAM0]);
564     } else {
565         napi_value message = nullptr;
566         napi_create_string_utf8(env, "Error, Operation not supported or Failed", NAPI_AUTO_LENGTH, &message);
567         napi_create_error(env, nullptr, message, &result[PARAM0]);
568     }
569 
570     if (context->deferred) {
571         if (!context->status) {
572             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
573         } else {
574             napi_reject_deferred(env, context->deferred, result[PARAM0]);
575         }
576     } else {
577         napi_get_reference_value(env, context->callbackRef, &callback);
578         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
579         napi_delete_reference(env, context->callbackRef);
580     }
581     napi_delete_async_work(env, context->work);
582 
583     delete context;
584     context = nullptr;
585 }
586 
SetSystemNotificationUri(napi_env env,napi_callback_info info)587 napi_value SystemSoundManagerNapi::SetSystemNotificationUri(napi_env env, napi_callback_info info)
588 {
589     napi_status status;
590     napi_value result = nullptr;
591     napi_value resource = nullptr;
592     size_t argc = ARGS_THREE;
593     napi_value argv[ARGS_THREE] = {0};
594     char buffer[SIZE];
595     napi_value thisVar = nullptr;
596     const int32_t refCount = 1;
597     size_t res = 0;
598 
599     status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
600     napi_get_undefined(env, &result);
601     if (status != napi_ok || thisVar == nullptr) {
602         HiLog::Error(LABEL, "Failed to retrieve details about the callback");
603         return result;
604     }
605 
606     NAPI_ASSERT(env, (argc == ARGS_TWO || argc == ARGS_THREE), "requires 3 parameters maximum");
607     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext
608         = std::make_unique<SystemSoundManagerAsyncContext>();
609     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
610     if (status != napi_ok || asyncContext->objectInfo == nullptr) {
611         HiLog::Error(LABEL, "Failed to unwrap object");
612         return result;
613     }
614 
615     for (size_t i = PARAM0; i < argc; i++) {
616         napi_valuetype valueType = napi_undefined;
617         napi_typeof(env, argv[i], &valueType);
618         if (i == PARAM0) {
619             asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
620         } else if (i == PARAM1 && valueType == napi_string) {
621             napi_get_value_string_utf8(env, argv[i], buffer, SIZE, &res);
622             asyncContext->uri = std::string(buffer);
623         } else if (i == PARAM2 && valueType == napi_function) {
624             napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
625             break;
626         } else {
627             if ((i == PARAM1) && (valueType == napi_null)) {
628                 HiLog::Error(LABEL, "string value type is null");
629                 continue;
630             }
631             NAPI_ASSERT(env, false, "type mismatch");
632         }
633     }
634 
635     if (asyncContext->callbackRef == nullptr) {
636         napi_create_promise(env, &asyncContext->deferred, &result);
637     }
638 
639     napi_create_string_utf8(env, "SetSystemNotificationUri", NAPI_AUTO_LENGTH, &resource);
640     status = napi_create_async_work(env, nullptr, resource,
641         [](napi_env env, void* data) {
642             SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
643             if (context->uri.empty()) {
644                 context->status = ERROR;
645             } else {
646                 context->status = context->objectInfo->sysSoundMgrClient_->SetSystemNotificationUri(
647                     context->abilityContext_, context->uri);
648             }
649         },
650         SetSysNotUriAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
651     if (status != napi_ok) {
652         HiLog::Error(LABEL, "Failed to get create async work");
653         napi_get_undefined(env, &result);
654     } else {
655         napi_queue_async_work(env, asyncContext->work);
656         asyncContext.release();
657     }
658 
659     return result;
660 }
661 
GetSysNotUriAsyncCallbackComp(napi_env env,napi_status status,void * data)662 static void GetSysNotUriAsyncCallbackComp(napi_env env, napi_status status, void* data)
663 {
664     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
665     napi_value callback = nullptr;
666     napi_value retVal = nullptr;
667     napi_value result[2] = {};
668 
669     if (!context->status) {
670         napi_get_undefined(env, &result[PARAM0]);
671         napi_create_string_utf8(env, context->uri.c_str(), NAPI_AUTO_LENGTH, &result[PARAM1]);
672     } else {
673         napi_value message = nullptr;
674         napi_create_string_utf8(env, "Error, Operation not supported or Failed", NAPI_AUTO_LENGTH, &message);
675         napi_create_error(env, nullptr, message, &result[PARAM0]);
676         napi_get_undefined(env, &result[PARAM1]);
677     }
678 
679     if (context->deferred) {
680         if (!context->status) {
681             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
682         } else {
683             napi_reject_deferred(env, context->deferred, result[PARAM0]);
684         }
685     } else {
686         napi_get_reference_value(env, context->callbackRef, &callback);
687         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
688         napi_delete_reference(env, context->callbackRef);
689     }
690     napi_delete_async_work(env, context->work);
691 
692     delete context;
693     context = nullptr;
694 }
695 
GetSystemNotificationUri(napi_env env,napi_callback_info info)696 napi_value SystemSoundManagerNapi::GetSystemNotificationUri(napi_env env, napi_callback_info info)
697 {
698     napi_status status;
699     napi_value result = nullptr;
700     napi_value resource = nullptr;
701     size_t argc = ARGS_TWO;
702     napi_value argv[ARGS_TWO] = {0};
703     napi_value thisVar = nullptr;
704     const int32_t refCount = 1;
705 
706     status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
707     napi_get_undefined(env, &result);
708     if (status != napi_ok || thisVar == nullptr) {
709         HiLog::Error(LABEL, "Failed to retrieve details about the callback");
710         return result;
711     }
712 
713     NAPI_ASSERT(env, (argc == ARGS_ONE || argc == ARGS_TWO), "requires 2 parameters maximum");
714     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext
715         = std::make_unique<SystemSoundManagerAsyncContext>();
716     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
717     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
718         if (argc == ARGS_TWO) {
719             asyncContext->abilityContext_ = GetAbilityContext(env, argv[PARAM0]);
720 
721             napi_valuetype valueType = napi_undefined;
722             napi_typeof(env, argv[PARAM1], &valueType);
723             if (valueType == napi_function) {
724                 napi_create_reference(env, argv[PARAM1], refCount, &asyncContext->callbackRef);
725             } else {
726                 NAPI_ASSERT(env, false, "type mismatch");
727             }
728         } else {
729             napi_create_promise(env, &asyncContext->deferred, &result);
730         }
731 
732         napi_create_string_utf8(env, "GetSystemNotificationUri", NAPI_AUTO_LENGTH, &resource);
733         status = napi_create_async_work(env, nullptr, resource,
734             [](napi_env env, void* data) {
735                 SystemSoundManagerAsyncContext *context
736                     = static_cast<SystemSoundManagerAsyncContext *>(data);
737                 context->uri = context->objectInfo->sysSoundMgrClient_->GetSystemNotificationUri(
738                     context->abilityContext_);
739                 context->status = SUCCESS;
740             },
741             GetSysNotUriAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
742         if (status != napi_ok) {
743             HiLog::Error(LABEL, "Failed to get create async work");
744             napi_get_undefined(env, &result);
745         } else {
746             napi_queue_async_work(env, asyncContext->work);
747             asyncContext.release();
748         }
749     }
750 
751     return result;
752 }
753 
SetSysAlarmUriAsyncCallbackComp(napi_env env,napi_status status,void * data)754 static void SetSysAlarmUriAsyncCallbackComp(napi_env env, napi_status status, void* data)
755 {
756     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
757     napi_value callback = nullptr;
758     napi_value retVal = nullptr;
759     napi_value result[2] = {};
760 
761     napi_get_undefined(env, &result[PARAM1]);
762     if (!context->status) {
763         napi_get_undefined(env, &result[PARAM0]);
764     } else {
765         napi_value message = nullptr;
766         napi_create_string_utf8(env, "Error, Operation not supported or Failed", NAPI_AUTO_LENGTH, &message);
767         napi_create_error(env, nullptr, message, &result[PARAM0]);
768     }
769 
770     if (context->deferred) {
771         if (!context->status) {
772             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
773         } else {
774             napi_reject_deferred(env, context->deferred, result[PARAM0]);
775         }
776     } else {
777         napi_get_reference_value(env, context->callbackRef, &callback);
778         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
779         napi_delete_reference(env, context->callbackRef);
780     }
781     napi_delete_async_work(env, context->work);
782 
783     delete context;
784     context = nullptr;
785 }
786 
SetSystemAlarmUri(napi_env env,napi_callback_info info)787 napi_value SystemSoundManagerNapi::SetSystemAlarmUri(napi_env env, napi_callback_info info)
788 {
789     napi_status status;
790     napi_value result = nullptr;
791     napi_value resource = nullptr;
792     size_t argc = ARGS_THREE;
793     napi_value argv[ARGS_THREE] = {0};
794     char buffer[SIZE];
795     napi_value thisVar = nullptr;
796     const int32_t refCount = 1;
797     size_t res = 0;
798 
799     status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
800     napi_get_undefined(env, &result);
801     if (status != napi_ok || thisVar == nullptr) {
802         HiLog::Error(LABEL, "Failed to retrieve details about the callback");
803         return result;
804     }
805 
806     NAPI_ASSERT(env, (argc == ARGS_TWO || argc == ARGS_THREE), "requires 3 parameters maximum");
807     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext
808         = std::make_unique<SystemSoundManagerAsyncContext>();
809     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
810     if (status != napi_ok || asyncContext->objectInfo == nullptr) {
811         HiLog::Error(LABEL, "Failed to unwrap object");
812         return result;
813     }
814 
815     for (size_t i = PARAM1; i < argc; i++) {
816         napi_valuetype valueType = napi_undefined;
817         napi_typeof(env, argv[i], &valueType);
818         if (i == PARAM1 && valueType == napi_string) {
819             napi_get_value_string_utf8(env, argv[i], buffer, SIZE, &res);
820             asyncContext->uri = std::string(buffer);
821         } else if (i == PARAM2 && valueType == napi_function) {
822             napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
823             break;
824         } else {
825             if ((i == PARAM1) && (valueType == napi_null)) {
826                 HiLog::Error(LABEL, "string value type is null");
827                 continue;
828             }
829             NAPI_ASSERT(env, false, "type mismatch");
830         }
831     }
832 
833     if (asyncContext->callbackRef == nullptr) {
834         napi_create_promise(env, &asyncContext->deferred, &result);
835     }
836 
837     napi_create_string_utf8(env, "SetSystemAlarmUri", NAPI_AUTO_LENGTH, &resource);
838     status = napi_create_async_work(env, nullptr, resource,
839         [](napi_env env, void* data) {
840             SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
841             if (context->uri.empty()) {
842                 context->status = ERROR;
843             } else {
844                 context->status = context->objectInfo->sysSoundMgrClient_->SetSystemAlarmUri(
845                     context->abilityContext_, context->uri);
846             }
847         },
848         SetSysAlarmUriAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
849     if (status != napi_ok) {
850         HiLog::Error(LABEL, "Failed to get create async work");
851         napi_get_undefined(env, &result);
852     } else {
853         napi_queue_async_work(env, asyncContext->work);
854         asyncContext.release();
855     }
856 
857     return result;
858 }
859 
GetSysAlarmUriAsyncCallbackComp(napi_env env,napi_status status,void * data)860 static void GetSysAlarmUriAsyncCallbackComp(napi_env env, napi_status status, void* data)
861 {
862     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
863     napi_value callback = nullptr;
864     napi_value retVal = nullptr;
865     napi_value result[2] = {};
866 
867     if (!context->status) {
868         napi_get_undefined(env, &result[PARAM0]);
869         napi_create_string_utf8(env, context->uri.c_str(), NAPI_AUTO_LENGTH, &result[PARAM1]);
870     } else {
871         napi_value message = nullptr;
872         napi_create_string_utf8(env, "Error, Operation not supported or Failed", NAPI_AUTO_LENGTH, &message);
873         napi_create_error(env, nullptr, message, &result[PARAM0]);
874         napi_get_undefined(env, &result[PARAM1]);
875     }
876 
877     if (context->deferred) {
878         if (!context->status) {
879             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
880         } else {
881             napi_reject_deferred(env, context->deferred, result[PARAM0]);
882         }
883     } else {
884         napi_get_reference_value(env, context->callbackRef, &callback);
885         napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal);
886         napi_delete_reference(env, context->callbackRef);
887     }
888     napi_delete_async_work(env, context->work);
889 
890     delete context;
891     context = nullptr;
892 }
893 
GetSystemAlarmUri(napi_env env,napi_callback_info info)894 napi_value SystemSoundManagerNapi::GetSystemAlarmUri(napi_env env, napi_callback_info info)
895 {
896     napi_status status;
897     napi_value result = nullptr;
898     napi_value resource = nullptr;
899     size_t argc = ARGS_TWO;
900     napi_value argv[ARGS_TWO] = {0};
901     napi_value thisVar = nullptr;
902     const int32_t refCount = 1;
903 
904     status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
905     napi_get_undefined(env, &result);
906     if (status != napi_ok || thisVar == nullptr) {
907         HiLog::Error(LABEL, "Failed to retrieve details about the callback");
908         return result;
909     }
910 
911     NAPI_ASSERT(env, (argc == ARGS_ONE || argc == ARGS_TWO), "requires 2 parameters maximum");
912     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext
913         = std::make_unique<SystemSoundManagerAsyncContext>();
914     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
915     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
916         if (argc == ARGS_TWO) {
917             asyncContext->abilityContext_ = GetAbilityContext(env, argv[PARAM0]);
918 
919             napi_valuetype valueType = napi_undefined;
920             napi_typeof(env, argv[PARAM1], &valueType);
921             if (valueType == napi_function) {
922                 napi_create_reference(env, argv[PARAM1], refCount, &asyncContext->callbackRef);
923             } else {
924                 NAPI_ASSERT(env, false, "type mismatch");
925             }
926         } else {
927             napi_create_promise(env, &asyncContext->deferred, &result);
928         }
929 
930         napi_create_string_utf8(env, "GetSystemAlarmUri", NAPI_AUTO_LENGTH, &resource);
931         status = napi_create_async_work(env, nullptr, resource,
932             [](napi_env env, void* data) {
933                 SystemSoundManagerAsyncContext *context
934                     = static_cast<SystemSoundManagerAsyncContext *>(data);
935                 context->uri = context->objectInfo->sysSoundMgrClient_->GetSystemAlarmUri(
936                     context->abilityContext_);
937                 context->status = SUCCESS;
938             },
939             GetSysAlarmUriAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
940         if (status != napi_ok) {
941             HiLog::Error(LABEL, "Failed to get create async work");
942             napi_get_undefined(env, &result);
943         } else {
944             napi_queue_async_work(env, asyncContext->work);
945             asyncContext.release();
946         }
947     }
948 
949     return result;
950 }
951 } // namespace AudioStandard
952 } // namespace OHOS