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