• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 
16 #include "renderer_data_request_callback_napi.h"
17 
18 #include <uv.h>
19 
20 #include "audio_errors.h"
21 #include "audio_log.h"
22 
23 namespace {
24     const std::string RENDERER_DATA_REQUEST_CALLBACK_NAME = "dataRequest";
25 }
26 
27 namespace OHOS {
28 namespace AudioStandard {
RendererDataRequestCallbackNapi(napi_env env,AudioRendererNapi * rendererNapi)29 RendererDataRequestCallbackNapi::RendererDataRequestCallbackNapi(napi_env env, AudioRendererNapi *rendererNapi)
30     : env_(env),
31       rendererNapi_(rendererNapi)
32 {
33     AUDIO_INFO_LOG("RendererDataRequestCallbackNapi: instance create");
34 }
35 
~RendererDataRequestCallbackNapi()36 RendererDataRequestCallbackNapi::~RendererDataRequestCallbackNapi()
37 {
38     AUDIO_INFO_LOG("RendererDataRequestCallbackNapi: instance destroy");
39 }
40 
SaveCallbackReference(const std::string & callbackName,napi_value args)41 void RendererDataRequestCallbackNapi::SaveCallbackReference(const std::string &callbackName, napi_value args)
42 {
43     std::lock_guard<std::mutex> lock(mutex_);
44     napi_ref callback = nullptr;
45     const int32_t refCount = 1;
46     napi_status status = napi_create_reference(env_, args, refCount, &callback);
47     CHECK_AND_RETURN_LOG(status == napi_ok && callback != nullptr,
48                          "RendererDataRequestCallbackNapi: creating reference for callback fail");
49 
50     std::shared_ptr<AutoRef> cb = std::make_shared<AutoRef>(env_, callback);
51     if (callbackName == RENDERER_DATA_REQUEST_CALLBACK_NAME) {
52         rendererDataRequestCallback_ = cb;
53     } else {
54         AUDIO_ERR_LOG("RendererDataRequestCallbackNapi: Unknown callback type: %{public}s", callbackName.c_str());
55     }
56 }
57 
OnWriteData(size_t length)58 void RendererDataRequestCallbackNapi::OnWriteData(size_t length)
59 {
60     std::lock_guard<std::mutex> lock(mutex_);
61     AUDIO_DEBUG_LOG("RendererDataRequestCallbackNapi: onDataRequest enqueue added");
62     CHECK_AND_RETURN_LOG(rendererDataRequestCallback_ != nullptr, "Cannot find the reference of dataRequest callback");
63     CHECK_AND_RETURN_LOG(rendererNapi_ != nullptr, "Cannot find the reference to audio renderer napi");
64     std::unique_ptr<RendererDataRequestJsCallback> cb = std::make_unique<RendererDataRequestJsCallback>();
65     CHECK_AND_RETURN_LOG(cb != nullptr, "No memory");
66     cb->callback = rendererDataRequestCallback_;
67     cb->callbackName = RENDERER_DATA_REQUEST_CALLBACK_NAME;
68     size_t reqLen = length;
69     cb->bufDesc_.buffer = nullptr;
70     cb->rendererNapiObj = rendererNapi_;
71     rendererNapi_->audioRenderer_->GetBufferDesc(cb->bufDesc_);
72     if (cb->bufDesc_.buffer == nullptr) {
73         return;
74     }
75     if (reqLen > cb->bufDesc_.bufLength) {
76         cb->bufDesc_.dataLength = cb->bufDesc_.bufLength;
77     } else {
78         cb->bufDesc_.dataLength = reqLen;
79     }
80     AudioRendererDataInfo audioRendererDataInfo = {};
81     audioRendererDataInfo.buffer = cb->bufDesc_.buffer;
82     audioRendererDataInfo.flag =  cb->bufDesc_.bufLength;
83     cb->audioRendererDataInfo = audioRendererDataInfo;
84     return OnJsRendererDataRequestCallback(cb);
85 }
86 
SetValueInt32(const napi_env & env,const std::string & fieldStr,const int intValue,napi_value & result)87 static void SetValueInt32(const napi_env& env, const std::string& fieldStr, const int intValue, napi_value& result)
88 {
89     napi_value value = nullptr;
90     napi_create_int32(env, intValue, &value);
91     napi_set_named_property(env, result, fieldStr.c_str(), value);
92 }
93 
CreateArrayBuffer(const napi_env & env,const std::string & fieldStr,size_t bufferLen,uint8_t * bufferData,napi_value & result)94 static void CreateArrayBuffer(const napi_env& env, const std::string& fieldStr, size_t bufferLen,
95     uint8_t* bufferData, napi_value& result)
96 {
97     napi_value value = nullptr;
98 
99     napi_create_arraybuffer(env, bufferLen, (void**)&bufferData, &value);
100     napi_set_named_property(env, result, fieldStr.c_str(), value);
101 }
102 
NativeAudioRendererDataInfoToJsObj(const napi_env & env,napi_value & jsObj,const AudioRendererDataInfo & audioRendererDataInfo)103 static void NativeAudioRendererDataInfoToJsObj(const napi_env& env, napi_value& jsObj,
104     const AudioRendererDataInfo &audioRendererDataInfo)
105 {
106     napi_create_object(env, &jsObj);
107 
108     SetValueInt32(env, "flag", static_cast<int32_t>(audioRendererDataInfo.flag), jsObj);
109     CreateArrayBuffer(env, "buffer", audioRendererDataInfo.flag, audioRendererDataInfo.buffer, jsObj);
110 }
111 
OnJsRendererDataRequestCallback(std::unique_ptr<RendererDataRequestJsCallback> & jsCb)112 void RendererDataRequestCallbackNapi::OnJsRendererDataRequestCallback(
113     std::unique_ptr<RendererDataRequestJsCallback> &jsCb)
114 {
115     uv_loop_s *loop = nullptr;
116     napi_get_uv_event_loop(env_, &loop);
117     if (loop == nullptr) {
118         return;
119     }
120 
121     uv_work_t *work = new(std::nothrow) uv_work_t;
122     if (work == nullptr) {
123         AUDIO_ERR_LOG("RendererDataRequestCallbackNapi: OnJsRendererPeriodPositionCallback: No memory");
124         return;
125     }
126     if (jsCb.get() == nullptr) {
127         AUDIO_ERR_LOG("RendererDataRequestCallbackNapi: OnJsRendererPeriodPositionCallback: jsCb.get() is null");
128         delete work;
129         return;
130     }
131     work->data = reinterpret_cast<void *>(jsCb.get());
132 
133     int ret = uv_queue_work(loop, work, [] (uv_work_t *work) {}, [] (uv_work_t *work, int status) {
134         // Js Thread
135         RendererDataRequestJsCallback *event = reinterpret_cast<RendererDataRequestJsCallback *>(work->data);
136         std::string request = event->callbackName;
137         napi_env env = event->callback->env_;
138         napi_ref callback = event->callback->cb_;
139         AUDIO_DEBUG_LOG("RendererDataRequestCallbackNapi: JsCallBack %{public}s, uv_queue_work start",
140             request.c_str());
141         do {
142             CHECK_AND_BREAK_LOG(status != UV_ECANCELED, "%{public}s canceled", request.c_str());
143 
144             napi_value jsCallback = nullptr;
145             napi_status nstatus = napi_get_reference_value(env, callback, &jsCallback);
146             CHECK_AND_BREAK_LOG(nstatus == napi_ok && jsCallback != nullptr, "%{public}s get reference value fail",
147                 request.c_str());
148 
149             napi_value args[1] = { nullptr };
150             NativeAudioRendererDataInfoToJsObj(env, args[0], event->audioRendererDataInfo);
151             CHECK_AND_BREAK_LOG(nstatus == napi_ok && args[0] != nullptr,
152                 "%{public}s fail to create position callback", request.c_str());
153             const size_t argCount = 1;
154             napi_value result = nullptr;
155             nstatus = napi_call_function(env, nullptr, jsCallback, argCount, args, &result);
156             event->rendererNapiObj->audioRenderer_->Enqueue(event->bufDesc_);
157             CHECK_AND_BREAK_LOG(nstatus == napi_ok, "%{public}s fail to call position callback", request.c_str());
158         } while (0);
159         delete event;
160         delete work;
161     });
162     if (ret != 0) {
163         AUDIO_ERR_LOG("Failed to execute libuv work queue");
164         delete work;
165     } else {
166         jsCb.release();
167     }
168 }
169 }  // namespace AudioStandard
170 }  // namespace OHOS
171