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_napi.h"
17 #include "input/camera_manager_napi.h"
18
19 namespace OHOS {
20 namespace CameraStandard {
21 using namespace std;
22 using OHOS::HiviewDFX::HiLog;
23 using OHOS::HiviewDFX::HiLogLabel;
24
25 thread_local napi_ref CameraManagerNapi::sConstructor_ = nullptr;
26 thread_local uint32_t CameraManagerNapi::cameraManagerTaskId = CAMERA_MANAGER_TASKID;
27
28 namespace {
29 constexpr HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "CameraManager"};
30 }
31
CameraManagerNapi()32 CameraManagerNapi::CameraManagerNapi() : env_(nullptr), wrapper_(nullptr)
33 {
34 CAMERA_SYNC_TRACE;
35 }
36
~CameraManagerNapi()37 CameraManagerNapi::~CameraManagerNapi()
38 {
39 if (wrapper_ != nullptr) {
40 napi_delete_reference(env_, wrapper_);
41 }
42 if (cameraManager_) {
43 cameraManager_ = nullptr;
44 }
45 }
46
47 // Constructor callback
CameraManagerNapiConstructor(napi_env env,napi_callback_info info)48 napi_value CameraManagerNapi::CameraManagerNapiConstructor(napi_env env, napi_callback_info info)
49 {
50 napi_status status;
51 napi_value result = nullptr;
52 napi_value thisVar = nullptr;
53
54 napi_get_undefined(env, &result);
55 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
56
57 if (status == napi_ok && thisVar != nullptr) {
58 std::unique_ptr<CameraManagerNapi> obj = std::make_unique<CameraManagerNapi>();
59 obj->env_ = env;
60 obj->cameraManager_ = CameraManager::GetInstance();
61 if (obj->cameraManager_ == nullptr) {
62 MEDIA_ERR_LOG("Failure wrapping js to native napi, obj->cameraManager_ null");
63 return result;
64 }
65 status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
66 CameraManagerNapi::CameraManagerNapiDestructor, nullptr, &(obj->wrapper_));
67 if (status == napi_ok) {
68 obj.release();
69 return thisVar;
70 } else {
71 MEDIA_ERR_LOG("Failure wrapping js to native napi");
72 }
73 }
74
75 return result;
76 }
77
CameraManagerNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)78 void CameraManagerNapi::CameraManagerNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
79 {
80 CameraManagerNapi* camera = reinterpret_cast<CameraManagerNapi*>(nativeObject);
81 if (camera != nullptr) {
82 camera->~CameraManagerNapi();
83 }
84 }
85
Init(napi_env env,napi_value exports)86 napi_value CameraManagerNapi::Init(napi_env env, napi_value exports)
87 {
88 napi_status status;
89 napi_value ctorObj;
90 int32_t refCount = 1;
91
92 napi_property_descriptor camera_mgr_properties[] = {
93 // CameraManager
94 DECLARE_NAPI_FUNCTION("getSupportedCameras", GetSupportedCameras),
95 DECLARE_NAPI_FUNCTION("getSupportedOutputCapability", GetSupportedOutputCapability),
96 DECLARE_NAPI_FUNCTION("isCameraMuted", IsCameraMuted),
97 DECLARE_NAPI_FUNCTION("isCameraMuteSupported", IsCameraMuteSupported),
98 DECLARE_NAPI_FUNCTION("muteCamera", MuteCamera),
99 DECLARE_NAPI_FUNCTION("createCameraInput", CreateCameraInputInstance),
100 DECLARE_NAPI_FUNCTION("createCaptureSession", CreateCameraSessionInstance),
101 DECLARE_NAPI_FUNCTION("createPreviewOutput", CreatePreviewOutputInstance),
102 DECLARE_NAPI_FUNCTION("createDeferredPreviewOutput", CreateDeferredPreviewOutputInstance),
103 DECLARE_NAPI_FUNCTION("createPhotoOutput", CreatePhotoOutputInstance),
104 DECLARE_NAPI_FUNCTION("createVideoOutput", CreateVideoOutputInstance),
105 DECLARE_NAPI_FUNCTION("createMetadataOutput", CreateMetadataOutputInstance),
106 DECLARE_NAPI_FUNCTION("on", On)
107 };
108
109 status = napi_define_class(env, CAMERA_MANAGER_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
110 CameraManagerNapiConstructor, nullptr,
111 sizeof(camera_mgr_properties) / sizeof(camera_mgr_properties[PARAM0]),
112 camera_mgr_properties, &ctorObj);
113 if (status == napi_ok) {
114 if (napi_create_reference(env, ctorObj, refCount, &sConstructor_) == napi_ok) {
115 status = napi_set_named_property(env, exports, CAMERA_MANAGER_NAPI_CLASS_NAME, ctorObj);
116 if (status == napi_ok) {
117 return exports;
118 }
119 }
120 }
121
122 return nullptr;
123 }
124
CreateCameraManager(napi_env env)125 napi_value CameraManagerNapi::CreateCameraManager(napi_env env)
126 {
127 napi_status status;
128 napi_value result = nullptr;
129 napi_value ctor;
130
131 status = napi_get_reference_value(env, sConstructor_, &ctor);
132 if (status == napi_ok) {
133 status = napi_new_instance(env, ctor, 0, nullptr, &result);
134 if (status == napi_ok) {
135 return result;
136 } else {
137 MEDIA_ERR_LOG("New instance could not be obtained");
138 }
139 }
140 napi_get_undefined(env, &result);
141 return result;
142 }
143
CreateCameraJSArray(napi_env env,napi_status status,std::vector<sptr<CameraDevice>> cameraObjList)144 static napi_value CreateCameraJSArray(napi_env env, napi_status status,
145 std::vector<sptr<CameraDevice>> cameraObjList)
146 {
147 napi_value cameraArray = nullptr;
148 napi_value camera = nullptr;
149
150 if (cameraObjList.empty()) {
151 MEDIA_ERR_LOG("cameraObjList is empty");
152 return cameraArray;
153 }
154
155 status = napi_create_array(env, &cameraArray);
156 if (status == napi_ok) {
157 for (size_t i = 0; i < cameraObjList.size(); i++) {
158 camera = CameraDeviceNapi::CreateCameraObj(env, cameraObjList[i]);
159 MEDIA_INFO_LOG("GetCameras CreateCameraObj success");
160 if (camera == nullptr || napi_set_element(env, cameraArray, i, camera) != napi_ok) {
161 MEDIA_ERR_LOG("Failed to create camera napi wrapper object");
162 return nullptr;
163 }
164 }
165 }
166 return cameraArray;
167 }
168
CameraManagerCommonCompleteCallback(napi_env env,napi_status status,void * data)169 void CameraManagerCommonCompleteCallback(napi_env env, napi_status status, void* data)
170 {
171 auto context = static_cast<CameraManagerContext*>(data);
172
173 CAMERA_NAPI_CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
174 std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
175 MEDIA_INFO_LOG("modeForAsync = %{public}d", context->modeForAsync);
176 napi_get_undefined(env, &jsContext->error);
177 if (context->modeForAsync == CREATE_DEFERRED_PREVIEW_OUTPUT_ASYNC_CALLBACK) {
178 jsContext->data = PhotoOutputNapi::CreatePhotoOutput(env, context->profile, context->surfaceId);
179 MEDIA_INFO_LOG("CreatePhotoOutput context->photoSurfaceId : %{public}s", context->surfaceId.c_str());
180 }
181
182 if (jsContext->data == nullptr) {
183 context->status = false;
184 context->errString = context->funcName + " failed";
185 MEDIA_ERR_LOG("Failed to create napi, funcName = %{public}s", context->funcName.c_str());
186 CameraNapiUtils::CreateNapiErrorObject(env, context->errorCode, context->errString.c_str(), jsContext);
187 } else {
188 jsContext->status = true;
189 MEDIA_INFO_LOG("Success to create napi, funcName = %{public}s", context->funcName.c_str());
190 }
191
192 // Finish async trace
193 if (!context->funcName.empty() && context->taskId > 0) {
194 CAMERA_FINISH_ASYNC_TRACE(context->funcName, context->taskId);
195 jsContext->funcName = context->funcName;
196 }
197 if (context->work != nullptr) {
198 CameraNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
199 context->work, *jsContext);
200 }
201 MEDIA_INFO_LOG("context->InvokeJSAsyncMethod end");
202 delete context;
203 }
204
CreateCameraSessionInstance(napi_env env,napi_callback_info info)205 napi_value CameraManagerNapi::CreateCameraSessionInstance(napi_env env, napi_callback_info info)
206 {
207 MEDIA_INFO_LOG("CreateCameraSessionInstance is called");
208 napi_status status;
209 napi_value result = nullptr;
210 size_t argc = ARGS_ZERO;
211 napi_value argv[ARGS_ZERO];
212 napi_value thisVar = nullptr;
213
214 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
215
216 napi_get_undefined(env, &result);
217
218 CameraManagerNapi* cameraManagerNapi = nullptr;
219 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&cameraManagerNapi));
220 if (status != napi_ok || cameraManagerNapi == nullptr) {
221 MEDIA_ERR_LOG("napi_unwrap failure!");
222 return nullptr;
223 }
224 result = CameraSessionNapi::CreateCameraSession(env);
225 return result;
226 }
227
ParseSize(napi_env env,napi_value root,Size * size)228 bool ParseSize(napi_env env, napi_value root, Size* size)
229 {
230 napi_value tempValue = nullptr;
231
232 if (napi_get_named_property(env, root, "width", &tempValue) == napi_ok) {
233 napi_get_value_uint32(env, tempValue, &size->width);
234 }
235
236 if (napi_get_named_property(env, root, "height", &tempValue) == napi_ok) {
237 napi_get_value_uint32(env, tempValue, &(size->height));
238 }
239
240 return true;
241 }
242
ParseProfile(napi_env env,napi_value root,Profile * profile)243 bool ParseProfile(napi_env env, napi_value root, Profile* profile)
244 {
245 napi_value res = nullptr;
246
247 if (napi_get_named_property(env, root, "size", &res) == napi_ok) {
248 ParseSize(env, res, &(profile->size_));
249 }
250
251 int32_t intValue = {0};
252 if (napi_get_named_property(env, root, "format", &res) == napi_ok) {
253 napi_get_value_int32(env, res, &intValue);
254 profile->format_ = static_cast<CameraFormat>(intValue);
255 }
256
257 return true;
258 }
259
ParseVideoProfile(napi_env env,napi_value root,VideoProfile * profile)260 bool ParseVideoProfile(napi_env env, napi_value root, VideoProfile* profile)
261 {
262 napi_value res = nullptr;
263
264 if (napi_get_named_property(env, root, "size", &res) == napi_ok) {
265 ParseSize(env, res, &(profile->size_));
266 }
267 int32_t intValue = {0};
268 if (napi_get_named_property(env, root, "format", &res) == napi_ok) {
269 napi_get_value_int32(env, res, &intValue);
270 profile->format_ = static_cast<CameraFormat>(intValue);
271 }
272
273 if (napi_get_named_property(env, root, "frameRateRange", &res) == napi_ok) {
274 const static int32_t LENGTH = 2;
275 std::vector<int32_t> rateRanges(LENGTH);
276
277 int32_t intValue = {0};
278 const static uint32_t MIN_INDEX = 0;
279 const static uint32_t MAX_INDEX = 1;
280
281 napi_value value;
282 if (napi_get_named_property(env, res, "min", &value) == napi_ok) {
283 napi_get_value_int32(env, value, &intValue);
284 rateRanges[MIN_INDEX] = intValue;
285 }
286 if (napi_get_named_property(env, res, "max", &value) == napi_ok) {
287 napi_get_value_int32(env, value, &intValue);
288 rateRanges[MAX_INDEX] = intValue;
289 }
290 profile->framerates_ = rateRanges;
291 }
292
293 return true;
294 }
295
ConvertJSArgsToNative(napi_env env,size_t argc,const napi_value argv[],CameraManagerContext & asyncContext)296 static napi_value ConvertJSArgsToNative(napi_env env, size_t argc, const napi_value argv[],
297 CameraManagerContext &asyncContext)
298 {
299 char buffer[PATH_MAX];
300 const int32_t refCount = 1;
301 napi_value result;
302 size_t length = 0;
303 auto context = &asyncContext;
304
305 NAPI_ASSERT(env, argv != nullptr, "Argument list is empty");
306
307 for (size_t i = PARAM0; i < argc; i++) {
308 napi_valuetype valueType = napi_undefined;
309 napi_typeof(env, argv[i], &valueType);
310 if (i == PARAM0 && valueType == napi_object) {
311 bool isVideoMode = false;
312 (void)napi_has_named_property(env, argv[i], "frameRateRange", &isVideoMode);
313 if (!isVideoMode) {
314 ParseProfile(env, argv[i], &(context->profile));
315 MEDIA_INFO_LOG("ConvertJSArgsToNative ParseProfile "
316 "size.width = %{public}d, size.height = %{public}d, format = %{public}d",
317 context->profile.size_.width, context->profile.size_.height, context->profile.format_);
318 } else {
319 ParseVideoProfile(env, argv[i], &(context->videoProfile));
320 MEDIA_INFO_LOG("ConvertJSArgsToNative ParseVideoProfile "
321 "size.width = %{public}d, size.height = %{public}d, format = %{public}d, "
322 "frameRateRange : min = %{public}d, max = %{public}d",
323 context->videoProfile.size_.width,
324 context->videoProfile.size_.height,
325 context->videoProfile.format_,
326 context->videoProfile.framerates_[0],
327 context->videoProfile.framerates_[1]);
328 }
329 } else if (i == PARAM1 && valueType == napi_string) {
330 if (napi_get_value_string_utf8(env, argv[i], buffer, PATH_MAX, &length) == napi_ok) {
331 MEDIA_INFO_LOG("surfaceId buffer --1 : %{public}s", buffer);
332 context->surfaceId = std::string(buffer);
333 MEDIA_INFO_LOG("context->surfaceId after convert : %{public}s", context->surfaceId.c_str());
334 } else {
335 MEDIA_ERR_LOG("Could not able to read surfaceId argument!");
336 }
337 } else if (i == PARAM2 && valueType == napi_function) {
338 napi_create_reference(env, argv[i], refCount, &context->callbackRef);
339 break;
340 } else {
341 NAPI_ASSERT(env, false, "type mismatch");
342 }
343 }
344
345 // Return true napi_value if params are successfully obtained
346 napi_get_boolean(env, true, &result);
347 return result;
348 }
349
CreatePreviewOutputInstance(napi_env env,napi_callback_info info)350 napi_value CameraManagerNapi::CreatePreviewOutputInstance(napi_env env, napi_callback_info info)
351 {
352 MEDIA_INFO_LOG("CreatePreviewOutputInstance called");
353 napi_status status;
354 napi_value result = nullptr;
355 size_t argc = ARGS_TWO;
356 napi_value argv[ARGS_TWO] = {0};
357 napi_value thisVar = nullptr;
358
359 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
360 if (!CameraNapiUtils::CheckInvalidArgument(env, argc, ARGS_TWO, argv, CREATE_PREVIEW_OUTPUT_INSTANCE)) {
361 MEDIA_INFO_LOG("CheckInvalidArgument napi_throw_type_error ");
362 return result;
363 }
364 MEDIA_INFO_LOG("CheckInvalidArgument pass");
365 napi_get_undefined(env, &result);
366 CameraManagerNapi* cameraManagerNapi = nullptr;
367 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&cameraManagerNapi));
368 if (status != napi_ok || cameraManagerNapi == nullptr) {
369 MEDIA_ERR_LOG("napi_unwrap failure!");
370 return nullptr;
371 }
372 Profile profile;
373 ParseProfile(env, argv[PARAM0], &profile);
374 MEDIA_INFO_LOG("ConvertJSArgsToNative ParseProfile "
375 "size.width = %{public}d, size.height = %{public}d, format = %{public}d",
376 profile.size_.width, profile.size_.height, profile.format_);
377
378 char buffer[PATH_MAX];
379 size_t length = 0;
380 if (napi_get_value_string_utf8(env, argv[PARAM1], buffer, PATH_MAX, &length) == napi_ok) {
381 MEDIA_INFO_LOG("surfaceId buffer --1 : %{public}s", buffer);
382 std::string surfaceId = std::string(buffer);
383 result = PreviewOutputNapi::CreatePreviewOutput(env, profile, surfaceId);
384 MEDIA_INFO_LOG("surfaceId after convert : %{public}s", surfaceId.c_str());
385 } else {
386 MEDIA_ERR_LOG("Could not able to read surfaceId argument!");
387 }
388 return result;
389 }
390
CreateDeferredPreviewOutputInstance(napi_env env,napi_callback_info info)391 napi_value CameraManagerNapi::CreateDeferredPreviewOutputInstance(napi_env env, napi_callback_info info)
392 {
393 MEDIA_INFO_LOG("CreateDeferredPreviewOutputInstance is called");
394 napi_status status;
395 napi_value result = nullptr;
396 napi_value resource = nullptr;
397 size_t argc = ARGS_TWO;
398 napi_value argv[ARGS_TWO] = {0};
399 napi_value thisVar = nullptr;
400
401 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
402 NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 2 parameters maximum");
403
404 napi_get_undefined(env, &result);
405 std::unique_ptr<CameraManagerContext> asyncContext = std::make_unique<CameraManagerContext>();
406 result = ConvertJSArgsToNative(env, argc, argv, *asyncContext);
407 CAMERA_NAPI_CHECK_NULL_PTR_RETURN_UNDEFINED(env, result, result, "Failed to obtain arguments");
408 CAMERA_NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
409 CAMERA_NAPI_CREATE_RESOURCE_NAME(env, resource, "CreateDeferredPreviewOutput");
410 status = napi_create_async_work(
411 env, nullptr, resource,
412 [](napi_env env, void* data) {
413 auto context = static_cast<CameraManagerContext*>(data);
414 // Start async trace
415 context->funcName = "CameraManagerNapi::CreateDeferredPreviewOutputInstance";
416 context->taskId = CameraNapiUtils::IncreamentAndGet(cameraManagerTaskId);
417 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
418 MEDIA_INFO_LOG("cameraManager_->CreateDeferredPreviewOutputInstance()");
419 context->status = true;
420 context->modeForAsync = CREATE_DEFERRED_PREVIEW_OUTPUT_ASYNC_CALLBACK;
421 },
422 CameraManagerCommonCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
423 if (status != napi_ok) {
424 MEDIA_ERR_LOG("Failed to create napi_create_async_work for CreatePhotoOutputInstance");
425 napi_get_undefined(env, &result);
426 } else {
427 napi_queue_async_work(env, asyncContext->work);
428 asyncContext.release();
429 }
430
431 return result;
432 }
433
CreatePhotoOutputInstance(napi_env env,napi_callback_info info)434 napi_value CameraManagerNapi::CreatePhotoOutputInstance(napi_env env, napi_callback_info info)
435 {
436 MEDIA_INFO_LOG("CreatePhotoOutputInstance is called");
437 napi_status status;
438 napi_value result = nullptr;
439 size_t argc = ARGS_TWO;
440 napi_value argv[ARGS_TWO] = {0};
441 napi_value thisVar = nullptr;
442
443 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
444 if (!CameraNapiUtils::CheckInvalidArgument(env, argc, ARGS_TWO, argv, CREATE_PHOTO_OUTPUT_INSTANCE)) {
445 return result;
446 }
447
448 napi_get_undefined(env, &result);
449 CameraManagerNapi* cameraManagerNapi = nullptr;
450 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&cameraManagerNapi));
451 if (status != napi_ok || cameraManagerNapi == nullptr) {
452 MEDIA_ERR_LOG("napi_unwrap failure!");
453 return nullptr;
454 }
455
456 Profile profile;
457 ParseProfile(env, argv[PARAM0], &profile);
458 MEDIA_INFO_LOG("ParseProfile "
459 "size.width = %{public}d, size.height = %{public}d, format = %{public}d",
460 profile.size_.width, profile.size_.height, profile.format_);
461
462 char buffer[PATH_MAX];
463 size_t length = 0;
464 if (napi_get_value_string_utf8(env, argv[PARAM1], buffer, PATH_MAX, &length) == napi_ok) {
465 MEDIA_INFO_LOG("surfaceId buffer --1 : %{public}s", buffer);
466 std::string surfaceId = std::string(buffer);
467 result = PhotoOutputNapi::CreatePhotoOutput(env, profile, surfaceId);
468 MEDIA_INFO_LOG("surfaceId after convert : %{public}s", surfaceId.c_str());
469 } else {
470 MEDIA_ERR_LOG("Could not able to read surfaceId argument!");
471 }
472 return result;
473 }
474
CreateVideoOutputInstance(napi_env env,napi_callback_info info)475 napi_value CameraManagerNapi::CreateVideoOutputInstance(napi_env env, napi_callback_info info)
476 {
477 MEDIA_INFO_LOG("CreateVideoOutputInstance is called");
478 napi_status status;
479 napi_value result = nullptr;
480 size_t argc = ARGS_TWO;
481 napi_value argv[ARGS_TWO] = {0};
482 napi_value thisVar = nullptr;
483
484 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
485 if (!CameraNapiUtils::CheckInvalidArgument(env, argc, ARGS_TWO, argv, CREATE_VIDEO_OUTPUT_INSTANCE)) {
486 return result;
487 }
488
489 CameraManagerNapi* cameraManagerNapi = nullptr;
490 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&cameraManagerNapi));
491 if (status != napi_ok || cameraManagerNapi == nullptr) {
492 MEDIA_ERR_LOG("napi_unwrap failure!");
493 return nullptr;
494 }
495 VideoProfile vidProfile;
496 ParseVideoProfile(env, argv[0], &(vidProfile));
497 MEDIA_INFO_LOG("ConvertJSArgsToNative ParseVideoProfile "
498 "size.width = %{public}d, size.height = %{public}d, format = %{public}d, "
499 "frameRateRange : min = %{public}d, max = %{public}d",
500 vidProfile.size_.width,
501 vidProfile.size_.height,
502 vidProfile.format_,
503 vidProfile.framerates_[0],
504 vidProfile.framerates_[1]);
505 char buffer[PATH_MAX];
506 size_t length = 0;
507 if (napi_get_value_string_utf8(env, argv[PARAM1], buffer, PATH_MAX, &length) == napi_ok) {
508 MEDIA_INFO_LOG("surfaceId buffer --1 : %{public}s", buffer);
509 std::string surfaceId = std::string(buffer);
510 result = VideoOutputNapi::CreateVideoOutput(env, vidProfile, surfaceId);
511 MEDIA_INFO_LOG("surfaceId after convert : %{public}s", surfaceId.c_str());
512 } else {
513 MEDIA_ERR_LOG("Could not able to read surfaceId argument!");
514 }
515 return result;
516 }
517
ParseMetadataObjectTypes(napi_env env,napi_value arrayParam,std::vector<MetadataObjectType> & metadataObjectTypes)518 napi_value ParseMetadataObjectTypes(napi_env env, napi_value arrayParam,
519 std::vector<MetadataObjectType> &metadataObjectTypes)
520 {
521 napi_value result;
522 uint32_t length = 0;
523 napi_value value;
524 int32_t metadataType;
525 napi_get_array_length(env, arrayParam, &length);
526 napi_valuetype type = napi_undefined;
527 for (uint32_t i = 0; i < length; i++) {
528 napi_get_element(env, arrayParam, i, &value);
529 napi_typeof(env, value, &type);
530 if (type != napi_number) {
531 return nullptr;
532 }
533 napi_get_value_int32(env, value, &metadataType);
534 metadataObjectTypes.push_back(static_cast<MetadataObjectType>(metadataType));
535 }
536 napi_get_boolean(env, true, &result);
537 return result;
538 }
539
CreateMetadataOutputInstance(napi_env env,napi_callback_info info)540 napi_value CameraManagerNapi::CreateMetadataOutputInstance(napi_env env, napi_callback_info info)
541 {
542 MEDIA_INFO_LOG("CreateMetadataOutputInstance is called");
543 napi_status status;
544 napi_value result = nullptr;
545 size_t argc = ARGS_ONE;
546 napi_value argv[ARGS_ONE] = {0};
547 napi_value thisVar = nullptr;
548
549 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
550 if (!CameraNapiUtils::CheckInvalidArgument(env, argc, ARGS_ONE, argv, CREATE_METADATA_OUTPUT_INSTANCE)) {
551 return result;
552 }
553
554 napi_get_undefined(env, &result);
555 CameraManagerNapi* cameraManagerNapi = nullptr;
556 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&cameraManagerNapi));
557 if (status != napi_ok || cameraManagerNapi == nullptr) {
558 MEDIA_ERR_LOG("napi_unwrap failure!");
559 return nullptr;
560 }
561 std::vector<MetadataObjectType> metadataObjectTypes;
562 ParseMetadataObjectTypes(env, argv[PARAM0], metadataObjectTypes);
563 result = MetadataOutputNapi::CreateMetadataOutput(env);
564 return result;
565 }
566
GetSupportedCameras(napi_env env,napi_callback_info info)567 napi_value CameraManagerNapi::GetSupportedCameras(napi_env env, napi_callback_info info)
568 {
569 MEDIA_INFO_LOG("GetSupportedCameras is called");
570 napi_status status;
571 napi_value result = nullptr;
572 size_t argc = ARGS_ZERO;
573 napi_value argv[ARGS_ZERO];
574 napi_value thisVar = nullptr;
575
576 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
577
578 napi_get_undefined(env, &result);
579 CameraManagerNapi* cameraManagerNapi = nullptr;
580 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&cameraManagerNapi));
581 if (status == napi_ok && cameraManagerNapi != nullptr) {
582 std::vector<sptr<CameraDevice>> cameraObjList = cameraManagerNapi->cameraManager_->GetSupportedCameras();
583 result = CreateCameraJSArray(env, status, cameraObjList);
584 }
585 return result;
586 }
587
GetSupportedOutputCapability(napi_env env,napi_callback_info info)588 napi_value CameraManagerNapi::GetSupportedOutputCapability(napi_env env, napi_callback_info info)
589 {
590 MEDIA_INFO_LOG("GetSupportedOutputCapability is called");
591 napi_status status;
592
593 napi_value result = nullptr;
594 size_t argc = ARGS_ONE;
595 napi_value argv[ARGS_ONE] = {0};
596 napi_value thisVar = nullptr;
597 CameraDeviceNapi* cameraDeviceNapi = nullptr;
598 CameraManagerNapi* cameraManagerNapi = nullptr;
599
600 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
601
602 napi_get_undefined(env, &result);
603 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&cameraManagerNapi));
604 if (status != napi_ok || cameraManagerNapi == nullptr) {
605 MEDIA_ERR_LOG("napi_unwrap( ) failure!");
606 return result;
607 }
608 status = napi_unwrap(env, argv[PARAM0], reinterpret_cast<void **>(&cameraDeviceNapi));
609 if (status != napi_ok || cameraDeviceNapi == nullptr) {
610 MEDIA_ERR_LOG("Could not able to read cameraId argument!");
611 return result;
612 }
613 sptr<CameraDevice> cameraInfo = cameraDeviceNapi->cameraDevice_;
614 result = CameraOutputCapabilityNapi::CreateCameraOutputCapability(env, cameraInfo);
615 return result;
616 }
617
IsCameraMuted(napi_env env,napi_callback_info info)618 napi_value CameraManagerNapi::IsCameraMuted(napi_env env, napi_callback_info info)
619 {
620 MEDIA_INFO_LOG("IsCameraMuted is called");
621 napi_value result = nullptr;
622 size_t argc = ARGS_ONE;
623 napi_value argv[ARGS_ONE] = {0};
624 napi_value thisVar = nullptr;
625
626 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
627 NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum");
628 bool isMuted = CameraManager::GetInstance()->IsCameraMuted();
629 MEDIA_INFO_LOG("CameraManager::GetInstance()->IsCameraMuted : %{public}d", isMuted);
630 napi_get_boolean(env, isMuted, &result);
631 return result;
632 }
633
IsCameraMuteSupported(napi_env env,napi_callback_info info)634 napi_value CameraManagerNapi::IsCameraMuteSupported(napi_env env, napi_callback_info info)
635 {
636 MEDIA_INFO_LOG("IsCameraMuteSupported is called");
637 napi_value result = nullptr;
638 size_t argc = ARGS_ONE;
639 napi_value argv[ARGS_ONE] = {0};
640 napi_value thisVar = nullptr;
641
642 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
643 NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameters maximum");
644
645 bool isMuteSupported = CameraManager::GetInstance()->IsCameraMuteSupported();
646 MEDIA_INFO_LOG("CameraManager::GetInstance()->IsCameraMuteSupported : %{public}d", isMuteSupported);
647 napi_get_boolean(env, isMuteSupported, &result);
648 return result;
649 }
650
MuteCamera(napi_env env,napi_callback_info info)651 napi_value CameraManagerNapi::MuteCamera(napi_env env, napi_callback_info info)
652 {
653 MEDIA_INFO_LOG("MuteCamera is called");
654 napi_value result = nullptr;
655 size_t argc = ARGS_TWO;
656 napi_value argv[ARGS_TWO] = {0};
657 napi_value thisVar = nullptr;
658
659 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
660 NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 1 parameters maximum");
661 bool isSupported;
662 napi_get_value_bool(env, argv[PARAM0], &isSupported);
663 CameraManager::GetInstance()->MuteCamera(isSupported);
664 MEDIA_INFO_LOG("MuteCamera");
665 napi_get_undefined(env, &result);
666 return result;
667 }
668
CreateCameraInputInstance(napi_env env,napi_callback_info info)669 napi_value CameraManagerNapi::CreateCameraInputInstance(napi_env env, napi_callback_info info)
670 {
671 MEDIA_INFO_LOG("CreateCameraInputInstance is called");
672 napi_status status;
673 napi_value result = nullptr;
674 size_t argc = ARGS_TWO;
675 napi_value argv[ARGS_TWO] = {0};
676 napi_value thisVar = nullptr;
677
678 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
679 if (!CameraNapiUtils::CheckInvalidArgument(env, argc, ARGS_TWO, argv, CREATE_CAMERA_INPUT_INSTANCE)) {
680 return result;
681 }
682
683 napi_get_undefined(env, &result);
684 CameraManagerNapi* cameraManagerNapi = nullptr;
685 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&cameraManagerNapi));
686 if (status != napi_ok || cameraManagerNapi == nullptr) {
687 MEDIA_ERR_LOG("napi_unwrap( ) failure!");
688 return result;
689 }
690 sptr<CameraDevice> cameraInfo = nullptr;
691 if (argc == ARGS_ONE) {
692 CameraDeviceNapi* cameraDeviceNapi = nullptr;
693 status = napi_unwrap(env, argv[PARAM0], reinterpret_cast<void **>(&cameraDeviceNapi));
694 if (status != napi_ok || cameraDeviceNapi == nullptr) {
695 MEDIA_ERR_LOG("napi_unwrap( ) failure!");
696 return result;
697 }
698 cameraInfo = cameraDeviceNapi->cameraDevice_;
699 } else if (argc == ARGS_TWO) {
700 int32_t numValue;
701
702 napi_get_value_int32(env, argv[PARAM0], &numValue);
703 CameraPosition cameraPosition = static_cast<CameraPosition>(numValue);
704
705 napi_get_value_int32(env, argv[PARAM1], &numValue);
706 CameraType cameraType = static_cast<CameraType>(numValue);
707
708 std::vector<sptr<CameraDevice>> cameraObjList = cameraManagerNapi->cameraManager_->GetSupportedCameras();
709 MEDIA_DEBUG_LOG("cameraInfo is null, cameraManager_->GetSupportedCameras() : %{public}zu",
710 cameraObjList.size());
711 for (size_t i = 0; i < cameraObjList.size(); i++) {
712 sptr<CameraDevice> cameraDevice = cameraObjList[i];
713 if (cameraDevice == nullptr) {
714 continue;
715 }
716 if (cameraDevice->GetPosition() == cameraPosition &&
717 cameraDevice->GetCameraType() == cameraType) {
718 cameraInfo = cameraDevice;
719 break;
720 }
721 }
722 }
723 if (cameraInfo != nullptr) {
724 sptr<CameraInput> cameraInput = nullptr;
725 int retCode = CameraManager::GetInstance()->CreateCameraInput(cameraInfo, &cameraInput);
726 if (!CameraNapiUtils::CheckError(env, retCode)) {
727 return nullptr;
728 }
729 result = CameraInputNapi::CreateCameraInput(env, cameraInput);
730 }
731 return result;
732 }
733
On(napi_env env,napi_callback_info info)734 napi_value CameraManagerNapi::On(napi_env env, napi_callback_info info)
735 {
736 MEDIA_INFO_LOG("On is called");
737 napi_value undefinedResult = nullptr;
738 size_t argCount = ARGS_TWO;
739 napi_value argv[ARGS_TWO] = {nullptr};
740 napi_value thisVar = nullptr;
741 size_t res = 0;
742 char buffer[SIZE];
743 CameraManagerNapi* obj = nullptr;
744 napi_status status;
745
746 napi_get_undefined(env, &undefinedResult);
747
748 CAMERA_NAPI_GET_JS_ARGS(env, info, argCount, argv, thisVar);
749 NAPI_ASSERT(env, argCount == ARGS_TWO, "requires 2 parameters");
750
751 if (thisVar == nullptr || argv[PARAM0] == nullptr || argv[PARAM1] == nullptr) {
752 MEDIA_ERR_LOG("Failed to retrieve details about the callback");
753 return undefinedResult;
754 }
755
756 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&obj));
757 if (status == napi_ok && obj != nullptr) {
758 napi_valuetype valueType = napi_undefined;
759 if (napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string
760 || napi_typeof(env, argv[PARAM1], &valueType) != napi_ok || valueType != napi_function) {
761 return undefinedResult;
762 }
763
764 napi_get_value_string_utf8(env, argv[PARAM0], buffer, SIZE, &res);
765 std::string eventType = std::string(buffer);
766
767 napi_ref callbackRef;
768 const int32_t refCount = 1;
769 napi_create_reference(env, argv[PARAM1], refCount, &callbackRef);
770
771 if (!eventType.empty() && (eventType.compare("cameraStatus")==0)) {
772 shared_ptr<CameraManagerCallbackNapi> callback =
773 make_shared<CameraManagerCallbackNapi>(env, callbackRef);
774 obj->cameraManager_->SetCallback(callback);
775 } else if (!eventType.empty() && (eventType.compare("cameraMute")==0)) {
776 shared_ptr<CameraMuteListenerNapi> listener =
777 make_shared<CameraMuteListenerNapi>(env, callbackRef);
778 obj->cameraManager_->RegisterCameraMuteListener(listener);
779 } else {
780 MEDIA_ERR_LOG("Incorrect callback event type provided for camera manager!");
781 if (callbackRef != nullptr) {
782 napi_delete_reference(env, callbackRef);
783 }
784 }
785 }
786
787 return undefinedResult;
788 }
789 } // namespace CameraStandard
790 } // namespace OHOS
791