• 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_TWO = 2;
36 const int32_t ARGS_THREE = 3;
37 const int32_t SIZE = 1024;
38 
39 const int UNSUPPORTED_ERROR = -5;
40 const int OPERATION_ERROR = -4;
41 const int IO_ERROR = -3;
42 
43 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO_NAPI, "SystemSoundManagerNapi"};
44 }
45 
46 namespace OHOS {
47 namespace Media {
GetToneHapticsSettings(napi_env env,napi_callback_info info)48 napi_value SystemSoundManagerNapi::GetToneHapticsSettings(napi_env env, napi_callback_info info)
49 {
50     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(), ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO,
51         NAPI_ERR_PERMISSION_DENIED), "No system permission");
52     napi_value result = nullptr;
53     napi_value resource = nullptr;
54     napi_value thisVar = nullptr;
55     size_t argc = ARGS_TWO;
56     napi_value argv[ARGS_TWO] = {};
57 
58     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
59     napi_get_undefined(env, &result);
60     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
61         "GetToneHapticsSettings: Failed to retrieve details about the callback");
62     CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
63         NAPI_ERR_INPUT_INVALID), "invalid arguments");
64     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
65     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
66     CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
67         "GetToneHapticsSettings: Failed to unwrap object");
68 
69     for (size_t i = PARAM0; i < argc; i++) {
70         napi_valuetype valueType = napi_undefined;
71         napi_typeof(env, argv[i], &valueType);
72         if (i == PARAM0) {
73             asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
74         } else if (i == PARAM1 && valueType == napi_number) {
75             napi_get_value_int32(env, argv[PARAM1], &asyncContext->toneHapticsType);
76             asyncContext->toneHapticsType = asyncContext->toneHapticsType;
77         }
78     }
79     MEDIA_LOGI("GetToneHapticsSettings toneHapticsType : %{public}d", asyncContext->toneHapticsType);
80     CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
81         ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
82     napi_create_promise(env, &asyncContext->deferred, &result);
83     napi_create_string_utf8(env, "GetToneHapticsSettings", NAPI_AUTO_LENGTH, &resource);
84     status = napi_create_async_work(env, nullptr, resource, AsyncGetToneHapticsSettings,
85         GetToneHapticsSettingsAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
86     if (status != napi_ok) {
87         MEDIA_LOGE("GetToneHapticsSettings: Failed to get create async work");
88         napi_get_undefined(env, &result);
89     } else {
90         napi_queue_async_work(env, asyncContext->work);
91         asyncContext.release();
92     }
93     return result;
94 }
95 
AsyncGetToneHapticsSettings(napi_env env,void * data)96 void SystemSoundManagerNapi::AsyncGetToneHapticsSettings(napi_env env, void *data)
97 {
98     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
99     if (context->objectInfo->sysSoundMgrClient_ == nullptr) {
100         return;
101     }
102     int32_t result = context->objectInfo->sysSoundMgrClient_->GetToneHapticsSettings(context->abilityContext_,
103         static_cast<ToneHapticsType>(context->toneHapticsType), context->toneHapticsSettings);
104     context->status = result;
105     if (result == IO_ERROR) {
106         context->errCode = NAPI_ERR_IO_ERROR;
107         context->errMessage = NAPI_ERR_IO_ERROR_INFO;
108     } else if (result == UNSUPPORTED_ERROR) {
109         context->errCode = NAPI_ERR_UNSUPPORTED_OPERATION;
110         context->errMessage = NAPI_ERR_UNSUPPORTED_OPERATION_INFO;
111     }
112 }
113 
GetToneHapticsSettingsAsyncCallbackComp(napi_env env,napi_status status,void * data)114 void SystemSoundManagerNapi::GetToneHapticsSettingsAsyncCallbackComp(napi_env env, napi_status status,
115     void *data)
116 {
117     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
118     napi_value result[2] = {};
119 
120     if (!context->status) {
121         napi_get_undefined(env, &result[PARAM0]);
122         context->status = ToneHapticsSettingsNapi::NewInstance(env, context->toneHapticsSettings, result[PARAM1]);
123     } else {
124         result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
125         napi_get_undefined(env, &result[PARAM1]);
126     }
127 
128     if (context->deferred) {
129         if (!context->status) {
130             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
131         } else {
132             napi_reject_deferred(env, context->deferred, result[PARAM0]);
133         }
134     }
135 
136     napi_delete_async_work(env, context->work);
137     delete context;
138     context = nullptr;
139 }
140 
ExtractStringToEnv(const napi_env & env,const napi_value & argv)141 std::string SystemSoundManagerNapi::ExtractStringToEnv(const napi_env &env, const napi_value &argv)
142 {
143     char buffer[SIZE] = {0};
144     size_t res = 0;
145     napi_get_value_string_utf8(env, argv, buffer, SIZE, &res);
146     return std::string(buffer);
147 }
148 
GetToneHapticsSettingsToEnv(const napi_env & env,const napi_value & argv,ToneHapticsSettings & toneHapticsSettings)149 void SystemSoundManagerNapi::GetToneHapticsSettingsToEnv(const napi_env &env, const napi_value &argv,
150     ToneHapticsSettings &toneHapticsSettings)
151 {
152     napi_value property = nullptr;
153     char buffer[SIZE] = {0};
154     size_t res = 0;
155     int32_t mode = 0;
156 
157     if (napi_get_named_property(env, argv, "mode", &property) == napi_ok) {
158         napi_get_value_int32(env, property, &mode);
159         toneHapticsSettings.mode = static_cast<ToneHapticsMode>(mode);
160     }
161     if (napi_get_named_property(env, argv, "hapticsUri", &property) == napi_ok) {
162         napi_get_value_string_utf8(env, property, buffer, SIZE, &res);
163         toneHapticsSettings.hapticsUri = std::string(buffer);
164     }
165 }
166 
SetToneHapticsSettings(napi_env env,napi_callback_info info)167 napi_value SystemSoundManagerNapi::SetToneHapticsSettings(napi_env env, napi_callback_info info)
168 {
169     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(), ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO,
170         NAPI_ERR_PERMISSION_DENIED), "No system permission");
171     napi_value result = nullptr;
172     napi_value resource = nullptr;
173     napi_value thisVar = nullptr;
174     size_t argc = ARGS_THREE;
175     napi_value argv[ARGS_THREE] = {0};
176     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
177     napi_get_undefined(env, &result);
178     CHECK_AND_RETURN_RET_LOG(status == napi_ok && thisVar != nullptr, result,
179         "SetToneHapticsSettings: get_cb_info failed");
180     CHECK_AND_RETURN_RET_LOG(argc == ARGS_THREE, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
181         NAPI_ERR_INPUT_INVALID), "invalid arguments");
182     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
183     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
184     CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
185         "SetToneHapticsSettings: Failed to unwrap object");
186     for (size_t i = PARAM0; i < argc; i++) {
187         napi_valuetype valueType = napi_undefined;
188         napi_typeof(env, argv[i], &valueType);
189         if (i == PARAM0) {
190             asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
191         } else if (i == PARAM1 && valueType == napi_number) {
192             napi_get_value_int32(env, argv[i], &asyncContext->toneHapticsType);
193             asyncContext->toneHapticsType = asyncContext->toneHapticsType;
194         } else if (i == PARAM2 && valueType == napi_object) {
195             GetToneHapticsSettingsToEnv(env, argv[PARAM2], asyncContext->toneHapticsSettings);
196         }
197     }
198     MEDIA_LOGI("SetToneHapticsSettings toneHapticsType : %{public}d mode : %{public}d", asyncContext->toneHapticsType,
199         asyncContext->toneHapticsSettings.mode);
200     CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
201         ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
202     napi_create_promise(env, &asyncContext->deferred, &result);
203     napi_create_string_utf8(env, "SetToneHapticsSettings", NAPI_AUTO_LENGTH, &resource);
204     status = napi_create_async_work(env, nullptr, resource, AsyncSetToneHapticsSettings,
205         SetToneHapticsSettingsAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
206     if (status != napi_ok) {
207         MEDIA_LOGE("SetToneHapticsSettings: Failed to get create async work");
208         napi_get_undefined(env, &result);
209     } else {
210         napi_queue_async_work(env, asyncContext->work);
211         asyncContext.release();
212     }
213     return result;
214 }
215 
AsyncSetToneHapticsSettings(napi_env env,void * data)216 void SystemSoundManagerNapi::AsyncSetToneHapticsSettings(napi_env env, void *data)
217 {
218     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
219     if (context->objectInfo->sysSoundMgrClient_ == nullptr) {
220         return;
221     }
222     int32_t result = context->objectInfo->sysSoundMgrClient_->SetToneHapticsSettings(context->abilityContext_,
223         static_cast<ToneHapticsType>(context->toneHapticsType), context->toneHapticsSettings);
224     context->status = result;
225     if (result == OPERATION_ERROR) {
226         context->errCode = NAPI_ERR_OPERATE_NOT_ALLOWED;
227         context->errMessage = NAPI_ERR_OPERATE_NOT_ALLOWED_INFO;
228     } else if (result == IO_ERROR) {
229         context->errCode = NAPI_ERR_IO_ERROR;
230         context->errMessage = NAPI_ERR_IO_ERROR_INFO;
231     } else if (result == UNSUPPORTED_ERROR) {
232         context->errCode = NAPI_ERR_UNSUPPORTED_OPERATION;
233         context->errMessage = NAPI_ERR_UNSUPPORTED_OPERATION_INFO;
234     }
235 }
236 
SetToneHapticsSettingsAsyncCallbackComp(napi_env env,napi_status status,void * data)237 void SystemSoundManagerNapi::SetToneHapticsSettingsAsyncCallbackComp(napi_env env, napi_status status, void *data)
238 {
239     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
240     napi_value result[2] = {};
241 
242     if (!context->status) {
243         napi_get_undefined(env, &result[PARAM0]);
244         napi_get_undefined(env, &result[PARAM1]);
245     } else {
246         result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
247         napi_get_undefined(env, &result[PARAM1]);
248     }
249 
250     if (context->deferred) {
251         if (!context->status) {
252             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
253         } else {
254             napi_reject_deferred(env, context->deferred, result[PARAM0]);
255         }
256     }
257 
258     napi_delete_async_work(env, context->work);
259     delete context;
260     context = nullptr;
261 }
262 
GetToneHapticsList(napi_env env,napi_callback_info info)263 napi_value SystemSoundManagerNapi::GetToneHapticsList(napi_env env, napi_callback_info info)
264 {
265     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(), ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO,
266         NAPI_ERR_PERMISSION_DENIED), "No system permission");
267     napi_value result = nullptr;
268     napi_value resource = nullptr;
269     napi_value thisVar = nullptr;
270     size_t argc = ARGS_TWO;
271     napi_value argv[ARGS_TWO] = {0};
272 
273     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
274     napi_get_undefined(env, &result);
275     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
276         "GetToneHapticsList: Failed to retrieve details about the callback");
277     CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
278         NAPI_ERR_INPUT_INVALID), "invalid arguments");
279     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
280     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
281     CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
282         "GetToneHapticsList: Failed to unwrap object");
283     for (size_t i = PARAM0; i < argc; i ++) {
284         napi_valuetype valueType = napi_undefined;
285         napi_typeof(env, argv[i], &valueType);
286         if (i == PARAM0) {
287             asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
288         } else if (i == PARAM1 && valueType == napi_boolean) {
289             napi_get_value_bool(env, argv[i], &asyncContext->isSynced);
290         }
291     }
292     MEDIA_LOGI("GetToneHapticsList isSynced : %{public}s", asyncContext->isSynced ? "true" : "false");
293     CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
294         ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "Parameter error");
295     napi_create_promise(env, &asyncContext->deferred, &result);
296     napi_create_string_utf8(env, "GetToneHapticsList", NAPI_AUTO_LENGTH, &resource);
297     status = napi_create_async_work(env, nullptr, resource, AsyncGetToneHapticsList,
298         GetToneHapticsListAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
299     if (status != napi_ok) {
300         MEDIA_LOGE("Failed to get create async work");
301         napi_get_undefined(env, &result);
302     } else {
303         napi_queue_async_work(env, asyncContext->work);
304         asyncContext.release();
305     }
306     return result;
307 }
308 
AsyncGetToneHapticsList(napi_env env,void * data)309 void SystemSoundManagerNapi::AsyncGetToneHapticsList(napi_env env, void *data)
310 {
311     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
312     if (context->objectInfo->sysSoundMgrClient_ == nullptr) {
313         return;
314     }
315     int32_t result = context->objectInfo->sysSoundMgrClient_->GetToneHapticsList(context->abilityContext_,
316         context->isSynced, context->toneHapticsAttrsArray);
317     context->status = result;
318     if (result == IO_ERROR) {
319         context->errCode = NAPI_ERR_IO_ERROR;
320         context->errMessage = NAPI_ERR_IO_ERROR_INFO;
321     } else if (result == UNSUPPORTED_ERROR) {
322         context->errCode = NAPI_ERR_UNSUPPORTED_OPERATION;
323         context->errMessage = NAPI_ERR_UNSUPPORTED_OPERATION_INFO;
324     }
325 }
326 
GetToneHapticsListAsyncCallbackComp(napi_env env,napi_status status,void * data)327 void SystemSoundManagerNapi::GetToneHapticsListAsyncCallbackComp(napi_env env, napi_status status, void *data)
328 {
329     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
330     napi_value result[2] = {};
331     if (!context->status) {
332         napi_get_undefined(env, &result[PARAM0]);
333         context->status = napi_create_array_with_length(env, context->toneHapticsAttrsArray.size(), &result[PARAM1]);
334         size_t count = 0;
335         for (auto &toneHapticsAttrs : context->toneHapticsAttrsArray) {
336             napi_value jsToneHapticsAttrs = nullptr;
337             ToneHapticsAttrsNapi::NewInstance(env, toneHapticsAttrs, jsToneHapticsAttrs);
338             context->status = napi_set_element(env, result[PARAM1], count, jsToneHapticsAttrs);
339             count++;
340         }
341     } else {
342         result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
343         napi_get_undefined(env, &result[PARAM1]);
344     }
345     if (context->deferred) {
346         if (!context->status) {
347             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
348         } else {
349             napi_reject_deferred(env, context->deferred, result[PARAM0]);
350         }
351     }
352 
353     napi_delete_async_work(env, context->work);
354     delete context;
355     context = nullptr;
356 }
357 
GetHapticsAttrsSyncedWithTone(napi_env env,napi_callback_info info)358 napi_value SystemSoundManagerNapi::GetHapticsAttrsSyncedWithTone(napi_env env, napi_callback_info info)
359 {
360     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(), ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO,
361         NAPI_ERR_PERMISSION_DENIED), "No system permission");
362     napi_value result = nullptr;
363     napi_value resource = nullptr;
364     napi_value thisVar = nullptr;
365     size_t argc = ARGS_TWO;
366     napi_value argv[ARGS_TWO] = {};
367     char buffer[SIZE];
368     size_t res = 0;
369     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
370     napi_get_undefined(env, &result);
371     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
372         "GetHapticsAttrsSyncedWithTone: Failed to retrieve details about the callback");
373     CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
374         NAPI_ERR_INPUT_INVALID), "invalid arguments");
375     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
376     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
377     CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
378         "GetHapticsAttrsSyncedWithTone: Failed to unwrap object");
379     for (size_t i = PARAM0; i < argc; i++) {
380         napi_valuetype valueType = napi_undefined;
381         napi_typeof(env, argv[i], &valueType);
382         if (i == PARAM0) {
383             asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
384         } else if (i == PARAM1 && valueType == napi_string) {
385             napi_get_value_string_utf8(env, argv[i], buffer, SIZE, &res);
386             asyncContext->toneUri = std::string(buffer);
387         }
388     }
389     MEDIA_LOGI("GetHapticsAttrsSyncedWithTone toneUri : %{public}s", asyncContext->toneUri.c_str());
390     CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
391         ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
392     napi_create_promise(env, &asyncContext->deferred, &result);
393     napi_create_string_utf8(env, "GetHapticsAttrsSyncedWithTone", NAPI_AUTO_LENGTH, &resource);
394     status = napi_create_async_work(env, nullptr, resource, AsyncGetHapticsAttrsSyncedWithTone,
395         GetHapticsAttrsSyncedWithToneAsyncCallbackComp, static_cast<void*>(asyncContext.get()),
396         &asyncContext->work);
397     if (status != napi_ok) {
398         MEDIA_LOGE("GetHapticsAttrsSyncedWithTone : Failed to get create async work");
399         napi_get_undefined(env, &result);
400     } else {
401         napi_queue_async_work(env, asyncContext->work);
402         asyncContext.release();
403     }
404     return result;
405 }
406 
AsyncGetHapticsAttrsSyncedWithTone(napi_env env,void * data)407 void SystemSoundManagerNapi::AsyncGetHapticsAttrsSyncedWithTone(napi_env env, void *data)
408 {
409     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
410     if (context->objectInfo->sysSoundMgrClient_ == nullptr) {
411         return;
412     }
413     int32_t result = context->objectInfo->sysSoundMgrClient_->GetHapticsAttrsSyncedWithTone(context->abilityContext_,
414         context->toneUri, context->toneHapticsAttrs);
415     context->status = result;
416     if (result == OPERATION_ERROR) {
417         context->errCode = NAPI_ERR_OPERATE_NOT_ALLOWED;
418         context->errMessage = NAPI_ERR_OPERATE_NOT_ALLOWED_INFO;
419     } else if (result == IO_ERROR) {
420         context->errCode = NAPI_ERR_IO_ERROR;
421         context->errMessage = NAPI_ERR_IO_ERROR_INFO;
422     } else if (result == UNSUPPORTED_ERROR) {
423         context->errCode = NAPI_ERR_UNSUPPORTED_OPERATION;
424         context->errMessage = NAPI_ERR_UNSUPPORTED_OPERATION_INFO;
425     }
426 }
427 
GetHapticsAttrsSyncedWithToneAsyncCallbackComp(napi_env env,napi_status status,void * data)428 void SystemSoundManagerNapi::GetHapticsAttrsSyncedWithToneAsyncCallbackComp(napi_env env, napi_status status,
429     void *data)
430 {
431     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
432     napi_value result[2] = {};
433 
434     if (!context->status) {
435         napi_get_undefined(env, &result[PARAM0]);
436         ToneHapticsAttrsNapi::NewInstance(env, context->toneHapticsAttrs, result[PARAM1]);
437     } else {
438         result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
439         napi_get_undefined(env, &result[PARAM1]);
440     }
441 
442     if (context->deferred) {
443         if (!context->status) {
444             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
445         } else {
446             napi_reject_deferred(env, context->deferred, result[PARAM0]);
447         }
448     }
449 
450     napi_delete_async_work(env, context->work);
451     delete context;
452     context = nullptr;
453 }
454 
455 
OpenToneHaptics(napi_env env,napi_callback_info info)456 napi_value SystemSoundManagerNapi::OpenToneHaptics(napi_env env, napi_callback_info info)
457 {
458     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
459         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
460         "No system permission");
461     napi_value result = nullptr;
462     napi_value resource = nullptr;
463     napi_value thisVar = nullptr;
464     size_t argc = ARGS_TWO;
465     napi_value argv[ARGS_TWO] = {};
466     char buffer[SIZE];
467     size_t res = 0;
468     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
469     napi_get_undefined(env, &result);
470     CHECK_AND_RETURN_RET_LOG((status == napi_ok && thisVar != nullptr), result,
471         "OpenToneHaptics: Failed to retrieve details about the callback");
472     CHECK_AND_RETURN_RET_LOG(argc == ARGS_TWO, ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO,
473         NAPI_ERR_INPUT_INVALID), "invalid arguments");
474     std::unique_ptr<SystemSoundManagerAsyncContext> asyncContext = std::make_unique<SystemSoundManagerAsyncContext>();
475     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
476     CHECK_AND_RETURN_RET_LOG(status == napi_ok && asyncContext->objectInfo != nullptr, result,
477         "OpenToneHaptics: Failed to unwrap object");
478     for (size_t i = PARAM0; i < argc; i++) {
479         napi_valuetype valueType = napi_undefined;
480         napi_typeof(env, argv[i], &valueType);
481         if (i == PARAM0) {
482             asyncContext->abilityContext_ = GetAbilityContext(env, argv[i]);
483         } else if (i == PARAM1 && valueType == napi_string) {
484             napi_get_value_string_utf8(env, argv[i], buffer, SIZE, &res);
485             asyncContext->hapticsUri = std::string(buffer);
486         }
487     }
488     MEDIA_LOGI("OpenToneHaptics hapticsUri : %{public}s", asyncContext->hapticsUri.c_str());
489     CHECK_AND_RETURN_RET_LOG(asyncContext->abilityContext_ != nullptr,
490         ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID), "invalid arguments");
491     napi_create_promise(env, &asyncContext->deferred, &result);
492     napi_create_string_utf8(env, "OpenToneHaptics", NAPI_AUTO_LENGTH, &resource);
493     status = napi_create_async_work(env, nullptr, resource, AsyncOpenToneHaptics,
494         OpenToneHapticsAsyncCallbackComp, static_cast<void*>(asyncContext.get()), &asyncContext->work);
495     if (status != napi_ok) {
496         MEDIA_LOGE("OpenToneHaptics : Failed to get create async work");
497         napi_get_undefined(env, &result);
498     } else {
499         napi_queue_async_work(env, asyncContext->work);
500         asyncContext.release();
501     }
502     return result;
503 }
504 
AsyncOpenToneHaptics(napi_env env,void * data)505 void SystemSoundManagerNapi::AsyncOpenToneHaptics(napi_env env, void *data)
506 {
507     SystemSoundManagerAsyncContext *context = static_cast<SystemSoundManagerAsyncContext *>(data);
508     if (context->objectInfo->sysSoundMgrClient_ == nullptr) {
509         return;
510     }
511     int32_t result = context->objectInfo->sysSoundMgrClient_->OpenToneHaptics(context->abilityContext_,
512         context->hapticsUri);
513     context->fd = result;
514     context->status = context->fd <= 0;
515     if (result == OPERATION_ERROR) {
516         context->errCode = NAPI_ERR_OPERATE_NOT_ALLOWED;
517         context->errMessage = NAPI_ERR_OPERATE_NOT_ALLOWED_INFO;
518     } else if (result == IO_ERROR) {
519         context->errCode = NAPI_ERR_IO_ERROR;
520         context->errMessage = NAPI_ERR_IO_ERROR_INFO;
521     } else if (result == UNSUPPORTED_ERROR) {
522         context->errCode = NAPI_ERR_UNSUPPORTED_OPERATION;
523         context->errMessage = NAPI_ERR_UNSUPPORTED_OPERATION_INFO;
524     }
525 }
526 
OpenToneHapticsAsyncCallbackComp(napi_env env,napi_status status,void * data)527 void SystemSoundManagerNapi::OpenToneHapticsAsyncCallbackComp(napi_env env, napi_status status, void *data)
528 {
529     auto context = static_cast<SystemSoundManagerAsyncContext *>(data);
530     napi_value result[2] = {};
531     if (!context->status) {
532         napi_get_undefined(env, &result[PARAM0]);
533         napi_create_int32(env, context->fd, &result[PARAM1]);
534     } else {
535         result[PARAM0] = AsyncThrowErrorAndReturn(env, context->errMessage, context->errCode);
536         napi_get_undefined(env, &result[PARAM1]);
537     }
538     if (context->deferred) {
539         if (!context->status) {
540             napi_resolve_deferred(env, context->deferred, result[PARAM1]);
541         } else {
542             napi_reject_deferred(env, context->deferred, result[PARAM0]);
543         }
544     }
545     napi_delete_async_work(env, context->work);
546     delete context;
547     context = nullptr;
548 }
549 } // namespace Media
550 } // namespace OHOS
551