1 /*
2 * Copyright (c) 2024 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 "system_sound_manager_napi.h"
17
18 #include "access_token.h"
19 #include "accesstoken_kit.h"
20 #include "audio_renderer_info_napi.h"
21 #include "ipc_skeleton.h"
22 #include "system_sound_log.h"
23 #include "tokenid_kit.h"
24
25 using namespace std;
26 using OHOS::Security::AccessToken::AccessTokenKit;
27
28 namespace {
29 /* Constants for array index */
30 const int32_t PARAM0 = 0;
31 const int32_t PARAM1 = 1;
32 const int32_t PARAM2 = 2;
33
34 /* Constants for array size */
35 const int32_t ARGS_ONE = 1;
36 const int32_t ARGS_TWO = 2;
37 const int32_t ARGS_THREE = 3;
38 const int32_t SIZE = 1024;
39
40 const int UNSUPPORTED_ERROR = -5;
41 const int OPERATION_ERROR = -4;
42 const int IO_ERROR = -3;
43 const int ERROR = -1;
44
45 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO_NAPI, "SystemSoundManagerNapi"};
46 }
47
48 namespace OHOS {
49 namespace Media {
GetToneHapticsSettings(napi_env env,napi_callback_info info)50 napi_value SystemSoundManagerNapi::GetToneHapticsSettings(napi_env env, napi_callback_info info)
51 {
52 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(), ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO,
53 NAPI_ERR_PERMISSION_DENIED), "No system permission");
54 napi_value result = nullptr;
55 napi_value resource = nullptr;
56 napi_value thisVar = nullptr;
57 size_t argc = ARGS_TWO;
58 napi_value argv[ARGS_TWO] = {};
59
60 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
61 napi_get_undefined(env, &result);
62 CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
63 "GetToneHapticsSettings: Failed to retrieve details about the callback");
64 CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
65 NAPI_ERR_INPUT_INVALID), "invalid arguments");
66 std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
67 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
68 CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
69 "GetToneHapticsSettings: Failed to unwrap object");
70
71 for (size_t i = PARAM0; i < argc; i++) {
72 napi_valuetype valueType = napi_undefined;
73 napi_typeof(env, argv[i], &valueType);
74 if (i == PARAM0) {
75 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
76 } else if (i == PARAM1 && valueType == napi_number) {
77 napi_get_value_int32(env, argv[PARAM1], &asyncContext->toneHapticsType);
78 asyncContext->toneHapticsType = asyncContext->toneHapticsType;
79 }
80 }
81 MEDIA_LOGI("GetToneHapticsSettings toneHapticsType : %{public}d", asyncContext->toneHapticsType);
82 CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
83 ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
84 napi_create_promise(env, &asyncContext->deferred, &result);
85 napi_create_string_utf8(env, "GetToneHapticsSettings", NAPI_AUTO_LENGTH, &resource);
86 status = napi_create_async_work(env, nullptr, resource, AsyncGetToneHapticsSettings,
87 GetToneHapticsSettingsAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
88 if (status != napi_ok) {
89 MEDIA_LOGE("GetToneHapticsSettings: Failed to get create async work");
90 napi_get_undefined(env, &result);
91 } else {
92 napi_queue_async_work(env, asyncContext->work);
93 asyncContext.release();
94 }
95 return result;
96 }
97
AsyncGetToneHapticsSettings(napi_env env,void * data)98 void SystemSoundManagerNapi::AsyncGetToneHapticsSettings(napi_env env, void *data)
99 {
100 SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
101 if (context->objectInfo->sysSoundMgrClient_ == nullptr) {
102 return;
103 }
104 int32_t result = context->objectInfo->sysSoundMgrClient_->GetToneHapticsSettings(context->abilityContext_,
105 static_cast<ToneHapticsType>(context->toneHapticsType), context->toneHapticsSettings);
106 context->status = result;
107 if (result == IO_ERROR) {
108 context->errCode = NAPI_ERR_IO_ERROR;
109 context->errMessage = NAPI_ERR_IO_ERROR_INFO;
110 } else if (result == UNSUPPORTED_ERROR) {
111 context->errCode = NAPI_ERR_UNSUPPORTED_OPERATION;
112 context->errMessage = NAPI_ERR_UNSUPPORTED_OPERATION_INFO;
113 }
114 }
115
GetToneHapticsSettingsAsyncCallbackComp(napi_env env,napi_status status,void * data)116 void SystemSoundManagerNapi::GetToneHapticsSettingsAsyncCallbackComp(napi_env env, napi_status status,
117 void *data)
118 {
119 auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
120 napi_value result[2] = {};
121
122 if (!context->status) {
123 napi_get_undefined(env, &result[PARAM0]);
124 context->status = ToneHapticsSettingsNapi::NewInstance(env, context->toneHapticsSettings, result[PARAM1]);
125 } else {
126 result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
127 napi_get_undefined(env, &result[PARAM1]);
128 }
129
130 if (context->deferred) {
131 if (!context->status) {
132 napi_resolve_deferred(env, context->deferred, result[PARAM1]);
133 } else {
134 napi_reject_deferred(env, context->deferred, result[PARAM0]);
135 }
136 }
137
138 napi_delete_async_work(env, context->work);
139 delete context;
140 context = nullptr;
141 }
142
ExtractStringToEnv(const napi_env & env,const napi_value & argv)143 std::string SystemSoundManagerNapi::ExtractStringToEnv(const napi_env &env, const napi_value &argv)
144 {
145 char buffer[SIZE] = {0};
146 size_t res = 0;
147 napi_get_value_string_utf8(env, argv, buffer, SIZE, &res);
148 return std::string(buffer);
149 }
150
GetToneHapticsSettingsToEnv(const napi_env & env,const napi_value & argv,ToneHapticsSettings & toneHapticsSettings)151 void SystemSoundManagerNapi::GetToneHapticsSettingsToEnv(const napi_env &env, const napi_value &argv,
152 ToneHapticsSettings &toneHapticsSettings)
153 {
154 napi_value property = nullptr;
155 char buffer[SIZE] = {0};
156 size_t res = 0;
157 int32_t mode = 0;
158
159 if (napi_get_named_property(env, argv, "mode", &property) == napi_ok) {
160 napi_get_value_int32(env, property, &mode);
161 toneHapticsSettings.mode = static_cast<ToneHapticsMode>(mode);
162 }
163 if (napi_get_named_property(env, argv, "hapticsUri", &property) == napi_ok) {
164 napi_get_value_string_utf8(env, property, buffer, SIZE, &res);
165 toneHapticsSettings.hapticsUri = std::string(buffer);
166 }
167 }
168
SetToneHapticsSettings(napi_env env,napi_callback_info info)169 napi_value SystemSoundManagerNapi::SetToneHapticsSettings(napi_env env, napi_callback_info info)
170 {
171 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(), ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO,
172 NAPI_ERR_PERMISSION_DENIED), "No system permission");
173 napi_value result = nullptr;
174 napi_value resource = nullptr;
175 napi_value thisVar = nullptr;
176 size_t argc = ARGS_THREE;
177 napi_value argv[ARGS_THREE] = {0};
178 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
179 napi_get_undefined(env, &result);
180 CHECK_AND_RETURN_RET_LOG(status == napi_ok && thisVar != nullptr, result,
181 "SetToneHapticsSettings: get_cb_info failed");
182 CHECK_AND_RETURN_RET_LOG(argc == ARGS_THREE, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
183 NAPI_ERR_INPUT_INVALID), "invalid arguments");
184 std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
185 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
186 CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
187 "SetToneHapticsSettings: Failed to unwrap object");
188 for (size_t i = PARAM0; i < argc; i++) {
189 napi_valuetype valueType = napi_undefined;
190 napi_typeof(env, argv[i], &valueType);
191 if (i == PARAM0) {
192 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
193 } else if (i == PARAM1 && valueType == napi_number) {
194 napi_get_value_int32(env, argv[i], &asyncContext->toneHapticsType);
195 asyncContext->toneHapticsType = asyncContext->toneHapticsType;
196 } else if (i == PARAM2 && valueType == napi_object) {
197 GetToneHapticsSettingsToEnv(env, argv[PARAM2], asyncContext->toneHapticsSettings);
198 }
199 }
200 MEDIA_LOGI("SetToneHapticsSettings toneHapticsType : %{public}d mode : %{public}d", asyncContext->toneHapticsType,
201 asyncContext->toneHapticsSettings.mode);
202 CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
203 ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
204 napi_create_promise(env, &asyncContext->deferred, &result);
205 napi_create_string_utf8(env, "SetToneHapticsSettings", NAPI_AUTO_LENGTH, &resource);
206 status = napi_create_async_work(env, nullptr, resource, AsyncSetToneHapticsSettings,
207 SetToneHapticsSettingsAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
208 if (status != napi_ok) {
209 MEDIA_LOGE("SetToneHapticsSettings: Failed to get create async work");
210 napi_get_undefined(env, &result);
211 } else {
212 napi_queue_async_work(env, asyncContext->work);
213 asyncContext.release();
214 }
215 return result;
216 }
217
AsyncSetToneHapticsSettings(napi_env env,void * data)218 void SystemSoundManagerNapi::AsyncSetToneHapticsSettings(napi_env env, void *data)
219 {
220 SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
221 if (context->objectInfo->sysSoundMgrClient_ == nullptr) {
222 return;
223 }
224 int32_t result = context->objectInfo->sysSoundMgrClient_->SetToneHapticsSettings(context->abilityContext_,
225 static_cast<ToneHapticsType>(context->toneHapticsType), context->toneHapticsSettings);
226 context->status = result;
227 if (result == OPERATION_ERROR) {
228 context->errCode = NAPI_ERR_OPERATE_NOT_ALLOWED;
229 context->errMessage = NAPI_ERR_OPERATE_NOT_ALLOWED_INFO;
230 } else if (result == IO_ERROR) {
231 context->errCode = NAPI_ERR_IO_ERROR;
232 context->errMessage = NAPI_ERR_IO_ERROR_INFO;
233 } else if (result == UNSUPPORTED_ERROR) {
234 context->errCode = NAPI_ERR_UNSUPPORTED_OPERATION;
235 context->errMessage = NAPI_ERR_UNSUPPORTED_OPERATION_INFO;
236 }
237 }
238
SetToneHapticsSettingsAsyncCallbackComp(napi_env env,napi_status status,void * data)239 void SystemSoundManagerNapi::SetToneHapticsSettingsAsyncCallbackComp(napi_env env, napi_status status, void *data)
240 {
241 auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
242 napi_value result[2] = {};
243
244 if (!context->status) {
245 napi_get_undefined(env, &result[PARAM0]);
246 napi_get_undefined(env, &result[PARAM1]);
247 } else {
248 result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
249 napi_get_undefined(env, &result[PARAM1]);
250 }
251
252 if (context->deferred) {
253 if (!context->status) {
254 napi_resolve_deferred(env, context->deferred, result[PARAM1]);
255 } else {
256 napi_reject_deferred(env, context->deferred, result[PARAM0]);
257 }
258 }
259
260 napi_delete_async_work(env, context->work);
261 delete context;
262 context = nullptr;
263 }
264
GetToneHapticsList(napi_env env,napi_callback_info info)265 napi_value SystemSoundManagerNapi::GetToneHapticsList(napi_env env, napi_callback_info info)
266 {
267 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(), ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO,
268 NAPI_ERR_PERMISSION_DENIED), "No system permission");
269 napi_value result = nullptr;
270 napi_value resource = nullptr;
271 napi_value thisVar = nullptr;
272 size_t argc = ARGS_TWO;
273 napi_value argv[ARGS_TWO] = {0};
274
275 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
276 napi_get_undefined(env, &result);
277 CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
278 "GetToneHapticsList: Failed to retrieve details about the callback");
279 CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
280 NAPI_ERR_INPUT_INVALID), "invalid arguments");
281 std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
282 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
283 CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
284 "GetToneHapticsList: Failed to unwrap object");
285 for (size_t i = PARAM0; i < argc; i ++) {
286 napi_valuetype valueType = napi_undefined;
287 napi_typeof(env, argv[i], &valueType);
288 if (i == PARAM0) {
289 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
290 } else if (i == PARAM1 && valueType == napi_boolean) {
291 napi_get_value_bool(env, argv[i], &asyncContext->isSynced);
292 }
293 }
294 MEDIA_LOGI("GetToneHapticsList isSynced : %{public}s", asyncContext->isSynced ? "true" : "false");
295 CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
296 ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "Parameter error");
297 napi_create_promise(env, &asyncContext->deferred, &result);
298 napi_create_string_utf8(env, "GetToneHapticsList", NAPI_AUTO_LENGTH, &resource);
299 status = napi_create_async_work(env, nullptr, resource, AsyncGetToneHapticsList,
300 GetToneHapticsListAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
301 if (status != napi_ok) {
302 MEDIA_LOGE("Failed to get create async work");
303 napi_get_undefined(env, &result);
304 } else {
305 napi_queue_async_work(env, asyncContext->work);
306 asyncContext.release();
307 }
308 return result;
309 }
310
AsyncGetToneHapticsList(napi_env env,void * data)311 void SystemSoundManagerNapi::AsyncGetToneHapticsList(napi_env env, void *data)
312 {
313 SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
314 if (context->objectInfo->sysSoundMgrClient_ == nullptr) {
315 return;
316 }
317 int32_t result = context->objectInfo->sysSoundMgrClient_->GetToneHapticsList(context->abilityContext_,
318 context->isSynced, context->toneHapticsAttrsArray);
319 context->status = result;
320 if (result == IO_ERROR) {
321 context->errCode = NAPI_ERR_IO_ERROR;
322 context->errMessage = NAPI_ERR_IO_ERROR_INFO;
323 } else if (result == UNSUPPORTED_ERROR) {
324 context->errCode = NAPI_ERR_UNSUPPORTED_OPERATION;
325 context->errMessage = NAPI_ERR_UNSUPPORTED_OPERATION_INFO;
326 }
327 }
328
GetToneHapticsListAsyncCallbackComp(napi_env env,napi_status status,void * data)329 void SystemSoundManagerNapi::GetToneHapticsListAsyncCallbackComp(napi_env env, napi_status status, void *data)
330 {
331 auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
332 napi_value result[2] = {};
333 if (!context->status) {
334 napi_get_undefined(env, &result[PARAM0]);
335 context->status = napi_create_array_with_length(env, context->toneHapticsAttrsArray.size(), &result[PARAM1]);
336 size_t count = 0;
337 for (auto &toneHapticsAttrs : context->toneHapticsAttrsArray) {
338 napi_value jsToneHapticsAttrs = nullptr;
339 ToneHapticsAttrsNapi::NewInstance(env, toneHapticsAttrs, jsToneHapticsAttrs);
340 context->status = napi_set_element(env, result[PARAM1], count, jsToneHapticsAttrs);
341 count++;
342 }
343 } else {
344 result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
345 napi_get_undefined(env, &result[PARAM1]);
346 }
347 if (context->deferred) {
348 if (!context->status) {
349 napi_resolve_deferred(env, context->deferred, result[PARAM1]);
350 } else {
351 napi_reject_deferred(env, context->deferred, result[PARAM0]);
352 }
353 }
354
355 napi_delete_async_work(env, context->work);
356 delete context;
357 context = nullptr;
358 }
359
GetHapticsAttrsSyncedWithTone(napi_env env,napi_callback_info info)360 napi_value SystemSoundManagerNapi::GetHapticsAttrsSyncedWithTone(napi_env env, napi_callback_info info)
361 {
362 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(), ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO,
363 NAPI_ERR_PERMISSION_DENIED), "No system permission");
364 napi_value result = nullptr;
365 napi_value resource = nullptr;
366 napi_value thisVar = nullptr;
367 size_t argc = ARGS_TWO;
368 napi_value argv[ARGS_TWO] = {};
369 char buffer[SIZE];
370 size_t res = 0;
371 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
372 napi_get_undefined(env, &result);
373 CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
374 "GetHapticsAttrsSyncedWithTone: Failed to retrieve details about the callback");
375 CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
376 NAPI_ERR_INPUT_INVALID), "invalid arguments");
377 std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
378 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
379 CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
380 "GetHapticsAttrsSyncedWithTone: Failed to unwrap object");
381 for (size_t i = PARAM0; i < argc; i++) {
382 napi_valuetype valueType = napi_undefined;
383 napi_typeof(env, argv[i], &valueType);
384 if (i == PARAM0) {
385 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
386 } else if (i == PARAM1 && valueType == napi_string) {
387 napi_get_value_string_utf8(env, argv[i], buffer, SIZE, &res);
388 asyncContext->toneUri = std::string(buffer);
389 }
390 }
391 MEDIA_LOGI("GetHapticsAttrsSyncedWithTone toneUri : %{public}s", asyncContext->toneUri.c_str());
392 CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
393 ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
394 napi_create_promise(env, &asyncContext->deferred, &result);
395 napi_create_string_utf8(env, "GetHapticsAttrsSyncedWithTone", NAPI_AUTO_LENGTH, &resource);
396 status = napi_create_async_work(env, nullptr, resource, AsyncGetHapticsAttrsSyncedWithTone,
397 GetHapticsAttrsSyncedWithToneAsyncCallbackComp, static_cast<void*>(asyncContext.get()),
398 &asyncContext->work);
399 if (status != napi_ok) {
400 MEDIA_LOGE("GetHapticsAttrsSyncedWithTone : Failed to get create async work");
401 napi_get_undefined(env, &result);
402 } else {
403 napi_queue_async_work(env, asyncContext->work);
404 asyncContext.release();
405 }
406 return result;
407 }
408
AsyncGetHapticsAttrsSyncedWithTone(napi_env env,void * data)409 void SystemSoundManagerNapi::AsyncGetHapticsAttrsSyncedWithTone(napi_env env, void *data)
410 {
411 SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
412 if (context->objectInfo->sysSoundMgrClient_ == nullptr) {
413 return;
414 }
415 int32_t result = context->objectInfo->sysSoundMgrClient_->GetHapticsAttrsSyncedWithTone(context->abilityContext_,
416 context->toneUri, context->toneHapticsAttrs);
417 context->status = result;
418 if (result == OPERATION_ERROR) {
419 context->errCode = NAPI_ERR_OPERATE_NOT_ALLOWED;
420 context->errMessage = NAPI_ERR_OPERATE_NOT_ALLOWED_INFO;
421 } else if (result == IO_ERROR) {
422 context->errCode = NAPI_ERR_IO_ERROR;
423 context->errMessage = NAPI_ERR_IO_ERROR_INFO;
424 } else if (result == UNSUPPORTED_ERROR) {
425 context->errCode = NAPI_ERR_UNSUPPORTED_OPERATION;
426 context->errMessage = NAPI_ERR_UNSUPPORTED_OPERATION_INFO;
427 }
428 }
429
GetHapticsAttrsSyncedWithToneAsyncCallbackComp(napi_env env,napi_status status,void * data)430 void SystemSoundManagerNapi::GetHapticsAttrsSyncedWithToneAsyncCallbackComp(napi_env env, napi_status status,
431 void *data)
432 {
433 auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
434 napi_value result[2] = {};
435
436 if (!context->status) {
437 napi_get_undefined(env, &result[PARAM0]);
438 ToneHapticsAttrsNapi::NewInstance(env, context->toneHapticsAttrs, result[PARAM1]);
439 } else {
440 result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
441 napi_get_undefined(env, &result[PARAM1]);
442 }
443
444 if (context->deferred) {
445 if (!context->status) {
446 napi_resolve_deferred(env, context->deferred, result[PARAM1]);
447 } else {
448 napi_reject_deferred(env, context->deferred, result[PARAM0]);
449 }
450 }
451
452 napi_delete_async_work(env, context->work);
453 delete context;
454 context = nullptr;
455 }
456
457
OpenToneHaptics(napi_env env,napi_callback_info info)458 napi_value SystemSoundManagerNapi::OpenToneHaptics(napi_env env, napi_callback_info info)
459 {
460 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
461 ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
462 "No system permission");
463 napi_value result = nullptr;
464 napi_value resource = nullptr;
465 napi_value thisVar = nullptr;
466 size_t argc = ARGS_TWO;
467 napi_value argv[ARGS_TWO] = {};
468 char buffer[SIZE];
469 size_t res = 0;
470 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
471 napi_get_undefined(env, &result);
472 CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
473 "OpenToneHaptics: Failed to retrieve details about the callback");
474 CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
475 NAPI_ERR_INPUT_INVALID), "invalid arguments");
476 std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
477 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
478 CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
479 "OpenToneHaptics: Failed to unwrap object");
480 for (size_t i = PARAM0; i < argc; i++) {
481 napi_valuetype valueType = napi_undefined;
482 napi_typeof(env, argv[i], &valueType);
483 if (i == PARAM0) {
484 asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
485 } else if (i == PARAM1 && valueType == napi_string) {
486 napi_get_value_string_utf8(env, argv[i], buffer, SIZE, &res);
487 asyncContext->hapticsUri = std::string(buffer);
488 }
489 }
490 MEDIA_LOGI("OpenToneHaptics hapticsUri : %{public}s", asyncContext->hapticsUri.c_str());
491 CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
492 ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
493 napi_create_promise(env, &asyncContext->deferred, &result);
494 napi_create_string_utf8(env, "OpenToneHaptics", NAPI_AUTO_LENGTH, &resource);
495 status = napi_create_async_work(env, nullptr, resource, AsyncOpenToneHaptics,
496 OpenToneHapticsAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
497 if (status != napi_ok) {
498 MEDIA_LOGE("OpenToneHaptics : Failed to get create async work");
499 napi_get_undefined(env, &result);
500 } else {
501 napi_queue_async_work(env, asyncContext->work);
502 asyncContext.release();
503 }
504 return result;
505 }
506
AsyncOpenToneHaptics(napi_env env,void * data)507 void SystemSoundManagerNapi::AsyncOpenToneHaptics(napi_env env, void *data)
508 {
509 SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
510 if (context->objectInfo->sysSoundMgrClient_ == nullptr) {
511 return;
512 }
513 int32_t result = context->objectInfo->sysSoundMgrClient_->OpenToneHaptics(context->abilityContext_,
514 context->hapticsUri);
515 context->fd = result;
516 context->status = context->fd <= 0;
517 if (result == OPERATION_ERROR) {
518 context->errCode = NAPI_ERR_OPERATE_NOT_ALLOWED;
519 context->errMessage = NAPI_ERR_OPERATE_NOT_ALLOWED_INFO;
520 } else if (result == IO_ERROR) {
521 context->errCode = NAPI_ERR_IO_ERROR;
522 context->errMessage = NAPI_ERR_IO_ERROR_INFO;
523 } else if (result == UNSUPPORTED_ERROR) {
524 context->errCode = NAPI_ERR_UNSUPPORTED_OPERATION;
525 context->errMessage = NAPI_ERR_UNSUPPORTED_OPERATION_INFO;
526 }
527 }
528
OpenToneHapticsAsyncCallbackComp(napi_env env,napi_status status,void * data)529 void SystemSoundManagerNapi::OpenToneHapticsAsyncCallbackComp(napi_env env, napi_status status, void *data)
530 {
531 auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
532 napi_value result[2] = {};
533 if (!context->status) {
534 napi_get_undefined(env, &result[PARAM0]);
535 napi_create_int32(env, context->fd, &result[PARAM1]);
536 } else {
537 result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
538 napi_get_undefined(env, &result[PARAM1]);
539 }
540 if (context->deferred) {
541 if (!context->status) {
542 napi_resolve_deferred(env, context->deferred, result[PARAM1]);
543 } else {
544 napi_reject_deferred(env, context->deferred, result[PARAM0]);
545 }
546 }
547 napi_delete_async_work(env, context->work);
548 delete context;
549 context = nullptr;
550 }
551
RemoveCustomizedToneList(napi_env env,napi_callback_info info)552 napi_value SystemSoundManagerNapi::RemoveCustomizedToneList(napi_env env, napi_callback_info info)
553 {
554 MEDIA_LOGI("RemoveCustomizedToneList start");
555 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
556 ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
557 "No system permission");
558 CHECK_AND_RETURN_RET_LOG(VerifyRingtonePermission(), ThrowErrorAndReturn(env,
559 NAPI_ERR_NO_PERMISSION_INFO, NAPI_ERR_NO_PERMISSION), "Permission denied");
560 napi_value result = nullptr;
561 napi_value resource = nullptr;
562 napi_value thisVar = nullptr;
563 size_t argc = ARGS_ONE;
564 napi_value argv[ARGS_ONE] = {};
565
566 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
567 napi_get_undefined(env, &result);
568 CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
569 "RemoveCustomizedToneList: Failed to retrieve details about the callback");
570
571 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
572 NAPI_ERR_INPUT_INVALID), "invalid arguments");
573 std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
574 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
575 CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
576 "RemoveCustomizedToneList: Failed to unwrap object");
577
578 status = GetUriVector(env, asyncContext->uriList, argv[PARAM0]);
579 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "GetUriVector: Failed to get uriList");
580 CHECK_AND_RETURN_RET_LOG(!asyncContext->uriList.empty(), ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
581 NAPI_ERR_INPUT_INVALID), "invalid arguments");
582
583 napi_create_promise(env, &asyncContext->deferred, &result);
584 napi_create_string_utf8(env, "RemoveCustomizedToneList", NAPI_AUTO_LENGTH, &resource);
585
586 status = napi_create_async_work(env, nullptr, resource, AsyncRemoveCustomizedToneList,
587 RemoveCustomizedToneListAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
588 if (status != napi_ok) {
589 MEDIA_LOGE("RemoveCustomizedToneList : Failed to get create async work");
590 napi_get_undefined(env, &result);
591 } else {
592 napi_queue_async_work(env, asyncContext->work);
593 asyncContext.release();
594 }
595 return result;
596 }
597
GetUriVector(const napi_env & env,std::vector<std::string> & uriList,napi_value in)598 napi_status SystemSoundManagerNapi::GetUriVector(const napi_env &env,
599 std::vector<std::string> &uriList, napi_value in)
600 {
601 uint32_t arrayLen = 0;
602 napi_get_array_length(env, in, &arrayLen);
603 for (uint32_t i = 0; i < arrayLen; i++) {
604 napi_value element;
605 if (napi_get_element(env, in, i, &element) == napi_ok) {
606 uriList.push_back(GetStringArgument(env, element));
607 }
608 }
609 return napi_ok;
610 }
611
GetStringArgument(napi_env env,napi_value value)612 std::string SystemSoundManagerNapi::GetStringArgument(napi_env env, napi_value value)
613 {
614 std::string strValue = "";
615 size_t bufLength = 0;
616 napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &bufLength);
617 if (status == napi_ok && bufLength > 0 && bufLength < PATH_MAX) {
618 strValue.reserve(bufLength + 1);
619 strValue.resize(bufLength);
620 status = napi_get_value_string_utf8(env, value, strValue.data(), bufLength + 1, &bufLength);
621 if (status == napi_ok) {
622 MEDIA_LOGE("argument = %{public}s", strValue.c_str());
623 }
624 }
625 return strValue;
626 }
627
AsyncRemoveCustomizedToneList(napi_env env,void * data)628 void SystemSoundManagerNapi::AsyncRemoveCustomizedToneList(napi_env env, void *data)
629 {
630 SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
631 SystemSoundError error = ERROR_INVALID_PARAM;
632 if (context->objectInfo->sysSoundMgrClient_ != nullptr) {
633 context->removeResultArray = context->objectInfo->sysSoundMgrClient_->RemoveCustomizedToneList(
634 context->uriList, error);
635 }
636 if (error == ERROR_INVALID_PARAM) {
637 context->status = ERROR;
638 context->errCode = ERROR_INVALID_PARAM;
639 context->errMessage = NAPI_ERR_URILIST_OVER_LIMIT_INFO;
640 }
641 }
642
RemoveCustomizedToneListAsyncCallbackComp(napi_env env,napi_status status,void * data)643 void SystemSoundManagerNapi::RemoveCustomizedToneListAsyncCallbackComp(napi_env env, napi_status status, void* data)
644 {
645 auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
646 napi_value result[2] = {};
647 if (!context->status) {
648 napi_get_undefined(env, &result[PARAM0]);
649 context->status = napi_create_array_with_length(env, context->removeResultArray.size(), &result[PARAM1]);
650 size_t count = 0;
651 for (auto &removeResult : context->removeResultArray) {
652 napi_value jsTuple;
653 napi_create_array(env, &jsTuple);
654
655 napi_value jsString;
656 napi_create_string_utf8(env, std::get<0>(removeResult).c_str(), NAPI_AUTO_LENGTH, &jsString);
657 napi_set_element(env, jsTuple, 0, jsString);
658
659 napi_value jsError;
660 napi_create_int32(env, static_cast<int>(std::get<1>(removeResult)), &jsError);
661 napi_set_element(env, jsTuple, 1, jsError);
662
663 napi_set_element(env, result[PARAM1], count, jsTuple);
664 count++;
665 }
666 } else {
667 result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
668 napi_get_undefined(env, &result[PARAM1]);
669 }
670 if (context->deferred) {
671 if (!context->status) {
672 napi_resolve_deferred(env, context->deferred, result[PARAM1]);
673 } else {
674 napi_reject_deferred(env, context->deferred, result[PARAM0]);
675 }
676 }
677 napi_delete_async_work(env, context->work);
678 delete context;
679 context = nullptr;
680 }
681
OpenToneList(napi_env env,napi_callback_info info)682 napi_value SystemSoundManagerNapi::OpenToneList(napi_env env, napi_callback_info info)
683 {
684 MEDIA_LOGI("OpenToneList start");
685 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
686 ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
687 "No system permission");
688 napi_value result = nullptr;
689 napi_value resource = nullptr;
690 napi_value thisVar = nullptr;
691 size_t argc = ARGS_ONE;
692 napi_value argv[ARGS_ONE] = {};
693
694 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
695 napi_get_undefined(env, &result);
696 CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
697 "OpenToneList: Failed to retrieve details about the callback");
698 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
699 NAPI_ERR_INPUT_INVALID), "invalid arguments");
700
701 std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
702 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
703 CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
704 "OpenToneList: Failed to unwrap object");
705
706 status = GetUriVector(env, asyncContext->uriList, argv[PARAM0]);
707 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "GetUriVector: Failed to get uriList");
708 CHECK_AND_RETURN_RET_LOG(!asyncContext->uriList.empty(), ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
709 NAPI_ERR_INPUT_INVALID), "invalid arguments");
710
711 napi_create_promise(env, &asyncContext->deferred, &result);
712 napi_create_string_utf8(env, "OpenToneList", NAPI_AUTO_LENGTH, &resource);
713
714 status = napi_create_async_work(env, nullptr, resource, AsyncOpenToneList,
715 AsyncOpenToneListAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
716 if (status != napi_ok) {
717 MEDIA_LOGE("OpenToneList : Failed to get create async work");
718 napi_get_undefined(env, &result);
719 } else {
720 napi_queue_async_work(env, asyncContext->work);
721 asyncContext.release();
722 }
723 return result;
724 }
725
AsyncOpenToneList(napi_env env,void * data)726 void SystemSoundManagerNapi::AsyncOpenToneList(napi_env env, void *data)
727 {
728 SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
729 SystemSoundError error = ERROR_INVALID_PARAM;
730 if (context->objectInfo->sysSoundMgrClient_ != nullptr) {
731 context->openToneResultArray = context->objectInfo->sysSoundMgrClient_->OpenToneList(
732 context->uriList, error);
733 }
734 if (error == ERROR_INVALID_PARAM) {
735 context->status = ERROR;
736 context->errCode = ERROR_INVALID_PARAM;
737 context->errMessage = NAPI_ERR_URILIST_OVER_LIMIT_INFO;
738 }
739 }
740
AsyncOpenToneListAsyncCallbackComp(napi_env env,napi_status status,void * data)741 void SystemSoundManagerNapi::AsyncOpenToneListAsyncCallbackComp(napi_env env, napi_status status, void* data)
742 {
743 auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
744 napi_value result[2] = {};
745
746 if (!context->status) {
747 napi_get_undefined(env, &result[PARAM0]);
748 context->status = napi_create_array_with_length(env, context->openToneResultArray.size(), &result[PARAM1]);
749 size_t count = 0;
750
751 for (auto &openToneResult : context->openToneResultArray) {
752 napi_value jsTuple;
753 napi_create_array(env, &jsTuple);
754 napi_value jsString;
755 napi_create_string_utf8(env, std::get<PARAM0>(openToneResult).c_str(), NAPI_AUTO_LENGTH, &jsString);
756 napi_set_element(env, jsTuple, PARAM0, jsString);
757
758 napi_value jsNumber;
759 napi_create_int64(env, std::get<PARAM1>(openToneResult), &jsNumber);
760 napi_set_element(env, jsTuple, PARAM1, jsNumber);
761
762 napi_value jsError;
763 napi_create_int32(env, static_cast<int>(std::get<PARAM2>(openToneResult)), &jsError);
764 napi_set_element(env, jsTuple, PARAM2, jsError);
765
766 napi_set_element(env, result[PARAM1], count, jsTuple);
767 count++;
768 }
769 } else {
770 result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
771 napi_get_undefined(env, &result[PARAM1]);
772 }
773
774 if (context->deferred) {
775 if (!context->status) {
776 napi_resolve_deferred(env, context->deferred, result[PARAM1]);
777 } else {
778 napi_reject_deferred(env, context->deferred, result[PARAM0]);
779 }
780 }
781 napi_delete_async_work(env, context->work);
782 delete context;
783 context = nullptr;
784 }
785
GetCurrentRingtoneAttribute(napi_env env,napi_callback_info info)786 napi_value SystemSoundManagerNapi::GetCurrentRingtoneAttribute(napi_env env, napi_callback_info info)
787 {
788 MEDIA_LOGI("GetCurrentRingtoneAttribute start");
789 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
790 ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
791 "No system permission");
792 napi_value result = nullptr;
793 napi_value resource = nullptr;
794 napi_value thisVar = nullptr;
795 size_t argc = ARGS_ONE;
796 napi_value argv[ARGS_ONE] = {0};
797 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
798 napi_get_undefined(env, &result);
799
800 CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
801 "GetCurrentRingtoneAttribute: Failed to retrieve details about the callback");
802 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
803 NAPI_ERR_INPUT_INVALID), "invalid arguments");
804
805 std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
806 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
807 CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
808 "GetCurrentRingtoneAttribute: Failed to unwrap object");
809
810 napi_get_value_int32(env, argv[PARAM0], &asyncContext->ringtoneType);
811 MEDIA_LOGI("GetCurrentRingtoneAttribute ringtoneType is: %{public}d", asyncContext->ringtoneType);
812 CHECK_AND_RETURN_RET_LOG(asyncContext->ringtoneType == RINGTONE_TYPE_SIM_CARD_0 || asyncContext->ringtoneType
813 == RINGTONE_TYPE_SIM_CARD_1,
814 ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "Parameter error");
815
816 napi_create_promise(env, &asyncContext->deferred, &result);
817 napi_create_string_utf8(env, "GetCurrentRingtoneAttribute", NAPI_AUTO_LENGTH, &resource);
818 status = napi_create_async_work(env, nullptr, resource, AsyncGetCurrentRingtoneAttribute,
819 GetDefaultAttrsAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
820 if (status != napi_ok) {
821 napi_get_undefined(env, &result);
822 } else {
823 napi_queue_async_work(env, asyncContext->work);
824 asyncContext.release();
825 }
826 return result;
827 }
828
AsyncGetCurrentRingtoneAttribute(napi_env env,void * data)829 void SystemSoundManagerNapi::AsyncGetCurrentRingtoneAttribute(napi_env env, void *data)
830 {
831 SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
832 if (context->objectInfo->sysSoundMgrClient_ != nullptr) {
833 context->toneAttrs = std::make_shared<ToneAttrs>(context->objectInfo->sysSoundMgrClient_->
834 GetCurrentRingtoneAttribute(static_cast<RingtoneType>(context->ringtoneType)));
835 }
836 if (context->toneAttrs == nullptr) {
837 context->status = ERROR;
838 context->errCode = NAPI_ERR_IO_ERROR;
839 context->errMessage = "I/O error. Can not get default ring tone.";
840 }
841 }
842 } // namespace Media
843 } // namespace OHOS
844