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