• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "input/camera_input_napi.h"
17 
18 #include <cstdint>
19 #include <memory>
20 #include <uv.h>
21 
22 #include "camera_device.h"
23 #include "camera_error_code.h"
24 #include "camera_log.h"
25 #include "camera_napi_const.h"
26 #include "camera_napi_param_parser.h"
27 #include "camera_napi_security_utils.h"
28 #include "camera_napi_utils.h"
29 #include "camera_napi_worker_queue_keeper.h"
30 #include "input/camera_napi.h"
31 #include "js_native_api.h"
32 #include "napi/native_common.h"
33 #include "napi/native_node_api.h"
34 
35 namespace OHOS {
36 namespace CameraStandard {
37 namespace {
AsyncCompleteCallback(napi_env env,napi_status status,void * data)38 void AsyncCompleteCallback(napi_env env, napi_status status, void* data)
39 {
40     auto context = static_cast<CameraInputAsyncContext*>(data);
41     CHECK_ERROR_RETURN_LOG(context == nullptr, "CameraInputNapi AsyncCompleteCallback context is null");
42     MEDIA_INFO_LOG("CameraInputNapi AsyncCompleteCallback %{public}s, status = %{public}d", context->funcName.c_str(),
43         context->status);
44     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
45     jsContext->status = context->status;
46     if (!context->status) {
47         CameraNapiUtils::CreateNapiErrorObject(env, context->errorCode, context->errorMsg.c_str(), jsContext);
48     } else {
49         if (context->isEnableSecCam) {
50             napi_create_bigint_uint64(env, context->secureCameraSeqId, &jsContext->data);
51         } else {
52             napi_get_undefined(env, &jsContext->data);
53         }
54     }
55     if (!context->funcName.empty() && context->taskId > 0) {
56         // Finish async trace
57         CAMERA_FINISH_ASYNC_TRACE(context->funcName, context->taskId);
58         jsContext->funcName = context->funcName.c_str();
59     }
60     CHECK_EXECUTE(context->work != nullptr,
61         CameraNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef, context->work, *jsContext));
62     context->FreeHeldNapiValue(env);
63     delete context;
64 }
65 } // namespace
66 
67 using namespace std;
68 thread_local napi_ref CameraInputNapi::sConstructor_ = nullptr;
69 thread_local sptr<CameraInput> CameraInputNapi::sCameraInput_ = nullptr;
70 thread_local uint32_t CameraInputNapi::cameraInputTaskId = CAMERA_INPUT_TASKID;
71 
OnErrorCallbackAsync(const int32_t errorType,const int32_t errorMsg) const72 void ErrorCallbackListener::OnErrorCallbackAsync(const int32_t errorType, const int32_t errorMsg) const
73 {
74     MEDIA_DEBUG_LOG("OnErrorCallbackAsync is called");
75     std::unique_ptr<ErrorCallbackInfo> callbackInfo =
76         std::make_unique<ErrorCallbackInfo>(errorType, errorMsg, shared_from_this());
77     ErrorCallbackInfo *event = callbackInfo.get();
78     auto task = [event]() {
79         ErrorCallbackInfo* callbackInfo = reinterpret_cast<ErrorCallbackInfo *>(event);
80         if (callbackInfo) {
81             auto listener = callbackInfo->listener_.lock();
82             CHECK_EXECUTE(listener, listener->OnErrorCallback(callbackInfo->errorType_, callbackInfo->errorMsg_));
83             delete callbackInfo;
84         }
85     };
86     if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
87         MEDIA_ERR_LOG("failed to execute work");
88     } else {
89         callbackInfo.release();
90     }
91 }
92 
OnErrorCallback(const int32_t errorType,const int32_t errorMsg) const93 void ErrorCallbackListener::OnErrorCallback(const int32_t errorType, const int32_t errorMsg) const
94 {
95     MEDIA_DEBUG_LOG("OnErrorCallback is called");
96     napi_value result;
97     napi_value retVal;
98     napi_value propValue;
99 
100     napi_create_int32(env_, errorType, &propValue);
101     napi_create_object(env_, &result);
102     napi_set_named_property(env_, result, "code", propValue);
103     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_ONE, .argv = &result, .result = &retVal };
104     ExecuteCallback("error", callbackNapiPara);
105 }
106 
OnError(const int32_t errorType,const int32_t errorMsg) const107 void ErrorCallbackListener::OnError(const int32_t errorType, const int32_t errorMsg) const
108 {
109     MEDIA_DEBUG_LOG("OnError is called!, errorType: %{public}d", errorType);
110     OnErrorCallbackAsync(errorType, errorMsg);
111 }
112 
OnCameraOcclusionDetectedCallback(const uint8_t isCameraOcclusion,const uint8_t isCameraLensDirty) const113 void OcclusionDetectCallbackListener::OnCameraOcclusionDetectedCallback(const uint8_t isCameraOcclusion,
114     const uint8_t isCameraLensDirty) const
115 {
116     MEDIA_DEBUG_LOG("OnCameraOcclusionDetectedCallback is called");
117     napi_value result[ARGS_TWO];
118     napi_value retVal;
119     napi_value propValue;
120 
121     napi_get_undefined(env_, &result[PARAM0]);
122     napi_create_object(env_, &result[PARAM1]);
123     napi_get_boolean(env_, isCameraOcclusion == 1 ? true : false, &propValue);
124     napi_set_named_property(env_, result[PARAM1], "isCameraOccluded", propValue);
125 
126     napi_value propValueForLensDirty = nullptr;
127     napi_get_boolean(env_, isCameraLensDirty == 1 ? true : false, &propValueForLensDirty);
128     napi_set_named_property(env_, result[PARAM1], "isCameraLensDirty", propValueForLensDirty);
129 
130     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
131     ExecuteCallback("cameraOcclusionDetect", callbackNapiPara);
132 }
133 
OnCameraOcclusionDetectedCallbackAsync(const uint8_t isCameraOcclusion,const uint8_t isCameraLensDirty) const134 void OcclusionDetectCallbackListener::OnCameraOcclusionDetectedCallbackAsync(
135     const uint8_t isCameraOcclusion, const uint8_t isCameraLensDirty) const
136 {
137     MEDIA_DEBUG_LOG("OnCameraOcclusionDetectedCallbackAsync is called");
138     std::unique_ptr<CameraOcclusionDetectResult> callbackInfo =
139         std::make_unique<CameraOcclusionDetectResult>(isCameraOcclusion, isCameraLensDirty, shared_from_this());
140     CameraOcclusionDetectResult *event = callbackInfo.get();
141     auto task = [event]() {
142         CameraOcclusionDetectResult* callbackInfo = reinterpret_cast<CameraOcclusionDetectResult *>(event);
143         if (callbackInfo) {
144             auto listener = callbackInfo->listener_.lock();
145             CHECK_EXECUTE(listener, listener->OnCameraOcclusionDetectedCallback(callbackInfo->isCameraOccluded_,
146                 callbackInfo->isCameraLensDirty_));
147             delete callbackInfo;
148         }
149     };
150     if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
151         MEDIA_ERR_LOG("failed to execute work");
152     } else {
153         callbackInfo.release();
154     }
155 }
156 
OnCameraOcclusionDetected(const uint8_t isCameraOcclusion,const uint8_t isCameraLensDirty) const157 void OcclusionDetectCallbackListener::OnCameraOcclusionDetected(const uint8_t isCameraOcclusion,
158     const uint8_t isCameraLensDirty) const
159 {
160     MEDIA_DEBUG_LOG("OnCameraOcclusionDetected is called!, "
161                     "isCameraOcclusion: %{public}u, isCameraLensDirty: %{public}u",
162                     isCameraOcclusion, isCameraLensDirty);
163     OnCameraOcclusionDetectedCallbackAsync(isCameraOcclusion, isCameraLensDirty);
164 }
165 
CameraInputNapi()166 CameraInputNapi::CameraInputNapi() : env_(nullptr)
167 {
168 }
169 
~CameraInputNapi()170 CameraInputNapi::~CameraInputNapi()
171 {
172     MEDIA_INFO_LOG("~CameraInputNapi is called");
173 }
174 
CameraInputNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)175 void CameraInputNapi::CameraInputNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
176 {
177     MEDIA_INFO_LOG("CameraInputNapiDestructor is called");
178     CameraInputNapi* cameraObj = reinterpret_cast<CameraInputNapi*>(nativeObject);
179     if (cameraObj != nullptr) {
180         delete cameraObj;
181     }
182 }
183 
Init(napi_env env,napi_value exports)184 napi_value CameraInputNapi::Init(napi_env env, napi_value exports)
185 {
186     MEDIA_DEBUG_LOG("Init is called");
187     napi_status status;
188     napi_value ctorObj;
189     int32_t refCount = 1;
190 
191     // todo: Open and Close in native have not implemented
192     napi_property_descriptor camera_input_props[] = {
193         DECLARE_NAPI_FUNCTION("open", Open),
194         DECLARE_NAPI_FUNCTION("close", Close),
195         DECLARE_NAPI_FUNCTION("closeDelayed", closeDelayed),
196         DECLARE_NAPI_FUNCTION("release", Release),
197         DECLARE_NAPI_FUNCTION("on", On),
198         DECLARE_NAPI_FUNCTION("once", Once),
199         DECLARE_NAPI_FUNCTION("off", Off),
200         DECLARE_NAPI_FUNCTION("usedAsPosition", UsedAsPosition),
201         DECLARE_NAPI_FUNCTION("controlAuxiliary", ControlAuxiliary)
202     };
203 
204     status = napi_define_class(env, CAMERA_INPUT_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
205                                CameraInputNapiConstructor, nullptr,
206                                sizeof(camera_input_props) / sizeof(camera_input_props[PARAM0]),
207                                camera_input_props, &ctorObj);
208     if (status == napi_ok) {
209         status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
210         if (status == napi_ok) {
211             status = napi_set_named_property(env, exports, CAMERA_INPUT_NAPI_CLASS_NAME, ctorObj);
212             CHECK_ERROR_RETURN_RET(status == napi_ok, exports);
213         }
214     }
215     MEDIA_ERR_LOG("Init call Failed!");
216     return nullptr;
217 }
218 
219 // Constructor callback
CameraInputNapiConstructor(napi_env env,napi_callback_info info)220 napi_value CameraInputNapi::CameraInputNapiConstructor(napi_env env, napi_callback_info info)
221 {
222     MEDIA_INFO_LOG("CameraInputNapiConstructor is called");
223     napi_status status;
224     napi_value result = nullptr;
225     napi_value thisVar = nullptr;
226 
227     napi_get_undefined(env, &result);
228     CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
229 
230     if (status == napi_ok && thisVar != nullptr) {
231         std::unique_ptr<CameraInputNapi> obj = std::make_unique<CameraInputNapi>();
232         obj->env_ = env;
233         obj->cameraInput_ = sCameraInput_;
234         status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
235                            CameraInputNapi::CameraInputNapiDestructor, nullptr, nullptr);
236         if (status == napi_ok) {
237             obj.release();
238             return thisVar;
239         } else {
240             MEDIA_ERR_LOG("Failure wrapping js to native napi");
241         }
242     }
243     MEDIA_ERR_LOG("CameraInputNapiConstructor call Failed!");
244     return result;
245 }
246 
CreateCameraInput(napi_env env,sptr<CameraInput> cameraInput)247 napi_value CameraInputNapi::CreateCameraInput(napi_env env, sptr<CameraInput> cameraInput)
248 {
249     MEDIA_INFO_LOG("CreateCameraInput is called");
250     CAMERA_SYNC_TRACE;
251     napi_status status;
252     napi_value result = nullptr;
253     napi_value constructor;
254     CHECK_ERROR_RETURN_RET(cameraInput == nullptr, result);
255     status = napi_get_reference_value(env, sConstructor_, &constructor);
256     if (status == napi_ok) {
257         sCameraInput_ = cameraInput;
258         status = napi_new_instance(env, constructor, 0, nullptr, &result);
259         sCameraInput_ = nullptr;
260         if (status == napi_ok && result != nullptr) {
261             return result;
262         } else {
263             MEDIA_ERR_LOG("Failed to create Camera input instance");
264         }
265     }
266     napi_get_undefined(env, &result);
267     MEDIA_ERR_LOG("CreateCameraInput call Failed!");
268     return result;
269 }
270 
GetCameraInput()271 sptr<CameraInput> CameraInputNapi::GetCameraInput()
272 {
273     return cameraInput_;
274 }
275 
Open(napi_env env,napi_callback_info info)276 napi_value CameraInputNapi::Open(napi_env env, napi_callback_info info)
277 {
278     MEDIA_INFO_LOG("Open is called");
279     std::unique_ptr<CameraInputAsyncContext> asyncContext = std::make_unique<CameraInputAsyncContext>(
280         "CameraInputNapi::Open", CameraNapiUtils::IncrementAndGet(cameraInputTaskId));
281     bool isEnableSecureCamera = false;
282     auto asyncFunction =
283         std::make_shared<CameraNapiAsyncFunction>(env, "Open", asyncContext->callbackRef, asyncContext->deferred);
284     CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction, isEnableSecureCamera);
285     if (jsParamParser.IsStatusOk()) {
286         CameraNapiUtils::IsEnableSecureCamera(isEnableSecureCamera);
287         MEDIA_DEBUG_LOG("set  EnableSecureCamera CameraInputNapi::Open");
288     } else {
289         MEDIA_WARNING_LOG("CameraInputNapi::Open check secure parameter fail, try open with CameraConcurrentType");
290         int32_t cameraConcurrentType = 0;
291         jsParamParser = CameraNapiParamParser(env, info, asyncContext->objectInfo, asyncFunction, cameraConcurrentType);
292         if (jsParamParser.IsStatusOk()) {
293             asyncContext->cameraConcurrentType = cameraConcurrentType;
294         } else {
295             MEDIA_WARNING_LOG("CameraInputNapi::Open check secure parameter fail, try open without secure flag");
296             jsParamParser = CameraNapiParamParser(env, info, asyncContext->objectInfo, asyncFunction);
297         }
298     }
299     CHECK_ERROR_RETURN_RET_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument"),
300         nullptr, "CameraInputNapi::Open invalid argument");
301     asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
302     napi_status status = napi_create_async_work(
303         env, nullptr, asyncFunction->GetResourceName(),
304         [](napi_env env, void* data) {
305             MEDIA_INFO_LOG("CameraInputNapi::Open running on worker");
306             auto context = static_cast<CameraInputAsyncContext*>(data);
307             CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "CameraInputNapi::Open async info is nullptr");
308             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
309             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
310                 context->isEnableSecCam = CameraNapiUtils::GetEnableSecureCamera();
311                 MEDIA_DEBUG_LOG("CameraInputNapi::Open context->isEnableSecCam %{public}d", context->isEnableSecCam);
312                 if (context->isEnableSecCam) {
313                     context->errorCode = context->objectInfo->GetCameraInput()->Open(true, &context->secureCameraSeqId);
314                     MEDIA_INFO_LOG("CameraInputNapi::Open, SeqId = %{public}" PRIu64 "", context->secureCameraSeqId);
315                 } else if (context->cameraConcurrentType != -1) {
316                     context->errorCode = context->objectInfo->GetCameraInput()->Open(context->cameraConcurrentType);
317                 } else {
318                     context->errorCode = context->objectInfo->GetCameraInput()->Open();
319                 }
320                 context->status = context->errorCode == CameraErrorCode::SUCCESS;
321                 CameraNapiUtils::IsEnableSecureCamera(false);
322             });
323         },
324         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
325     if (status != napi_ok) {
326         MEDIA_ERR_LOG("Failed to create napi_create_async_work for CameraInputNapi::Open");
327         asyncFunction->Reset();
328     } else {
329         asyncContext->queueTask =
330             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("CameraInputNapi::Open");
331         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
332         asyncContext.release();
333     }
334     CHECK_ERROR_RETURN_RET(asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE,
335         asyncFunction->GetPromise());
336     return CameraNapiUtils::GetUndefinedValue(env);
337 }
338 
Close(napi_env env,napi_callback_info info)339 napi_value CameraInputNapi::Close(napi_env env, napi_callback_info info)
340 {
341     MEDIA_INFO_LOG("Close is called");
342     std::unique_ptr<CameraInputAsyncContext> asyncContext = std::make_unique<CameraInputAsyncContext>(
343         "CameraInputNapi::Close", CameraNapiUtils::IncrementAndGet(cameraInputTaskId));
344     auto asyncFunction =
345         std::make_shared<CameraNapiAsyncFunction>(env, "Close", asyncContext->callbackRef, asyncContext->deferred);
346     CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
347     CHECK_ERROR_RETURN_RET_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument"),
348         nullptr, "CameraInputNapi::Close invalid argument");
349     asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
350     napi_status status = napi_create_async_work(
351         env, nullptr, asyncFunction->GetResourceName(),
352         [](napi_env env, void* data) {
353             MEDIA_INFO_LOG("CameraInputNapi::Close running on worker");
354             auto context = static_cast<CameraInputAsyncContext*>(data);
355             CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "CameraInputNapi::Close async info is nullptr");
356             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
357             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
358                 context->errorCode = context->objectInfo->GetCameraInput()->Close();
359                 context->status = context->errorCode == CameraErrorCode::SUCCESS;
360                 CameraNapiUtils::IsEnableSecureCamera(false);
361             });
362         },
363         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
364     if (status != napi_ok) {
365         MEDIA_ERR_LOG("Failed to create napi_create_async_work for CameraInputNapi::Close");
366         asyncFunction->Reset();
367     } else {
368         asyncContext->queueTask =
369             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("CameraInputNapi::Close");
370         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
371         asyncContext.release();
372     }
373     CHECK_ERROR_RETURN_RET(asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE,
374         asyncFunction->GetPromise());
375     return CameraNapiUtils::GetUndefinedValue(env);
376 }
377 
closeDelayed(napi_env env,napi_callback_info info)378 napi_value CameraInputNapi::closeDelayed(napi_env env, napi_callback_info info)
379 {
380     MEDIA_INFO_LOG("closeDelayed is called");
381     if (!CameraNapiSecurity::CheckSystemApp(env)) {
382         MEDIA_ERR_LOG("SystemApi closeDelayed is called!");
383         return nullptr;
384     }
385     std::unique_ptr<CameraInputAsyncContext> asyncContext = std::make_unique<CameraInputAsyncContext>(
386         "CameraInputNapi::closeDelayed", CameraNapiUtils::IncrementAndGet(cameraInputTaskId));
387     int32_t delayTime  = 0 ;
388     auto asyncFunction = std::make_shared<CameraNapiAsyncFunction>(
389         env, "closeDelayed", asyncContext->callbackRef, asyncContext->deferred);
390     CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction, delayTime);
391     asyncContext->delayTime = delayTime;
392     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
393         MEDIA_ERR_LOG("CameraInputNapi::closeDelayed invalid argument");
394         return nullptr;
395     }
396     asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
397     napi_status status = napi_create_async_work(
398         env, nullptr, asyncFunction->GetResourceName(),
399         [](napi_env env, void* date) {
400             MEDIA_INFO_LOG("CameraInputNapi::closeDelayed running on worker");
401             auto context = static_cast<CameraInputAsyncContext*>(date);
402             CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr,
403                 "CameraInputNapi::closeDelayed async info is nullptr");
404             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
405             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
406                 context->errorCode = context->objectInfo->GetCameraInput()->closeDelayed(context->delayTime);
407                 context->status = context->errorCode == CameraErrorCode::SUCCESS;
408             });
409         },
410         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
411     if (status != napi_ok) {
412         MEDIA_ERR_LOG("Failed to create napi_create_async_work for CameraInputNapi::closeDelayed");
413         asyncFunction->Reset();
414     } else {
415         asyncContext->queueTask =
416             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("CameraInputNapi::closeDelayed");
417         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
418         asyncContext.release();
419     }
420     CHECK_ERROR_RETURN_RET(asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE,
421         asyncFunction->GetPromise());
422     return CameraNapiUtils::GetUndefinedValue(env);
423 }
424 
Release(napi_env env,napi_callback_info info)425 napi_value CameraInputNapi::Release(napi_env env, napi_callback_info info)
426 {
427     MEDIA_INFO_LOG("Release is called");
428     std::unique_ptr<CameraInputAsyncContext> asyncContext = std::make_unique<CameraInputAsyncContext>(
429         "CameraInputNapi::Release", CameraNapiUtils::IncrementAndGet(cameraInputTaskId));
430     auto asyncFunction =
431         std::make_shared<CameraNapiAsyncFunction>(env, "Release", asyncContext->callbackRef, asyncContext->deferred);
432     CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
433     CHECK_ERROR_RETURN_RET_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument"),
434         nullptr, "CameraInputNapi::Release invalid argument");
435     asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
436     napi_status status = napi_create_async_work(
437         env, nullptr, asyncFunction->GetResourceName(),
438         [](napi_env env, void* data) {
439             MEDIA_INFO_LOG("CameraInputNapi::Release running on worker");
440             auto context = static_cast<CameraInputAsyncContext*>(data);
441             CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "CameraInputNapi::Release async info is nullptr");
442             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
443             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
444                 context->errorCode = context->objectInfo->GetCameraInput()->Release();
445                 context->status = context->errorCode == CameraErrorCode::SUCCESS;
446             });
447         },
448         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
449     if (status != napi_ok) {
450         MEDIA_ERR_LOG("Failed to create napi_create_async_work for CameraInputNapi::Release");
451         asyncFunction->Reset();
452     } else {
453         asyncContext->queueTask =
454             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("CameraInputNapi::Release");
455         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
456         asyncContext.release();
457     }
458     if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
459         return asyncFunction->GetPromise();
460     }
461     return CameraNapiUtils::GetUndefinedValue(env);
462 }
463 
RegisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)464 void CameraInputNapi::RegisterErrorCallbackListener(
465     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
466 {
467     MEDIA_INFO_LOG("CameraInputNapi::RegisterErrorCallbackListener arg size is %{public}zu", args.size());
468     CameraNapiObject emptyDevice { {} };
469     CameraNapiParamParser jsParamParser(env, args, emptyDevice);
470     CHECK_ERROR_RETURN_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT,
471         "Could not able to read cameraDevice argument!"),
472         "CameraInputNapi::RegisterErrorCallbackListener Could not able to read cameraDevice argument!");
473 
474     // Set callback for error
475     if (errorCallback_ == nullptr) {
476         errorCallback_ = make_shared<ErrorCallbackListener>(env);
477         cameraInput_->SetErrorCallback(errorCallback_);
478     }
479     errorCallback_->SaveCallbackReference(eventName, callback, isOnce);
480     MEDIA_INFO_LOG("CameraInputNapi::RegisterErrorCallbackListener success");
481 }
482 
UnregisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)483 void CameraInputNapi::UnregisterErrorCallbackListener(
484     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
485 {
486     MEDIA_INFO_LOG("CameraInputNapi::UnregisterErrorCallbackListener arg size is %{public}zu", args.size());
487     CameraNapiObject emptyDevice { {} };
488     CameraNapiParamParser jsParamParser(env, args, emptyDevice);
489     CHECK_ERROR_RETURN_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT,
490         "Could not able to read cameraDevice argument!"),
491         "CameraInputNapi::UnregisterErrorCallbackListener Could not able to read cameraDevice argument!");
492 
493     CHECK_ERROR_RETURN_LOG(errorCallback_ == nullptr, "errorCallback is null");
494     errorCallback_->RemoveCallbackRef(eventName, callback);
495     MEDIA_INFO_LOG("CameraInputNapi::UnregisterErrorCallbackListener success");
496 }
497 
RegisterOcclusionDetectCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)498 void CameraInputNapi::RegisterOcclusionDetectCallbackListener(
499     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
500 {
501     CHECK_ERROR_RETURN_LOG(!CameraNapiSecurity::CheckSystemApp(env),
502         "SystemApi RegisterOcclusionDetectCallbackListener is called!");
503     if (occlusionDetectCallback_ == nullptr) {
504         occlusionDetectCallback_ = make_shared<OcclusionDetectCallbackListener>(env);
505         cameraInput_->SetOcclusionDetectCallback(occlusionDetectCallback_);
506     }
507     occlusionDetectCallback_->SaveCallbackReference(eventName, callback, isOnce);
508     MEDIA_INFO_LOG("CameraInputNapi::RegisterOcclusionDetectCallbackListener success");
509 }
510 
UnregisterOcclusionDetectCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)511 void CameraInputNapi::UnregisterOcclusionDetectCallbackListener(
512     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
513 {
514     CHECK_ERROR_RETURN_LOG(!CameraNapiSecurity::CheckSystemApp(env),
515         "SystemApi UnregisterOcclusionDetectCallbackListener is called!");
516     CHECK_ERROR_RETURN_LOG(occlusionDetectCallback_ == nullptr, "occlusionDetectCallback is null");
517     occlusionDetectCallback_->RemoveCallbackRef(eventName, callback);
518     MEDIA_INFO_LOG("CameraInputNapi::RegisterOcclusionDetectCallbackListener success");
519 }
520 
GetEmitterFunctions()521 const CameraInputNapi::EmitterFunctions& CameraInputNapi::GetEmitterFunctions()
522 {
523     static const EmitterFunctions funMap = {
524         { "error", {
525             &CameraInputNapi::RegisterErrorCallbackListener,
526             &CameraInputNapi::UnregisterErrorCallbackListener } },
527         { "cameraOcclusionDetect", {
528             &CameraInputNapi::RegisterOcclusionDetectCallbackListener,
529             &CameraInputNapi::UnregisterOcclusionDetectCallbackListener } } };
530     return funMap;
531 }
532 
On(napi_env env,napi_callback_info info)533 napi_value CameraInputNapi::On(napi_env env, napi_callback_info info)
534 {
535     return ListenerTemplate<CameraInputNapi>::On(env, info);
536 }
537 
Once(napi_env env,napi_callback_info info)538 napi_value CameraInputNapi::Once(napi_env env, napi_callback_info info)
539 {
540     return ListenerTemplate<CameraInputNapi>::Once(env, info);
541 }
542 
Off(napi_env env,napi_callback_info info)543 napi_value CameraInputNapi::Off(napi_env env, napi_callback_info info)
544 {
545     return ListenerTemplate<CameraInputNapi>::Off(env, info);
546 }
547 
UsedAsPosition(napi_env env,napi_callback_info info)548 napi_value CameraInputNapi::UsedAsPosition(napi_env env, napi_callback_info info)
549 {
550     MEDIA_INFO_LOG("CameraInputNapi::UsedAsPosition is called");
551     CameraInputNapi* cameraInputNapi = nullptr;
552     int32_t cameraPosition;
553     CameraNapiParamParser jsParamParser(env, info, cameraInputNapi, cameraPosition);
554     CHECK_ERROR_RETURN_RET_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT,
555         "input usedAsPosition with invalid arguments!"), nullptr, "CameraInputNapi::UsedAsPosition invalid arguments!");
556     MEDIA_INFO_LOG("CameraInputNapi::UsedAsPosition params: %{public}d", cameraPosition);
557     cameraInputNapi->cameraInput_->SetInputUsedAsPosition(static_cast<const CameraPosition>(cameraPosition));
558     return CameraNapiUtils::GetUndefinedValue(env);
559 }
560 
ControlAuxiliary(napi_env env,napi_callback_info info)561 napi_value CameraInputNapi::ControlAuxiliary(napi_env env, napi_callback_info info)
562 {
563     MEDIA_INFO_LOG("CameraInputNapi::ControlAuxiliary is called");
564     if (!CameraNapiSecurity::CheckSystemApp(env)) {
565         MEDIA_ERR_LOG("SystemApi ControlAuxiliary is called!");
566         return nullptr;
567     }
568     CameraInputNapi* cameraInputNapi = nullptr;
569     int32_t auxiliaryType;
570     int32_t auxiliaryStatus;
571     CameraNapiParamParser jsParamParser(env, info, cameraInputNapi, auxiliaryType, auxiliaryStatus);
572     if (!jsParamParser.AssertStatus(PARAMETER_ERROR, "input controlAuxiliary with invalid arguments!")) {
573         MEDIA_ERR_LOG("CameraInputNapi::ControlAuxiliary invalid arguments");
574         return nullptr;
575     }
576     cameraInputNapi->cameraInput_->ControlAuxiliary(static_cast<const AuxiliaryType>(auxiliaryType),
577         static_cast<const AuxiliaryStatus>(auxiliaryStatus));
578     return CameraNapiUtils::GetUndefinedValue(env);
579 }
580 } // namespace CameraStandard
581 } // namespace OHOS
582