• 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 "NapiAudioCapturerInfoChangeCallback"
17 #endif
18 
19 #include "js_native_api.h"
20 #include "napi_audio_capturer_info_change_callback.h"
21 #include "audio_errors.h"
22 #include "audio_capturer_log.h"
23 #include "napi_param_utils.h"
24 
25 namespace OHOS {
26 namespace AudioStandard {
NapiAudioCapturerInfoChangeCallback(napi_env env)27 NapiAudioCapturerInfoChangeCallback::NapiAudioCapturerInfoChangeCallback(napi_env env)
28     : env_(env)
29 {
30     AUDIO_DEBUG_LOG("Instance create");
31 }
32 
~NapiAudioCapturerInfoChangeCallback()33 NapiAudioCapturerInfoChangeCallback::~NapiAudioCapturerInfoChangeCallback()
34 {
35     if (regAcInfoChgTsfn_) {
36         napi_release_threadsafe_function(acInfoChgTsfn_, napi_tsfn_abort);
37     }
38     AUDIO_DEBUG_LOG("Instance destroy");
39 }
40 
SaveCallbackReference(const std::string & callbackName,napi_value args)41 void NapiAudioCapturerInfoChangeCallback::SaveCallbackReference(const std::string &callbackName, napi_value args)
42 {
43     std::lock_guard<std::mutex> lock(mutex_);
44 
45     // create function that will operate while save callback reference success.
46     std::function<void(std::shared_ptr<AutoRef> generatedCallback)> successed =
47         [this](std::shared_ptr<AutoRef> generatedCallback) {
48             callbackPtr_ = generatedCallback;
49             callback_ = callbackPtr_->cb_;
50         };
51         NapiAudioCapturerCallbackInner::SaveCallbackReferenceInner(callbackName, args, successed);
52 }
53 
RemoveCallbackReference(const std::string & callbackName,napi_env env,napi_value callback)54 void NapiAudioCapturerInfoChangeCallback::RemoveCallbackReference(const std::string &callbackName, napi_env env,
55     napi_value callback)
56 {
57     std::lock_guard<std::mutex> lock(mutex_);
58     std::function<void()> successed =
59         [this]() {
60         callbackPtr_ = nullptr;
61         callback_ = nullptr;
62         };
63     NapiAudioCapturerCallbackInner::RemoveCallbackReferenceInner(callbackName, env, callback, successed);
64 }
65 
CreateCaptureInfoChangeTsfn(napi_env env)66 void NapiAudioCapturerInfoChangeCallback::CreateCaptureInfoChangeTsfn(napi_env env)
67 {
68     regAcInfoChgTsfn_ = true;
69     napi_value cbName;
70     std::string callbackName = "AudioCapturerChangeInfo";
71     napi_create_string_utf8(env, callbackName.c_str(), callbackName.length(), &cbName);
72     napi_create_threadsafe_function(env_, nullptr, nullptr, cbName, 0, 1, nullptr, CapturerChangeInfoTsfnFinalize,
73         nullptr, SafeJsCallbackCapturerChangeInfoWork, &acInfoChgTsfn_);
74 }
75 
ContainSameJsCallback(napi_value args)76 bool NapiAudioCapturerInfoChangeCallback::ContainSameJsCallback(napi_value args)
77 {
78     bool isEquals = false;
79     napi_value copyValue = nullptr;
80 
81     napi_get_reference_value(env_, callback_, &copyValue);
82     CHECK_AND_RETURN_RET_LOG(args != nullptr, false, "args is nullptr");
83 
84     CHECK_AND_RETURN_RET_LOG(napi_strict_equals(env_, copyValue, args, &isEquals) == napi_ok, false,
85         "Get napi_strict_equals failed");
86 
87     return isEquals;
88 }
89 
OnStateChange(const AudioCapturerChangeInfo & capturerChangeInfo)90 void NapiAudioCapturerInfoChangeCallback::OnStateChange(const AudioCapturerChangeInfo &capturerChangeInfo)
91 {
92     OnJsCallbackCapturerChangeInfo(callback_, capturerChangeInfo);
93 }
94 
SafeJsCallbackCapturerChangeInfoWork(napi_env env,napi_value js_cb,void * context,void * data)95 void NapiAudioCapturerInfoChangeCallback::SafeJsCallbackCapturerChangeInfoWork(
96     napi_env env, napi_value js_cb, void *context, void *data)
97 {
98     AudioCapturerChangeInfoJsCallback *event = reinterpret_cast<AudioCapturerChangeInfoJsCallback *>(data);
99     CHECK_AND_RETURN_LOG((event != nullptr) && (event->callback_) != nullptr,
100         "OnJsCallbackCapturerChangeInfo: no memory");
101     std::shared_ptr<AudioCapturerChangeInfoJsCallback> safeContext(
102         static_cast<AudioCapturerChangeInfoJsCallback*>(data),
103         [](AudioCapturerChangeInfoJsCallback *ptr) {
104             delete ptr;
105     });
106     if (event == nullptr || event->callback_ == nullptr) {
107         AUDIO_ERR_LOG("OnJsCallbackCapturerChangeInfo: no memory");
108         return;
109     }
110     napi_ref callback = event->callback_;
111     napi_handle_scope scope = nullptr;
112     napi_open_handle_scope(env, &scope);
113     CHECK_AND_RETURN_LOG(scope != nullptr, "scope is nullptr");
114     AUDIO_INFO_LOG("SafeJsCallbackCapturerChangeInfoWork: safe js callback working.");
115     do {
116         napi_value jsCallback = nullptr;
117         napi_status nstatus = napi_get_reference_value(env, callback, &jsCallback);
118         CHECK_AND_BREAK_LOG(nstatus == napi_ok && jsCallback != nullptr, "Callback get reference value fail");
119         // Call back function
120         napi_value args[ARGS_ONE] = { nullptr };
121         NapiParamUtils::SetAudioCapturerChangeInfoDescriptors(env, event->capturerChangeInfo_, args[0]);
122         CHECK_AND_BREAK_LOG(nstatus == napi_ok && args[PARAM0] != nullptr,
123             "Fail to convert to jsobj");
124 
125         const size_t argCount = ARGS_ONE;
126         napi_value result = nullptr;
127         nstatus = napi_call_function(env, nullptr, jsCallback, argCount, args, &result);
128         CHECK_AND_BREAK_LOG(nstatus == napi_ok, "Fail to call capturer callback");
129     } while (0);
130     napi_close_handle_scope(env, scope);
131 }
132 
CapturerChangeInfoTsfnFinalize(napi_env env,void * data,void * hint)133 void NapiAudioCapturerInfoChangeCallback::CapturerChangeInfoTsfnFinalize(napi_env env, void *data, void *hint)
134 {
135     AUDIO_INFO_LOG("CapturerChangeInfoTsfnFinalize: safe thread resource release.");
136 }
137 
OnJsCallbackCapturerChangeInfo(napi_ref method,const AudioCapturerChangeInfo & capturerChangeInfo)138 void NapiAudioCapturerInfoChangeCallback::OnJsCallbackCapturerChangeInfo(napi_ref method,
139     const AudioCapturerChangeInfo &capturerChangeInfo)
140 {
141     CHECK_AND_RETURN_LOG(method != nullptr, "method is nullptr");
142     AudioCapturerChangeInfoJsCallback *event =
143         new AudioCapturerChangeInfoJsCallback {method, env_, capturerChangeInfo};
144 
145     napi_acquire_threadsafe_function(acInfoChgTsfn_);
146     napi_call_threadsafe_function(acInfoChgTsfn_, event, napi_tsfn_blocking);
147 }
148 
GetEnv()149 napi_env &NapiAudioCapturerInfoChangeCallback::GetEnv()
150 {
151     return env_;
152 }
153 
GetCallback(const std::string & callbackName)154 std::shared_ptr<AutoRef> NapiAudioCapturerInfoChangeCallback::GetCallback(const std::string &callbackName)
155 {
156     return callbackPtr_;
157 }
158 
CheckIfTargetCallbackName(const std::string & callbackName)159 bool NapiAudioCapturerInfoChangeCallback::CheckIfTargetCallbackName(const std::string &callbackName)
160 {
161     if (callbackName == AUDIO_CAPTURER_CHANGE_CALLBACK_NAME) {
162         return true;
163     }
164     return false;
165 }
166 }  // namespace AudioStandard
167 }  // namespace OHOS
168