1 /*
2 * Copyright (c) 2020-2021 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 #include "audio_module.h"
16 #include "media_log.h"
17 #include "js_async_work.h"
18 #include <unistd.h>
19 #include "serializer.h"
20 #include "hal_trace.h"
21
22 extern "C" bool WriteInt32(IpcIo *io, int32_t value);
23 extern "C" void RpcClientTest(int32_t* progress);
24
25 namespace OHOS {
26 namespace ACELite {
27 constexpr char PROP_SUCCESS[] = "success";
28 constexpr char PROP_COMPLETE[] = "complete";
29
30 AudioCallbackInfo AudioModule::audiocallbackinfo_;
31
OnTerminate()32 void AudioModule::OnTerminate()
33 {
34 }
35
DefineProperty(JSIValue target,const char * propName,JSIFunctionHandler getter,JSIFunctionHandler setter)36 void AudioModule::DefineProperty(JSIValue target,
37 const char *propName,
38 JSIFunctionHandler getter,
39 JSIFunctionHandler setter)
40 {
41 JSPropertyDescriptor descriptor;
42 descriptor.getter = getter;
43 descriptor.setter = setter;
44 JSI::DefineNamedProperty(target, propName, descriptor);
45 }
46
Play(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)47 JSIValue AudioModule::Play(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
48 {
49 return JSI::CreateBoolean(AudioPlayer::GetInstance()->Play());
50 }
51
Pause(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)52 JSIValue AudioModule::Pause(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
53 {
54 return JSI::CreateBoolean(AudioPlayer::GetInstance()->Pause());
55 }
56
Stop(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)57 JSIValue AudioModule::Stop(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
58 {
59 return JSI::CreateBoolean(AudioPlayer::GetInstance()->Stop());
60 }
61
GetPlayState(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)62 JSIValue AudioModule::GetPlayState(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
63 {
64 if (argsSize < 1) {
65 MEDIA_ERR_LOG("1 argument is required.");
66 return JSI::CreateBoolean(false);
67 }
68
69 JSIValue options = args[0];
70 if (!JSI::ValueIsObject(options)) {
71 MEDIA_ERR_LOG("invalid parameter.");
72 return JSI::CreateBoolean(false);
73 }
74
75 JSIValue successCallback = JSI::GetNamedProperty(options, PROP_SUCCESS);
76 if (!JSI::ValueIsUndefined(successCallback)) {
77 AudioPlayer *audioPlayer = AudioPlayer::GetInstance();
78 JSIValue data = JSI::CreateObject();
79 JSI::SetStringProperty(data, "status", audioPlayer->GetStatus());
80 JSI::SetStringProperty(data, "src", audioPlayer->GetSrc());
81 JSI::SetNumberProperty(data, "currentTime", audioPlayer->GetCurrentTime());
82 JSI::SetBooleanProperty(data, "autoplay", audioPlayer->GetAutoPlay());
83 JSI::SetBooleanProperty(data, "loop", audioPlayer->IsLooping());
84 JSI::SetNumberProperty(data, "volume", audioPlayer->GetVolume());
85 JSI::SetBooleanProperty(data, "muted", audioPlayer->IsMuted());
86 JSIValue params[1] = { data };
87 JSI::CallFunction(successCallback, thisVal, params, 1);
88 JSI::ReleaseValue(successCallback);
89 }
90
91 JSIValue completeCallback = JSI::GetNamedProperty(options, PROP_COMPLETE);
92 if (!JSI::ValueIsUndefined(completeCallback)) {
93 JSI::CallFunction(completeCallback, thisVal, nullptr, 0);
94 JSI::ReleaseValue(completeCallback);
95 }
96
97 return JSI::CreateUndefined();
98 }
99
SrcGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)100 JSIValue AudioModule::SrcGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
101 {
102 char *src = AudioPlayer::GetInstance()->GetSrc();
103 return (src == nullptr) ? JSI::CreateUndefined() : JSI::CreateString(src);
104 }
105
SrcSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)106 JSIValue AudioModule::SrcSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
107 {
108 if (argsSize < 1) {
109 MEDIA_ERR_LOG("1 argument is required.");
110 return JSI::CreateBoolean(false);
111 }
112 char *src = JSI::ValueToString(args[0]);
113 return JSI::CreateBoolean(AudioPlayer::GetInstance()->SetSrc(src));
114 }
115
CurrentTimeGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)116 JSIValue AudioModule::CurrentTimeGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
117 {
118 return JSI::CreateNumber(AudioPlayer::GetInstance()->GetCurrentTime());
119 }
120
CurrentTimeSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)121 JSIValue AudioModule::CurrentTimeSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
122 {
123 if (argsSize < 1) {
124 MEDIA_ERR_LOG("1 argument is required.");
125 return JSI::CreateBoolean(false);
126 }
127
128 int64_t currentTime = static_cast<int64_t>(JSI::ValueToNumber(args[0]));
129 return JSI::CreateBoolean(AudioPlayer::GetInstance()->SetCurrentTime(currentTime));
130 }
131
DurationGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)132 JSIValue AudioModule::DurationGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
133 {
134 int64_t duation = AudioPlayer::GetInstance()->GetDuration();
135 return duation == -1 ? JSI::CreateNumberNaN() : JSI::CreateNumber(static_cast<double>(duation));
136 }
137
DurationSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)138 JSIValue AudioModule::DurationSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
139 {
140 return JSI::CreateError(JsiErrorType::JSI_ERROR_COMMON, "duration is readonly.");
141 }
142
AutoPlayGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)143 JSIValue AudioModule::AutoPlayGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
144 {
145 return JSI::CreateBoolean(AudioPlayer::GetInstance()->GetAutoPlay());
146 }
147
AutoPlaySetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)148 JSIValue AudioModule::AutoPlaySetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
149 {
150 if (argsSize < 1) {
151 MEDIA_ERR_LOG("1 argument is required.");
152 return JSI::CreateBoolean(false);
153 }
154 bool autoPlay = JSI::ValueToBoolean(args[0]);
155 return JSI::CreateBoolean(AudioPlayer::GetInstance()->SetAutoPlay(autoPlay));
156 }
157
LoopGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)158 JSIValue AudioModule::LoopGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
159 {
160 return JSI::CreateBoolean(AudioPlayer::GetInstance()->IsLooping());
161 }
162
LoopSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)163 JSIValue AudioModule::LoopSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
164 {
165 if (argsSize < 1) {
166 MEDIA_ERR_LOG("1 argument is required.");
167 return JSI::CreateBoolean(false);
168 }
169
170 bool loop = JSI::ValueToBoolean(args[0]);
171 return JSI::CreateBoolean(AudioPlayer::GetInstance()->SetLoop(loop));
172 }
173
VolumeGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)174 JSIValue AudioModule::VolumeGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
175 {
176 return JSI::CreateNumber(AudioPlayer::GetInstance()->GetVolume());
177 }
178
VolumeSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)179 JSIValue AudioModule::VolumeSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
180 {
181 if (argsSize < 1) {
182 MEDIA_ERR_LOG("1 argument is required.");
183 return JSI::CreateBoolean(false);
184 }
185 float volume = static_cast<float>(JSI::ValueToNumber(args[0]));
186 return JSI::CreateBoolean(AudioPlayer::GetInstance()->SetVolume(volume));
187 }
188
MutedGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)189 JSIValue AudioModule::MutedGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
190 {
191 return JSI::CreateBoolean(AudioPlayer::GetInstance()->IsMuted());
192 }
193
MutedSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)194 JSIValue AudioModule::MutedSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
195 {
196 if (argsSize < 1) {
197 MEDIA_ERR_LOG("1 argument is required.");
198 return JSI::CreateBoolean(false);
199 }
200 bool muted = JSI::ValueToBoolean(args[0]);
201 return JSI::CreateBoolean(AudioPlayer::GetInstance()->SetMuted(muted));
202 }
203
OnPlayGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)204 JSIValue AudioModule::OnPlayGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
205 {
206 return GetEventCallback(AudioPlayer::GetInstance()->GetOnPlayListener());
207 }
208
OnPlaySetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)209 JSIValue AudioModule::OnPlaySetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
210 {
211 AudioEventListener *listener = CreateAudioEventListener(args, argsSize);
212 if (listener == nullptr) {
213 return JSI::CreateBoolean(false);
214 }
215 AudioPlayer::GetInstance()->SetOnPlayListener(listener);
216 return JSI::CreateBoolean(true);
217 }
218
OnPauseGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)219 JSIValue AudioModule::OnPauseGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
220 {
221 return GetEventCallback(AudioPlayer::GetInstance()->GetOnPauseListener());
222 }
223
OnPauseSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)224 JSIValue AudioModule::OnPauseSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
225 {
226 AudioEventListener *listener = CreateAudioEventListener(args, argsSize);
227 if (listener == nullptr) {
228 return JSI::CreateBoolean(false);
229 }
230 AudioPlayer::GetInstance()->SetOnPauseListener(listener);
231 return JSI::CreateBoolean(true);
232 }
233
OnStopGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)234 JSIValue AudioModule::OnStopGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
235 {
236 return GetEventCallback(AudioPlayer::GetInstance()->GetOnStopListener());
237 }
238
OnStopSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)239 JSIValue AudioModule::OnStopSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
240 {
241 AudioEventListener *listener = CreateAudioEventListener(args, argsSize);
242 if (listener == nullptr) {
243 return JSI::CreateBoolean(false);
244 }
245 AudioPlayer::GetInstance()->SetOnStopListener(listener);
246 return JSI::CreateBoolean(true);
247 }
248
OnLoadedDataGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)249 JSIValue AudioModule::OnLoadedDataGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
250 {
251 return GetEventCallback(AudioPlayer::GetInstance()->GetOnLoadedDataListener());
252 }
253
OnLoadedDataSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)254 JSIValue AudioModule::OnLoadedDataSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
255 {
256 AudioEventListener *listener = CreateAudioEventListener(args, argsSize);
257 if (listener == nullptr) {
258 return JSI::CreateBoolean(false);
259 }
260 AudioPlayer::GetInstance()->SetOnLoadedDataListener(listener);
261 return JSI::CreateBoolean(true);
262 }
263
OnEndedGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)264 JSIValue AudioModule::OnEndedGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
265 {
266 return GetEventCallback(AudioPlayer::GetInstance()->GetOnEndedListener());
267 }
268
OnEndedSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)269 JSIValue AudioModule::OnEndedSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
270 {
271 AudioEventListener *listener = CreateAudioEventListener(args, argsSize);
272 if (listener == nullptr) {
273 return JSI::CreateBoolean(false);
274 }
275 AudioPlayer::GetInstance()->SetOnEndedListener(listener);
276 return JSI::CreateBoolean(true);
277 }
278
OnErrorGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)279 JSIValue AudioModule::OnErrorGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
280 {
281 return GetEventCallback(AudioPlayer::GetInstance()->GetOnErrorListener());
282 }
283
OnErrorSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)284 JSIValue AudioModule::OnErrorSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
285 {
286 AudioEventListener *listener = CreateAudioEventListener(args, argsSize);
287 if (listener == nullptr) {
288 return JSI::CreateBoolean(false);
289 }
290 AudioPlayer::GetInstance()->SetOnErrorListener(listener);
291 return JSI::CreateBoolean(true);
292 }
293
OnTimeUpdateGetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)294 JSIValue AudioModule::OnTimeUpdateGetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
295 {
296 return GetEventCallback(AudioPlayer::GetInstance()->GetOnTimeUpdateListener());
297 }
298
OnTimeUpdateSetter(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)299 JSIValue AudioModule::OnTimeUpdateSetter(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
300 {
301 AudioEventListener *listener = CreateAudioEventListener(args, argsSize);
302 if (listener == nullptr) {
303 return JSI::CreateBoolean(false);
304 }
305 AudioPlayer::GetInstance()->SetOnTimeUpdateListener(listener);
306 return JSI::CreateBoolean(true);
307 }
308
GetEventCallback(const AudioEventListener * listener)309 JSIValue AudioModule::GetEventCallback(const AudioEventListener *listener)
310 {
311 return (listener == nullptr) ? JSI::CreateUndefined() : listener->GetCallback();
312 }
313
CreateAudioEventListener(const JSIValue * args,uint8_t argsSize)314 AudioEventListener *AudioModule::CreateAudioEventListener(const JSIValue *args, uint8_t argsSize)
315 {
316 if (argsSize < 1) {
317 MEDIA_ERR_LOG("1 argument is required.");
318 return nullptr;
319 }
320
321 JSIValue callback = args[0];
322 if (!JSI::ValueIsFunction(callback)) {
323 MEDIA_ERR_LOG("a function is required.");
324 return nullptr;
325 }
326
327 AudioEventListener *listener = new AudioEventListener(callback);
328 if (listener == nullptr) {
329 MEDIA_ERR_LOG("out of memory.");
330 }
331
332 return listener;
333 }
334 //..............
Oncallback(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)335 JSIValue AudioModule::Oncallback(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
336 {
337 TRACE(0, "%s %d", __func__, __LINE__);
338 audiocallbackinfo_.callback = JSI::AcquireValue(args[0]);
339 audiocallbackinfo_.thisVal_ = JSI::AcquireValue(thisVal);
340
341 return JSI::CreateUndefined();
342 }
343
PlayRemote(const JSIValue thisVal,const JSIValue * args,uint8_t argsSize)344 JSIValue AudioModule::PlayRemote(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
345 {
346 TRACE(0, "%s %d", __func__, __LINE__);
347 if (!JSI::ValueIsNumber(args[0])){
348 return JSI::CreateUndefined();
349 }
350 int32_t data = (int32_t)JSI::ValueToNumber(args[0]);
351 TRACE(0, "this progress: %d", data);
352 RpcClientTest(&data);
353 return JSI::CreateUndefined();
354 }
355
OnPlayRemote(int32_t data)356 void AudioModule::OnPlayRemote(int32_t data)
357 {
358 TRACE(0, "%s %d", __func__, __LINE__);
359 JSIValue dataOne = JSI::CreateObject();
360
361 JSI::SetNumberProperty(dataOne, "progress", (double)data);
362
363 JSIValue param[1] = {dataOne};
364
365 FuncParams* params = new FuncParams();
366 params->handlerRef = audiocallbackinfo_.callback;
367 params->thisVarRef_ = audiocallbackinfo_.thisVal_;
368 params->args = param;
369 params->argsSize = 1;
370 JsAsyncWork::DispatchAsyncWork(OnEventAsyncWorkFunc, reinterpret_cast<void *>(params));
371 }
372
OnEventAsyncWorkFunc(void * data)373 void AudioModule::OnEventAsyncWorkFunc(void *data)
374 {
375 TRACE(0, "%s %d", __func__, __LINE__);
376 FuncParams* params = reinterpret_cast<FuncParams *>(data);
377 JSI::CallFunction(params->handlerRef, params->thisVarRef_, params->args, params->argsSize);
378 }
379
380 static int g_init = 0;
InitAudioModule(JSIValue exports)381 void InitAudioModule(JSIValue exports)
382 {
383
384 if (g_init == 0) {
385 AudioPlayer::GetInstance()->CreatePlayer();
386 AudioPlayer::GetInstance()->ForkUpdateTimeThread();
387 g_init = 1;
388 }
389
390 JSI::SetOnTerminate(exports, AudioModule::OnTerminate);
391 JSI::SetModuleAPI(exports, "play", AudioModule::Play);
392 JSI::SetModuleAPI(exports, "pause", AudioModule::Pause);
393 JSI::SetModuleAPI(exports, "stop", AudioModule::Stop);
394 JSI::SetModuleAPI(exports, "getPlayState", AudioModule::GetPlayState);
395
396 JSI::SetModuleAPI(exports, "onCallback", AudioModule::Oncallback);
397 JSI::SetModuleAPI(exports, "playRemote", AudioModule::PlayRemote);
398
399 AudioModule::DefineProperty(exports, "src", AudioModule::SrcGetter, AudioModule::SrcSetter);
400 AudioModule::DefineProperty(exports, "currentTime", AudioModule::CurrentTimeGetter, AudioModule::CurrentTimeSetter);
401 AudioModule::DefineProperty(exports, "duration", AudioModule::DurationGetter, AudioModule::DurationSetter);
402 AudioModule::DefineProperty(exports, "autoplay", AudioModule::AutoPlayGetter, AudioModule::AutoPlaySetter);
403 AudioModule::DefineProperty(exports, "loop", AudioModule::LoopGetter, AudioModule::LoopSetter);
404 AudioModule::DefineProperty(exports, "volume", AudioModule::VolumeGetter, AudioModule::VolumeSetter);
405 AudioModule::DefineProperty(exports, "muted", AudioModule::MutedGetter, AudioModule::MutedSetter);
406
407 AudioModule::DefineProperty(exports, "onplay", AudioModule::OnPlayGetter, AudioModule::OnPlaySetter);
408 AudioModule::DefineProperty(exports, "onpause", AudioModule::OnPauseGetter, AudioModule::OnPauseSetter);
409 AudioModule::DefineProperty(exports, "onstop", AudioModule::OnStopGetter, AudioModule::OnStopSetter);
410 AudioModule::DefineProperty(exports, "onloadeddata", AudioModule::OnLoadedDataGetter,
411 AudioModule::OnLoadedDataSetter);
412 AudioModule::DefineProperty(exports, "onended", AudioModule::OnEndedGetter, AudioModule::OnEndedSetter);
413 AudioModule::DefineProperty(exports, "onerror", AudioModule::OnErrorGetter, AudioModule::OnErrorSetter);
414 AudioModule::DefineProperty(exports, "ontimeupdate", AudioModule::OnTimeUpdateGetter,
415 AudioModule::OnTimeUpdateSetter);
416 }
417 } // namespace ACELite
418 } // namespace OHOS