• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "input/camera_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