• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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