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