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