• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_sound_manager_napi.h"
17 
18 #include "access_token.h"
19 #include "accesstoken_kit.h"
20 #include "audio_renderer_info_napi.h"
21 #include "ipc_skeleton.h"
22 #include "system_sound_log.h"
23 #include "tokenid_kit.h"
24 
25 using namespace std;
26 using OHOS::Security::AccessToken::AccessTokenKit;
27 
28 namespace {
29 /* Constants for array index */
30 const int32_t PARAM0 = 0;
31 const int32_t PARAM1 = 1;
32 const int32_t PARAM2 = 2;
33 const int32_t PARAM3 = 3;
34 const int32_t PARAM4 = 4;
35 
36 /* Constants for array size */
37 const int32_t ARGS_ONE = 1;
38 const int32_t ARGS_TWO = 2;
39 const int32_t ARGS_THREE = 3;
40 const int32_t ARGS_FOUR = 4;
41 const int32_t ARGS_FIVE = 5;
42 const int32_t SIZE = 1024;
43 
44 /* Constants for tone type */
45 const int32_t CARD_0 = 0;
46 const int32_t CARD_1 = 1;
47 const int32_t SYSTEM_NOTIFICATION = 32;
48 
49 const int TYPEERROR = -2;
50 const int ERROR = -1;
51 const int SUCCESS = 0;
52 
53 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO_NAPI, "SystemSoundManagerNapi"};
54 }
55 
56 namespace OHOS {
57 namespace Media {
58 thread_local napi_ref SystemSoundManagerNapi::sConstructor_ = nullptr;
59 thread_local napi_ref SystemSoundManagerNapi::ringtoneType_ = nullptr;
60 thread_local napi_ref SystemSoundManagerNapi::systemToneType_ = nullptr;
61 thread_local napi_ref SystemSoundManagerNapi::toneCustomizedType_ = nullptr;
62 thread_local napi_ref SystemSoundManagerNapi::toneHapticsMode_ = nullptr;
63 
SystemSoundManagerNapi()64 SystemSoundManagerNapi::SystemSoundManagerNapi()
65     : env_(nullptr), sysSoundMgrClient_(nullptr) {}
66 
67 SystemSoundManagerNapi::~SystemSoundManagerNapi() = default;
68 
AddNamedProperty(napi_env env,napi_value object,const std::string name,int32_t enumValue)69 napi_status SystemSoundManagerNapi::AddNamedProperty(napi_env env, napi_value object, const std::string name,
70     int32_t enumValue)
71 {
72     napi_status status;
73     napi_value napiValue;
74 
75     status = napi_create_int32(env, enumValue, &napiValue);
76     if (status == napi_ok) {
77         status = napi_set_named_property(env, object, name.c_str(), napiValue);
78     }
79 
80     return status;
81 }
82 
CreateRingtoneTypeObject(napi_env env)83 napi_value SystemSoundManagerNapi::CreateRingtoneTypeObject(napi_env env)
84 {
85     napi_value result = nullptr;
86     napi_status status;
87     std::string propName;
88     int32_t refCount = 1;
89 
90     status = napi_create_object(env, &result);
91     if (status == napi_ok) {
92         for (auto &iter: ringtoneTypeMap) {
93             propName = iter.first;
94             status = AddNamedProperty(env, result, propName, iter.second);
95             if (status != napi_ok) {
96                 MEDIA_LOGE("CreateRingtoneTypeObject: Failed to add named prop!");
97                 break;
98             }
99             propName.clear();
100         }
101         if (status == napi_ok) {
102             status = napi_create_reference(env, result, refCount, &ringtoneType_);
103             if (status == napi_ok) {
104                 return result;
105             }
106         }
107     }
108     napi_get_undefined(env, &result);
109 
110     return result;
111 }
112 
CreateSystemToneTypeObject(napi_env env)113 napi_value SystemSoundManagerNapi::CreateSystemToneTypeObject(napi_env env)
114 {
115     napi_value result = nullptr;
116     napi_status status;
117     std::string propName;
118     int32_t refCount = 1;
119 
120     status = napi_create_object(env, &result);
121     if (status == napi_ok) {
122         for (auto &iter: systemToneTypeMap) {
123             propName = iter.first;
124             status = AddNamedProperty(env, result, propName, iter.second);
125             if (status != napi_ok) {
126                 MEDIA_LOGE("CreateSystemToneTypeObject: Failed to add named prop!");
127                 break;
128             }
129             propName.clear();
130         }
131         if (status == napi_ok) {
132             status = napi_create_reference(env, result, refCount, &systemToneType_);
133             if (status == napi_ok) {
134                 return result;
135             }
136         }
137     }
138     napi_get_undefined(env, &result);
139 
140     return result;
141 }
142 
CreateToneHapticsTypeObject(napi_env env)143 napi_value SystemSoundManagerNapi::CreateToneHapticsTypeObject(napi_env env)
144 {
145     napi_value result = nullptr;
146     napi_status status;
147     std::string propName;
148     int32_t refCount = 1;
149 
150     status = napi_create_object(env, &result);
151     if (status == napi_ok) {
152         for (auto &iter: toneHapticsTypeMap) {
153             propName = iter.first;
154             status = AddNamedProperty(env, result, propName, iter.second);
155             if (status != napi_ok) {
156                 MEDIA_LOGE("CreateToneHapticsTypeObject: Failed to add named prop!");
157                 break;
158             }
159             propName.clear();
160         }
161         if (status == napi_ok) {
162             status = napi_create_reference(env, result, refCount, &systemToneType_);
163             if (status == napi_ok) {
164                 return result;
165             }
166         }
167     }
168     napi_get_undefined(env, &result);
169 
170     return result;
171 }
172 
CreateToneCustomizedTypeObject(napi_env env)173 napi_value SystemSoundManagerNapi::CreateToneCustomizedTypeObject(napi_env env)
174 {
175     napi_value result = nullptr;
176     napi_status status;
177     std::string propName;
178     int32_t refCount = 1;
179 
180     status = napi_create_object(env, &result);
181     if (status == napi_ok) {
182         for (auto &iter: toneCustomizedTypeMap) {
183             propName = iter.first;
184             status = AddNamedProperty(env, result, propName, iter.second);
185             if (status != napi_ok) {
186                 MEDIA_LOGE("CreateToneCustomizedTypeObject: Failed to add named prop!");
187                 break;
188             }
189             propName.clear();
190         }
191         if (status == napi_ok) {
192             status = napi_create_reference(env, result, refCount, &toneCustomizedType_);
193             if (status == napi_ok) {
194                 return result;
195             }
196         }
197     }
198     napi_get_undefined(env, &result);
199 
200     return result;
201 }
202 
CreateToneHapticsModeObject(napi_env env)203 napi_value SystemSoundManagerNapi::CreateToneHapticsModeObject(napi_env env)
204 {
205     napi_value result = nullptr;
206     napi_status status;
207     std::string propName;
208     int32_t refCount = 1;
209 
210     status = napi_create_object(env, &result);
211     if (status == napi_ok) {
212         for (auto &iter: toneHapticsModeMap) {
213             propName = iter.first;
214             status = AddNamedProperty(env, result, propName, iter.second);
215             if (status != napi_ok) {
216                 MEDIA_LOGE("CreateToneHapticsModeObject: Failed to add named prop!");
217                 break;
218             }
219             propName.clear();
220         }
221         if (status == napi_ok) {
222             status = napi_create_reference(env, result, refCount, &toneHapticsMode_);
223             if (status == napi_ok) {
224                 return result;
225             }
226         }
227     }
228     napi_get_undefined(env, &result);
229 
230     return result;
231 }
232 
CreateToneCategoryRingtoneObject(napi_env env)233 napi_value SystemSoundManagerNapi::CreateToneCategoryRingtoneObject(napi_env env)
234 {
235     napi_value toneCategoryRingtone;
236     napi_create_int32(env, TONE_CATEGORY_RINGTONE, &toneCategoryRingtone);
237     return toneCategoryRingtone;
238 }
239 
CreateToneCategoryTextMessageObject(napi_env env)240 napi_value SystemSoundManagerNapi::CreateToneCategoryTextMessageObject(napi_env env)
241 {
242     napi_value toneCategoryTextMessage;
243     napi_create_int32(env, TONE_CATEGORY_TEXT_MESSAGE, &toneCategoryTextMessage);
244     return toneCategoryTextMessage;
245 }
246 
CreateToneCategoryNotificationObject(napi_env env)247 napi_value SystemSoundManagerNapi::CreateToneCategoryNotificationObject(napi_env env)
248 {
249     napi_value toneCategoryNotification;
250     napi_create_int32(env, TONE_CATEGORY_NOTIFICATION, &toneCategoryNotification);
251     return toneCategoryNotification;
252 }
253 
CreateToneCategoryAlarmObject(napi_env env)254 napi_value SystemSoundManagerNapi::CreateToneCategoryAlarmObject(napi_env env)
255 {
256     napi_value toneCategoryAlarm;
257     napi_create_int32(env, TONE_CATEGORY_ALARM, &toneCategoryAlarm);
258     return toneCategoryAlarm;
259 }
260 
CreateToneCategoryContactsObject(napi_env env)261 napi_value SystemSoundManagerNapi::CreateToneCategoryContactsObject(napi_env env)
262 {
263     napi_value toneCategoryContacts;
264     napi_create_int32(env, TONE_CATEGORY_CONTACTS, &toneCategoryContacts);
265     return toneCategoryContacts;
266 }
267 
DefineClassProperties(napi_env env,napi_value & ctorObj)268 napi_status SystemSoundManagerNapi::DefineClassProperties(napi_env env, napi_value &ctorObj)
269 {
270     napi_property_descriptor syssndmgr_prop[] = {
271         DECLARE_NAPI_FUNCTION("setSystemRingtoneUri", SetRingtoneUri), // deprecated
272         DECLARE_NAPI_FUNCTION("setRingtoneUri", SetRingtoneUri),
273         DECLARE_NAPI_FUNCTION("getSystemRingtoneUri", GetRingtoneUri), // deprecated
274         DECLARE_NAPI_FUNCTION("getRingtoneUri", GetRingtoneUri),
275         DECLARE_NAPI_FUNCTION("getSystemRingtonePlayer", GetRingtonePlayer), // deprecated
276         DECLARE_NAPI_FUNCTION("getRingtonePlayer", GetRingtonePlayer),
277         DECLARE_NAPI_FUNCTION("setSystemToneUri", SetSystemToneUri),
278         DECLARE_NAPI_FUNCTION("getSystemToneUri", GetSystemToneUri),
279         DECLARE_NAPI_FUNCTION("getSystemTonePlayer", GetSystemTonePlayer),
280         DECLARE_NAPI_FUNCTION("getDefaultRingtoneAttrs", GetDefaultRingtoneAttrs),
281         DECLARE_NAPI_FUNCTION("getRingtoneAttrList", GetRingtoneAttrList),
282         DECLARE_NAPI_FUNCTION("getDefaultSystemToneAttrs", GetDefaultSystemToneAttrs),
283         DECLARE_NAPI_FUNCTION("getSystemToneAttrList", GetSystemToneAttrList),
284         DECLARE_NAPI_FUNCTION("getDefaultAlarmToneAttrs", GetDefaultAlarmToneAttrs),
285         DECLARE_NAPI_FUNCTION("setAlarmToneUri", SetAlarmToneUri),
286         DECLARE_NAPI_FUNCTION("getAlarmToneUri", GetAlarmToneUri),
287         DECLARE_NAPI_FUNCTION("getAlarmToneAttrList", GetAlarmToneAttrList),
288         DECLARE_NAPI_FUNCTION("openAlarmTone", OpenAlarmTone),
289         DECLARE_NAPI_FUNCTION("close", Close),
290         DECLARE_NAPI_FUNCTION("addCustomizedTone", AddCustomizedTone),
291         DECLARE_NAPI_FUNCTION("removeCustomizedTone", RemoveCustomizedTone),
292         DECLARE_NAPI_FUNCTION("getToneHapticsSettings", GetToneHapticsSettings),
293         DECLARE_NAPI_FUNCTION("setToneHapticsSettings", SetToneHapticsSettings),
294         DECLARE_NAPI_FUNCTION("getToneHapticsList", GetToneHapticsList),
295         DECLARE_NAPI_FUNCTION("getHapticsAttrsSyncedWithTone", GetHapticsAttrsSyncedWithTone),
296         DECLARE_NAPI_FUNCTION("openToneHaptics", OpenToneHaptics),
297         DECLARE_NAPI_FUNCTION("getCurrentRingtoneAttribute", GetCurrentRingtoneAttribute),
298         DECLARE_NAPI_FUNCTION("removeCustomizedToneList", RemoveCustomizedToneList),
299         DECLARE_NAPI_FUNCTION("openToneList", OpenToneList),
300     };
301 
302     return napi_define_class(env, SYSTEM_SND_MNGR_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
303         Construct, nullptr, sizeof(syssndmgr_prop) / sizeof(syssndmgr_prop[0]), syssndmgr_prop, &ctorObj);
304 }
305 
DefineStaticProperties(napi_env env,napi_value exports)306 napi_status SystemSoundManagerNapi::DefineStaticProperties(napi_env env, napi_value exports)
307 {
308     napi_property_descriptor static_prop[] = {
309         DECLARE_NAPI_STATIC_FUNCTION("getSystemSoundManager", GetSystemSoundManager),
310         DECLARE_NAPI_PROPERTY("RingtoneType", CreateRingtoneTypeObject(env)),
311         DECLARE_NAPI_PROPERTY("SystemToneType", CreateSystemToneTypeObject(env)),
312         DECLARE_NAPI_PROPERTY("ToneHapticsType", CreateToneHapticsTypeObject(env)),
313         DECLARE_NAPI_STATIC_FUNCTION("createCustomizedToneAttrs", CreateCustomizedToneAttrs),
314         DECLARE_NAPI_PROPERTY("ToneCustomizedType", CreateToneCustomizedTypeObject(env)),
315         DECLARE_NAPI_PROPERTY("TONE_CATEGORY_RINGTONE", CreateToneCategoryRingtoneObject(env)),
316         DECLARE_NAPI_PROPERTY("TONE_CATEGORY_TEXT_MESSAGE", CreateToneCategoryTextMessageObject(env)),
317         DECLARE_NAPI_PROPERTY("TONE_CATEGORY_NOTIFICATION", CreateToneCategoryNotificationObject(env)),
318         DECLARE_NAPI_PROPERTY("TONE_CATEGORY_CONTACTS", CreateToneCategoryContactsObject(env)),
319         DECLARE_NAPI_PROPERTY("TONE_CATEGORY_ALARM", CreateToneCategoryAlarmObject(env)),
320         DECLARE_NAPI_PROPERTY("ToneHapticsMode", CreateToneHapticsModeObject(env)),
321     };
322 
323     return napi_define_properties(env, exports, sizeof(static_prop) / sizeof(static_prop[0]), static_prop);
324 }
325 
Init(napi_env env,napi_value exports)326 napi_value SystemSoundManagerNapi::Init(napi_env env, napi_value exports)
327 {
328     napi_value ctorObj;
329     int32_t refCount = 1;
330 
331     napi_status status = DefineClassProperties(env, ctorObj);
332     if (status != napi_ok) {
333         return nullptr;
334     }
335 
336     status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
337     if (status != napi_ok) {
338         return nullptr;
339     }
340 
341     status = napi_set_named_property(env, exports, SYSTEM_SND_MNGR_NAPI_CLASS_NAME.c_str(), ctorObj);
342     if (status != napi_ok) {
343         return nullptr;
344     }
345 
346     status = DefineStaticProperties(env, exports);
347     if (status != napi_ok) {
348         return nullptr;
349     }
350 
351     return exports;
352 }
353 
GetAbilityContext(napi_env env,napi_value contextArg)354 shared_ptr<AbilityRuntime::Context> SystemSoundManagerNapi::GetAbilityContext(napi_env env, napi_value contextArg)
355 {
356     MEDIA_LOGI("SystemSoundManagerNapi::GetAbilityContext");
357     bool stageMode = false;
358 
359     napi_status status = AbilityRuntime::IsStageContext(env, contextArg, stageMode);
360     if (status == napi_ok && stageMode) {
361         MEDIA_LOGI("GetAbilityContext: Getting context with stage model");
362         auto context = AbilityRuntime::GetStageModeContext(env, contextArg);
363         CHECK_AND_RETURN_RET_LOG(context != nullptr, nullptr, "Failed to obtain ability in STAGE mode");
364         return context;
365     } else {
366         MEDIA_LOGI("GetAbilityContext: Getting context with FA model");
367         auto ability = AbilityRuntime::GetCurrentAbility(env);
368         CHECK_AND_RETURN_RET_LOG(ability != nullptr, nullptr, "Failed to obtain ability in FA mode");
369         auto faContext = ability->GetAbilityContext();
370         CHECK_AND_RETURN_RET_LOG(faContext != nullptr, nullptr, "GetAbilityContext returned null in FA model");
371         return faContext;
372     }
373 }
374 
Construct(napi_env env,napi_callback_info info)375 napi_value SystemSoundManagerNapi::Construct(napi_env env, napi_callback_info info)
376 {
377     napi_status status;
378     napi_value result = nullptr;
379     napi_value thisVar = nullptr;
380 
381     napi_get_undefined(env, &result);
382     status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
383     if (status == napi_ok && thisVar != nullptr) {
384         std::unique_ptr<SystemSoundManagerNapi> obj = std::make_unique<SystemSoundManagerNapi>();
385         if (obj != nullptr) {
386             obj->env_ = env;
387             obj->sysSoundMgrClient_ = SystemSoundManagerFactory::CreateSystemSoundManager();
388             if (obj->sysSoundMgrClient_ == nullptr) {
389                 MEDIA_LOGE("Failed to create sysSoundMgrClient_ instance.");
390                 return result;
391             }
392 
393             status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
394                                SystemSoundManagerNapi::Destructor, nullptr, nullptr);
395             if (status == napi_ok) {
396                 obj.release();
397                 return thisVar;
398             } else {
399                 MEDIA_LOGE("Failed to wrap the native sysSoundMgr object with JS.");
400             }
401         }
402     }
403 
404     return result;
405 }
406 
Destructor(napi_env env,void * nativeObject,void * finalize_hint)407 void SystemSoundManagerNapi::Destructor(napi_env env, void* nativeObject, void* finalize_hint)
408 {
409     SystemSoundManagerNapi *systemSoundManagerhelper = reinterpret_cast<SystemSoundManagerNapi*>(nativeObject);
410     if (systemSoundManagerhelper != nullptr) {
411         systemSoundManagerhelper->~SystemSoundManagerNapi();
412     }
413 }
414 
VerifySelfSystemPermission()415 bool SystemSoundManagerNapi::VerifySelfSystemPermission()
416 {
417     Security::AccessToken::FullTokenID selfTokenID = IPCSkeleton::GetSelfTokenID();
418     auto tokenTypeFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(static_cast<uint32_t>(selfTokenID));
419     if (tokenTypeFlag == Security::AccessToken::TOKEN_NATIVE ||
420         tokenTypeFlag == Security::AccessToken::TOKEN_SHELL ||
421         Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfTokenID)) {
422         return true;
423     }
424     return false;
425 }
426 
VerifyRingtonePermission()427 bool SystemSoundManagerNapi::VerifyRingtonePermission()
428 {
429     Security::AccessToken::FullTokenID selfTokenID = IPCSkeleton::GetSelfTokenID();
430     if (Security::AccessToken::AccessTokenKit::VerifyAccessToken(selfTokenID, "ohos.permission.WRITE_RINGTONE")) {
431         return false;
432     }
433     return true;
434 }
435 
SetSystemSoundUriAsyncCallbackComp(napi_env env,napi_status status,void * data)436 void SystemSoundManagerNapi::SetSystemSoundUriAsyncCallbackComp(napi_env env, napi_status status, void* data)
437 {
438     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
439     napi_value setUriCallback = nullptr;
440     napi_value retVal = nullptr;
441     napi_value result[2] = {};
442 
443     napi_get_undefined(env, &result[PARAM1]);
444     if (!context->status) {
445         napi_get_undefined(env, &result[PARAM0]);
446     } else {
447         result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
448         napi_get_undefined(env, &result[PARAM1]);
449     }
450 
451     if (context->deferred) {
452         if (!context->status) {
453             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
454         } else {
455             napi_reject_deferred(env, context->deferred, result[PARAM0]);
456         }
457     } else {
458         napi_get_reference_value(env, context->callbackRef, &setUriCallback);
459         napi_call_function(env, nullptr, setUriCallback, ARGS_TWO, result, &retVal);
460         napi_delete_reference(env, context->callbackRef);
461     }
462     napi_delete_async_work(env, context->work);
463 
464     delete context;
465     context = nullptr;
466 }
467 
GetSystemSoundUriAsyncCallbackComp(napi_env env,napi_status status,void * data)468 void SystemSoundManagerNapi::GetSystemSoundUriAsyncCallbackComp(napi_env env, napi_status status, void* data)
469 {
470     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
471     napi_value getUriCallback = nullptr;
472     napi_value retVal = nullptr;
473     napi_value result[2] = {};
474 
475     if (!context->status) {
476         napi_get_undefined(env, &result[PARAM0]);
477         napi_create_string_utf8(env, context->uri.c_str(), NAPI_AUTO_LENGTH, &result[PARAM1]);
478     } else {
479         result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
480         napi_get_undefined(env, &result[PARAM1]);
481     }
482 
483     if (context->deferred) {
484         if (!context->status) {
485             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
486         } else {
487             napi_reject_deferred(env, context->deferred, result[PARAM0]);
488         }
489     } else {
490         napi_get_reference_value(env, context->callbackRef, &getUriCallback);
491         napi_call_function(env, nullptr, getUriCallback, ARGS_TWO, result, &retVal);
492         napi_delete_reference(env, context->callbackRef);
493     }
494     napi_delete_async_work(env, context->work);
495 
496     delete context;
497     context = nullptr;
498 }
499 
GetSystemSoundManager(napi_env env,napi_callback_info info)500 napi_value SystemSoundManagerNapi::GetSystemSoundManager(napi_env env, napi_callback_info info)
501 {
502     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
503         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
504         "No system permission");
505     napi_status status;
506     napi_value result = nullptr;
507     napi_value ctor;
508 
509     status = napi_get_reference_value(env, sConstructor_, &ctor);
510     if (status == napi_ok) {
511         status = napi_new_instance(env, ctor, 0, nullptr, &result);
512         if (status == napi_ok) {
513             return result;
514         } else {
515             MEDIA_LOGE("GetSystemSoundManager: new instance can not be obtained.");
516         }
517     }
518 
519     napi_get_undefined(env, &result);
520     return result;
521 }
522 
SetRingtoneUri(napi_env env,napi_callback_info info)523 napi_value SystemSoundManagerNapi::SetRingtoneUri(napi_env env, napi_callback_info info)
524 {
525     napi_value result = nullptr;
526     napi_value resource = nullptr;
527     size_t argc = ARGS_FOUR;
528     napi_value argv[ARGS_FOUR] = {0};
529     napi_value thisVar = nullptr;
530     const int32_t refCount = 1;
531 
532     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
533     napi_get_undefined(env, &result);
534     CHECK_AND_RETURN_RET_LOG(status == napi_ok && thisVar != nullptr, result, "SetRingtoneUri: napi_get_cb_info fail");
535 
536     NAPI_ASSERT(env, (argc == ARGS_THREE || argc == ARGS_FOUR), "SetRingtoneUri: requires 4 parameters maximum");
537     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
538     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
539     CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
540         "SetRingtoneUri: Failed to unwrap object");
541 
542     for (size_t i = PARAM0; i < argc; i++) {
543         napi_valuetype valueType = napi_undefined;
544         napi_typeof(env, argv[i], &valueType);
545         if (i == PARAM0) {
546             asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
547         } else if (i == PARAM1 && valueType == napi_string) {
548             asyncContext->uri = ExtractStringToEnv(env, argv[i]);
549         } else if (i == PARAM2 && valueType == napi_number) {
550             napi_get_value_int32(env, argv[i], &asyncContext->ringtoneType);
551         } else if (i == PARAM3 && valueType == napi_function) {
552             napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
553             break;
554         } else {
555             CHECK_AND_CONTINUE(!(i == PARAM1) && (valueType == napi_null));
556             NAPI_ASSERT(env, false, "SetRingtoneUri: type mismatch");
557         }
558     }
559 
560     if (asyncContext->callbackRef == nullptr) {
561         napi_create_promise(env, &asyncContext->deferred, &result);
562     }
563 
564     napi_create_string_utf8(env, "SetRingtoneUri", NAPI_AUTO_LENGTH, &resource);
565     status = napi_create_async_work(env, nullptr, resource, AsyncSetRingtoneUri,
566         SetSystemSoundUriAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
567     if (status != napi_ok) {
568         MEDIA_LOGE("Failed to get create async work");
569         napi_get_undefined(env, &result);
570     } else {
571         napi_queue_async_work(env, asyncContext->work);
572         asyncContext.release();
573     }
574 
575     return result;
576 }
577 
AsyncSetRingtoneUri(napi_env env,void * data)578 void SystemSoundManagerNapi::AsyncSetRingtoneUri(napi_env env, void *data)
579 {
580     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
581     if (context->uri.empty()) {
582         context->status = ERROR;
583     } else {
584         context->status = context->objectInfo->sysSoundMgrClient_->SetRingtoneUri(
585             context->abilityContext_, context->uri, static_cast<RingtoneType>(context->ringtoneType));
586     }
587     if (context->status) {
588         context->errCode = NAPI_ERR_IO_ERROR;
589         context->errMessage = "I/O error. Uri is empty, can not found.";
590     }
591 }
592 
GetRingtoneUri(napi_env env,napi_callback_info info)593 napi_value SystemSoundManagerNapi::GetRingtoneUri(napi_env env, napi_callback_info info)
594 {
595     napi_status status;
596     napi_value result = nullptr;
597     napi_value resource = nullptr;
598     size_t argc = ARGS_THREE;
599     napi_value argv[ARGS_THREE] = {0};
600     napi_value thisVar = nullptr;
601     const int32_t refCount = 1;
602 
603     status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
604     napi_get_undefined(env, &result);
605     CHECK_AND_RETURN_RET_LOG(status == napi_ok && thisVar != nullptr, result,
606         "GetRingtoneUri: Failed to retrieve details about the callback");
607 
608     NAPI_ASSERT(env, (argc == ARGS_TWO || argc == ARGS_THREE), "GetRingtoneUri: requires 3 parameters maximum");
609     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
610     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
611     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
612         for (size_t i = PARAM0; i < argc; i++) {
613             napi_valuetype valueType = napi_undefined;
614             napi_typeof(env, argv[i], &valueType);
615             if (i == PARAM0) {
616                 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
617             } else if (i == PARAM1 && valueType == napi_number) {
618                 napi_get_value_int32(env, argv[i], &asyncContext->ringtoneType);
619             } else if (i == PARAM2 && valueType == napi_function) {
620                 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
621                 break;
622             } else {
623                 NAPI_ASSERT(env, false, "GetRingtoneUri: type mismatch");
624             }
625         }
626 
627         if (asyncContext->callbackRef == nullptr) {
628             napi_create_promise(env, &asyncContext->deferred, &result);
629         }
630 
631         napi_create_string_utf8(env, "GetRingtoneUri", NAPI_AUTO_LENGTH, &resource);
632         status = napi_create_async_work(env, nullptr, resource, AsyncGetRingtoneUri,
633             GetSystemSoundUriAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
634         if (status != napi_ok) {
635             MEDIA_LOGE("GetRingtoneUri: Failed to get create async work");
636             napi_get_undefined(env, &result);
637         } else {
638             napi_queue_async_work(env, asyncContext->work);
639             asyncContext.release();
640         }
641     }
642 
643     return result;
644 }
645 
AsyncGetRingtoneUri(napi_env env,void * data)646 void SystemSoundManagerNapi::AsyncGetRingtoneUri(napi_env env, void *data)
647 {
648     SystemSoundManagerAsyncContext *context
649         = static_cast<SystemSoundManagerAsyncContext *>(data);
650     context->uri = context->objectInfo->sysSoundMgrClient_->GetRingtoneUri(
651         context->abilityContext_, static_cast<RingtoneType>(context->ringtoneType));
652     context->status = SUCCESS;
653 }
654 
GetRingtonePlayerAsyncCallbackComp(napi_env env,napi_status status,void * data)655 void SystemSoundManagerNapi::GetRingtonePlayerAsyncCallbackComp(napi_env env, napi_status status, void* data)
656 {
657     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
658     napi_value getPlayerCallback = nullptr;
659     napi_value retVal = nullptr;
660     napi_value result[2] = {};
661     napi_value rngplrResult = nullptr;
662 
663     if (context->ringtonePlayer != nullptr) {
664         rngplrResult = RingtonePlayerNapi::GetRingtonePlayerInstance(env, context->ringtonePlayer);
665         if (rngplrResult == nullptr) {
666             napi_value message = nullptr;
667             napi_create_string_utf8(env, "GetRingtonePlayer Error: Operation is not supported or failed",
668                 NAPI_AUTO_LENGTH, &message);
669             napi_create_error(env, nullptr, message, &result[PARAM0]);
670             napi_get_undefined(env, &result[PARAM1]);
671         } else {
672             napi_get_undefined(env, &result[0]);
673             result[PARAM1] = rngplrResult;
674         }
675     } else {
676         MEDIA_LOGE("Failed to get system tone player!");
677         napi_value message = nullptr;
678         napi_create_string_utf8(env, "GetRingtonePlayer Error: Operation is not supported or failed",
679             NAPI_AUTO_LENGTH, &message);
680         napi_create_error(env, nullptr, message, &result[PARAM0]);
681         napi_get_undefined(env, &result[PARAM1]);
682     }
683 
684     if (context->deferred) {
685         if (!context->status) {
686             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
687         } else {
688             napi_reject_deferred(env, context->deferred, result[PARAM0]);
689         }
690     } else {
691         napi_get_reference_value(env, context->callbackRef, &getPlayerCallback);
692         napi_call_function(env, nullptr, getPlayerCallback, ARGS_TWO, result, &retVal);
693         napi_delete_reference(env, context->callbackRef);
694     }
695     napi_delete_async_work(env, context->work);
696 
697     delete context;
698     context = nullptr;
699 }
700 
GetRingtonePlayer(napi_env env,napi_callback_info info)701 napi_value SystemSoundManagerNapi::GetRingtonePlayer(napi_env env, napi_callback_info info)
702 {
703     napi_value result = nullptr;
704     napi_value resource = nullptr;
705     size_t argc = ARGS_THREE;
706     napi_value argv[ARGS_THREE] = {0};
707     napi_value thisVar = nullptr;
708     const int32_t refCount = 1;
709 
710     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
711     napi_get_undefined(env, &result);
712     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
713         "GetRingtonePlayer: Failed to retrieve details about the callback");
714 
715     NAPI_ASSERT(env, (argc == ARGS_TWO || argc == ARGS_THREE), "GetRingtonePlayer: require 3 parameters max");
716     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
717     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
718     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
719         for (size_t i = PARAM0; i < argc; i++) {
720             napi_valuetype valueType = napi_undefined;
721             napi_typeof(env, argv[i], &valueType);
722             if (i == PARAM0) {
723                 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
724             } else if (i == PARAM1 && valueType == napi_number) {
725                 napi_get_value_int32(env, argv[i], &asyncContext->ringtoneType);
726             } else if (i == PARAM2 && valueType == napi_function) {
727                 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
728                 break;
729             } else {
730                 NAPI_ASSERT(env, false, "GetRingtonePlayer: type mismatch");
731             }
732         }
733 
734         if (asyncContext->callbackRef == nullptr) {
735             napi_create_promise(env, &asyncContext->deferred, &result);
736         }
737 
738         napi_create_string_utf8(env, "GetRingtonePlayer", NAPI_AUTO_LENGTH, &resource);
739         status = napi_create_async_work(env, nullptr, resource, AsyncGetRingtonePlayer,
740             GetRingtonePlayerAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
741         if (status != napi_ok) {
742             MEDIA_LOGE("GetRingtonePlayer: Failed to get create async work");
743             napi_get_undefined(env, &result);
744         } else {
745             napi_queue_async_work(env, asyncContext->work);
746             asyncContext.release();
747         }
748     }
749 
750     return result;
751 }
752 
AsyncGetRingtonePlayer(napi_env env,void * data)753 void SystemSoundManagerNapi::AsyncGetRingtonePlayer(napi_env env, void *data)
754 {
755     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
756     std::shared_ptr<RingtonePlayer> ringtonePlayer =context->objectInfo->sysSoundMgrClient_->
757         GetRingtonePlayer(context->abilityContext_, static_cast<RingtoneType>(context->ringtoneType));
758     if (ringtonePlayer != nullptr) {
759         context->ringtonePlayer = ringtonePlayer;
760         context->status = SUCCESS;
761     } else {
762         context->status = ERROR;
763     }
764 }
765 
SetSystemToneUri(napi_env env,napi_callback_info info)766 napi_value SystemSoundManagerNapi::SetSystemToneUri(napi_env env, napi_callback_info info)
767 {
768     napi_value result = nullptr;
769     napi_value resource = nullptr;
770     size_t argc = ARGS_FOUR;
771     napi_value argv[ARGS_FOUR] = {0};
772     napi_value thisVar = nullptr;
773     const int32_t refCount = 1;
774 
775     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
776     napi_get_undefined(env, &result);
777     CHECK_AND_RETURN_RET_LOG(status == napi_ok && thisVar != nullptr, result, "SetSystemToneUri: get_cb_info failed");
778 
779     NAPI_ASSERT(env, (argc == ARGS_THREE || argc == ARGS_FOUR), "SetSystemToneUri: requires 4 parameters maximum");
780     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
781     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
782     CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
783         "SetSystemToneUri: Failed to unwrap object");
784 
785     for (size_t i = PARAM0; i < argc; i++) {
786         napi_valuetype valueType = napi_undefined;
787         napi_typeof(env, argv[i], &valueType);
788         if (i == PARAM0) {
789             asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
790         } else if (i == PARAM1 && valueType == napi_string) {
791             asyncContext->uri = ExtractStringToEnv(env, argv[i]);
792         } else if (i == PARAM2 && valueType == napi_number) {
793             napi_get_value_int32(env, argv[i], &asyncContext->systemToneType);
794         } else if (i == PARAM3 && valueType == napi_function) {
795             napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
796             break;
797         } else {
798             CHECK_AND_CONTINUE(!(i == PARAM1) && (valueType == napi_null));
799             NAPI_ASSERT(env, false, "SetSystemToneUri: type mismatch");
800         }
801     }
802 
803     if (asyncContext->callbackRef == nullptr) {
804         napi_create_promise(env, &asyncContext->deferred, &result);
805     }
806 
807     napi_create_string_utf8(env, "SetSystemToneUri", NAPI_AUTO_LENGTH, &resource);
808     status = napi_create_async_work(env, nullptr, resource, AsyncSetSystemToneUri,
809         SetSystemSoundUriAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
810     if (status != napi_ok) {
811         MEDIA_LOGE("Failed to get create async work");
812         napi_get_undefined(env, &result);
813     } else {
814         napi_queue_async_work(env, asyncContext->work);
815         asyncContext.release();
816     }
817 
818     return result;
819 }
820 
AsyncSetSystemToneUri(napi_env env,void * data)821 void SystemSoundManagerNapi::AsyncSetSystemToneUri(napi_env env, void *data)
822 {
823     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
824     if (context->uri.empty()) {
825         context->status = ERROR;
826     } else {
827         context->status = context->objectInfo->sysSoundMgrClient_->SetSystemToneUri(
828             context->abilityContext_, context->uri, static_cast<SystemToneType>(context->systemToneType));
829     }
830     if (context->status) {
831         context->errCode = NAPI_ERR_IO_ERROR;
832         context->errMessage = "I/O error. Uri is empty, can not found.";
833     }
834 }
835 
GetSystemToneUri(napi_env env,napi_callback_info info)836 napi_value SystemSoundManagerNapi::GetSystemToneUri(napi_env env, napi_callback_info info)
837 {
838     napi_status status;
839     napi_value result = nullptr;
840     napi_value resource = nullptr;
841     size_t argc = ARGS_THREE;
842     napi_value argv[ARGS_THREE] = {0};
843     napi_value thisVar = nullptr;
844     const int32_t refCount = 1;
845 
846     status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
847     napi_get_undefined(env, &result);
848     CHECK_AND_RETURN_RET_LOG(status == napi_ok && thisVar != nullptr, result,
849         "GetSystemToneUri: Failed to retrieve details about the callback");
850 
851     NAPI_ASSERT(env, (argc == ARGS_TWO || argc == ARGS_THREE), "GetSystemToneUri: requires 3 parameters maximum");
852     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
853     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
854     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
855         for (size_t i = PARAM0; i < argc; i++) {
856             napi_valuetype valueType = napi_undefined;
857             napi_typeof(env, argv[i], &valueType);
858             if (i == PARAM0) {
859                 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
860             } else if (i == PARAM1 && valueType == napi_number) {
861                 napi_get_value_int32(env, argv[i], &asyncContext->systemToneType);
862             } else if (i == PARAM2 && valueType == napi_function) {
863                 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
864                 break;
865             } else {
866                 NAPI_ASSERT(env, false, "GetSystemToneUri: type mismatch");
867             }
868         }
869 
870         if (asyncContext->callbackRef == nullptr) {
871             napi_create_promise(env, &asyncContext->deferred, &result);
872         }
873 
874         napi_create_string_utf8(env, "GetSystemToneUri", NAPI_AUTO_LENGTH, &resource);
875         status = napi_create_async_work(env, nullptr, resource, AsyncGetSystemToneUri,
876             GetSystemSoundUriAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
877         if (status != napi_ok) {
878             MEDIA_LOGE("GetSystemToneUri: Failed to get create async work");
879             napi_get_undefined(env, &result);
880         } else {
881             napi_queue_async_work(env, asyncContext->work);
882             asyncContext.release();
883         }
884     }
885 
886     return result;
887 }
888 
AsyncGetSystemToneUri(napi_env env,void * data)889 void SystemSoundManagerNapi::AsyncGetSystemToneUri(napi_env env, void *data)
890 {
891     SystemSoundManagerAsyncContext *context
892         = static_cast<SystemSoundManagerAsyncContext *>(data);
893     context->uri = context->objectInfo->sysSoundMgrClient_->GetSystemToneUri(
894         context->abilityContext_, static_cast<SystemToneType>(context->systemToneType));
895     context->status = SUCCESS;
896 }
897 
GetSystemTonePlayer(napi_env env,napi_callback_info info)898 napi_value SystemSoundManagerNapi::GetSystemTonePlayer(napi_env env, napi_callback_info info)
899 {
900     napi_value result = nullptr;
901     napi_value resource = nullptr;
902     size_t argc = ARGS_THREE;
903     napi_value argv[ARGS_THREE] = {0};
904     napi_value thisVar = nullptr;
905     const int32_t refCount = 1;
906 
907     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
908     napi_get_undefined(env, &result);
909     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
910         "GetSystemTonePlayer: Failed to retrieve details about the callback");
911 
912     NAPI_ASSERT(env, (argc == ARGS_TWO || argc == ARGS_THREE), "GetSystemTonePlayer: require 3 parameters max");
913     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
914     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
915     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
916         for (size_t i = PARAM0; i < argc; i++) {
917             napi_valuetype valueType = napi_undefined;
918             napi_typeof(env, argv[i], &valueType);
919             if (i == PARAM0) {
920                 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
921             } else if (i == PARAM1 && valueType == napi_number) {
922                 napi_get_value_int32(env, argv[i], &asyncContext->systemToneType);
923             } else if (i == PARAM2 && valueType == napi_function) {
924                 napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef);
925                 break;
926             } else {
927                 NAPI_ASSERT(env, false, "GetSystemTonePlayer: type mismatch");
928             }
929         }
930 
931         if (asyncContext->callbackRef == nullptr) {
932             napi_create_promise(env, &asyncContext->deferred, &result);
933         }
934 
935         napi_create_string_utf8(env, "GetSystemTonePlayer", NAPI_AUTO_LENGTH, &resource);
936         status = napi_create_async_work(env, nullptr, resource, AsyncGetSystemTonePlayer,
937             GetSystemTonePlayerAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
938         if (status != napi_ok) {
939             MEDIA_LOGE("GetRingtonePlayer: Failed to get create async work");
940             napi_get_undefined(env, &result);
941         } else {
942             napi_queue_async_work(env, asyncContext->work);
943             asyncContext.release();
944         }
945     }
946 
947     return result;
948 }
949 
AsyncGetSystemTonePlayer(napi_env env,void * data)950 void SystemSoundManagerNapi::AsyncGetSystemTonePlayer(napi_env env, void *data)
951 {
952     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
953     std::shared_ptr<SystemTonePlayer> systemTonePlayer =context->objectInfo->sysSoundMgrClient_->
954         GetSystemTonePlayer(context->abilityContext_, static_cast<SystemToneType>(context->systemToneType));
955     if (systemTonePlayer != nullptr) {
956         context->systemTonePlayer = systemTonePlayer;
957         context->status = SUCCESS;
958     } else {
959         context->status = ERROR;
960     }
961 }
962 
GetSystemTonePlayerAsyncCallbackComp(napi_env env,napi_status status,void * data)963 void SystemSoundManagerNapi::GetSystemTonePlayerAsyncCallbackComp(napi_env env, napi_status status, void* data)
964 {
965     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
966     napi_value getPlayerCallback = nullptr;
967     napi_value retVal = nullptr;
968     napi_value result[2] = {};
969     napi_value rngplrResult = nullptr;
970 
971     if (context->systemTonePlayer != nullptr) {
972         rngplrResult = SystemTonePlayerNapi::GetSystemTonePlayerInstance(env, context->systemTonePlayer);
973         if (rngplrResult == nullptr) {
974             napi_value message = nullptr;
975             napi_create_string_utf8(env, "GetSystemTonePlayer Error: Operation is not supported or failed",
976                 NAPI_AUTO_LENGTH, &message);
977             napi_create_error(env, nullptr, message, &result[PARAM0]);
978             napi_get_undefined(env, &result[PARAM1]);
979         } else {
980             napi_get_undefined(env, &result[0]);
981             result[PARAM1] = rngplrResult;
982         }
983     } else {
984         MEDIA_LOGE("Failed to get system tone player!");
985         napi_value message = nullptr;
986         napi_create_string_utf8(env, "GetSystemTonePlayer Error: Operation is not supported or failed",
987             NAPI_AUTO_LENGTH, &message);
988         napi_create_error(env, nullptr, message, &result[PARAM0]);
989         napi_get_undefined(env, &result[PARAM1]);
990     }
991 
992     if (context->deferred) {
993         if (!context->status) {
994             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
995         } else {
996             napi_reject_deferred(env, context->deferred, result[PARAM0]);
997         }
998     } else {
999         napi_get_reference_value(env, context->callbackRef, &getPlayerCallback);
1000         napi_call_function(env, nullptr, getPlayerCallback, ARGS_TWO, result, &retVal);
1001         napi_delete_reference(env, context->callbackRef);
1002     }
1003     napi_delete_async_work(env, context->work);
1004 
1005     delete context;
1006     context = nullptr;
1007 }
1008 
CreateCustomizedToneAttrs(napi_env env,napi_callback_info info)1009 napi_value SystemSoundManagerNapi::CreateCustomizedToneAttrs(napi_env env, napi_callback_info info)
1010 {
1011     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
1012         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
1013         "No system permission");
1014     napi_status status;
1015     napi_value result = nullptr;
1016     std::shared_ptr<ToneAttrs> nativeToneAttrs = make_shared<ToneAttrs>("default",
1017         "default", "default", CUSTOMISED, TONE_CATEGORY_INVALID);
1018     status = ToneAttrsNapi::NewInstance(env, nativeToneAttrs, result);
1019     if (status == napi_ok) {
1020         return result;
1021     } else {
1022         MEDIA_LOGE("CreateCustomizedToneAttrs: new instance can not be obtained.");
1023     }
1024     napi_get_undefined(env, &result);
1025     return result;
1026 }
1027 
GetDefaultRingtoneAttrs(napi_env env,napi_callback_info info)1028 napi_value SystemSoundManagerNapi::GetDefaultRingtoneAttrs(napi_env env, napi_callback_info info)
1029 {
1030     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
1031         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
1032         "No system permission");
1033     napi_value result = nullptr;
1034     napi_value resource = nullptr;
1035     napi_value thisVar = nullptr;
1036     size_t argc = ARGS_TWO;
1037     napi_value argv[ARGS_TWO] = {0};
1038     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1039     napi_get_undefined(env, &result);
1040     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
1041         "GetDefaultRingtoneAttrs: Failed to retrieve details about the callback");
1042     CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1043         NAPI_ERR_INPUT_INVALID), "invalid arguments");
1044     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
1045     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1046     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1047         for (size_t i = PARAM0; i < argc; i++) {
1048             napi_valuetype valueType = napi_undefined;
1049             napi_typeof(env, argv[i], &valueType);
1050             if (i == PARAM0) {
1051                 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
1052             } else if (i == PARAM1 && valueType == napi_number) {
1053                 napi_get_value_int32(env, argv[i], &asyncContext->ringtoneType);
1054             }
1055         }
1056         CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr && (asyncContext->ringtoneType == CARD_0 ||
1057             asyncContext->ringtoneType == CARD_1),
1058             ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "Parameter error");
1059         napi_create_promise(env, &asyncContext->deferred, &result);
1060         napi_create_string_utf8(env, "GetDefaultRingtoneAttrs", NAPI_AUTO_LENGTH, &resource);
1061         status = napi_create_async_work(env, nullptr, resource, AsyncGetDefaultRingtoneAttrs,
1062             GetDefaultAttrsAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1063         if (status != napi_ok) {
1064             napi_get_undefined(env, &result);
1065         } else {
1066             napi_queue_async_work(env, asyncContext->work);
1067             asyncContext.release();
1068         }
1069     }
1070     return result;
1071 }
1072 
AsyncGetDefaultRingtoneAttrs(napi_env env,void * data)1073 void SystemSoundManagerNapi::AsyncGetDefaultRingtoneAttrs(napi_env env, void *data)
1074 {
1075     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
1076     if (context->objectInfo->sysSoundMgrClient_ != nullptr) {
1077         context->toneAttrs = context->objectInfo->sysSoundMgrClient_->GetDefaultRingtoneAttrs(
1078             context->abilityContext_, static_cast<RingtoneType>(context->ringtoneType));
1079     }
1080     if (context->toneAttrs == nullptr) {
1081         context->status = ERROR;
1082         context->errCode = NAPI_ERR_IO_ERROR;
1083         context->errMessage = "I/O error. Can not get default ring tone.";
1084     }
1085 }
1086 
GetDefaultAttrsAsyncCallbackComp(napi_env env,napi_status status,void * data)1087 void SystemSoundManagerNapi::GetDefaultAttrsAsyncCallbackComp(napi_env env, napi_status status, void* data)
1088 {
1089     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
1090     napi_value result[2] = {};
1091 
1092     if (context->status == napi_ok) {
1093         napi_get_undefined(env, &result[PARAM0]);
1094         context->status = ToneAttrsNapi::NewInstance(env, context->toneAttrs, result[PARAM1]);
1095     } else {
1096         result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
1097         napi_get_undefined(env, &result[PARAM1]);
1098     }
1099 
1100     if (context->deferred) {
1101         if (!context->status) {
1102             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
1103         } else {
1104             napi_reject_deferred(env, context->deferred, result[PARAM0]);
1105         }
1106     }
1107 
1108     napi_delete_async_work(env, context->work);
1109     delete context;
1110     context = nullptr;
1111 }
1112 
GetRingtoneAttrList(napi_env env,napi_callback_info info)1113 napi_value SystemSoundManagerNapi::GetRingtoneAttrList(napi_env env, napi_callback_info info)
1114 {
1115     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
1116         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
1117         "No system permission");
1118     napi_value result = nullptr;
1119     napi_value resource = nullptr;
1120     napi_value thisVar = nullptr;
1121     size_t argc = ARGS_TWO;
1122     napi_value argv[ARGS_TWO] = {0};
1123 
1124     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1125     napi_get_undefined(env, &result);
1126     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
1127         "GetRingtoneAttrList: Failed to retrieve details about the callback");
1128     CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1129         NAPI_ERR_INPUT_INVALID), "invalid arguments");
1130     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
1131     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1132     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1133         for (size_t i = PARAM0; i < argc; i++) {
1134             napi_valuetype valueType = napi_undefined;
1135             napi_typeof(env, argv[i], &valueType);
1136             if (i == PARAM0) {
1137                 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
1138             } else if (i == PARAM1 && valueType == napi_number) {
1139                 napi_get_value_int32(env, argv[i], &asyncContext->ringtoneType);
1140             }
1141         }
1142         CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr && (asyncContext->ringtoneType == CARD_0 ||
1143             asyncContext->ringtoneType == CARD_1),
1144             ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "Parameter error");
1145         napi_create_promise(env, &asyncContext->deferred, &result);
1146         napi_create_string_utf8(env, "GetRingtoneAttrList", NAPI_AUTO_LENGTH, &resource);
1147         status = napi_create_async_work(env, nullptr, resource, AsyncGetRingtoneAttrList,
1148             GetToneAttrsListAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1149         if (status != napi_ok) {
1150             napi_get_undefined(env, &result);
1151         } else {
1152             napi_queue_async_work(env, asyncContext->work);
1153             asyncContext.release();
1154         }
1155     }
1156     return result;
1157 }
1158 
AsyncGetRingtoneAttrList(napi_env env,void * data)1159 void SystemSoundManagerNapi::AsyncGetRingtoneAttrList(napi_env env, void *data)
1160 {
1161     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
1162     if (context->objectInfo->sysSoundMgrClient_ != nullptr) {
1163         context->toneAttrsArray = context->objectInfo->sysSoundMgrClient_->GetRingtoneAttrList(
1164             context->abilityContext_, static_cast<RingtoneType>(context->ringtoneType));
1165     }
1166     if (context->toneAttrsArray.empty()) {
1167         context->status = ERROR;
1168         context->errCode = NAPI_ERR_IO_ERROR;
1169         context->errMessage = "I/O error. Can not get default ring tone.";
1170     }
1171 }
1172 
GetToneAttrsListAsyncCallbackComp(napi_env env,napi_status status,void * data)1173 void SystemSoundManagerNapi::GetToneAttrsListAsyncCallbackComp(napi_env env, napi_status status, void* data)
1174 {
1175     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
1176     napi_value result[2] = {};
1177     if (context->status == napi_ok) {
1178         napi_get_undefined(env, &result[PARAM0]);
1179         context->status = napi_create_array_with_length(env, (context->toneAttrsArray).size(), &result[PARAM1]);
1180         size_t count = 0;
1181         for (auto &toneAttrs : context->toneAttrsArray) {
1182             napi_value jsToneAttrs = nullptr;
1183             ToneAttrsNapi::NewInstance(env, toneAttrs, jsToneAttrs);
1184             context->status = napi_set_element(env, result[PARAM1], count, jsToneAttrs);
1185             count ++;
1186         }
1187     } else {
1188         result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
1189         napi_get_undefined(env, &result[PARAM1]);
1190     }
1191     if (context->deferred) {
1192         if (!context->status) {
1193             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
1194         } else {
1195             napi_reject_deferred(env, context->deferred, result[PARAM0]);
1196         }
1197     }
1198 
1199     napi_delete_async_work(env, context->work);
1200     delete context;
1201     context = nullptr;
1202 }
1203 
GetDefaultSystemToneAttrs(napi_env env,napi_callback_info info)1204 napi_value SystemSoundManagerNapi::GetDefaultSystemToneAttrs(napi_env env, napi_callback_info info)
1205 {
1206     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
1207         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
1208         "No system permission");
1209     napi_value result = nullptr;
1210     napi_value resource = nullptr;
1211     napi_value thisVar = nullptr;
1212     size_t argc = ARGS_TWO;
1213     napi_value argv[ARGS_TWO] = {0};
1214 
1215     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1216     napi_get_undefined(env, &result);
1217     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
1218         "GetDefaultSystemToneAttrs: Failed to retrieve details about the callback");
1219     CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1220         NAPI_ERR_INPUT_INVALID), "invalid arguments");
1221     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
1222     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1223     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1224         for (size_t i = PARAM0; i < argc; i++) {
1225             napi_valuetype valueType = napi_undefined;
1226             napi_typeof(env, argv[i], &valueType);
1227             if (i == PARAM0) {
1228                 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
1229             } else if (i == PARAM1 && valueType == napi_number) {
1230                 napi_get_value_int32(env, argv[i], &asyncContext->systemToneType);
1231             }
1232         }
1233         CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr && (asyncContext->systemToneType == CARD_0 ||
1234             asyncContext->systemToneType == CARD_1 || asyncContext->systemToneType == SYSTEM_NOTIFICATION),
1235             ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "Parameter error");
1236         napi_create_promise(env, &asyncContext->deferred, &result);
1237         napi_create_string_utf8(env, "GetDefaultSystemToneAttrs", NAPI_AUTO_LENGTH, &resource);
1238         status = napi_create_async_work(env, nullptr, resource, AsyncGetDefaultSystemToneAttrs,
1239             GetDefaultAttrsAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1240         if (status != napi_ok) {
1241             napi_get_undefined(env, &result);
1242         } else {
1243             napi_queue_async_work(env, asyncContext->work);
1244             asyncContext.release();
1245         }
1246     }
1247     return result;
1248 }
1249 
AsyncGetDefaultSystemToneAttrs(napi_env env,void * data)1250 void SystemSoundManagerNapi::AsyncGetDefaultSystemToneAttrs(napi_env env, void *data)
1251 {
1252     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
1253     if (context->objectInfo->sysSoundMgrClient_ != nullptr) {
1254         context->toneAttrs= context->objectInfo->sysSoundMgrClient_->GetDefaultSystemToneAttrs(
1255             context->abilityContext_, static_cast<SystemToneType>(context->systemToneType));
1256     }
1257     if (context->toneAttrs == nullptr) {
1258         context->status = ERROR;
1259         context->errCode = NAPI_ERR_IO_ERROR;
1260         context->errMessage = "I/O error. Can not get default system tone.";
1261     }
1262 }
1263 
GetSystemToneAttrList(napi_env env,napi_callback_info info)1264 napi_value SystemSoundManagerNapi::GetSystemToneAttrList(napi_env env, napi_callback_info info)
1265 {
1266     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
1267         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
1268         "No system permission");
1269     napi_value result = nullptr;
1270     napi_value resource = nullptr;
1271     napi_value thisVar = nullptr;
1272     size_t argc = ARGS_TWO;
1273     napi_value argv[ARGS_TWO] = {0};
1274 
1275     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1276     napi_get_undefined(env, &result);
1277     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
1278         "GetSystemToneAttrList: Failed to retrieve details about the callback");
1279     CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1280         NAPI_ERR_INPUT_INVALID), "invalid arguments");
1281     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
1282     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1283     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1284         for (size_t i = PARAM0; i < argc; i ++) {
1285             napi_valuetype valueType = napi_undefined;
1286             napi_typeof(env, argv[i], &valueType);
1287             if (i == PARAM0) {
1288                 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
1289             } else if (i == PARAM1 && valueType == napi_number) {
1290                 napi_get_value_int32(env, argv[i], &asyncContext->systemToneType);
1291             }
1292         }
1293         CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr && (asyncContext->systemToneType == CARD_0 ||
1294             asyncContext->systemToneType == CARD_1 || asyncContext->systemToneType == SYSTEM_NOTIFICATION),
1295             ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "Parameter error");
1296         napi_create_promise(env, &asyncContext->deferred, &result);
1297         napi_create_string_utf8(env, "GetSystemToneAttrList", NAPI_AUTO_LENGTH, &resource);
1298         status = napi_create_async_work(env, nullptr, resource, AsyncGetSystemToneAttrList,
1299             GetToneAttrsListAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1300         if (status != napi_ok) {
1301             napi_get_undefined(env, &result);
1302         } else {
1303             napi_queue_async_work(env, asyncContext->work);
1304             asyncContext.release();
1305         }
1306     }
1307     return result;
1308 }
1309 
AsyncGetSystemToneAttrList(napi_env env,void * data)1310 void SystemSoundManagerNapi::AsyncGetSystemToneAttrList(napi_env env, void *data)
1311 {
1312     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
1313     if (context->objectInfo->sysSoundMgrClient_ != nullptr) {
1314         context->toneAttrsArray = context->objectInfo->sysSoundMgrClient_->GetSystemToneAttrList(
1315             context->abilityContext_, static_cast<SystemToneType>(context->systemToneType));
1316     }
1317     if (context->toneAttrsArray.empty()) {
1318         context->status = ERROR;
1319         context->errCode = NAPI_ERR_IO_ERROR;
1320         context->errMessage = "I/O error. Can not get default system tone.";
1321     }
1322 }
1323 
SetAlarmToneUri(napi_env env,napi_callback_info info)1324 napi_value SystemSoundManagerNapi::SetAlarmToneUri(napi_env env, napi_callback_info info)
1325 {
1326     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
1327         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
1328         "No system permission");
1329     napi_value result = nullptr;
1330     napi_value resource = nullptr;
1331     napi_value thisVar = nullptr;
1332     size_t argc = ARGS_TWO;
1333     napi_value argv[ARGS_TWO] = {0};
1334     char buffer[SIZE];
1335     size_t res = 0;
1336 
1337     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1338     napi_get_undefined(env, &result);
1339     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
1340         "SetAlarmToneUri: Failed to retrieve details about the callback");
1341     CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1342         NAPI_ERR_INPUT_INVALID), "invalid arguments");
1343     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
1344     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1345     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1346         for (size_t i = PARAM0; i < argc; i++) {
1347             napi_valuetype valueType = napi_undefined;
1348             napi_typeof(env, argv[i], &valueType);
1349             if (i == PARAM0) {
1350                 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
1351             } else if (i == PARAM1 &&  valueType == napi_string) {
1352                 napi_get_value_string_utf8(env, argv[i], buffer, SIZE, &res);
1353                 asyncContext->uri = std::string(buffer);
1354             }
1355         }
1356         CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
1357             ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
1358         CHECK_AND_RETURN_RET_LOG(!asyncContext->uri.empty(), ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1359             NAPI_ERR_INPUT_INVALID), "invalid arguments");
1360         napi_create_promise(env, &asyncContext->deferred, &result);
1361         napi_create_string_utf8(env, "SetAlarmToneUri", NAPI_AUTO_LENGTH, &resource);
1362         status = napi_create_async_work(env, nullptr, resource, AsyncSetAlarmToneUri,
1363             SetSystemSoundUriAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1364         if (status != napi_ok) {
1365             napi_get_undefined(env, &result);
1366         } else {
1367             napi_queue_async_work(env, asyncContext->work);
1368             asyncContext.release();
1369         }
1370     }
1371     return result;
1372 }
1373 
AsyncSetAlarmToneUri(napi_env env,void * data)1374 void SystemSoundManagerNapi::AsyncSetAlarmToneUri(napi_env env, void *data)
1375 {
1376     int32_t result = ERROR;
1377     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
1378     if (context->objectInfo->sysSoundMgrClient_ != nullptr) {
1379         result = context->objectInfo->sysSoundMgrClient_->SetAlarmToneUri(
1380             context->abilityContext_, context->uri);
1381     }
1382     if (result == TYPEERROR) {
1383         context->status = ERROR;
1384         context->errCode = NAPI_ERR_URI_ERROR;
1385         context->errMessage = "Tone type mismatch. Uri of tone is not alarm.";
1386     } else if (result == ERROR) {
1387         context->status = ERROR;
1388         context->errCode = NAPI_ERR_IO_ERROR;
1389         context->errMessage = "I/O error. Uri is empty, can not found.";
1390     }
1391 }
1392 
GetAlarmToneUri(napi_env env,napi_callback_info info)1393 napi_value SystemSoundManagerNapi::GetAlarmToneUri(napi_env env, napi_callback_info info)
1394 {
1395     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
1396         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
1397         "No system permission");
1398     napi_value result = nullptr;
1399     napi_value resource = nullptr;
1400     napi_value thisVar = nullptr;
1401     size_t argc = ARGS_ONE;
1402     napi_value argv[ARGS_ONE] = {0};
1403     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1404     napi_get_undefined(env, &result);
1405     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
1406         "GetAlarmToneUri: Failed to retrieve details about the callback");
1407     CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1408         NAPI_ERR_INPUT_INVALID), "invalid arguments");
1409     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
1410     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1411     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1412         asyncContext->abilityContext_ = GetAbilityContext(env, argv[0]);
1413         CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
1414             ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
1415         napi_create_promise(env, &asyncContext->deferred, &result);
1416         napi_create_string_utf8(env, "GetAlarmToneUri", NAPI_AUTO_LENGTH, &resource);
1417         status = napi_create_async_work(env, nullptr, resource, AsyncGetAlarmToneUri,
1418             GetSystemSoundUriAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1419         if (status != napi_ok) {
1420             napi_get_undefined(env, &result);
1421         } else {
1422             napi_queue_async_work(env, asyncContext->work);
1423             asyncContext.release();
1424         }
1425     }
1426     return result;
1427 }
1428 
AsyncGetAlarmToneUri(napi_env env,void * data)1429 void SystemSoundManagerNapi::AsyncGetAlarmToneUri(napi_env env, void *data)
1430 {
1431     SystemSoundManagerAsyncContext *context
1432         = static_cast<SystemSoundManagerAsyncContext *>(data);
1433     if (context->objectInfo->sysSoundMgrClient_ != nullptr) {
1434         context->uri = context->objectInfo->sysSoundMgrClient_->GetAlarmToneUri(
1435             context->abilityContext_);
1436     }
1437     if (context->uri.empty()) {
1438         context->status = ERROR;
1439         context->errCode = NAPI_ERR_IO_ERROR;
1440         context->errMessage = "I/O error. Uri is empty, can not found.";
1441     } else {
1442         context->status = SUCCESS;
1443     }
1444 }
1445 
GetDefaultAlarmToneAttrs(napi_env env,napi_callback_info info)1446 napi_value SystemSoundManagerNapi::GetDefaultAlarmToneAttrs(napi_env env, napi_callback_info info)
1447 {
1448     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
1449         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
1450         "No system permission");
1451     napi_value result = nullptr;
1452     napi_value resource = nullptr;
1453     napi_value thisVar = nullptr;
1454     size_t argc = ARGS_ONE;
1455     napi_value argv[ARGS_ONE] = {0};
1456 
1457     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1458     napi_get_undefined(env, &result);
1459     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
1460         "GetDefaultAlarmToneAttrs: Failed to retrieve details about the callback");
1461     CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1462         NAPI_ERR_INPUT_INVALID), "invalid arguments");
1463     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
1464     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1465     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1466         asyncContext->abilityContext_ = GetAbilityContext(env, argv[PARAM0]);
1467         CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
1468             ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
1469         napi_create_promise(env, &asyncContext->deferred, &result);
1470         napi_create_string_utf8(env, "GetDefaultAlarmToneAttrs", NAPI_AUTO_LENGTH, &resource);
1471         status = napi_create_async_work(env, nullptr, resource, AsyncGetDefaultAlarmToneAttrs,
1472             GetDefaultAttrsAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1473         if (status != napi_ok) {
1474             napi_get_undefined(env, &result);
1475         } else {
1476             napi_queue_async_work(env, asyncContext->work);
1477             asyncContext.release();
1478         }
1479     }
1480     return result;
1481 }
1482 
AsyncGetDefaultAlarmToneAttrs(napi_env env,void * data)1483 void SystemSoundManagerNapi::AsyncGetDefaultAlarmToneAttrs(napi_env env, void *data)
1484 {
1485     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
1486     if (context->objectInfo->sysSoundMgrClient_ != nullptr) {
1487         context->toneAttrs= context->objectInfo->sysSoundMgrClient_->GetDefaultAlarmToneAttrs(
1488             context->abilityContext_);
1489     }
1490     if (context->toneAttrs == nullptr) {
1491         context->status = ERROR;
1492         context->errCode = NAPI_ERR_IO_ERROR;
1493         context->errMessage = "I/O error. Can not get default alarm tone.";
1494     }
1495 }
1496 
GetAlarmToneAttrList(napi_env env,napi_callback_info info)1497 napi_value SystemSoundManagerNapi::GetAlarmToneAttrList(napi_env env, napi_callback_info info)
1498 {
1499     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
1500         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
1501         "No system permission");
1502     napi_value result = nullptr;
1503     napi_value resource = nullptr;
1504     napi_value thisVar = nullptr;
1505     size_t argc = ARGS_ONE;
1506     napi_value argv[ARGS_ONE] = {};
1507     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1508     napi_get_undefined(env, &result);
1509     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
1510         "GetAlarmToneAttrList: Failed to retrieve details about the callback");
1511     CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1512         NAPI_ERR_INPUT_INVALID), "invalid arguments");
1513     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
1514     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1515     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1516         asyncContext->abilityContext_ = GetAbilityContext(env, argv[0]);
1517         CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
1518             ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
1519         napi_create_promise(env, &asyncContext->deferred, &result);
1520         napi_create_string_utf8(env, "GetAlarmToneAttrList", NAPI_AUTO_LENGTH, &resource);
1521         status = napi_create_async_work(env, nullptr, resource, AsyncGetAlarmToneAttrList,
1522             GetToneAttrsListAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1523         if (status != napi_ok) {
1524             napi_get_undefined(env, &result);
1525         } else {
1526             napi_queue_async_work(env, asyncContext->work);
1527             asyncContext.release();
1528         }
1529     }
1530     return result;
1531 }
1532 
AsyncGetAlarmToneAttrList(napi_env env,void * data)1533 void SystemSoundManagerNapi::AsyncGetAlarmToneAttrList(napi_env env, void *data)
1534 {
1535     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
1536     if (context->objectInfo->sysSoundMgrClient_ != nullptr) {
1537         context->toneAttrsArray = context->objectInfo->sysSoundMgrClient_->GetAlarmToneAttrList(
1538             context->abilityContext_);
1539     }
1540     if (context->toneAttrsArray.empty()) {
1541         context->status = ERROR;
1542         context->errCode = NAPI_ERR_IO_ERROR;
1543         context->errMessage = "I/O error. Can not get alarm tone.";
1544     }
1545 }
1546 
OpenAlarmTone(napi_env env,napi_callback_info info)1547 napi_value SystemSoundManagerNapi::OpenAlarmTone(napi_env env, napi_callback_info info)
1548 {
1549     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
1550         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
1551         "No system permission");
1552     napi_value result = nullptr;
1553     napi_value resource = nullptr;
1554     napi_value thisVar = nullptr;
1555     size_t argc = ARGS_TWO;
1556     napi_value argv[ARGS_TWO] = {};
1557     char buffer[SIZE];
1558     size_t res = 0;
1559 
1560     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1561     napi_get_undefined(env, &result);
1562     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
1563         "OpenAlarmTone: Failed to retrieve details about the callback");
1564     CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1565         NAPI_ERR_INPUT_INVALID), "invalid arguments");
1566     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
1567     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1568     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1569         for (size_t i = PARAM0; i < argc; i++) {
1570             napi_valuetype valueType = napi_undefined;
1571             napi_typeof(env, argv[i], &valueType);
1572             if (i == PARAM0) {
1573                 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
1574             } else if (i == PARAM1 &&  valueType == napi_string) {
1575                 napi_get_value_string_utf8(env, argv[i], buffer, SIZE, &res);
1576                 asyncContext->uri = std::string(buffer);
1577             }
1578         }
1579         CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
1580             ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
1581         CHECK_AND_RETURN_RET_LOG(!asyncContext->uri.empty(), ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1582             NAPI_ERR_INPUT_INVALID), "invalid arguments");
1583         napi_create_promise(env, &asyncContext->deferred, &result);
1584         napi_create_string_utf8(env, "OpenAlarmTone", NAPI_AUTO_LENGTH, &resource);
1585         status = napi_create_async_work(env, nullptr, resource, AsyncOpenAlarmTone,
1586             OpenAlarmToneAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1587         if (status != napi_ok) {
1588             napi_get_undefined(env, &result);
1589         } else {
1590             napi_queue_async_work(env, asyncContext->work);
1591             asyncContext.release();
1592         }
1593     }
1594     return result;
1595 }
1596 
AsyncOpenAlarmTone(napi_env env,void * data)1597 void SystemSoundManagerNapi::AsyncOpenAlarmTone(napi_env env, void *data)
1598 {
1599     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
1600     if (context->objectInfo->sysSoundMgrClient_ != nullptr) {
1601         context->fd = context->objectInfo->sysSoundMgrClient_->OpenAlarmTone(
1602             context->abilityContext_, context->uri);
1603     }
1604     if (context->fd == TYPEERROR) {
1605         context->status = ERROR;
1606         context->errCode = NAPI_ERR_URI_ERROR;
1607         context->errMessage = "Tone type mismatch. Uri of tone is not alarm.";
1608     } else if (context->fd == ERROR) {
1609         context->status = ERROR;
1610         context->errCode = NAPI_ERR_IO_ERROR;
1611         context->errMessage = "I/O error. Uri is empty, can not found.";
1612     }
1613 }
1614 
OpenAlarmToneAsyncCallbackComp(napi_env env,napi_status status,void * data)1615 void SystemSoundManagerNapi::OpenAlarmToneAsyncCallbackComp(napi_env env, napi_status status, void* data)
1616 {
1617     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
1618     napi_value result[2] = {};
1619     if (!context->status) {
1620         napi_get_undefined(env, &result[PARAM0]);
1621         napi_create_int32(env, context->fd, &result[PARAM1]);
1622     } else {
1623         result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
1624         napi_get_undefined(env, &result[PARAM1]);
1625     }
1626     if (context->deferred) {
1627         if (!context->status) {
1628             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
1629         } else {
1630             napi_reject_deferred(env, context->deferred, result[PARAM0]);
1631         }
1632     }
1633     napi_delete_async_work(env, context->work);
1634     delete context;
1635     context = nullptr;
1636 }
1637 
Close(napi_env env,napi_callback_info info)1638 napi_value SystemSoundManagerNapi::Close(napi_env env, napi_callback_info info)
1639 {
1640     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
1641         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
1642         "No system permission");
1643     napi_value result = nullptr;
1644     napi_value resource = nullptr;
1645     napi_value thisVar = nullptr;
1646     size_t argc = ARGS_ONE;
1647     napi_value argv[ARGS_ONE] = {0};
1648 
1649     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1650     napi_get_undefined(env, &result);
1651     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
1652         "Close: Failed to retrieve details about the callback");
1653     CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1654         NAPI_ERR_INPUT_INVALID), "invalid arguments");
1655     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
1656     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1657     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1658         napi_valuetype valueType = napi_undefined;
1659         napi_typeof(env, argv[0], &valueType);
1660         if (valueType == napi_number) {
1661             napi_get_value_int32(env, argv[0], &asyncContext->fd);
1662         }
1663         CHECK_AND_RETURN_RET_LOG(asyncContext->fd > 0, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1664             NAPI_ERR_INPUT_INVALID), "invalid arguments");
1665         napi_create_promise(env, &asyncContext->deferred, &result);
1666         napi_create_string_utf8(env, "Close", NAPI_AUTO_LENGTH, &resource);
1667         status = napi_create_async_work(env, nullptr, resource, AsyncClose,
1668             CloseAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1669         if (status != napi_ok) {
1670             napi_get_undefined(env, &result);
1671         } else {
1672             napi_queue_async_work(env, asyncContext->work);
1673             asyncContext.release();
1674         }
1675     }
1676     return result;
1677 }
1678 
AsyncClose(napi_env env,void * data)1679 void SystemSoundManagerNapi::AsyncClose(napi_env env, void *data)
1680 {
1681     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
1682     if (context->objectInfo->sysSoundMgrClient_ != nullptr) {
1683         context->status = context->objectInfo->sysSoundMgrClient_->Close(context->fd);
1684     }
1685     if (context->status) {
1686         context->errCode = NAPI_ERR_IO_ERROR;
1687         context->errMessage = "I/O error. Uri is empty, can not found.";
1688     }
1689 }
1690 
CloseAsyncCallbackComp(napi_env env,napi_status status,void * data)1691 void SystemSoundManagerNapi::CloseAsyncCallbackComp(napi_env env, napi_status status, void* data)
1692 {
1693     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
1694     napi_value result[2] = {};
1695     napi_get_undefined(env, &result[PARAM1]);
1696     if (!context->status) {
1697         napi_get_undefined(env, &result[PARAM0]);
1698     } else {
1699         result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
1700         napi_get_undefined(env, &result[PARAM1]);
1701     }
1702     if (context->deferred) {
1703         if (!context->status) {
1704             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
1705         } else {
1706             napi_reject_deferred(env, context->deferred, result[PARAM0]);
1707         }
1708     }
1709     napi_delete_async_work(env, context->work);
1710     delete context;
1711     context = nullptr;
1712 }
1713 
AddCustomizedTone(napi_env env,napi_callback_info info)1714 napi_value SystemSoundManagerNapi::AddCustomizedTone(napi_env env, napi_callback_info info)
1715 {
1716     CHECK_AND_RETURN_RET_LOG(VerifyRingtonePermission(), ThrowErrorAndReturn(env,
1717         NAPI_ERR_NO_PERMISSION_INFO, NAPI_ERR_NO_PERMISSION), "Permission denied");
1718     napi_value result = nullptr;
1719     napi_value thisVar = nullptr;
1720     size_t argc = ARGS_FIVE;
1721     napi_value argv[ARGS_FIVE] = {};
1722     char buffer[SIZE];
1723     size_t res = 0;
1724     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1725     napi_get_undefined(env, &result);
1726     CHECK_AND_RETURN_RET_LOG((argc == ARGS_THREE || argc == ARGS_FOUR || argc == ARGS_FIVE), ThrowErrorAndReturn(env,
1727         NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
1728     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
1729     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1730     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1731         for (size_t i = PARAM0; i < argc; i++) {
1732             napi_valuetype valueType = napi_undefined;
1733             napi_typeof(env, argv[i], &valueType);
1734             if (i == PARAM0) {
1735                 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
1736             } else if (i == PARAM1 && valueType == napi_object) {
1737                 napi_unwrap(env, argv[i], reinterpret_cast<void**>(&asyncContext->toneAttrsNapi));
1738             } else if (i == PARAM2 && valueType == napi_string) {
1739                 napi_get_value_string_utf8(env, argv[i], buffer, SIZE, &res);
1740                 asyncContext->externalUri = std::string(buffer);
1741             } else if (i == PARAM2 && valueType == napi_number) {
1742                 napi_get_value_int32(env, argv[i], &asyncContext->fd);
1743             } else if (i == PARAM3 && valueType == napi_number) {
1744                 napi_get_value_int32(env, argv[i], &asyncContext->offset);
1745                 asyncContext->length = INT_MAX;
1746             } else if (i == PARAM4 && valueType == napi_number) {
1747                 napi_get_value_int32(env, argv[i], &asyncContext->length);
1748             }
1749         }
1750         CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr && asyncContext->toneAttrsNapi != nullptr,
1751             ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
1752         napi_create_promise(env, &asyncContext->deferred, &result);
1753         napi_create_string_utf8(env, "AddCustomizedTone", NAPI_AUTO_LENGTH, &thisVar);
1754         status = napi_create_async_work(env, nullptr, thisVar, AsyncAddCustomizedTone,
1755             AddCustomizedToneAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1756         if (status != napi_ok) {
1757             napi_get_undefined(env, &result);
1758         } else {
1759             napi_queue_async_work(env, asyncContext->work);
1760             asyncContext.release();
1761         }
1762     }
1763     return result;
1764 }
1765 
AsyncAddCustomizedTone(napi_env env,void * data)1766 void SystemSoundManagerNapi::AsyncAddCustomizedTone(napi_env env, void *data)
1767 {
1768     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
1769     ParamsForAddCustomizedTone paramsForAddCustomizedTone = { "", context->fd, context->length,
1770         context->offset, false };
1771     if (context->objectInfo->sysSoundMgrClient_ == nullptr) {
1772         context->status = ERROR;
1773         context->errCode = NAPI_ERR_IO_ERROR;
1774         context->errMessage = "I/O error. System sound manager is empty.";
1775     } else if (!context->externalUri.empty()) {
1776         context->uri = context->objectInfo->sysSoundMgrClient_->AddCustomizedToneByExternalUri(
1777             context->abilityContext_, context->toneAttrsNapi->GetToneAttrs(), context->externalUri);
1778         context->status = SUCCESS;
1779     } else if (context->fd > 0) {
1780         if (context->offset >= 0 && context->length >= 0) {
1781             context->uri = context->objectInfo->sysSoundMgrClient_->AddCustomizedToneByFdAndOffset(
1782                 context->abilityContext_, context->toneAttrsNapi->GetToneAttrs(), paramsForAddCustomizedTone);
1783             context->status = SUCCESS;
1784         } else if (context->offset == 0 && context->length == 0) {
1785             context->uri = context->objectInfo->sysSoundMgrClient_->AddCustomizedToneByFd(
1786                 context->abilityContext_, context->toneAttrsNapi->GetToneAttrs(), context->fd);
1787             context->status = SUCCESS;
1788         } else {
1789             context->status = ERROR;
1790         }
1791     } else {
1792         context->status = ERROR;
1793     }
1794     DealErrorForAddCustomizedTone(context->uri, context->status, context->errCode, context->errMessage,
1795         paramsForAddCustomizedTone.duplicateFile);
1796 }
1797 
DealErrorForAddCustomizedTone(std::string & uri,bool & status,int32_t & errCode,std::string & errMessage,bool & duplicateFile)1798 void SystemSoundManagerNapi::DealErrorForAddCustomizedTone(std::string &uri, bool &status, int32_t &errCode,
1799     std::string &errMessage, bool &duplicateFile)
1800 {
1801     std::string result = "TYPEERROR";
1802     if (uri == result) {
1803         status = ERROR;
1804         errCode = NAPI_ERR_OPERATE_NOT_ALLOWED;
1805         errMessage = NAPI_ERR_OPERATE_NOT_ALLOWED_INFO;
1806     } else if (uri.empty()) {
1807         status = ERROR;
1808         errCode = NAPI_ERR_IO_ERROR;
1809         errMessage = "I/O error. Uri is empty, can not found.";
1810     } else if (uri == FILE_SIZE_EXCEEDS_LIMIT) {
1811         status = ERROR;
1812         errCode = ERROR_DATA_TOO_LARGE;
1813         errMessage = NAPI_ERR_DATA_TOO_LARGE_INFO;
1814     } else if (uri == FILE_COUNT_EXCEEDS_LIMIT) {
1815         status = ERROR;
1816         errCode = ERROR_TOO_MANY_FILES;
1817         errMessage = NAPI_ERR_TOO_MANY_FILES_INFO;
1818     } else if (uri == ROM_IS_INSUFFICIENT) {
1819         status = ERROR;
1820         errCode = ERROR_INSUFFICIENT_ROM;
1821         errMessage = NAPI_ERR_INSUFFICIENT_ROM_INFO;
1822     } else if (duplicateFile) {
1823         status = ERROR;
1824         errCode = NAPI_ERR_IO_ERROR;
1825         errMessage = NAPI_ERR_IO_ERROR_DUPLICATE_FILE_NAME;
1826     }
1827 }
1828 
AddCustomizedToneAsyncCallbackComp(napi_env env,napi_status status,void * data)1829 void SystemSoundManagerNapi::AddCustomizedToneAsyncCallbackComp(napi_env env, napi_status status, void* data)
1830 {
1831     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
1832     napi_value result[2] = {};
1833     if (!context->status) {
1834         napi_get_undefined(env, &result[PARAM0]);
1835         napi_create_string_utf8(env, context->uri.c_str(), NAPI_AUTO_LENGTH, &result[PARAM1]);
1836     } else {
1837         result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
1838         if (context->uri.empty()) {
1839             napi_get_undefined(env, &result[PARAM1]);
1840         } else {
1841             napi_create_string_utf8(env, context->uri.c_str(), NAPI_AUTO_LENGTH, &result[PARAM1]);
1842         }
1843     }
1844 
1845     if (context->deferred) {
1846         if (!context->status) {
1847             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
1848         } else {
1849             napi_reject_deferred(env, context->deferred, result[PARAM0]);
1850         }
1851     }
1852 
1853     napi_delete_async_work(env, context->work);
1854     delete context;
1855     context = nullptr;
1856 }
1857 
RemoveCustomizedTone(napi_env env,napi_callback_info info)1858 napi_value SystemSoundManagerNapi::RemoveCustomizedTone(napi_env env, napi_callback_info info)
1859 {
1860     CHECK_AND_RETURN_RET_LOG(VerifyRingtonePermission(), ThrowErrorAndReturn(env,
1861         NAPI_ERR_NO_PERMISSION_INFO, NAPI_ERR_NO_PERMISSION), "Permission denied");
1862     napi_value result = nullptr;
1863     napi_value resource = nullptr;
1864     napi_value thisVar = nullptr;
1865     size_t argc = ARGS_TWO;
1866     napi_value argv[ARGS_TWO] = {};
1867     char buffer[SIZE];
1868     size_t res = 0;
1869 
1870     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1871     napi_get_undefined(env, &result);
1872     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
1873         "RemoveCustomizedTone: Failed to retrieve details about the callback");
1874     CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1875         NAPI_ERR_INPUT_INVALID), "invalid arguments");
1876     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
1877     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1878     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1879         for (size_t i = PARAM0; i < argc; i++) {
1880             napi_valuetype valueType = napi_undefined;
1881             napi_typeof(env, argv[i], &valueType);
1882             if (i == PARAM0) {
1883                 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
1884             } else if (i == PARAM1 && valueType == napi_string) {
1885                 napi_get_value_string_utf8(env, argv[i], buffer, SIZE, &res);
1886                 asyncContext->uri = std::string(buffer);
1887             }
1888         }
1889         CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
1890             ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
1891         CHECK_AND_RETURN_RET_LOG(!asyncContext->uri.empty(), ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
1892             NAPI_ERR_INPUT_INVALID), "invalid arguments");
1893         napi_create_promise(env, &asyncContext->deferred, &result);
1894         napi_create_string_utf8(env, "RemoveCustomizedTone", NAPI_AUTO_LENGTH, &resource);
1895         status = napi_create_async_work(env, nullptr, resource, AsyncRemoveCustomizedTone,
1896             RemoveCustomizedToneAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1897         if (status != napi_ok) {
1898             MEDIA_LOGE("RemoveCustomizedTone: Failed to get create async work");
1899             napi_get_undefined(env, &result);
1900         } else {
1901             napi_queue_async_work(env, asyncContext->work);
1902             asyncContext.release();
1903         }
1904     }
1905     return result;
1906 }
1907 
AsyncRemoveCustomizedTone(napi_env env,void * data)1908 void SystemSoundManagerNapi::AsyncRemoveCustomizedTone(napi_env env, void *data)
1909 {
1910     int32_t result = ERROR;
1911     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
1912     if (context->objectInfo->sysSoundMgrClient_ != nullptr) {
1913         result = context->objectInfo->sysSoundMgrClient_->RemoveCustomizedTone(
1914             context->abilityContext_, context->uri);
1915     }
1916     if (result == TYPEERROR) {
1917         context->status = ERROR;
1918         context->errCode = NAPI_ERR_OPERATE_NOT_ALLOWED;
1919         context->errMessage = NAPI_ERR_OPERATE_NOT_ALLOWED_INFO;
1920     } else if (result == ERROR) {
1921         context->status = ERROR;
1922         context->errCode = NAPI_ERR_IO_ERROR;
1923         context->errMessage = "I/O error. The current ring tone does not exist.";
1924     }
1925 }
1926 
RemoveCustomizedToneAsyncCallbackComp(napi_env env,napi_status status,void * data)1927 void SystemSoundManagerNapi::RemoveCustomizedToneAsyncCallbackComp(napi_env env, napi_status status, void* data)
1928 {
1929     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
1930     napi_value result[2] = {};
1931     napi_get_undefined(env, &result[PARAM1]);
1932     if (!context->status) {
1933         napi_get_undefined(env, &result[PARAM0]);
1934     } else {
1935         result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
1936         napi_get_undefined(env, &result[PARAM1]);
1937     }
1938     if (context->deferred) {
1939         if (!context->status) {
1940             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
1941         } else {
1942             napi_reject_deferred(env, context->deferred, result[PARAM0]);
1943         }
1944     }
1945     napi_delete_async_work(env, context->work);
1946     delete context;
1947     context = nullptr;
1948 }
1949 
ThrowErrorAndReturn(napi_env env,const std::string & errMsg,int32_t errCode)1950 napi_value SystemSoundManagerNapi::ThrowErrorAndReturn(napi_env env, const std::string& errMsg, int32_t errCode)
1951 {
1952     napi_value message = nullptr;
1953     napi_value code = nullptr;
1954     napi_value errVal = nullptr;
1955     napi_value errNameVal = nullptr;
1956     napi_value result{};
1957     napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message);
1958     napi_create_error(env, nullptr, message, &errVal);
1959     napi_create_int32(env, errCode, &code);
1960     napi_set_named_property(env, errVal, "code", code);
1961     napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &errNameVal);
1962     napi_set_named_property(env, errVal, "BusinessError", errNameVal);
1963     napi_throw(env, errVal);
1964     napi_get_undefined(env, &result);
1965     return result;
1966 }
1967 
AsyncThrowErrorAndReturn(napi_env env,const std::string & errMsg,int32_t errCode)1968 napi_value SystemSoundManagerNapi::AsyncThrowErrorAndReturn(napi_env env, const std::string& errMsg, int32_t errCode)
1969 {
1970     napi_value message = nullptr;
1971     napi_value code = nullptr;
1972     napi_value errVal = nullptr;
1973     napi_value errNameVal = nullptr;
1974     napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message);
1975     napi_create_error(env, nullptr, message, &errVal);
1976     napi_create_int32(env, errCode, &code);
1977     napi_set_named_property(env, errVal, "code", code);
1978     napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &errNameVal);
1979     napi_set_named_property(env, errVal, "BusinessError", errNameVal);
1980     return errVal;
1981 }
1982 
Init(napi_env env,napi_value exports)1983 static napi_value Init(napi_env env, napi_value exports)
1984 {
1985     ToneAttrsNapi::Init(env, exports);
1986     ToneHapticsAttrsNapi::Init(env, exports);
1987     ToneHapticsSettingsNapi::Init(env, exports);
1988     SystemSoundManagerNapi::Init(env, exports);
1989     AudioRendererInfoNapi::Init(env, exports);
1990     RingtoneOptionsNapi::Init(env, exports);
1991     RingtonePlayerNapi::Init(env, exports);
1992     SystemToneOptionsNapi::Init(env, exports);
1993     SystemTonePlayerNapi::Init(env, exports);
1994 
1995     return exports;
1996 }
1997 
1998 /*
1999  * module define
2000  */
2001 static napi_module g_module = {
2002     .nm_version = 1,
2003     .nm_flags = 0,
2004     .nm_filename = nullptr,
2005     .nm_register_func = Init,
2006     .nm_modname = "multimedia.systemSoundManager",
2007     .nm_priv = (reinterpret_cast<void*>(0)),
2008     .reserved = {0}
2009 };
2010 
2011 /*
2012  * module register
2013  */
RegisterModule(void)2014 extern "C" __attribute__((constructor)) void RegisterModule(void)
2015 {
2016     napi_module_register(&g_module);
2017 }
2018 } // namespace Media
2019 } // namespace OHOS
2020