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 };
231
232 status = napi_define_class(env, CAMERA_INPUT_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
233 CameraInputNapiConstructor, nullptr,
234 sizeof(camera_input_props) / sizeof(camera_input_props[PARAM0]),
235 camera_input_props, &ctorObj);
236 if (status == napi_ok) {
237 status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
238 if (status == napi_ok) {
239 status = napi_set_named_property(env, exports, CAMERA_INPUT_NAPI_CLASS_NAME, ctorObj);
240 if (status == napi_ok) {
241 return exports;
242 }
243 }
244 }
245 MEDIA_ERR_LOG("Init call Failed!");
246 return nullptr;
247 }
248
249 // Constructor callback
CameraInputNapiConstructor(napi_env env,napi_callback_info info)250 napi_value CameraInputNapi::CameraInputNapiConstructor(napi_env env, napi_callback_info info)
251 {
252 MEDIA_INFO_LOG("CameraInputNapiConstructor is called");
253 napi_status status;
254 napi_value result = nullptr;
255 napi_value thisVar = nullptr;
256
257 napi_get_undefined(env, &result);
258 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
259
260 if (status == napi_ok && thisVar != nullptr) {
261 std::unique_ptr<CameraInputNapi> obj = std::make_unique<CameraInputNapi>();
262 obj->env_ = env;
263 obj->cameraInput_ = sCameraInput_;
264 status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
265 CameraInputNapi::CameraInputNapiDestructor, nullptr, nullptr);
266 if (status == napi_ok) {
267 obj.release();
268 return thisVar;
269 } else {
270 MEDIA_ERR_LOG("Failure wrapping js to native napi");
271 }
272 }
273 MEDIA_ERR_LOG("CameraInputNapiConstructor call Failed!");
274 return result;
275 }
276
CreateCameraInput(napi_env env,sptr<CameraInput> cameraInput)277 napi_value CameraInputNapi::CreateCameraInput(napi_env env, sptr<CameraInput> cameraInput)
278 {
279 MEDIA_INFO_LOG("CreateCameraInput is called");
280 CAMERA_SYNC_TRACE;
281 napi_status status;
282 napi_value result = nullptr;
283 napi_value constructor;
284 if (cameraInput == nullptr) {
285 return result;
286 }
287 status = napi_get_reference_value(env, sConstructor_, &constructor);
288 if (status == napi_ok) {
289 sCameraInput_ = cameraInput;
290 status = napi_new_instance(env, constructor, 0, nullptr, &result);
291 sCameraInput_ = nullptr;
292 if (status == napi_ok && result != nullptr) {
293 return result;
294 } else {
295 MEDIA_ERR_LOG("Failed to create Camera input instance");
296 }
297 }
298 napi_get_undefined(env, &result);
299 MEDIA_ERR_LOG("CreateCameraInput call Failed!");
300 return result;
301 }
302
GetCameraInput()303 sptr<CameraInput> CameraInputNapi::GetCameraInput()
304 {
305 return cameraInput_;
306 }
307
Open(napi_env env,napi_callback_info info)308 napi_value CameraInputNapi::Open(napi_env env, napi_callback_info info)
309 {
310 MEDIA_INFO_LOG("Open is called");
311 std::unique_ptr<CameraInputAsyncContext> asyncContext = std::make_unique<CameraInputAsyncContext>(
312 "CameraInputNapi::Open", CameraNapiUtils::IncrementAndGet(cameraInputTaskId));
313 bool isEnableSecureCamera = false;
314 auto asyncFunction =
315 std::make_shared<CameraNapiAsyncFunction>(env, "Open", asyncContext->callbackRef, asyncContext->deferred);
316 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction, isEnableSecureCamera);
317 if (jsParamParser.IsStatusOk()) {
318 CameraNapiUtils::IsEnableSecureCamera(isEnableSecureCamera);
319 MEDIA_DEBUG_LOG("set EnableSecureCamera CameraInputNapi::Open");
320 } else {
321 MEDIA_WARNING_LOG("CameraInputNapi::Open check secure parameter fail, try open without secure flag");
322 jsParamParser = CameraNapiParamParser(env, info, asyncContext->objectInfo, asyncFunction);
323 }
324 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
325 MEDIA_ERR_LOG("CameraInputNapi::Open invalid argument");
326 return nullptr;
327 }
328 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
329 napi_status status = napi_create_async_work(
330 env, nullptr, asyncFunction->GetResourceName(),
331 [](napi_env env, void* data) {
332 MEDIA_INFO_LOG("CameraInputNapi::Open running on worker");
333 auto context = static_cast<CameraInputAsyncContext*>(data);
334 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "CameraInputNapi::Open async info is nullptr");
335 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
336 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
337 context->isEnableSecCam = CameraNapiUtils::GetEnableSecureCamera();
338 MEDIA_DEBUG_LOG("CameraInputNapi::Open context->isEnableSecCam %{public}d", context->isEnableSecCam);
339 if (context->isEnableSecCam) {
340 context->errorCode = context->objectInfo->GetCameraInput()->Open(true, &context->secureCameraSeqId);
341 MEDIA_INFO_LOG("CameraInputNapi::Open, SeqId = %{public}" PRIu64 "", context->secureCameraSeqId);
342 } else {
343 context->errorCode = context->objectInfo->GetCameraInput()->Open();
344 }
345 context->status = context->errorCode == CameraErrorCode::SUCCESS;
346 CameraNapiUtils::IsEnableSecureCamera(false);
347 });
348 },
349 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
350 if (status != napi_ok) {
351 MEDIA_ERR_LOG("Failed to create napi_create_async_work for CameraInputNapi::Open");
352 asyncFunction->Reset();
353 } else {
354 asyncContext->queueTask =
355 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("CameraInputNapi::Open");
356 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
357 asyncContext.release();
358 }
359 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
360 return asyncFunction->GetPromise();
361 }
362 return CameraNapiUtils::GetUndefinedValue(env);
363 }
364
Close(napi_env env,napi_callback_info info)365 napi_value CameraInputNapi::Close(napi_env env, napi_callback_info info)
366 {
367 MEDIA_INFO_LOG("Close is called");
368 std::unique_ptr<CameraInputAsyncContext> asyncContext = std::make_unique<CameraInputAsyncContext>(
369 "CameraInputNapi::Close", CameraNapiUtils::IncrementAndGet(cameraInputTaskId));
370 auto asyncFunction =
371 std::make_shared<CameraNapiAsyncFunction>(env, "Close", asyncContext->callbackRef, asyncContext->deferred);
372 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
373 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
374 MEDIA_ERR_LOG("CameraInputNapi::Close invalid argument");
375 return nullptr;
376 }
377 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
378 napi_status status = napi_create_async_work(
379 env, nullptr, asyncFunction->GetResourceName(),
380 [](napi_env env, void* data) {
381 MEDIA_INFO_LOG("CameraInputNapi::Close running on worker");
382 auto context = static_cast<CameraInputAsyncContext*>(data);
383 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "CameraInputNapi::Close async info is nullptr");
384 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
385 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
386 context->errorCode = context->objectInfo->GetCameraInput()->Close();
387 context->status = context->errorCode == CameraErrorCode::SUCCESS;
388 CameraNapiUtils::IsEnableSecureCamera(false);
389 });
390 },
391 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
392 if (status != napi_ok) {
393 MEDIA_ERR_LOG("Failed to create napi_create_async_work for CameraInputNapi::Close");
394 asyncFunction->Reset();
395 } else {
396 asyncContext->queueTask =
397 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("CameraInputNapi::Close");
398 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
399 asyncContext.release();
400 }
401 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
402 return asyncFunction->GetPromise();
403 }
404 return CameraNapiUtils::GetUndefinedValue(env);
405 }
406
Release(napi_env env,napi_callback_info info)407 napi_value CameraInputNapi::Release(napi_env env, napi_callback_info info)
408 {
409 MEDIA_INFO_LOG("Release is called");
410 std::unique_ptr<CameraInputAsyncContext> asyncContext = std::make_unique<CameraInputAsyncContext>(
411 "CameraInputNapi::Release", CameraNapiUtils::IncrementAndGet(cameraInputTaskId));
412 auto asyncFunction =
413 std::make_shared<CameraNapiAsyncFunction>(env, "Release", asyncContext->callbackRef, asyncContext->deferred);
414 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
415 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
416 MEDIA_ERR_LOG("CameraInputNapi::Release invalid argument");
417 return nullptr;
418 }
419 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
420 napi_status status = napi_create_async_work(
421 env, nullptr, asyncFunction->GetResourceName(),
422 [](napi_env env, void* data) {
423 MEDIA_INFO_LOG("CameraInputNapi::Release running on worker");
424 auto context = static_cast<CameraInputAsyncContext*>(data);
425 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "CameraInputNapi::Release async info is nullptr");
426 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
427 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
428 context->errorCode = context->objectInfo->GetCameraInput()->Release();
429 context->status = context->errorCode == CameraErrorCode::SUCCESS;
430 });
431 },
432 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
433 if (status != napi_ok) {
434 MEDIA_ERR_LOG("Failed to create napi_create_async_work for CameraInputNapi::Release");
435 asyncFunction->Reset();
436 } else {
437 asyncContext->queueTask =
438 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("CameraInputNapi::Release");
439 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
440 asyncContext.release();
441 }
442 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
443 return asyncFunction->GetPromise();
444 }
445 return CameraNapiUtils::GetUndefinedValue(env);
446 }
447
RegisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)448 void CameraInputNapi::RegisterErrorCallbackListener(
449 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
450 {
451 MEDIA_INFO_LOG("CameraInputNapi::RegisterErrorCallbackListener arg size is %{public}zu", args.size());
452 CameraNapiObject emptyDevice { {} };
453 CameraNapiParamParser jsParamParser(env, args, emptyDevice);
454 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "Could not able to read cameraDevice argument!")) {
455 MEDIA_ERR_LOG("CameraInputNapi::RegisterErrorCallbackListener Could not able to read cameraDevice argument!");
456 return;
457 }
458
459 // Set callback for error
460 if (errorCallback_ == nullptr) {
461 errorCallback_ = make_shared<ErrorCallbackListener>(env);
462 cameraInput_->SetErrorCallback(errorCallback_);
463 }
464 errorCallback_->SaveCallbackReference(eventName, callback, isOnce);
465 MEDIA_INFO_LOG("CameraInputNapi::RegisterErrorCallbackListener success");
466 }
467
UnregisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)468 void CameraInputNapi::UnregisterErrorCallbackListener(
469 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
470 {
471 MEDIA_INFO_LOG("CameraInputNapi::UnregisterErrorCallbackListener arg size is %{public}zu", args.size());
472 CameraNapiObject emptyDevice { {} };
473 CameraNapiParamParser jsParamParser(env, args, emptyDevice);
474 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "Could not able to read cameraDevice argument!")) {
475 MEDIA_ERR_LOG("CameraInputNapi::UnregisterErrorCallbackListener Could not able to read cameraDevice argument!");
476 return;
477 }
478
479 if (errorCallback_ == nullptr) {
480 MEDIA_ERR_LOG("errorCallback is null");
481 return;
482 }
483 errorCallback_->RemoveCallbackRef(eventName, callback);
484 MEDIA_INFO_LOG("CameraInputNapi::UnregisterErrorCallbackListener success");
485 }
486
RegisterOcclusionDetectCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)487 void CameraInputNapi::RegisterOcclusionDetectCallbackListener(
488 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
489 {
490 if (!CameraNapiSecurity::CheckSystemApp(env)) {
491 MEDIA_ERR_LOG("SystemApi RegisterOcclusionDetectCallbackListener is called!");
492 return;
493 }
494 if (occlusionDetectCallback_ == nullptr) {
495 occlusionDetectCallback_ = make_shared<OcclusionDetectCallbackListener>(env);
496 cameraInput_->SetOcclusionDetectCallback(occlusionDetectCallback_);
497 }
498 occlusionDetectCallback_->SaveCallbackReference(eventName, callback, isOnce);
499 MEDIA_INFO_LOG("CameraInputNapi::RegisterOcclusionDetectCallbackListener success");
500 }
501
UnregisterOcclusionDetectCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)502 void CameraInputNapi::UnregisterOcclusionDetectCallbackListener(
503 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
504 {
505 if (!CameraNapiSecurity::CheckSystemApp(env)) {
506 MEDIA_ERR_LOG("SystemApi UnregisterOcclusionDetectCallbackListener is called!");
507 return;
508 }
509 if (occlusionDetectCallback_ == nullptr) {
510 MEDIA_ERR_LOG("occlusionDetectCallback is null");
511 return;
512 }
513 occlusionDetectCallback_->RemoveCallbackRef(eventName, callback);
514 MEDIA_INFO_LOG("CameraInputNapi::RegisterOcclusionDetectCallbackListener success");
515 }
516
GetEmitterFunctions()517 const CameraInputNapi::EmitterFunctions& CameraInputNapi::GetEmitterFunctions()
518 {
519 static const EmitterFunctions funMap = {
520 { "error", {
521 &CameraInputNapi::RegisterErrorCallbackListener,
522 &CameraInputNapi::UnregisterErrorCallbackListener } },
523 { "cameraOcclusionDetect", {
524 &CameraInputNapi::RegisterOcclusionDetectCallbackListener,
525 &CameraInputNapi::UnregisterOcclusionDetectCallbackListener } } };
526 return funMap;
527 }
528
On(napi_env env,napi_callback_info info)529 napi_value CameraInputNapi::On(napi_env env, napi_callback_info info)
530 {
531 return ListenerTemplate<CameraInputNapi>::On(env, info);
532 }
533
Once(napi_env env,napi_callback_info info)534 napi_value CameraInputNapi::Once(napi_env env, napi_callback_info info)
535 {
536 return ListenerTemplate<CameraInputNapi>::Once(env, info);
537 }
538
Off(napi_env env,napi_callback_info info)539 napi_value CameraInputNapi::Off(napi_env env, napi_callback_info info)
540 {
541 return ListenerTemplate<CameraInputNapi>::Off(env, info);
542 }
543
UsedAsPosition(napi_env env,napi_callback_info info)544 napi_value CameraInputNapi::UsedAsPosition(napi_env env, napi_callback_info info)
545 {
546 MEDIA_INFO_LOG("CameraInputNapi::UsedAsPosition is called");
547 CameraInputNapi* cameraInputNapi = nullptr;
548 int32_t cameraPosition;
549 CameraNapiParamParser jsParamParser(env, info, cameraInputNapi, cameraPosition);
550 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "input usedAsPosition with invalid arguments!")) {
551 MEDIA_ERR_LOG("CameraInputNapi::UsedAsPosition invalid arguments");
552 return nullptr;
553 }
554 MEDIA_INFO_LOG("CameraInputNapi::UsedAsPosition params: %{public}d", cameraPosition);
555 cameraInputNapi->cameraInput_->SetInputUsedAsPosition(static_cast<const CameraPosition>(cameraPosition));
556 return CameraNapiUtils::GetUndefinedValue(env);
557 }
558 } // namespace CameraStandard
559 } // namespace OHOS
560