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