• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #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 "audio_utils.h"
28 #include "xpower_event_js.h"
29 #include "napi_audio_spatialization_manager_callback.h"
30 
31 namespace OHOS {
32 namespace AudioStandard {
33 using namespace std;
34 using namespace HiviewDFX;
35 static __thread napi_ref g_spatializationManagerConstructor = nullptr;
NapiAudioSpatializationManager()36 NapiAudioSpatializationManager::NapiAudioSpatializationManager()
37     : audioSpatializationMngr_(nullptr), env_(nullptr) {}
38 
39 NapiAudioSpatializationManager::~NapiAudioSpatializationManager() = default;
40 
CheckContextStatus(std::shared_ptr<AudioSpatializationManagerAsyncContext> context)41 bool NapiAudioSpatializationManager::CheckContextStatus(std::shared_ptr<AudioSpatializationManagerAsyncContext> context)
42 {
43     CHECK_AND_RETURN_RET_LOG(context != nullptr, false, "context object is nullptr.");
44     if (context->native == nullptr) {
45         context->SignError(NAPI_ERR_SYSTEM);
46         AUDIO_ERR_LOG("context object state is error.");
47         return false;
48     }
49     return true;
50 }
51 
CheckAudioSpatializationManagerStatus(NapiAudioSpatializationManager * napi,std::shared_ptr<AudioSpatializationManagerAsyncContext> context)52 bool NapiAudioSpatializationManager::CheckAudioSpatializationManagerStatus(NapiAudioSpatializationManager *napi,
53     std::shared_ptr<AudioSpatializationManagerAsyncContext> context)
54 {
55     CHECK_AND_RETURN_RET_LOG(napi != nullptr, false, "napi object is nullptr.");
56     if (napi->audioSpatializationMngr_ == nullptr) {
57         context->SignError(NAPI_ERR_SYSTEM);
58         AUDIO_ERR_LOG("audioSpatializationMngr is nullptr.");
59         return false;
60     }
61     return true;
62 }
63 
Destructor(napi_env env,void * nativeObject,void * finalizeHint)64 void NapiAudioSpatializationManager::Destructor(napi_env env, void *nativeObject, void *finalizeHint)
65 {
66     if (nativeObject != nullptr) {
67         auto obj = static_cast<NapiAudioSpatializationManager *>(nativeObject);
68         ObjectRefMap<NapiAudioSpatializationManager>::DecreaseRef(obj);
69     }
70     AUDIO_INFO_LOG("Destructor is successful");
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("on", On),
168         DECLARE_NAPI_FUNCTION("off", Off),
169     };
170 
171     status = napi_define_class(env, AUDIO_SPATIALIZATION_MANAGER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct,
172         nullptr,
173         sizeof(audio_spatialization_manager_properties) / sizeof(audio_spatialization_manager_properties[PARAM0]),
174         audio_spatialization_manager_properties, &constructor);
175     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_define_class fail");
176 
177     status = napi_create_reference(env, constructor, refCount, &g_spatializationManagerConstructor);
178     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_create_reference fail");
179     status = napi_set_named_property(env, exports, AUDIO_SPATIALIZATION_MANAGER_NAPI_CLASS_NAME.c_str(),
180         constructor);
181     CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_set_named_property fail");
182     return exports;
183 }
184 
IsSpatializationEnabled(napi_env env,napi_callback_info info)185 napi_value NapiAudioSpatializationManager::IsSpatializationEnabled(napi_env env, napi_callback_info info)
186 {
187     AUDIO_INFO_LOG("IsSpatializationEnabled in");
188     napi_value result = nullptr;
189     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
190         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
191 
192     bool isSpatializationEnabled = false;
193     const size_t requireArgc = ARGS_ONE;
194     size_t argc = PARAM1;
195     napi_value args[ARGS_ONE] = {};
196     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, args);
197     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
198         "napiAudioSpatializationManager is nullptr");
199     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
200         "audioSpatializationMngr is nullptr");
201 
202     if (argc == requireArgc) {
203         bool argTransFlag = true;
204         napi_valuetype valueType = napi_undefined;
205         napi_typeof(env, args[PARAM0], &valueType);
206         CHECK_AND_RETURN_RET_LOG(valueType == napi_object, NapiAudioError::ThrowErrorAndReturn(env,
207         NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of deviceDescriptor must be object"),
208             "invalid valueType");
209 
210         sptr<AudioDeviceDescriptor> selectedAudioDevice = new (std::nothrow) AudioDeviceDescriptor();
211         NapiParamUtils::GetAudioDeviceDescriptor(env, selectedAudioDevice, argTransFlag, args[PARAM0]);
212         CHECK_AND_RETURN_RET_LOG(argTransFlag == true, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
213             "parameter verification failed: The param of deviceDescriptor must be interface AudioDeviceDescriptor"),
214             "invalid parameter");
215 
216         isSpatializationEnabled = napiAudioSpatializationManager->audioSpatializationMngr_
217             ->IsSpatializationEnabled(selectedAudioDevice);
218     } else if (argc < requireArgc) {
219         isSpatializationEnabled = napiAudioSpatializationManager->audioSpatializationMngr_->IsSpatializationEnabled();
220     } else {
221         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID, "invalid arguments");
222         return NapiParamUtils::GetUndefinedValue(env);
223     }
224     NapiParamUtils::SetValueBoolean(env, isSpatializationEnabled, result);
225     return result;
226 }
227 
SetSpatializationEnabled(napi_env env,napi_callback_info info)228 napi_value NapiAudioSpatializationManager::SetSpatializationEnabled(napi_env env, napi_callback_info info)
229 {
230     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
231         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
232 
233     size_t requireArgc = ARGS_ONE;
234     auto context = std::make_shared<AudioSpatializationManagerAsyncContext>();
235     if (context == nullptr) {
236         AUDIO_ERR_LOG("SetSpatializationEnabled failed : no memory");
237         NapiAudioError::ThrowError(env, "SetSpatializationEnabled failed : no memory", NAPI_ERR_NO_MEMORY);
238         return NapiParamUtils::GetUndefinedValue(env);
239     }
240 
241     auto inputParser = [env, context, &requireArgc](size_t argc, napi_value *argv) {
242         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "mandatory parameters are left unspecified",
243             NAPI_ERR_INPUT_INVALID);
244             bool argTransFlag = true;
245         if (argc == ARGS_ONE) {
246             context->status = NapiParamUtils::GetValueBoolean(env, context->spatializationEnable, argv[PARAM0]);
247             NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
248                 "incorrect parameter types: The type of enable must be boolean", NAPI_ERR_INPUT_INVALID);
249         } else if (argc == ARGS_TWO) {
250             context->status = NapiParamUtils::GetValueBoolean(env, context->spatializationEnable, argv[PARAM0]);
251             if (context->status == napi_ok) {
252                 requireArgc = ARGS_ONE;
253             } else {
254                 requireArgc = ARGS_TWO;
255                 context->status = NapiParamUtils::GetAudioDeviceDescriptor(env, context->deviceDescriptor, argTransFlag,
256                     argv[PARAM0]);
257                 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
258                     "incorrect parameter types: The param of deviceDescriptor must be interface AudioDeviceDescriptor",
259                     NAPI_ERR_INPUT_INVALID);
260                 context->status = NapiParamUtils::GetValueBoolean(env, context->spatializationEnable, argv[PARAM1]);
261                 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
262                     "incorrect parameter types: The type of enable must be boolean", NAPI_ERR_INPUT_INVALID);
263             }
264         }
265     };
266     context->GetCbInfo(env, info, inputParser);
267     if (context->status != napi_ok) {
268         NapiAudioError::ThrowError(env, context->errCode, context->errMessage);
269         return NapiParamUtils::GetUndefinedValue(env);
270     }
271 
272     return updateSpatializationEnabled(env, requireArgc, context);
273 }
274 
updateSpatializationEnabled(napi_env env,const std::size_t argc,std::shared_ptr<AudioSpatializationManagerAsyncContext> & context)275 napi_value NapiAudioSpatializationManager::updateSpatializationEnabled(napi_env env, const std::size_t argc,
276     std::shared_ptr<AudioSpatializationManagerAsyncContext> &context)
277 {
278     auto executor = [context, argc]() {
279         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
280         auto obj = reinterpret_cast<NapiAudioSpatializationManager*>(context->native);
281         ObjectRefMap objectGuard(obj);
282         auto *napiAudioSpatializationManager = objectGuard.GetPtr();
283         CHECK_AND_RETURN_LOG(CheckAudioSpatializationManagerStatus(napiAudioSpatializationManager, context),
284             "audio spatialization manager state is error.");
285         if (argc == ARGS_ONE) {
286             context->intValue = napiAudioSpatializationManager->audioSpatializationMngr_->SetSpatializationEnabled(
287                 context->spatializationEnable);
288         } else if (argc == ARGS_TWO) {
289             context->intValue = napiAudioSpatializationManager->audioSpatializationMngr_->SetSpatializationEnabled(
290                 context->deviceDescriptor, context->spatializationEnable);
291         }
292 
293         if (context->intValue == ERR_PERMISSION_DENIED) {
294             context->SignError(NAPI_ERR_NO_PERMISSION);
295         } else if (context->intValue != SUCCESS) {
296             context->SignError(NAPI_ERR_SYSTEM);
297         }
298     };
299 
300     auto complete = [env](napi_value &output) {
301         output = NapiParamUtils::GetUndefinedValue(env);
302     };
303     return NapiAsyncWork::Enqueue(env, context, "SetSpatializationEnabled", executor, complete);
304 }
305 
IsHeadTrackingEnabled(napi_env env,napi_callback_info info)306 napi_value NapiAudioSpatializationManager::IsHeadTrackingEnabled(napi_env env, napi_callback_info info)
307 {
308     AUDIO_INFO_LOG("IsHeadTrackingEnabled in");
309     napi_value result = nullptr;
310     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
311         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
312 
313     bool isHeadTrackingEnabled = false;
314     const size_t requireArgc = ARGS_ONE;
315     size_t argc = PARAM1;
316     napi_value args[ARGS_ONE] = {};
317     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, args);
318     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
319         "napiAudioSpatializationManager is nullptr");
320     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
321         "audioSpatializationMngr_ is nullptr");
322 
323     if (argc == requireArgc) {
324         bool argTransFlag = true;
325         napi_valuetype valueType = napi_undefined;
326         napi_typeof(env, args[PARAM0], &valueType);
327         CHECK_AND_RETURN_RET_LOG(valueType == napi_object, NapiAudioError::ThrowErrorAndReturn(env,
328         NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of deviceDescriptor must be object"),
329             "invalid valueType");
330 
331         sptr<AudioDeviceDescriptor> selectedAudioDevice = new (std::nothrow) AudioDeviceDescriptor();
332         NapiParamUtils::GetAudioDeviceDescriptor(env, selectedAudioDevice, argTransFlag, args[PARAM0]);
333         CHECK_AND_RETURN_RET_LOG(argTransFlag == true, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
334             "parameter verification failed: The param of deviceDescriptor must be interface AudioDeviceDescriptor"),
335             "invalid parameter");
336 
337         isHeadTrackingEnabled = napiAudioSpatializationManager->audioSpatializationMngr_
338             ->IsHeadTrackingEnabled(selectedAudioDevice);
339     } else if (argc < requireArgc) {
340         isHeadTrackingEnabled = napiAudioSpatializationManager->audioSpatializationMngr_->IsHeadTrackingEnabled();
341     } else {
342         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID, "invalid arguments");
343         return NapiParamUtils::GetUndefinedValue(env);
344     }
345     NapiParamUtils::SetValueBoolean(env, isHeadTrackingEnabled, result);
346     return result;
347 }
348 
SetHeadTrackingEnabled(napi_env env,napi_callback_info info)349 napi_value NapiAudioSpatializationManager::SetHeadTrackingEnabled(napi_env env, napi_callback_info info)
350 {
351     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
352         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
353 
354     size_t requireArgc = ARGS_ONE;
355     auto context = std::make_shared<AudioSpatializationManagerAsyncContext>();
356     if (context == nullptr) {
357         AUDIO_ERR_LOG("SetHeadTrackingEnabled failed : no memory");
358         NapiAudioError::ThrowError(env, "SetHeadTrackingEnabled failed : no memory", NAPI_ERR_NO_MEMORY);
359         return NapiParamUtils::GetUndefinedValue(env);
360     }
361 
362     auto inputParser = [env, context, &requireArgc](size_t argc, napi_value *argv) {
363         NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "mandatory parameters are left unspecified",
364             NAPI_ERR_INPUT_INVALID);
365         bool argTransFlag = true;
366         if (argc == ARGS_ONE) {
367             context->status = NapiParamUtils::GetValueBoolean(env, context->headTrackingEnable, argv[PARAM0]);
368             NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
369                 "incorrect parameter types: The type of enable must be boolean", NAPI_ERR_INPUT_INVALID);
370         } else if (argc == ARGS_TWO) {
371             context->status = NapiParamUtils::GetValueBoolean(env, context->headTrackingEnable, argv[PARAM0]);
372             if (context->status == napi_ok) {
373                 requireArgc = ARGS_ONE;
374             } else {
375                 requireArgc = ARGS_TWO;
376                 context->status = NapiParamUtils::GetAudioDeviceDescriptor(env, context->deviceDescriptor, argTransFlag,
377                     argv[PARAM0]);
378                 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
379                     "incorrect parameter types: The param of deviceDescriptor must be interface AudioDeviceDescriptor",
380                     NAPI_ERR_INPUT_INVALID);
381                 context->status = NapiParamUtils::GetValueBoolean(env, context->headTrackingEnable, argv[PARAM1]);
382                 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok,
383                     "incorrect parameter types: The type of enable must be boolean", NAPI_ERR_INPUT_INVALID);
384             }
385         }
386     };
387     context->GetCbInfo(env, info, inputParser);
388     if (context->status != napi_ok) {
389         NapiAudioError::ThrowError(env, context->errCode);
390         return NapiParamUtils::GetUndefinedValue(env);
391     }
392 
393     return updateHeadTrackingEnabled(env, requireArgc, context);
394 }
395 
updateHeadTrackingEnabled(napi_env env,const std::size_t argc,std::shared_ptr<AudioSpatializationManagerAsyncContext> & context)396 napi_value NapiAudioSpatializationManager::updateHeadTrackingEnabled(napi_env env, const std::size_t argc,
397     std::shared_ptr<AudioSpatializationManagerAsyncContext> &context)
398 {
399     auto executor = [context, argc]() {
400         CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
401         auto obj = reinterpret_cast<NapiAudioSpatializationManager*>(context->native);
402         ObjectRefMap objectGuard(obj);
403         auto *napiAudioSpatializationManager = objectGuard.GetPtr();
404         CHECK_AND_RETURN_LOG(CheckAudioSpatializationManagerStatus(napiAudioSpatializationManager, context),
405             "audio spatialization manager state is error.");
406         if (argc == ARGS_ONE) {
407             context->intValue = napiAudioSpatializationManager->audioSpatializationMngr_->SetHeadTrackingEnabled(
408                 context->headTrackingEnable);
409         } else if (argc == ARGS_TWO) {
410             context->intValue = napiAudioSpatializationManager->audioSpatializationMngr_->SetHeadTrackingEnabled(
411                 context->deviceDescriptor, context->headTrackingEnable);
412         }
413 
414         if (context->intValue == ERR_PERMISSION_DENIED) {
415             context->SignError(NAPI_ERR_NO_PERMISSION);
416         } else if (context->intValue != SUCCESS) {
417             context->SignError(NAPI_ERR_SYSTEM);
418         }
419     };
420 
421     auto complete = [env](napi_value &output) {
422         output = NapiParamUtils::GetUndefinedValue(env);
423     };
424     return NapiAsyncWork::Enqueue(env, context, "SetHeadTrackingEnabled", executor, complete);
425 }
426 
IsSpatializationSupported(napi_env env,napi_callback_info info)427 napi_value NapiAudioSpatializationManager::IsSpatializationSupported(napi_env env, napi_callback_info info)
428 {
429     AUDIO_DEBUG_LOG("IsSpatializationSupported in");
430     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
431         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
432 
433     napi_value result = nullptr;
434     size_t argc = PARAM0;
435     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, nullptr);
436     CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID),
437         "invalid arguments");
438     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
439         "napiAudioSpatializationManager is nullptr");
440     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
441         "audioSpatializationMngr_ is nullptr");
442     bool isSpatializationSupported =
443         napiAudioSpatializationManager->audioSpatializationMngr_->IsSpatializationSupported();
444     NapiParamUtils::SetValueBoolean(env, isSpatializationSupported, result);
445 
446     return result;
447 }
448 
IsSpatializationSupportedForDevice(napi_env env,napi_callback_info info)449 napi_value NapiAudioSpatializationManager::IsSpatializationSupportedForDevice(napi_env env, napi_callback_info info)
450 {
451     AUDIO_DEBUG_LOG("IsSpatializationSupportedForDevice");
452     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
453         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
454 
455     napi_value result = nullptr;
456     bool argTransFlag = true;
457     size_t argc = ARGS_ONE;
458     napi_value args[ARGS_ONE] = {};
459     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, args);
460     CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
461         "mandatory parameters are left unspecified"), "invalid arguments");
462 
463     napi_valuetype valueType = napi_undefined;
464     napi_typeof(env, args[PARAM0], &valueType);
465     CHECK_AND_RETURN_RET_LOG(valueType == napi_object, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
466         "incorrect parameter types: The type of deviceDescriptor must be object"), "invalid valueType");
467 
468     sptr<AudioDeviceDescriptor> selectedAudioDevice = new (std::nothrow) AudioDeviceDescriptor();
469     NapiParamUtils::GetAudioDeviceDescriptor(env, selectedAudioDevice, argTransFlag, args[PARAM0]);
470     CHECK_AND_RETURN_RET_LOG(argTransFlag == true, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
471         "parameter verification failed: The param of deviceDescriptor must be interface AudioDeviceDescriptor"),
472         "invalid parameter");
473     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
474         "napiAudioSpatializationManager is nullptr");
475     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
476         "audioSpatializationMngr_ is nullptr");
477 
478     bool isSpatializationSupportedForDevice = napiAudioSpatializationManager
479         ->audioSpatializationMngr_->IsSpatializationSupportedForDevice(selectedAudioDevice);
480     NapiParamUtils::SetValueBoolean(env, isSpatializationSupportedForDevice, result);
481     return result;
482 }
483 
IsHeadTrackingSupported(napi_env env,napi_callback_info info)484 napi_value NapiAudioSpatializationManager::IsHeadTrackingSupported(napi_env env, napi_callback_info info)
485 {
486     AUDIO_DEBUG_LOG("IsHeadTrackingSupported in");
487     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
488         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
489 
490     napi_value result = nullptr;
491     size_t argc = PARAM0;
492     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, nullptr);
493     CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID),
494         "invalid arguments");
495     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
496         "napiAudioSpatializationManager is nullptr");
497     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
498         "audioSpatializationMngr_ is nullptr");
499     bool isHeadTrackingSupported =
500         napiAudioSpatializationManager->audioSpatializationMngr_->IsHeadTrackingSupported();
501     NapiParamUtils::SetValueBoolean(env, isHeadTrackingSupported, result);
502     return result;
503 }
504 
IsHeadTrackingSupportedForDevice(napi_env env,napi_callback_info info)505 napi_value NapiAudioSpatializationManager::IsHeadTrackingSupportedForDevice(napi_env env, napi_callback_info info)
506 {
507     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
508         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
509 
510     napi_value result = nullptr;
511     bool argTransFlag = true;
512     size_t argc = ARGS_ONE;
513     napi_value args[ARGS_ONE] = {};
514     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, args);
515     CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
516         "mandatory parameters are left unspecified"), "invalid arguments");
517 
518     napi_valuetype valueType = napi_undefined;
519     napi_typeof(env, args[PARAM0], &valueType);
520     CHECK_AND_RETURN_RET_LOG(valueType == napi_object, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
521         "incorrect parameter types: The type of deviceDescriptor must be object"), "invalid valueType");
522 
523     sptr<AudioDeviceDescriptor> selectedAudioDevice = new (std::nothrow) AudioDeviceDescriptor();
524     NapiParamUtils::GetAudioDeviceDescriptor(env, selectedAudioDevice, argTransFlag, args[PARAM0]);
525     CHECK_AND_RETURN_RET_LOG(argTransFlag == true, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
526         "parameter verification failed: The param of deviceDescriptor must be interface AudioDeviceDescriptor"),
527         "invalid parameter");
528 
529     bool isHeadTrackingSupportedForDevice = napiAudioSpatializationManager
530         ->audioSpatializationMngr_->IsHeadTrackingSupportedForDevice(selectedAudioDevice);
531     NapiParamUtils::SetValueBoolean(env, isHeadTrackingSupportedForDevice, result);
532     return result;
533 }
534 
UpdateSpatialDeviceState(napi_env env,napi_callback_info info)535 napi_value NapiAudioSpatializationManager::UpdateSpatialDeviceState(napi_env env, napi_callback_info info)
536 {
537     AUDIO_INFO_LOG("UpdateSpatialDeviceState");
538     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
539         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
540 
541     napi_value result = nullptr;
542     size_t argc = ARGS_ONE;
543     napi_value args[ARGS_ONE] = {};
544     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, args);
545     CHECK_AND_RETURN_RET_LOG(argc >= ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
546         "mandatory parameters are left unspecified"), "invalid arguments");
547 
548     AudioSpatialDeviceState audioSpatialDeviceState;
549     if (NapiParamUtils::GetSpatialDeviceState(env, &audioSpatialDeviceState, args[PARAM0]) != napi_ok) {
550         NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
551             "parameter verification failed: The param of spatialDeviceState must be interface AudioSpatialDeviceState");
552     }
553     if (napiAudioSpatializationManager == nullptr || napiAudioSpatializationManager
554             ->audioSpatializationMngr_ == nullptr) {
555         AUDIO_ERR_LOG("napiAudioSpatializationManager or audioSpatializationMngr_ is  nullptr");
556         return nullptr;
557     }
558     int32_t ret = napiAudioSpatializationManager->audioSpatializationMngr_->UpdateSpatialDeviceState(
559         audioSpatialDeviceState);
560     if (ret == ERR_PERMISSION_DENIED) {
561         NapiAudioError::ThrowError(env, NAPI_ERR_NO_PERMISSION);
562     }
563     return result;
564 }
565 
GetSpatializationSceneType(napi_env env,napi_callback_info info)566 napi_value NapiAudioSpatializationManager::GetSpatializationSceneType(napi_env env, napi_callback_info info)
567 {
568     AUDIO_INFO_LOG("Start to get current spatialization rendering scene type");
569     napi_value result = nullptr;
570     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
571         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
572 
573     size_t argc = PARAM0;
574     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, nullptr);
575     CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID),
576         "invalid arguments");
577     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
578         "napiAudioSpatializationManager is nullptr");
579     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
580         "audioSpatializationMngr_ is nullptr");
581     AudioSpatializationSceneType sceneType =
582         napiAudioSpatializationManager->audioSpatializationMngr_->GetSpatializationSceneType();
583     NapiParamUtils::SetValueInt32(env, static_cast<int32_t>(sceneType), result);
584 
585     return result;
586 }
587 
SetSpatializationSceneType(napi_env env,napi_callback_info info)588 napi_value NapiAudioSpatializationManager::SetSpatializationSceneType(napi_env env, napi_callback_info info)
589 {
590     AUDIO_INFO_LOG("Start to set spatialization rendering scene type");
591     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
592         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
593 
594     napi_value result = nullptr;
595     size_t argc = ARGS_ONE;
596     napi_value args[ARGS_ONE] = {};
597     auto *napiAudioSpatializationManager = GetParamWithSync(env, info, argc, args);
598     CHECK_AND_RETURN_RET_LOG(argc >= ARGS_ONE, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
599         "mandatory parameters are left unspecified"), "invalid arguments");
600 
601     napi_valuetype valueType = napi_undefined;
602     napi_typeof(env, args[PARAM0], &valueType);
603     CHECK_AND_RETURN_RET_LOG(valueType == napi_number, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
604         "incorrect parameter types: The type of spatializationSceneType must be number"), "invalid valueType");
605 
606     int32_t sceneType;
607     NapiParamUtils::GetValueInt32(env, sceneType, args[PARAM0]);
608     CHECK_AND_RETURN_RET_LOG(NapiAudioEnum::IsLegalInputArgumentSpatializationSceneType(sceneType),
609         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
610         "parameter verification failed: The param of spatializationSceneType must be \
611         enum AudioSpatializationSceneType"), "get sceneType failed");
612 
613     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager != nullptr, result,
614         "napiAudioSpatializationManager is nullptr");
615     CHECK_AND_RETURN_RET_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr, result,
616         "audioSpatializationMngr_ is nullptr");
617     int32_t ret = napiAudioSpatializationManager->audioSpatializationMngr_->SetSpatializationSceneType(
618         static_cast<AudioSpatializationSceneType>(sceneType));
619     if (ret == ERR_PERMISSION_DENIED) {
620         NapiAudioError::ThrowError(env, NAPI_ERR_NO_PERMISSION);
621     }
622     return result;
623 }
624 
RegisterCallback(napi_env env,napi_value jsThis,napi_value * args,const std::string & cbName)625 void NapiAudioSpatializationManager::RegisterCallback(napi_env env, napi_value jsThis,
626     napi_value *args, const std::string &cbName)
627 {
628     NapiAudioSpatializationManager *napiAudioSpatializationManager = nullptr;
629     napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiAudioSpatializationManager));
630     if ((status != napi_ok) || (napiAudioSpatializationManager == nullptr) ||
631         (napiAudioSpatializationManager->audioSpatializationMngr_ == nullptr)) {
632         AUDIO_ERR_LOG("NapiAudioSpatializationManager::Failed to retrieve audio spatialization manager napi instance.");
633         return;
634     }
635 
636     if (!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_CALLBACK_NAME)) {
637         RegisterSpatializationEnabledChangeCallback(env, args, cbName, napiAudioSpatializationManager);
638     } else if (!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_FOR_ANY_DEVICES_CALLBACK_NAME)) {
639         RegisterSpatializationEnabledChangeCallback(env, args, cbName, napiAudioSpatializationManager);
640     } else if (!cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_CALLBACK_NAME)) {
641         RegisterHeadTrackingEnabledChangeCallback(env, args, cbName, napiAudioSpatializationManager);
642     } else if (!cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_FOR_ANY_DEVICES_CALLBACK_NAME)) {
643         RegisterHeadTrackingEnabledChangeCallback(env, args, cbName, napiAudioSpatializationManager);
644     } else {
645         AUDIO_ERR_LOG("NapiAudioSpatializationManager::No such callback supported");
646         NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
647             "parameter verification failed: The param of type is not supported");
648     }
649 }
650 
RegisterSpatializationEnabledChangeCallback(napi_env env,napi_value * args,const std::string & cbName,NapiAudioSpatializationManager * napiAudioSpatializationManager)651 void NapiAudioSpatializationManager::RegisterSpatializationEnabledChangeCallback(napi_env env, napi_value *args,
652     const std::string &cbName, NapiAudioSpatializationManager *napiAudioSpatializationManager)
653 {
654     if (!napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_) {
655         napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_ =
656             std::make_shared<NapiAudioSpatializationEnabledChangeCallback>(env);
657         CHECK_AND_RETURN_LOG(napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_ != nullptr,
658             "NapiAudioSpatializationManager: Memory Allocation Failed !!");
659 
660         int32_t ret = napiAudioSpatializationManager->audioSpatializationMngr_->
661             RegisterSpatializationEnabledEventListener(
662             napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_);
663         CHECK_AND_RETURN_LOG(ret == SUCCESS,
664             "NapiAudioSpatializationManager: Registering of Spatialization Enabled Change Callback Failed");
665     }
666 
667     std::shared_ptr<NapiAudioSpatializationEnabledChangeCallback> cb =
668         std::static_pointer_cast<NapiAudioSpatializationEnabledChangeCallback>
669         (napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_);
670     cb->SaveSpatializationEnabledChangeCallbackReference(args[PARAM1], cbName);
671 
672     AUDIO_INFO_LOG("Register spatialization enabled callback is successful");
673 }
674 
RegisterHeadTrackingEnabledChangeCallback(napi_env env,napi_value * args,const std::string & cbName,NapiAudioSpatializationManager * napiAudioSpatializationManager)675 void NapiAudioSpatializationManager::RegisterHeadTrackingEnabledChangeCallback(napi_env env, napi_value *args,
676     const std::string &cbName, NapiAudioSpatializationManager *napiAudioSpatializationManager)
677 {
678     if (!napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_) {
679         napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_ =
680             std::make_shared<NapiAudioHeadTrackingEnabledChangeCallback>(env);
681         CHECK_AND_RETURN_LOG(napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_ != nullptr,
682             "NapiAudioSpatializationManager: Memory Allocation Failed !!");
683 
684         int32_t ret = napiAudioSpatializationManager->audioSpatializationMngr_->
685             RegisterHeadTrackingEnabledEventListener(
686             napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_);
687         CHECK_AND_RETURN_LOG(ret == SUCCESS,
688             "NapiAudioSpatializationManager: Registering of Head Tracking Enabled Change Callback Failed");
689     }
690 
691     std::shared_ptr<NapiAudioHeadTrackingEnabledChangeCallback> cb =
692         std::static_pointer_cast<NapiAudioHeadTrackingEnabledChangeCallback>
693         (napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_);
694     cb->SaveHeadTrackingEnabledChangeCallbackReference(args[PARAM1], cbName);
695 
696     AUDIO_INFO_LOG("Register head tracking enabled callback is successful");
697 }
698 
On(napi_env env,napi_callback_info info)699 napi_value NapiAudioSpatializationManager::On(napi_env env, napi_callback_info info)
700 {
701     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
702         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
703 
704     const size_t requireArgc = ARGS_TWO;
705     size_t argc = ARGS_THREE;
706     napi_value undefinedResult = nullptr;
707     napi_get_undefined(env, &undefinedResult);
708 
709     napi_value args[requireArgc + 1] = {nullptr, nullptr, nullptr};
710     napi_value jsThis = nullptr;
711     napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
712     if (status != napi_ok || argc < requireArgc) {
713         AUDIO_ERR_LOG("On fail to napi_get_cb_info/Requires min 2 parameters");
714         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified");
715     }
716 
717     napi_valuetype eventType = napi_undefined;
718     if (napi_typeof(env, args[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
719         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
720             "incorrect parameter types: The type of eventType must be string");
721         return undefinedResult;
722     }
723     std::string callbackName = NapiParamUtils::GetStringArgument(env, args[PARAM0]);
724     AUDIO_DEBUG_LOG("On callbackName: %{public}s", callbackName.c_str());
725 
726     napi_valuetype handler = napi_undefined;
727     if (napi_typeof(env, args[PARAM1], &handler) != napi_ok || handler != napi_function) {
728         AUDIO_ERR_LOG("On type mismatch for parameter 2");
729         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
730             "incorrect parameter types: The type of callback must be function");
731         return undefinedResult;
732     }
733 
734     RegisterCallback(env, jsThis, args, callbackName);
735 
736     return undefinedResult;
737 }
738 
UnRegisterCallback(napi_env env,napi_value jsThis,napi_value * args,const std::string & cbName)739 void NapiAudioSpatializationManager::UnRegisterCallback(napi_env env, napi_value jsThis,
740     napi_value *args, const std::string &cbName)
741 {
742     NapiAudioSpatializationManager *napiAudioSpatializationManager = nullptr;
743     napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiAudioSpatializationManager));
744     CHECK_AND_RETURN_LOG(status == napi_ok && napiAudioSpatializationManager != nullptr,
745         "Failed to retrieve napi instance.");
746     CHECK_AND_RETURN_LOG(napiAudioSpatializationManager->audioSpatializationMngr_ != nullptr,
747         "spatialization instance null.");
748 
749     if (!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_CALLBACK_NAME)) {
750         UnregisterSpatializationEnabledChangeCallback(env, args[PARAM1], cbName, napiAudioSpatializationManager);
751     } else if (!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_FOR_ANY_DEVICES_CALLBACK_NAME)) {
752         UnregisterSpatializationEnabledChangeCallback(env, args[PARAM1], cbName, napiAudioSpatializationManager);
753     } else if (!cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_CALLBACK_NAME)) {
754         UnregisterHeadTrackingEnabledChangeCallback(env, args[PARAM1], cbName, napiAudioSpatializationManager);
755     } else if (!cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_FOR_ANY_DEVICES_CALLBACK_NAME)) {
756         UnregisterHeadTrackingEnabledChangeCallback(env, args[PARAM1], cbName, napiAudioSpatializationManager);
757     } else {
758         NapiAudioError::ThrowError(env, NAPI_ERR_INVALID_PARAM,
759             "parameter verification failed: The param of type is not supported");
760     }
761 }
762 
UnregisterSpatializationEnabledChangeCallback(napi_env env,napi_value callback,const std::string & cbName,NapiAudioSpatializationManager * napiAudioSpatializationManager)763 void NapiAudioSpatializationManager::UnregisterSpatializationEnabledChangeCallback(napi_env env, napi_value callback,
764     const std::string &cbName, NapiAudioSpatializationManager *napiAudioSpatializationManager)
765 {
766     if (napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_ != nullptr) {
767         std::shared_ptr<NapiAudioSpatializationEnabledChangeCallback> cb =
768             std::static_pointer_cast<NapiAudioSpatializationEnabledChangeCallback>(
769             napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_);
770         if (callback != nullptr) {
771             cb->RemoveSpatializationEnabledChangeCallbackReference(env, callback, cbName);
772         }
773         if (callback == nullptr || cb->GetSpatializationEnabledChangeCbListSize(cbName) == 0) {
774             int32_t ret = napiAudioSpatializationManager->audioSpatializationMngr_->
775                 UnregisterSpatializationEnabledEventListener();
776             CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnregisterSpatializationEnabledEventListener Failed");
777             napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_.reset();
778             napiAudioSpatializationManager->spatializationEnabledChangeCallbackNapi_ = nullptr;
779             cb->RemoveAllSpatializationEnabledChangeCallbackReference(cbName);
780         }
781     } else {
782         AUDIO_ERR_LOG("UnregisterSpatializationEnabledChangeCb: spatializationEnabledChangeCallbackNapi_ is null");
783     }
784 }
785 
UnregisterHeadTrackingEnabledChangeCallback(napi_env env,napi_value callback,const std::string & cbName,NapiAudioSpatializationManager * napiAudioSpatializationManager)786 void NapiAudioSpatializationManager::UnregisterHeadTrackingEnabledChangeCallback(napi_env env, napi_value callback,
787     const std::string &cbName, NapiAudioSpatializationManager *napiAudioSpatializationManager)
788 {
789     if (napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_ != nullptr) {
790         std::shared_ptr<NapiAudioHeadTrackingEnabledChangeCallback> cb =
791             std::static_pointer_cast<NapiAudioHeadTrackingEnabledChangeCallback>(
792             napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_);
793         if (callback != nullptr) {
794             cb->RemoveHeadTrackingEnabledChangeCallbackReference(env, callback, cbName);
795         }
796         if (callback == nullptr || cb->GetHeadTrackingEnabledChangeCbListSize(cbName) == 0) {
797             int32_t ret = napiAudioSpatializationManager->audioSpatializationMngr_->
798                 UnregisterHeadTrackingEnabledEventListener();
799             CHECK_AND_RETURN_LOG(ret == SUCCESS, "UnregisterHeadTrackingEnabledEventListener Failed");
800             napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_.reset();
801             napiAudioSpatializationManager->headTrackingEnabledChangeCallbackNapi_ = nullptr;
802             cb->RemoveAllHeadTrackingEnabledChangeCallbackReference(cbName);
803         }
804     } else {
805         AUDIO_ERR_LOG("UnregisterHeadTrackingEnabledChangeCb: headTrackingEnabledChangeCallbackNapi_ is null");
806     }
807 }
808 
Off(napi_env env,napi_callback_info info)809 napi_value NapiAudioSpatializationManager::Off(napi_env env, napi_callback_info info)
810 {
811     CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
812         NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
813     const size_t requireArgc = ARGS_ONE;
814     size_t argc = PARAM2;
815 
816     napi_value undefinedResult = nullptr;
817     napi_get_undefined(env, &undefinedResult);
818 
819     napi_value args[requireArgc + 1] = {nullptr, nullptr};
820     napi_value jsThis = nullptr;
821     napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
822     if (status != napi_ok || argc < requireArgc) {
823         AUDIO_ERR_LOG("Off fail to napi_get_cb_info/Requires min 1 parameters");
824         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified");
825         return undefinedResult;
826     }
827 
828     napi_valuetype eventType = napi_undefined;
829     if (napi_typeof(env, args[PARAM0], &eventType) != napi_ok || eventType != napi_string) {
830         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
831             "incorrect parameter types: The type of eventType must be string");
832         return undefinedResult;
833     }
834 
835     napi_valuetype secondArgsType = napi_undefined;
836     if (argc > requireArgc &&
837         (napi_typeof(env, args[PARAM1], &secondArgsType) != napi_ok || secondArgsType != napi_function)) {
838         NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID,
839             "incorrect parameter types: The type of callback must be function");
840         return undefinedResult;
841     }
842     std::string callbackName = NapiParamUtils::GetStringArgument(env, args[PARAM0]);
843 
844     if (argc == requireArgc) {
845         args[PARAM1] = nullptr;
846     }
847     AUDIO_DEBUG_LOG("AudioSpatializationManagerNapi: Off callbackName: %{public}s", callbackName.c_str());
848 
849     UnRegisterCallback(env, jsThis, args, callbackName);
850 
851     return undefinedResult;
852 }
853 } // namespace AudioStandard
854 } // namespace OHOS
855