123b3eb3cSopenharmony_ci/*
223b3eb3cSopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
323b3eb3cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
423b3eb3cSopenharmony_ci * you may not use this file except in compliance with the License.
523b3eb3cSopenharmony_ci * You may obtain a copy of the License at
623b3eb3cSopenharmony_ci *
723b3eb3cSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
823b3eb3cSopenharmony_ci *
923b3eb3cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1023b3eb3cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1123b3eb3cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1223b3eb3cSopenharmony_ci * See the License for the specific language governing permissions and
1323b3eb3cSopenharmony_ci * limitations under the License.
1423b3eb3cSopenharmony_ci */
1523b3eb3cSopenharmony_ci
1623b3eb3cSopenharmony_ci#include "core/common/ai/image_analyzer_manager.h"
1723b3eb3cSopenharmony_ci
1823b3eb3cSopenharmony_ci#include "core/common/ai/image_analyzer_adapter.h"
1923b3eb3cSopenharmony_ci#include "core/common/ai/image_analyzer_mgr.h"
2023b3eb3cSopenharmony_ci#include "core/components_ng/pattern/image/image_pattern.h"
2123b3eb3cSopenharmony_ci#include "core/components_ng/pattern/video/video_layout_property.h"
2223b3eb3cSopenharmony_ci
2323b3eb3cSopenharmony_cinamespace OHOS::Ace {
2423b3eb3cSopenharmony_ci
2523b3eb3cSopenharmony_ciImageAnalyzerManager::ImageAnalyzerManager(const RefPtr<NG::FrameNode>& frameNode, ImageAnalyzerHolder holder)
2623b3eb3cSopenharmony_ci    : frameNode_(frameNode), holder_(holder)
2723b3eb3cSopenharmony_ci{
2823b3eb3cSopenharmony_ci    imageAnalyzerAdapter_ = std::shared_ptr<ImageAnalyzerAdapter>(CreateImageAnalyzerAdapter());
2923b3eb3cSopenharmony_ci}
3023b3eb3cSopenharmony_ci
3123b3eb3cSopenharmony_civoid ImageAnalyzerManager::CreateAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap,
3223b3eb3cSopenharmony_ci    const NG::OffsetF& offset)
3323b3eb3cSopenharmony_ci{
3423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageAnalyzerAdapter_);
3523b3eb3cSopenharmony_ci    void* pixelmapNapiVal = nullptr;
3623b3eb3cSopenharmony_ci    if (pixelMap) {
3723b3eb3cSopenharmony_ci        pixelmapNapiVal = imageAnalyzerAdapter_->ConvertPixmapNapi(pixelMap);
3823b3eb3cSopenharmony_ci    }
3923b3eb3cSopenharmony_ci
4023b3eb3cSopenharmony_ci    analyzerUIConfig_.holder = holder_;
4123b3eb3cSopenharmony_ci    if (holder_ != ImageAnalyzerHolder::IMAGE && holder_ != ImageAnalyzerHolder::WEB) {
4223b3eb3cSopenharmony_ci        analyzerUIConfig_.contentWidth = pixelMap->GetWidth();
4323b3eb3cSopenharmony_ci        analyzerUIConfig_.contentHeight = pixelMap->GetHeight();
4423b3eb3cSopenharmony_ci    }
4523b3eb3cSopenharmony_ci
4623b3eb3cSopenharmony_ci    if (holder_ == ImageAnalyzerHolder::VIDEO_CUSTOM) {
4723b3eb3cSopenharmony_ci        analyzerUIConfig_.pixelMapWidth = pixelMap->GetWidth();
4823b3eb3cSopenharmony_ci        analyzerUIConfig_.pixelMapHeight = pixelMap->GetHeight();
4923b3eb3cSopenharmony_ci        analyzerUIConfig_.overlayOffset = offset;
5023b3eb3cSopenharmony_ci    }
5123b3eb3cSopenharmony_ci
5223b3eb3cSopenharmony_ci    RefPtr<NG::UINode> customNode;
5323b3eb3cSopenharmony_ci    {
5423b3eb3cSopenharmony_ci        NG::ScopedViewStackProcessor builderViewStackProcessor;
5523b3eb3cSopenharmony_ci        auto analyzerConfig = imageAnalyzerAdapter_->GetImageAnalyzerConfig();
5623b3eb3cSopenharmony_ci        ImageAnalyzerMgr::GetInstance().BuildNodeFunc(
5723b3eb3cSopenharmony_ci            pixelmapNapiVal, analyzerConfig, &analyzerUIConfig_, &overlayData_);
5823b3eb3cSopenharmony_ci        customNode = NG::ViewStackProcessor::GetInstance()->Finish();
5923b3eb3cSopenharmony_ci    }
6023b3eb3cSopenharmony_ci    auto overlayNode = AceType::DynamicCast<NG::FrameNode>(customNode);
6123b3eb3cSopenharmony_ci    CHECK_NULL_VOID(overlayNode);
6223b3eb3cSopenharmony_ci    auto node = frameNode_.Upgrade();
6323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(node);
6423b3eb3cSopenharmony_ci    node->SetOverlayNode(overlayNode);
6523b3eb3cSopenharmony_ci    overlayNode->SetParent(AceType::WeakClaim(AceType::RawPtr(node)));
6623b3eb3cSopenharmony_ci    overlayNode->SetActive(true);
6723b3eb3cSopenharmony_ci    UpdateAnalyzerOverlayLayout();
6823b3eb3cSopenharmony_ci
6923b3eb3cSopenharmony_ci    auto renderContext = overlayNode->GetRenderContext();
7023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(renderContext);
7123b3eb3cSopenharmony_ci    renderContext->UpdateZIndex(INT32_MAX);
7223b3eb3cSopenharmony_ci    auto focusHub = overlayNode->GetOrCreateFocusHub();
7323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(focusHub);
7423b3eb3cSopenharmony_ci    focusHub->SetFocusable(false);
7523b3eb3cSopenharmony_ci    overlayNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE_SELF);
7623b3eb3cSopenharmony_ci
7723b3eb3cSopenharmony_ci    isAnalyzerOverlayBuild_ = true;
7823b3eb3cSopenharmony_ci    CHECK_NULL_VOID(analyzerUIConfig_.onAnalyzed);
7923b3eb3cSopenharmony_ci    (analyzerUIConfig_.onAnalyzed.value())(ImageAnalyzerState::FINISHED);
8023b3eb3cSopenharmony_ci    analyzerUIConfig_.onAnalyzed = std::nullopt;
8123b3eb3cSopenharmony_ci}
8223b3eb3cSopenharmony_ci
8323b3eb3cSopenharmony_civoid ImageAnalyzerManager::CreateMovingPhotoAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap,
8423b3eb3cSopenharmony_ci    MovingPhotoAnalyzerInfo info)
8523b3eb3cSopenharmony_ci{
8623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageAnalyzerAdapter_);
8723b3eb3cSopenharmony_ci    void* pixelmapNapiVal = nullptr;
8823b3eb3cSopenharmony_ci
8923b3eb3cSopenharmony_ci    CHECK_NULL_VOID(pixelMap);
9023b3eb3cSopenharmony_ci    pixelmapNapiVal = imageAnalyzerAdapter_->ConvertPixmapNapi(pixelMap);
9123b3eb3cSopenharmony_ci    analyzerUIConfig_.holder = holder_;
9223b3eb3cSopenharmony_ci    analyzerUIConfig_.contentWidth = info.contentWidth;
9323b3eb3cSopenharmony_ci    analyzerUIConfig_.contentHeight = info.contentHeight;
9423b3eb3cSopenharmony_ci    analyzerUIConfig_.pixelMapWidth = pixelMap->GetWidth();
9523b3eb3cSopenharmony_ci    analyzerUIConfig_.pixelMapHeight = pixelMap->GetHeight();
9623b3eb3cSopenharmony_ci
9723b3eb3cSopenharmony_ci    RefPtr<NG::UINode> customNode;
9823b3eb3cSopenharmony_ci    {
9923b3eb3cSopenharmony_ci        NG::ScopedViewStackProcessor builderViewStackProcessor;
10023b3eb3cSopenharmony_ci        auto analyzerConfig = imageAnalyzerAdapter_->GetImageAnalyzerConfig();
10123b3eb3cSopenharmony_ci        ImageAnalyzerMgr::GetInstance().BuildNodeFunc(info.uri, pixelmapNapiVal,
10223b3eb3cSopenharmony_ci            info.frameTimestamp, analyzerConfig, &analyzerUIConfig_, &overlayData_);
10323b3eb3cSopenharmony_ci        customNode = NG::ViewStackProcessor::GetInstance()->Finish();
10423b3eb3cSopenharmony_ci    }
10523b3eb3cSopenharmony_ci    auto overlayNode = AceType::DynamicCast<NG::FrameNode>(customNode);
10623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(overlayNode);
10723b3eb3cSopenharmony_ci    auto node = frameNode_.Upgrade();
10823b3eb3cSopenharmony_ci    CHECK_NULL_VOID(node);
10923b3eb3cSopenharmony_ci    node->SetOverlayNode(overlayNode);
11023b3eb3cSopenharmony_ci    overlayNode->SetParent(AceType::WeakClaim(AceType::RawPtr(node)));
11123b3eb3cSopenharmony_ci    overlayNode->SetActive(true);
11223b3eb3cSopenharmony_ci    UpdateAnalyzerOverlayLayout();
11323b3eb3cSopenharmony_ci
11423b3eb3cSopenharmony_ci    auto renderContext = overlayNode->GetRenderContext();
11523b3eb3cSopenharmony_ci    CHECK_NULL_VOID(renderContext);
11623b3eb3cSopenharmony_ci    renderContext->UpdateZIndex(INT32_MAX);
11723b3eb3cSopenharmony_ci    overlayNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE_SELF);
11823b3eb3cSopenharmony_ci
11923b3eb3cSopenharmony_ci    isAnalyzerOverlayBuild_ = true;
12023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(analyzerUIConfig_.onAnalyzed);
12123b3eb3cSopenharmony_ci    (analyzerUIConfig_.onAnalyzed.value())(ImageAnalyzerState::FINISHED);
12223b3eb3cSopenharmony_ci    analyzerUIConfig_.onAnalyzed = std::nullopt;
12323b3eb3cSopenharmony_ci}
12423b3eb3cSopenharmony_ci
12523b3eb3cSopenharmony_civoid ImageAnalyzerManager::UpdateAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap,
12623b3eb3cSopenharmony_ci    const NG::OffsetF& offset)
12723b3eb3cSopenharmony_ci{
12823b3eb3cSopenharmony_ci    if (!isAnalyzerOverlayBuild_) {
12923b3eb3cSopenharmony_ci        return;
13023b3eb3cSopenharmony_ci    }
13123b3eb3cSopenharmony_ci
13223b3eb3cSopenharmony_ci    auto node = frameNode_.Upgrade();
13323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(node);
13423b3eb3cSopenharmony_ci    if (holder_ == ImageAnalyzerHolder::IMAGE) {
13523b3eb3cSopenharmony_ci        auto imagePattern = AceType::DynamicCast<NG::ImagePattern>(node->GetPattern());
13623b3eb3cSopenharmony_ci        CHECK_NULL_VOID(imagePattern);
13723b3eb3cSopenharmony_ci        if (!imagePattern->hasSceneChanged()) {
13823b3eb3cSopenharmony_ci            return;
13923b3eb3cSopenharmony_ci        }
14023b3eb3cSopenharmony_ci    }
14123b3eb3cSopenharmony_ci
14223b3eb3cSopenharmony_ci    CHECK_NULL_VOID(pixelMap);
14323b3eb3cSopenharmony_ci    if (holder_ == ImageAnalyzerHolder::VIDEO_CUSTOM) {
14423b3eb3cSopenharmony_ci        analyzerUIConfig_.pixelMapWidth = pixelMap->GetWidth();
14523b3eb3cSopenharmony_ci        analyzerUIConfig_.pixelMapHeight = pixelMap->GetHeight();
14623b3eb3cSopenharmony_ci        analyzerUIConfig_.overlayOffset = offset;
14723b3eb3cSopenharmony_ci    }
14823b3eb3cSopenharmony_ci
14923b3eb3cSopenharmony_ci    if (holder_ != ImageAnalyzerHolder::IMAGE) {
15023b3eb3cSopenharmony_ci        analyzerUIConfig_.contentWidth = pixelMap->GetWidth();
15123b3eb3cSopenharmony_ci        analyzerUIConfig_.contentHeight = pixelMap->GetHeight();
15223b3eb3cSopenharmony_ci    }
15323b3eb3cSopenharmony_ci
15423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageAnalyzerAdapter_);
15523b3eb3cSopenharmony_ci    auto pixelmapNapiVal = imageAnalyzerAdapter_->ConvertPixmapNapi(pixelMap);
15623b3eb3cSopenharmony_ci    auto overlayNode = node->GetOverlayNode();
15723b3eb3cSopenharmony_ci    CHECK_NULL_VOID(overlayNode);
15823b3eb3cSopenharmony_ci    auto analyzerConfig = imageAnalyzerAdapter_->GetImageAnalyzerConfig();
15923b3eb3cSopenharmony_ci    ImageAnalyzerMgr::GetInstance().UpdateImage(&overlayData_, pixelmapNapiVal, analyzerConfig, &analyzerUIConfig_);
16023b3eb3cSopenharmony_ci    overlayNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE_SELF);
16123b3eb3cSopenharmony_ci}
16223b3eb3cSopenharmony_ci
16323b3eb3cSopenharmony_civoid ImageAnalyzerManager::UpdateMovingPhotoAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap,
16423b3eb3cSopenharmony_ci    MovingPhotoAnalyzerInfo info)
16523b3eb3cSopenharmony_ci{
16623b3eb3cSopenharmony_ci    if (!isAnalyzerOverlayBuild_) {
16723b3eb3cSopenharmony_ci        return;
16823b3eb3cSopenharmony_ci    }
16923b3eb3cSopenharmony_ci
17023b3eb3cSopenharmony_ci    auto node = frameNode_.Upgrade();
17123b3eb3cSopenharmony_ci    CHECK_NULL_VOID(node);
17223b3eb3cSopenharmony_ci    if (holder_ == ImageAnalyzerHolder::IMAGE) {
17323b3eb3cSopenharmony_ci        auto imagePattern = AceType::DynamicCast<NG::ImagePattern>(node->GetPattern());
17423b3eb3cSopenharmony_ci        CHECK_NULL_VOID(imagePattern);
17523b3eb3cSopenharmony_ci        if (!imagePattern->hasSceneChanged()) {
17623b3eb3cSopenharmony_ci            return;
17723b3eb3cSopenharmony_ci        }
17823b3eb3cSopenharmony_ci    }
17923b3eb3cSopenharmony_ci
18023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(pixelMap);
18123b3eb3cSopenharmony_ci    analyzerUIConfig_.holder = holder_;
18223b3eb3cSopenharmony_ci    analyzerUIConfig_.contentWidth = info.contentWidth;
18323b3eb3cSopenharmony_ci    analyzerUIConfig_.contentHeight = info.contentHeight;
18423b3eb3cSopenharmony_ci    analyzerUIConfig_.pixelMapWidth = pixelMap->GetWidth();
18523b3eb3cSopenharmony_ci    analyzerUIConfig_.pixelMapHeight = pixelMap->GetHeight();
18623b3eb3cSopenharmony_ci
18723b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageAnalyzerAdapter_);
18823b3eb3cSopenharmony_ci    auto pixelmapNapiVal = imageAnalyzerAdapter_->ConvertPixmapNapi(pixelMap);
18923b3eb3cSopenharmony_ci    auto overlayNode = node->GetOverlayNode();
19023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(overlayNode);
19123b3eb3cSopenharmony_ci    auto analyzerConfig = imageAnalyzerAdapter_->GetImageAnalyzerConfig();
19223b3eb3cSopenharmony_ci    ImageAnalyzerMgr::GetInstance().UpdateImage(&overlayData_, info.uri, pixelmapNapiVal,
19323b3eb3cSopenharmony_ci        info.frameTimestamp, analyzerConfig, &analyzerUIConfig_);
19423b3eb3cSopenharmony_ci    overlayNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE_SELF);
19523b3eb3cSopenharmony_ci}
19623b3eb3cSopenharmony_ci
19723b3eb3cSopenharmony_civoid ImageAnalyzerManager::DestroyAnalyzerOverlay()
19823b3eb3cSopenharmony_ci{
19923b3eb3cSopenharmony_ci    ReleaseImageAnalyzer();
20023b3eb3cSopenharmony_ci
20123b3eb3cSopenharmony_ci    if (!isAnalyzerOverlayBuild_) {
20223b3eb3cSopenharmony_ci        return;
20323b3eb3cSopenharmony_ci    }
20423b3eb3cSopenharmony_ci    auto node = frameNode_.Upgrade();
20523b3eb3cSopenharmony_ci    CHECK_NULL_VOID(node);
20623b3eb3cSopenharmony_ci    auto overlayNode = node->GetOverlayNode();
20723b3eb3cSopenharmony_ci    CHECK_NULL_VOID(overlayNode);
20823b3eb3cSopenharmony_ci    node->SetOverlayNode(RefPtr<NG::FrameNode>());
20923b3eb3cSopenharmony_ci
21023b3eb3cSopenharmony_ci    isAnalyzerOverlayBuild_ = false;
21123b3eb3cSopenharmony_ci    CHECK_NULL_VOID(analyzerUIConfig_.onAnalyzed);
21223b3eb3cSopenharmony_ci    (analyzerUIConfig_.onAnalyzed.value())(ImageAnalyzerState::STOPPED);
21323b3eb3cSopenharmony_ci    analyzerUIConfig_.onAnalyzed = std::nullopt;
21423b3eb3cSopenharmony_ci
21523b3eb3cSopenharmony_ci    napi_value nullValue = nullptr;
21623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageAnalyzerAdapter_);
21723b3eb3cSopenharmony_ci    imageAnalyzerAdapter_->SetImageAnalyzerConfig(nullValue);
21823b3eb3cSopenharmony_ci}
21923b3eb3cSopenharmony_ci
22023b3eb3cSopenharmony_cibool ImageAnalyzerManager::IsSupportImageAnalyzerFeature()
22123b3eb3cSopenharmony_ci{
22223b3eb3cSopenharmony_ci    auto node = frameNode_.Upgrade();
22323b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(node, false);
22423b3eb3cSopenharmony_ci    auto eventHub = node->GetEventHub<NG::EventHub>();
22523b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(eventHub, false);
22623b3eb3cSopenharmony_ci    if (!eventHub->IsEnabled()) {
22723b3eb3cSopenharmony_ci        return false;
22823b3eb3cSopenharmony_ci    }
22923b3eb3cSopenharmony_ci
23023b3eb3cSopenharmony_ci    bool hasObscured = false;
23123b3eb3cSopenharmony_ci    if (node->GetRenderContext()->GetObscured().has_value()) {
23223b3eb3cSopenharmony_ci        auto obscuredReasons = node->GetRenderContext()->GetObscured().value();
23323b3eb3cSopenharmony_ci        hasObscured = std::any_of(obscuredReasons.begin(), obscuredReasons.end(),
23423b3eb3cSopenharmony_ci            [](const auto& reason) { return reason == ObscuredReasons::PLACEHOLDER; });
23523b3eb3cSopenharmony_ci        if (hasObscured) {
23623b3eb3cSopenharmony_ci            return false;
23723b3eb3cSopenharmony_ci        }
23823b3eb3cSopenharmony_ci    }
23923b3eb3cSopenharmony_ci
24023b3eb3cSopenharmony_ci    if (holder_ == ImageAnalyzerHolder::IMAGE) {
24123b3eb3cSopenharmony_ci        auto imageRenderProperty = node->GetPaintProperty<NG::ImageRenderProperty>();
24223b3eb3cSopenharmony_ci        CHECK_NULL_RETURN(imageRenderProperty, false);
24323b3eb3cSopenharmony_ci        ImageRepeat repeat = imageRenderProperty->GetImageRepeat().value_or(ImageRepeat::NO_REPEAT);
24423b3eb3cSopenharmony_ci        if (repeat != ImageRepeat::NO_REPEAT) {
24523b3eb3cSopenharmony_ci            return false;
24623b3eb3cSopenharmony_ci        }
24723b3eb3cSopenharmony_ci    }
24823b3eb3cSopenharmony_ci
24923b3eb3cSopenharmony_ci    return ImageAnalyzerMgr::GetInstance().IsImageAnalyzerSupported();
25023b3eb3cSopenharmony_ci}
25123b3eb3cSopenharmony_ci
25223b3eb3cSopenharmony_cibool ImageAnalyzerManager::IsOverlayCreated()
25323b3eb3cSopenharmony_ci{
25423b3eb3cSopenharmony_ci    return isAnalyzerOverlayBuild_;
25523b3eb3cSopenharmony_ci}
25623b3eb3cSopenharmony_ci
25723b3eb3cSopenharmony_civoid ImageAnalyzerManager::UpdateAnalyzerOverlayLayout()
25823b3eb3cSopenharmony_ci{
25923b3eb3cSopenharmony_ci    auto node = frameNode_.Upgrade();
26023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(node);
26123b3eb3cSopenharmony_ci    auto layoutProperty = node->GetLayoutProperty();
26223b3eb3cSopenharmony_ci    CHECK_NULL_VOID(layoutProperty);
26323b3eb3cSopenharmony_ci    auto padding = layoutProperty->CreatePaddingAndBorder();
26423b3eb3cSopenharmony_ci    auto overlayNode = node->GetOverlayNode();
26523b3eb3cSopenharmony_ci    CHECK_NULL_VOID(overlayNode);
26623b3eb3cSopenharmony_ci    auto overlayLayoutProperty = overlayNode->GetLayoutProperty();
26723b3eb3cSopenharmony_ci    CHECK_NULL_VOID(overlayLayoutProperty);
26823b3eb3cSopenharmony_ci    overlayLayoutProperty->UpdateMeasureType(NG::MeasureType::MATCH_PARENT);
26923b3eb3cSopenharmony_ci    overlayLayoutProperty->UpdateAlignment(Alignment::TOP_LEFT);
27023b3eb3cSopenharmony_ci    if (NeedUpdateOverlayOffset()) {
27123b3eb3cSopenharmony_ci        overlayLayoutProperty->SetOverlayOffset(Dimension(padding.Offset().GetX()),
27223b3eb3cSopenharmony_ci                                                Dimension(padding.Offset().GetY()));
27323b3eb3cSopenharmony_ci        if (holder_ == ImageAnalyzerHolder::IMAGE) {
27423b3eb3cSopenharmony_ci            auto renderContext = overlayNode->GetRenderContext();
27523b3eb3cSopenharmony_ci            CHECK_NULL_VOID(renderContext);
27623b3eb3cSopenharmony_ci            renderContext->SetRenderFrameOffset({ -padding.Offset().GetX(), -padding.Offset().GetY() });
27723b3eb3cSopenharmony_ci        }
27823b3eb3cSopenharmony_ci    }
27923b3eb3cSopenharmony_ci}
28023b3eb3cSopenharmony_ci
28123b3eb3cSopenharmony_civoid ImageAnalyzerManager::UpdateAnalyzerUIConfig(const RefPtr<NG::GeometryNode>& geometryNode,
28223b3eb3cSopenharmony_ci    const PixelMapInfo& info)
28323b3eb3cSopenharmony_ci{
28423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(geometryNode);
28523b3eb3cSopenharmony_ci    auto node = frameNode_.Upgrade();
28623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(node);
28723b3eb3cSopenharmony_ci    bool isUIConfigUpdate = false;
28823b3eb3cSopenharmony_ci
28923b3eb3cSopenharmony_ci    auto layoutProps = node->GetLayoutProperty();
29023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(layoutProps);
29123b3eb3cSopenharmony_ci    if (holder_ == ImageAnalyzerHolder::IMAGE) {
29223b3eb3cSopenharmony_ci        auto props = DynamicCast<NG::ImageLayoutProperty>(layoutProps);
29323b3eb3cSopenharmony_ci        CHECK_NULL_VOID(props);
29423b3eb3cSopenharmony_ci        if (analyzerUIConfig_.imageFit != props->GetImageFit().value_or(ImageFit::COVER)) {
29523b3eb3cSopenharmony_ci            analyzerUIConfig_.imageFit = props->GetImageFit().value_or(ImageFit::COVER);
29623b3eb3cSopenharmony_ci            isUIConfigUpdate = true;
29723b3eb3cSopenharmony_ci        }
29823b3eb3cSopenharmony_ci    }
29923b3eb3cSopenharmony_ci
30023b3eb3cSopenharmony_ci    if (holder_ == ImageAnalyzerHolder::VIDEO_CUSTOM) {
30123b3eb3cSopenharmony_ci        isUIConfigUpdate = UpdateVideoConfig(info);
30223b3eb3cSopenharmony_ci    } else {
30323b3eb3cSopenharmony_ci        auto padding = layoutProps->CreatePaddingAndBorder();
30423b3eb3cSopenharmony_ci        float paddingWidth = 0.0f;
30523b3eb3cSopenharmony_ci        float paddingHeight = 0.0f;
30623b3eb3cSopenharmony_ci        if (holder_ == ImageAnalyzerHolder::IMAGE || holder_ == ImageAnalyzerHolder::XCOMPONENT) {
30723b3eb3cSopenharmony_ci            paddingWidth = padding.left.value_or(0) + padding.right.value_or(0);
30823b3eb3cSopenharmony_ci            paddingHeight = padding.top.value_or(0) + padding.bottom.value_or(0);
30923b3eb3cSopenharmony_ci        }
31023b3eb3cSopenharmony_ci        NG::SizeF frameSize = geometryNode->GetFrameSize();
31123b3eb3cSopenharmony_ci        bool shouldUpdateSize = analyzerUIConfig_.contentWidth != frameSize.Width() - paddingWidth ||
31223b3eb3cSopenharmony_ci                                analyzerUIConfig_.contentHeight != frameSize.Height() - paddingHeight;
31323b3eb3cSopenharmony_ci        if (shouldUpdateSize) {
31423b3eb3cSopenharmony_ci            analyzerUIConfig_.contentWidth = frameSize.Width() - paddingWidth;
31523b3eb3cSopenharmony_ci            analyzerUIConfig_.contentHeight = frameSize.Height()- paddingHeight;
31623b3eb3cSopenharmony_ci            isUIConfigUpdate = true;
31723b3eb3cSopenharmony_ci        }
31823b3eb3cSopenharmony_ci    }
31923b3eb3cSopenharmony_ci
32023b3eb3cSopenharmony_ci    auto renderContext = node->GetRenderContext();
32123b3eb3cSopenharmony_ci    CHECK_NULL_VOID(renderContext);
32223b3eb3cSopenharmony_ci    auto transformMat = renderContext->GetTransformMatrixValue(Matrix4::CreateIdentity());
32323b3eb3cSopenharmony_ci    if (!(analyzerUIConfig_.transformMat == transformMat)) {
32423b3eb3cSopenharmony_ci        analyzerUIConfig_.transformMat = transformMat;
32523b3eb3cSopenharmony_ci        isUIConfigUpdate = true;
32623b3eb3cSopenharmony_ci    }
32723b3eb3cSopenharmony_ci
32823b3eb3cSopenharmony_ci    if (isUIConfigUpdate) {
32923b3eb3cSopenharmony_ci        ImageAnalyzerMgr::GetInstance().UpdateInnerConfig(&overlayData_, &analyzerUIConfig_);
33023b3eb3cSopenharmony_ci    }
33123b3eb3cSopenharmony_ci}
33223b3eb3cSopenharmony_ci
33323b3eb3cSopenharmony_cibool ImageAnalyzerManager::UpdateVideoConfig(const PixelMapInfo& info)
33423b3eb3cSopenharmony_ci{
33523b3eb3cSopenharmony_ci    bool shouldUpdateFit = false;
33623b3eb3cSopenharmony_ci    auto node = frameNode_.Upgrade();
33723b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(node, false);
33823b3eb3cSopenharmony_ci    auto layoutProps = node->GetLayoutProperty();
33923b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(layoutProps, false);
34023b3eb3cSopenharmony_ci    auto videoProps = DynamicCast<NG::VideoLayoutProperty>(layoutProps);
34123b3eb3cSopenharmony_ci    if (analyzerUIConfig_.imageFit != videoProps->GetObjectFitValue(ImageFit::COVER)) {
34223b3eb3cSopenharmony_ci        analyzerUIConfig_.imageFit = videoProps->GetObjectFitValue(ImageFit::COVER);
34323b3eb3cSopenharmony_ci        shouldUpdateFit = true;
34423b3eb3cSopenharmony_ci    }
34523b3eb3cSopenharmony_ci
34623b3eb3cSopenharmony_ci    bool shouldUpdateSize = analyzerUIConfig_.contentWidth != info.width ||
34723b3eb3cSopenharmony_ci                            analyzerUIConfig_.contentHeight != info.height ||
34823b3eb3cSopenharmony_ci                            analyzerUIConfig_.overlayOffset != info.overlayOffset;
34923b3eb3cSopenharmony_ci    if (shouldUpdateSize) {
35023b3eb3cSopenharmony_ci        analyzerUIConfig_.UpdateFromInfo(info);
35123b3eb3cSopenharmony_ci    }
35223b3eb3cSopenharmony_ci    return shouldUpdateFit || shouldUpdateSize;
35323b3eb3cSopenharmony_ci}
35423b3eb3cSopenharmony_ci
35523b3eb3cSopenharmony_civoid ImageAnalyzerManager::SetImageAnalyzerConfig(void* config)
35623b3eb3cSopenharmony_ci{
35723b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageAnalyzerAdapter_);
35823b3eb3cSopenharmony_ci    bool hasConfig = imageAnalyzerAdapter_->HasImageAnalyzerConfig();
35923b3eb3cSopenharmony_ci    if (hasConfig) {
36023b3eb3cSopenharmony_ci        return;
36123b3eb3cSopenharmony_ci    }
36223b3eb3cSopenharmony_ci    imageAnalyzerAdapter_->SetImageAnalyzerConfig(config);
36323b3eb3cSopenharmony_ci    auto analyzerConfig = imageAnalyzerAdapter_->GetImageAnalyzerConfig();
36423b3eb3cSopenharmony_ci    if (isAnalyzerOverlayBuild_) {
36523b3eb3cSopenharmony_ci        ImageAnalyzerMgr::GetInstance().UpdateConfig(&overlayData_, analyzerConfig);
36623b3eb3cSopenharmony_ci    }
36723b3eb3cSopenharmony_ci}
36823b3eb3cSopenharmony_ci
36923b3eb3cSopenharmony_civoid ImageAnalyzerManager::SetImageAIOptions(void* options)
37023b3eb3cSopenharmony_ci{
37123b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageAnalyzerAdapter_);
37223b3eb3cSopenharmony_ci    imageAnalyzerAdapter_->SetImageAnalyzerConfig(options, true);
37323b3eb3cSopenharmony_ci    auto analyzerConfig = imageAnalyzerAdapter_->GetImageAnalyzerConfig();
37423b3eb3cSopenharmony_ci    if (isAnalyzerOverlayBuild_) {
37523b3eb3cSopenharmony_ci        ImageAnalyzerMgr::GetInstance().UpdateConfig(&overlayData_, analyzerConfig);
37623b3eb3cSopenharmony_ci    }
37723b3eb3cSopenharmony_ci}
37823b3eb3cSopenharmony_ci
37923b3eb3cSopenharmony_civoid ImageAnalyzerManager::SetImageAnalyzerCallback(OnAnalyzedCallback& callback)
38023b3eb3cSopenharmony_ci{
38123b3eb3cSopenharmony_ci    analyzerUIConfig_.onAnalyzed = callback;
38223b3eb3cSopenharmony_ci}
38323b3eb3cSopenharmony_ci
38423b3eb3cSopenharmony_civoid ImageAnalyzerManager::ReleaseImageAnalyzer()
38523b3eb3cSopenharmony_ci{
38623b3eb3cSopenharmony_ci    if (isAnalyzerOverlayBuild_) {
38723b3eb3cSopenharmony_ci        ImageAnalyzerMgr::GetInstance().Release(&overlayData_);
38823b3eb3cSopenharmony_ci    }
38923b3eb3cSopenharmony_ci}
39023b3eb3cSopenharmony_ci
39123b3eb3cSopenharmony_civoid ImageAnalyzerManager::UpdatePressOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap, int offsetX, int offsetY,
39223b3eb3cSopenharmony_ci    int rectWidth, int rectHeight, int pointX, int pointY, OnTextSelectedCallback callback)
39323b3eb3cSopenharmony_ci{
39423b3eb3cSopenharmony_ci    analyzerUIConfig_.overlayOffset.SetX(offsetX);
39523b3eb3cSopenharmony_ci    analyzerUIConfig_.overlayOffset.SetY(offsetY);
39623b3eb3cSopenharmony_ci    if (rectWidth > 0 && rectHeight > 0) {
39723b3eb3cSopenharmony_ci        analyzerUIConfig_.touchInfo.touchPoint.x = 1.0 * pointX / rectWidth * pixelMap->GetWidth();
39823b3eb3cSopenharmony_ci        analyzerUIConfig_.touchInfo.touchPoint.y = 1.0 * pointY / rectHeight * pixelMap->GetHeight();
39923b3eb3cSopenharmony_ci    }
40023b3eb3cSopenharmony_ci    analyzerUIConfig_.touchInfo.touchType = TouchType::DOWN;
40123b3eb3cSopenharmony_ci    analyzerUIConfig_.selectedStatus = Status::SELECTED;
40223b3eb3cSopenharmony_ci    analyzerUIConfig_.menuStatus = Status::MENU_SHOW;
40323b3eb3cSopenharmony_ci    if (!analyzerUIConfig_.onTextSelected) {
40423b3eb3cSopenharmony_ci        analyzerUIConfig_.onTextSelected = std::move(callback);
40523b3eb3cSopenharmony_ci    }
40623b3eb3cSopenharmony_ci    if (pixelMap && imageAnalyzerAdapter_) {
40723b3eb3cSopenharmony_ci        analyzerUIConfig_.contentWidth = rectWidth;
40823b3eb3cSopenharmony_ci        analyzerUIConfig_.contentHeight = rectHeight;
40923b3eb3cSopenharmony_ci        analyzerUIConfig_.pixelMapWidth = pixelMap->GetWidth();
41023b3eb3cSopenharmony_ci        analyzerUIConfig_.pixelMapHeight = pixelMap->GetHeight();
41123b3eb3cSopenharmony_ci        analyzerUIConfig_.pixelmapNapiVal = imageAnalyzerAdapter_->ConvertPixmapNapi(pixelMap);
41223b3eb3cSopenharmony_ci    }
41323b3eb3cSopenharmony_ci    ImageAnalyzerMgr::GetInstance().UpdatePressOverlay(&overlayData_, &analyzerUIConfig_);
41423b3eb3cSopenharmony_ci    analyzerUIConfig_.pixelmapNapiVal = nullptr;
41523b3eb3cSopenharmony_ci}
41623b3eb3cSopenharmony_ci
41723b3eb3cSopenharmony_civoid ImageAnalyzerManager::UpdateOverlayTouchInfo(int touchPointX, int touchPointY, TouchType touchType)
41823b3eb3cSopenharmony_ci{
41923b3eb3cSopenharmony_ci    analyzerUIConfig_.touchInfo.touchPoint.x = touchPointX - analyzerUIConfig_.overlayOffset.GetX();
42023b3eb3cSopenharmony_ci    analyzerUIConfig_.touchInfo.touchPoint.y = touchPointY - analyzerUIConfig_.overlayOffset.GetY();
42123b3eb3cSopenharmony_ci    analyzerUIConfig_.touchInfo.touchType = touchType;
42223b3eb3cSopenharmony_ci    ImageAnalyzerMgr::GetInstance().UpdatePressOverlay(&overlayData_, &analyzerUIConfig_);
42323b3eb3cSopenharmony_ci}
42423b3eb3cSopenharmony_ci
42523b3eb3cSopenharmony_civoid ImageAnalyzerManager::UpdateOverlayStatus(bool status, int offsetX, int offsetY, int rectWidth, int rectHeight)
42623b3eb3cSopenharmony_ci{
42723b3eb3cSopenharmony_ci    if (status) {
42823b3eb3cSopenharmony_ci        analyzerUIConfig_.overlayOffset.SetX(offsetX);
42923b3eb3cSopenharmony_ci        analyzerUIConfig_.overlayOffset.SetY(offsetY);
43023b3eb3cSopenharmony_ci        analyzerUIConfig_.contentWidth = rectWidth;
43123b3eb3cSopenharmony_ci        analyzerUIConfig_.contentHeight = rectHeight;
43223b3eb3cSopenharmony_ci        analyzerUIConfig_.selectedStatus = Status::SELECTED;
43323b3eb3cSopenharmony_ci        analyzerUIConfig_.menuStatus = Status::MENU_SHOW;
43423b3eb3cSopenharmony_ci    } else {
43523b3eb3cSopenharmony_ci        analyzerUIConfig_.selectedStatus = Status::UNSELECTED;
43623b3eb3cSopenharmony_ci        analyzerUIConfig_.menuStatus = Status::MENU_HIDE;
43723b3eb3cSopenharmony_ci    }
43823b3eb3cSopenharmony_ci    ImageAnalyzerMgr::GetInstance().UpdateOverlayStatus(&overlayData_, &analyzerUIConfig_);
43923b3eb3cSopenharmony_ci}
44023b3eb3cSopenharmony_ci
44123b3eb3cSopenharmony_civoid ImageAnalyzerManager::UpdateAIButtonConfig(AIButtonConfig config)
44223b3eb3cSopenharmony_ci{
44323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(isAnalyzerOverlayBuild_);
44423b3eb3cSopenharmony_ci    ImageAnalyzerMgr::GetInstance().UpdateAIButtonConfig(&overlayData_, &config);
44523b3eb3cSopenharmony_ci}
44623b3eb3cSopenharmony_ci
44723b3eb3cSopenharmony_civoid ImageAnalyzerManager::UpdateOverlayActiveStatus(bool status)
44823b3eb3cSopenharmony_ci{
44923b3eb3cSopenharmony_ci    CHECK_NULL_VOID(isAnalyzerOverlayBuild_);
45023b3eb3cSopenharmony_ci    ImageAnalyzerMgr::GetInstance().UpdateOverlayActiveStatus(&overlayData_, status);
45123b3eb3cSopenharmony_ci}
45223b3eb3cSopenharmony_ci
45323b3eb3cSopenharmony_cibool ImageAnalyzerManager::NeedUpdateOverlayOffset()
45423b3eb3cSopenharmony_ci{
45523b3eb3cSopenharmony_ci    return holder_ == ImageAnalyzerHolder::IMAGE ||
45623b3eb3cSopenharmony_ci           holder_ == ImageAnalyzerHolder::VIDEO_CUSTOM ||
45723b3eb3cSopenharmony_ci           holder_ == ImageAnalyzerHolder::XCOMPONENT;
45823b3eb3cSopenharmony_ci}
45923b3eb3cSopenharmony_ci
46023b3eb3cSopenharmony_civoid ImageAnalyzerManager::SetNotifySelectedCallback(
46123b3eb3cSopenharmony_ci    OnNotifySelectedStatusCallback&& callback)
46223b3eb3cSopenharmony_ci{
46323b3eb3cSopenharmony_ci    analyzerUIConfig_.onNotifySelectedStatus = std::move(callback);
46423b3eb3cSopenharmony_ci}
46523b3eb3cSopenharmony_ci
46623b3eb3cSopenharmony_civoid ImageAnalyzerManager::SetOnCanPlayCallback(
46723b3eb3cSopenharmony_ci    OnCanPlayCallback&& onCanPlay)
46823b3eb3cSopenharmony_ci{
46923b3eb3cSopenharmony_ci    analyzerUIConfig_.onCanPlay = std::move(onCanPlay);
47023b3eb3cSopenharmony_ci}
47123b3eb3cSopenharmony_ci} // namespace OHOS::Ace