• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 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 #ifndef LOG_TAG
16 #define LOG_TAG "NapiAudioSpatializationManager"
17 #endif
18 
19 #include "napi_audio_spatialization_manager.h"
20 
21 #include <vector>
22 #include "napi_audio_error.h"
23 #include "napi_param_utils.h"
24 #include "napi_audio_enum.h"
25 #include "audio_errors.h"
26 #include "audio_manager_log.h"
27 #ifndef CROSS_PLATFORM
28 #include "xpower_event_js.h"
29 #endif
30 #include "napi_audio_spatialization_manager_callback.h"
31 
32 namespace OHOS {
33 namespace AudioStandard {
34 using namespace std;
35 using namespace HiviewDFX;
36 static __thread napi_ref g_spatializationManagerConstructor = nullptr;
NapiAudioSpatializationManager()37 NapiAudioSpatializationManager::NapiAudioSpatializationManager()
38     : audioSpatializationMngr_(nullptr), env_(nullptr) {}
39 
40 NapiAudioSpatializationManager::~NapiAudioSpatializationManager() = default;
41 
CheckContextStatus(std::shared_ptr<AudioSpatializationManagerAsyncContext> context)42 bool NapiAudioSpatializationManager::CheckContextStatus(std::shared_ptr<AudioSpatializationManagerAsyncContext> context)
43 {
44     CHECK_AND_RETURN_RET_LOG(context != nullptr, false, "context object is nullptr.");
45     if (context->native == nullptr) {
46         context->SignError(NAPI_ERR_SYSTEM);
47         AUDIO_ERR_LOG("context object state is error.");
48         return false;
49     }
50     return true;
51 }
52 
CheckAudioSpatializationManagerStatus(NapiAudioSpatializationManager * napi,std::shared_ptr<AudioSpatializationManagerAsyncContext> context)53 bool NapiAudioSpatializationManager::CheckAudioSpatializationManagerStatus(NapiAudioSpatializationManager *napi,
54     std::shared_ptr<AudioSpatializationManagerAsyncContext> context)
55 {
56     CHECK_AND_RETURN_RET_LOG(napi != nullptr, false, "napi object is nullptr.");
57     if (napi->audioSpatializationMngr_ == nullptr) {
58         context->SignError(NAPI_ERR_SYSTEM);
59         AUDIO_ERR_LOG("audioSpatializationMngr is nullptr.");
60         return false;
61     }
62     return true;
63 }
64 
Destructor(napi_env env,void * nativeObject,void * finalizeHint)65 void NapiAudioSpatializationManager::Destructor(napi_env env, void *nativeObject, void *finalizeHint)
66 {
67     if (nativeObject == nullptr) {
68         AUDIO_WARNING_LOG("Native object is null");
69         return;
70     }
71     auto obj = static_cast<NapiAudioSpatializationManager *>(nativeObject);
72     ObjectRefMap<NapiAudioSpatializationManager>::DecreaseRef(obj);
73     AUDIO_INFO_LOG("Decrease obj count");
74 }
75 
Construct(napi_env env,napi_callback_info info)76 napi_value NapiAudioSpatializationManager::Construct(napi_env env, napi_callback_info info)
77 {
78     AUDIO_INFO_LOG("Construct");
79     napi_status status;
80     napi_value result = nullptr;
81     napi_get_undefined(env, &result);
82 
83     size_t argc = ARGS_TWO;
84     napi_value argv[ARGS_TWO] = {0};
85     napi_value thisVar = nullptr;
86     void *data = nullptr;
87     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
88     unique_ptr<NapiAudioSpatializationManager> napiAudioSpatializationManager =
89         make_unique<NapiAudioSpatializationManager>();
90     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result, "No memory");
91 
92     napiAudioSpatializationManager->audioSpatializationMngr_ = AudioSpatializationManager::GetInstance();
93     napiAudioSpatializationManager->env_ = env;
94 
95     ObjectRefMap<NapiAudioSpatializationManager>::Insert(napiAudioSpatializationManager.get());
96     status = napi_wrap(env, thisVar, static_cast<void*>(napiAudioSpatializationManager.get()),
97         NapiAudioSpatializationManager::Destructor, nullptr, nullptr);
98     if (status != napi_ok) {
99         ObjectRefMap<NapiAudioSpatializationManager>::Erase(napiAudioSpatializationManager.get());
100         return result;
101     }
102     napiAudioSpatializationManager.release();
103     return thisVar;
104 }
105 
GetParamWithSync(const napi_env & env,napi_callback_info info,size_t & argc,napi_value * args)106 NapiAudioSpatializationManager* NapiAudioSpatializationManager::GetParamWithSync(const napi_env &env,
107     napi_callback_info info, size_t &argc, napi_value *args)
108 {
109     napi_status status;
110     NapiAudioSpatializationManager *napiAudioSpatializationManager = nullptr;
111     napi_value jsThis = nullptr;
112 
113     status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
114     CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr, nullptr,
115         "GetParamWithSync fail to napi_get_cb_info");
116 
117     status = napi_unwrap(env, jsThis, (void **)&napiAudioSpatializationManager);
118     CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "napi_unwrap failed");
119     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr &&
120         napiAudioSpatializationManager->audioSpatializationMngr_ !=
121         nullptr, napiAudioSpatializationManager, "GetParamWithSync fail to napi_unwrap");
122     return napiAudioSpatializationManager;
123 }
124 
CreateSpatializationManagerWrapper(napi_env env)125 napi_value NapiAudioSpatializationManager::CreateSpatializationManagerWrapper(napi_env env)
126 {
127     napi_status status;
128     napi_value result = nullptr;
129     napi_value constructor;
130 
131     status = napi_get_reference_value(env, g_spatializationManagerConstructor, &constructor);
132     if (status != napi_ok) {
133         AUDIO_ERR_LOG("Failed in CreateSpatializationManagerWrapper, %{public}d", status);
134         goto fail;
135     }
136     status = napi_new_instance(env, constructor, 0, nullptr, &result);
137     if (status != napi_ok) {
138         AUDIO_ERR_LOG("napi_new_instance failed, status:%{public}d", status);
139         goto fail;
140     }
141     return result;
142 
143 fail:
144     napi_get_undefined(env, &result);
145     return result;
146 }
147 
Init(napi_env env,napi_value exports)148 napi_value NapiAudioSpatializationManager::Init(napi_env env, napi_value exports)
149 {
150     AUDIO_DEBUG_LOG("Init");
151 
152     napi_status status;
153     napi_value constructor;
154     napi_value result = nullptr;
155     const int32_t refCount = 1;
156     napi_get_undefined(env, &result);
157 
158     napi_property_descriptor audio_spatialization_manager_properties[] = {
159         DECLARE_NAPI_FUNCTION("isSpatializationEnabled", IsSpatializationEnabled),
160         DECLARE_NAPI_FUNCTION("setSpatializationEnabled", SetSpatializationEnabled),
161         DECLARE_NAPI_FUNCTION("isHeadTrackingEnabled", IsHeadTrackingEnabled),
162         DECLARE_NAPI_FUNCTION("setHeadTrackingEnabled", SetHeadTrackingEnabled),
163         DECLARE_NAPI_FUNCTION("isSpatializationSupported", IsSpatializationSupported),
164         DECLARE_NAPI_FUNCTION("isSpatializationSupportedForDevice", IsSpatializationSupportedForDevice),
165         DECLARE_NAPI_FUNCTION("isHeadTrackingSupported", IsHeadTrackingSupported),
166         DECLARE_NAPI_FUNCTION("isHeadTrackingSupportedForDevice", IsHeadTrackingSupportedForDevice),
167         DECLARE_NAPI_FUNCTION("updateSpatialDeviceState", UpdateSpatialDeviceState),
168         DECLARE_NAPI_FUNCTION("getSpatializationSceneType", GetSpatializationSceneType),
169         DECLARE_NAPI_FUNCTION("setSpatializationSceneType", SetSpatializationSceneType),
170         DECLARE_NAPI_FUNCTION("isSpatializationEnabledForCurrentDevice", IsSpatializationEnabledForCurrentDevice),
171         DECLARE_NAPI_FUNCTION("on", On),
172         DECLARE_NAPI_FUNCTION("off", Off),
173     };
174 
175     status = napi_define_class(env, AUDIO_SPATIALIZATION_MANAGER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct,
176         nullptr,
177         sizeof(audio_spatialization_manager_properties) / sizeof(audio_spatialization_manager_properties[PARAM0]),
178         audio_spatialization_manager_properties, &constructor);
179     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_define_class fail");
180 
181     status = napi_create_reference(env, constructor, refCount, &g_spatializationManagerConstructor);
182     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_create_reference fail");
183     status = napi_set_named_property(env, exports, AUDIO_SPATIALIZATION_MANAGER_NAPI_CLASS_NAME.c_str(),
184         constructor);
185     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_set_named_property fail");
186     return exports;
187 }
188 
IsSpatializationEnabled(napi_env env,napi_callback_info info)189 napi_value NapiAudioSpatializationManager::IsSpatializationEnabled(napi_env env, napi_callback_info info)
190 {
191     AUDIO_INFO_LOG("in");
192     napi_value result = nullptr;
193     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
194         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
195 
196     bool isSpatializationEnabled = false;
197     const size_t requireArgc = ARGS_ONE;
198     size_t argc = PARAM1;
199     napi_value args[ARGS_ONE] = {};
200     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, args);
201     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
202         "napiAudioSpatializationManager is nullptr");
203     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
204         "audioSpatializationMngr is nullptr");
205 
206     if (argc == requireArgc) {
207         bool argTransFlag = true;
208         napi_valuetype valueType = napi_undefined;
209         napi_typeof(env, args[PARAM0], &valueType);
210         CHECK_AND_RETURN_RET_LOG(valueType == napi_object, NapiAudioError::ThrowErrorAndReturn(env,
211             NAPI_ERR_INPUT_INVALID,
212             "incorrect parameter types: The type of deviceDescriptor must be object"), "invalid valueType");
213 
214         std::shared_ptr<AudioDeviceDescriptor> selectedAudioDevice = std::make_shared<AudioDeviceDescriptor>();
215         NapiParamUtils::GetAudioDeviceDescriptor(env, selectedAudioDevice, argTransFlag, args[PARAM0]);
216         CHECK_AND_RETURN_RET_LOG(argTransFlag == true, NapiAudioError::ThrowErrorAndReturn(env,
217             NAPI_ERR_INVALID_PARAM,
218             "parameter verification failed: The param of deviceDescriptor must be interface AudioDeviceDescriptor"),
219             "invalid parameter");
220 
221         isSpatializationEnabled = napiAudioSpatializationManager->audioSpatializationMngr_
222             ->IsSpatializationEnabled(selectedAudioDevice);
223     } else if (argc < requireArgc) {
224         isSpatializationEnabled = napiAudioSpatializationManager->audioSpatializationMngr_->IsSpatializationEnabled();
225     } else {
226         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID, "invalid arguments");
227         return NapiParamUtils::GetUndefinedValue(env);
228     }
229     NapiParamUtils::SetValueBoolean(env, isSpatializationEnabled, result);
230     return result;
231 }
232 
SetSpatializationEnabled(napi_env env,napi_callback_info info)233 napi_value NapiAudioSpatializationManager::SetSpatializationEnabled(napi_env env, napi_callback_info info)
234 {
235     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
236         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
237 
238     size_t requireArgc = ARGS_ONE;
239     auto context = std::make_shared<AudioSpatializationManagerAsyncContext>();
240     if (context == nullptr) {
241         AUDIO_ERR_LOG("SetSpatializationEnabled failed : no memory");
242         NapiAudioError::ThrowError(env, "SetSpatializationEnabled failed : no memory",
243             NAPI_ERR_NO_MEMORY);
244         return NapiParamUtils::GetUndefinedValue(env);
245     }
246 
247     auto inputParser = [env, context, &requireArgc](size_t argc, napi_value *argv) {
248         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "mandatory parameters are left unspecified",
249             NAPI_ERR_INPUT_INVALID);
250             bool argTransFlag = true;
251         if (argc == ARGS_ONE) {
252             context->status = NapiParamUtils::GetValueBoolean(env, context->spatializationEnable, argv[PARAM0]);
253             NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
254                 "incorrect parameter types: The type of enable must be boolean",
255                 NAPI_ERR_INPUT_INVALID);
256         } else if (argc == ARGS_TWO) {
257             context->status = NapiParamUtils::GetValueBoolean(env, context->spatializationEnable, argv[PARAM0]);
258             if (context->status == napi_ok) {
259                 requireArgc = ARGS_ONE;
260             } else {
261                 requireArgc = ARGS_TWO;
262                 context->status = NapiParamUtils::GetAudioDeviceDescriptor(env, context->deviceDescriptor, argTransFlag,
263                     argv[PARAM0]);
264                 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
265                     "incorrect parameter types: The param of deviceDescriptor must be interface AudioDeviceDescriptor",
266                     NAPI_ERR_INPUT_INVALID);
267                 context->status = NapiParamUtils::GetValueBoolean(env, context->spatializationEnable, argv[PARAM1]);
268                 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
269                     "incorrect parameter types: The type of enable must be boolean",
270                     NAPI_ERR_INPUT_INVALID);
271             }
272         }
273     };
274     context->GetCbInfo(env, info, inputParser);
275     if (context->status != napi_ok) {
276         NapiAudioError::ThrowError(env, context->errCode, context->errMessage);
277         return NapiParamUtils::GetUndefinedValue(env);
278     }
279 
280     return updateSpatializationEnabled(env, requireArgc, context);
281 }
282 
updateSpatializationEnabled(napi_env env,const std::size_t argc,std::shared_ptr<AudioSpatializationManagerAsyncContext> & context)283 napi_value NapiAudioSpatializationManager::updateSpatializationEnabled(napi_env env, const std::size_t argc,
284     std::shared_ptr<AudioSpatializationManagerAsyncContext> &context)
285 {
286     auto executor = [context, argc]() {
287         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
288         auto obj = reinterpret_cast<NapiAudioSpatializationManager*>(context->native);
289         ObjectRefMap objectGuard(obj);
290         auto *napiAudioSpatializationManager = objectGuard.GetPtr();
291         CHECK_AND_RETURN_LOG(CheckAudioSpatializationManagerStatus(napiAudioSpatializationManager, context),
292             "audio spatialization manager state is error.");
293         if (argc == ARGS_ONE) {
294             context->intValue = napiAudioSpatializationManager->audioSpatializationMngr_->SetSpatializationEnabled(
295                 context->spatializationEnable);
296         } else if (argc == ARGS_TWO) {
297             context->intValue = napiAudioSpatializationManager->audioSpatializationMngr_->SetSpatializationEnabled(
298                 context->deviceDescriptor, context->spatializationEnable);
299         }
300 
301         if (context->intValue == ERR_PERMISSION_DENIED) {
302             context->SignError(NAPI_ERR_NO_PERMISSION);
303         } else if (context->intValue != SUCCESS) {
304             context->SignError(NAPI_ERR_SYSTEM);
305         }
306     };
307 
308     auto complete = [env](napi_value &output) {
309         output = NapiParamUtils::GetUndefinedValue(env);
310     };
311     return NapiAsyncWork::Enqueue(env, context, "SetSpatializationEnabled", executor, complete);
312 }
313 
IsHeadTrackingEnabled(napi_env env,napi_callback_info info)314 napi_value NapiAudioSpatializationManager::IsHeadTrackingEnabled(napi_env env, napi_callback_info info)
315 {
316     AUDIO_INFO_LOG("in");
317     napi_value result = nullptr;
318     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
319         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
320 
321     bool isHeadTrackingEnabled = false;
322     const size_t requireArgc = ARGS_ONE;
323     size_t argc = PARAM1;
324     napi_value args[ARGS_ONE] = {};
325     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, args);
326     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
327         "napiAudioSpatializationManager is nullptr");
328     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
329         "audioSpatializationMngr_ is nullptr");
330 
331     if (argc == requireArgc) {
332         bool argTransFlag = true;
333         napi_valuetype valueType = napi_undefined;
334         napi_typeof(env, args[PARAM0], &valueType);
335         CHECK_AND_RETURN_RET_LOG(valueType == napi_object, NapiAudioError::ThrowErrorAndReturn(env,
336         NAPI_ERR_INPUT_INVALID,
337             "incorrect parameter types: The type of deviceDescriptor must be object"), "invalid valueType");
338 
339         std::shared_ptr<AudioDeviceDescriptor> selectedAudioDevice = std::make_shared<AudioDeviceDescriptor>();
340         NapiParamUtils::GetAudioDeviceDescriptor(env, selectedAudioDevice, argTransFlag, args[PARAM0]);
341         CHECK_AND_RETURN_RET_LOG(argTransFlag == true, NapiAudioError::ThrowErrorAndReturn(env,
342             NAPI_ERR_INVALID_PARAM,
343             "parameter verification failed: The param of deviceDescriptor must be interface AudioDeviceDescriptor"),
344             "invalid parameter");
345 
346         isHeadTrackingEnabled = napiAudioSpatializationManager->audioSpatializationMngr_
347             ->IsHeadTrackingEnabled(selectedAudioDevice);
348     } else if (argc < requireArgc) {
349         isHeadTrackingEnabled = napiAudioSpatializationManager->audioSpatializationMngr_->IsHeadTrackingEnabled();
350     } else {
351         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID, "invalid arguments");
352         return NapiParamUtils::GetUndefinedValue(env);
353     }
354     NapiParamUtils::SetValueBoolean(env, isHeadTrackingEnabled, result);
355     return result;
356 }
357 
SetHeadTrackingEnabled(napi_env env,napi_callback_info info)358 napi_value NapiAudioSpatializationManager::SetHeadTrackingEnabled(napi_env env, napi_callback_info info)
359 {
360     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
361         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
362 
363     size_t requireArgc = ARGS_ONE;
364     auto context = std::make_shared<AudioSpatializationManagerAsyncContext>();
365     if (context == nullptr) {
366         AUDIO_ERR_LOG("SetHeadTrackingEnabled failed : no memory");
367         NapiAudioError::ThrowError(env, "SetHeadTrackingEnabled failed : no memory",
368             NAPI_ERR_NO_MEMORY);
369         return NapiParamUtils::GetUndefinedValue(env);
370     }
371 
372     auto inputParser = [env, context, &requireArgc](size_t argc, napi_value *argv) {
373         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "mandatory parameters are left unspecified",
374             NAPI_ERR_INPUT_INVALID);
375         bool argTransFlag = true;
376         if (argc == ARGS_ONE) {
377             context->status = NapiParamUtils::GetValueBoolean(env, context->headTrackingEnable, argv[PARAM0]);
378             NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
379                 "incorrect parameter types: The type of enable must be boolean",
380                 NAPI_ERR_INPUT_INVALID);
381         } else if (argc == ARGS_TWO) {
382             context->status = NapiParamUtils::GetValueBoolean(env, context->headTrackingEnable, argv[PARAM0]);
383             if (context->status == napi_ok) {
384                 requireArgc = ARGS_ONE;
385             } else {
386                 requireArgc = ARGS_TWO;
387                 context->status = NapiParamUtils::GetAudioDeviceDescriptor(env, context->deviceDescriptor, argTransFlag,
388                     argv[PARAM0]);
389                 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
390                     "incorrect parameter types: The param of deviceDescriptor must be interface AudioDeviceDescriptor",
391                     NAPI_ERR_INPUT_INVALID);
392                 context->status = NapiParamUtils::GetValueBoolean(env, context->headTrackingEnable, argv[PARAM1]);
393                 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
394                     "incorrect parameter types: The type of enable must be boolean",
395                     NAPI_ERR_INPUT_INVALID);
396             }
397         }
398     };
399     context->GetCbInfo(env, info, inputParser);
400     if (context->status != napi_ok) {
401         NapiAudioError::ThrowError(env, context->errCode);
402         return NapiParamUtils::GetUndefinedValue(env);
403     }
404 
405     return updateHeadTrackingEnabled(env, requireArgc, context);
406 }
407 
updateHeadTrackingEnabled(napi_env env,const std::size_t argc,std::shared_ptr<AudioSpatializationManagerAsyncContext> & context)408 napi_value NapiAudioSpatializationManager::updateHeadTrackingEnabled(napi_env env, const std::size_t argc,
409     std::shared_ptr<AudioSpatializationManagerAsyncContext> &context)
410 {
411     auto executor = [context, argc]() {
412         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
413         auto obj = reinterpret_cast<NapiAudioSpatializationManager*>(context->native);
414         ObjectRefMap objectGuard(obj);
415         auto *napiAudioSpatializationManager = objectGuard.GetPtr();
416         CHECK_AND_RETURN_LOG(CheckAudioSpatializationManagerStatus(napiAudioSpatializationManager, context),
417             "audio spatialization manager state is error.");
418         if (argc == ARGS_ONE) {
419             context->intValue = napiAudioSpatializationManager->audioSpatializationMngr_->SetHeadTrackingEnabled(
420                 context->headTrackingEnable);
421         } else if (argc == ARGS_TWO) {
422             context->intValue = napiAudioSpatializationManager->audioSpatializationMngr_->SetHeadTrackingEnabled(
423                 context->deviceDescriptor, context->headTrackingEnable);
424         }
425 
426         if (context->intValue == ERR_PERMISSION_DENIED) {
427             context->SignError(NAPI_ERR_NO_PERMISSION);
428         } else if (context->intValue != SUCCESS) {
429             context->SignError(NAPI_ERR_SYSTEM);
430         }
431     };
432 
433     auto complete = [env](napi_value &output) {
434         output = NapiParamUtils::GetUndefinedValue(env);
435     };
436     return NapiAsyncWork::Enqueue(env, context, "SetHeadTrackingEnabled", executor, complete);
437 }
438 
IsSpatializationSupported(napi_env env,napi_callback_info info)439 napi_value NapiAudioSpatializationManager::IsSpatializationSupported(napi_env env, napi_callback_info info)
440 {
441     AUDIO_DEBUG_LOG("in");
442     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
443         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
444 
445     napi_value result = nullptr;
446     size_t argc = PARAM0;
447     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, nullptr);
448     CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
449         NAPI_ERR_INPUT_INVALID), "invalid arguments");
450     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
451         "napiAudioSpatializationManager is nullptr");
452     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
453         "audioSpatializationMngr_ is nullptr");
454     bool isSpatializationSupported =
455         napiAudioSpatializationManager->audioSpatializationMngr_->IsSpatializationSupported();
456     NapiParamUtils::SetValueBoolean(env, isSpatializationSupported, result);
457 
458     return result;
459 }
460 
IsSpatializationSupportedForDevice(napi_env env,napi_callback_info info)461 napi_value NapiAudioSpatializationManager::IsSpatializationSupportedForDevice(napi_env env, napi_callback_info info)
462 {
463     AUDIO_DEBUG_LOG("IsSpatializationSupportedForDevice");
464     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
465         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
466 
467     napi_value result = nullptr;
468     bool argTransFlag = true;
469     size_t argc = ARGS_ONE;
470     napi_value args[ARGS_ONE] = {};
471     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, args);
472     CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
473         NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "invalid arguments");
474 
475     napi_valuetype valueType = napi_undefined;
476     napi_typeof(env, args[PARAM0], &valueType);
477     CHECK_AND_RETURN_RET_LOG(valueType == napi_object, NapiAudioError::ThrowErrorAndReturn(env,
478         NAPI_ERR_INPUT_INVALID,
479         "incorrect parameter types: The type of deviceDescriptor must be object"), "invalid valueType");
480 
481     std::shared_ptr<AudioDeviceDescriptor> selectedAudioDevice = std::make_shared<AudioDeviceDescriptor>();
482     NapiParamUtils::GetAudioDeviceDescriptor(env, selectedAudioDevice, argTransFlag, args[PARAM0]);
483     CHECK_AND_RETURN_RET_LOG(argTransFlag == true, NapiAudioError::ThrowErrorAndReturn(env,
484         NAPI_ERR_INVALID_PARAM,
485         "parameter verification failed: The param of deviceDescriptor must be interface AudioDeviceDescriptor"),
486         "invalid parameter");
487     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
488         "napiAudioSpatializationManager is nullptr");
489     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
490         "audioSpatializationMngr_ is nullptr");
491 
492     bool isSpatializationSupportedForDevice = napiAudioSpatializationManager
493         ->audioSpatializationMngr_->IsSpatializationSupportedForDevice(selectedAudioDevice);
494     NapiParamUtils::SetValueBoolean(env, isSpatializationSupportedForDevice, result);
495     return result;
496 }
497 
IsHeadTrackingSupported(napi_env env,napi_callback_info info)498 napi_value NapiAudioSpatializationManager::IsHeadTrackingSupported(napi_env env, napi_callback_info info)
499 {
500     AUDIO_DEBUG_LOG("in");
501     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
502         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
503 
504     napi_value result = nullptr;
505     size_t argc = PARAM0;
506     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, nullptr);
507     CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
508         NAPI_ERR_INPUT_INVALID), "invalid arguments");
509     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
510         "napiAudioSpatializationManager is nullptr");
511     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
512         "audioSpatializationMngr_ is nullptr");
513     bool isHeadTrackingSupported =
514         napiAudioSpatializationManager->audioSpatializationMngr_->IsHeadTrackingSupported();
515     NapiParamUtils::SetValueBoolean(env, isHeadTrackingSupported, result);
516     return result;
517 }
518 
IsHeadTrackingSupportedForDevice(napi_env env,napi_callback_info info)519 napi_value NapiAudioSpatializationManager::IsHeadTrackingSupportedForDevice(napi_env env, napi_callback_info info)
520 {
521     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
522         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
523 
524     napi_value result = nullptr;
525     bool argTransFlag = true;
526     size_t argc = ARGS_ONE;
527     napi_value args[ARGS_ONE] = {};
528     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, args);
529     CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
530         NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "invalid arguments");
531     if (napiAudioSpatializationManager == nullptr || napiAudioSpatializationManager
532             ->audioSpatializationMngr_ == nullptr) {
533         AUDIO_ERR_LOG("napiAudioSpatializationManager or audioSpatializationMngr_ is  nullptr");
534         NapiAudioError::ThrowError(env, NAPI_ERR_SYSTEM);
535         return nullptr;
536     }
537 
538     napi_valuetype valueType = napi_undefined;
539     napi_typeof(env, args[PARAM0], &valueType);
540     CHECK_AND_RETURN_RET_LOG(valueType == napi_object, NapiAudioError::ThrowErrorAndReturn(env,
541         NAPI_ERR_INPUT_INVALID,
542         "incorrect parameter types: The type of deviceDescriptor must be object"), "invalid valueType");
543 
544     std::shared_ptr<AudioDeviceDescriptor> selectedAudioDevice = std::make_shared<AudioDeviceDescriptor>();
545     NapiParamUtils::GetAudioDeviceDescriptor(env, selectedAudioDevice, argTransFlag, args[PARAM0]);
546     CHECK_AND_RETURN_RET_LOG(argTransFlag == true, NapiAudioError::ThrowErrorAndReturn(env,
547         NAPI_ERR_INVALID_PARAM,
548         "parameter verification failed: The param of deviceDescriptor must be interface AudioDeviceDescriptor"),
549         "invalid parameter");
550     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
551         "napiAudioSpatializationManager is nullptr");
552     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
553         "audioSpatializationMngr_ is nullptr");
554 
555     bool isHeadTrackingSupportedForDevice = napiAudioSpatializationManager
556         ->audioSpatializationMngr_->IsHeadTrackingSupportedForDevice(selectedAudioDevice);
557     NapiParamUtils::SetValueBoolean(env, isHeadTrackingSupportedForDevice, result);
558     return result;
559 }
560 
UpdateSpatialDeviceState(napi_env env,napi_callback_info info)561 napi_value NapiAudioSpatializationManager::UpdateSpatialDeviceState(napi_env env, napi_callback_info info)
562 {
563     AUDIO_INFO_LOG("UpdateSpatialDeviceState");
564     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
565         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
566 
567     napi_value result = nullptr;
568     size_t argc = ARGS_ONE;
569     napi_value args[ARGS_ONE] = {};
570     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, args);
571     CHECK_AND_RETURN_RET_LOG(argc >= ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
572         NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "invalid arguments");
573 
574     AudioSpatialDeviceState audioSpatialDeviceState;
575     if (NapiParamUtils::GetSpatialDeviceState(env, &audioSpatialDeviceState, args[PARAM0]) != napi_ok) {
576         NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
577             "parameter verification failed: The param of spatialDeviceState must be interface AudioSpatialDeviceState");
578     }
579     if (napiAudioSpatializationManager == nullptr || napiAudioSpatializationManager
580             ->audioSpatializationMngr_ == nullptr) {
581         AUDIO_ERR_LOG("napiAudioSpatializationManager or audioSpatializationMngr_ is  nullptr");
582         return nullptr;
583     }
584     int32_t ret = napiAudioSpatializationManager->audioSpatializationMngr_->UpdateSpatialDeviceState(
585         audioSpatialDeviceState);
586     if (ret == ERR_PERMISSION_DENIED) {
587         NapiAudioError::ThrowError(env, NAPI_ERR_NO_PERMISSION);
588     }
589     return result;
590 }
591 
GetSpatializationSceneType(napi_env env,napi_callback_info info)592 napi_value NapiAudioSpatializationManager::GetSpatializationSceneType(napi_env env, napi_callback_info info)
593 {
594     AUDIO_INFO_LOG("Start to get current spatialization rendering scene type");
595     napi_value result = nullptr;
596     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
597         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
598 
599     size_t argc = PARAM0;
600     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, nullptr);
601     CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
602         NAPI_ERR_INPUT_INVALID), "invalid arguments");
603     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
604         "napiAudioSpatializationManager is nullptr");
605     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
606         "audioSpatializationMngr_ is nullptr");
607     AudioSpatializationSceneType sceneType =
608         napiAudioSpatializationManager->audioSpatializationMngr_->GetSpatializationSceneType();
609     NapiParamUtils::SetValueInt32(env, static_cast<int32_t>(sceneType), result);
610 
611     return result;
612 }
613 
SetSpatializationSceneType(napi_env env,napi_callback_info info)614 napi_value NapiAudioSpatializationManager::SetSpatializationSceneType(napi_env env, napi_callback_info info)
615 {
616     AUDIO_INFO_LOG("Start to set spatialization rendering scene type");
617     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
618         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
619 
620     napi_value result = nullptr;
621     size_t argc = ARGS_ONE;
622     napi_value args[ARGS_ONE] = {};
623     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, args);
624     CHECK_AND_RETURN_RET_LOG(argc >= ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env,
625         NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "invalid arguments");
626 
627     napi_valuetype valueType = napi_undefined;
628     napi_typeof(env, args[PARAM0], &valueType);
629     CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env,
630         NAPI_ERR_INPUT_INVALID,
631         "incorrect parameter types: The type of spatializationSceneType must be number"), "invalid valueType");
632 
633     int32_t sceneType;
634     NapiParamUtils::GetValueInt32(env, sceneType, args[PARAM0]);
635     CHECK_AND_RETURN_RET_LOG(NapiAudioEnum::IsLegalInputArgumentSpatializationSceneType(sceneType),
636         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
637         "parameter verification failed: The param of spatializationSceneType must be \
638         enum AudioSpatializationSceneType"), "get sceneType failed");
639 
640     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
641         "napiAudioSpatializationManager is nullptr");
642     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
643         "audioSpatializationMngr_ is nullptr");
644     int32_t ret = napiAudioSpatializationManager->audioSpatializationMngr_->SetSpatializationSceneType(
645         static_cast<AudioSpatializationSceneType>(sceneType));
646     if (ret == ERR_PERMISSION_DENIED) {
647         NapiAudioError::ThrowError(env, NAPI_ERR_NO_PERMISSION);
648     }
649     return result;
650 }
651 
RegisterCallback(napi_env env,napi_value jsThis,napi_value * args,const std::string & cbName)652 napi_value NapiAudioSpatializationManager::RegisterCallback(napi_env env, napi_value jsThis,
653     napi_value *args, const std::string &cbName)
654 {
655     napi_value undefinedResult = nullptr;
656     NapiAudioSpatializationManager *napiAudioSpatializationManager = nullptr;
657     napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiAudioSpatializationManager));
658     if ((status != napi_ok) || (napiAudioSpatializationManager == nullptr) ||
659         (napiAudioSpatializationManager->audioSpatializationMngr_ == nullptr)) {
660         AUDIO_ERR_LOG("NapiAudioSpatializationManager::Failed to retrieve audio spatialization manager napi instance.");
661         return undefinedResult;
662     }
663 
664     if (!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_CALLBACK_NAME) ||
665         !cbName.compare(SPATIALIZATION_ENABLED_CHANGE_FOR_ANY_DEVICES_CALLBACK_NAME)) {
666         CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
667             NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
668         RegisterSpatializationEnabledChangeCallback(env, args, cbName, napiAudioSpatializationManager);
669     } else if (!cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_CALLBACK_NAME) ||
670         !cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_FOR_ANY_DEVICES_CALLBACK_NAME)) {
671         CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
672             NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
673         RegisterHeadTrackingEnabledChangeCallback(env, args, cbName, napiAudioSpatializationManager);
674     } else if (!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_FOR_CURRENT_DEVICE_CALLBACK_NAME)) {
675         RegisterSpatializationEnabledChangeForCurrentDeviceCallback(env, args, cbName, napiAudioSpatializationManager);
676     } else {
677         AUDIO_ERR_LOG("NapiAudioSpatializationManager::No such callback supported");
678         NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
679             "parameter verification failed: The param of type is not supported");
680     }
681     return undefinedResult;
682 }
683 
RegisterSpatializationEnabledChangeCallback(napi_env env,napi_value * args,const std::string & cbName,NapiAudioSpatializationManager * napiAudioSpatializationManager)684 void NapiAudioSpatializationManager::RegisterSpatializationEnabledChangeCallback(napi_env env, napi_value *args,
685     const std::string &cbName, NapiAudioSpatializationManager *napiAudioSpatializationManager)
686 {
687     if (!napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_) {
688         napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_ =
689             std::make_shared<NapiAudioSpatializationEnabledChangeCallback>(env);
690         CHECK_AND_RETURN_LOG(napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_ != nullptr,
691             "NapiAudioSpatializationManager: Memory Allocation Failed !!");
692 
693         int32_t ret = napiAudioSpatializationManager->audioSpatializationMngr_->
694             RegisterSpatializationEnabledEventListener(
695             napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_);
696         CHECK_AND_RETURN_LOG(ret == SUCCESS,
697             "NapiAudioSpatializationManager: Registering of Spatialization Enabled Change Callback Failed");
698     }
699 
700     std::shared_ptr<NapiAudioSpatializationEnabledChangeCallback> cb =
701         std::static_pointer_cast<NapiAudioSpatializationEnabledChangeCallback>
702         (napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_);
703     cb->SaveSpatializationEnabledChangeCallbackReference(args[PARAM1], cbName);
704     if (!cb->GetSpatEnableTsfnFlag()) {
705         cb->CreateSpatEnableTsfn(env);
706     }
707 
708     AUDIO_INFO_LOG("Register spatialization enabled callback is successful");
709 }
710 
RegisterSpatializationEnabledChangeForCurrentDeviceCallback(napi_env env,napi_value * args,const std::string & cbName,NapiAudioSpatializationManager * napiAudioSpatializationManager)711 void NapiAudioSpatializationManager::RegisterSpatializationEnabledChangeForCurrentDeviceCallback(napi_env env,
712     napi_value *args, const std::string &cbName, NapiAudioSpatializationManager *napiAudioSpatializationManager)
713 {
714     if (!napiAudioSpatializationManager->spatializationEnabledChangeForCurrentDeviceCallbackNapi_) {
715         napiAudioSpatializationManager->spatializationEnabledChangeForCurrentDeviceCallbackNapi_ =
716             std::make_shared<NapiAudioCurrentSpatializationEnabledChangeCallback>(env);
717         CHECK_AND_RETURN_LOG(napiAudioSpatializationManager->spatializationEnabledChangeForCurrentDeviceCallbackNapi_ !=
718             nullptr, "NapiAudioSpatializationManager: Memory Allocation Failed !!");
719 
720         int32_t ret = napiAudioSpatializationManager->audioSpatializationMngr_->
721             RegisterSpatializationEnabledForCurrentDeviceEventListener(
722             napiAudioSpatializationManager->spatializationEnabledChangeForCurrentDeviceCallbackNapi_);
723         CHECK_AND_RETURN_LOG(ret == SUCCESS,
724             "NapiAudioSpatializationManager: Registering of Spatialization Enabled Change For Current Device Callback"
725             "Failed");
726     }
727 
728     std::shared_ptr<NapiAudioCurrentSpatializationEnabledChangeCallback> cb =
729         std::static_pointer_cast<NapiAudioCurrentSpatializationEnabledChangeCallback>
730         (napiAudioSpatializationManager->spatializationEnabledChangeForCurrentDeviceCallbackNapi_);
731     cb->SaveCurrentSpatializationEnabledChangeCallbackReference(args[PARAM1], cbName);
732     if (!cb->GetCurrentSpatEnableForCurrentDeviceTsfnFlag()) {
733         cb->CreateCurrentSpatEnableForCurrentDeviceTsfn(env);
734     }
735 
736     AUDIO_INFO_LOG("Register spatialization enabled for current device callback is successful");
737 }
738 
RegisterHeadTrackingEnabledChangeCallback(napi_env env,napi_value * args,const std::string & cbName,NapiAudioSpatializationManager * napiAudioSpatializationManager)739 void NapiAudioSpatializationManager::RegisterHeadTrackingEnabledChangeCallback(napi_env env, napi_value *args,
740     const std::string &cbName, NapiAudioSpatializationManager *napiAudioSpatializationManager)
741 {
742     if (!napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_) {
743         napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_ =
744             std::make_shared<NapiAudioHeadTrackingEnabledChangeCallback>(env);
745         CHECK_AND_RETURN_LOG(napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_ != nullptr,
746             "NapiAudioSpatializationManager: Memory Allocation Failed !!");
747 
748         int32_t ret = napiAudioSpatializationManager->audioSpatializationMngr_->
749             RegisterHeadTrackingEnabledEventListener(
750             napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_);
751         CHECK_AND_RETURN_LOG(ret == SUCCESS,
752             "NapiAudioSpatializationManager: Registering of Head Tracking Enabled Change Callback Failed");
753     }
754 
755     std::shared_ptr<NapiAudioHeadTrackingEnabledChangeCallback> cb =
756         std::static_pointer_cast<NapiAudioHeadTrackingEnabledChangeCallback>
757         (napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_);
758     cb->SaveHeadTrackingEnabledChangeCallbackReference(args[PARAM1], cbName);
759     if (!cb->GetHeadTrackingTsfnFlag()) {
760         cb->CreateHeadTrackingTsfn(env);
761     }
762 
763     AUDIO_INFO_LOG("Register head tracking enabled callback is successful");
764 }
765 
On(napi_env env,napi_callback_info info)766 napi_value NapiAudioSpatializationManager::On(napi_env env, napi_callback_info info)
767 {
768     const size_t requireArgc = ARGS_TWO;
769     size_t argc = ARGS_THREE;
770     napi_value undefinedResult = nullptr;
771     napi_get_undefined(env, &undefinedResult);
772 
773     napi_value args[requireArgc + 1] = {nullptr, nullptr, nullptr};
774     napi_value jsThis = nullptr;
775     napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
776     if (status != napi_ok || argc < requireArgc) {
777         AUDIO_ERR_LOG("On fail to napi_get_cb_info/Requires min 2 parameters");
778         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
779             "mandatory parameters are left unspecified");
780     }
781 
782     napi_valuetype eventType = napi_undefined;
783     if (napi_typeof(env, args[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
784         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
785             "incorrect parameter types: The type of eventType must be string");
786         return undefinedResult;
787     }
788     std::string callbackName = NapiParamUtils::GetStringArgument(env, args[PARAM0]);
789     AUDIO_DEBUG_LOG("On callbackName: %{public}s", callbackName.c_str());
790 
791     napi_valuetype handler = napi_undefined;
792     if (napi_typeof(env, args[PARAM1], &handler) != napi_ok || handler != napi_function) {
793         AUDIO_ERR_LOG("On type mismatch for parameter 2");
794         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
795             "incorrect parameter types: The type of callback must be function");
796         return undefinedResult;
797     }
798 
799     return RegisterCallback(env, jsThis, args, callbackName);
800 }
801 
UnRegisterCallback(napi_env env,napi_value jsThis,napi_value * args,const std::string & cbName)802 napi_value NapiAudioSpatializationManager::UnRegisterCallback(napi_env env, napi_value jsThis,
803     napi_value *args, const std::string &cbName)
804 {
805     napi_value undefinedResult = nullptr;
806     NapiAudioSpatializationManager *napiAudioSpatializationManager = nullptr;
807     napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiAudioSpatializationManager));
808     CHECK_AND_RETURN_RET_LOG(status == napi_ok && napiAudioSpatializationManager != nullptr, undefinedResult,
809         "Failed to retrieve napi instance.");
810     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, undefinedResult,
811         "spatialization instance null.");
812 
813     if (!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_CALLBACK_NAME) ||
814         !cbName.compare(SPATIALIZATION_ENABLED_CHANGE_FOR_ANY_DEVICES_CALLBACK_NAME)) {
815         CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
816             NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
817         UnregisterSpatializationEnabledChangeCallback(env, args[PARAM1], cbName, napiAudioSpatializationManager);
818     } else if (!cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_CALLBACK_NAME) ||
819         !cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_FOR_ANY_DEVICES_CALLBACK_NAME)) {
820         CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
821             NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
822         UnregisterHeadTrackingEnabledChangeCallback(env, args[PARAM1], cbName, napiAudioSpatializationManager);
823     } else if (!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_FOR_CURRENT_DEVICE_CALLBACK_NAME)) {
824         UnregisterSpatializationEnabledChangeForCurrentDeviceCallback(env, args[PARAM1], cbName,
825             napiAudioSpatializationManager);
826     } else {
827         NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
828             "parameter verification failed: The param of type is not supported");
829     }
830     return undefinedResult;
831 }
832 
UnregisterSpatializationEnabledChangeCallback(napi_env env,napi_value callback,const std::string & cbName,NapiAudioSpatializationManager * napiAudioSpatializationManager)833 void NapiAudioSpatializationManager::UnregisterSpatializationEnabledChangeCallback(napi_env env, napi_value callback,
834     const std::string &cbName, NapiAudioSpatializationManager *napiAudioSpatializationManager)
835 {
836     if (napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_ != nullptr) {
837         std::shared_ptr<NapiAudioSpatializationEnabledChangeCallback> cb =
838             std::static_pointer_cast<NapiAudioSpatializationEnabledChangeCallback>(
839             napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_);
840         if (callback != nullptr) {
841             cb->RemoveSpatializationEnabledChangeCallbackReference(env, callback, cbName);
842         }
843         if (callback == nullptr || cb->GetSpatializationEnabledChangeCbListSize(cbName) == 0) {
844             int32_t ret = napiAudioSpatializationManager->audioSpatializationMngr_->
845                 UnregisterSpatializationEnabledEventListener();
846             CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnregisterSpatializationEnabledEventListener Failed");
847             napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_.reset();
848             napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_ = nullptr;
849             cb->RemoveAllSpatializationEnabledChangeCallbackReference(cbName);
850         }
851     } else {
852         AUDIO_ERR_LOG("UnregisterSpatializationEnabledChangeCb: spatializationEnabledChangeCallbackNapi_ is null");
853     }
854 }
855 
UnregisterSpatializationEnabledChangeForCurrentDeviceCallback(napi_env env,napi_value callback,const std::string & cbName,NapiAudioSpatializationManager * napiAudioSpatializationManager)856 void NapiAudioSpatializationManager::UnregisterSpatializationEnabledChangeForCurrentDeviceCallback(napi_env env,
857     napi_value callback, const std::string &cbName, NapiAudioSpatializationManager *napiAudioSpatializationManager)
858 {
859     if (napiAudioSpatializationManager->spatializationEnabledChangeForCurrentDeviceCallbackNapi_ != nullptr) {
860         std::shared_ptr<NapiAudioCurrentSpatializationEnabledChangeCallback> cb =
861             std::static_pointer_cast<NapiAudioCurrentSpatializationEnabledChangeCallback>(
862             napiAudioSpatializationManager->spatializationEnabledChangeForCurrentDeviceCallbackNapi_);
863         if (callback != nullptr) {
864             cb->RemoveCurrentSpatializationEnabledChangeCallbackReference(env, callback, cbName);
865         }
866         if (callback == nullptr || cb->GetCurrentSpatializationEnabledChangeCbListSize(cbName) == 0) {
867             int32_t ret = napiAudioSpatializationManager->audioSpatializationMngr_->
868                 UnregisterSpatializationEnabledForCurrentDeviceEventListener();
869             CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnregisterSpatializationEnabledForCurrentDeviceEventListener Failed");
870             napiAudioSpatializationManager->spatializationEnabledChangeForCurrentDeviceCallbackNapi_.reset();
871             napiAudioSpatializationManager->spatializationEnabledChangeForCurrentDeviceCallbackNapi_ = nullptr;
872             cb->RemoveAllCurrentSpatializationEnabledChangeCallbackReference(cbName);
873         }
874     } else {
875         AUDIO_ERR_LOG("UnregisterSpatializationEnabledChangeForCurrentDeviceCallback:"
876             "spatializationEnabledChangeForCurrentDeviceCallbackNapi_ is null");
877     }
878 }
879 
UnregisterHeadTrackingEnabledChangeCallback(napi_env env,napi_value callback,const std::string & cbName,NapiAudioSpatializationManager * napiAudioSpatializationManager)880 void NapiAudioSpatializationManager::UnregisterHeadTrackingEnabledChangeCallback(napi_env env, napi_value callback,
881     const std::string &cbName, NapiAudioSpatializationManager *napiAudioSpatializationManager)
882 {
883     if (napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_ != nullptr) {
884         std::shared_ptr<NapiAudioHeadTrackingEnabledChangeCallback> cb =
885             std::static_pointer_cast<NapiAudioHeadTrackingEnabledChangeCallback>(
886             napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_);
887         if (callback != nullptr) {
888             cb->RemoveHeadTrackingEnabledChangeCallbackReference(env, callback, cbName);
889         }
890         if (callback == nullptr || cb->GetHeadTrackingEnabledChangeCbListSize(cbName) == 0) {
891             int32_t ret = napiAudioSpatializationManager->audioSpatializationMngr_->
892                 UnregisterHeadTrackingEnabledEventListener();
893             CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnregisterHeadTrackingEnabledEventListener Failed");
894             napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_.reset();
895             napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_ = nullptr;
896             cb->RemoveAllHeadTrackingEnabledChangeCallbackReference(cbName);
897         }
898     } else {
899         AUDIO_ERR_LOG("UnregisterHeadTrackingEnabledChangeCb: headTrackingEnabledChangeCallbackNapi_ is null");
900     }
901 }
902 
Off(napi_env env,napi_callback_info info)903 napi_value NapiAudioSpatializationManager::Off(napi_env env, napi_callback_info info)
904 {
905     const size_t requireArgc = ARGS_ONE;
906     size_t argc = PARAM2;
907 
908     napi_value undefinedResult = nullptr;
909     napi_get_undefined(env, &undefinedResult);
910 
911     napi_value args[requireArgc + 1] = {nullptr, nullptr};
912     napi_value jsThis = nullptr;
913     napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
914     if (status != napi_ok || argc < requireArgc) {
915         AUDIO_ERR_LOG("Off fail to napi_get_cb_info/Requires min 1 parameters");
916         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
917             "mandatory parameters are left unspecified");
918         return undefinedResult;
919     }
920 
921     napi_valuetype eventType = napi_undefined;
922     if (napi_typeof(env, args[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
923         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
924             "incorrect parameter types: The type of eventType must be string");
925         return undefinedResult;
926     }
927 
928     napi_valuetype secondArgsType = napi_undefined;
929     if (argc > requireArgc &&
930         (napi_typeof(env, args[PARAM1], &secondArgsType) != napi_ok || secondArgsType != napi_function)) {
931         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
932             "incorrect parameter types: The type of callback must be function");
933         return undefinedResult;
934     }
935     std::string callbackName = NapiParamUtils::GetStringArgument(env, args[PARAM0]);
936 
937     if (argc == requireArgc) {
938         args[PARAM1] = nullptr;
939     }
940     AUDIO_DEBUG_LOG("AudioSpatializationManagerNapi: Off callbackName: %{public}s", callbackName.c_str());
941 
942     return UnRegisterCallback(env, jsThis, args, callbackName);
943 }
944 
IsSpatializationEnabledForCurrentDevice(napi_env env,napi_callback_info info)945 napi_value NapiAudioSpatializationManager::IsSpatializationEnabledForCurrentDevice(napi_env env,
946     napi_callback_info info)
947 {
948     AUDIO_INFO_LOG("in");
949     napi_value result = nullptr;
950 
951     size_t argc = PARAM0;
952     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, nullptr);
953     CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID),
954         "invaild arguments");
955     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
956         "napiAudioSpatializationManager is nullptr");
957     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
958         "audioSpatializationMngr is nullptr");
959 
960     bool IsSpatializationEnabledForCurrentDevice = napiAudioSpatializationManager->audioSpatializationMngr_
961         ->IsSpatializationEnabledForCurrentDevice();
962     NapiParamUtils::SetValueBoolean(env, IsSpatializationEnabledForCurrentDevice, result);
963     return result;
964 }
965 } // namespace AudioStandard
966 } // namespace OHOS
967