1 /*
2 * Copyright (c) 2021-2024 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/photo_output_napi.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <memory>
21 #include <mutex>
22 #include <string>
23 #include <unistd.h>
24 #include <unordered_set>
25 #include <uv.h>
26
27 #include "buffer_extra_data_impl.h"
28 #include "camera_buffer_handle_utils.h"
29 #include "camera_error_code.h"
30 #include "camera_log.h"
31 #include "camera_napi_const.h"
32 #include "camera_napi_object_types.h"
33 #include "camera_napi_param_parser.h"
34 #include "camera_napi_security_utils.h"
35 #include "camera_napi_template_utils.h"
36 #include "camera_napi_utils.h"
37 #include "camera_napi_worker_queue_keeper.h"
38 #include "camera_output_capability.h"
39 #include "camera_photo_proxy.h"
40 #include "camera_report_dfx_uitls.h"
41 #include "camera_util.h"
42 #include "dp_utils.h"
43 #include "image_napi.h"
44 #include "image_packer.h"
45 #include "image_receiver.h"
46 #include "ipc_skeleton.h"
47 #include "js_native_api.h"
48 #include "js_native_api_types.h"
49 #include "listener_base.h"
50 #include "media_library_comm_napi.h"
51 #include "media_library_manager.h"
52 #include "output/deferred_photo_proxy_napi.h"
53 #include "output/photo_napi.h"
54 #include "output/photo_output_napi.h"
55 #include "photo_output.h"
56 #include "pixel_map_napi.h"
57 #include "picture.h"
58 #include "refbase.h"
59 #include "securec.h"
60 #include "video_key_info.h"
61
62 namespace OHOS {
63 namespace CameraStandard {
64 using namespace std;
65 namespace {
AsyncCompleteCallback(napi_env env,napi_status status,void * data)66 void AsyncCompleteCallback(napi_env env, napi_status status, void* data)
67 {
68 auto context = static_cast<PhotoOutputAsyncContext*>(data);
69 CHECK_ERROR_RETURN_LOG(context == nullptr, "CameraInputNapi AsyncCompleteCallback context is null");
70 MEDIA_INFO_LOG("CameraInputNapi AsyncCompleteCallback %{public}s, status = %{public}d", context->funcName.c_str(),
71 context->status);
72 std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
73 jsContext->status = context->status;
74
75 if (!context->status) {
76 CameraNapiUtils::CreateNapiErrorObject(env, context->errorCode, context->errorMsg.c_str(), jsContext);
77 } else {
78 napi_get_undefined(env, &jsContext->data);
79 }
80 if (!context->funcName.empty() && context->taskId > 0) {
81 // Finish async trace
82 CAMERA_FINISH_ASYNC_TRACE(context->funcName, context->taskId);
83 jsContext->funcName = context->funcName;
84 }
85 if (context->work != nullptr) {
86 CameraNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef, context->work, *jsContext);
87 }
88 context->FreeHeldNapiValue(env);
89 delete context;
90 }
91
ProcessCapture(PhotoOutputAsyncContext * context,bool isBurst)92 void ProcessCapture(PhotoOutputAsyncContext* context, bool isBurst)
93 {
94 context->status = true;
95 sptr<PhotoOutput> photoOutput = context->objectInfo->GetPhotoOutput();
96 MEDIA_INFO_LOG("PhotoOutputAsyncContext objectInfo GetEnableMirror is %{public}d",
97 context->objectInfo->GetEnableMirror());
98 if (context->hasPhotoSettings) {
99 std::shared_ptr<PhotoCaptureSetting> capSettings = make_shared<PhotoCaptureSetting>();
100 if (context->quality != -1) {
101 capSettings->SetQuality(static_cast<PhotoCaptureSetting::QualityLevel>(context->quality));
102 }
103 if (context->rotation != -1) {
104 capSettings->SetRotation(static_cast<PhotoCaptureSetting::RotationConfig>(context->rotation));
105 }
106 if (!context->isMirrorSettedByUser) {
107 capSettings->SetMirror(context->objectInfo->GetEnableMirror());
108 } else {
109 capSettings->SetMirror(context->isMirror);
110 }
111 if (context->location != nullptr) {
112 capSettings->SetLocation(context->location);
113 }
114 if (isBurst) {
115 MEDIA_ERR_LOG("ProcessContext BurstCapture");
116 uint8_t burstState = 1; // 0:end 1:start
117 capSettings->SetBurstCaptureState(burstState);
118 }
119 context->errorCode = photoOutput->Capture(capSettings);
120 } else {
121 std::shared_ptr<PhotoCaptureSetting> capSettings = make_shared<PhotoCaptureSetting>();
122 capSettings->SetMirror(context->objectInfo->GetEnableMirror());
123 context->errorCode = photoOutput->Capture(capSettings);
124 }
125 context->status = context->errorCode == 0;
126 }
127
ValidQualityLevelFromJs(int32_t jsQuality)128 bool ValidQualityLevelFromJs(int32_t jsQuality)
129 {
130 MEDIA_INFO_LOG("PhotoOutputNapi::ValidQualityLevelFromJs quality level = %{public}d", jsQuality);
131 switch (jsQuality) {
132 case QUALITY_LEVEL_HIGH:
133 // Fallthrough
134 case QUALITY_LEVEL_MEDIUM:
135 // Fallthrough
136 case QUALITY_LEVEL_LOW:
137 return true;
138 default:
139 MEDIA_ERR_LOG("Invalid quality value received from application");
140 return false;
141 }
142 return false;
143 }
144
ValidImageRotationFromJs(int32_t jsRotation)145 bool ValidImageRotationFromJs(int32_t jsRotation)
146 {
147 MEDIA_INFO_LOG("js rotation = %{public}d", jsRotation);
148 switch (jsRotation) {
149 case ROTATION_0:
150 // Fallthrough
151 case ROTATION_90:
152 // Fallthrough
153 case ROTATION_180:
154 // Fallthrough
155 case ROTATION_270:
156 return true;
157 default:
158 MEDIA_ERR_LOG("Invalid rotation value received from application");
159 return false;
160 }
161 return false;
162 }
163 } // namespace
164
165 thread_local napi_ref PhotoOutputNapi::sConstructor_ = nullptr;
166 thread_local sptr<PhotoOutput> PhotoOutputNapi::sPhotoOutput_ = nullptr;
167 thread_local sptr<Surface> PhotoOutputNapi::sPhotoSurface_ = nullptr;
168 thread_local uint32_t PhotoOutputNapi::photoOutputTaskId = CAMERA_PHOTO_OUTPUT_TASKID;
169 thread_local napi_ref PhotoOutputNapi::rawCallback_ = nullptr;
170 static uv_sem_t g_captureStartSem;
171 static bool g_isSemInited;
172 static std::mutex g_photoImageMutex;
173 static int32_t g_captureId;
174
PhotoListener(napi_env env,const sptr<Surface> photoSurface,wptr<PhotoOutput> photoOutput)175 PhotoListener::PhotoListener(napi_env env, const sptr<Surface> photoSurface, wptr<PhotoOutput> photoOutput)
176 : ListenerBase(env), photoSurface_(photoSurface), photoOutput_(photoOutput)
177 {
178 if (bufferProcessor_ == nullptr && photoSurface != nullptr) {
179 bufferProcessor_ = std::make_shared<PhotoBufferProcessor>(photoSurface);
180 }
181 if (taskManager_ == nullptr) {
182 constexpr int32_t numThreads = 1;
183 taskManager_ = std::make_shared<DeferredProcessing::TaskManager>("PhotoListener",
184 numThreads, true);
185 }
186 }
187
RawPhotoListener(napi_env env,const sptr<Surface> rawPhotoSurface)188 RawPhotoListener::RawPhotoListener(napi_env env, const sptr<Surface> rawPhotoSurface)
189 : ListenerBase(env), rawPhotoSurface_(rawPhotoSurface)
190 {
191 if (bufferProcessor_ == nullptr && rawPhotoSurface != nullptr) {
192 bufferProcessor_ = std::make_shared<PhotoBufferProcessor>(rawPhotoSurface);
193 }
194 }
195
AuxiliaryPhotoListener(const std::string surfaceName,const sptr<Surface> surface,wptr<PhotoOutput> photoOutput)196 AuxiliaryPhotoListener::AuxiliaryPhotoListener(const std::string surfaceName, const sptr<Surface> surface,
197 wptr<PhotoOutput> photoOutput) : surfaceName_(surfaceName), surface_(surface), photoOutput_(photoOutput)
198 {
199 if (bufferProcessor_ == nullptr && surface != nullptr) {
200 bufferProcessor_ = std::make_shared<PhotoBufferProcessor>(surface);
201 }
202 if (taskManager_ == nullptr) {
203 constexpr int32_t numThreads = 1;
204 taskManager_ = std::make_shared<DeferredProcessing::TaskManager>("AuxiliaryPhotoListener_" + surfaceName,
205 numThreads, true);
206 }
207 }
208
GetCaptureId(sptr<SurfaceBuffer> surfaceBuffer)209 int32_t GetCaptureId(sptr<SurfaceBuffer> surfaceBuffer)
210 {
211 int32_t captureId;
212 int32_t burstSeqId;
213 int32_t invalidSeqenceId = -1;
214 int32_t captureIdMask = 0x0000FFFF;
215 int32_t captureIdShit = 16;
216 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::burstSequenceId, burstSeqId);
217 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
218 if (burstSeqId != invalidSeqenceId) {
219 burstSeqId = ((captureId & captureIdMask) << captureIdShit) | burstSeqId;
220 MEDIA_INFO_LOG("PhotoListener captureId:%{public}d, burstSeqId:%{public}d", captureId, burstSeqId);
221 return burstSeqId;
222 }
223 MEDIA_INFO_LOG("PhotoListener captureId:%{public}d, burstSeqId:%{public}d", captureId, burstSeqId);
224 return captureId;
225 }
226
InitPictureListeners(napi_env env,wptr<PhotoOutput> photoOutput)227 void PictureListener::InitPictureListeners(napi_env env, wptr<PhotoOutput> photoOutput)
228 {
229 if (photoOutput == nullptr) {
230 MEDIA_ERR_LOG("photoOutput is null");
231 return;
232 }
233 SurfaceError ret;
234 string retStr = "";
235 std::string surfaceName = "";
236 if (photoOutput->gainmapSurface_ != nullptr) {
237 surfaceName = CONST_GAINMAP_SURFACE;
238 gainmapImageListener = new (std::nothrow) AuxiliaryPhotoListener(surfaceName, photoOutput->gainmapSurface_,
239 photoOutput);
240 ret = photoOutput->gainmapSurface_->RegisterConsumerListener(
241 (sptr<IBufferConsumerListener>&)gainmapImageListener);
242 retStr = ret != SURFACE_ERROR_OK ? retStr + "[gainmap]" : retStr;
243 }
244 if (photoOutput->deepSurface_ != nullptr) {
245 surfaceName = CONST_DEEP_SURFACE;
246 deepImageListener = new (std::nothrow) AuxiliaryPhotoListener(surfaceName, photoOutput->deepSurface_,
247 photoOutput);
248 ret = photoOutput->deepSurface_->RegisterConsumerListener(
249 (sptr<IBufferConsumerListener>&)deepImageListener);
250 retStr = ret != SURFACE_ERROR_OK ? retStr + "[deep]" : retStr;
251 }
252 if (photoOutput->exifSurface_ != nullptr) {
253 surfaceName = CONST_EXIF_SURFACE;
254 exifImageListener = new (std::nothrow) AuxiliaryPhotoListener(surfaceName, photoOutput->exifSurface_,
255 photoOutput);
256 ret = photoOutput->exifSurface_->RegisterConsumerListener(
257 (sptr<IBufferConsumerListener>&)exifImageListener);
258 retStr = ret != SURFACE_ERROR_OK ? retStr + "[exif]" : retStr;
259 }
260 if (photoOutput->debugSurface_ != nullptr) {
261 surfaceName = CONST_DEBUG_SURFACE;
262 debugImageListener = new (std::nothrow) AuxiliaryPhotoListener(surfaceName, photoOutput->debugSurface_,
263 photoOutput);
264 ret = photoOutput->debugSurface_->RegisterConsumerListener(
265 (sptr<IBufferConsumerListener>&)debugImageListener);
266 retStr = ret != SURFACE_ERROR_OK ? retStr + "[debug]" : retStr;
267 }
268 if (retStr != "") {
269 MEDIA_ERR_LOG("register surface consumer listener failed! type = %{public}s", retStr.c_str());
270 }
271 }
272
DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer,sptr<SurfaceBuffer> surfaceBuffer) const273 void AuxiliaryPhotoListener::DeepCopyBuffer(
274 sptr<SurfaceBuffer> newSurfaceBuffer, sptr<SurfaceBuffer> surfaceBuffer) const
275 {
276 MEDIA_INFO_LOG("PhotoListener::DeepCopyBuffer w=%{public}d, h=%{public}d, f=%{public}d",
277 surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight(), surfaceBuffer->GetFormat());
278 BufferRequestConfig requestConfig = {
279 .width = surfaceBuffer->GetWidth(),
280 .height = surfaceBuffer->GetHeight(),
281 .strideAlignment = 0x8, // default stride is 8 Bytes.
282 .format = surfaceBuffer->GetFormat(),
283 .usage = surfaceBuffer->GetUsage(),
284 .timeout = 0,
285 .colorGamut = surfaceBuffer->GetSurfaceBufferColorGamut(),
286 .transform = surfaceBuffer->GetSurfaceBufferTransform(),
287 };
288 auto allocErrorCode = newSurfaceBuffer->Alloc(requestConfig);
289 MEDIA_INFO_LOG("SurfaceBuffer alloc ret: %d", allocErrorCode);
290 if (memcpy_s(newSurfaceBuffer->GetVirAddr(), newSurfaceBuffer->GetSize(),
291 surfaceBuffer->GetVirAddr(), surfaceBuffer->GetSize()) != EOK) {
292 MEDIA_ERR_LOG("PhotoListener memcpy_s failed");
293 }
294 }
295
ExecuteDeepyCopySurfaceBuffer()296 void AuxiliaryPhotoListener::ExecuteDeepyCopySurfaceBuffer()
297 {
298 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto ExecuteDeepyCopySurfaceBuffer surfaceName = %{public}s",
299 surfaceName_.c_str());
300 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
301 int32_t fence = -1;
302 int64_t timestamp;
303 OHOS::Rect damage;
304 SurfaceError surfaceRet = surface_->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
305 if (surfaceRet != SURFACE_ERROR_OK) {
306 MEDIA_ERR_LOG("AuxiliaryPhotoListener Failed to acquire surface buffer");
307 return;
308 }
309 // deep copy buffer
310 sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
311 DeepCopyBuffer(newSurfaceBuffer, surfaceBuffer);
312 BufferHandle* bufferHandle = newSurfaceBuffer->GetBufferHandle();
313 if (bufferHandle == nullptr) {
314 MEDIA_ERR_LOG("invalid bufferHandle");
315 }
316 newSurfaceBuffer->Map();
317 if (surfaceName_ == CONST_EXIF_SURFACE) {
318 int32_t dataSize = 0;
319 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::dataSize, dataSize);
320 sptr<BufferExtraData> extraData = new BufferExtraDataImpl();
321 extraData->ExtraSet("exifDataSize", dataSize);
322 newSurfaceBuffer->SetExtraData(extraData);
323 MEDIA_INFO_LOG("AuxiliaryPhotoListener exifDataSize = %{public}d", dataSize);
324 }
325 int32_t captureId = GetCaptureId(surfaceBuffer);
326 MEDIA_INFO_LOG("AuxiliaryPhotoListener surfaceName_ = %{public}s w=%{public}d, h=%{public}d, f=%{public}d"
327 "captureId=%{public}d", surfaceName_.c_str(), newSurfaceBuffer->GetWidth(),
328 newSurfaceBuffer->GetHeight(), newSurfaceBuffer->GetFormat(), captureId);
329 surface_->ReleaseBuffer(surfaceBuffer, -1);
330 {
331 std::lock_guard<std::mutex> lock(g_photoImageMutex);
332 auto photoOutput = photoOutput_.promote();
333 if (photoOutput->caputreIdAuxiliaryCountMap_.count(captureId)) {
334 int32_t auxiliaryCount = photoOutput->caputreIdAuxiliaryCountMap_[captureId];
335 int32_t expectCount = photoOutput->caputreIdCountMap_[captureId];
336 if (auxiliaryCount == -1 || (expectCount != 0 && auxiliaryCount == expectCount)) {
337 MEDIA_INFO_LOG("AuxiliaryPhotoListener ReleaseBuffer, captureId=%{public}d", captureId);
338 return;
339 }
340 }
341 photoOutput->caputreIdAuxiliaryCountMap_[captureId]++;
342 switch (SurfaceTypeHelper.ToEnum(surfaceName_)) {
343 case SurfaceType::GAINMAP_SURFACE: {
344 photoOutput->gainmapSurfaceBuffer_ = newSurfaceBuffer;
345 MEDIA_INFO_LOG("AuxiliaryPhotoListener gainmapSurfaceBuffer_, captureId=%{public}d", captureId);
346 } break;
347 case SurfaceType::DEEP_SURFACE: {
348 photoOutput->deepSurfaceBuffer_ = newSurfaceBuffer;
349 MEDIA_INFO_LOG("AuxiliaryPhotoListener deepSurfaceBuffer_, captureId=%{public}d", captureId);
350 } break;
351 case SurfaceType::EXIF_SURFACE: {
352 photoOutput->exifSurfaceBuffer_ = newSurfaceBuffer;
353 MEDIA_INFO_LOG("AuxiliaryPhotoListener exifSurfaceBuffer_, captureId=%{public}d", captureId);
354 } break;
355 case SurfaceType::DEBUG_SURFACE: {
356 photoOutput->debugSurfaceBuffer_ = newSurfaceBuffer;
357 MEDIA_INFO_LOG("AuxiliaryPhotoListener debugSurfaceBuffer_, captureId=%{public}d", captureId);
358 } break;
359 default:
360 break;
361 }
362 MEDIA_INFO_LOG("AuxiliaryPhotoListener auxiliaryPhotoCount = %{public}d, captureCount = %{public}d, "
363 "surfaceName=%{public}s, captureId=%{public}d",
364 photoOutput->caputreIdAuxiliaryCountMap_[captureId], photoOutput->caputreIdCountMap_[captureId],
365 surfaceName_.c_str(), captureId);
366 if (photoOutput->caputreIdCountMap_[captureId] != 0 &&
367 photoOutput->caputreIdAuxiliaryCountMap_[captureId] == photoOutput->caputreIdCountMap_[captureId]) {
368 uint32_t handle = photoOutput->caputreIdHandleMap_[captureId];
369 MEDIA_INFO_LOG("AuxiliaryPhotoListener StopMonitor, surfaceName=%{public}s, handle = %{public}d, "
370 "captureId = %{public}d",
371 surfaceName_.c_str(), handle, captureId);
372 DeferredProcessing::GetGlobalWatchdog().DoTimeout(handle);
373 DeferredProcessing::GetGlobalWatchdog().StopMonitor(handle);
374 photoOutput->caputreIdAuxiliaryCountMap_[captureId] = -1;
375 MEDIA_INFO_LOG("AuxiliaryPhotoListener caputreIdAuxiliaryCountMap_ = -1");
376 }
377 MEDIA_INFO_LOG("AuxiliaryPhotoListener auxiliaryPhotoCount = %{public}d, captureCount = %{public}d, "
378 "surfaceName=%{public}s, captureId=%{public}d",
379 photoOutput->caputreIdAuxiliaryCountMap_[captureId], photoOutput->caputreIdCountMap_[captureId],
380 surfaceName_.c_str(), captureId);
381 }
382 }
383
OnBufferAvailable()384 void AuxiliaryPhotoListener::OnBufferAvailable()
385 {
386 CAMERA_SYNC_TRACE;
387 MEDIA_INFO_LOG("AuxiliaryPhotoListener::OnBufferAvailable is called, surfaceName=%{public}s", surfaceName_.c_str());
388 if (!surface_) {
389 MEDIA_ERR_LOG("AuxiliaryPhotoListener napi photoSurface_ is null");
390 return;
391 }
392 taskManager_->SubmitTask([this]() {
393 this->ExecuteDeepyCopySurfaceBuffer();
394 });
395 MEDIA_INFO_LOG("AuxiliaryPhotoListener::OnBufferAvailable is end, surfaceName=%{public}s", surfaceName_.c_str());
396 }
397
GetAuxiliaryPhotoCount(sptr<SurfaceBuffer> surfaceBuffer)398 int32_t PhotoListener::GetAuxiliaryPhotoCount(sptr<SurfaceBuffer> surfaceBuffer)
399 {
400 int32_t auxiliaryCount;
401 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::imageCount, auxiliaryCount);
402 MEDIA_INFO_LOG("PhotoListener auxiliaryCount:%{public}d", auxiliaryCount);
403 return auxiliaryCount;
404 }
405
CreateCameraPhotoProxy(sptr<SurfaceBuffer> surfaceBuffer)406 sptr<CameraPhotoProxy> PhotoListener::CreateCameraPhotoProxy(sptr<SurfaceBuffer> surfaceBuffer)
407 {
408 int32_t isDegradedImage;
409 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::isDegradedImage, isDegradedImage);
410 MEDIA_INFO_LOG("PhotoListener CreateCameraPhotoProxy isDegradedImage:%{public}d", isDegradedImage);
411 int64_t imageId = 0;
412 int32_t deferredProcessingType;
413 int32_t captureId;
414 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::imageId, imageId);
415 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredProcessingType, deferredProcessingType);
416 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
417 MEDIA_INFO_LOG("PhotoListener CreateCameraPhotoProxy imageId:%{public}" PRId64 ", "
418 "deferredProcessingType:%{public}d, captureId = %{public}d", imageId, deferredProcessingType, captureId);
419 // get buffer handle and photo info
420 int32_t photoWidth;
421 int32_t photoHeight;
422 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, photoWidth);
423 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, photoHeight);
424 uint64_t size = static_cast<uint64_t>(surfaceBuffer->GetSize());
425 int32_t extraDataSize = 0;
426 auto res = surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::dataSize, extraDataSize);
427 if (res != 0) {
428 MEDIA_INFO_LOG("ExtraGet dataSize error %{public}d", res);
429 } else if (extraDataSize <= 0) {
430 MEDIA_INFO_LOG("ExtraGet dataSize Ok, but size <= 0");
431 } else if (static_cast<uint64_t>(extraDataSize) > size) {
432 MEDIA_INFO_LOG("ExtraGet dataSize Ok,but dataSize %{public}d is bigger than bufferSize %{public}" PRIu64,
433 extraDataSize, size);
434 } else {
435 MEDIA_INFO_LOG("ExtraGet dataSize %{public}d", extraDataSize);
436 size = static_cast<uint64_t>(extraDataSize);
437 }
438 int32_t deferredImageFormat = 0;
439 res = surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredImageFormat, deferredImageFormat);
440 bool isHighQuality = (isDegradedImage == 0);
441 MEDIA_INFO_LOG("PhotoListener CreateCameraPhotoProxy deferredImageFormat:%{public}d, isHighQuality = %{public}d, "
442 "size:%{public}" PRId64, deferredImageFormat, isHighQuality, size);
443 sptr<CameraPhotoProxy> photoProxy = new(std::nothrow) CameraPhotoProxy(
444 nullptr, deferredImageFormat, photoWidth, photoHeight, isHighQuality, captureId);
445 std::string imageIdStr = std::to_string(imageId);
446 photoProxy->SetDeferredAttrs(imageIdStr, deferredProcessingType, size, deferredImageFormat);
447 return photoProxy;
448 }
449
ExecuteDeepyCopySurfaceBuffer()450 void PhotoListener::ExecuteDeepyCopySurfaceBuffer()
451 {
452 auto photoOutput = photoOutput_.promote();
453 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
454 int32_t fence = -1;
455 int64_t timestamp;
456 OHOS::Rect damage;
457 SurfaceError surfaceRet = photoSurface_->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
458 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 0");
459 if (surfaceRet != SURFACE_ERROR_OK) {
460 MEDIA_ERR_LOG("PhotoListener Failed to acquire surface buffer");
461 return;
462 }
463 {
464 std::lock_guard<std::mutex> lock(g_photoImageMutex);
465 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 1");
466 int32_t auxiliaryCount = GetAuxiliaryPhotoCount(surfaceBuffer);
467 int32_t captureId = GetCaptureId(surfaceBuffer);
468 photoOutput->caputreIdCountMap_[captureId] = auxiliaryCount;
469 photoOutput->caputreIdAuxiliaryCountMap_[captureId]++;
470 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 2 captureId = %{public}d", captureId);
471 sptr<CameraPhotoProxy> photoProxy = CreateCameraPhotoProxy(surfaceBuffer);
472 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 3");
473 if (!photoProxy) {
474 MEDIA_ERR_LOG("photoProxy is nullptr");
475 return;
476 }
477 // deep copy buffer
478 sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
479 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 4");
480 DeepCopyBuffer(newSurfaceBuffer, surfaceBuffer);
481 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 5");
482 photoSurface_->ReleaseBuffer(surfaceBuffer, -1);
483 BufferHandle* bufferHandle = newSurfaceBuffer->GetBufferHandle();
484 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 6");
485 if (bufferHandle == nullptr) {
486 MEDIA_ERR_LOG("invalid bufferHandle");
487 return;
488 }
489 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 7");
490 newSurfaceBuffer->Map();
491 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 8");
492 if (photoProxy->isHighQuality_ && (callbackFlag_ & CAPTURE_PHOTO) != 0) {
493 UpdateMainPictureStageOneJSCallback(surfaceBuffer, timestamp);
494 return;
495 }
496 photoProxy->bufferHandle_ = bufferHandle;
497 std::unique_ptr<Media::Picture> picture = Media::Picture::Create(newSurfaceBuffer);
498 if (!picture) {
499 MEDIA_ERR_LOG("picture is nullptr");
500 return;
501 }
502 Media::ImageInfo imageInfo;
503 if (picture->GetMainPixel()) {
504 picture->GetMainPixel()->GetImageInfo(imageInfo);
505 }
506 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto GetMainPixel w=%{public}d, h=%{public}d, f=%{public}d",
507 imageInfo.size.width, imageInfo.size.height, imageInfo.pixelFormat);
508 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto MainSurface w=%{public}d, h=%{public}d, f=%{public}d",
509 newSurfaceBuffer->GetWidth(), newSurfaceBuffer->GetHeight(), newSurfaceBuffer->GetFormat());
510 photoOutput->caputreIdPictureMap_[captureId] = std::move(picture);
511 photoOutput->photoProxy_ = photoProxy;
512 uint32_t pictureHandle;
513 constexpr uint32_t delayMilli = 1 * 1000;
514 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto GetGlobalWatchdog StartMonitor, captureId=%{public}d",
515 captureId);
516 DeferredProcessing::GetGlobalWatchdog().StartMonitor(pictureHandle, delayMilli,
517 [this, captureId, timestamp](uint32_t handle) {
518 MEDIA_INFO_LOG("PhotoListener PhotoListener-Watchdog executed, handle: %{public}d, "
519 "captureId=%{public}d", static_cast<int>(handle), captureId);
520 AssembleAuxiliaryPhoto(timestamp, captureId);
521 auto photoOutput = photoOutput_.promote();
522 if (photoOutput) {
523 photoOutput->caputreIdAuxiliaryCountMap_[captureId] = -1;
524 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto caputreIdAuxiliaryCountMap_ = -1, "
525 "captureId=%{public}d", captureId);
526 }
527 });
528 photoOutput->caputreIdHandleMap_[captureId] = pictureHandle;
529 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto, pictureHandle: %{public}d, captureId=%{public}d "
530 "caputreIdCountMap = %{public}d, caputreIdAuxiliaryCountMap = %{public}d",
531 pictureHandle, captureId, photoOutput->caputreIdCountMap_[captureId],
532 photoOutput->caputreIdAuxiliaryCountMap_[captureId]);
533 if (photoOutput->caputreIdCountMap_[captureId] != 0 &&
534 photoOutput->caputreIdAuxiliaryCountMap_[captureId] == photoOutput->caputreIdCountMap_[captureId]) {
535 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto auxiliaryCount is complete, StopMonitor DoTimeout "
536 "handle = %{public}d, captureId = %{public}d", pictureHandle, captureId);
537 DeferredProcessing::GetGlobalWatchdog().DoTimeout(pictureHandle);
538 DeferredProcessing::GetGlobalWatchdog().StopMonitor(pictureHandle);
539 }
540 MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto end");
541 }
542 }
OnBufferAvailable()543 void PhotoListener::OnBufferAvailable()
544 {
545 CAMERA_SYNC_TRACE;
546 MEDIA_INFO_LOG("PhotoListener::OnBufferAvailable is called");
547 if (!photoSurface_) {
548 MEDIA_ERR_LOG("photoOutput napi photoSurface_ is null");
549 return;
550 }
551 auto photoOutput = photoOutput_.promote();
552 if (photoOutput->IsYuvOrHeifPhoto()) {
553 taskManager_->SubmitTask([this]() {
554 ExecuteDeepyCopySurfaceBuffer();
555 });
556 } else {
557 UpdateJSCallbackAsync(photoSurface_);
558 }
559 MEDIA_INFO_LOG("PhotoListener::OnBufferAvailable is called");
560 }
561
UpdatePictureJSCallback(const string uri,int32_t cameraShotType,const std::string burstKey) const562 void PhotoListener::UpdatePictureJSCallback(const string uri, int32_t cameraShotType, const std::string burstKey) const
563 {
564 MEDIA_INFO_LOG("PhotoListener:UpdatePictureJSCallback called");
565 uv_loop_s* loop = nullptr;
566 napi_get_uv_event_loop(env_, &loop);
567 if (!loop) {
568 MEDIA_ERR_LOG("PhotoListenerInfo:UpdateJSCallbackAsync() failed to get event loop");
569 return;
570 }
571 uv_work_t* work = new (std::nothrow) uv_work_t;
572 if (!work) {
573 MEDIA_ERR_LOG("PhotoListenerInfo:UpdateJSCallbackAsync() failed to allocate work");
574 return;
575 }
576 std::unique_ptr<PhotoListenerInfo> callbackInfo = std::make_unique<PhotoListenerInfo>(nullptr, this);
577 callbackInfo->uri = uri;
578 callbackInfo->cameraShotType = cameraShotType;
579 callbackInfo->burstKey = burstKey;
580 work->data = callbackInfo.get();
581 int ret = uv_queue_work_with_qos(
582 loop, work, [](uv_work_t* work) {},
583 [](uv_work_t* work, int status) {
584 PhotoListenerInfo* callbackInfo = reinterpret_cast<PhotoListenerInfo*>(work->data);
585 if (callbackInfo && callbackInfo->listener_) {
586 MEDIA_INFO_LOG("ExecutePhotoAsset picture");
587 napi_value result[ARGS_TWO] = { nullptr, nullptr };
588 napi_value retVal;
589 napi_get_undefined(callbackInfo->listener_->env_, &result[PARAM0]);
590 napi_get_undefined(callbackInfo->listener_->env_, &result[PARAM1]);
591 result[PARAM1] = Media::MediaLibraryCommNapi::CreatePhotoAssetNapi(callbackInfo->listener_->env_,
592 callbackInfo->uri, callbackInfo->cameraShotType, callbackInfo->burstKey);
593 MEDIA_INFO_LOG("UpdatePictureJSCallback result %{public}s, type %{public}d, burstKey %{public}s",
594 callbackInfo->uri.c_str(), callbackInfo->cameraShotType, callbackInfo->burstKey.c_str());
595 ExecuteCallbackNapiPara callbackPara {
596 .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
597 callbackInfo->listener_->ExecuteCallback(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callbackPara);
598 MEDIA_INFO_LOG("PhotoListener:UpdateJSCallbackAsync() complete");
599 callbackInfo->listener_ = nullptr;
600 delete callbackInfo;
601 }
602 delete work;
603 },
604 uv_qos_user_initiated);
605 if (ret) {
606 MEDIA_ERR_LOG("RawPhotoListener:UpdateJSCallbackAsync() failed to execute work");
607 delete work;
608 } else {
609 callbackInfo.release();
610 }
611 }
612
UpdateMainPictureStageOneJSCallback(sptr<SurfaceBuffer> surfaceBuffer,int64_t timestamp) const613 void PhotoListener::UpdateMainPictureStageOneJSCallback(sptr<SurfaceBuffer> surfaceBuffer, int64_t timestamp) const
614 {
615 MEDIA_INFO_LOG("PhotoListener:UpdateMainPictureStageOneJSCallback called");
616 uv_loop_s* loop = nullptr;
617 napi_get_uv_event_loop(env_, &loop);
618 if (!loop) {
619 MEDIA_ERR_LOG("PhotoListenerInfo:UpdateMainPictureStageOneJSCallback() failed to get event loop");
620 return;
621 }
622 uv_work_t* work = new (std::nothrow) uv_work_t;
623 if (!work) {
624 MEDIA_ERR_LOG("PhotoListenerInfo:UpdateMainPictureStageOneJSCallback() failed to allocate work");
625 return;
626 }
627 std::unique_ptr<PhotoListenerInfo> callbackInfo = std::make_unique<PhotoListenerInfo>(nullptr, this);
628 callbackInfo->surfaceBuffer = surfaceBuffer;
629 callbackInfo->timestamp = timestamp;
630 work->data = callbackInfo.get();
631 int ret = uv_queue_work_with_qos(
632 loop, work, [](uv_work_t* work) {},
633 [](uv_work_t* work, int status) {
634 PhotoListenerInfo* callbackInfo = reinterpret_cast<PhotoListenerInfo*>(work->data);
635 if (callbackInfo && callbackInfo->listener_) {
636 MEDIA_INFO_LOG("ExecutePhotoAsset picture");
637 sptr<SurfaceBuffer> surfaceBuffer = callbackInfo->surfaceBuffer;
638 int64_t timestamp = callbackInfo->timestamp;
639 callbackInfo->listener_->ExecutePhoto(surfaceBuffer, timestamp);
640 callbackInfo->listener_ = nullptr;
641 delete callbackInfo;
642 }
643 delete work;
644 },
645 uv_qos_user_initiated);
646 if (ret) {
647 MEDIA_ERR_LOG("RawPhotoListener:UpdateJSCallbackAsync() failed to execute work");
648 delete work;
649 } else {
650 callbackInfo.release();
651 }
652 }
653
LoggingSurfaceBufferInfo(sptr<SurfaceBuffer> buffer,std::string bufName)654 inline void LoggingSurfaceBufferInfo(sptr<SurfaceBuffer> buffer, std::string bufName)
655 {
656 if (buffer) {
657 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto %{public}s w=%{public}d, h=%{public}d, f=%{public}d", bufName.c_str(),
658 buffer->GetWidth(), buffer->GetHeight(), buffer->GetFormat());
659 }
660 };
661
GetLocationBySettings(std::shared_ptr<PhotoCaptureSetting> settings)662 std::shared_ptr<Location> GetLocationBySettings(std::shared_ptr<PhotoCaptureSetting> settings)
663 {
664 auto location = make_shared<Location>();
665 if (settings) {
666 settings->GetLocation(location);
667 MEDIA_INFO_LOG("GetLocationBySettings latitude:%{private}f, longitude:%{private}f",
668 location->latitude, location->longitude);
669 } else {
670 MEDIA_ERR_LOG("GetLocationBySettings failed!");
671 }
672 return location;
673 }
674
AssembleAuxiliaryPhoto(int64_t timestamp,int32_t captureId)675 void PhotoListener::AssembleAuxiliaryPhoto(int64_t timestamp, int32_t captureId) __attribute__((no_sanitize("cfi")))
676 {
677 auto photoOutput = photoOutput_.promote();
678 if (photoOutput && photoOutput->GetSession()) {
679 auto settings = photoOutput->GetDefaultCaptureSetting();
680 if (settings) {
681 auto location = make_shared<Location>();
682 settings->GetLocation(location);
683 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto GetLocation latitude:%{public}f, longitude:%{public}f",
684 location->latitude, location->longitude);
685 photoOutput->photoProxy_->SetLocation(location->latitude, location->longitude);
686 }
687 std::unique_ptr<Media::Picture> picture = std::move(photoOutput->caputreIdPictureMap_[captureId]);
688 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto picture %{public}d", picture != nullptr);
689 if (photoOutput->exifSurfaceBuffer_ && picture) {
690 LoggingSurfaceBufferInfo(photoOutput->exifSurfaceBuffer_, "exifSurfaceBuffer");
691 picture->SetExifMetadata(photoOutput->exifSurfaceBuffer_);
692 }
693 if (photoOutput->gainmapSurfaceBuffer_ && picture) {
694 std::unique_ptr<Media::AuxiliaryPicture> uniptr = Media::AuxiliaryPicture::Create(
695 photoOutput->gainmapSurfaceBuffer_, Media::AuxiliaryPictureType::GAINMAP);
696 std::shared_ptr<Media::AuxiliaryPicture> picturePtr = std::move(uniptr);
697 LoggingSurfaceBufferInfo(photoOutput->gainmapSurfaceBuffer_, "gainmapSurfaceBuffer");
698 picture->SetAuxiliaryPicture(picturePtr);
699 photoOutput->gainmapSurfaceBuffer_ = nullptr;
700 }
701 if (photoOutput->deepSurfaceBuffer_ && picture) {
702 std::unique_ptr<Media::AuxiliaryPicture> uniptr = Media::AuxiliaryPicture::Create(
703 photoOutput->deepSurfaceBuffer_, Media::AuxiliaryPictureType::DEPTH_MAP);
704 std::shared_ptr<Media::AuxiliaryPicture> picturePtr = std::move(uniptr);
705 LoggingSurfaceBufferInfo(photoOutput->deepSurfaceBuffer_, "deepSurfaceBuffer");
706 picture->SetAuxiliaryPicture(picturePtr);
707 }
708 if (photoOutput->debugSurfaceBuffer_ && picture) {
709 LoggingSurfaceBufferInfo(photoOutput->debugSurfaceBuffer_, "debugSurfaceBuffer");
710 picture->SetMaintenanceData(photoOutput->debugSurfaceBuffer_);
711 }
712 MEDIA_INFO_LOG("AssembleAuxiliaryPhoto captureId %{public}d", captureId);
713 if (picture) {
714 std::string uri;
715 int32_t cameraShotType;
716 std::string burstKey = "";
717 photoOutput->GetSession()->CreateMediaLibrary(std::move(picture), photoOutput->photoProxy_,
718 uri, cameraShotType, burstKey, timestamp);
719 MEDIA_INFO_LOG("CreateMediaLibrary result %{public}s, type %{public}d", uri.c_str(), cameraShotType);
720 UpdatePictureJSCallback(uri, cameraShotType, burstKey);
721 } else {
722 MEDIA_ERR_LOG("CreateMediaLibrary picture is nullptr");
723 }
724 }
725 }
726
ExecutePhoto(sptr<SurfaceBuffer> surfaceBuffer,int64_t timestamp) const727 void PhotoListener::ExecutePhoto(sptr<SurfaceBuffer> surfaceBuffer, int64_t timestamp) const
728 {
729 MEDIA_INFO_LOG("ExecutePhoto");
730 napi_value result[ARGS_TWO] = {nullptr, nullptr};
731 napi_value retVal;
732 napi_value mainImage = nullptr;
733 std::shared_ptr<Media::NativeImage> image = std::make_shared<Media::NativeImage>(surfaceBuffer,
734 bufferProcessor_, timestamp);
735 napi_get_undefined(env_, &result[PARAM0]);
736 napi_get_undefined(env_, &result[PARAM1]);
737 mainImage = Media::ImageNapi::Create(env_, image);
738 if (mainImage == nullptr) {
739 MEDIA_ERR_LOG("ImageNapi Create failed");
740 napi_get_undefined(env_, &mainImage);
741 }
742 result[PARAM1] = PhotoNapi::CreatePhoto(env_, mainImage);
743 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
744 ExecuteCallback(CONST_CAPTURE_PHOTO_AVAILABLE, callbackNapiPara);
745 photoSurface_->ReleaseBuffer(surfaceBuffer, -1);
746 }
747
ExecuteDeferredPhoto(sptr<SurfaceBuffer> surfaceBuffer) const748 void PhotoListener::ExecuteDeferredPhoto(sptr<SurfaceBuffer> surfaceBuffer) const
749 {
750 MEDIA_INFO_LOG("ExecuteDeferredPhoto");
751 napi_value result[ARGS_TWO] = {nullptr, nullptr};
752 napi_value retVal;
753
754 BufferHandle* bufferHandle = surfaceBuffer->GetBufferHandle();
755 int64_t imageId;
756 int32_t deferredProcessingType;
757 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::imageId, imageId);
758 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredProcessingType, deferredProcessingType);
759 MEDIA_INFO_LOG("PhotoListener ExecuteDeferredPhoto imageId:%{public}" PRId64 ", deferredProcessingType:%{public}d",
760 imageId, deferredProcessingType);
761
762 // create pixelMap to encode
763 int32_t thumbnailWidth;
764 int32_t thumbnailHeight;
765 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, thumbnailWidth);
766 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, thumbnailHeight);
767 MEDIA_INFO_LOG("thumbnailWidth:%{public}d, thumbnailHeight: %{public}d", thumbnailWidth, thumbnailHeight);
768
769 MEDIA_DEBUG_LOG("w:%{public}d, h:%{public}d, s:%{public}d, fd:%{public}d, size: %{public}d, format: %{public}d",
770 bufferHandle->width, bufferHandle->height, bufferHandle->stride, bufferHandle->fd, bufferHandle->size,
771 bufferHandle->format);
772
773 napi_get_undefined(env_, &result[PARAM0]);
774 napi_get_undefined(env_, &result[PARAM1]);
775
776 // deep copy buffer
777 sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
778 DeepCopyBuffer(newSurfaceBuffer, surfaceBuffer);
779 BufferHandle *newBufferHandle = CameraCloneBufferHandle(newSurfaceBuffer->GetBufferHandle());
780 if (newBufferHandle == nullptr) {
781 napi_value errorCode;
782 napi_create_int32(env_, CameraErrorCode::INVALID_ARGUMENT, &errorCode);
783 result[PARAM0] = errorCode;
784 MEDIA_ERR_LOG("invalid bufferHandle");
785 }
786
787 // call js function
788 sptr<DeferredPhotoProxy> deferredPhotoProxy;
789 std::string imageIdStr = std::to_string(imageId);
790 deferredPhotoProxy = new(std::nothrow) DeferredPhotoProxy(newBufferHandle, imageIdStr, deferredProcessingType,
791 thumbnailWidth, thumbnailHeight);
792 if (deferredPhotoProxy == nullptr) {
793 napi_value errorCode;
794 napi_create_int32(env_, CameraErrorCode::SERVICE_FATL_ERROR, &errorCode);
795 result[PARAM0] = errorCode;
796 MEDIA_ERR_LOG("failed to new deferredPhotoProxy!");
797 }
798 result[PARAM1] = DeferredPhotoProxyNapi::CreateDeferredPhotoProxy(env_, deferredPhotoProxy);
799
800 ExecuteCallbackNapiPara callbackPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
801 ExecuteCallback(CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE, callbackPara);
802
803 // return buffer to buffer queue
804 photoSurface_->ReleaseBuffer(surfaceBuffer, -1);
805 }
806
DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer,sptr<SurfaceBuffer> surfaceBuffer) const807 void PhotoListener::DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer, sptr<SurfaceBuffer> surfaceBuffer) const
808 {
809 BufferRequestConfig requestConfig = {
810 .width = surfaceBuffer->GetWidth(),
811 .height = surfaceBuffer->GetHeight(),
812 .strideAlignment = 0x8, // default stride is 8 Bytes.
813 .format = surfaceBuffer->GetFormat(),
814 .usage = surfaceBuffer->GetUsage(),
815 .timeout = 0,
816 .colorGamut = surfaceBuffer->GetSurfaceBufferColorGamut(),
817 .transform = surfaceBuffer->GetSurfaceBufferTransform(),
818 };
819 auto allocErrorCode = newSurfaceBuffer->Alloc(requestConfig);
820 MEDIA_INFO_LOG("SurfaceBuffer alloc ret: %d", allocErrorCode);
821 if (memcpy_s(newSurfaceBuffer->GetVirAddr(), newSurfaceBuffer->GetSize(),
822 surfaceBuffer->GetVirAddr(), surfaceBuffer->GetSize()) != EOK) {
823 MEDIA_ERR_LOG("PhotoListener memcpy_s failed");
824 }
825 }
826
ExecutePhotoAsset(sptr<SurfaceBuffer> surfaceBuffer,bool isHighQuality,int64_t timestamp) const827 void PhotoListener::ExecutePhotoAsset(sptr<SurfaceBuffer> surfaceBuffer, bool isHighQuality, int64_t timestamp) const
828 {
829 CameraReportDfxUtils::GetInstance()->SetPrepareProxyStartInfo();
830 CAMERA_SYNC_TRACE;
831 MEDIA_INFO_LOG("ExecutePhotoAsset");
832 napi_value result[ARGS_TWO] = { nullptr, nullptr };
833 napi_value retVal;
834 napi_get_undefined(env_, &result[PARAM0]);
835 napi_get_undefined(env_, &result[PARAM1]);
836 // deep copy buffer
837 sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
838 DeepCopyBuffer(newSurfaceBuffer, surfaceBuffer);
839 BufferHandle* bufferHandle = newSurfaceBuffer->GetBufferHandle();
840 if (bufferHandle == nullptr) {
841 napi_value errorCode;
842 napi_create_int32(env_, CameraErrorCode::INVALID_ARGUMENT, &errorCode);
843 result[PARAM0] = errorCode;
844 MEDIA_ERR_LOG("invalid bufferHandle");
845 }
846 newSurfaceBuffer->Map();
847 auto photoOutput = photoOutput_.promote();
848 string uri = "";
849 int32_t cameraShotType = 0;
850
851 std::string burstKey = "";
852 CreateMediaLibrary(surfaceBuffer, bufferHandle, isHighQuality, uri, cameraShotType, burstKey, timestamp);
853 MEDIA_INFO_LOG("CreateMediaLibrary result uri:%{public}s cameraShotType:%{public}d burstKey:%{public}s",
854 uri.c_str(), cameraShotType, burstKey.c_str());
855 result[PARAM1] = Media::MediaLibraryCommNapi::CreatePhotoAssetNapi(env_, uri, cameraShotType, burstKey);
856 ExecuteCallbackNapiPara callbackPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
857 ExecuteCallback(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callbackPara);
858 // return buffer to buffer queue
859 photoSurface_->ReleaseBuffer(surfaceBuffer, -1);
860 }
861
CreateMediaLibrary(sptr<SurfaceBuffer> surfaceBuffer,BufferHandle * bufferHandle,bool isHighQuality,std::string & uri,int32_t & cameraShotType,std::string & burstKey,int64_t timestamp) const862 void PhotoListener::CreateMediaLibrary(sptr<SurfaceBuffer> surfaceBuffer, BufferHandle *bufferHandle,
863 bool isHighQuality, std::string &uri, int32_t &cameraShotType, std::string &burstKey, int64_t timestamp) const
864 {
865 CAMERA_SYNC_TRACE;
866 if (bufferHandle == nullptr) {
867 MEDIA_ERR_LOG("bufferHandle is nullptr");
868 return;
869 }
870 int32_t captureId;
871 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
872 int64_t imageId = 0;
873 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::imageId, imageId);
874 int32_t deferredProcessingType;
875 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredProcessingType, deferredProcessingType);
876 MEDIA_INFO_LOG(
877 "PhotoListener ExecutePhotoAsset captureId:%{public}d "
878 "imageId:%{public}" PRId64 ", deferredProcessingType:%{public}d",
879 captureId, imageId, deferredProcessingType);
880 int32_t photoWidth;
881 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, photoWidth);
882 int32_t photoHeight;
883 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, photoHeight);
884 uint64_t size = static_cast<uint64_t>(surfaceBuffer->GetSize());
885 int32_t extraDataSize = 0;
886 auto res = surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::dataSize, extraDataSize);
887 if (res != 0) {
888 MEDIA_INFO_LOG("ExtraGet dataSize error %{public}d", res);
889 } else if (extraDataSize <= 0) {
890 MEDIA_INFO_LOG("ExtraGet dataSize Ok, but size <= 0");
891 } else if (static_cast<uint64_t>(extraDataSize) > size) {
892 MEDIA_INFO_LOG("ExtraGet dataSize Ok,but dataSize %{public}d is bigger than bufferSize %{public}" PRIu64,
893 extraDataSize, size);
894 } else {
895 MEDIA_INFO_LOG("ExtraGet dataSize %{public}d", extraDataSize);
896 size = static_cast<uint64_t>(extraDataSize);
897 }
898 int32_t deferredImageFormat = 0;
899 res = surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredImageFormat, deferredImageFormat);
900 MEDIA_INFO_LOG("deferredImageFormat:%{public}d, width:%{public}d, height:%{public}d, size:%{public}" PRId64,
901 deferredImageFormat, photoWidth, photoHeight, size);
902 int32_t format = bufferHandle->format;
903 sptr<CameraPhotoProxy> photoProxy;
904 std::string imageIdStr = std::to_string(imageId);
905 photoProxy = new(std::nothrow) CameraPhotoProxy(bufferHandle, format, photoWidth, photoHeight,
906 isHighQuality, captureId);
907 if (photoProxy == nullptr) {
908 return;
909 }
910 photoProxy->SetDeferredAttrs(imageIdStr, deferredProcessingType, size, deferredImageFormat);
911 auto photoOutput = photoOutput_.promote();
912 if (photoOutput && photoOutput->GetSession()) {
913 auto settings = photoOutput->GetDefaultCaptureSetting();
914 if (settings) {
915 auto location = make_shared<Location>();
916 settings->GetLocation(location);
917 photoProxy->SetLocation(location->latitude, location->longitude);
918 }
919 CameraReportDfxUtils::GetInstance()->SetPrepareProxyEndInfo();
920 CameraReportDfxUtils::GetInstance()->SetAddProxyStartInfo();
921 photoOutput->GetSession()->CreateMediaLibrary(photoProxy, uri, cameraShotType, burstKey, timestamp);
922 CameraReportDfxUtils::GetInstance()->SetAddProxyEndInfo();
923 }
924 }
925
UpdateJSCallback(sptr<Surface> photoSurface) const926 void PhotoListener::UpdateJSCallback(sptr<Surface> photoSurface) const
927 {
928 MEDIA_DEBUG_LOG("PhotoListener UpdateJSCallback enter");
929 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
930 int32_t fence = -1;
931 int64_t timestamp;
932 OHOS::Rect damage;
933 SurfaceError surfaceRet = photoSurface->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
934 if (surfaceRet != SURFACE_ERROR_OK) {
935 MEDIA_ERR_LOG("PhotoListener Failed to acquire surface buffer");
936 return;
937 }
938 MEDIA_INFO_LOG("PhotoListener::UpdateJSCallback ts is:%{public}" PRId64, timestamp);
939 int32_t isDegradedImage;
940 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::isDegradedImage, isDegradedImage);
941 MEDIA_INFO_LOG("PhotoListener UpdateJSCallback isDegradedImage:%{public}d", isDegradedImage);
942 if ((callbackFlag_ & CAPTURE_PHOTO_ASSET) != 0) {
943 CameraReportDfxUtils::GetInstance()->SetFirstBufferEndInfo();
944 ExecutePhotoAsset(surfaceBuffer, isDegradedImage == 0, timestamp);
945 } else if (isDegradedImage == 0 && (callbackFlag_ & CAPTURE_PHOTO) != 0) {
946 ExecutePhoto(surfaceBuffer, timestamp);
947 } else if (isDegradedImage != 0 && (callbackFlag_ & CAPTURE_DEFERRED_PHOTO) != 0) {
948 ExecuteDeferredPhoto(surfaceBuffer);
949 } else {
950 MEDIA_INFO_LOG("PhotoListener on error callback");
951 }
952 }
953
UpdateJSCallbackAsync(sptr<Surface> photoSurface) const954 void PhotoListener::UpdateJSCallbackAsync(sptr<Surface> photoSurface) const
955 {
956 MEDIA_DEBUG_LOG("PhotoListener UpdateJSCallbackAsync enter");
957 uv_loop_s* loop = nullptr;
958 napi_get_uv_event_loop(env_, &loop);
959 MEDIA_INFO_LOG("PhotoListener UpdateJSCallbackAsync get loop");
960 if (!loop) {
961 MEDIA_ERR_LOG("PhotoListener:UpdateJSCallbackAsync() failed to get event loop");
962 return;
963 }
964 uv_work_t* work = new (std::nothrow) uv_work_t;
965 if (!work) {
966 MEDIA_ERR_LOG("PhotoListener:UpdateJSCallbackAsync() failed to allocate work");
967 return;
968 }
969 std::unique_ptr<PhotoListenerInfo> callbackInfo = std::make_unique<PhotoListenerInfo>(photoSurface, this);
970 work->data = callbackInfo.get();
971 MEDIA_DEBUG_LOG("PhotoListener UpdateJSCallbackAsync uv_queue_work_with_qos start");
972 int ret = uv_queue_work_with_qos(
973 loop, work, [](uv_work_t* work) {},
974 [](uv_work_t* work, int status) {
975 PhotoListenerInfo* callbackInfo = reinterpret_cast<PhotoListenerInfo*>(work->data);
976 if (callbackInfo) {
977 callbackInfo->listener_->UpdateJSCallback(callbackInfo->photoSurface_);
978 MEDIA_INFO_LOG("PhotoListener:UpdateJSCallbackAsync() complete");
979 callbackInfo->photoSurface_ = nullptr;
980 callbackInfo->listener_ = nullptr;
981 delete callbackInfo;
982 }
983 delete work;
984 },
985 uv_qos_user_initiated);
986 if (ret) {
987 MEDIA_ERR_LOG("PhotoListener:UpdateJSCallbackAsync() failed to execute work");
988 delete work;
989 } else {
990 callbackInfo.release();
991 }
992 }
993
SaveCallback(const std::string eventName,napi_value callback)994 void PhotoListener::SaveCallback(const std::string eventName, napi_value callback)
995 {
996 MEDIA_INFO_LOG("PhotoListener::SaveCallback is called eventName:%{public}s", eventName.c_str());
997 auto eventTypeEnum = PhotoOutputEventTypeHelper.ToEnum(eventName);
998 switch (eventTypeEnum) {
999 case PhotoOutputEventType::CAPTURE_PHOTO_AVAILABLE:
1000 callbackFlag_ |= CAPTURE_PHOTO;
1001 break;
1002 case PhotoOutputEventType::CAPTURE_DEFERRED_PHOTO_AVAILABLE:
1003 callbackFlag_ |= CAPTURE_DEFERRED_PHOTO;
1004 break;
1005 case PhotoOutputEventType::CAPTURE_PHOTO_ASSET_AVAILABLE:
1006 callbackFlag_ |= CAPTURE_PHOTO_ASSET;
1007 break;
1008 default:
1009 MEDIA_ERR_LOG("Incorrect photo callback event type received from JS");
1010 return;
1011 }
1012 auto photoOutput = photoOutput_.promote();
1013 if (photoOutput) {
1014 photoOutput->SetCallbackFlag(callbackFlag_);
1015 } else {
1016 MEDIA_ERR_LOG("cannot get photoOutput");
1017 }
1018 SaveCallbackReference(eventName, callback, false);
1019 }
1020
RemoveCallback(const std::string eventName,napi_value callback)1021 void PhotoListener::RemoveCallback(const std::string eventName, napi_value callback)
1022 {
1023 MEDIA_INFO_LOG("PhotoListener::RemoveCallback is called eventName:%{public}s", eventName.c_str());
1024 if (eventName == CONST_CAPTURE_PHOTO_AVAILABLE) {
1025 callbackFlag_ &= ~CAPTURE_PHOTO;
1026 } else if (eventName == CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE) {
1027 callbackFlag_ &= ~CAPTURE_DEFERRED_PHOTO;
1028 } else if (eventName == CONST_CAPTURE_PHOTO_ASSET_AVAILABLE) {
1029 auto photoOutput = photoOutput_.promote();
1030 if (photoOutput != nullptr) {
1031 photoOutput_->DeferImageDeliveryFor(DeferredDeliveryImageType::DELIVERY_NONE);
1032 }
1033 callbackFlag_ &= ~CAPTURE_PHOTO_ASSET;
1034 }
1035 RemoveCallbackRef(eventName, callback);
1036 }
1037
OnBufferAvailable()1038 void RawPhotoListener::OnBufferAvailable()
1039 {
1040 std::lock_guard<std::mutex> lock(g_photoImageMutex);
1041 CAMERA_SYNC_TRACE;
1042 MEDIA_INFO_LOG("RawPhotoListener::OnBufferAvailable is called");
1043 if (!rawPhotoSurface_) {
1044 MEDIA_ERR_LOG("RawPhotoListener napi rawPhotoSurface_ is null");
1045 return;
1046 }
1047 UpdateJSCallbackAsync(rawPhotoSurface_);
1048 }
1049
ExecuteRawPhoto(sptr<SurfaceBuffer> surfaceBuffer) const1050 void RawPhotoListener::ExecuteRawPhoto(sptr<SurfaceBuffer> surfaceBuffer) const
1051 {
1052 MEDIA_INFO_LOG("ExecuteRawPhoto");
1053 napi_value result[ARGS_TWO] = { nullptr, nullptr };
1054 napi_value retVal;
1055 napi_value rawImage = nullptr;
1056 std::shared_ptr<Media::NativeImage> image = std::make_shared<Media::NativeImage>(surfaceBuffer, bufferProcessor_);
1057 napi_get_undefined(env_, &result[PARAM0]);
1058 napi_get_undefined(env_, &result[PARAM1]);
1059 rawImage = Media::ImageNapi::Create(env_, image);
1060 if (rawImage == nullptr) {
1061 MEDIA_ERR_LOG("ImageNapi Create failed");
1062 napi_get_undefined(env_, &rawImage);
1063 }
1064 result[PARAM1] = PhotoNapi::CreateRawPhoto(env_, rawImage);
1065 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1066 ExecuteCallback(CONST_CAPTURE_PHOTO_AVAILABLE, callbackNapiPara);
1067 rawPhotoSurface_->ReleaseBuffer(surfaceBuffer, -1);
1068 }
1069
UpdateJSCallback(sptr<Surface> rawPhotoSurface) const1070 void RawPhotoListener::UpdateJSCallback(sptr<Surface> rawPhotoSurface) const
1071 {
1072 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
1073 int32_t fence = -1;
1074 int64_t timestamp;
1075 OHOS::Rect damage;
1076 SurfaceError surfaceRet = rawPhotoSurface->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
1077 if (surfaceRet != SURFACE_ERROR_OK) {
1078 MEDIA_ERR_LOG("RawPhotoListener Failed to acquire surface buffer");
1079 return;
1080 }
1081
1082 int32_t isDegradedImage;
1083 surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::isDegradedImage, isDegradedImage);
1084 MEDIA_INFO_LOG("RawPhotoListener UpdateJSCallback isDegradedImage:%{public}d", isDegradedImage);
1085
1086 if (isDegradedImage == 0) {
1087 ExecuteRawPhoto(surfaceBuffer);
1088 } else {
1089 MEDIA_ERR_LOG("RawPhoto not support deferred photo");
1090 }
1091 }
1092
UpdateJSCallbackAsync(sptr<Surface> rawPhotoSurface) const1093 void RawPhotoListener::UpdateJSCallbackAsync(sptr<Surface> rawPhotoSurface) const
1094 {
1095 uv_loop_s* loop = nullptr;
1096 napi_get_uv_event_loop(env_, &loop);
1097 if (!loop) {
1098 MEDIA_ERR_LOG("RawPhotoListener:UpdateJSCallbackAsync() failed to get event loop");
1099 return;
1100 }
1101 uv_work_t* work = new (std::nothrow) uv_work_t;
1102 if (!work) {
1103 MEDIA_ERR_LOG("RawPhotoListener:UpdateJSCallbackAsync() failed to allocate work");
1104 return;
1105 }
1106 std::unique_ptr<RawPhotoListenerInfo> callbackInfo = std::make_unique<RawPhotoListenerInfo>(rawPhotoSurface, this);
1107 work->data = callbackInfo.get();
1108 int ret = uv_queue_work_with_qos(
1109 loop, work, [](uv_work_t* work) {},
1110 [](uv_work_t* work, int status) {
1111 RawPhotoListenerInfo* callbackInfo = reinterpret_cast<RawPhotoListenerInfo*>(work->data);
1112 if (callbackInfo) {
1113 callbackInfo->listener_->UpdateJSCallback(callbackInfo->rawPhotoSurface_);
1114 MEDIA_INFO_LOG("RawPhotoListener:UpdateJSCallbackAsync() complete");
1115 callbackInfo->rawPhotoSurface_ = nullptr;
1116 callbackInfo->listener_ = nullptr;
1117 delete callbackInfo;
1118 }
1119 delete work;
1120 },
1121 uv_qos_user_initiated);
1122 if (ret) {
1123 MEDIA_ERR_LOG("RawPhotoListener:UpdateJSCallbackAsync() failed to execute work");
1124 delete work;
1125 } else {
1126 callbackInfo.release();
1127 }
1128 }
1129
PhotoOutputCallback(napi_env env)1130 PhotoOutputCallback::PhotoOutputCallback(napi_env env) : ListenerBase(env) {}
1131
UpdateJSExecute(uv_work_t * work)1132 void UpdateJSExecute(uv_work_t* work)
1133 {
1134 PhotoOutputCallbackInfo* callbackInfo = reinterpret_cast<PhotoOutputCallbackInfo*>(work->data);
1135 if (callbackInfo) {
1136 if (callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START ||
1137 callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START_WITH_INFO) {
1138 g_captureId = callbackInfo->info_.captureID;
1139 MEDIA_DEBUG_LOG("UpdateJSExecute CAPTURE_START g_captureId:%{public}d", g_captureId);
1140 }
1141 if (callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_FRAME_SHUTTER &&
1142 g_captureId != callbackInfo->info_.captureID) {
1143 uv_sem_wait(&g_captureStartSem);
1144 }
1145 }
1146 }
1147
UpdateJSCallbackAsync(PhotoOutputEventType eventType,const CallbackInfo & info) const1148 void PhotoOutputCallback::UpdateJSCallbackAsync(PhotoOutputEventType eventType, const CallbackInfo &info) const
1149 {
1150 MEDIA_DEBUG_LOG("UpdateJSCallbackAsync is called");
1151 uv_loop_s* loop = nullptr;
1152 napi_get_uv_event_loop(env_, &loop);
1153 if (loop == nullptr) {
1154 MEDIA_ERR_LOG("failed to get event loop or failed to allocate work");
1155 return;
1156 }
1157 uv_work_t* work = new(std::nothrow) uv_work_t;
1158 if (work == nullptr) {
1159 MEDIA_ERR_LOG("UpdateJSCallbackAsync work is null");
1160 return;
1161 }
1162 if (!g_isSemInited) {
1163 uv_sem_init(&g_captureStartSem, 0);
1164 g_isSemInited = true;
1165 }
1166 std::unique_ptr<PhotoOutputCallbackInfo> callbackInfo =
1167 std::make_unique<PhotoOutputCallbackInfo>(eventType, info, shared_from_this());
1168 work->data = callbackInfo.get();
1169 int ret = uv_queue_work_with_qos(loop, work, UpdateJSExecute, [] (uv_work_t* work, int status) {
1170 PhotoOutputCallbackInfo* callbackInfo = reinterpret_cast<PhotoOutputCallbackInfo *>(work->data);
1171 if (callbackInfo) {
1172 auto listener = callbackInfo->listener_.lock();
1173 if (listener) {
1174 listener->UpdateJSCallback(callbackInfo->eventType_, callbackInfo->info_);
1175 if (callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START ||
1176 callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START_WITH_INFO) {
1177 MEDIA_DEBUG_LOG("PhotoOutputEventType::CAPTURE_START work done execute!");
1178 uv_sem_post(&g_captureStartSem);
1179 } else if (callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_FRAME_SHUTTER) {
1180 MEDIA_DEBUG_LOG("PhotoOutputEventType::CAPTURE_FRAME_SHUTTER work done execute!");
1181 uv_sem_destroy(&g_captureStartSem);
1182 g_isSemInited = false;
1183 }
1184 }
1185 delete callbackInfo;
1186 }
1187 delete work;
1188 }, uv_qos_user_initiated);
1189 if (ret) {
1190 MEDIA_ERR_LOG("failed to execute work");
1191 delete work;
1192 } else {
1193 callbackInfo.release();
1194 }
1195 }
1196
OnCaptureStarted(const int32_t captureID) const1197 void PhotoOutputCallback::OnCaptureStarted(const int32_t captureID) const
1198 {
1199 CAMERA_SYNC_TRACE;
1200 MEDIA_DEBUG_LOG("OnCaptureStarted is called!, captureID: %{public}d", captureID);
1201 CallbackInfo info;
1202 info.captureID = captureID;
1203 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_START, info);
1204 }
1205
OnCaptureStarted(const int32_t captureID,uint32_t exposureTime) const1206 void PhotoOutputCallback::OnCaptureStarted(const int32_t captureID, uint32_t exposureTime) const
1207 {
1208 CAMERA_SYNC_TRACE;
1209 MEDIA_DEBUG_LOG("OnCaptureStarted is called!, captureID: %{public}d", captureID);
1210 CallbackInfo info;
1211 info.captureID = captureID;
1212 info.timestamp = exposureTime;
1213 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_START_WITH_INFO, info);
1214 }
1215
OnCaptureEnded(const int32_t captureID,const int32_t frameCount) const1216 void PhotoOutputCallback::OnCaptureEnded(const int32_t captureID, const int32_t frameCount) const
1217 {
1218 CAMERA_SYNC_TRACE;
1219 MEDIA_DEBUG_LOG("OnCaptureEnded is called!, captureID: %{public}d, frameCount: %{public}d",
1220 captureID, frameCount);
1221 CallbackInfo info;
1222 info.captureID = captureID;
1223 info.frameCount = frameCount;
1224 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_END, info);
1225 }
1226
OnFrameShutter(const int32_t captureId,const uint64_t timestamp) const1227 void PhotoOutputCallback::OnFrameShutter(const int32_t captureId, const uint64_t timestamp) const
1228 {
1229 CAMERA_SYNC_TRACE;
1230 MEDIA_DEBUG_LOG(
1231 "OnFrameShutter is called, captureID: %{public}d, timestamp: %{public}" PRIu64, captureId, timestamp);
1232 CallbackInfo info;
1233 info.captureID = captureId;
1234 info.timestamp = timestamp;
1235 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_FRAME_SHUTTER, info);
1236 }
1237
OnFrameShutterEnd(const int32_t captureId,const uint64_t timestamp) const1238 void PhotoOutputCallback::OnFrameShutterEnd(const int32_t captureId, const uint64_t timestamp) const
1239 {
1240 CAMERA_SYNC_TRACE;
1241 MEDIA_DEBUG_LOG(
1242 "OnFrameShutterEnd is called, captureID: %{public}d, timestamp: %{public}" PRIu64, captureId, timestamp);
1243 CallbackInfo info;
1244 info.captureID = captureId;
1245 info.timestamp = timestamp;
1246 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_FRAME_SHUTTER_END, info);
1247 }
1248
OnCaptureReady(const int32_t captureId,const uint64_t timestamp) const1249 void PhotoOutputCallback::OnCaptureReady(const int32_t captureId, const uint64_t timestamp) const
1250 {
1251 CAMERA_SYNC_TRACE;
1252 MEDIA_DEBUG_LOG(
1253 "OnCaptureReady is called, captureID: %{public}d, timestamp: %{public}" PRIu64, captureId, timestamp);
1254 CallbackInfo info;
1255 info.captureID = captureId;
1256 info.timestamp = timestamp;
1257 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_READY, info);
1258 }
1259
OnCaptureError(const int32_t captureId,const int32_t errorCode) const1260 void PhotoOutputCallback::OnCaptureError(const int32_t captureId, const int32_t errorCode) const
1261 {
1262 MEDIA_DEBUG_LOG("OnCaptureError is called!, captureID: %{public}d, errorCode: %{public}d", captureId, errorCode);
1263 CallbackInfo info;
1264 info.captureID = captureId;
1265 info.errorCode = errorCode;
1266 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_ERROR, info);
1267 }
1268
OnEstimatedCaptureDuration(const int32_t duration) const1269 void PhotoOutputCallback::OnEstimatedCaptureDuration(const int32_t duration) const
1270 {
1271 MEDIA_DEBUG_LOG("OnEstimatedCaptureDuration is called!, duration: %{public}d", duration);
1272 CallbackInfo info;
1273 info.duration = duration;
1274 UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_ESTIMATED_CAPTURE_DURATION, info);
1275 }
1276
ExecuteCaptureStartCb(const CallbackInfo & info) const1277 void PhotoOutputCallback::ExecuteCaptureStartCb(const CallbackInfo& info) const
1278 {
1279 napi_value result[ARGS_TWO] = { nullptr, nullptr };
1280 napi_value retVal;
1281 napi_get_undefined(env_, &result[PARAM0]);
1282 if (IsEmpty(CONST_CAPTURE_START_WITH_INFO)) {
1283 napi_create_int32(env_, info.captureID, &result[PARAM1]);
1284 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO,
1285 .argv = result, .result = &retVal };
1286 ExecuteCallback(CONST_CAPTURE_START, callbackNapiPara);
1287 } else {
1288 napi_value propValue;
1289 napi_create_object(env_, &result[PARAM1]);
1290 napi_create_int32(env_, info.captureID, &propValue);
1291 napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1292 int32_t invalidExposureTime = -1;
1293 napi_create_int32(env_, invalidExposureTime, &propValue);
1294 napi_set_named_property(env_, result[PARAM1], "time", propValue);
1295 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO,
1296 .argv = result, .result = &retVal };
1297 ExecuteCallback(CONST_CAPTURE_START_WITH_INFO, callbackNapiPara);
1298 }
1299 }
1300
ExecuteCaptureStartWithInfoCb(const CallbackInfo & info) const1301 void PhotoOutputCallback::ExecuteCaptureStartWithInfoCb(const CallbackInfo& info) const
1302 {
1303 napi_value result[ARGS_TWO] = { nullptr, nullptr };
1304 napi_value retVal;
1305 napi_value propValue;
1306 napi_get_undefined(env_, &result[PARAM0]);
1307 napi_create_object(env_, &result[PARAM1]);
1308 napi_create_int32(env_, info.captureID, &propValue);
1309 napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1310 napi_create_int32(env_, info.timestamp, &propValue);
1311 napi_set_named_property(env_, result[PARAM1], "time", propValue);
1312 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1313 ExecuteCallback(CONST_CAPTURE_START_WITH_INFO, callbackNapiPara);
1314 }
1315
ExecuteCaptureEndCb(const CallbackInfo & info) const1316 void PhotoOutputCallback::ExecuteCaptureEndCb(const CallbackInfo& info) const
1317 {
1318 napi_value result[ARGS_TWO] = { nullptr, nullptr };
1319 napi_value retVal;
1320 napi_value propValue;
1321 napi_get_undefined(env_, &result[PARAM0]);
1322 napi_create_object(env_, &result[PARAM1]);
1323 napi_create_int32(env_, info.captureID, &propValue);
1324 napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1325 napi_create_int32(env_, info.frameCount, &propValue);
1326 napi_set_named_property(env_, result[PARAM1], "frameCount", propValue);
1327 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1328 ExecuteCallback(CONST_CAPTURE_END, callbackNapiPara);
1329 }
1330
ExecuteFrameShutterCb(const CallbackInfo & info) const1331 void PhotoOutputCallback::ExecuteFrameShutterCb(const CallbackInfo& info) const
1332 {
1333 napi_value result[ARGS_TWO] = { nullptr, nullptr };
1334 napi_value retVal;
1335 napi_value propValue;
1336 napi_get_undefined(env_, &result[PARAM0]);
1337 napi_create_object(env_, &result[PARAM1]);
1338 napi_create_int32(env_, info.captureID, &propValue);
1339 napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1340 napi_create_int64(env_, info.timestamp, &propValue);
1341 napi_set_named_property(env_, result[PARAM1], "timestamp", propValue);
1342 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1343 ExecuteCallback(CONST_CAPTURE_FRAME_SHUTTER, callbackNapiPara);
1344 }
1345
ExecuteFrameShutterEndCb(const CallbackInfo & info) const1346 void PhotoOutputCallback::ExecuteFrameShutterEndCb(const CallbackInfo& info) const
1347 {
1348 napi_value result[ARGS_TWO] = { nullptr, nullptr };
1349 napi_value retVal;
1350 napi_value propValue;
1351 napi_get_undefined(env_, &result[PARAM0]);
1352 napi_create_object(env_, &result[PARAM1]);
1353 napi_create_int32(env_, info.captureID, &propValue);
1354 napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1355 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1356 ExecuteCallback(CONST_CAPTURE_FRAME_SHUTTER_END, callbackNapiPara);
1357 }
1358
ExecuteCaptureReadyCb(const CallbackInfo & info) const1359 void PhotoOutputCallback::ExecuteCaptureReadyCb(const CallbackInfo& info) const
1360 {
1361 napi_value result[ARGS_ONE] = { nullptr };
1362 napi_value retVal;
1363 napi_get_undefined(env_, &result[PARAM0]);
1364 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_ONE, .argv = result, .result = &retVal };
1365 ExecuteCallback(CONST_CAPTURE_READY, callbackNapiPara);
1366 }
1367
ExecuteCaptureErrorCb(const CallbackInfo & info) const1368 void PhotoOutputCallback::ExecuteCaptureErrorCb(const CallbackInfo& info) const
1369 {
1370 napi_value errJsResult[ARGS_ONE] = { nullptr };
1371 napi_value retVal;
1372 napi_value propValue;
1373
1374 napi_create_object(env_, &errJsResult[PARAM0]);
1375 napi_create_int32(env_, info.errorCode, &propValue);
1376 napi_set_named_property(env_, errJsResult[PARAM0], "code", propValue);
1377 ExecuteCallbackNapiPara callbackNapiPara {
1378 .recv = nullptr, .argc = ARGS_ONE, .argv = errJsResult, .result = &retVal
1379 };
1380 ExecuteCallback(CONST_CAPTURE_ERROR, callbackNapiPara);
1381 }
1382
ExecuteEstimatedCaptureDurationCb(const CallbackInfo & info) const1383 void PhotoOutputCallback::ExecuteEstimatedCaptureDurationCb(const CallbackInfo& info) const
1384 {
1385 napi_value result[ARGS_TWO] = { nullptr, nullptr };
1386 napi_value retVal;
1387 napi_get_undefined(env_, &result[PARAM0]);
1388 napi_create_int32(env_, info.duration, &result[PARAM1]);
1389 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1390 ExecuteCallback(CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, callbackNapiPara);
1391 }
1392
UpdateJSCallback(PhotoOutputEventType eventType,const CallbackInfo & info) const1393 void PhotoOutputCallback::UpdateJSCallback(PhotoOutputEventType eventType, const CallbackInfo& info) const
1394 {
1395 MEDIA_DEBUG_LOG("UpdateJSCallback is called");
1396 switch (eventType) {
1397 case PhotoOutputEventType::CAPTURE_START:
1398 ExecuteCaptureStartCb(info);
1399 break;
1400 case PhotoOutputEventType::CAPTURE_END:
1401 ExecuteCaptureEndCb(info);
1402 break;
1403 case PhotoOutputEventType::CAPTURE_FRAME_SHUTTER:
1404 ExecuteFrameShutterCb(info);
1405 break;
1406 case PhotoOutputEventType::CAPTURE_ERROR:
1407 ExecuteCaptureErrorCb(info);
1408 break;
1409 case PhotoOutputEventType::CAPTURE_FRAME_SHUTTER_END:
1410 ExecuteFrameShutterEndCb(info);
1411 break;
1412 case PhotoOutputEventType::CAPTURE_READY:
1413 ExecuteCaptureReadyCb(info);
1414 break;
1415 case PhotoOutputEventType::CAPTURE_ESTIMATED_CAPTURE_DURATION:
1416 ExecuteEstimatedCaptureDurationCb(info);
1417 break;
1418 case PhotoOutputEventType::CAPTURE_START_WITH_INFO:
1419 ExecuteCaptureStartWithInfoCb(info);
1420 break;
1421 default:
1422 MEDIA_ERR_LOG("Incorrect photo callback event type received from JS");
1423 }
1424 }
1425
ThumbnailListener(napi_env env,const sptr<PhotoOutput> photoOutput)1426 ThumbnailListener::ThumbnailListener(napi_env env, const sptr<PhotoOutput> photoOutput)
1427 : ListenerBase(env), photoOutput_(photoOutput)
1428 {}
1429
OnBufferAvailable()1430 void ThumbnailListener::OnBufferAvailable()
1431 {
1432 CAMERA_SYNC_TRACE;
1433 MEDIA_INFO_LOG("ThumbnailListener:OnBufferAvailable() called");
1434 UpdateJSCallbackAsync();
1435 }
1436
UpdateJSCallback() const1437 void ThumbnailListener::UpdateJSCallback() const
1438 {
1439 auto photoOutput = photoOutput_.promote();
1440 if (photoOutput == nullptr) {
1441 MEDIA_ERR_LOG("ThumbnailListener::UpdateJSCallback photoOutput is nullptr");
1442 return;
1443 }
1444 napi_value result[ARGS_TWO] = { 0 };
1445 napi_get_undefined(env_, &result[0]);
1446 napi_get_undefined(env_, &result[1]);
1447 napi_value retVal;
1448 MEDIA_INFO_LOG("enter ImageNapi::Create start");
1449 int32_t fence = -1;
1450 int64_t timestamp;
1451 OHOS::Rect damage;
1452 sptr<SurfaceBuffer> thumbnailBuffer = nullptr;
1453 SurfaceError surfaceRet = photoOutput->thumbnailSurface_->AcquireBuffer(thumbnailBuffer, fence, timestamp, damage);
1454 if (surfaceRet != SURFACE_ERROR_OK) {
1455 MEDIA_ERR_LOG("ThumbnailListener Failed to acquire surface buffer");
1456 return;
1457 }
1458 int32_t thumbnailWidth;
1459 int32_t thumbnailHeight;
1460 thumbnailBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, thumbnailWidth);
1461 thumbnailBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, thumbnailHeight);
1462 Media::InitializationOptions opts;
1463 opts.srcPixelFormat = Media::PixelFormat::RGBA_8888;
1464 opts.pixelFormat = Media::PixelFormat::RGBA_8888;
1465 opts.size = { .width = thumbnailWidth, .height = thumbnailHeight };
1466 MEDIA_INFO_LOG("thumbnailWidth:%{public}d, thumbnailheight: %{public}d", thumbnailWidth, thumbnailHeight);
1467 const int32_t formatSize = 4;
1468 auto pixelMap = Media::PixelMap::Create(static_cast<const uint32_t*>(thumbnailBuffer->GetVirAddr()),
1469 thumbnailWidth * thumbnailHeight * formatSize, 0, thumbnailWidth, opts, true);
1470 napi_value valueParam = Media::PixelMapNapi::CreatePixelMap(env_, std::move(pixelMap));
1471 if (valueParam == nullptr) {
1472 MEDIA_ERR_LOG("ImageNapi Create failed");
1473 napi_get_undefined(env_, &valueParam);
1474 }
1475 MEDIA_INFO_LOG("enter ImageNapi::Create end");
1476 result[1] = valueParam;
1477
1478 ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1479 ExecuteCallback(CONST_CAPTURE_QUICK_THUMBNAIL, callbackNapiPara);
1480 photoOutput->thumbnailSurface_->ReleaseBuffer(thumbnailBuffer, -1);
1481 }
1482
UpdateJSCallbackAsync()1483 void ThumbnailListener::UpdateJSCallbackAsync()
1484 {
1485 uv_loop_s* loop = nullptr;
1486 napi_get_uv_event_loop(env_, &loop);
1487 if (!loop) {
1488 MEDIA_ERR_LOG("ThumbnailListener:UpdateJSCallbackAsync() failed to get event loop");
1489 return;
1490 }
1491 uv_work_t* work = new (std::nothrow) uv_work_t;
1492 if (!work) {
1493 MEDIA_ERR_LOG("ThumbnailListener:UpdateJSCallbackAsync() failed to allocate work");
1494 return;
1495 }
1496 std::unique_ptr<ThumbnailListenerInfo> callbackInfo = std::make_unique<ThumbnailListenerInfo>(this);
1497 work->data = callbackInfo.get();
1498 int ret = uv_queue_work_with_qos(
1499 loop, work, [](uv_work_t* work) {},
1500 [](uv_work_t* work, int status) {
1501 ThumbnailListenerInfo* callbackInfo = reinterpret_cast<ThumbnailListenerInfo*>(work->data);
1502 if (callbackInfo) {
1503 auto listener = callbackInfo->listener_.promote();
1504 if (listener != nullptr) {
1505 listener->UpdateJSCallback();
1506 MEDIA_INFO_LOG("ThumbnailListener:UpdateJSCallbackAsync() complete");
1507 }
1508 delete callbackInfo;
1509 }
1510 delete work;
1511 },
1512 uv_qos_user_initiated);
1513 if (ret) {
1514 MEDIA_ERR_LOG("ThumbnailListener:UpdateJSCallbackAsync() failed to execute work");
1515 delete work;
1516 } else {
1517 callbackInfo.release();
1518 }
1519 }
1520
PhotoOutputNapi()1521 PhotoOutputNapi::PhotoOutputNapi() {}
1522
~PhotoOutputNapi()1523 PhotoOutputNapi::~PhotoOutputNapi()
1524 {
1525 if (pictureListener_) {
1526 pictureListener_->gainmapImageListener = nullptr;
1527 pictureListener_->deepImageListener = nullptr;
1528 pictureListener_->exifImageListener = nullptr;
1529 pictureListener_->debugImageListener = nullptr;
1530 }
1531 pictureListener_ = nullptr;
1532 MEDIA_DEBUG_LOG("~PhotoOutputNapi is called");
1533 }
1534
PhotoOutputNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)1535 void PhotoOutputNapi::PhotoOutputNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
1536 {
1537 MEDIA_DEBUG_LOG("PhotoOutputNapiDestructor is called");
1538 PhotoOutputNapi* photoOutput = reinterpret_cast<PhotoOutputNapi*>(nativeObject);
1539 if (photoOutput != nullptr) {
1540 delete photoOutput;
1541 }
1542 }
1543
Init(napi_env env,napi_value exports)1544 napi_value PhotoOutputNapi::Init(napi_env env, napi_value exports)
1545 {
1546 MEDIA_DEBUG_LOG("Init is called");
1547 napi_status status;
1548 napi_value ctorObj;
1549 int32_t refCount = 1;
1550
1551 napi_property_descriptor photo_output_props[] = {
1552 DECLARE_NAPI_FUNCTION("isMovingPhotoSupported", IsMovingPhotoSupported),
1553 DECLARE_NAPI_FUNCTION("enableMovingPhoto", EnableMovingPhoto),
1554 DECLARE_NAPI_FUNCTION("capture", Capture),
1555 DECLARE_NAPI_FUNCTION("burstCapture", BurstCapture),
1556 DECLARE_NAPI_FUNCTION("confirmCapture", ConfirmCapture),
1557 DECLARE_NAPI_FUNCTION("release", Release),
1558 DECLARE_NAPI_FUNCTION("isMirrorSupported", IsMirrorSupported),
1559 DECLARE_NAPI_FUNCTION("enableMirror", EnableMirror),
1560 DECLARE_NAPI_FUNCTION("enableQuickThumbnail", EnableQuickThumbnail),
1561 DECLARE_NAPI_FUNCTION("isQuickThumbnailSupported", IsQuickThumbnailSupported),
1562 DECLARE_NAPI_FUNCTION("enableRawDelivery", EnableRawDelivery),
1563 DECLARE_NAPI_FUNCTION("isRawDeliverySupported", IsRawDeliverySupported),
1564 DECLARE_NAPI_FUNCTION("getSupportedMovingPhotoVideoCodecTypes", GetSupportedMovingPhotoVideoCodecTypes),
1565 DECLARE_NAPI_FUNCTION("setMovingPhotoVideoCodecType", SetMovingPhotoVideoCodecType),
1566 DECLARE_NAPI_FUNCTION("on", On),
1567 DECLARE_NAPI_FUNCTION("once", Once),
1568 DECLARE_NAPI_FUNCTION("off", Off),
1569 DECLARE_NAPI_FUNCTION("deferImageDelivery", DeferImageDeliveryFor),
1570 DECLARE_NAPI_FUNCTION("deferImageDeliveryFor", DeferImageDeliveryFor),
1571 DECLARE_NAPI_FUNCTION("isDeferredImageDeliverySupported", IsDeferredImageDeliverySupported),
1572 DECLARE_NAPI_FUNCTION("isDeferredImageDeliveryEnabled", IsDeferredImageDeliveryEnabled),
1573 DECLARE_NAPI_FUNCTION("isAutoHighQualityPhotoSupported", IsAutoHighQualityPhotoSupported),
1574 DECLARE_NAPI_FUNCTION("enableAutoHighQualityPhoto", EnableAutoHighQualityPhoto),
1575 DECLARE_NAPI_FUNCTION("getActiveProfile", GetActiveProfile),
1576 DECLARE_NAPI_FUNCTION("getPhotoRotation", GetPhotoRotation),
1577 DECLARE_NAPI_FUNCTION("isAutoCloudImageEnhancementSupported", IsAutoCloudImageEnhancementSupported),
1578 DECLARE_NAPI_FUNCTION("enableAutoCloudImageEnhancement", EnableAutoCloudImageEnhancement),
1579 DECLARE_NAPI_FUNCTION("isDepthDataDeliverySupported", IsDepthDataDeliverySupported),
1580 DECLARE_NAPI_FUNCTION("enableDepthDataDelivery", EnableDepthDataDelivery)
1581 };
1582
1583 status = napi_define_class(env, CAMERA_PHOTO_OUTPUT_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH, PhotoOutputNapiConstructor,
1584 nullptr, sizeof(photo_output_props) / sizeof(photo_output_props[PARAM0]), photo_output_props, &ctorObj);
1585 if (status == napi_ok) {
1586 status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
1587 if (status == napi_ok) {
1588 status = napi_set_named_property(env, exports, CAMERA_PHOTO_OUTPUT_NAPI_CLASS_NAME, ctorObj);
1589 if (status == napi_ok) {
1590 return exports;
1591 }
1592 }
1593 }
1594 MEDIA_ERR_LOG("Init call Failed!");
1595 return nullptr;
1596 }
1597
1598 // Constructor callback
PhotoOutputNapiConstructor(napi_env env,napi_callback_info info)1599 napi_value PhotoOutputNapi::PhotoOutputNapiConstructor(napi_env env, napi_callback_info info)
1600 {
1601 MEDIA_DEBUG_LOG("PhotoOutputNapiConstructor is called");
1602 napi_status status;
1603 napi_value result = nullptr;
1604 napi_value thisVar = nullptr;
1605
1606 napi_get_undefined(env, &result);
1607 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
1608
1609 if (status == napi_ok && thisVar != nullptr) {
1610 std::unique_ptr<PhotoOutputNapi> obj = std::make_unique<PhotoOutputNapi>();
1611 obj->photoOutput_ = sPhotoOutput_;
1612 obj->profile_ = sPhotoOutput_->GetPhotoProfile();
1613 status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
1614 PhotoOutputNapi::PhotoOutputNapiDestructor, nullptr, nullptr);
1615 if (status == napi_ok) {
1616 obj.release();
1617 return thisVar;
1618 } else {
1619 MEDIA_ERR_LOG("Failure wrapping js to native napi");
1620 }
1621 }
1622 MEDIA_ERR_LOG("PhotoOutputNapiConstructor call Failed!");
1623 return result;
1624 }
1625
GetPhotoOutput()1626 sptr<PhotoOutput> PhotoOutputNapi::GetPhotoOutput()
1627 {
1628 return photoOutput_;
1629 }
1630
GetEnableMirror()1631 bool PhotoOutputNapi::GetEnableMirror()
1632 {
1633 return isMirrorEnabled_;
1634 }
1635
IsPhotoOutput(napi_env env,napi_value obj)1636 bool PhotoOutputNapi::IsPhotoOutput(napi_env env, napi_value obj)
1637 {
1638 MEDIA_DEBUG_LOG("IsPhotoOutput is called");
1639 bool result = false;
1640 napi_status status;
1641 napi_value constructor = nullptr;
1642
1643 status = napi_get_reference_value(env, sConstructor_, &constructor);
1644 if (status == napi_ok) {
1645 status = napi_instanceof(env, obj, constructor, &result);
1646 if (status != napi_ok) {
1647 result = false;
1648 }
1649 }
1650 return result;
1651 }
1652
CreateMultiChannelPictureLisenter(napi_env env)1653 void PhotoOutputNapi::CreateMultiChannelPictureLisenter(napi_env env)
1654 {
1655 if (pictureListener_ == nullptr) {
1656 MEDIA_INFO_LOG("new photoListener and register surface consumer listener");
1657 sptr<PictureListener> pictureListener = new (std::nothrow) PictureListener();
1658 pictureListener->InitPictureListeners(env, photoOutput_);
1659 if (photoListener_ == nullptr) {
1660 sptr<PhotoListener> photoListener = new (std::nothrow) PhotoListener(env, sPhotoSurface_, photoOutput_);
1661 SurfaceError ret = sPhotoSurface_->RegisterConsumerListener((sptr<IBufferConsumerListener>&)photoListener);
1662 if (ret != SURFACE_ERROR_OK) {
1663 MEDIA_ERR_LOG("register surface consumer listener failed!");
1664 }
1665 photoListener_ = photoListener;
1666 pictureListener_ = pictureListener;
1667 }
1668 }
1669 }
1670
CreateSingleChannelPhotoLisenter(napi_env env)1671 void PhotoOutputNapi::CreateSingleChannelPhotoLisenter(napi_env env)
1672 {
1673 if (photoListener_ == nullptr) {
1674 MEDIA_INFO_LOG("new photoListener and register surface consumer listener");
1675 sptr<PhotoListener> photoListener = new (std::nothrow) PhotoListener(env, sPhotoSurface_, photoOutput_);
1676 SurfaceError ret = sPhotoSurface_->RegisterConsumerListener((sptr<IBufferConsumerListener>&)photoListener);
1677 if (ret != SURFACE_ERROR_OK) {
1678 MEDIA_ERR_LOG("register surface consumer listener failed!");
1679 }
1680 photoListener_ = photoListener;
1681 }
1682 }
1683
CreatePhotoOutput(napi_env env,Profile & profile,std::string surfaceId)1684 napi_value PhotoOutputNapi::CreatePhotoOutput(napi_env env, Profile& profile, std::string surfaceId)
1685 {
1686 MEDIA_DEBUG_LOG("CreatePhotoOutput is called, profile CameraFormat= %{public}d", profile.GetCameraFormat());
1687 CAMERA_SYNC_TRACE;
1688 napi_value result = nullptr;
1689 napi_get_undefined(env, &result);
1690 napi_value constructor;
1691 napi_status status = napi_get_reference_value(env, sConstructor_, &constructor);
1692 if (status == napi_ok) {
1693 MEDIA_INFO_LOG("CreatePhotoOutput surfaceId: %{public}s", surfaceId.c_str());
1694 sptr<Surface> photoSurface;
1695 if (surfaceId == "") {
1696 MEDIA_INFO_LOG("create surface as consumer");
1697 photoSurface = Surface::CreateSurfaceAsConsumer("photoOutput");
1698 sPhotoSurface_ = photoSurface;
1699 } else {
1700 MEDIA_INFO_LOG("get surface by surfaceId");
1701 photoSurface = Media::ImageReceiver::getSurfaceById(surfaceId);
1702 }
1703 if (photoSurface == nullptr) {
1704 MEDIA_ERR_LOG("failed to get surface");
1705 return result;
1706 }
1707 photoSurface->SetUserData(CameraManager::surfaceFormat, std::to_string(profile.GetCameraFormat()));
1708 sptr<IBufferProducer> surfaceProducer = photoSurface->GetProducer();
1709 MEDIA_INFO_LOG("profile width: %{public}d, height: %{public}d, format = %{public}d, "
1710 "surface width: %{public}d, height: %{public}d", profile.GetSize().width,
1711 profile.GetSize().height, static_cast<int32_t>(profile.GetCameraFormat()),
1712 photoSurface->GetDefaultWidth(), photoSurface->GetDefaultHeight());
1713 int retCode = CameraManager::GetInstance()->CreatePhotoOutput(profile, surfaceProducer, &sPhotoOutput_);
1714 if (!CameraNapiUtils::CheckError(env, retCode) || sPhotoOutput_ == nullptr) {
1715 MEDIA_ERR_LOG("failed to create CreatePhotoOutput");
1716 return result;
1717 }
1718 if (surfaceId == "") {
1719 sPhotoOutput_->SetNativeSurface(true);
1720 }
1721 if (sPhotoOutput_->IsYuvOrHeifPhoto()) {
1722 sPhotoOutput_->CreateMultiChannel();
1723 }
1724 status = napi_new_instance(env, constructor, 0, nullptr, &result);
1725 sPhotoOutput_ = nullptr;
1726 if (status == napi_ok && result != nullptr) {
1727 MEDIA_INFO_LOG("Success to create photo output instance");
1728 return result;
1729 }
1730 }
1731 MEDIA_ERR_LOG("CreatePhotoOutput call Failed!");
1732 return result;
1733 }
1734
CreatePhotoOutput(napi_env env,std::string surfaceId)1735 napi_value PhotoOutputNapi::CreatePhotoOutput(napi_env env, std::string surfaceId)
1736 {
1737 MEDIA_INFO_LOG("CreatePhotoOutput with only surfaceId is called");
1738 CAMERA_SYNC_TRACE;
1739 napi_status status;
1740 napi_value result = nullptr;
1741 napi_value constructor;
1742 napi_get_undefined(env, &result);
1743 status = napi_get_reference_value(env, sConstructor_, &constructor);
1744 if (status == napi_ok) {
1745 MEDIA_INFO_LOG("CreatePhotoOutput surfaceId: %{public}s", surfaceId.c_str());
1746 sptr<Surface> photoSurface;
1747 if (surfaceId == "") {
1748 MEDIA_INFO_LOG("create surface as consumer");
1749 photoSurface = Surface::CreateSurfaceAsConsumer("photoOutput");
1750 sPhotoSurface_ = photoSurface;
1751 } else {
1752 MEDIA_INFO_LOG("get surface by surfaceId");
1753 photoSurface = Media::ImageReceiver::getSurfaceById(surfaceId);
1754 }
1755 if (photoSurface == nullptr) {
1756 MEDIA_ERR_LOG("failed to get surface");
1757 return result;
1758 }
1759 sptr<IBufferProducer> surfaceProducer = photoSurface->GetProducer();
1760 MEDIA_INFO_LOG("surface width: %{public}d, height: %{public}d", photoSurface->GetDefaultWidth(),
1761 photoSurface->GetDefaultHeight());
1762 int retCode = CameraManager::GetInstance()->CreatePhotoOutputWithoutProfile(surfaceProducer, &sPhotoOutput_);
1763 if (!CameraNapiUtils::CheckError(env, retCode) || sPhotoOutput_ == nullptr) {
1764 MEDIA_ERR_LOG("failed to create CreatePhotoOutput");
1765 return result;
1766 }
1767 status = napi_new_instance(env, constructor, 0, nullptr, &result);
1768 sPhotoOutput_ = nullptr;
1769 if (status == napi_ok && result != nullptr) {
1770 MEDIA_DEBUG_LOG("Success to create photo output instance");
1771 return result;
1772 } else {
1773 MEDIA_ERR_LOG("Failed to create photo output instance");
1774 }
1775 }
1776 MEDIA_ERR_LOG("CreatePhotoOutput call Failed!");
1777 return result;
1778 }
1779
ParseCaptureSettings(napi_env env,napi_callback_info info,PhotoOutputAsyncContext * asyncContext,std::shared_ptr<CameraNapiAsyncFunction> & asyncFunction,bool isSettingOptional)1780 bool ParseCaptureSettings(napi_env env, napi_callback_info info, PhotoOutputAsyncContext* asyncContext,
1781 std::shared_ptr<CameraNapiAsyncFunction>& asyncFunction, bool isSettingOptional)
1782 {
1783 Location settingsLocation;
1784 CameraNapiObject settingsLocationNapiOjbect { {
1785 { "latitude", &settingsLocation.latitude },
1786 { "longitude", &settingsLocation.longitude },
1787 { "altitude", &settingsLocation.altitude },
1788 } };
1789 CameraNapiObject settingsNapiOjbect { {
1790 { "quality", &asyncContext->quality },
1791 { "rotation", &asyncContext->rotation },
1792 { "location", &settingsLocationNapiOjbect },
1793 { "mirror", &asyncContext->isMirror },
1794 } };
1795 unordered_set<std::string> optionalKeys = { "quality", "rotation", "location", "mirror" };
1796 settingsNapiOjbect.SetOptionalKeys(optionalKeys);
1797
1798 asyncFunction =
1799 std::make_shared<CameraNapiAsyncFunction>(env, "Capture", asyncContext->callbackRef, asyncContext->deferred);
1800 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction, settingsNapiOjbect);
1801 if (jsParamParser.IsStatusOk()) {
1802 if (settingsNapiOjbect.IsKeySetted("quality") && !ValidQualityLevelFromJs(asyncContext->quality)) {
1803 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "quality field not legal");
1804 return false;
1805 }
1806 if (settingsNapiOjbect.IsKeySetted("rotation") && !ValidImageRotationFromJs(asyncContext->rotation)) {
1807 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "rotation field not legal");
1808 return false;
1809 }
1810 if (settingsNapiOjbect.IsKeySetted("mirror") && asyncContext->isMirror) {
1811 MEDIA_INFO_LOG("GetMirrorStatus is ok!");
1812 asyncContext->isMirrorSettedByUser = true;
1813 }
1814 MEDIA_INFO_LOG("ParseCaptureSettings with capture settings pass");
1815 asyncContext->hasPhotoSettings = true;
1816 if (settingsNapiOjbect.IsKeySetted("location")) {
1817 asyncContext->location = std::make_shared<Location>(settingsLocation);
1818 }
1819 } else if (isSettingOptional) {
1820 MEDIA_WARNING_LOG("ParseCaptureSettings check capture settings fail, try capture without settings");
1821 jsParamParser = CameraNapiParamParser(env, info, asyncContext->objectInfo, asyncFunction);
1822 } else {
1823 // Do nothing.
1824 }
1825 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
1826 MEDIA_ERR_LOG("ParseCaptureSettings invalid argument");
1827 return false;
1828 }
1829 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
1830 return true;
1831 }
1832
Capture(napi_env env,napi_callback_info info)1833 napi_value PhotoOutputNapi::Capture(napi_env env, napi_callback_info info)
1834 {
1835 MEDIA_INFO_LOG("Capture is called");
1836 std::unique_ptr<PhotoOutputAsyncContext> asyncContext = std::make_unique<PhotoOutputAsyncContext>(
1837 "PhotoOutputNapi::Capture", CameraNapiUtils::IncrementAndGet(photoOutputTaskId));
1838 std::shared_ptr<CameraNapiAsyncFunction> asyncFunction;
1839 if (!ParseCaptureSettings(env, info, asyncContext.get(), asyncFunction, true)) {
1840 MEDIA_ERR_LOG("PhotoOutputNapi::Capture parse parameters fail.");
1841 return nullptr;
1842 }
1843 napi_status status = napi_create_async_work(
1844 env, nullptr, asyncFunction->GetResourceName(),
1845 [](napi_env env, void* data) {
1846 MEDIA_INFO_LOG("PhotoOutputNapi::Capture running on worker");
1847 auto context = static_cast<PhotoOutputAsyncContext*>(data);
1848 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "PhotoOutputNapi::Capture async info is nullptr");
1849 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
1850 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(
1851 context->queueTask, [&context]() { ProcessCapture(context, false); });
1852 },
1853 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1854 if (status != napi_ok) {
1855 MEDIA_ERR_LOG("Failed to create napi_create_async_work for PhotoOutputNapi::Capture");
1856 asyncFunction->Reset();
1857 } else {
1858 asyncContext->queueTask =
1859 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PhotoOutputNapi::Capture");
1860 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
1861 asyncContext.release();
1862 }
1863 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
1864 return asyncFunction->GetPromise();
1865 }
1866 return CameraNapiUtils::GetUndefinedValue(env);
1867 }
1868
BurstCapture(napi_env env,napi_callback_info info)1869 napi_value PhotoOutputNapi::BurstCapture(napi_env env, napi_callback_info info)
1870 {
1871 MEDIA_INFO_LOG("BurstCapture is called");
1872 if (!CameraNapiSecurity::CheckSystemApp(env)) {
1873 MEDIA_ERR_LOG("SystemApi EnableAutoHighQualityPhoto is called!");
1874 return nullptr;
1875 }
1876
1877 std::unique_ptr<PhotoOutputAsyncContext> asyncContext = std::make_unique<PhotoOutputAsyncContext>(
1878 "PhotoOutputNapi::BurstCapture", CameraNapiUtils::IncrementAndGet(photoOutputTaskId));
1879 std::shared_ptr<CameraNapiAsyncFunction> asyncFunction;
1880 if (!ParseCaptureSettings(env, info, asyncContext.get(), asyncFunction, false)) {
1881 MEDIA_ERR_LOG("PhotoOutputNapi::BurstCapture parse parameters fail.");
1882 return nullptr;
1883 }
1884 napi_status status = napi_create_async_work(
1885 env, nullptr, asyncFunction->GetResourceName(),
1886 [](napi_env env, void* data) {
1887 MEDIA_INFO_LOG("PhotoOutputNapi::BurstCapture running on worker");
1888 auto context = static_cast<PhotoOutputAsyncContext*>(data);
1889 CHECK_ERROR_RETURN_LOG(
1890 context->objectInfo == nullptr, "PhotoOutputNapi::BurstCapture async info is nullptr");
1891 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
1892 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(
1893 context->queueTask, [&context]() { ProcessCapture(context, true); });
1894 },
1895 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1896 if (status != napi_ok) {
1897 MEDIA_ERR_LOG("Failed to create napi_create_async_work for PhotoOutputNapi::BurstCapture");
1898 asyncFunction->Reset();
1899 } else {
1900 asyncContext->queueTask =
1901 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PhotoOutputNapi::BurstCapture");
1902 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
1903 asyncContext.release();
1904 }
1905 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
1906 return asyncFunction->GetPromise();
1907 }
1908 return CameraNapiUtils::GetUndefinedValue(env);
1909 }
1910
ConfirmCapture(napi_env env,napi_callback_info info)1911 napi_value PhotoOutputNapi::ConfirmCapture(napi_env env, napi_callback_info info)
1912 {
1913 MEDIA_INFO_LOG("ConfirmCapture is called");
1914 napi_status status;
1915 napi_value result = nullptr;
1916 size_t argc = ARGS_ZERO;
1917 napi_value argv[ARGS_ZERO] = {};
1918 napi_value thisVar = nullptr;
1919
1920 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1921
1922 napi_get_undefined(env, &result);
1923 PhotoOutputNapi* photoOutputNapi = nullptr;
1924 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1925 if (status == napi_ok && photoOutputNapi != nullptr) {
1926 int32_t retCode = photoOutputNapi->photoOutput_->ConfirmCapture();
1927 if (!CameraNapiUtils::CheckError(env, retCode)) {
1928 return result;
1929 }
1930 }
1931 return result;
1932 }
1933
Release(napi_env env,napi_callback_info info)1934 napi_value PhotoOutputNapi::Release(napi_env env, napi_callback_info info)
1935 {
1936 MEDIA_INFO_LOG("Release is called");
1937 std::unique_ptr<PhotoOutputAsyncContext> asyncContext = std::make_unique<PhotoOutputAsyncContext>(
1938 "PhotoOutputNapi::Release", CameraNapiUtils::IncrementAndGet(photoOutputTaskId));
1939 auto asyncFunction =
1940 std::make_shared<CameraNapiAsyncFunction>(env, "Release", asyncContext->callbackRef, asyncContext->deferred);
1941 CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
1942 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
1943 MEDIA_ERR_LOG("PhotoOutputNapi::Release invalid argument");
1944 return nullptr;
1945 }
1946 asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
1947 napi_status status = napi_create_async_work(
1948 env, nullptr, asyncFunction->GetResourceName(),
1949 [](napi_env env, void* data) {
1950 MEDIA_INFO_LOG("PhotoOutputNapi::Release running on worker");
1951 auto context = static_cast<PhotoOutputAsyncContext*>(data);
1952 CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "PhotoOutputNapi::Release async info is nullptr");
1953 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
1954 CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
1955 context->errorCode = context->objectInfo->photoOutput_->Release();
1956 context->status = context->errorCode == CameraErrorCode::SUCCESS;
1957 });
1958 },
1959 AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1960 if (status != napi_ok) {
1961 MEDIA_ERR_LOG("Failed to create napi_create_async_work for PhotoOutputNapi::Release");
1962 asyncFunction->Reset();
1963 } else {
1964 asyncContext->queueTask =
1965 CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PhotoOutputNapi::Release");
1966 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
1967 asyncContext.release();
1968 }
1969 if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
1970 return asyncFunction->GetPromise();
1971 }
1972 return CameraNapiUtils::GetUndefinedValue(env);
1973 }
1974
IsMirrorSupported(napi_env env,napi_callback_info info)1975 napi_value PhotoOutputNapi::IsMirrorSupported(napi_env env, napi_callback_info info)
1976 {
1977 MEDIA_INFO_LOG("IsMirrorSupported is called");
1978 napi_status status;
1979 napi_value result = nullptr;
1980 size_t argc = ARGS_ZERO;
1981 napi_value argv[ARGS_ZERO];
1982 napi_value thisVar = nullptr;
1983
1984 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1985
1986 napi_get_undefined(env, &result);
1987 PhotoOutputNapi* photoOutputNapi = nullptr;
1988 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1989 if (status == napi_ok && photoOutputNapi != nullptr) {
1990 bool isSupported = photoOutputNapi->photoOutput_->IsMirrorSupported();
1991 napi_get_boolean(env, isSupported, &result);
1992 } else {
1993 MEDIA_ERR_LOG("IsMirrorSupported call Failed!");
1994 }
1995 return result;
1996 }
1997
EnableMirror(napi_env env,napi_callback_info info)1998 napi_value PhotoOutputNapi::EnableMirror(napi_env env, napi_callback_info info)
1999 {
2000 auto result = CameraNapiUtils::GetUndefinedValue(env);
2001 MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableMirror is called");
2002 PhotoOutputNapi* photoOutputNapi = nullptr;
2003 bool isMirror = false;
2004 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isMirror);
2005 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
2006 MEDIA_ERR_LOG("PhotoOutputNapi::EnableMirror invalid argument");
2007 return nullptr;
2008 }
2009 auto session = photoOutputNapi->GetPhotoOutput()->GetSession();
2010 if (session != nullptr) {
2011 photoOutputNapi->isMirrorEnabled_ = isMirror;
2012 int32_t retCode = session->EnableMovingPhotoMirror(isMirror);
2013 if (!CameraNapiUtils::CheckError(env, retCode)) {
2014 return result;
2015 }
2016 }
2017 return result;
2018 }
2019
IsQuickThumbnailSupported(napi_env env,napi_callback_info info)2020 napi_value PhotoOutputNapi::IsQuickThumbnailSupported(napi_env env, napi_callback_info info)
2021 {
2022 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2023 MEDIA_ERR_LOG("SystemApi IsQuickThumbnailSupported is called!");
2024 return nullptr;
2025 }
2026 napi_status status;
2027 napi_value result = nullptr;
2028 size_t argc = ARGS_ZERO;
2029 napi_value argv[ARGS_ZERO];
2030 napi_value thisVar = nullptr;
2031
2032 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2033
2034 napi_get_undefined(env, &result);
2035 PhotoOutputNapi* photoOutputNapi = nullptr;
2036 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2037 if (status == napi_ok && photoOutputNapi != nullptr) {
2038 int32_t retCode = photoOutputNapi->photoOutput_->IsQuickThumbnailSupported();
2039 bool isSupported = (retCode == 0);
2040 if (retCode > 0 && !CameraNapiUtils::CheckError(env, retCode)) {
2041 return result;
2042 }
2043 napi_get_boolean(env, isSupported, &result);
2044 }
2045 return result;
2046 }
2047
DeferImageDeliveryFor(napi_env env,napi_callback_info info)2048 napi_value PhotoOutputNapi::DeferImageDeliveryFor(napi_env env, napi_callback_info info)
2049 {
2050 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2051 MEDIA_ERR_LOG("SystemApi DeferImageDeliveryFor is called!");
2052 return nullptr;
2053 }
2054 napi_status status;
2055 napi_value result = nullptr;
2056 size_t argc = ARGS_ONE;
2057 napi_value argv[ARGS_ONE] = {0};
2058 napi_value thisVar = nullptr;
2059 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2060 NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2061 napi_get_undefined(env, &result);
2062 PhotoOutputNapi* photoOutputNapi = nullptr;
2063 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2064 if (status == napi_ok && photoOutputNapi != nullptr) {
2065 int32_t deliveryType;
2066 napi_get_value_int32(env, argv[PARAM0], &deliveryType);
2067 photoOutputNapi->photoOutput_->DeferImageDeliveryFor(static_cast<DeferredDeliveryImageType>(deliveryType));
2068 photoOutputNapi->isDeferredPhotoEnabled_ = deliveryType == DELIVERY_PHOTO;
2069 }
2070 return result;
2071 }
2072
IsDeferredImageDeliverySupported(napi_env env,napi_callback_info info)2073 napi_value PhotoOutputNapi::IsDeferredImageDeliverySupported(napi_env env, napi_callback_info info)
2074 {
2075 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2076 MEDIA_ERR_LOG("SystemApi IsDeferredImageDeliverySupported is called!");
2077 return nullptr;
2078 }
2079 napi_status status;
2080 napi_value result = nullptr;
2081 size_t argc = ARGS_ONE;
2082 napi_value argv[ARGS_ONE] = {0};
2083 napi_value thisVar = nullptr;
2084 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2085 NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2086 napi_get_undefined(env, &result);
2087 PhotoOutputNapi* photoOutputNapi = nullptr;
2088 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2089 if (status == napi_ok && photoOutputNapi != nullptr) {
2090 int32_t deliveryType;
2091 napi_get_value_int32(env, argv[PARAM0], &deliveryType);
2092 int32_t retCode = photoOutputNapi->photoOutput_->IsDeferredImageDeliverySupported(
2093 static_cast<DeferredDeliveryImageType>(deliveryType));
2094 bool isSupported = (retCode == 0);
2095 if (retCode > 0 && !CameraNapiUtils::CheckError(env, retCode)) {
2096 return result;
2097 }
2098 napi_get_boolean(env, isSupported, &result);
2099 }
2100 return result;
2101 }
2102
GetPhotoRotation(napi_env env,napi_callback_info info)2103 napi_value PhotoOutputNapi::GetPhotoRotation(napi_env env, napi_callback_info info)
2104 {
2105 MEDIA_DEBUG_LOG("GetPhotoRotation is called!");
2106 napi_status status;
2107 napi_value result = nullptr;
2108 size_t argc = ARGS_ONE;
2109 napi_value argv[ARGS_ONE] = {0};
2110 napi_value thisVar = nullptr;
2111 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2112
2113 napi_get_undefined(env, &result);
2114 PhotoOutputNapi* photoOutputNapi = nullptr;
2115 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2116 if (status == napi_ok && photoOutputNapi != nullptr) {
2117 int32_t value;
2118 napi_status ret = napi_get_value_int32(env, argv[PARAM0], &value);
2119 if (ret != napi_ok) {
2120 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT,
2121 "GetPhotoRotation parameter missing or parameter type incorrect.");
2122 return result;
2123 }
2124 int32_t retCode = photoOutputNapi->photoOutput_->GetPhotoRotation(value);
2125 if (retCode == SERVICE_FATL_ERROR) {
2126 CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR,
2127 "GetPhotoRotation Camera service fatal error.");
2128 return result;
2129 }
2130 napi_create_int32(env, retCode, &result);
2131 MEDIA_INFO_LOG("PhotoOutputNapi GetPhotoRotation! %{public}d", retCode);
2132 } else {
2133 MEDIA_ERR_LOG("PhotoOutputNapi GetPhotoRotation! called failed!");
2134 }
2135 return result;
2136 }
2137
IsDeferredImageDeliveryEnabled(napi_env env,napi_callback_info info)2138 napi_value PhotoOutputNapi::IsDeferredImageDeliveryEnabled(napi_env env, napi_callback_info info)
2139 {
2140 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2141 MEDIA_ERR_LOG("SystemApi IsDeferredImageDeliveryEnabled is called!");
2142 return nullptr;
2143 }
2144 napi_status status;
2145 napi_value result = nullptr;
2146 size_t argc = ARGS_ONE;
2147 napi_value argv[ARGS_ONE] = {0};
2148 napi_value thisVar = nullptr;
2149 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2150 NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2151 napi_get_undefined(env, &result);
2152 PhotoOutputNapi* photoOutputNapi = nullptr;
2153 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2154 if (status == napi_ok && photoOutputNapi != nullptr) {
2155 int32_t deliveryType;
2156 napi_get_value_int32(env, argv[PARAM0], &deliveryType);
2157 int32_t retCode = photoOutputNapi->photoOutput_->IsDeferredImageDeliveryEnabled(
2158 static_cast<DeferredDeliveryImageType>(deliveryType));
2159 bool isSupported = (retCode == 0);
2160 if (retCode > 0 && !CameraNapiUtils::CheckError(env, retCode)) {
2161 return result;
2162 }
2163 napi_get_boolean(env, isSupported, &result);
2164 }
2165 return result;
2166 }
2167
IsMovingPhotoSupported(napi_env env,napi_callback_info info)2168 napi_value PhotoOutputNapi::IsMovingPhotoSupported(napi_env env, napi_callback_info info)
2169 {
2170 MEDIA_DEBUG_LOG("IsMotionPhotoSupported is called");
2171 napi_status status;
2172 napi_value result = nullptr;
2173 size_t argc = ARGS_ZERO;
2174 napi_value argv[ARGS_ZERO];
2175 napi_value thisVar = nullptr;
2176
2177 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2178
2179 napi_get_undefined(env, &result);
2180 PhotoOutputNapi* photoOutputNapi = nullptr;
2181 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2182 if (status != napi_ok || photoOutputNapi == nullptr) {
2183 MEDIA_ERR_LOG("IsMotionPhotoSupported photoOutputNapi is null!");
2184 return result;
2185 }
2186 auto session = photoOutputNapi->GetPhotoOutput()->GetSession();
2187 if (session != nullptr) {
2188 bool isSupported = session->IsMovingPhotoSupported();
2189 napi_get_boolean(env, isSupported, &result);
2190 } else {
2191 napi_get_boolean(env, false, &result);
2192 MEDIA_ERR_LOG("IsMotionPhotoSupported call Failed!");
2193 }
2194 return result;
2195 }
2196
EnableMovingPhoto(napi_env env,napi_callback_info info)2197 napi_value PhotoOutputNapi::EnableMovingPhoto(napi_env env, napi_callback_info info)
2198 {
2199 MEDIA_DEBUG_LOG("enableMovingPhoto is called");
2200 napi_status status;
2201 napi_value result = nullptr;
2202 size_t argc = ARGS_ONE;
2203 napi_value argv[ARGS_ONE] = { 0 };
2204 napi_value thisVar = nullptr;
2205 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2206 NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2207 napi_valuetype valueType = napi_undefined;
2208 napi_typeof(env, argv[0], &valueType);
2209 if (valueType != napi_boolean && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT)) {
2210 return result;
2211 }
2212 napi_get_undefined(env, &result);
2213 PhotoOutputNapi* photoOutputNapi = nullptr;
2214 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2215 if (status != napi_ok || photoOutputNapi == nullptr) {
2216 MEDIA_ERR_LOG("EnableMovingPhoto photoOutputNapi is null!");
2217 return result;
2218 }
2219 auto session = photoOutputNapi->GetPhotoOutput()->GetSession();
2220 if (session != nullptr) {
2221 bool isEnableMovingPhoto;
2222 napi_get_value_bool(env, argv[PARAM0], &isEnableMovingPhoto);
2223 session->LockForControl();
2224 int32_t retCode = session->EnableMovingPhoto(isEnableMovingPhoto);
2225 session->UnlockForControl();
2226 if (retCode != 0 && !CameraNapiUtils::CheckError(env, retCode)) {
2227 return result;
2228 }
2229 }
2230 return result;
2231 }
2232
GetSupportedMovingPhotoVideoCodecTypes(napi_env env,napi_callback_info info)2233 napi_value PhotoOutputNapi::GetSupportedMovingPhotoVideoCodecTypes(napi_env env, napi_callback_info info)
2234 {
2235 MEDIA_DEBUG_LOG("IsMotionPhotoSupported is called");
2236 napi_status status;
2237 napi_value result = nullptr;
2238 size_t argc = ARGS_ZERO;
2239 napi_value argv[ARGS_ZERO];
2240 napi_value thisVar = nullptr;
2241
2242 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2243
2244 napi_get_undefined(env, &result);
2245 PhotoOutputNapi* photoOutputNapi = nullptr;
2246 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2247 if (status != napi_ok || photoOutputNapi == nullptr) {
2248 MEDIA_ERR_LOG("IsMotionPhotoSupported photoOutputNapi is null!");
2249 return result;
2250 }
2251 vector<int32_t> videoCodecTypes = {VideoCodecType::VIDEO_ENCODE_TYPE_AVC, VideoCodecType::VIDEO_ENCODE_TYPE_HEVC};
2252 result = CameraNapiUtils::CreateJSArray(env, status, videoCodecTypes);
2253 if (status != napi_ok) {
2254 result = CameraNapiUtils::CreateJSArray(env, status, {});
2255 }
2256 return result;
2257 }
2258
SetMovingPhotoVideoCodecType(napi_env env,napi_callback_info info)2259 napi_value PhotoOutputNapi::SetMovingPhotoVideoCodecType(napi_env env, napi_callback_info info)
2260 {
2261 MEDIA_DEBUG_LOG("SetMovingPhotoVideoCodecType is called");
2262 napi_status status;
2263 napi_value result = nullptr;
2264 size_t argc = ARGS_ONE;
2265 napi_value argv[ARGS_ONE] = { 0 };
2266 napi_value thisVar = nullptr;
2267 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2268 NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2269 napi_valuetype valueType = napi_undefined;
2270 napi_typeof(env, argv[0], &valueType);
2271 if (valueType != napi_number && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT)) {
2272 return result;
2273 }
2274 napi_get_undefined(env, &result);
2275 PhotoOutputNapi* photoOutputNapi = nullptr;
2276 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2277 if (status != napi_ok || photoOutputNapi == nullptr) {
2278 MEDIA_ERR_LOG("SetMovingPhotoVideoCodecType photoOutputNapi is null!");
2279 return result;
2280 }
2281 if (photoOutputNapi->GetPhotoOutput() != nullptr) {
2282 int32_t codecType;
2283 napi_get_value_int32(env, argv[PARAM0], &codecType);
2284 int32_t retCode = photoOutputNapi->GetPhotoOutput()->SetMovingPhotoVideoCodecType(codecType);
2285 if (retCode != 0 && !CameraNapiUtils::CheckError(env, retCode)) {
2286 return result;
2287 }
2288 }
2289 return result;
2290 }
2291
EnableQuickThumbnail(napi_env env,napi_callback_info info)2292 napi_value PhotoOutputNapi::EnableQuickThumbnail(napi_env env, napi_callback_info info)
2293 {
2294 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2295 MEDIA_ERR_LOG("SystemApi EnableQuickThumbnail is called!");
2296 return nullptr;
2297 }
2298 napi_status status;
2299 napi_value result = nullptr;
2300 size_t argc = ARGS_ONE;
2301 napi_value argv[ARGS_ONE] = { 0 };
2302 napi_value thisVar = nullptr;
2303 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2304 NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2305 napi_valuetype valueType = napi_undefined;
2306 napi_typeof(env, argv[0], &valueType);
2307 if (valueType != napi_boolean && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT)) {
2308 return result;
2309 }
2310 napi_get_undefined(env, &result);
2311 PhotoOutputNapi* photoOutputNapi = nullptr;
2312 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2313 bool thumbnailSwitch;
2314 if (status == napi_ok && photoOutputNapi != nullptr) {
2315 napi_get_value_bool(env, argv[PARAM0], &thumbnailSwitch);
2316 photoOutputNapi->isQuickThumbnailEnabled_ = thumbnailSwitch;
2317 int32_t retCode = photoOutputNapi->photoOutput_->SetThumbnail(thumbnailSwitch);
2318 if (retCode != 0 && !CameraNapiUtils::CheckError(env, retCode)) {
2319 return result;
2320 }
2321 }
2322 return result;
2323 }
2324
IsRawDeliverySupported(napi_env env,napi_callback_info info)2325 napi_value PhotoOutputNapi::IsRawDeliverySupported(napi_env env, napi_callback_info info)
2326 {
2327 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2328 MEDIA_ERR_LOG("SystemApi IsRawDeliverySupported is called!");
2329 return nullptr;
2330 }
2331 napi_status status;
2332 napi_value result = nullptr;
2333 size_t argc = ARGS_ZERO;
2334 napi_value argv[ARGS_ZERO];
2335 napi_value thisVar = nullptr;
2336
2337 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2338
2339 napi_get_undefined(env, &result);
2340 bool isSupported = false;
2341 PhotoOutputNapi* photoOutputNapi = nullptr;
2342 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2343 if (status == napi_ok && photoOutputNapi != nullptr) {
2344 int32_t retCode = photoOutputNapi->photoOutput_->IsRawDeliverySupported();
2345 isSupported = (retCode == 1);
2346 }
2347 napi_get_boolean(env, isSupported, &result);
2348 return result;
2349 }
2350
EnableRawDelivery(napi_env env,napi_callback_info info)2351 napi_value PhotoOutputNapi::EnableRawDelivery(napi_env env, napi_callback_info info)
2352 {
2353 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2354 MEDIA_ERR_LOG("SystemApi EnableRawDelivery is called!");
2355 return nullptr;
2356 }
2357 napi_status status;
2358 napi_value result = nullptr;
2359 size_t argc = ARGS_ONE;
2360 napi_value argv[ARGS_ONE] = { 0 };
2361 napi_value thisVar = nullptr;
2362 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2363 NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2364 napi_valuetype valueType = napi_undefined;
2365 napi_typeof(env, argv[0], &valueType);
2366 if (valueType != napi_boolean && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT)) {
2367 return result;
2368 }
2369 napi_get_undefined(env, &result);
2370 PhotoOutputNapi* photoOutputNapi = nullptr;
2371 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2372 bool rawDeliverySwitch;
2373 if (status == napi_ok && photoOutputNapi != nullptr) {
2374 napi_get_value_bool(env, argv[PARAM0], &rawDeliverySwitch);
2375 int32_t retCode = photoOutputNapi->photoOutput_->EnableRawDelivery(rawDeliverySwitch);
2376 if (retCode != 0 && !CameraNapiUtils::CheckError(env, retCode)) {
2377 return result;
2378 }
2379 }
2380 MEDIA_INFO_LOG("new rawPhotoListener and register surface consumer listener");
2381 auto rawSurface = photoOutputNapi->photoOutput_->rawPhotoSurface_;
2382 CHECK_ERROR_RETURN_RET_LOG(photoOutputNapi == nullptr, result, "photoOutputNapi is null!");
2383 if (rawSurface == nullptr) {
2384 MEDIA_ERR_LOG("rawPhotoSurface_ is null!");
2385 return result;
2386 }
2387 sptr<RawPhotoListener> rawPhotoListener = new (std::nothrow) RawPhotoListener(env, rawSurface);
2388 if (rawPhotoListener == nullptr) {
2389 MEDIA_ERR_LOG("failed to new rawPhotoListener");
2390 return result;
2391 }
2392 SurfaceError ret = rawSurface->RegisterConsumerListener((sptr<IBufferConsumerListener>&)rawPhotoListener);
2393 if (ret != SURFACE_ERROR_OK) {
2394 MEDIA_ERR_LOG("register surface consumer listener failed!");
2395 }
2396 photoOutputNapi->rawPhotoListener_ = rawPhotoListener;
2397 napi_value callback;
2398 napi_get_reference_value(env, rawCallback_, &callback);
2399 photoOutputNapi->rawPhotoListener_->SaveCallbackReference(CONST_CAPTURE_PHOTO_AVAILABLE, callback, false);
2400 return result;
2401 }
2402
GetActiveProfile(napi_env env,napi_callback_info info)2403 napi_value PhotoOutputNapi::GetActiveProfile(napi_env env, napi_callback_info info)
2404 {
2405 MEDIA_DEBUG_LOG("PhotoOutputNapi::GetActiveProfile is called");
2406 PhotoOutputNapi* photoOutputNapi = nullptr;
2407 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
2408 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
2409 MEDIA_ERR_LOG("PhotoOutputNapi::GetActiveProfile parse parameter occur error");
2410 return nullptr;
2411 }
2412 auto profile = photoOutputNapi->photoOutput_->GetPhotoProfile();
2413 if (profile == nullptr) {
2414 return CameraNapiUtils::GetUndefinedValue(env);
2415 }
2416 return CameraNapiObjProfile(*profile).GenerateNapiValue(env);
2417 }
2418
RegisterQuickThumbnailCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2419 void PhotoOutputNapi::RegisterQuickThumbnailCallbackListener(
2420 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2421 {
2422 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2423 MEDIA_ERR_LOG("SystemApi quickThumbnail on is called!");
2424 return;
2425 }
2426
2427 // Set callback for exposureStateChange
2428 if (thumbnailListener_ == nullptr) {
2429 if (!isQuickThumbnailEnabled_) {
2430 MEDIA_ERR_LOG("quickThumbnail is not enabled!");
2431 napi_throw_error(env, std::to_string(SESSION_NOT_RUNNING).c_str(), "");
2432 return;
2433 }
2434 thumbnailListener_ = new ThumbnailListener(env, photoOutput_);
2435 photoOutput_->SetThumbnailListener((sptr<IBufferConsumerListener>&)thumbnailListener_);
2436 }
2437 thumbnailListener_->SaveCallbackReference(eventName, callback, isOnce);
2438 }
2439
UnregisterQuickThumbnailCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2440 void PhotoOutputNapi::UnregisterQuickThumbnailCallbackListener(
2441 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2442 {
2443 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2444 MEDIA_ERR_LOG("SystemApi quickThumbnail off is called!");
2445 return;
2446 }
2447 if (!isQuickThumbnailEnabled_) {
2448 MEDIA_ERR_LOG("quickThumbnail is not enabled!");
2449 napi_throw_error(env, std::to_string(SESSION_NOT_RUNNING).c_str(), "");
2450 return;
2451 }
2452 if (thumbnailListener_ != nullptr) {
2453 thumbnailListener_->RemoveCallbackRef(eventName, callback);
2454 }
2455 }
2456
RegisterPhotoAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2457 void PhotoOutputNapi::RegisterPhotoAvailableCallbackListener(
2458 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2459 {
2460 if (sPhotoSurface_ == nullptr) {
2461 MEDIA_ERR_LOG("sPhotoSurface_ is null!");
2462 return;
2463 }
2464 if (photoListener_ == nullptr) {
2465 MEDIA_INFO_LOG("new photoListener and register surface consumer listener");
2466 sptr<PhotoListener> photoListener = new (std::nothrow) PhotoListener(env, sPhotoSurface_, photoOutput_);
2467 if (photoListener == nullptr) {
2468 MEDIA_ERR_LOG("photoListener is null!");
2469 return;
2470 }
2471 SurfaceError ret = sPhotoSurface_->RegisterConsumerListener((sptr<IBufferConsumerListener>&)photoListener);
2472 if (ret != SURFACE_ERROR_OK) {
2473 MEDIA_ERR_LOG("register surface consumer listener failed!");
2474 }
2475 photoListener_ = photoListener;
2476 }
2477 photoListener_->SaveCallback(CONST_CAPTURE_PHOTO_AVAILABLE, callback);
2478
2479 // Preconfig can't support rawPhotoListener.
2480 if (photoOutput_ != nullptr && profile_ != nullptr) {
2481 napi_ref rawCallback;
2482 napi_create_reference(env, callback, 1, &rawCallback);
2483 rawCallback_ = rawCallback;
2484 if (profile_->GetCameraFormat() == CAMERA_FORMAT_YUV_420_SP) {
2485 CreateMultiChannelPictureLisenter(env);
2486 }
2487 }
2488 }
2489
UnregisterPhotoAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2490 void PhotoOutputNapi::UnregisterPhotoAvailableCallbackListener(
2491 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2492 {
2493 if (photoListener_ != nullptr) {
2494 photoListener_->RemoveCallback(CONST_CAPTURE_PHOTO_AVAILABLE, callback);
2495 }
2496 if (rawPhotoListener_ != nullptr) {
2497 rawPhotoListener_->RemoveCallbackRef(CONST_CAPTURE_PHOTO_AVAILABLE, callback);
2498 }
2499 }
2500
RegisterDeferredPhotoProxyAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2501 void PhotoOutputNapi::RegisterDeferredPhotoProxyAvailableCallbackListener(
2502 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2503 {
2504 if (sPhotoSurface_ == nullptr) {
2505 MEDIA_ERR_LOG("sPhotoSurface_ is null!");
2506 return;
2507 }
2508 if (photoListener_ == nullptr) {
2509 MEDIA_INFO_LOG("new deferred photoListener and register surface consumer listener");
2510 sptr<PhotoListener> photoListener = new (std::nothrow) PhotoListener(env, sPhotoSurface_, photoOutput_);
2511 if (photoListener == nullptr) {
2512 MEDIA_ERR_LOG("failed to new photoListener!");
2513 return;
2514 }
2515 SurfaceError ret = sPhotoSurface_->RegisterConsumerListener((sptr<IBufferConsumerListener>&)photoListener);
2516 if (ret != SURFACE_ERROR_OK) {
2517 MEDIA_ERR_LOG("register surface consumer listener failed!");
2518 }
2519 photoListener_ = photoListener;
2520 }
2521 photoListener_->SaveCallback(CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE, callback);
2522 }
2523
UnregisterDeferredPhotoProxyAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2524 void PhotoOutputNapi::UnregisterDeferredPhotoProxyAvailableCallbackListener(
2525 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2526 {
2527 if (photoListener_ != nullptr) {
2528 photoListener_->RemoveCallback(CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE, callback);
2529 }
2530 }
2531
RegisterPhotoAssetAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2532 void PhotoOutputNapi::RegisterPhotoAssetAvailableCallbackListener(
2533 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2534 {
2535 if (sPhotoSurface_ == nullptr) {
2536 MEDIA_ERR_LOG("sPhotoSurface_ is null!");
2537 return;
2538 }
2539 if (photoOutput_ == nullptr) {
2540 MEDIA_ERR_LOG("photoOutput_ is null!");
2541 return;
2542 }
2543 if (photoOutput_->IsYuvOrHeifPhoto()) {
2544 CreateMultiChannelPictureLisenter(env);
2545 } else {
2546 CreateSingleChannelPhotoLisenter(env);
2547 }
2548 photoListener_->SaveCallback(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callback);
2549 }
2550
UnregisterPhotoAssetAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2551 void PhotoOutputNapi::UnregisterPhotoAssetAvailableCallbackListener(
2552 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2553 {
2554 if (photoListener_ != nullptr) {
2555 photoListener_->RemoveCallback(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callback);
2556 }
2557 }
2558
RegisterCaptureStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2559 void PhotoOutputNapi::RegisterCaptureStartCallbackListener(
2560 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2561 {
2562 if (photoOutputCallback_ == nullptr) {
2563 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2564 photoOutput_->SetCallback(photoOutputCallback_);
2565 }
2566 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_START, callback, isOnce);
2567 }
2568
UnregisterCaptureStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2569 void PhotoOutputNapi::UnregisterCaptureStartCallbackListener(
2570 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2571 {
2572 if (photoOutputCallback_ == nullptr) {
2573 MEDIA_ERR_LOG("photoOutputCallback is null");
2574 return;
2575 }
2576 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_START, callback);
2577 }
2578
RegisterCaptureStartWithInfoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2579 void PhotoOutputNapi::RegisterCaptureStartWithInfoCallbackListener(
2580 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2581 {
2582 if (photoOutputCallback_ == nullptr) {
2583 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2584 photoOutput_->SetCallback(photoOutputCallback_);
2585 }
2586 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_START_WITH_INFO, callback, isOnce);
2587 }
2588
UnregisterCaptureStartWithInfoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2589 void PhotoOutputNapi::UnregisterCaptureStartWithInfoCallbackListener(
2590 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2591 {
2592 if (photoOutputCallback_ == nullptr) {
2593 MEDIA_ERR_LOG("photoOutputCallback is null");
2594 return;
2595 }
2596 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_START_WITH_INFO, callback);
2597 }
2598
RegisterCaptureEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2599 void PhotoOutputNapi::RegisterCaptureEndCallbackListener(
2600 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2601 {
2602 if (photoOutputCallback_ == nullptr) {
2603 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2604 photoOutput_->SetCallback(photoOutputCallback_);
2605 }
2606 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_END, callback, isOnce);
2607 }
2608
UnregisterCaptureEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2609 void PhotoOutputNapi::UnregisterCaptureEndCallbackListener(
2610 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2611 {
2612 if (photoOutputCallback_ == nullptr) {
2613 MEDIA_ERR_LOG("photoOutputCallback is null");
2614 return;
2615 }
2616 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_END, callback);
2617 }
2618
RegisterFrameShutterCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2619 void PhotoOutputNapi::RegisterFrameShutterCallbackListener(
2620 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2621 {
2622 if (photoOutputCallback_ == nullptr) {
2623 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2624 photoOutput_->SetCallback(photoOutputCallback_);
2625 }
2626 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_FRAME_SHUTTER, callback, isOnce);
2627 }
2628
UnregisterFrameShutterCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2629 void PhotoOutputNapi::UnregisterFrameShutterCallbackListener(
2630 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2631 {
2632 if (photoOutputCallback_ == nullptr) {
2633 MEDIA_ERR_LOG("photoOutputCallback is null");
2634 return;
2635 }
2636 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_FRAME_SHUTTER, callback);
2637 }
2638
RegisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2639 void PhotoOutputNapi::RegisterErrorCallbackListener(
2640 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2641 {
2642 if (photoOutputCallback_ == nullptr) {
2643 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2644 photoOutput_->SetCallback(photoOutputCallback_);
2645 }
2646 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_ERROR, callback, isOnce);
2647 }
2648
UnregisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2649 void PhotoOutputNapi::UnregisterErrorCallbackListener(
2650 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2651 {
2652 if (photoOutputCallback_ == nullptr) {
2653 MEDIA_ERR_LOG("photoOutputCallback is null");
2654 return;
2655 }
2656 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_ERROR, callback);
2657 }
2658
RegisterFrameShutterEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2659 void PhotoOutputNapi::RegisterFrameShutterEndCallbackListener(
2660 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2661 {
2662 if (photoOutputCallback_ == nullptr) {
2663 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2664 photoOutput_->SetCallback(photoOutputCallback_);
2665 }
2666 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_FRAME_SHUTTER_END, callback, isOnce);
2667 }
2668
UnregisterFrameShutterEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2669 void PhotoOutputNapi::UnregisterFrameShutterEndCallbackListener(
2670 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2671 {
2672 if (photoOutputCallback_ == nullptr) {
2673 MEDIA_ERR_LOG("photoOutputCallback is null");
2674 return;
2675 }
2676 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_FRAME_SHUTTER_END, callback);
2677 }
2678
RegisterReadyCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2679 void PhotoOutputNapi::RegisterReadyCallbackListener(
2680 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2681 {
2682 if (photoOutputCallback_ == nullptr) {
2683 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2684 photoOutput_->SetCallback(photoOutputCallback_);
2685 }
2686 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_READY, callback, isOnce);
2687 }
2688
UnregisterReadyCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2689 void PhotoOutputNapi::UnregisterReadyCallbackListener(
2690 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2691 {
2692 if (photoOutputCallback_ == nullptr) {
2693 MEDIA_ERR_LOG("photoOutputCallback is null");
2694 return;
2695 }
2696 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_READY, callback);
2697 }
2698
RegisterEstimatedCaptureDurationCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2699 void PhotoOutputNapi::RegisterEstimatedCaptureDurationCallbackListener(
2700 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2701 {
2702 if (photoOutputCallback_ == nullptr) {
2703 photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2704 photoOutput_->SetCallback(photoOutputCallback_);
2705 }
2706 photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, callback, isOnce);
2707 }
2708
UnregisterEstimatedCaptureDurationCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2709 void PhotoOutputNapi::UnregisterEstimatedCaptureDurationCallbackListener(
2710 const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2711 {
2712 if (photoOutputCallback_ == nullptr) {
2713 MEDIA_ERR_LOG("photoOutputCallback is null");
2714 return;
2715 }
2716 photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, callback);
2717 }
2718
GetEmitterFunctions()2719 const PhotoOutputNapi::EmitterFunctions& PhotoOutputNapi::GetEmitterFunctions()
2720 {
2721 static const EmitterFunctions funMap = {
2722 { CONST_CAPTURE_QUICK_THUMBNAIL, {
2723 &PhotoOutputNapi::RegisterQuickThumbnailCallbackListener,
2724 &PhotoOutputNapi::UnregisterQuickThumbnailCallbackListener } },
2725 { CONST_CAPTURE_PHOTO_AVAILABLE, {
2726 &PhotoOutputNapi::RegisterPhotoAvailableCallbackListener,
2727 &PhotoOutputNapi::UnregisterPhotoAvailableCallbackListener } },
2728 { CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE, {
2729 &PhotoOutputNapi::RegisterDeferredPhotoProxyAvailableCallbackListener,
2730 &PhotoOutputNapi::UnregisterDeferredPhotoProxyAvailableCallbackListener } },
2731 { CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, {
2732 &PhotoOutputNapi::RegisterPhotoAssetAvailableCallbackListener,
2733 &PhotoOutputNapi::UnregisterPhotoAssetAvailableCallbackListener } },
2734 { CONST_CAPTURE_START, {
2735 &PhotoOutputNapi::RegisterCaptureStartCallbackListener,
2736 &PhotoOutputNapi::UnregisterCaptureStartCallbackListener } },
2737 { CONST_CAPTURE_END, {
2738 &PhotoOutputNapi::RegisterCaptureEndCallbackListener,
2739 &PhotoOutputNapi::UnregisterCaptureEndCallbackListener } },
2740 { CONST_CAPTURE_FRAME_SHUTTER, {
2741 &PhotoOutputNapi::RegisterFrameShutterCallbackListener,
2742 &PhotoOutputNapi::UnregisterFrameShutterCallbackListener } },
2743 { CONST_CAPTURE_ERROR, {
2744 &PhotoOutputNapi::RegisterErrorCallbackListener,
2745 &PhotoOutputNapi::UnregisterErrorCallbackListener } },
2746 { CONST_CAPTURE_FRAME_SHUTTER_END, {
2747 &PhotoOutputNapi::RegisterFrameShutterEndCallbackListener,
2748 &PhotoOutputNapi::UnregisterFrameShutterEndCallbackListener } },
2749 { CONST_CAPTURE_READY, {
2750 &PhotoOutputNapi::RegisterReadyCallbackListener,
2751 &PhotoOutputNapi::UnregisterReadyCallbackListener } },
2752 { CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, {
2753 &PhotoOutputNapi::RegisterEstimatedCaptureDurationCallbackListener,
2754 &PhotoOutputNapi::UnregisterEstimatedCaptureDurationCallbackListener } },
2755 { CONST_CAPTURE_START_WITH_INFO, {
2756 &PhotoOutputNapi::RegisterCaptureStartWithInfoCallbackListener,
2757 &PhotoOutputNapi::UnregisterCaptureStartWithInfoCallbackListener } } };
2758 return funMap;
2759 }
2760
On(napi_env env,napi_callback_info info)2761 napi_value PhotoOutputNapi::On(napi_env env, napi_callback_info info)
2762 {
2763 return ListenerTemplate<PhotoOutputNapi>::On(env, info);
2764 }
2765
Once(napi_env env,napi_callback_info info)2766 napi_value PhotoOutputNapi::Once(napi_env env, napi_callback_info info)
2767 {
2768 return ListenerTemplate<PhotoOutputNapi>::Once(env, info);
2769 }
2770
Off(napi_env env,napi_callback_info info)2771 napi_value PhotoOutputNapi::Off(napi_env env, napi_callback_info info)
2772 {
2773 return ListenerTemplate<PhotoOutputNapi>::Off(env, info);
2774 }
2775
IsAutoHighQualityPhotoSupported(napi_env env,napi_callback_info info)2776 napi_value PhotoOutputNapi::IsAutoHighQualityPhotoSupported(napi_env env, napi_callback_info info)
2777 {
2778 auto result = CameraNapiUtils::GetUndefinedValue(env);
2779 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2780 MEDIA_ERR_LOG("SystemApi IsAutoHighQualityPhotoSupported is called!");
2781 return result;
2782 }
2783 MEDIA_DEBUG_LOG("PhotoOutputNapi::IsAutoHighQualityPhotoSupported is called");
2784 PhotoOutputNapi* photoOutputNapi = nullptr;
2785 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
2786 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
2787 MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoHighQualityPhotoSupported parse parameter occur error");
2788 return result;
2789 }
2790 if (photoOutputNapi->photoOutput_ == nullptr) {
2791 MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoHighQualityPhotoSupported get native object fail");
2792 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
2793 return result;
2794 }
2795
2796 int32_t isAutoHighQualityPhotoSupported;
2797 int32_t retCode = photoOutputNapi->photoOutput_->IsAutoHighQualityPhotoSupported(isAutoHighQualityPhotoSupported);
2798 if (retCode == 0 && isAutoHighQualityPhotoSupported != -1) {
2799 napi_get_boolean(env, true, &result);
2800 return result;
2801 }
2802 MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoHighQualityPhotoSupported is not supported");
2803 napi_get_boolean(env, false, &result);
2804 return result;
2805 }
2806
IsAutoCloudImageEnhancementSupported(napi_env env,napi_callback_info info)2807 napi_value PhotoOutputNapi::IsAutoCloudImageEnhancementSupported(napi_env env, napi_callback_info info)
2808 {
2809 auto result = CameraNapiUtils::GetUndefinedValue(env);
2810 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2811 MEDIA_ERR_LOG("SystemApi IsAutoCloudImageEnhancementSupported is called!");
2812 return result;
2813 }
2814 MEDIA_DEBUG_LOG("PhotoOutputNapi::IsAutoCloudImageEnhancementSupported is called");
2815 PhotoOutputNapi* photoOutputNapi = nullptr;
2816 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
2817 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
2818 MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoCloudImageEnhancementSupported parse parameter occur error");
2819 return result;
2820 }
2821 if (photoOutputNapi->photoOutput_ == nullptr) {
2822 MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoCloudImageEnhancementSupported get native object fail");
2823 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
2824 return result;
2825 }
2826 bool isAutoCloudImageEnhancementSupported = false;
2827 int32_t retCode =
2828 photoOutputNapi->photoOutput_->IsAutoCloudImageEnhancementSupported(
2829 isAutoCloudImageEnhancementSupported);
2830 if (!CameraNapiUtils::CheckError(env, retCode)) {
2831 return nullptr;
2832 }
2833 napi_get_boolean(env, isAutoCloudImageEnhancementSupported, &result);
2834 MEDIA_DEBUG_LOG("PhotoOutputNapi::IsAutoCloudImageEnhancementSupported is %{public}d",
2835 isAutoCloudImageEnhancementSupported);
2836 return result;
2837 }
2838
EnableAutoHighQualityPhoto(napi_env env,napi_callback_info info)2839 napi_value PhotoOutputNapi::EnableAutoHighQualityPhoto(napi_env env, napi_callback_info info)
2840 {
2841 auto result = CameraNapiUtils::GetUndefinedValue(env);
2842 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2843 MEDIA_ERR_LOG("SystemApi EnableAutoHighQualityPhoto is called!");
2844 return result;
2845 }
2846 MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto is called");
2847 PhotoOutputNapi* photoOutputNapi = nullptr;
2848 bool isEnable;
2849 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isEnable);
2850 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
2851 MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto parse parameter occur error");
2852 return result;
2853 }
2854 if (photoOutputNapi->photoOutput_ == nullptr) {
2855 MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto get native object fail");
2856 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
2857 return result;
2858 }
2859
2860 int32_t retCode = photoOutputNapi->photoOutput_->EnableAutoHighQualityPhoto(isEnable);
2861 if (!CameraNapiUtils::CheckError(env, retCode)) {
2862 MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto fail %{public}d", retCode);
2863 }
2864 return result;
2865 }
2866
EnableAutoCloudImageEnhancement(napi_env env,napi_callback_info info)2867 napi_value PhotoOutputNapi::EnableAutoCloudImageEnhancement(napi_env env, napi_callback_info info)
2868 {
2869 auto result = CameraNapiUtils::GetUndefinedValue(env);
2870 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2871 MEDIA_ERR_LOG("SystemApi EnableAutoCloudImageEnhancement is called!");
2872 return result;
2873 }
2874 MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement is called");
2875 PhotoOutputNapi* photoOutputNapi = nullptr;
2876 bool isEnable;
2877 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isEnable);
2878 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
2879 MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement parse parameter occur error");
2880 return result;
2881 }
2882 if (photoOutputNapi->photoOutput_ == nullptr) {
2883 MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement get native object fail");
2884 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
2885 return result;
2886 }
2887
2888 int32_t retCode = photoOutputNapi->photoOutput_->EnableAutoCloudImageEnhancement(isEnable);
2889 if (!CameraNapiUtils::CheckError(env, retCode)) {
2890 MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement fail %{public}d", retCode);
2891 return result;
2892 }
2893 MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement success");
2894 return result;
2895 }
2896
IsDepthDataDeliverySupported(napi_env env,napi_callback_info info)2897 napi_value PhotoOutputNapi::IsDepthDataDeliverySupported(napi_env env, napi_callback_info info)
2898 {
2899 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2900 MEDIA_ERR_LOG("SystemApi IsDepthDataDeliverySupported is called!");
2901 return nullptr;
2902 }
2903 MEDIA_DEBUG_LOG("PhotoOutputNapi::IsDepthDataDeliverySupported is called");
2904 PhotoOutputNapi* photoOutputNapi = nullptr;
2905 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
2906 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
2907 MEDIA_ERR_LOG("PhotoOutputNapi::IsDepthDataDeliverySupported parse parameter occur error");
2908 return nullptr;
2909 }
2910 if (photoOutputNapi->photoOutput_ == nullptr) {
2911 MEDIA_ERR_LOG("PhotoOutputNapi::IsDepthDataDeliverySupported get native object fail");
2912 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
2913 return nullptr;
2914 }
2915 napi_value result = nullptr;
2916 int32_t retCode = photoOutputNapi->photoOutput_->IsDepthDataDeliverySupported();
2917 if (retCode == 0) {
2918 napi_get_boolean(env, true, &result);
2919 return result;
2920 }
2921 MEDIA_ERR_LOG("PhotoOutputNapi::IsDepthDataDeliverySupported is not supported");
2922 napi_get_boolean(env, false, &result);
2923 return result;
2924 }
2925
EnableDepthDataDelivery(napi_env env,napi_callback_info info)2926 napi_value PhotoOutputNapi::EnableDepthDataDelivery(napi_env env, napi_callback_info info)
2927 {
2928 if (!CameraNapiSecurity::CheckSystemApp(env)) {
2929 MEDIA_ERR_LOG("SystemApi EnableDepthDataDelivery is called!");
2930 return nullptr;
2931 }
2932 MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableDepthDataDelivery is called");
2933 PhotoOutputNapi* photoOutputNapi = nullptr;
2934 bool isEnable;
2935 CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isEnable);
2936 if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
2937 MEDIA_ERR_LOG("PhotoOutputNapi::EnableDepthDataDelivery parse parameter occur error");
2938 return nullptr;
2939 }
2940 if (photoOutputNapi->photoOutput_ == nullptr) {
2941 MEDIA_ERR_LOG("PhotoOutputNapi::EnableDepthDataDelivery get native object fail");
2942 CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
2943 return nullptr;
2944 }
2945
2946 int32_t retCode = photoOutputNapi->photoOutput_->EnableDepthDataDelivery(isEnable);
2947 if (!CameraNapiUtils::CheckError(env, retCode)) {
2948 MEDIA_ERR_LOG("PhotoOutputNapi::EnableDepthDataDelivery fail %{public}d", retCode);
2949 }
2950 return CameraNapiUtils::GetUndefinedValue(env);
2951 }
2952 } // namespace CameraStandard
2953 } // namespace OHOS