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 "NapiAudioSpatializationMgrCallback"
17 #endif
18
19 #include "napi_audio_spatialization_manager_callback.h"
20 #include "audio_errors.h"
21 #include "audio_manager_log.h"
22 #include "napi_param_utils.h"
23 #include "napi_audio_error.h"
24 #include "napi_audio_manager_callbacks.h"
25
26 namespace OHOS {
27 namespace AudioStandard {
28 bool NapiAudioSpatializationEnabledChangeCallback::onSpatializationEnabledChangeFlag_;
29 bool NapiAudioHeadTrackingEnabledChangeCallback::onHeadTrackingEnabledChangeFlag_;
30 using namespace std;
NapiAudioSpatializationEnabledChangeCallback(napi_env env)31 NapiAudioSpatializationEnabledChangeCallback::NapiAudioSpatializationEnabledChangeCallback(napi_env env)
32 : env_(env)
33 {
34 AUDIO_DEBUG_LOG("NapiAudioSpatializationEnabledChangeCallback: instance create");
35 }
36
~NapiAudioSpatializationEnabledChangeCallback()37 NapiAudioSpatializationEnabledChangeCallback::~NapiAudioSpatializationEnabledChangeCallback()
38 {
39 AUDIO_DEBUG_LOG("NapiAudioSpatializationEnabledChangeCallback: instance destroy");
40 }
41
SaveSpatializationEnabledChangeCallbackReference(napi_value args,const std::string & cbName)42 void NapiAudioSpatializationEnabledChangeCallback::SaveSpatializationEnabledChangeCallbackReference(napi_value args,
43 const std::string &cbName)
44 {
45 std::lock_guard<std::mutex> lock(mutex_);
46 napi_ref callback = nullptr;
47 const int32_t refCount = ARGS_ONE;
48
49 if (!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_CALLBACK_NAME)) {
50 for (auto it = spatializationEnabledChangeCbList_.begin();
51 it != spatializationEnabledChangeCbList_.end(); ++it) {
52 bool isSameCallback = NapiAudioManagerCallback::IsSameCallback(env_, args, (*it)->cb_);
53 CHECK_AND_RETURN_LOG(!isSameCallback, "SaveCallbackReference: spatialization manager has same callback");
54 }
55
56 napi_status status = napi_create_reference(env_, args, refCount, &callback);
57 CHECK_AND_RETURN_LOG(status == napi_ok && callback != nullptr,
58 "NapiAudioSpatializationEnabledChangeCallback: creating reference for callback fail");
59
60 std::shared_ptr<AutoRef> cb = std::make_shared<AutoRef>(env_, callback);
61 CHECK_AND_RETURN_LOG(cb != nullptr, "NapiAudioSpatializationEnabledChangeCallback: creating callback failed");
62 spatializationEnabledChangeCbList_.push_back(cb);
63 } else if (!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_FOR_ANY_DEVICES_CALLBACK_NAME)) {
64 for (auto it = spatializationEnabledChangeCbForAnyDeviceList_.begin();
65 it != spatializationEnabledChangeCbForAnyDeviceList_.end(); ++it) {
66 bool isSameCallback = NapiAudioManagerCallback::IsSameCallback(env_, args, (*it)->cb_);
67 CHECK_AND_RETURN_LOG(!isSameCallback, "SaveCallbackReference: spatialization manager has same callback");
68 }
69
70 napi_status status = napi_create_reference(env_, args, refCount, &callback);
71 CHECK_AND_RETURN_LOG(status == napi_ok && callback != nullptr,
72 "NapiAudioSpatializationEnabledChangeCallback: creating reference for callback fail");
73
74 std::shared_ptr<AutoRef> cb = std::make_shared<AutoRef>(env_, callback);
75 CHECK_AND_RETURN_LOG(cb != nullptr, "NapiAudioSpatializationEnabledChangeCallback: creating callback failed");
76 spatializationEnabledChangeCbForAnyDeviceList_.push_back(cb);
77 }
78 }
79
RemoveSpatializationEnabledChangeCallbackReference(napi_env env,napi_value args,const std::string & cbName)80 void NapiAudioSpatializationEnabledChangeCallback::RemoveSpatializationEnabledChangeCallbackReference(napi_env env,
81 napi_value args, const std::string &cbName)
82 {
83 std::lock_guard<std::mutex> lock(mutex_);
84 if (!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_CALLBACK_NAME)) {
85 for (auto it = spatializationEnabledChangeCbList_.begin();
86 it != spatializationEnabledChangeCbList_.end(); ++it) {
87 bool isSameCallback = NapiAudioManagerCallback::IsSameCallback(env_, args, (*it)->cb_);
88 if (isSameCallback) {
89 AUDIO_INFO_LOG("RemoveSpatializationEnabledChangeCallbackReference: find js callback, delete it");
90 napi_delete_reference(env, (*it)->cb_);
91 (*it)->cb_ = nullptr;
92 spatializationEnabledChangeCbList_.erase(it);
93 return;
94 }
95 }
96 } else if (!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_FOR_ANY_DEVICES_CALLBACK_NAME)) {
97 for (auto it = spatializationEnabledChangeCbForAnyDeviceList_.begin();
98 it != spatializationEnabledChangeCbForAnyDeviceList_.end(); ++it) {
99 bool isSameCallback = NapiAudioManagerCallback::IsSameCallback(env_, args, (*it)->cb_);
100 if (isSameCallback) {
101 AUDIO_INFO_LOG("RemoveSpatializationEnabledChangeCallbackReference: find js callback, delete it");
102 napi_delete_reference(env, (*it)->cb_);
103 (*it)->cb_ = nullptr;
104 spatializationEnabledChangeCbForAnyDeviceList_.erase(it);
105 return;
106 }
107 }
108 }
109 AUDIO_INFO_LOG("RemoveSpatializationEnabledChangeCallbackReference: js callback no find");
110 }
111
RemoveAllSpatializationEnabledChangeCallbackReference(const std::string & cbName)112 void NapiAudioSpatializationEnabledChangeCallback::RemoveAllSpatializationEnabledChangeCallbackReference(
113 const std::string &cbName)
114 {
115 std::lock_guard<std::mutex> lock(mutex_);
116 if (!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_CALLBACK_NAME)) {
117 for (auto it = spatializationEnabledChangeCbList_.begin();
118 it != spatializationEnabledChangeCbList_.end(); ++it) {
119 napi_delete_reference(env_, (*it)->cb_);
120 (*it)->cb_ = nullptr;
121 }
122 spatializationEnabledChangeCbList_.clear();
123 } else if (!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_FOR_ANY_DEVICES_CALLBACK_NAME)) {
124 for (auto it = spatializationEnabledChangeCbForAnyDeviceList_.begin();
125 it != spatializationEnabledChangeCbForAnyDeviceList_.end(); ++it) {
126 napi_delete_reference(env_, (*it)->cb_);
127 (*it)->cb_ = nullptr;
128 }
129 spatializationEnabledChangeCbForAnyDeviceList_.clear();
130 }
131 AUDIO_INFO_LOG("RemoveAllSpatializationEnabledChangeCallbackReference: remove all js callbacks success");
132 }
133
GetSpatializationEnabledChangeCbListSize(const std::string & cbName)134 int32_t NapiAudioSpatializationEnabledChangeCallback::GetSpatializationEnabledChangeCbListSize(
135 const std::string &cbName)
136 {
137 std::lock_guard<std::mutex> lock(mutex_);
138 return ((!cbName.compare(SPATIALIZATION_ENABLED_CHANGE_CALLBACK_NAME)) ? spatializationEnabledChangeCbList_.size():
139 spatializationEnabledChangeCbForAnyDeviceList_.size());
140 }
141
OnSpatializationEnabledChange(const bool & enabled)142 void NapiAudioSpatializationEnabledChangeCallback::OnSpatializationEnabledChange(const bool &enabled)
143 {
144 AUDIO_INFO_LOG("OnSpatializationEnabledChange entered");
145 std::lock_guard<std::mutex> lock(mutex_);
146
147 for (auto it = spatializationEnabledChangeCbList_.begin(); it != spatializationEnabledChangeCbList_.end(); it++) {
148 std::unique_ptr<AudioSpatializationEnabledJsCallback> cb =
149 std::make_unique<AudioSpatializationEnabledJsCallback>();
150 CHECK_AND_RETURN_LOG(cb != nullptr, "No memory!!");
151 cb->callback = (*it);
152 cb->enabled = enabled;
153 onSpatializationEnabledChangeFlag_ = true;
154 OnJsCallbackSpatializationEnabled(cb);
155 }
156 return;
157 }
158
OnSpatializationEnabledChangeForAnyDevice(const sptr<AudioDeviceDescriptor> & deviceDescriptor,const bool & enabled)159 void NapiAudioSpatializationEnabledChangeCallback::OnSpatializationEnabledChangeForAnyDevice(
160 const sptr<AudioDeviceDescriptor> &deviceDescriptor, const bool &enabled)
161 {
162 AUDIO_INFO_LOG("OnSpatializationEnabledChange by the speified device entered");
163 std::lock_guard<std::mutex> lock(mutex_);
164
165 for (auto it = spatializationEnabledChangeCbList_.begin(); it != spatializationEnabledChangeCbList_.end(); it++) {
166 std::unique_ptr<AudioSpatializationEnabledJsCallback> cb =
167 std::make_unique<AudioSpatializationEnabledJsCallback>();
168 CHECK_AND_RETURN_LOG(cb != nullptr, "No memory!!");
169 cb->callback = (*it);
170 cb->enabled = enabled;
171 onSpatializationEnabledChangeFlag_ = true;
172 OnJsCallbackSpatializationEnabled(cb);
173 }
174 for (auto it = spatializationEnabledChangeCbForAnyDeviceList_.begin();
175 it != spatializationEnabledChangeCbForAnyDeviceList_.end(); it++) {
176 std::unique_ptr<AudioSpatializationEnabledJsCallback> cb =
177 std::make_unique<AudioSpatializationEnabledJsCallback>();
178 CHECK_AND_RETURN_LOG(cb != nullptr, "No memory!!");
179 cb->callback = (*it);
180 cb->deviceDescriptor = deviceDescriptor;
181 cb->enabled = enabled;
182 onSpatializationEnabledChangeFlag_ = false;
183 OnJsCallbackSpatializationEnabled(cb);
184 }
185
186 return;
187 }
188
WorkCallbackInterruptDone(uv_work_t * work,int status)189 void NapiAudioSpatializationEnabledChangeCallback::WorkCallbackInterruptDone(uv_work_t *work, int status)
190 {
191 std::shared_ptr<AudioSpatializationEnabledJsCallback> context(
192 static_cast<AudioSpatializationEnabledJsCallback*>(work->data),
193 [work](AudioSpatializationEnabledJsCallback* ptr) {
194 delete ptr;
195 delete work;
196 });
197 CHECK_AND_RETURN_LOG(work != nullptr, "work is nullptr");
198 AudioSpatializationEnabledJsCallback *event = reinterpret_cast<AudioSpatializationEnabledJsCallback *>(work->data);
199 CHECK_AND_RETURN_LOG(event != nullptr, "event is nullptr");
200 CHECK_AND_RETURN_LOG(event->callback != nullptr, "event is nullptr");
201 napi_env env = event->callback->env_;
202 napi_ref callback = event->callback->cb_;
203 napi_handle_scope scope = nullptr;
204 napi_open_handle_scope(env, &scope);
205 CHECK_AND_RETURN_LOG(scope != nullptr, "scope is nullptr");
206 do {
207 napi_value jsCallback = nullptr;
208 napi_status nstatus = napi_get_reference_value(env, callback, &jsCallback);
209 CHECK_AND_BREAK_LOG(nstatus == napi_ok && jsCallback != nullptr, "callback get reference value fail");
210 napi_value args[ARGS_ONE] = { nullptr };
211 const size_t argCount = ARGS_ONE;
212 napi_value result = nullptr;
213
214 if (onSpatializationEnabledChangeFlag_) {
215 NapiParamUtils::SetValueBoolean(env, event->enabled, args[PARAM0]);
216 CHECK_AND_BREAK_LOG(nstatus == napi_ok && args[PARAM0] != nullptr, "fail to convert to jsobj");
217 } else {
218 AudioSpatialEnabledStateForDevice audioSpatialEnabledStateForDevice;
219 audioSpatialEnabledStateForDevice.deviceDescriptor = event->deviceDescriptor;
220 audioSpatialEnabledStateForDevice.enabled = event->enabled;
221 NapiParamUtils::SetAudioSpatialEnabledStateForDevice(env, audioSpatialEnabledStateForDevice, args[PARAM0]);
222 CHECK_AND_BREAK_LOG(nstatus == napi_ok && args[PARAM0] != nullptr, "fail to convert to jsobj");
223 }
224
225 nstatus = napi_call_function(env, nullptr, jsCallback, argCount, args, &result);
226 CHECK_AND_BREAK_LOG(nstatus == napi_ok, "Fail to call spatialization enabled callback");
227 } while (0);
228 napi_close_handle_scope(env, scope);
229 }
230
OnJsCallbackSpatializationEnabled(std::unique_ptr<AudioSpatializationEnabledJsCallback> & jsCb)231 void NapiAudioSpatializationEnabledChangeCallback::OnJsCallbackSpatializationEnabled(
232 std::unique_ptr<AudioSpatializationEnabledJsCallback> &jsCb)
233 {
234 uv_loop_s *loop = nullptr;
235 napi_get_uv_event_loop(env_, &loop);
236 CHECK_AND_RETURN_LOG(loop != nullptr, "loop is nullptr");
237
238 uv_work_t *work = new(std::nothrow) uv_work_t;
239 CHECK_AND_RETURN_LOG(work != nullptr, "OnJsCallbackSpatializationEnabled: No memory");
240
241 work->data = reinterpret_cast<void *>(jsCb.get());
242 int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {}, WorkCallbackInterruptDone,
243 uv_qos_default);
244 if (ret != 0) {
245 AUDIO_ERR_LOG("Failed to execute libuv work queue");
246 delete work;
247 } else {
248 jsCb.release();
249 }
250 }
251
NapiAudioHeadTrackingEnabledChangeCallback(napi_env env)252 NapiAudioHeadTrackingEnabledChangeCallback::NapiAudioHeadTrackingEnabledChangeCallback(napi_env env)
253 : env_(env)
254 {
255 AUDIO_DEBUG_LOG("NapiAudioHeadTrackingEnabledChangeCallback: instance create");
256 }
257
~NapiAudioHeadTrackingEnabledChangeCallback()258 NapiAudioHeadTrackingEnabledChangeCallback::~NapiAudioHeadTrackingEnabledChangeCallback()
259 {
260 AUDIO_DEBUG_LOG("NapiAudioHeadTrackingEnabledChangeCallback: instance destroy");
261 }
262
SaveHeadTrackingEnabledChangeCallbackReference(napi_value args,const std::string & cbName)263 void NapiAudioHeadTrackingEnabledChangeCallback::SaveHeadTrackingEnabledChangeCallbackReference(napi_value args,
264 const std::string &cbName)
265 {
266 std::lock_guard<std::mutex> lock(mutex_);
267 napi_ref callback = nullptr;
268 const int32_t refCount = ARGS_ONE;
269 if (!cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_CALLBACK_NAME)) {
270 for (auto it = headTrackingEnabledChangeCbList_.begin(); it != headTrackingEnabledChangeCbList_.end(); ++it) {
271 bool isSameCallback = NapiAudioManagerCallback::IsSameCallback(env_, args, (*it)->cb_);
272 CHECK_AND_RETURN_LOG(!isSameCallback, "SaveCallbackReference: spatialization manager has same callback");
273 }
274
275 napi_status status = napi_create_reference(env_, args, refCount, &callback);
276 CHECK_AND_RETURN_LOG(status == napi_ok && callback != nullptr,
277 "NapiAudioHeadTrackingEnabledChangeCallback: creating reference for callback fail");
278
279 std::shared_ptr<AutoRef> cb = std::make_shared<AutoRef>(env_, callback);
280 CHECK_AND_RETURN_LOG(cb != nullptr, "NapiAudioHeadTrackingEnabledChangeCallback: creating callback failed");
281
282 headTrackingEnabledChangeCbList_.push_back(cb);
283 } else if (!cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_FOR_ANY_DEVICES_CALLBACK_NAME)) {
284 for (auto it = headTrackingEnabledChangeCbForAnyDeviceList_.begin();
285 it != headTrackingEnabledChangeCbForAnyDeviceList_.end(); ++it) {
286 bool isSameCallback = NapiAudioManagerCallback::IsSameCallback(env_, args, (*it)->cb_);
287 CHECK_AND_RETURN_LOG(!isSameCallback, "SaveCallbackReference: spatialization manager has same callback");
288 }
289
290 napi_status status = napi_create_reference(env_, args, refCount, &callback);
291 CHECK_AND_RETURN_LOG(status == napi_ok && callback != nullptr,
292 "NapiAudioHeadTrackingEnabledChangeCallback: creating reference for callback fail");
293
294 std::shared_ptr<AutoRef> cb = std::make_shared<AutoRef>(env_, callback);
295 CHECK_AND_RETURN_LOG(cb != nullptr, "NapiAudioHeadTrackingEnabledChangeCallback: creating callback failed");
296
297 headTrackingEnabledChangeCbForAnyDeviceList_.push_back(cb);
298 }
299 }
300
RemoveHeadTrackingEnabledChangeCallbackReference(napi_env env,napi_value args,const std::string & cbName)301 void NapiAudioHeadTrackingEnabledChangeCallback::RemoveHeadTrackingEnabledChangeCallbackReference(napi_env env,
302 napi_value args, const std::string &cbName)
303 {
304 std::lock_guard<std::mutex> lock(mutex_);
305 if (!cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_CALLBACK_NAME)) {
306 for (auto it = headTrackingEnabledChangeCbList_.begin(); it != headTrackingEnabledChangeCbList_.end(); ++it) {
307 bool isSameCallback = NapiAudioManagerCallback::IsSameCallback(env_, args, (*it)->cb_);
308 if (isSameCallback) {
309 AUDIO_INFO_LOG("RemoveHeadTrackingEnabledChangeCallbackReference: find js callback, delete it");
310 napi_delete_reference(env, (*it)->cb_);
311 (*it)->cb_ = nullptr;
312 headTrackingEnabledChangeCbList_.erase(it);
313 return;
314 }
315 }
316 } else if (!cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_FOR_ANY_DEVICES_CALLBACK_NAME)) {
317 for (auto it = headTrackingEnabledChangeCbForAnyDeviceList_.begin();
318 it != headTrackingEnabledChangeCbForAnyDeviceList_.end(); ++it) {
319 bool isSameCallback = NapiAudioManagerCallback::IsSameCallback(env_, args, (*it)->cb_);
320 if (isSameCallback) {
321 AUDIO_INFO_LOG("RemoveHeadTrackingEnabledChangeCallbackReference: find js callback, delete it");
322 napi_delete_reference(env, (*it)->cb_);
323 (*it)->cb_ = nullptr;
324 headTrackingEnabledChangeCbForAnyDeviceList_.erase(it);
325 return;
326 }
327 }
328 }
329 AUDIO_INFO_LOG("RemoveHeadTrackingEnabledChangeCallbackReference: js callback no find");
330 }
331
RemoveAllHeadTrackingEnabledChangeCallbackReference(const std::string & cbName)332 void NapiAudioHeadTrackingEnabledChangeCallback::RemoveAllHeadTrackingEnabledChangeCallbackReference(const std::string
333 &cbName)
334 {
335 std::lock_guard<std::mutex> lock(mutex_);
336 if (!cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_CALLBACK_NAME)) {
337 for (auto it = headTrackingEnabledChangeCbList_.begin(); it != headTrackingEnabledChangeCbList_.end(); ++it) {
338 napi_delete_reference(env_, (*it)->cb_);
339 (*it)->cb_ = nullptr;
340 }
341 headTrackingEnabledChangeCbList_.clear();
342 } else if (!cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_FOR_ANY_DEVICES_CALLBACK_NAME)) {
343 for (auto it = headTrackingEnabledChangeCbForAnyDeviceList_.begin();
344 it != headTrackingEnabledChangeCbForAnyDeviceList_.end(); ++it) {
345 napi_delete_reference(env_, (*it)->cb_);
346 (*it)->cb_ = nullptr;
347 }
348 headTrackingEnabledChangeCbForAnyDeviceList_.clear();
349 }
350 AUDIO_INFO_LOG("RemoveAllHeadTrackingEnabledChangeCallbackReference: remove all js callbacks success");
351 }
352
GetHeadTrackingEnabledChangeCbListSize(const std::string & cbName)353 int32_t NapiAudioHeadTrackingEnabledChangeCallback::GetHeadTrackingEnabledChangeCbListSize(const std::string &cbName)
354 {
355 std::lock_guard<std::mutex> lock(mutex_);
356 return ((!cbName.compare(HEAD_TRACKING_ENABLED_CHANGE_CALLBACK_NAME)) ? headTrackingEnabledChangeCbList_.size():
357 headTrackingEnabledChangeCbForAnyDeviceList_.size());
358 }
359
OnHeadTrackingEnabledChange(const bool & enabled)360 void NapiAudioHeadTrackingEnabledChangeCallback::OnHeadTrackingEnabledChange(const bool &enabled)
361 {
362 AUDIO_INFO_LOG("OnHeadTrackingEnabledChange entered");
363 std::lock_guard<std::mutex> lock(mutex_);
364
365 for (auto it = headTrackingEnabledChangeCbList_.begin(); it != headTrackingEnabledChangeCbList_.end(); it++) {
366 std::unique_ptr<AudioHeadTrackingEnabledJsCallback> cb =
367 std::make_unique<AudioHeadTrackingEnabledJsCallback>();
368 CHECK_AND_RETURN_LOG(cb != nullptr, "No memory!!");
369 cb->callback = (*it);
370 cb->enabled = enabled;
371 onHeadTrackingEnabledChangeFlag_ = true;
372 OnJsCallbackHeadTrackingEnabled(cb);
373 }
374
375 return;
376 }
377
OnHeadTrackingEnabledChangeForAnyDevice(const sptr<AudioDeviceDescriptor> & deviceDescriptor,const bool & enabled)378 void NapiAudioHeadTrackingEnabledChangeCallback::OnHeadTrackingEnabledChangeForAnyDevice(
379 const sptr<AudioDeviceDescriptor> &deviceDescriptor, const bool &enabled)
380 {
381 AUDIO_INFO_LOG("OnHeadTrackingEnabledChange by the specified device entered");
382 std::lock_guard<std::mutex> lock(mutex_);
383
384 for (auto it = headTrackingEnabledChangeCbList_.begin(); it != headTrackingEnabledChangeCbList_.end(); it++) {
385 std::unique_ptr<AudioHeadTrackingEnabledJsCallback> cb =
386 std::make_unique<AudioHeadTrackingEnabledJsCallback>();
387 CHECK_AND_RETURN_LOG(cb != nullptr, "No memory!!");
388 cb->callback = (*it);
389 cb->enabled = enabled;
390 onHeadTrackingEnabledChangeFlag_ = true;
391 OnJsCallbackHeadTrackingEnabled(cb);
392 }
393 for (auto it = headTrackingEnabledChangeCbForAnyDeviceList_.begin();
394 it != headTrackingEnabledChangeCbForAnyDeviceList_.end(); it++) {
395 std::unique_ptr<AudioHeadTrackingEnabledJsCallback> cb =
396 std::make_unique<AudioHeadTrackingEnabledJsCallback>();
397 CHECK_AND_RETURN_LOG(cb != nullptr, "No memory!!");
398 cb->callback = (*it);
399 cb->deviceDescriptor = deviceDescriptor;
400 cb->enabled = enabled;
401 onHeadTrackingEnabledChangeFlag_ = false;
402 OnJsCallbackHeadTrackingEnabled(cb);
403 }
404
405 return;
406 }
407
WorkCallbackInterruptDone(uv_work_t * work,int status)408 void NapiAudioHeadTrackingEnabledChangeCallback::WorkCallbackInterruptDone(uv_work_t *work, int status)
409 {
410 std::shared_ptr<AudioHeadTrackingEnabledJsCallback> context(
411 static_cast<AudioHeadTrackingEnabledJsCallback*>(work->data),
412 [work](AudioHeadTrackingEnabledJsCallback* ptr) {
413 delete ptr;
414 delete work;
415 });
416 CHECK_AND_RETURN_LOG(work != nullptr, "work is nullptr");
417 AudioHeadTrackingEnabledJsCallback *event = reinterpret_cast<AudioHeadTrackingEnabledJsCallback *>(work->data);
418 CHECK_AND_RETURN_LOG(event != nullptr, "event is nullptr");
419 CHECK_AND_RETURN_LOG(event->callback != nullptr, "event is nullptr");
420 napi_env env = event->callback->env_;
421 napi_ref callback = event->callback->cb_;
422 napi_handle_scope scope = nullptr;
423 napi_open_handle_scope(env, &scope);
424 CHECK_AND_RETURN_LOG(scope != nullptr, "scope is nullptr");
425 do {
426 napi_value jsCallback = nullptr;
427 napi_status nstatus = napi_get_reference_value(env, callback, &jsCallback);
428 CHECK_AND_BREAK_LOG(nstatus == napi_ok && jsCallback != nullptr, "callback get reference value fail");
429 napi_value args[ARGS_ONE] = { nullptr };
430 const size_t argCount = ARGS_ONE;
431 napi_value result = nullptr;
432
433 if (onHeadTrackingEnabledChangeFlag_) {
434 NapiParamUtils::SetValueBoolean(env, event->enabled, args[PARAM0]);
435 CHECK_AND_BREAK_LOG(nstatus == napi_ok && args[PARAM0] != nullptr, "fail to convert to jsobj");
436 } else {
437 AudioSpatialEnabledStateForDevice audioSpatialEnabledStateForDevice;
438 audioSpatialEnabledStateForDevice.deviceDescriptor = event->deviceDescriptor;
439 audioSpatialEnabledStateForDevice.enabled = event->enabled;
440 NapiParamUtils::SetAudioSpatialEnabledStateForDevice(env, audioSpatialEnabledStateForDevice, args[PARAM0]);
441 CHECK_AND_BREAK_LOG(nstatus == napi_ok && args[PARAM0] != nullptr, "fail to convert to jsobj");
442 }
443
444 nstatus = napi_call_function(env, nullptr, jsCallback, argCount, args, &result);
445 CHECK_AND_BREAK_LOG(nstatus == napi_ok, "Fail to call head tracking enabled callback");
446 } while (0);
447 napi_close_handle_scope(env, scope);
448 }
449
OnJsCallbackHeadTrackingEnabled(std::unique_ptr<AudioHeadTrackingEnabledJsCallback> & jsCb)450 void NapiAudioHeadTrackingEnabledChangeCallback::OnJsCallbackHeadTrackingEnabled(
451 std::unique_ptr<AudioHeadTrackingEnabledJsCallback> &jsCb)
452 {
453 uv_loop_s *loop = nullptr;
454 napi_get_uv_event_loop(env_, &loop);
455 CHECK_AND_RETURN_LOG(loop != nullptr, "loop is nullptr");
456
457 uv_work_t *work = new(std::nothrow) uv_work_t;
458 CHECK_AND_RETURN_LOG(work != nullptr, "OnJsCallbackHeadTrackingEnabled: No memory");
459
460 work->data = reinterpret_cast<void *>(jsCb.get());
461 int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {}, WorkCallbackInterruptDone,
462 uv_qos_default);
463 if (ret != 0) {
464 AUDIO_ERR_LOG("Failed to execute libuv work queue");
465 delete work;
466 } else {
467 jsCb.release();
468 }
469 }
470 } // namespace AudioStandard
471 } // namespace OHOS