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 "output/preview_output_napi.h"
17
18 #include <cstdint>
19 #include <memory>
20 #include <string>
21 #include <unistd.h>
22 #include <uv.h>
23
24 #include "camera_error_code.h"
25 #include "camera_napi_const.h"
26 #include "camera_napi_object_types.h"
27 #include "camera_napi_param_parser.h"
28 #include "camera_napi_security_utils.h"
29 #include "camera_napi_template_utils.h"
30 #include "camera_napi_utils.h"
31 #include "camera_napi_worker_queue_keeper.h"
32 #include "camera_output_capability.h"
33 #include "js_native_api.h"
34 #include "js_native_api_types.h"
35 #include "listener_base.h"
36 #include "napi/native_api.h"
37 #include "napi/native_common.h"
38 #include "preview_output.h"
39 #include "refbase.h"
40 #include "surface_utils.h"
41
42 namespace OHOS {
43 namespace CameraStandard {
44 using namespace std;
45 namespace {
GetSurfaceFromSurfaceId(napi_env env,std::string & surfaceId)46 sptr<Surface> GetSurfaceFromSurfaceId(napi_env env, std::string& surfaceId)
47 {
48 MEDIA_DEBUG_LOG("GetSurfaceFromSurfaceId enter");
49 char *ptr;
50 uint64_t iSurfaceId = std::strtoull(surfaceId.c_str(), &ptr, 10);
51 MEDIA_INFO_LOG("GetSurfaceFromSurfaceId surfaceId %{public}" PRIu64, iSurfaceId);
52
53 return SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
54 }
55
AsyncCompleteCallback(napi_env env,napi_status status,void * data)56 void AsyncCompleteCallback(napi_env env, napi_status status, void* data)
57 {
58 auto context = static_cast<PreviewOutputAsyncContext*>(data);
59 if (context == nullptr) {
60 MEDIA_INFO_LOG("PreviewOutputNapi AsyncCompleteCallback context is null");
61 return;
62 }
63 MEDIA_INFO_LOG("PreviewOutputNapi AsyncCompleteCallback %{public}s, status = %{public}d", context->funcName.c_str(),
64 context->status);
65 std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
66 jsContext->status = context->status;
67 if (!context->status) {
68 CameraNapiUtils::CreateNapiErrorObject(env, context->errorCode, context->errorMsg.c_str(), jsContext);
69 } else {
70 napi_get_undefined(env, &jsContext->data);
71 }
72 if (!context->funcName.empty() && context->taskId > 0) {
73 // Finish async trace
74 CAMERA_FINISH_ASYNC_TRACE(context->funcName, context->taskId);
75 jsContext->funcName = context->funcName;
76 }
77 if (context->work != nullptr) {
78 CameraNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef, context->work, *jsContext);
79 }
80 context->FreeHeldNapiValue(env);
81 delete context;
82 }
83 } // namespace
84
85 thread_local napi_ref PreviewOutputNapi::sConstructor_ = nullptr;
86 thread_local sptr<PreviewOutput> PreviewOutputNapi::sPreviewOutput_ = nullptr;
87 thread_local uint32_t PreviewOutputNapi::previewOutputTaskId = CAMERA_PREVIEW_OUTPUT_TASKID;
88
PreviewOutputCallback(napi_env env)89 PreviewOutputCallback::PreviewOutputCallback(napi_env env) : ListenerBase(env) {}
90
UpdateJSCallbackAsync(PreviewOutputEventType eventType,const int32_t value) const91 void PreviewOutputCallback::UpdateJSCallbackAsync(PreviewOutputEventType eventType, const int32_t value) const
92 {
93 MEDIA_DEBUG_LOG("UpdateJSCallbackAsync is called");
94 uv_loop_s* loop = nullptr;
95 napi_get_uv_event_loop(env_, &loop);
96 if (!loop) {
97 MEDIA_ERR_LOG("failed to get event loop");
98 return;
99 }
100 uv_work_t* work = new(std::nothrow) uv_work_t;
101 if (!work) {
102 MEDIA_ERR_LOG("failed to allocate work");
103 return;
104 }
105 std::unique_ptr<PreviewOutputCallbackInfo> callbackInfo =
106 std::make_unique<PreviewOutputCallbackInfo>(eventType, value, shared_from_this());
107 work->data = callbackInfo.get();
108 int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t* work) {}, [] (uv_work_t* work, int status) {
109 PreviewOutputCallbackInfo* callbackInfo = reinterpret_cast<PreviewOutputCallbackInfo *>(work->data);
110 if (callbackInfo) {
111 auto listener = callbackInfo->listener_.lock();
112 if (listener) {
113 listener->UpdateJSCallback(callbackInfo->eventType_, callbackInfo->value_);
114 }
115 delete callbackInfo;
116 }
117 delete work;
118 }, uv_qos_user_initiated);
119 if (ret) {
120 MEDIA_ERR_LOG("failed to execute work");
121 delete work;
122 } else {
123 callbackInfo.release();
124 }
125 }
126
OnFrameStarted() const127 void PreviewOutputCallback::OnFrameStarted() const
128 {
129 CAMERA_SYNC_TRACE;
130 MEDIA_INFO_LOG("OnFrameStarted is called");
131 UpdateJSCallbackAsync(PreviewOutputEventType::PREVIEW_FRAME_START, -1);
132 }
133
OnFrameEnded(const int32_t frameCount) const134 void PreviewOutputCallback::OnFrameEnded(const int32_t frameCount) const
135 {
136 CAMERA_SYNC_TRACE;
137 MEDIA_DEBUG_LOG("OnFrameEnded is called, frameCount: %{public}d", frameCount);
138 UpdateJSCallbackAsync(PreviewOutputEventType::PREVIEW_FRAME_END, frameCount);
139 }
140
OnError(const int32_t errorCode) const141 void PreviewOutputCallback::OnError(const int32_t errorCode) const
142 {
143 CAMERA_SYNC_TRACE;
144 MEDIA_DEBUG_LOG("OnError is called, errorCode: %{public}d", errorCode);
145 UpdateJSCallbackAsync(PreviewOutputEventType::PREVIEW_FRAME_ERROR, errorCode);
146 }
147
OnSketchStatusDataChangedAsync(SketchStatusData statusData) const148 void PreviewOutputCallback::OnSketchStatusDataChangedAsync(SketchStatusData statusData) const
149 {
150 MEDIA_DEBUG_LOG("OnSketchStatusChangedAsync is called");
151 uv_loop_s* loop = nullptr;
152 napi_get_uv_event_loop(env_, &loop);
153 if (!loop) {
154 MEDIA_ERR_LOG("failed to get event loop");
155 return;
156 }
157 uv_work_t* work = new (std::nothrow) uv_work_t;
158 if (!work) {
159 MEDIA_ERR_LOG("failed to allocate work");
160 return;
161 }
162 std::unique_ptr<SketchStatusCallbackInfo> callbackInfo =
163 std::make_unique<SketchStatusCallbackInfo>(statusData, shared_from_this(), env_);
164 work->data = callbackInfo.get();
165 int ret = uv_queue_work_with_qos(
166 loop, work, [](uv_work_t* work) {},
167 [](uv_work_t* work, int status) {
168 SketchStatusCallbackInfo* callbackInfo = reinterpret_cast<SketchStatusCallbackInfo*>(work->data);
169 if (callbackInfo) {
170 auto listener = callbackInfo->listener_.lock();
171 if (listener) {
172 napi_handle_scope scope = nullptr;
173 napi_open_handle_scope(callbackInfo->env_, &scope);
174 listener->OnSketchStatusDataChangedCall(callbackInfo->sketchStatusData_);
175 napi_close_handle_scope(callbackInfo->env_, scope);
176 }
177 delete callbackInfo;
178 }
179 delete work;
180 },
181 uv_qos_user_initiated);
182 if (ret) {
183 MEDIA_ERR_LOG("failed to execute work");
184 delete work;
185 } else {
186 callbackInfo.release();
187 }
188 }
189
OnSketchStatusDataChangedCall(SketchStatusData sketchStatusData) const190 void PreviewOutputCallback::OnSketchStatusDataChangedCall(SketchStatusData sketchStatusData) const
191 {
192 CAMERA_SYNC_TRACE;
193 MEDIA_DEBUG_LOG("OnSketchStatusChangedCall is called");
194 napi_value args[ARGS_TWO];
195 napi_value retVal;
196 napi_get_undefined(env_, &args[PARAM0]);
197 napi_value napiSketchStatus;
198 napi_value napiSketchStatusKey;
199 napi_value napiSketchRatio;
200 napi_value napiSketchRatioKey;
201 napi_value callbackObj;
202 napi_create_object(env_, &callbackObj);
203 napi_create_string_utf8(env_, "status", NAPI_AUTO_LENGTH, &napiSketchStatusKey);
204 napi_create_int32(env_, static_cast<int32_t>(sketchStatusData.status), &napiSketchStatus);
205 napi_set_property(env_, callbackObj, napiSketchStatusKey, napiSketchStatus);
206 napi_create_string_utf8(env_, "sketchRatio", NAPI_AUTO_LENGTH, &napiSketchRatioKey);
207 napi_create_double(env_, sketchStatusData.sketchRatio, &napiSketchRatio);
208 napi_set_property(env_, callbackObj, napiSketchRatioKey, napiSketchRatio);
209 args[PARAM1] = callbackObj;
210
211 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = args, .result = &retVal };
212 ExecuteCallback(CONST_SKETCH_STATUS_CHANGED, callbackNapiPara);
213 }
214
OnSketchStatusDataChanged(const SketchStatusData & statusData) const215 void PreviewOutputCallback::OnSketchStatusDataChanged(const SketchStatusData& statusData) const
216 {
217 CAMERA_SYNC_TRACE;
218 MEDIA_DEBUG_LOG("OnSketchStatusDataChanged is called");
219 OnSketchStatusDataChangedAsync(statusData);
220 }
221
UpdateJSCallback(PreviewOutputEventType eventType,const int32_t value) const222 void PreviewOutputCallback::UpdateJSCallback(PreviewOutputEventType eventType, const int32_t value) const
223 {
224 MEDIA_DEBUG_LOG("UpdateJSCallback is called");
225 napi_value result[ARGS_ONE];
226 napi_value retVal;
227 napi_value propValue;
228 napi_get_undefined(env_, &result[PARAM0]);
229 std::string eventName = PreviewOutputEventTypeHelper.GetKeyString(eventType);
230 if (eventName.empty()) {
231 MEDIA_WARNING_LOG(
232 "PreviewOutputCallback::UpdateJSCallback, event type is invalid %d", static_cast<int32_t>(eventType));
233 return;
234 }
235
236 if (eventType == PreviewOutputEventType::PREVIEW_FRAME_ERROR) {
237 napi_create_object(env_, &result[PARAM0]);
238 napi_create_int32(env_, value, &propValue);
239 napi_set_named_property(env_, result[PARAM0], "code", propValue);
240 }
241 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_ONE, .argv = result, .result = &retVal };
242 ExecuteCallback(eventName, callbackNapiPara);
243 }
244
PreviewOutputNapi()245 PreviewOutputNapi::PreviewOutputNapi() : env_(nullptr) {}
246
~PreviewOutputNapi()247 PreviewOutputNapi::~PreviewOutputNapi()
248 {
249 MEDIA_DEBUG_LOG("~PreviewOutputNapi is called");
250 }
251
PreviewOutputNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)252 void PreviewOutputNapi::PreviewOutputNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
253 {
254 MEDIA_DEBUG_LOG("PreviewOutputNapiDestructor is called");
255 PreviewOutputNapi* cameraObj = reinterpret_cast<PreviewOutputNapi*>(nativeObject);
256 if (cameraObj != nullptr) {
257 delete cameraObj;
258 }
259 }
260
Init(napi_env env,napi_value exports)261 napi_value PreviewOutputNapi::Init(napi_env env, napi_value exports)
262 {
263 MEDIA_DEBUG_LOG("Init is called");
264 napi_status status;
265 napi_value ctorObj;
266 int32_t refCount = 1;
267
268 napi_property_descriptor preview_output_props[] = {
269 DECLARE_NAPI_FUNCTION("addDeferredSurface", AddDeferredSurface),
270 DECLARE_NAPI_FUNCTION("start", Start),
271 DECLARE_NAPI_FUNCTION("stop", Stop),
272 DECLARE_NAPI_FUNCTION("release", Release),
273 DECLARE_NAPI_FUNCTION("on", On),
274 DECLARE_NAPI_FUNCTION("once", Once),
275 DECLARE_NAPI_FUNCTION("off", Off),
276 DECLARE_NAPI_FUNCTION("isSketchSupported", IsSketchSupported),
277 DECLARE_NAPI_FUNCTION("getSketchRatio", GetSketchRatio),
278 DECLARE_NAPI_FUNCTION("enableSketch", EnableSketch),
279 DECLARE_NAPI_FUNCTION("attachSketchSurface", AttachSketchSurface),
280 DECLARE_NAPI_FUNCTION("setFrameRate", SetFrameRate),
281 DECLARE_NAPI_FUNCTION("getActiveFrameRate", GetActiveFrameRate),
282 DECLARE_NAPI_FUNCTION("getSupportedFrameRates", GetSupportedFrameRates),
283 DECLARE_NAPI_FUNCTION("getActiveProfile", GetActiveProfile),
284 DECLARE_NAPI_FUNCTION("getPreviewRotation", GetPreviewRotation),
285 DECLARE_NAPI_FUNCTION("setPreviewRotation", SetPreviewRotation)
286 };
287
288 status = napi_define_class(env, CAMERA_PREVIEW_OUTPUT_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
289 PreviewOutputNapiConstructor, nullptr,
290 sizeof(preview_output_props) / sizeof(preview_output_props[PARAM0]),
291 preview_output_props, &ctorObj);
292 if (status == napi_ok) {
293 status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
294 if (status == napi_ok) {
295 status = napi_set_named_property(env, exports, CAMERA_PREVIEW_OUTPUT_NAPI_CLASS_NAME, ctorObj);
296 if (status == napi_ok) {
297 return exports;
298 }
299 }
300 }
301 MEDIA_ERR_LOG("Init call Failed!");
302 return nullptr;
303 }
304
305 // Constructor callback
PreviewOutputNapiConstructor(napi_env env,napi_callback_info info)306 napi_value PreviewOutputNapi::PreviewOutputNapiConstructor(napi_env env, napi_callback_info info)
307 {
308 MEDIA_DEBUG_LOG("PreviewOutputNapiConstructor is called");
309 napi_status status;
310 napi_value result = nullptr;
311 napi_value thisVar = nullptr;
312
313 napi_get_undefined(env, &result);
314 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
315
316 if (status == napi_ok && thisVar != nullptr) {
317 std::unique_ptr<PreviewOutputNapi> obj = std::make_unique<PreviewOutputNapi>();
318 if (obj != nullptr) {
319 obj->env_ = env;
320 obj->previewOutput_ = sPreviewOutput_;
321
322 status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
323 PreviewOutputNapi::PreviewOutputNapiDestructor, nullptr, nullptr);
324 if (status == napi_ok) {
325 obj.release();
326 return thisVar;
327 } else {
328 MEDIA_ERR_LOG("Failure wrapping js to native napi");
329 }
330 }
331 }
332 MEDIA_ERR_LOG("PreviewOutputNapiConstructor call Failed!");
333 return result;
334 }
335
CreateDeferredPreviewOutput(napi_env env,Profile & profile)336 napi_value PreviewOutputNapi::CreateDeferredPreviewOutput(napi_env env, Profile& profile)
337 {
338 CAMERA_SYNC_TRACE;
339 napi_status status;
340 napi_value result = nullptr;
341 napi_value constructor;
342
343 status = napi_get_reference_value(env, sConstructor_, &constructor);
344 if (status == napi_ok) {
345 sPreviewOutput_ = CameraManager::GetInstance()->CreateDeferredPreviewOutput(profile);
346 if (sPreviewOutput_ == nullptr) {
347 MEDIA_ERR_LOG("failed to create previewOutput");
348 return result;
349 }
350 status = napi_new_instance(env, constructor, 0, nullptr, &result);
351 sPreviewOutput_ = nullptr;
352
353 if (status == napi_ok && result != nullptr) {
354 return result;
355 } else {
356 MEDIA_ERR_LOG("Failed to create preview output instance");
357 }
358 }
359
360 napi_get_undefined(env, &result);
361 return result;
362 }
363
CreatePreviewOutput(napi_env env,Profile & profile,std::string surfaceId)364 napi_value PreviewOutputNapi::CreatePreviewOutput(napi_env env, Profile& profile, std::string surfaceId)
365 {
366 MEDIA_INFO_LOG("CreatePreviewOutput is called");
367 CAMERA_SYNC_TRACE;
368 napi_status status;
369 napi_value result = nullptr;
370 napi_value constructor;
371
372 status = napi_get_reference_value(env, sConstructor_, &constructor);
373 if (status == napi_ok) {
374 uint64_t iSurfaceId;
375 std::istringstream iss(surfaceId);
376 iss >> iSurfaceId;
377 sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
378 if (!surface) {
379 surface = Media::ImageReceiver::getSurfaceById(surfaceId);
380 }
381 if (surface == nullptr) {
382 MEDIA_ERR_LOG("failed to get surface");
383 return result;
384 }
385
386 surface->SetUserData(CameraManager::surfaceFormat, std::to_string(profile.GetCameraFormat()));
387 int retCode = CameraManager::GetInstance()->CreatePreviewOutput(profile, surface, &sPreviewOutput_);
388 if (!CameraNapiUtils::CheckError(env, retCode)) {
389 return nullptr;
390 }
391 if (sPreviewOutput_ == nullptr) {
392 MEDIA_ERR_LOG("failed to create previewOutput");
393 return result;
394 }
395 status = napi_new_instance(env, constructor, 0, nullptr, &result);
396 sPreviewOutput_ = nullptr;
397
398 if (status == napi_ok && result != nullptr) {
399 return result;
400 } else {
401 MEDIA_ERR_LOG("Failed to create preview output instance");
402 }
403 }
404 MEDIA_ERR_LOG("CreatePreviewOutput call Failed!");
405 napi_get_undefined(env, &result);
406 return result;
407 }
408
CreatePreviewOutput(napi_env env,std::string surfaceId)409 napi_value PreviewOutputNapi::CreatePreviewOutput(napi_env env, std::string surfaceId)
410 {
411 MEDIA_INFO_LOG("CreatePreviewOutput with only surfaceId is called");
412 CAMERA_SYNC_TRACE;
413 napi_status status;
414 napi_value result = nullptr;
415 napi_value constructor;
416
417 status = napi_get_reference_value(env, sConstructor_, &constructor);
418 if (status == napi_ok) {
419 uint64_t iSurfaceId;
420 std::istringstream iss(surfaceId);
421 iss >> iSurfaceId;
422 sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
423 if (!surface) {
424 surface = Media::ImageReceiver::getSurfaceById(surfaceId);
425 }
426 if (surface == nullptr) {
427 MEDIA_ERR_LOG("failed to get surface");
428 return result;
429 }
430 int retCode = CameraManager::GetInstance()->CreatePreviewOutputWithoutProfile(surface, &sPreviewOutput_);
431 if (!CameraNapiUtils::CheckError(env, retCode)) {
432 return nullptr;
433 }
434 if (sPreviewOutput_ == nullptr) {
435 MEDIA_ERR_LOG("failed to create previewOutput");
436 return result;
437 }
438 status = napi_new_instance(env, constructor, 0, nullptr, &result);
439 sPreviewOutput_ = nullptr;
440
441 if (status == napi_ok && result != nullptr) {
442 return result;
443 } else {
444 MEDIA_ERR_LOG("Failed to create preview output instance");
445 }
446 }
447 MEDIA_ERR_LOG("CreatePreviewOutput call Failed!");
448 napi_get_undefined(env, &result);
449 return result;
450 }
451
GetPreviewOutput()452 sptr<PreviewOutput> PreviewOutputNapi::GetPreviewOutput()
453 {
454 return previewOutput_;
455 }
456
IsPreviewOutput(napi_env env,napi_value obj)457 bool PreviewOutputNapi::IsPreviewOutput(napi_env env, napi_value obj)
458 {
459 MEDIA_DEBUG_LOG("IsPreviewOutput is called");
460 bool result = false;
461 napi_status status;
462 napi_value constructor = nullptr;
463
464 status = napi_get_reference_value(env, sConstructor_, &constructor);
465 if (status == napi_ok) {
466 status = napi_instanceof(env, obj, constructor, &result);
467 if (status != napi_ok) {
468 result = false;
469 }
470 }
471 return result;
472 }
473
GetActiveProfile(napi_env env,napi_callback_info info)474 napi_value PreviewOutputNapi::GetActiveProfile(napi_env env, napi_callback_info info)
475 {
476 MEDIA_DEBUG_LOG("PreviewOutputNapi::GetActiveProfile is called");
477 PreviewOutputNapi* previewOutputNapi = nullptr;
478 CameraNapiParamParser jsParamParser(env, info, previewOutputNapi);
479 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
480 MEDIA_ERR_LOG("PreviewOutputNapi::GetActiveProfile parse parameter occur error");
481 return nullptr;
482 }
483 auto profile = previewOutputNapi->previewOutput_->GetPreviewProfile();
484 if (profile == nullptr) {
485 return CameraNapiUtils::GetUndefinedValue(env);
486 }
487 return CameraNapiObjProfile(*profile).GenerateNapiValue(env);
488 }
489
Release(napi_env env,napi_callback_info info)490 napi_value PreviewOutputNapi::Release(napi_env env, napi_callback_info info)
491 {
492 MEDIA_INFO_LOG("PreviewOutputNapi::Release is called");
493 std::unique_ptr<PreviewOutputAsyncContext> asyncContext = std::make_unique<PreviewOutputAsyncContext>(
494 "PreviewOutputNapi::Release", CameraNapiUtils::IncrementAndGet(previewOutputTaskId));
495 auto asyncFunction =
496 std::make_shared<CameraNapiAsyncFunction>(env, "Release", asyncContext->callbackRef, asyncContext->deferred);
497 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
498 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
499 MEDIA_ERR_LOG("PreviewOutputNapi::Release invalid argument");
500 return nullptr;
501 }
502 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
503 napi_status status = napi_create_async_work(
504 env, nullptr, asyncFunction->GetResourceName(),
505 [](napi_env env, void* data) {
506 MEDIA_INFO_LOG("PreviewOutputNapi::Release running on worker");
507 auto context = static_cast<PreviewOutputAsyncContext*>(data);
508 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "PreviewOutputNapi::Release async info is nullptr");
509 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
510 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
511 context->errorCode = context->objectInfo->previewOutput_->Release();
512 context->status = context->errorCode == CameraErrorCode::SUCCESS;
513 });
514 },
515 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
516 if (status != napi_ok) {
517 MEDIA_ERR_LOG("Failed to create napi_create_async_work for PreviewOutputNapi::Release");
518 asyncFunction->Reset();
519 } else {
520 asyncContext->queueTask =
521 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PreviewOutputNapi::Release");
522 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
523 asyncContext.release();
524 }
525 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
526 return asyncFunction->GetPromise();
527 }
528 return CameraNapiUtils::GetUndefinedValue(env);
529 }
530
AddDeferredSurface(napi_env env,napi_callback_info info)531 napi_value PreviewOutputNapi::AddDeferredSurface(napi_env env, napi_callback_info info)
532 {
533 MEDIA_DEBUG_LOG("AddDeferredSurface is called");
534 if (!CameraNapiSecurity::CheckSystemApp(env)) {
535 MEDIA_ERR_LOG("SystemApi AddDeferredSurface is called!");
536 return nullptr;
537 }
538
539 PreviewOutputNapi* previewOutputNapi;
540 std::string surfaceId;
541 CameraNapiParamParser jsParamParser(env, info, previewOutputNapi, surfaceId);
542 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
543 MEDIA_ERR_LOG("CameraInputNapi::AddDeferredSurface invalid argument");
544 return nullptr;
545 }
546
547 uint64_t iSurfaceId;
548 std::istringstream iss(surfaceId);
549 iss >> iSurfaceId;
550 sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
551 if (!surface) {
552 surface = Media::ImageReceiver::getSurfaceById(surfaceId);
553 }
554 if (surface == nullptr) {
555 MEDIA_ERR_LOG("CameraInputNapi::AddDeferredSurface failed to get surface");
556 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "invalid argument surface get fail");
557 return nullptr;
558 }
559 auto previewProfile = previewOutputNapi->previewOutput_->GetPreviewProfile();
560 if (previewProfile != nullptr) {
561 surface->SetUserData(CameraManager::surfaceFormat, std::to_string(previewProfile->GetCameraFormat()));
562 }
563 previewOutputNapi->previewOutput_->AddDeferredSurface(surface);
564 return CameraNapiUtils::GetUndefinedValue(env);
565 }
566
Start(napi_env env,napi_callback_info info)567 napi_value PreviewOutputNapi::Start(napi_env env, napi_callback_info info)
568 {
569 MEDIA_INFO_LOG("Start is called");
570 std::unique_ptr<PreviewOutputAsyncContext> asyncContext = std::make_unique<PreviewOutputAsyncContext>(
571 "PreviewOutputNapi::Start", CameraNapiUtils::IncrementAndGet(previewOutputTaskId));
572 auto asyncFunction =
573 std::make_shared<CameraNapiAsyncFunction>(env, "Start", asyncContext->callbackRef, asyncContext->deferred);
574 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
575 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
576 MEDIA_ERR_LOG("PreviewOutputNapi::Start invalid argument");
577 return nullptr;
578 }
579 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
580 napi_status status = napi_create_async_work(
581 env, nullptr, asyncFunction->GetResourceName(),
582 [](napi_env env, void* data) {
583 MEDIA_INFO_LOG("PreviewOutputNapi::Start running on worker");
584 auto context = static_cast<PreviewOutputAsyncContext*>(data);
585 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "PreviewOutputNapi::Start async info is nullptr");
586 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
587 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
588 context->errorCode = context->objectInfo->previewOutput_->Start();
589 context->status = context->errorCode == CameraErrorCode::SUCCESS;
590 MEDIA_INFO_LOG("PreviewOutputNapi::Start errorCode:%{public}d", context->errorCode);
591 });
592 },
593 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
594 if (status != napi_ok) {
595 MEDIA_ERR_LOG("Failed to create napi_create_async_work for PreviewOutputNapi::Start");
596 asyncFunction->Reset();
597 } else {
598 asyncContext->queueTask =
599 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PreviewOutputNapi::Start");
600 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
601 asyncContext.release();
602 }
603 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
604 return asyncFunction->GetPromise();
605 }
606 return CameraNapiUtils::GetUndefinedValue(env);
607 }
608
Stop(napi_env env,napi_callback_info info)609 napi_value PreviewOutputNapi::Stop(napi_env env, napi_callback_info info)
610 {
611 MEDIA_INFO_LOG("Stop is called");
612 std::unique_ptr<PreviewOutputAsyncContext> asyncContext = std::make_unique<PreviewOutputAsyncContext>(
613 "PreviewOutputNapi::Stop", CameraNapiUtils::IncrementAndGet(previewOutputTaskId));
614 auto asyncFunction =
615 std::make_shared<CameraNapiAsyncFunction>(env, "Stop", asyncContext->callbackRef, asyncContext->deferred);
616 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
617 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
618 MEDIA_ERR_LOG("PreviewOutputNapi::Stop invalid argument");
619 return nullptr;
620 }
621 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
622 napi_status status = napi_create_async_work(
623 env, nullptr, asyncFunction->GetResourceName(),
624 [](napi_env env, void* data) {
625 MEDIA_INFO_LOG("PreviewOutputNapi::Stop running on worker");
626 auto context = static_cast<PreviewOutputAsyncContext*>(data);
627 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "PreviewOutputNapi::Stop async info is nullptr");
628 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
629 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
630 context->errorCode = context->objectInfo->previewOutput_->Stop();
631 context->status = context->errorCode == CameraErrorCode::SUCCESS;
632 MEDIA_INFO_LOG("PreviewOutputNapi::Stop errorCode:%{public}d", context->errorCode);
633 });
634 },
635 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
636 if (status != napi_ok) {
637 MEDIA_ERR_LOG("Failed to create napi_create_async_work for PreviewOutputNapi::Stop");
638 asyncFunction->Reset();
639 } else {
640 asyncContext->queueTask =
641 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PreviewOutputNapi::Stop");
642 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
643 asyncContext.release();
644 }
645 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
646 return asyncFunction->GetPromise();
647 }
648 return CameraNapiUtils::GetUndefinedValue(env);
649 }
650
RegisterFrameStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)651 void PreviewOutputNapi::RegisterFrameStartCallbackListener(
652 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
653 {
654 if (previewCallback_ == nullptr) {
655 previewCallback_ = std::make_shared<PreviewOutputCallback>(env);
656 previewOutput_->SetCallback(previewCallback_);
657 }
658 previewCallback_->SaveCallbackReference(CONST_PREVIEW_FRAME_START, callback, isOnce);
659 }
660
UnregisterFrameStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)661 void PreviewOutputNapi::UnregisterFrameStartCallbackListener(
662 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
663 {
664 if (previewCallback_ == nullptr) {
665 MEDIA_ERR_LOG("previewCallback is null");
666 return;
667 }
668 previewCallback_->RemoveCallbackRef(CONST_PREVIEW_FRAME_START, callback);
669 }
670
RegisterFrameEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)671 void PreviewOutputNapi::RegisterFrameEndCallbackListener(
672 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
673 {
674 if (previewCallback_ == nullptr) {
675 previewCallback_ = std::make_shared<PreviewOutputCallback>(env);
676 previewOutput_->SetCallback(previewCallback_);
677 }
678 previewCallback_->SaveCallbackReference(CONST_PREVIEW_FRAME_END, callback, isOnce);
679 }
UnregisterFrameEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)680 void PreviewOutputNapi::UnregisterFrameEndCallbackListener(
681 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
682 {
683 if (previewCallback_ == nullptr) {
684 MEDIA_ERR_LOG("previewCallback is null");
685 return;
686 }
687 previewCallback_->RemoveCallbackRef(CONST_PREVIEW_FRAME_END, callback);
688 }
689
RegisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)690 void PreviewOutputNapi::RegisterErrorCallbackListener(
691 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
692 {
693 if (previewCallback_ == nullptr) {
694 previewCallback_ = std::make_shared<PreviewOutputCallback>(env);
695 previewOutput_->SetCallback(previewCallback_);
696 }
697 previewCallback_->SaveCallbackReference(CONST_PREVIEW_FRAME_ERROR, callback, isOnce);
698 }
699
UnregisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)700 void PreviewOutputNapi::UnregisterErrorCallbackListener(
701 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
702 {
703 if (previewCallback_ == nullptr) {
704 MEDIA_ERR_LOG("previewCallback is null");
705 return;
706 }
707 previewCallback_->RemoveCallbackRef(CONST_PREVIEW_FRAME_ERROR, callback);
708 }
709
RegisterSketchStatusChangedCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)710 void PreviewOutputNapi::RegisterSketchStatusChangedCallbackListener(
711 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
712 {
713 if (!CameraNapiSecurity::CheckSystemApp(env)) {
714 MEDIA_ERR_LOG("SystemApi On sketchStatusChanged is called!");
715 return;
716 }
717 if (previewCallback_ == nullptr) {
718 previewCallback_ = std::make_shared<PreviewOutputCallback>(env);
719 previewOutput_->SetCallback(previewCallback_);
720 }
721 previewCallback_->SaveCallbackReference(CONST_SKETCH_STATUS_CHANGED, callback, isOnce);
722 previewOutput_->OnNativeRegisterCallback(CONST_SKETCH_STATUS_CHANGED);
723 }
724
UnregisterSketchStatusChangedCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)725 void PreviewOutputNapi::UnregisterSketchStatusChangedCallbackListener(
726 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
727 {
728 if (!CameraNapiSecurity::CheckSystemApp(env)) {
729 MEDIA_ERR_LOG("SystemApi Off sketchStatusChanged is called!");
730 return;
731 }
732 if (previewCallback_ == nullptr) {
733 MEDIA_ERR_LOG("previewCallback is null");
734 return;
735 }
736 previewCallback_->RemoveCallbackRef(CONST_SKETCH_STATUS_CHANGED, callback);
737 previewOutput_->OnNativeUnregisterCallback(CONST_SKETCH_STATUS_CHANGED);
738 }
739
GetEmitterFunctions()740 const PreviewOutputNapi::EmitterFunctions& PreviewOutputNapi::GetEmitterFunctions()
741 {
742 static const EmitterFunctions funMap = {
743 { CONST_PREVIEW_FRAME_START, {
744 &PreviewOutputNapi::RegisterFrameStartCallbackListener,
745 &PreviewOutputNapi::UnregisterFrameStartCallbackListener } },
746 { CONST_PREVIEW_FRAME_END, {
747 &PreviewOutputNapi::RegisterFrameEndCallbackListener,
748 &PreviewOutputNapi::UnregisterFrameEndCallbackListener } },
749 { CONST_PREVIEW_FRAME_ERROR, {
750 &PreviewOutputNapi::RegisterErrorCallbackListener,
751 &PreviewOutputNapi::UnregisterErrorCallbackListener } },
752 { CONST_SKETCH_STATUS_CHANGED, {
753 &PreviewOutputNapi::RegisterSketchStatusChangedCallbackListener,
754 &PreviewOutputNapi::UnregisterSketchStatusChangedCallbackListener } } };
755 return funMap;
756 }
757
IsSketchSupported(napi_env env,napi_callback_info info)758 napi_value PreviewOutputNapi::IsSketchSupported(napi_env env, napi_callback_info info)
759 {
760 if (!CameraNapiSecurity::CheckSystemApp(env)) {
761 MEDIA_ERR_LOG("SystemApi IsSketchSupported is called!");
762 return nullptr;
763 }
764 MEDIA_INFO_LOG("PreviewOutputNapi::IsSketchSupported is called");
765 PreviewOutputNapi* previewOutputNapi = nullptr;
766 CameraNapiParamParser jsParamParser(env, info, previewOutputNapi);
767 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
768 MEDIA_ERR_LOG("PreviewOutputNapi::IsSketchSupported parse parameter occur error");
769 return nullptr;
770 }
771
772 bool isSupported = previewOutputNapi->previewOutput_->IsSketchSupported();
773 return CameraNapiUtils::GetBooleanValue(env, isSupported);
774 }
775
GetSketchRatio(napi_env env,napi_callback_info info)776 napi_value PreviewOutputNapi::GetSketchRatio(napi_env env, napi_callback_info info)
777 {
778 if (!CameraNapiSecurity::CheckSystemApp(env)) {
779 MEDIA_ERR_LOG("SystemApi GetSketchRatio is called!");
780 return nullptr;
781 }
782 MEDIA_INFO_LOG("PreviewOutputNapi::GetSketchRatio is called");
783 PreviewOutputNapi* previewOutputNapi = nullptr;
784 CameraNapiParamParser jsParamParser(env, info, previewOutputNapi);
785 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
786 MEDIA_ERR_LOG("PreviewOutputNapi::GetSketchRatio parse parameter occur error");
787 return nullptr;
788 }
789 auto result = CameraNapiUtils::GetUndefinedValue(env);
790 float ratio = previewOutputNapi->previewOutput_->GetSketchRatio();
791 napi_create_double(env, ratio, &result);
792 return result;
793 }
794
EnableSketch(napi_env env,napi_callback_info info)795 napi_value PreviewOutputNapi::EnableSketch(napi_env env, napi_callback_info info)
796 {
797 MEDIA_DEBUG_LOG("PreviewOutputNapi::EnableSketch enter");
798 if (!CameraNapiSecurity::CheckSystemApp(env)) {
799 MEDIA_ERR_LOG("SystemApi EnableSketch is called!");
800 return nullptr;
801 }
802
803 bool isEnableSketch;
804 PreviewOutputNapi* previewOutputNapi = nullptr;
805 CameraNapiParamParser jsParamParser(env, info, previewOutputNapi, isEnableSketch);
806 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
807 MEDIA_ERR_LOG("PreviewOutputNapi::EnableSketch parse parameter occur error");
808 return nullptr;
809 }
810
811 int32_t retCode = previewOutputNapi->previewOutput_->EnableSketch(isEnableSketch);
812 if (!CameraNapiUtils::CheckError(env, retCode)) {
813 MEDIA_ERR_LOG("PreviewOutputNapi::EnableSketch fail! %{public}d", retCode);
814 return nullptr;
815 }
816 MEDIA_DEBUG_LOG("PreviewOutputNapi::EnableSketch success");
817 return CameraNapiUtils::GetUndefinedValue(env);
818 }
819
GetPreviewRotation(napi_env env,napi_callback_info info)820 napi_value PreviewOutputNapi::GetPreviewRotation(napi_env env, napi_callback_info info)
821 {
822 MEDIA_DEBUG_LOG("GetPreviewRotation is called!");
823 napi_status status;
824 napi_value result = nullptr;
825 size_t argc = ARGS_ONE;
826 napi_value argv[ARGS_ONE] = {0};
827 napi_value thisVar = nullptr;
828 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
829
830 napi_get_undefined(env, &result);
831 PreviewOutputNapi* previewOutputNapi = nullptr;
832 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&previewOutputNapi));
833 if (status == napi_ok && previewOutputNapi != nullptr) {
834 int32_t value;
835 napi_status ret = napi_get_value_int32(env, argv[PARAM0], &value);
836 if (ret != napi_ok) {
837 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT,
838 "GetPreviewRotation parameter missing or parameter type incorrect.");
839 return result;
840 }
841 int32_t retCode = previewOutputNapi->previewOutput_->GetPreviewRotation(value);
842 if (retCode == SERVICE_FATL_ERROR) {
843 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR,
844 "GetPreviewRotation Camera service fatal error.");
845 return result;
846 }
847 if (retCode == INVALID_ARGUMENT) {
848 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT,
849 "GetPreviewRotation Camera invalid argument.");
850 return result;
851 }
852 napi_create_int32(env, retCode, &result);
853 MEDIA_INFO_LOG("PreviewOutputNapi GetPreviewRotation! %{public}d", retCode);
854 } else {
855 MEDIA_ERR_LOG("PreviewOutputNapi GetPreviewRotation! called failed!");
856 }
857 return result;
858 }
859
SetPreviewRotation(napi_env env,napi_callback_info info)860 napi_value PreviewOutputNapi::SetPreviewRotation(napi_env env, napi_callback_info info)
861 {
862 MEDIA_DEBUG_LOG("SetPreviewRotation is called!");
863 PreviewOutputNapi* previewOutputNapi = nullptr;
864 int32_t imageRotation = 0;
865 bool isDisplayLocked = false;
866 int32_t retCode = 0;
867 CameraNapiParamParser jsParamParser(env, info, previewOutputNapi, imageRotation, isDisplayLocked);
868 if (jsParamParser.IsStatusOk()) {
869 MEDIA_INFO_LOG("PreviewOutputNapi SetPreviewRotation! %{public}d", imageRotation);
870 } else {
871 MEDIA_WARNING_LOG("PreviewOutputNapi SetPreviewRotation without isDisplayLocked flag!");
872 jsParamParser = CameraNapiParamParser(env, info, previewOutputNapi, imageRotation);
873 isDisplayLocked = false;
874 }
875 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
876 MEDIA_ERR_LOG("PreviewOutputNapi::SetPreviewRotation invalid argument");
877 return nullptr;
878 }
879 if (previewOutputNapi->previewOutput_ == nullptr || imageRotation < 0 ||
880 imageRotation > ROTATION_270 || (imageRotation % ROTATION_90 != 0)) {
881 MEDIA_ERR_LOG("PreviewOutputNapi::SetPreviewRotation get native object fail");
882 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
883 return nullptr;
884 }
885 retCode = previewOutputNapi->previewOutput_->SetPreviewRotation(imageRotation, isDisplayLocked);
886 if (!CameraNapiUtils::CheckError(env, retCode)) {
887 MEDIA_ERR_LOG("PreviewOutputNapi::SetPreviewRotation! %{public}d", retCode);
888 return nullptr;
889 }
890 MEDIA_DEBUG_LOG("PreviewOutputNapi::SetPreviewRotation success");
891 return CameraNapiUtils::GetUndefinedValue(env);
892 }
893
894
AttachSketchSurface(napi_env env,napi_callback_info info)895 napi_value PreviewOutputNapi::AttachSketchSurface(napi_env env, napi_callback_info info)
896 {
897 MEDIA_DEBUG_LOG("PreviewOutputNapi::AttachSketchSurface enter");
898 if (!CameraNapiSecurity::CheckSystemApp(env)) {
899 MEDIA_ERR_LOG("SystemApi AttachSketchSurface is called!");
900 return nullptr;
901 }
902
903 std::string surfaceId;
904 PreviewOutputNapi* previewOutputNapi = nullptr;
905 CameraNapiParamParser jsParamParser(env, info, previewOutputNapi, surfaceId);
906 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
907 MEDIA_ERR_LOG("PreviewOutputNapi::AttachSketchSurface parse parameter occur error");
908 return nullptr;
909 }
910
911 sptr<Surface> surface = GetSurfaceFromSurfaceId(env, surfaceId);
912 if (surface == nullptr) {
913 MEDIA_ERR_LOG("PreviewOutputNapi::AttachSketchSurface get surface is null");
914 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "input surface convert fail");
915 return nullptr;
916 }
917
918 int32_t retCode = previewOutputNapi->previewOutput_->AttachSketchSurface(surface);
919 if (!CameraNapiUtils::CheckError(env, retCode)) {
920 MEDIA_ERR_LOG("PreviewOutputNapi::AttachSketchSurface! %{public}d", retCode);
921 return nullptr;
922 }
923 MEDIA_DEBUG_LOG("PreviewOutputNapi::AttachSketchSurface success");
924 return CameraNapiUtils::GetUndefinedValue(env);
925 }
926
SetFrameRate(napi_env env,napi_callback_info info)927 napi_value PreviewOutputNapi::SetFrameRate(napi_env env, napi_callback_info info)
928 {
929 MEDIA_DEBUG_LOG("SetFrameRate is called");
930 CAMERA_SYNC_TRACE;
931 napi_status status;
932 napi_value result;
933 size_t argc = ARGS_TWO;
934 napi_value argv[ARGS_TWO] = {0};
935 napi_value thisVar = nullptr;
936
937 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
938
939 napi_get_undefined(env, &result);
940 PreviewOutputNapi* previewOutputNapi = nullptr;
941 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&previewOutputNapi));
942 if (status == napi_ok && previewOutputNapi != nullptr) {
943 int32_t minFrameRate;
944 napi_get_value_int32(env, argv[PARAM0], &minFrameRate);
945 int32_t maxFrameRate;
946 napi_get_value_int32(env, argv[PARAM1], &maxFrameRate);
947 int32_t retCode = previewOutputNapi->previewOutput_->SetFrameRate(minFrameRate, maxFrameRate);
948 if (!CameraNapiUtils::CheckError(env, retCode)) {
949 MEDIA_ERR_LOG("PreviewOutputNapi::SetFrameRate! %{public}d", retCode);
950 return result;
951 }
952 } else {
953 MEDIA_ERR_LOG("SetFrameRate call Failed!");
954 }
955 return result;
956 }
957
GetActiveFrameRate(napi_env env,napi_callback_info info)958 napi_value PreviewOutputNapi::GetActiveFrameRate(napi_env env, napi_callback_info info)
959 {
960 MEDIA_DEBUG_LOG("GetFrameRate is called");
961 CAMERA_SYNC_TRACE;
962 napi_status status;
963 napi_value result;
964 size_t argc = ARGS_ZERO;
965 napi_value argv[ARGS_ZERO];
966 napi_value thisVar = nullptr;
967
968 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
969 NAPI_ASSERT(env, (argc == ARGS_ZERO), "requires no parameter.");
970
971 napi_get_undefined(env, &result);
972 PreviewOutputNapi* previewOutputNapi = nullptr;
973 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&previewOutputNapi));
974 if (status == napi_ok && previewOutputNapi != nullptr) {
975 std::vector<int32_t> frameRateRange = previewOutputNapi->previewOutput_->GetFrameRateRange();
976 CameraNapiUtils::CreateFrameRateJSArray(env, frameRateRange, result);
977 } else {
978 MEDIA_ERR_LOG("GetFrameRate call failed!");
979 }
980 return result;
981 }
982
GetSupportedFrameRates(napi_env env,napi_callback_info info)983 napi_value PreviewOutputNapi::GetSupportedFrameRates(napi_env env, napi_callback_info info)
984 {
985 MEDIA_DEBUG_LOG("GetSupportedFrameRates is called");
986
987 CAMERA_SYNC_TRACE;
988 napi_status status;
989 napi_value result;
990 size_t argc = ARGS_ZERO;
991 napi_value argv[ARGS_ZERO];
992 napi_value thisVar = nullptr;
993
994 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
995 NAPI_ASSERT(env, (argc == ARGS_ZERO), "requires no parameter.");
996 napi_get_undefined(env, &result);
997 PreviewOutputNapi* previewOutputNapi = nullptr;
998 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&previewOutputNapi));
999 if (status == napi_ok && previewOutputNapi != nullptr) {
1000 std::vector<std::vector<int32_t>> supportedFrameRatesRange =
1001 previewOutputNapi->previewOutput_->GetSupportedFrameRates();
1002 result = CameraNapiUtils::CreateSupportFrameRatesJSArray(env, supportedFrameRatesRange);
1003 } else {
1004 MEDIA_ERR_LOG("GetSupportedFrameRates call failed!");
1005 }
1006 return result;
1007 }
1008
On(napi_env env,napi_callback_info info)1009 napi_value PreviewOutputNapi::On(napi_env env, napi_callback_info info)
1010 {
1011 return ListenerTemplate<PreviewOutputNapi>::On(env, info);
1012 }
1013
Once(napi_env env,napi_callback_info info)1014 napi_value PreviewOutputNapi::Once(napi_env env, napi_callback_info info)
1015 {
1016 return ListenerTemplate<PreviewOutputNapi>::Once(env, info);
1017 }
1018
Off(napi_env env,napi_callback_info info)1019 napi_value PreviewOutputNapi::Off(napi_env env, napi_callback_info info)
1020 {
1021 return ListenerTemplate<PreviewOutputNapi>::Off(env, info);
1022 }
1023 } // namespace CameraStandard
1024 } // namespace OHOS
1025