1 /*
2 * Copyright (c) 2021 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 "core/components/camera/camera_element.h"
17
18 #if defined(PREVIEW)
19 #include "base/i18n/localization.h"
20 #endif
21 #include "core/components/video/render_texture.h"
22
23 namespace OHOS::Ace {
24 namespace {
25
26 const char CALLBACK_COMPLETE[] = "complete";
27 const char IS_SUCCESS[] = "isSucceed";
28 const char PHOTO_PATH[] = "uri";
29 const char NULL_STRING[] = "";
30 const char ERROR_MSG[] = "errormsg";
31 const char ERROR_CODE[] = "errorcode";
32
GetStringFromMap(const std::map<std::string,std::string> & map,const std::string & key)33 inline std::string GetStringFromMap(const std::map<std::string, std::string>& map, const std::string& key)
34 {
35 auto iter = map.find(key);
36 if (iter != map.end()) {
37 return iter->second;
38 }
39 return NULL_STRING;
40 }
41
42 #ifndef OHOS_STANDARD_SYSTEM
GetSizeFromQuality(const std::string & quality)43 inline int32_t GetSizeFromQuality(const std::string& quality)
44 {
45 int32_t qualityInt;
46 if (quality == "high") {
47 qualityInt = 2;
48 } else if (quality == "low") {
49 qualityInt = 0;
50 } else {
51 qualityInt = 1;
52 }
53 return qualityInt;
54 }
55 #endif
56
57 } // namespace
58
~CameraElement()59 CameraElement::~CameraElement()
60 {
61 ReleasePlatformResource();
62 }
63
ReleasePlatformResource()64 void CameraElement::ReleasePlatformResource()
65 {
66 #ifdef OHOS_STANDARD_SYSTEM
67 StopPreview();
68 if (camera_) {
69 camera_->Release();
70 camera_.Reset();
71 }
72 #else
73 callbackIds_.clear();
74 auto context = context_.Upgrade();
75 if (!context) {
76 return;
77 }
78
79 if (texture_) {
80 auto platformTaskExecutor =
81 SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
82
83 // Release camera first.
84 if (camera_) {
85 ReleaseDeclarativePara();
86 camera_->Release();
87
88 if (platformTaskExecutor.IsRunOnCurrentThread()) {
89 camera_.Reset();
90 } else {
91 // Make sure it's destroyed when it's release task done.
92 platformTaskExecutor.PostTask([camera = camera_]() {}, "ArkUICameraResourceRelease");
93 }
94 }
95
96 if (platformTaskExecutor.IsRunOnCurrentThread()) {
97 texture_->Release();
98 texture_.Reset();
99 } else {
100 #if defined(ENABLE_NATIVE_VIEW)
101 texture_->Release();
102 // Make sure it's destroyed when it's release task done.
103 platformTaskExecutor.PostTask([texture = texture_]() {}, "ArkUICameraTextureReleaseCheck");
104 #else
105 auto gpuTaskExecutor =
106 SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::GPU);
107 // Release texture after paint.
108 auto weak = AceType::WeakClaim(AceType::RawPtr(texture_));
109 gpuTaskExecutor.PostTask([weak, platformTaskExecutor]() {
110 auto texture = weak.Upgrade();
111 if (texture == nullptr) {
112 LOGE("texture is nullptr");
113 return;
114 }
115 texture->Release();
116 // Make sure it's destroyed when it's release task done.
117 platformTaskExecutor.PostTask([texture]() {}, "ArkUICameraTextureReleaseCheck");
118 }, "ArkUICameraTextureRelease");
119 #endif
120 }
121 }
122 #endif
123 }
124
Prepare(const WeakPtr<Element> & parent)125 void CameraElement::Prepare(const WeakPtr<Element>& parent)
126 {
127 auto themeManager = GetThemeManager();
128 if (!themeManager) {
129 return;
130 }
131
132 auto cameraComponent = AceType::DynamicCast<CameraComponent>(component_);
133 theme_ = themeManager->GetTheme<CameraTheme>();
134 if (cameraComponent) {
135 #ifndef OHOS_STANDARD_SYSTEM
136 InitDeclarativePara(cameraComponent);
137 #endif
138 #if defined(PREVIEW)
139 textDirection_ = cameraComponent->GetTextDirection();
140 #endif
141 InitEvent(cameraComponent);
142 SetMethodCall(cameraComponent);
143 CreatePlatformResource();
144 }
145
146 RenderElement::Prepare(parent);
147 if (renderNode_) {
148 auto renderTexture = AceType::DynamicCast<RenderTexture>(renderNode_);
149 renderTexture->SetTextureSizeChange(
150 [weak = WeakClaim(this)](int64_t textureId, int32_t textureWidth, int32_t textureHeight) {
151 auto cameraElement = weak.Upgrade();
152 if (cameraElement) {
153 cameraElement->OnTextureSize(textureId, textureWidth, textureHeight);
154 }
155 });
156 renderTexture->SetHiddenChangeEvent(
157 [weak = WeakClaim(this)](bool hidden) {
158 auto cameraElement = weak.Upgrade();
159 if (cameraElement) {
160 cameraElement->HiddenChange(hidden);
161 }
162 });
163 #if OHOS_STANDARD_SYSTEM
164 renderTexture->SetTextureOffsetChange(
165 [weak = WeakClaim(this)](int64_t textureId, int32_t x, int32_t y) {
166 auto cameraElement = weak.Upgrade();
167 if (cameraElement) {
168 cameraElement->OnTextureOffset(textureId, x, y);
169 }
170 });
171 #else
172 renderTexture->SetIsAddGaussianFuzzy(false);
173 #endif
174 }
175 }
176
HiddenChange(bool hidden)177 void CameraElement::HiddenChange(bool hidden)
178 {
179 if (cameraState_ == CameraState::STATE_DISABLE) {
180 LOGE("CameraElement: CameraState is not enable when hidden change.");
181 return;
182 }
183
184 if (hidden) {
185 LOGI("CameraElement::HiddenChange: hidden.");
186 ReleasePlatformResource();
187 } else {
188 LOGI("CameraElement::HiddenChange: show.");
189 CreatePlatformResource();
190 }
191 }
192
InitEvent(const RefPtr<CameraComponent> & cameraComponent)193 void CameraElement::InitEvent(const RefPtr<CameraComponent>& cameraComponent)
194 {
195 if (!cameraComponent->GetErrorEventId().IsEmpty()) {
196 onError_ = AceAsyncEvent<void(const std::string&)>::Create(cameraComponent->GetErrorEventId(), context_);
197 }
198 }
199
OnTextureSize(int64_t textureId,int32_t textureWidth,int32_t textureHeight)200 void CameraElement::OnTextureSize(int64_t textureId, int32_t textureWidth, int32_t textureHeight)
201 {
202 LOGI("CameraElement::OnTextureSize");
203 auto renderTexture = AceType::DynamicCast<RenderTexture>(renderNode_);
204 if (!renderTexture || !camera_) {
205 LOGI("CameraElement: renderNode is not renderTexture type or camera is null..");
206 return;
207 }
208
209 #ifdef OHOS_STANDARD_SYSTEM
210 if (renderTexture->GetFit() == ImageFit::FILL) {
211 LOGI("CameraElement:OnTextureSize %{public}d %{public}d ", textureWidth, textureHeight);
212 camera_->OnCameraSizeChange(textureWidth, textureHeight);
213 }
214 #else
215 if (!texture_) {
216 LOGI("CameraElement: texture is null.");
217 return;
218 }
219
220 if (renderTexture->IsComponentSize() && renderTexture->GetFit() == ImageFit::FILL) {
221 if (isSetResolution_) {
222 camera_->SetPreViewSize(resolutionWidth_, resolutionHeight_);
223 } else {
224 camera_->SetPreViewSize(textureWidth, textureHeight);
225 }
226 renderTexture->SetIsComponentSize(false);
227 } else {
228 texture_->OnSize(textureId, textureWidth, textureHeight);
229 }
230 #endif
231 }
232
SetNewComponent(const RefPtr<Component> & newComponent)233 void CameraElement::SetNewComponent(const RefPtr<Component>& newComponent)
234 {
235 if (newComponent == nullptr) {
236 Element::SetNewComponent(newComponent);
237 return;
238 }
239
240 auto cameraComponent = AceType::DynamicCast<CameraComponent>(newComponent);
241 if (cameraComponent) {
242 #ifdef OHOS_STANDARD_SYSTEM
243 cameraComponent->SetFit(ImageFit::FILL);
244 #else
245 if (devicePosition_ == cameraComponent->GetDevicePosition()) {
246 UpdateCamera(cameraComponent);
247 } else {
248 UpdateCamera(cameraComponent);
249 if (cameraState_ != CameraState::STATE_DISABLE) {
250 if (renderNode_) {
251 auto renderTexture = AceType::DynamicCast<RenderTexture>(renderNode_);
252 if (renderTexture) {
253 renderTexture->SetIsAddGaussianFuzzy(true);
254 }
255 }
256 CreatePlatformResource();
257 }
258 }
259 #endif
260 }
261 Element::SetNewComponent(newComponent);
262 }
263
264 #ifdef OHOS_STANDARD_SYSTEM
OnTextureOffset(int64_t textureId,int32_t x,int32_t y)265 void CameraElement::OnTextureOffset(int64_t textureId, int32_t x, int32_t y)
266 {
267 LOGI("CameraElement::OnTextureOffset");
268 auto renderTexture = AceType::DynamicCast<RenderTexture>(renderNode_);
269 if (!renderTexture) {
270 LOGI("CameraElement::OnTextureSize: renderNode is not renderTexture type.");
271 return;
272 }
273
274 if (camera_ && renderTexture->GetFit() == ImageFit::FILL) {
275 LOGI("Camera:OnTextureOffset %{public}d %{public}d", x, y);
276 camera_->OnCameraOffsetChange(x, y);
277 }
278 }
279
CreateCamera()280 void CameraElement::CreateCamera()
281 {
282 LOGI("CameraElement::CreateCamera");
283 camera_ = AceType::MakeRefPtr<Camera>(context_);
284 InitListener();
285 camera_->SetRenderNode(GetRenderNode());
286 camera_->Create(nullptr);
287 StartPreview();
288 }
289
OnRecorderCallBack(const std::map<std::string,std::string> & result)290 void CameraElement::OnRecorderCallBack(const std::map<std::string, std::string>& result)
291 {
292 if (recorderBackId_.empty()) {
293 return;
294 }
295
296 std::string param = std::string("{\"arguments\":[");
297 if (GetStringFromMap(result, IS_SUCCESS) == "1") {
298 param.append("{\"")
299 .append(PHOTO_PATH)
300 .append("\":\"file://")
301 .append(GetStringFromMap(result, PHOTO_PATH))
302 .append("\"}],\"method\":\"success\"}");
303 ExecuteJsCallback(recorderBackId_, param);
304 } else if (GetStringFromMap(result, IS_SUCCESS) != "1") {
305 param.append("{\"")
306 .append(ERROR_MSG)
307 .append("\":\"")
308 .append(GetStringFromMap(result, ERROR_MSG))
309 .append("\", \"")
310 .append(ERROR_CODE)
311 .append("\":\"")
312 .append(GetStringFromMap(result, ERROR_CODE))
313 .append("\"}],\"method\":\"fail\"}");
314 ExecuteJsCallback(recorderBackId_, param);
315 }
316
317 std::string complete = std::string("{\"arguments\":[{\"")
318 .append(CALLBACK_COMPLETE)
319 .append("\":\"\"}],\"method\":\"complete\"}");
320 ExecuteJsCallback(recorderBackId_, complete);
321 }
322
StartPreview()323 void CameraElement::StartPreview()
324 {
325 if (camera_ && !isPreViewing_) {
326 camera_->StartPreview();
327 isPreViewing_ = true;
328 }
329 }
330
StopPreview()331 void CameraElement::StopPreview()
332 {
333 if (camera_ && isPreViewing_) {
334 camera_->Stop(true);
335 isPreViewing_ = false;
336 }
337 }
338
TakePhoto(const Size & size)339 void CameraElement::TakePhoto(const Size& size)
340 {
341 if (camera_) {
342 camera_->TakePhoto(size);
343 }
344 }
345
StartRecord()346 void CameraElement::StartRecord()
347 {
348 LOGI("CameraElement::StartRecord.");
349 if (camera_ && !isRecording_) {
350 camera_->StartRecord();
351 isRecording_ = true;
352 }
353 }
354
CloseRecorder(const std::string & params)355 void CameraElement::CloseRecorder(const std::string& params)
356 {
357 LOGI("CameraElement::CloseRecorder.");
358 auto context = context_.Upgrade();
359 if (!context) {
360 LOGE("fail to get context");
361 return;
362 }
363
364 if (camera_ && isRecording_) {
365 recorderBackId_ = params;
366
367 context->GetTaskExecutor()->PostTask(
368 [weak = WeakClaim(this)] {
369 auto cameraElement = weak.Upgrade();
370 if (cameraElement) {
371 cameraElement->CloseRecorder();
372 }
373 },
374 TaskExecutor::TaskType::PLATFORM, "ArkUICameraCloseRecorder");
375 isRecording_ = false;
376 }
377 }
378
CloseRecorder()379 void CameraElement::CloseRecorder()
380 {
381 if (camera_) {
382 LOGI("CameraElement:CloseRecorder Task");
383 camera_->Stop(false);
384 }
385 }
386
387 #else
UpdateCamera(const RefPtr<CameraComponent> & cameraComponent)388 void CameraElement::UpdateCamera(const RefPtr<CameraComponent> &cameraComponent)
389 {
390 if (flash_ != cameraComponent->GetFlash()) {
391 flash_ = cameraComponent->GetFlash();
392 if (camera_) {
393 camera_->SetFlashMode(flash_);
394 }
395 }
396 devicePosition_ = cameraComponent->GetDevicePosition();
397 if (texture_) {
398 cameraComponent->SetTextureId(texture_->GetId());
399 cameraComponent->SetFit(ImageFit::CONTAIN);
400
401 #if defined(IOS_PLATFORM)
402 cameraComponent->SetFit(ImageFit::COVER);
403 #endif
404
405 cameraComponent->SetSrcWidth(preViewWidth_);
406 cameraComponent->SetSrcHeight(preViewHeight_);
407 }
408 }
409
CreateTexture()410 void CameraElement::CreateTexture()
411 {
412 auto context = context_.Upgrade();
413 if (!context) {
414 return;
415 }
416
417 auto uiTaskExecutor =
418 SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
419 auto errorCallback = [weak = WeakClaim(this), uiTaskExecutor](
420 const std::string& errorcode, const std::string& errormsg) {
421 uiTaskExecutor.PostTask([weak, errorcode, errormsg] {
422 auto cameraElement = weak.Upgrade();
423 if (cameraElement) {
424 cameraElement->OnError(errorcode, errormsg);
425 }
426 }, "ArkUICameraErrorCallback");
427 };
428 texture_ = AceType::MakeRefPtr<Texture>(context_, errorCallback);
429
430 texture_->Create([weak = WeakClaim(this), errorCallback](int64_t id) mutable {
431 auto cameraElement = weak.Upgrade();
432 if (cameraElement) {
433 cameraElement->CreateCamera(id, std::move(errorCallback));
434 }
435 });
436 }
437
CreateCamera(int64_t id,ErrorCallback && errorCallback)438 void CameraElement::CreateCamera(int64_t id, ErrorCallback&& errorCallback)
439 {
440 camera_ = AceType::MakeRefPtr<Camera>(id, context_, std::move(errorCallback), devicePosition_);
441 InitListener();
442 if (theme_) {
443 camera_->SetBufferSize(theme_->GetBufferSize());
444 }
445 camera_->SetDeviceOrientation(
446 SystemProperties::GetDeviceOrientation() == DeviceOrientation::PORTRAIT);
447 camera_->Create(nullptr);
448 HandleDeclarativePara();
449 }
450
OnPreViewSizeChange(int32_t preViewWidth,int32_t preViewHeight)451 void CameraElement::OnPreViewSizeChange(int32_t preViewWidth, int32_t preViewHeight)
452 {
453 auto camera = AceType::MakeRefPtr<CameraComponent>();
454 camera->SetTextureId(texture_->GetId());
455 camera->SetFit(ImageFit::CONTAIN);
456
457 #if defined(IOS_PLATFORM)
458 camera->SetFit(ImageFit::COVER);
459 #endif
460
461 camera->SetSrcWidth(preViewWidth);
462 camera->SetSrcHeight(preViewHeight);
463 preViewWidth_ = preViewWidth;
464 preViewHeight_ = preViewHeight;
465
466 if (renderNode_ != nullptr) {
467 renderNode_->Update(camera);
468 }
469 }
470
InitDeclarativePara(const RefPtr<CameraComponent> & cameraComponent)471 void CameraElement::InitDeclarativePara(const RefPtr<CameraComponent>& cameraComponent)
472 {
473 auto context = context_.Upgrade();
474 if (!context) {
475 return;
476 }
477
478 if (context->GetIsDeclarative()) {
479 cameraId_ = cameraComponent->GetCameraId();
480 isSetResolution_ = cameraComponent->IsSetResolution();
481 if (isSetResolution_) {
482 resolutionWidth_ = cameraComponent->GetResolutionWidth();
483 resolutionHeight_ = cameraComponent->GetResolutionHeight();
484 }
485 }
486 }
487
HandleDeclarativePara()488 void CameraElement::HandleDeclarativePara()
489 {
490 auto context = context_.Upgrade();
491 if (!context) {
492 return;
493 }
494
495 if (context->GetIsDeclarative() && camera_) {
496 camera_->ChangeCameraComponentId(true, cameraId_);
497 }
498 }
499
ReleaseDeclarativePara()500 void CameraElement::ReleaseDeclarativePara()
501 {
502 auto context = context_.Upgrade();
503 if (!context) {
504 return;
505 }
506
507 if (context->GetIsDeclarative() && camera_) {
508 camera_->ChangeCameraComponentId(false, cameraId_);
509 }
510 }
511
OnTextureRefresh()512 void CameraElement::OnTextureRefresh()
513 {
514 if (renderNode_) {
515 renderNode_->MarkNeedRender();
516 }
517 }
518 #endif
519
OnPrepared()520 void CameraElement::OnPrepared()
521 {
522 LOGI("CameraElement::OnPrepared");
523 auto renderTexture = AceType::DynamicCast<RenderTexture>(renderNode_);
524 if (!renderTexture) {
525 LOGE("CameraElement: the renderNode is not renderTexture type.");
526 return;
527 }
528
529 auto camera = AceType::MakeRefPtr<CameraComponent>();
530 camera->SetFit(ImageFit::FILL);
531 #ifndef OHOS_STANDARD_SYSTEM
532 camera->SetTextureId(texture_->GetId());
533 renderTexture->SetIsComponentSize(true);
534 #endif
535 renderTexture->Update(camera);
536 cameraState_ = CameraState::STATE_ENABLE;
537
538 #ifndef OHOS_STANDARD_SYSTEM
539 renderTexture->OnLayout();
540 camera_->SetFlashMode(flash_);
541 #endif
542 }
543
CreatePlatformResource()544 void CameraElement::CreatePlatformResource()
545 {
546 cameraState_ = CameraState::STATE_DISABLE;
547 ReleasePlatformResource();
548
549 auto context = context_.Upgrade();
550 if (!context) {
551 LOGE("fail to get context");
552 return;
553 }
554
555 #ifdef OHOS_STANDARD_SYSTEM
556 context->GetTaskExecutor()->PostTask(
557 [weak = WeakClaim(this)] {
558 auto cameraElement = weak.Upgrade();
559 if (cameraElement) {
560 cameraElement->CreateCamera();
561 }
562 },
563 TaskExecutor::TaskType::PLATFORM, "ArkUICameraCreatePlatformResource");
564 #else
565 CreateTexture();
566 #endif
567 }
568
SetMethodCall(const RefPtr<CameraComponent> & cameraComponent)569 void CameraElement::SetMethodCall(const RefPtr<CameraComponent>& cameraComponent)
570 {
571 auto cameraController = cameraComponent->GetCameraController();
572 if (cameraController) {
573 auto context = context_.Upgrade();
574 if (!context) {
575 return;
576 }
577 auto uiTaskExecutor =
578 SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
579 cameraController->SetTakePhotoImpl(
580 [weak = WeakClaim(this), uiTaskExecutor](
581 const TakePhotoParams& params) {
582 uiTaskExecutor.PostTask([weak, params] {
583 auto cameraElement = weak.Upgrade();
584 if (cameraElement) {
585 cameraElement->TakePhoto(params);
586 }
587 }, "ArkUICameraControllerTakePhoto");
588 });
589 #ifdef OHOS_STANDARD_SYSTEM
590 cameraController->SetStartRecordImpl(
591 [weak = WeakClaim(this), uiTaskExecutor]() {
592 uiTaskExecutor.PostTask([weak] {
593 auto cameraElement = weak.Upgrade();
594 if (cameraElement) {
595 cameraElement->StartRecord();
596 }
597 }, "ArkUICameraStartRecord");
598 });
599
600 cameraController->SetCloseRecorderImpl(
601 [weak = WeakClaim(this), uiTaskExecutor](
602 const std::string& params) {
603 uiTaskExecutor.PostTask([weak, params] {
604 auto cameraElement = weak.Upgrade();
605 if (cameraElement) {
606 cameraElement->CloseRecorder(params);
607 }
608 }, "ArkUICameraControllerCloseRecorder");
609 });
610 #endif
611 }
612 }
613
InitListener()614 void CameraElement::InitListener()
615 {
616 auto context = context_.Upgrade();
617 if (!context) {
618 return;
619 }
620
621 if (!camera_) {
622 LOGE("CameraElement::InitListener: camera is null.");
623 return;
624 }
625
626 auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
627 auto takePhotoListener = [weak = WeakClaim(this), uiTaskExecutor](
628 const std::map<std::string, std::string> result) {
629 uiTaskExecutor.PostTask([weak, result] {
630 auto camera = weak.Upgrade();
631 if (camera) {
632 camera->OnTakePhotoCallBack(result);
633 }
634 }, "ArkUICameraTakePhotoCallBack");
635 };
636 camera_->AddTakePhotoListener(takePhotoListener);
637
638 auto onError = [weak = WeakClaim(this), uiTaskExecutor](const std::string& errorcode, const std::string& errormsg) {
639 uiTaskExecutor.PostTask([weak, errorcode, errormsg] {
640 auto camera = weak.Upgrade();
641 if (camera) {
642 camera->OnError(errorcode, errormsg);
643 }
644 }, "ArkUICameraError");
645 };
646 camera_->AddErrorListener(onError);
647
648 auto preparedCallBack = [weak = WeakClaim(this), uiTaskExecutor]() {
649 uiTaskExecutor.PostTask([weak] {
650 auto camera = weak.Upgrade();
651 if (camera) {
652 camera->OnPrepared();
653 }
654 }, "ArkUICameraPrepared");
655 };
656 camera_->AddPrepareEventListener(preparedCallBack);
657
658 #ifdef OHOS_STANDARD_SYSTEM
659 auto recorderCallBack = [weak = WeakClaim(this), uiTaskExecutor](
660 const std::map<std::string, std::string> result) {
661 uiTaskExecutor.PostTask([weak, result] {
662 auto camera = weak.Upgrade();
663 if (camera) {
664 camera->OnRecorderCallBack(result);
665 }
666 }, "ArkUICameraRecorder");
667 };
668 camera_->AddRecordListener(recorderCallBack);
669 #else
670 auto onSizeChangeListener = [weak = WeakClaim(this), uiTaskExecutor](
671 int32_t preViewWidth, int32_t preViewHeight) {
672 uiTaskExecutor.PostTask([weak, preViewWidth, preViewHeight] {
673 auto camera = weak.Upgrade();
674 if (camera) {
675 camera->OnPreViewSizeChange(preViewWidth, preViewHeight);
676 }
677 }, "ArkUICameraPreviewSizeChange");
678 };
679 camera_->AddPreViewSizeChang(onSizeChangeListener);
680
681 if (texture_) {
682 auto onTextureRefresh = [weak = WeakClaim(this), uiTaskExecutor]() {
683 uiTaskExecutor.PostSyncTask([weak] {
684 auto camera = weak.Upgrade();
685 if (camera) {
686 camera->OnTextureRefresh();
687 }
688 }, "ArkUICameraTextureRefresh");
689 };
690 texture_->SetRefreshListener(onTextureRefresh);
691 }
692 #endif
693 }
694
OnTakePhotoCallBack(const std::map<std::string,std::string> & result)695 void CameraElement::OnTakePhotoCallBack(const std::map<std::string, std::string>& result)
696 {
697 if (GetStringFromMap(result, IS_SUCCESS) == "1" && !callbackIds_.success.empty()) {
698 std::string param = std::string("{\"")
699 .append(PHOTO_PATH)
700 .append("\":\"file://")
701 .append(GetStringFromMap(result, PHOTO_PATH))
702 .append("\"}");
703 ExecuteJsCallback(callbackIds_.success, param);
704 } else if (GetStringFromMap(result, IS_SUCCESS) != "1" && !callbackIds_.fail.empty()) {
705 std::string param = std::string("{\"")
706 .append(ERROR_MSG)
707 .append("\":\"")
708 .append(GetStringFromMap(result, ERROR_MSG))
709 .append("\", \"")
710 .append(ERROR_CODE)
711 .append("\":\"")
712 .append(GetStringFromMap(result, ERROR_CODE))
713 .append("\"}");
714 ExecuteJsCallback(callbackIds_.fail, param);
715 }
716 if (!callbackIds_.complete.empty()) {
717 std::string param = std::string("{\"").append(CALLBACK_COMPLETE).append("\":\"\"}");
718 ExecuteJsCallback(callbackIds_.complete, param);
719 }
720 }
721
722 #if defined(PREVIEW)
CreateErrorText(const std::string & errorMsg)723 const RefPtr<Component> CameraElement::CreateErrorText(const std::string& errorMsg)
724 {
725 auto text = AceType::MakeRefPtr<TextComponent>(errorMsg);
726 text->SetTextStyle(theme_->GetErrorTextStyle());
727 text->SetTextDirection(textDirection_);
728
729 std::list<RefPtr<Component>> childrenAlign;
730 childrenAlign.emplace_back(text);
731
732 return AceType::MakeRefPtr<AlignComponent>(childrenAlign, Alignment::TOP_CENTER);
733 }
734
UpdateChildInner(const RefPtr<Component> & childComponent)735 void CameraElement::UpdateChildInner(const RefPtr<Component>& childComponent)
736 {
737 const auto& child = children_.empty() ? nullptr : children_.front();
738 UpdateChild(child, childComponent);
739 }
740 #endif
741
OnError(const std::string & errorcode,const std::string & errormsg)742 void CameraElement::OnError(const std::string& errorcode, const std::string& errormsg)
743 {
744 #if defined(PREVIEW)
745 std::string errorDescription = "This component is not supported on PC Preview.";
746 UpdateChildInner(CreateErrorText(errorDescription));
747 #endif
748 if (onError_) {
749 std::string param = std::string("\"error\",{\"")
750 .append(ERROR_MSG)
751 .append("\":\"")
752 .append(errormsg)
753 .append("\", \"")
754 .append(ERROR_CODE)
755 .append("\":\"")
756 .append(errorcode)
757 .append("\"}");
758 onError_(param);
759 }
760 cameraState_ = CameraState::STATE_UNDEFINED;
761 }
762
TakePhoto(const TakePhotoParams & params)763 void CameraElement::TakePhoto(const TakePhotoParams& params)
764 {
765 if (cameraState_ != CameraState::STATE_ENABLE) {
766 LOGE("CameraState is not enable.");
767 return;
768 }
769
770 auto context = context_.Upgrade();
771 if (!context) {
772 LOGE("fail to get context");
773 return;
774 }
775
776 if (!camera_) {
777 LOGE("Camera is null.");
778 return;
779 }
780
781 callbackIds_.clear();
782 callbackIds_ = params;
783 #ifdef OHOS_STANDARD_SYSTEM
784 context->GetTaskExecutor()->PostTask(
785 [weak = WeakClaim(this)] {
786 auto cameraElement = weak.Upgrade();
787 if (cameraElement) {
788 cameraElement->TakePhoto(Size());
789 }
790 },
791 TaskExecutor::TaskType::PLATFORM, "ArkUICameraTakePhoto");
792 #else
793 camera_->TakePhoto(GetSizeFromQuality(params.quality));
794 #endif
795 }
796
ExecuteJsCallback(const std::string & callbackId,const std::string & result)797 void CameraElement::ExecuteJsCallback(const std::string& callbackId, const std::string& result)
798 {
799 auto context = context_.Upgrade();
800 if (!context) {
801 return;
802 }
803 context->SendCallbackMessageToFrontend(callbackId, result);
804 LOGI("CameraElement: ExecuteJsCallback %{public}s %{public}s", callbackId.c_str(), result.c_str());
805 }
806
807 } // namespace OHOS::Ace
808