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