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 <unistd.h>
1723b3eb3cSopenharmony_ci
1823b3eb3cSopenharmony_ci#include "movingphoto_pattern.h"
1923b3eb3cSopenharmony_ci#include "movingphoto_node.h"
2023b3eb3cSopenharmony_ci#include "movingphoto_utils.h"
2123b3eb3cSopenharmony_ci
2223b3eb3cSopenharmony_ci#include "base/image/pixel_map.h"
2323b3eb3cSopenharmony_ci#include "core/components_ng/pattern/image/image_pattern.h"
2423b3eb3cSopenharmony_ci
2523b3eb3cSopenharmony_cinamespace OHOS::Ace::NG {
2623b3eb3cSopenharmony_cinamespace {
2723b3eb3cSopenharmony_ciconstexpr int32_t LONG_PRESS_DELAY = 300;
2823b3eb3cSopenharmony_ciconstexpr int32_t ANIMATION_DURATION_300 = 300;
2923b3eb3cSopenharmony_ciconstexpr int32_t ANIMATION_DURATION_400 = 400;
3023b3eb3cSopenharmony_ciconstexpr float NORMAL_SCALE = 1.0f;
3123b3eb3cSopenharmony_ciconstexpr float ZOOM_IN_SCALE = 1.1f;
3223b3eb3cSopenharmony_ciconstexpr double NORMAL_PLAY_SPEED = 1.0;
3323b3eb3cSopenharmony_ciconstexpr int32_t HALF = 2;
3423b3eb3cSopenharmony_ciconstexpr int64_t PERIOD_START = 0;
3523b3eb3cSopenharmony_ciconstexpr int32_t PREPARE_RETURN = 0;
3623b3eb3cSopenharmony_ciconstexpr int64_t VIDEO_PLAYTIME_START_POSITION = 0;
3723b3eb3cSopenharmony_ciconstexpr int64_t VIDEO_PLAYTIME_END_POSITION = 3000;
3823b3eb3cSopenharmony_ciconstexpr int32_t IMAGE_LOADING_COMPLETE = 0;
3923b3eb3cSopenharmony_ciconstexpr int32_t DURATION_FLAG = -1;
4023b3eb3cSopenharmony_ciconst std::string THUMBNAIL_MEDIUM_JOINT = "?&oper=thumbnail&width=-1&height=-1&path=";
4123b3eb3cSopenharmony_ciconst std::string COVER_POSITION = "cover_positon";
4223b3eb3cSopenharmony_ciconst std::string IMAGE_URI = "uri";
4323b3eb3cSopenharmony_ciconstexpr int32_t ANALYZER_DELAY_TIME = 100;
4423b3eb3cSopenharmony_ciconstexpr int32_t ANALYZER_CAPTURE_DELAY_TIME = 1000;
4523b3eb3cSopenharmony_ciconstexpr int32_t AVERAGE_VALUE = 2;
4623b3eb3cSopenharmony_ci}
4723b3eb3cSopenharmony_ciMovingPhotoPattern::MovingPhotoPattern(const RefPtr<MovingPhotoController>& controller)
4823b3eb3cSopenharmony_ci    : instanceId_(Container::CurrentId()), controller_(controller)
4923b3eb3cSopenharmony_ci{}
5023b3eb3cSopenharmony_ci
5123b3eb3cSopenharmony_civoid MovingPhotoPattern::OnModifyDone()
5223b3eb3cSopenharmony_ci{
5323b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto onModifydone start.");
5423b3eb3cSopenharmony_ci    Pattern::OnModifyDone();
5523b3eb3cSopenharmony_ci    UpdateImageNode();
5623b3eb3cSopenharmony_ci    UpdateVideoNode();
5723b3eb3cSopenharmony_ci    if (SystemProperties::GetExtSurfaceEnabled()) {
5823b3eb3cSopenharmony_ci        auto pipelineContext = PipelineContext::GetCurrentContext();
5923b3eb3cSopenharmony_ci        CHECK_NULL_VOID(pipelineContext);
6023b3eb3cSopenharmony_ci        auto host = GetHost();
6123b3eb3cSopenharmony_ci        CHECK_NULL_VOID(host);
6223b3eb3cSopenharmony_ci        pipelineContext->AddOnAreaChangeNode(host->GetId());
6323b3eb3cSopenharmony_ci    }
6423b3eb3cSopenharmony_ci    InitEvent();
6523b3eb3cSopenharmony_ci    UpdatePlayMode();
6623b3eb3cSopenharmony_ci    HandleImageAnalyzerMode();
6723b3eb3cSopenharmony_ci}
6823b3eb3cSopenharmony_ci
6923b3eb3cSopenharmony_civoid MovingPhotoPattern::OnAttachToFrameNode()
7023b3eb3cSopenharmony_ci{
7123b3eb3cSopenharmony_ci    auto host = GetHost();
7223b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
7323b3eb3cSopenharmony_ci    auto renderContext = host->GetRenderContext();
7423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(renderContext);
7523b3eb3cSopenharmony_ci    static RenderContext::ContextParam param = { RenderContext::ContextType::HARDWARE_SURFACE, "MediaPlayerSurface",
7623b3eb3cSopenharmony_ci                                                 RenderContext::PatternType::VIDEO };
7723b3eb3cSopenharmony_ci    renderContextForMediaPlayer_->InitContext(false, param);
7823b3eb3cSopenharmony_ci    renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
7923b3eb3cSopenharmony_ci    renderContextForMediaPlayer_->UpdateBackgroundColor(Color::TRANSPARENT);
8023b3eb3cSopenharmony_ci    renderContext->SetClipToBounds(true);
8123b3eb3cSopenharmony_ci
8223b3eb3cSopenharmony_ci    auto pipelineContext = PipelineContext::GetCurrentContext();
8323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(pipelineContext);
8423b3eb3cSopenharmony_ci    pipelineContext->AddWindowStateChangedCallback(host->GetId());
8523b3eb3cSopenharmony_ci
8623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(controller_);
8723b3eb3cSopenharmony_ci    ContainerScope scope(instanceId_);
8823b3eb3cSopenharmony_ci    auto context = PipelineContext::GetCurrentContext();
8923b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
9023b3eb3cSopenharmony_ci    auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
9123b3eb3cSopenharmony_ci    controller_->SetStartPlaybackImpl([weak = WeakClaim(this), uiTaskExecutor]() {
9223b3eb3cSopenharmony_ci        uiTaskExecutor.PostTask(
9323b3eb3cSopenharmony_ci            [weak]() {
9423b3eb3cSopenharmony_ci                auto pattern = weak.Upgrade();
9523b3eb3cSopenharmony_ci                CHECK_NULL_VOID(pattern);
9623b3eb3cSopenharmony_ci                ContainerScope scope(pattern->instanceId_);
9723b3eb3cSopenharmony_ci                pattern->StartPlayback();
9823b3eb3cSopenharmony_ci            },
9923b3eb3cSopenharmony_ci            "ArkUIMovingPhotoStart");
10023b3eb3cSopenharmony_ci    });
10123b3eb3cSopenharmony_ci
10223b3eb3cSopenharmony_ci    controller_->SetStopPlaybackImpl([weak = WeakClaim(this), uiTaskExecutor]() {
10323b3eb3cSopenharmony_ci        uiTaskExecutor.PostTask(
10423b3eb3cSopenharmony_ci            [weak]() {
10523b3eb3cSopenharmony_ci                auto pattern = weak.Upgrade();
10623b3eb3cSopenharmony_ci                CHECK_NULL_VOID(pattern);
10723b3eb3cSopenharmony_ci                ContainerScope scope(pattern->instanceId_);
10823b3eb3cSopenharmony_ci                pattern->StopPlayback();
10923b3eb3cSopenharmony_ci            },
11023b3eb3cSopenharmony_ci            "ArkUIMovingPhotoStop");
11123b3eb3cSopenharmony_ci    });
11223b3eb3cSopenharmony_ci
11323b3eb3cSopenharmony_ci    RegisterVisibleAreaChange();
11423b3eb3cSopenharmony_ci}
11523b3eb3cSopenharmony_ci
11623b3eb3cSopenharmony_civoid MovingPhotoPattern::OnDetachFromFrameNode(FrameNode* frameNode)
11723b3eb3cSopenharmony_ci{
11823b3eb3cSopenharmony_ci    auto id = frameNode->GetId();
11923b3eb3cSopenharmony_ci    auto pipeline = AceType::DynamicCast<PipelineContext>(PipelineBase::GetCurrentContext());
12023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(pipeline);
12123b3eb3cSopenharmony_ci    pipeline->RemoveWindowStateChangedCallback(id);
12223b3eb3cSopenharmony_ci    hasVisibleChangeRegistered_ = false;
12323b3eb3cSopenharmony_ci}
12423b3eb3cSopenharmony_ci
12523b3eb3cSopenharmony_civoid MovingPhotoPattern::OnDetachFromMainTree()
12623b3eb3cSopenharmony_ci{
12723b3eb3cSopenharmony_ci    auto host = GetHost();
12823b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
12923b3eb3cSopenharmony_ci    if (host->GetNodeStatus() == NodeStatus::BUILDER_NODE_OFF_MAINTREE) {
13023b3eb3cSopenharmony_ci        Stop();
13123b3eb3cSopenharmony_ci    }
13223b3eb3cSopenharmony_ci}
13323b3eb3cSopenharmony_ci
13423b3eb3cSopenharmony_civoid MovingPhotoPattern::OnRebuildFrame()
13523b3eb3cSopenharmony_ci{
13623b3eb3cSopenharmony_ci    if (!renderSurface_ || !renderSurface_->IsSurfaceValid()) {
13723b3eb3cSopenharmony_ci        return;
13823b3eb3cSopenharmony_ci    }
13923b3eb3cSopenharmony_ci    auto host = GetHost();
14023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
14123b3eb3cSopenharmony_ci    auto movingPhotoNode = AceType::DynamicCast<MovingPhotoNode>(host);
14223b3eb3cSopenharmony_ci    CHECK_NULL_VOID(movingPhotoNode);
14323b3eb3cSopenharmony_ci    auto video = AceType::DynamicCast<FrameNode>(movingPhotoNode->GetVideo());
14423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(video);
14523b3eb3cSopenharmony_ci    auto renderContext = video->GetRenderContext();
14623b3eb3cSopenharmony_ci    renderContext->AddChild(renderContextForMediaPlayer_, 0);
14723b3eb3cSopenharmony_ci}
14823b3eb3cSopenharmony_ci
14923b3eb3cSopenharmony_civoid MovingPhotoPattern::InitEvent()
15023b3eb3cSopenharmony_ci{
15123b3eb3cSopenharmony_ci    auto host = GetHost();
15223b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
15323b3eb3cSopenharmony_ci    auto gestureHub = host->GetOrCreateGestureEventHub();
15423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(gestureHub);
15523b3eb3cSopenharmony_ci    if (longPressEvent_) {
15623b3eb3cSopenharmony_ci        gestureHub->SetLongPressEvent(longPressEvent_, false, false, LONG_PRESS_DELAY);
15723b3eb3cSopenharmony_ci        return;
15823b3eb3cSopenharmony_ci    }
15923b3eb3cSopenharmony_ci    auto longPressCallback = [weak = WeakClaim(this)](GestureEvent& info) {
16023b3eb3cSopenharmony_ci        auto pattern = weak.Upgrade();
16123b3eb3cSopenharmony_ci        CHECK_NULL_VOID(pattern);
16223b3eb3cSopenharmony_ci        pattern->HandleLongPress(info);
16323b3eb3cSopenharmony_ci    };
16423b3eb3cSopenharmony_ci    longPressEvent_ = MakeRefPtr<LongPressEvent>(std::move(longPressCallback));
16523b3eb3cSopenharmony_ci    gestureHub->SetLongPressEvent(longPressEvent_, false, false, LONG_PRESS_DELAY);
16623b3eb3cSopenharmony_ci
16723b3eb3cSopenharmony_ci    if (touchEvent_) {
16823b3eb3cSopenharmony_ci        gestureHub->AddTouchEvent(touchEvent_);
16923b3eb3cSopenharmony_ci        return;
17023b3eb3cSopenharmony_ci    }
17123b3eb3cSopenharmony_ci    auto touchTask = [weak = WeakClaim(this)](TouchEventInfo& info) {
17223b3eb3cSopenharmony_ci        auto pattern = weak.Upgrade();
17323b3eb3cSopenharmony_ci        CHECK_NULL_VOID(pattern);
17423b3eb3cSopenharmony_ci        pattern->HandleTouchEvent(info);
17523b3eb3cSopenharmony_ci    };
17623b3eb3cSopenharmony_ci    touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(touchTask));
17723b3eb3cSopenharmony_ci    gestureHub->AddTouchEvent(touchEvent_);
17823b3eb3cSopenharmony_ci}
17923b3eb3cSopenharmony_ci
18023b3eb3cSopenharmony_civoid MovingPhotoPattern::LongPressEventModify(bool status)
18123b3eb3cSopenharmony_ci{
18223b3eb3cSopenharmony_ci    auto host = GetHost();
18323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
18423b3eb3cSopenharmony_ci    auto gestureHub = host->GetOrCreateGestureEventHub();
18523b3eb3cSopenharmony_ci    CHECK_NULL_VOID(gestureHub);
18623b3eb3cSopenharmony_ci    if (status) {
18723b3eb3cSopenharmony_ci        auto longPressCallback = [weak = WeakClaim(this)](GestureEvent& info) {
18823b3eb3cSopenharmony_ci            auto pattern = weak.Upgrade();
18923b3eb3cSopenharmony_ci            CHECK_NULL_VOID(pattern);
19023b3eb3cSopenharmony_ci            pattern->HandleLongPress(info);
19123b3eb3cSopenharmony_ci        };
19223b3eb3cSopenharmony_ci        longPressEvent_ = MakeRefPtr<LongPressEvent>(std::move(longPressCallback));
19323b3eb3cSopenharmony_ci        gestureHub->SetLongPressEvent(longPressEvent_, false, false, LONG_PRESS_DELAY);
19423b3eb3cSopenharmony_ci    } else {
19523b3eb3cSopenharmony_ci        gestureHub->SetLongPressEvent(nullptr);
19623b3eb3cSopenharmony_ci        longPressEvent_ = nullptr;
19723b3eb3cSopenharmony_ci    }
19823b3eb3cSopenharmony_ci}
19923b3eb3cSopenharmony_ci
20023b3eb3cSopenharmony_civoid MovingPhotoPattern::HandleLongPress(GestureEvent& info)
20123b3eb3cSopenharmony_ci{
20223b3eb3cSopenharmony_ci    isFastKeyUp_ = false;
20323b3eb3cSopenharmony_ci    if (currentPlayStatus_ == PlaybackStatus::STARTED || !isPrepared_ || isPlayByController_) {
20423b3eb3cSopenharmony_ci        return;
20523b3eb3cSopenharmony_ci    }
20623b3eb3cSopenharmony_ci    if (autoAndRepeatLevel_ == PlaybackMode::NONE && isEnableAnalyzer_) {
20723b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "HandleLongPress isEnableAnalyzer_ return.");
20823b3eb3cSopenharmony_ci        return;
20923b3eb3cSopenharmony_ci    }
21023b3eb3cSopenharmony_ci    if (autoAndRepeatLevel_ != PlaybackMode::NONE) {
21123b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "HandleLongPress auto&Repeat return.");
21223b3eb3cSopenharmony_ci        return;
21323b3eb3cSopenharmony_ci    }
21423b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto HandleLongPress start.");
21523b3eb3cSopenharmony_ci    if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
21623b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null or invalid.");
21723b3eb3cSopenharmony_ci        FireMediaPlayerError();
21823b3eb3cSopenharmony_ci        return;
21923b3eb3cSopenharmony_ci    }
22023b3eb3cSopenharmony_ci    if (currentPlayStatus_ == PlaybackStatus::STOPPED) {
22123b3eb3cSopenharmony_ci        mediaPlayer_->PrepareAsync();
22223b3eb3cSopenharmony_ci    }
22323b3eb3cSopenharmony_ci    if (isSetAutoPlayPeriod_ && (currentPlayStatus_ == PlaybackStatus::PLAYBACK_COMPLETE ||
22423b3eb3cSopenharmony_ci        currentPlayStatus_ == PlaybackStatus::PAUSED)) {
22523b3eb3cSopenharmony_ci        isSetAutoPlayPeriod_ = false;
22623b3eb3cSopenharmony_ci        int32_t duration = DURATION_FLAG;
22723b3eb3cSopenharmony_ci        mediaPlayer_->GetDuration(duration);
22823b3eb3cSopenharmony_ci        SetAutoPlayPeriod(PERIOD_START, duration);
22923b3eb3cSopenharmony_ci    }
23023b3eb3cSopenharmony_ci    Start();
23123b3eb3cSopenharmony_ci}
23223b3eb3cSopenharmony_ci
23323b3eb3cSopenharmony_civoid MovingPhotoPattern::HandleTouchEvent(TouchEventInfo& info)
23423b3eb3cSopenharmony_ci{
23523b3eb3cSopenharmony_ci    if (currentPlayStatus_ == PlaybackStatus::ERROR) {
23623b3eb3cSopenharmony_ci        ResetMediaPlayer();
23723b3eb3cSopenharmony_ci    }
23823b3eb3cSopenharmony_ci    if (autoAndRepeatLevel_ != PlaybackMode::NONE) {
23923b3eb3cSopenharmony_ci        TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "HandleTouchEvent auto&Repeat return.");
24023b3eb3cSopenharmony_ci        return;
24123b3eb3cSopenharmony_ci    }
24223b3eb3cSopenharmony_ci    if (!isPrepared_ || isPlayByController_) {
24323b3eb3cSopenharmony_ci        return;
24423b3eb3cSopenharmony_ci    }
24523b3eb3cSopenharmony_ci    if (autoAndRepeatLevel_ == PlaybackMode::NONE && isEnableAnalyzer_) {
24623b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "HandleTouchEvent isEnableAnalyzer_ return.");
24723b3eb3cSopenharmony_ci        return;
24823b3eb3cSopenharmony_ci    }
24923b3eb3cSopenharmony_ci    auto touchList = info.GetChangedTouches();
25023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(!touchList.empty());
25123b3eb3cSopenharmony_ci    auto touchInfo = touchList.front();
25223b3eb3cSopenharmony_ci    auto touchType = touchInfo.GetTouchType();
25323b3eb3cSopenharmony_ci    isFastKeyUp_ = false;
25423b3eb3cSopenharmony_ci    if (touchType == TouchType::UP || touchType == TouchType::CANCEL) {
25523b3eb3cSopenharmony_ci        if (currentPlayStatus_ == PlaybackStatus::STARTED) {
25623b3eb3cSopenharmony_ci            PausePlayback();
25723b3eb3cSopenharmony_ci        } else if (currentPlayStatus_ == PlaybackStatus::PLAYBACK_COMPLETE) {
25823b3eb3cSopenharmony_ci            currentPlayStatus_ = PlaybackStatus::NONE;
25923b3eb3cSopenharmony_ci            StopAnimation();
26023b3eb3cSopenharmony_ci        } else {
26123b3eb3cSopenharmony_ci            isFastKeyUp_ = true;
26223b3eb3cSopenharmony_ci        }
26323b3eb3cSopenharmony_ci    }
26423b3eb3cSopenharmony_ci}
26523b3eb3cSopenharmony_ci
26623b3eb3cSopenharmony_civoid MovingPhotoPattern::UpdateImageNode()
26723b3eb3cSopenharmony_ci{
26823b3eb3cSopenharmony_ci    if (startAnimationFlag_) {
26923b3eb3cSopenharmony_ci        needUpdateImageNode_ = true;
27023b3eb3cSopenharmony_ci        return;
27123b3eb3cSopenharmony_ci    }
27223b3eb3cSopenharmony_ci    auto host = GetHost();
27323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
27423b3eb3cSopenharmony_ci    auto movingPhoto = AceType::DynamicCast<MovingPhotoNode>(host);
27523b3eb3cSopenharmony_ci    CHECK_NULL_VOID(movingPhoto);
27623b3eb3cSopenharmony_ci    auto image = AceType::DynamicCast<FrameNode>(movingPhoto->GetImage());
27723b3eb3cSopenharmony_ci    CHECK_NULL_VOID(image);
27823b3eb3cSopenharmony_ci    ACE_UPDATE_NODE_PAINT_PROPERTY(ImageRenderProperty, DynamicMode, DynamicRangeMode::HIGH, image);
27923b3eb3cSopenharmony_ci    ACE_UPDATE_NODE_RENDER_CONTEXT(DynamicRangeMode, DynamicRangeMode::HIGH, image);
28023b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto set HDR.");
28123b3eb3cSopenharmony_ci    auto layoutProperty = GetLayoutProperty<MovingPhotoLayoutProperty>();
28223b3eb3cSopenharmony_ci    CHECK_NULL_VOID(layoutProperty);
28323b3eb3cSopenharmony_ci    if (!layoutProperty->HasImageSourceInfo()) {
28423b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "image info is null.");
28523b3eb3cSopenharmony_ci        auto posterLayoutProperty = image->GetLayoutProperty<ImageLayoutProperty>();
28623b3eb3cSopenharmony_ci        posterLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
28723b3eb3cSopenharmony_ci        image->MarkModifyDone();
28823b3eb3cSopenharmony_ci        return;
28923b3eb3cSopenharmony_ci    }
29023b3eb3cSopenharmony_ci    auto imageSourceInfo = layoutProperty->GetImageSourceInfo().value();
29123b3eb3cSopenharmony_ci    auto imageFit = layoutProperty->GetObjectFitValue(ImageFit::COVER);
29223b3eb3cSopenharmony_ci    if (!imageSourceInfo.IsValid()) {
29323b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "image info is invalid.");
29423b3eb3cSopenharmony_ci        auto posterLayoutProperty = image->GetLayoutProperty<ImageLayoutProperty>();
29523b3eb3cSopenharmony_ci        posterLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
29623b3eb3cSopenharmony_ci        image->MarkModifyDone();
29723b3eb3cSopenharmony_ci        return;
29823b3eb3cSopenharmony_ci    }
29923b3eb3cSopenharmony_ci    if (image) {
30023b3eb3cSopenharmony_ci        image->SetDraggable(false);
30123b3eb3cSopenharmony_ci        auto imageLayoutProperty = image->GetLayoutProperty<ImageLayoutProperty>();
30223b3eb3cSopenharmony_ci        imageLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
30323b3eb3cSopenharmony_ci        imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
30423b3eb3cSopenharmony_ci        imageLayoutProperty->UpdateImageFit(imageFit);
30523b3eb3cSopenharmony_ci        image->MarkModifyDone();
30623b3eb3cSopenharmony_ci    }
30723b3eb3cSopenharmony_ci    RegisterImageEvent();
30823b3eb3cSopenharmony_ci}
30923b3eb3cSopenharmony_ci
31023b3eb3cSopenharmony_civoid MovingPhotoPattern::RegisterImageEvent()
31123b3eb3cSopenharmony_ci{
31223b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "MovingPhoto RegisterImageEvent start.");
31323b3eb3cSopenharmony_ci    auto host = GetHost();
31423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
31523b3eb3cSopenharmony_ci    auto movingPhoto = AceType::DynamicCast<MovingPhotoNode>(host);
31623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(movingPhoto);
31723b3eb3cSopenharmony_ci    auto image = AceType::DynamicCast<FrameNode>(movingPhoto->GetImage());
31823b3eb3cSopenharmony_ci    CHECK_NULL_VOID(image);
31923b3eb3cSopenharmony_ci    auto imageHub = image->GetEventHub<ImageEventHub>();
32023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageHub);
32123b3eb3cSopenharmony_ci    auto imageCompleteEventCallback = [weak = WeakClaim(this)](const LoadImageSuccessEvent& info) {
32223b3eb3cSopenharmony_ci        auto pattern = weak.Upgrade();
32323b3eb3cSopenharmony_ci        CHECK_NULL_VOID(pattern);
32423b3eb3cSopenharmony_ci        pattern->HandleImageCompleteEvent(info);
32523b3eb3cSopenharmony_ci    };
32623b3eb3cSopenharmony_ci    imageHub->SetOnComplete(imageCompleteEventCallback);
32723b3eb3cSopenharmony_ci}
32823b3eb3cSopenharmony_ci
32923b3eb3cSopenharmony_civoid MovingPhotoPattern::HandleImageCompleteEvent(const LoadImageSuccessEvent& info)
33023b3eb3cSopenharmony_ci{
33123b3eb3cSopenharmony_ci    auto loadingStatus = info.GetLoadingStatus();
33223b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "HandleImageCompleteEvent start:%{public}d.", loadingStatus);
33323b3eb3cSopenharmony_ci    if (loadingStatus == IMAGE_LOADING_COMPLETE) {
33423b3eb3cSopenharmony_ci        FireMediaPlayerImageComplete();
33523b3eb3cSopenharmony_ci    }
33623b3eb3cSopenharmony_ci}
33723b3eb3cSopenharmony_ci
33823b3eb3cSopenharmony_civoid MovingPhotoPattern::UpdateVideoNode()
33923b3eb3cSopenharmony_ci{
34023b3eb3cSopenharmony_ci    ContainerScope scope(instanceId_);
34123b3eb3cSopenharmony_ci    auto pipelineContext = PipelineContext::GetCurrentContext();
34223b3eb3cSopenharmony_ci    CHECK_NULL_VOID(pipelineContext);
34323b3eb3cSopenharmony_ci    auto uiTaskExecutor = SingleTaskExecutor::Make(pipelineContext->GetTaskExecutor(), TaskExecutor::TaskType::UI);
34423b3eb3cSopenharmony_ci    uiTaskExecutor.PostTask(
34523b3eb3cSopenharmony_ci        [weak = WeakClaim(this)]() {
34623b3eb3cSopenharmony_ci            auto movingPhotoPattern = weak.Upgrade();
34723b3eb3cSopenharmony_ci            CHECK_NULL_VOID(movingPhotoPattern);
34823b3eb3cSopenharmony_ci            ContainerScope scope(movingPhotoPattern->instanceId_);
34923b3eb3cSopenharmony_ci            movingPhotoPattern->PrepareMediaPlayer();
35023b3eb3cSopenharmony_ci            movingPhotoPattern->UpdateMediaPlayerSpeed();
35123b3eb3cSopenharmony_ci            movingPhotoPattern->UpdateMediaPlayerMuted();
35223b3eb3cSopenharmony_ci        },
35323b3eb3cSopenharmony_ci        "ArkUIMovingPhotoUpdateVideo");
35423b3eb3cSopenharmony_ci}
35523b3eb3cSopenharmony_ci
35623b3eb3cSopenharmony_civoid MovingPhotoPattern::PrepareMediaPlayer()
35723b3eb3cSopenharmony_ci{
35823b3eb3cSopenharmony_ci    auto layoutProperty = GetLayoutProperty<MovingPhotoLayoutProperty>();
35923b3eb3cSopenharmony_ci    CHECK_NULL_VOID(layoutProperty);
36023b3eb3cSopenharmony_ci    if (!layoutProperty->HasMovingPhotoUri() || !layoutProperty->HasVideoSource()) {
36123b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MovingPhoto source is null.");
36223b3eb3cSopenharmony_ci        return;
36323b3eb3cSopenharmony_ci    }
36423b3eb3cSopenharmony_ci    if (layoutProperty->GetMovingPhotoUri().value() == uri_ &&
36523b3eb3cSopenharmony_ci        layoutProperty->GetVideoSource().value() == fd_) {
36623b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer source has not changed.");
36723b3eb3cSopenharmony_ci        return;
36823b3eb3cSopenharmony_ci    }
36923b3eb3cSopenharmony_ci    uri_ = layoutProperty->GetMovingPhotoUri().value();
37023b3eb3cSopenharmony_ci    fd_ = layoutProperty->GetVideoSource().value();
37123b3eb3cSopenharmony_ci    if (!mediaPlayer_) {
37223b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null.");
37323b3eb3cSopenharmony_ci        FireMediaPlayerError();
37423b3eb3cSopenharmony_ci        return;
37523b3eb3cSopenharmony_ci    }
37623b3eb3cSopenharmony_ci    if (!mediaPlayer_->IsMediaPlayerValid()) {
37723b3eb3cSopenharmony_ci        mediaPlayer_->CreateMediaPlayer();
37823b3eb3cSopenharmony_ci    }
37923b3eb3cSopenharmony_ci    if (!mediaPlayer_->IsMediaPlayerValid()) {
38023b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is invalid.");
38123b3eb3cSopenharmony_ci        FireMediaPlayerError();
38223b3eb3cSopenharmony_ci        return;
38323b3eb3cSopenharmony_ci    }
38423b3eb3cSopenharmony_ci    ContainerScope scope(instanceId_);
38523b3eb3cSopenharmony_ci    auto context = PipelineContext::GetCurrentContext();
38623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
38723b3eb3cSopenharmony_ci    auto platformTask = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::BACKGROUND);
38823b3eb3cSopenharmony_ci    platformTask.PostTask(
38923b3eb3cSopenharmony_ci        [weak = WeakClaim(this)] {
39023b3eb3cSopenharmony_ci            auto movingPhotoPattern = weak.Upgrade();
39123b3eb3cSopenharmony_ci            CHECK_NULL_VOID(movingPhotoPattern);
39223b3eb3cSopenharmony_ci            movingPhotoPattern->ResetMediaPlayer();
39323b3eb3cSopenharmony_ci        },
39423b3eb3cSopenharmony_ci        "ArkUIMovingPhotoPrepare");
39523b3eb3cSopenharmony_ci}
39623b3eb3cSopenharmony_ci
39723b3eb3cSopenharmony_civoid MovingPhotoPattern::ResetMediaPlayer()
39823b3eb3cSopenharmony_ci{
39923b3eb3cSopenharmony_ci    CHECK_NULL_VOID(mediaPlayer_);
40023b3eb3cSopenharmony_ci    isPrepared_ = false;
40123b3eb3cSopenharmony_ci    mediaPlayer_->ResetMediaPlayer();
40223b3eb3cSopenharmony_ci    RegisterMediaPlayerEvent();
40323b3eb3cSopenharmony_ci    if (!mediaPlayer_->SetSourceByFd(fd_)) {
40423b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "set source for MediaPlayer failed.");
40523b3eb3cSopenharmony_ci        ContainerScope scope(instanceId_);
40623b3eb3cSopenharmony_ci        auto context = PipelineContext::GetCurrentContext();
40723b3eb3cSopenharmony_ci        CHECK_NULL_VOID(context);
40823b3eb3cSopenharmony_ci
40923b3eb3cSopenharmony_ci        auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
41023b3eb3cSopenharmony_ci        uiTaskExecutor.PostTask(
41123b3eb3cSopenharmony_ci            [weak = WeakClaim(this)] {
41223b3eb3cSopenharmony_ci                auto pattern = weak.Upgrade();
41323b3eb3cSopenharmony_ci                CHECK_NULL_VOID(pattern);
41423b3eb3cSopenharmony_ci                ContainerScope scope(pattern->instanceId_);
41523b3eb3cSopenharmony_ci                pattern->FireMediaPlayerError();
41623b3eb3cSopenharmony_ci            },
41723b3eb3cSopenharmony_ci            "ArkUIMovingPhotoReset");
41823b3eb3cSopenharmony_ci        return;
41923b3eb3cSopenharmony_ci    }
42023b3eb3cSopenharmony_ci}
42123b3eb3cSopenharmony_ci
42223b3eb3cSopenharmony_civoid MovingPhotoPattern::RegisterMediaPlayerEvent()
42323b3eb3cSopenharmony_ci{
42423b3eb3cSopenharmony_ci    if (fd_ == -1 || !mediaPlayer_) {
42523b3eb3cSopenharmony_ci        return;
42623b3eb3cSopenharmony_ci    }
42723b3eb3cSopenharmony_ci    ContainerScope scope(instanceId_);
42823b3eb3cSopenharmony_ci    auto context = PipelineContext::GetCurrentContext();
42923b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
43023b3eb3cSopenharmony_ci    auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
43123b3eb3cSopenharmony_ci    auto movingPhotoPattern = WeakClaim(this);
43223b3eb3cSopenharmony_ci
43323b3eb3cSopenharmony_ci    auto&& positionUpdatedEvent = [movingPhotoPattern, uiTaskExecutor](uint32_t currentPos) {
43423b3eb3cSopenharmony_ci        uiTaskExecutor.PostTask([movingPhotoPattern, currentPos] {
43523b3eb3cSopenharmony_ci            auto movingPhoto = movingPhotoPattern.Upgrade();
43623b3eb3cSopenharmony_ci            CHECK_NULL_VOID(movingPhoto);
43723b3eb3cSopenharmony_ci            ContainerScope scope(movingPhoto->instanceId_);
43823b3eb3cSopenharmony_ci            movingPhoto->OnPlayPositionChanged(currentPos);
43923b3eb3cSopenharmony_ci        }, "ArkUIMovingPhotoPositionChanged");
44023b3eb3cSopenharmony_ci    };
44123b3eb3cSopenharmony_ci
44223b3eb3cSopenharmony_ci    auto&& stateChangedEvent = [movingPhotoPattern, uiTaskExecutor](PlaybackStatus status) {
44323b3eb3cSopenharmony_ci        uiTaskExecutor.PostTask([movingPhotoPattern, status] {
44423b3eb3cSopenharmony_ci            auto movingPhoto = movingPhotoPattern.Upgrade();
44523b3eb3cSopenharmony_ci            CHECK_NULL_VOID(movingPhoto);
44623b3eb3cSopenharmony_ci            ContainerScope scope(movingPhoto->instanceId_);
44723b3eb3cSopenharmony_ci            movingPhoto->OnMediaPlayerStatusChanged(status);
44823b3eb3cSopenharmony_ci        }, "ArkUIMovingPhotoStatusChanged");
44923b3eb3cSopenharmony_ci    };
45023b3eb3cSopenharmony_ci
45123b3eb3cSopenharmony_ci    auto&& errorEvent = [movingPhotoPattern, uiTaskExecutor]() {
45223b3eb3cSopenharmony_ci        uiTaskExecutor.PostSyncTask([movingPhotoPattern] {
45323b3eb3cSopenharmony_ci            auto movingPhoto = movingPhotoPattern.Upgrade();
45423b3eb3cSopenharmony_ci            CHECK_NULL_VOID(movingPhoto);
45523b3eb3cSopenharmony_ci            ContainerScope scope(movingPhoto->instanceId_);
45623b3eb3cSopenharmony_ci            movingPhoto->FireMediaPlayerError();
45723b3eb3cSopenharmony_ci        }, "ArkUIMovingPhotoOnError");
45823b3eb3cSopenharmony_ci    };
45923b3eb3cSopenharmony_ci
46023b3eb3cSopenharmony_ci    auto&& resolutionChangeEvent = [movingPhotoPattern, uiTaskExecutor]() {
46123b3eb3cSopenharmony_ci        uiTaskExecutor.PostTask([movingPhotoPattern] {
46223b3eb3cSopenharmony_ci            auto movingPhoto = movingPhotoPattern.Upgrade();
46323b3eb3cSopenharmony_ci            CHECK_NULL_VOID(movingPhoto);
46423b3eb3cSopenharmony_ci            ContainerScope scope(movingPhoto->instanceId_);
46523b3eb3cSopenharmony_ci            movingPhoto->OnResolutionChange();
46623b3eb3cSopenharmony_ci        }, "ArkUIMovingPhotoResolutionChanged");
46723b3eb3cSopenharmony_ci    };
46823b3eb3cSopenharmony_ci
46923b3eb3cSopenharmony_ci    auto&& startRenderFrameEvent = [movingPhotoPattern, uiTaskExecutor]() {
47023b3eb3cSopenharmony_ci        uiTaskExecutor.PostTask([movingPhotoPattern] {
47123b3eb3cSopenharmony_ci            auto movingPhoto = movingPhotoPattern.Upgrade();
47223b3eb3cSopenharmony_ci            CHECK_NULL_VOID(movingPhoto);
47323b3eb3cSopenharmony_ci            ContainerScope scope(movingPhoto->instanceId_);
47423b3eb3cSopenharmony_ci            movingPhoto->OnStartRenderFrame();
47523b3eb3cSopenharmony_ci        }, "ArkUIMovingPhotoStartRender");
47623b3eb3cSopenharmony_ci    };
47723b3eb3cSopenharmony_ci
47823b3eb3cSopenharmony_ci    mediaPlayer_->RegisterMediaPlayerEvent(
47923b3eb3cSopenharmony_ci        positionUpdatedEvent, stateChangedEvent, errorEvent, resolutionChangeEvent, startRenderFrameEvent);
48023b3eb3cSopenharmony_ci}
48123b3eb3cSopenharmony_ci
48223b3eb3cSopenharmony_civoid MovingPhotoPattern::PrepareSurface()
48323b3eb3cSopenharmony_ci{
48423b3eb3cSopenharmony_ci    if (!mediaPlayer_ || renderSurface_->IsSurfaceValid()) {
48523b3eb3cSopenharmony_ci        return;
48623b3eb3cSopenharmony_ci    }
48723b3eb3cSopenharmony_ci    if (!SystemProperties::GetExtSurfaceEnabled()) {
48823b3eb3cSopenharmony_ci        renderSurface_->SetRenderContext(renderContextForMediaPlayer_);
48923b3eb3cSopenharmony_ci    }
49023b3eb3cSopenharmony_ci    renderSurface_->InitSurface();
49123b3eb3cSopenharmony_ci    mediaPlayer_->SetRenderSurface(renderSurface_);
49223b3eb3cSopenharmony_ci    if (mediaPlayer_->SetSurface() != 0) {
49323b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "prepare MediaPlayer failed.");
49423b3eb3cSopenharmony_ci    }
49523b3eb3cSopenharmony_ci}
49623b3eb3cSopenharmony_ci
49723b3eb3cSopenharmony_civoid MovingPhotoPattern::UpdatePlayMode()
49823b3eb3cSopenharmony_ci{
49923b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto UpdatePlayMode.%{public}d", isChangePlayMode_);
50023b3eb3cSopenharmony_ci    if (isChangePlayMode_) {
50123b3eb3cSopenharmony_ci        if (historyAutoAndRepeatLevel_ == PlaybackMode::AUTO) {
50223b3eb3cSopenharmony_ci            SetAutoPlayPeriod(autoPlayPeriodStartTime_, autoPlayPeriodEndTime_);
50323b3eb3cSopenharmony_ci        }
50423b3eb3cSopenharmony_ci        MediaResetToPlay();
50523b3eb3cSopenharmony_ci        isChangePlayMode_ = false;
50623b3eb3cSopenharmony_ci    }
50723b3eb3cSopenharmony_ci}
50823b3eb3cSopenharmony_ci
50923b3eb3cSopenharmony_civoid MovingPhotoPattern::HandleImageAnalyzerMode()
51023b3eb3cSopenharmony_ci{
51123b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto HandleImageAnalyzerMode.");
51223b3eb3cSopenharmony_ci    if (isEnableAnalyzer_ && autoAndRepeatLevel_ == PlaybackMode::NONE) {
51323b3eb3cSopenharmony_ci        if (!imageAnalyzerManager_) {
51423b3eb3cSopenharmony_ci            EnableAnalyzer(isEnableAnalyzer_);
51523b3eb3cSopenharmony_ci        }
51623b3eb3cSopenharmony_ci        if (imageAnalyzerManager_ && !GetAnalyzerState()) {
51723b3eb3cSopenharmony_ci            StartImageAnalyzer();
51823b3eb3cSopenharmony_ci        }
51923b3eb3cSopenharmony_ci    }
52023b3eb3cSopenharmony_ci    if (!isEnableAnalyzer_ && IsSupportImageAnalyzer()) {
52123b3eb3cSopenharmony_ci        DestroyAnalyzerOverlay();
52223b3eb3cSopenharmony_ci        LongPressEventModify(true);
52323b3eb3cSopenharmony_ci    }
52423b3eb3cSopenharmony_ci}
52523b3eb3cSopenharmony_ci
52623b3eb3cSopenharmony_civoid MovingPhotoPattern::MediaResetToPlay()
52723b3eb3cSopenharmony_ci{
52823b3eb3cSopenharmony_ci    autoAndRepeatLevel_ = historyAutoAndRepeatLevel_;
52923b3eb3cSopenharmony_ci    if (currentPlayStatus_ == PlaybackStatus::STOPPED) {
53023b3eb3cSopenharmony_ci        mediaPlayer_->PrepareAsync();
53123b3eb3cSopenharmony_ci    } else if (currentPlayStatus_ == PlaybackStatus::PLAYBACK_COMPLETE ||
53223b3eb3cSopenharmony_ci        currentPlayStatus_ == PlaybackStatus::PAUSED ||
53323b3eb3cSopenharmony_ci        currentPlayStatus_ == PlaybackStatus::PREPARED) {
53423b3eb3cSopenharmony_ci            SelectPlaybackMode(historyAutoAndRepeatLevel_);
53523b3eb3cSopenharmony_ci    }
53623b3eb3cSopenharmony_ci}
53723b3eb3cSopenharmony_ci
53823b3eb3cSopenharmony_civoid MovingPhotoPattern::FireMediaPlayerImageComplete()
53923b3eb3cSopenharmony_ci{
54023b3eb3cSopenharmony_ci    auto eventHub = GetEventHub<MovingPhotoEventHub>();
54123b3eb3cSopenharmony_ci    CHECK_NULL_VOID(eventHub);
54223b3eb3cSopenharmony_ci    eventHub->FireCompleteEvent();
54323b3eb3cSopenharmony_ci}
54423b3eb3cSopenharmony_ci
54523b3eb3cSopenharmony_civoid MovingPhotoPattern::FireMediaPlayerStart()
54623b3eb3cSopenharmony_ci{
54723b3eb3cSopenharmony_ci    auto eventHub = GetEventHub<MovingPhotoEventHub>();
54823b3eb3cSopenharmony_ci    CHECK_NULL_VOID(eventHub);
54923b3eb3cSopenharmony_ci    eventHub->FireStartEvent();
55023b3eb3cSopenharmony_ci    if (isFastKeyUp_) {
55123b3eb3cSopenharmony_ci        isFastKeyUp_ = false;
55223b3eb3cSopenharmony_ci        PausePlayback();
55323b3eb3cSopenharmony_ci    }
55423b3eb3cSopenharmony_ci}
55523b3eb3cSopenharmony_ci
55623b3eb3cSopenharmony_civoid MovingPhotoPattern::FireMediaPlayerStop()
55723b3eb3cSopenharmony_ci{
55823b3eb3cSopenharmony_ci    auto eventHub = GetEventHub<MovingPhotoEventHub>();
55923b3eb3cSopenharmony_ci    CHECK_NULL_VOID(eventHub);
56023b3eb3cSopenharmony_ci    eventHub->FireStopEvent();
56123b3eb3cSopenharmony_ci}
56223b3eb3cSopenharmony_ci
56323b3eb3cSopenharmony_civoid MovingPhotoPattern::FireMediaPlayerPause()
56423b3eb3cSopenharmony_ci{
56523b3eb3cSopenharmony_ci    auto eventHub = GetEventHub<MovingPhotoEventHub>();
56623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(eventHub);
56723b3eb3cSopenharmony_ci    eventHub->FirePauseEvent();
56823b3eb3cSopenharmony_ci}
56923b3eb3cSopenharmony_ci
57023b3eb3cSopenharmony_civoid MovingPhotoPattern::FireMediaPlayerFinish()
57123b3eb3cSopenharmony_ci{
57223b3eb3cSopenharmony_ci    auto eventHub = GetEventHub<MovingPhotoEventHub>();
57323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(eventHub);
57423b3eb3cSopenharmony_ci    eventHub->FireFinishEvent();
57523b3eb3cSopenharmony_ci}
57623b3eb3cSopenharmony_ci
57723b3eb3cSopenharmony_civoid MovingPhotoPattern::FireMediaPlayerError()
57823b3eb3cSopenharmony_ci{
57923b3eb3cSopenharmony_ci    auto eventHub = GetEventHub<MovingPhotoEventHub>();
58023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(eventHub);
58123b3eb3cSopenharmony_ci    eventHub->FireErrorEvent();
58223b3eb3cSopenharmony_ci}
58323b3eb3cSopenharmony_ci
58423b3eb3cSopenharmony_civoid MovingPhotoPattern::OnResolutionChange()
58523b3eb3cSopenharmony_ci{
58623b3eb3cSopenharmony_ci    if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
58723b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null or invalid.");
58823b3eb3cSopenharmony_ci        return;
58923b3eb3cSopenharmony_ci    }
59023b3eb3cSopenharmony_ci    auto host = GetHost();
59123b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
59223b3eb3cSopenharmony_ci    SizeF videoSize =
59323b3eb3cSopenharmony_ci        SizeF(static_cast<float>(mediaPlayer_->GetVideoWidth()), static_cast<float>(mediaPlayer_->GetVideoHeight()));
59423b3eb3cSopenharmony_ci    auto movingPhotoLayoutProperty = host->GetLayoutProperty<MovingPhotoLayoutProperty>();
59523b3eb3cSopenharmony_ci    CHECK_NULL_VOID(movingPhotoLayoutProperty);
59623b3eb3cSopenharmony_ci    movingPhotoLayoutProperty->UpdateVideoSize(videoSize);
59723b3eb3cSopenharmony_ci    host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
59823b3eb3cSopenharmony_ci}
59923b3eb3cSopenharmony_ci
60023b3eb3cSopenharmony_civoid MovingPhotoPattern::OnStartRenderFrame()
60123b3eb3cSopenharmony_ci{
60223b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer OnStartRenderFrame.");
60323b3eb3cSopenharmony_ci}
60423b3eb3cSopenharmony_ci
60523b3eb3cSopenharmony_civoid MovingPhotoPattern::OnStartedStatusCallback()
60623b3eb3cSopenharmony_ci{
60723b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer OnStartedStatusCallback.");
60823b3eb3cSopenharmony_ci    ACE_FUNCTION_TRACE();
60923b3eb3cSopenharmony_ci    auto host = GetHost();
61023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
61123b3eb3cSopenharmony_ci    auto movingPhoto = AceType::DynamicCast<MovingPhotoNode>(host);
61223b3eb3cSopenharmony_ci    CHECK_NULL_VOID(movingPhoto);
61323b3eb3cSopenharmony_ci    auto image = AceType::DynamicCast<FrameNode>(movingPhoto->GetImage());
61423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(image);
61523b3eb3cSopenharmony_ci    StartAnimation();
61623b3eb3cSopenharmony_ci}
61723b3eb3cSopenharmony_ci
61823b3eb3cSopenharmony_cibool MovingPhotoPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
61923b3eb3cSopenharmony_ci{
62023b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer OnStartedStatusCallback.");
62123b3eb3cSopenharmony_ci    if (config.skipMeasure || dirty->SkipMeasureContent()) {
62223b3eb3cSopenharmony_ci        return false;
62323b3eb3cSopenharmony_ci    }
62423b3eb3cSopenharmony_ci    auto geometryNode = dirty->GetGeometryNode();
62523b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(geometryNode, false);
62623b3eb3cSopenharmony_ci    auto movingPhotoNodeSize = geometryNode->GetContentSize();
62723b3eb3cSopenharmony_ci    auto layoutProperty = GetLayoutProperty<MovingPhotoLayoutProperty>();
62823b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(layoutProperty, false);
62923b3eb3cSopenharmony_ci    auto videoFrameSize = MeasureContentLayout(movingPhotoNodeSize, layoutProperty);
63023b3eb3cSopenharmony_ci    if (renderContextForMediaPlayer_) {
63123b3eb3cSopenharmony_ci        renderContextForMediaPlayer_->SetBounds((movingPhotoNodeSize.Width() - videoFrameSize.Width()) / HALF,
63223b3eb3cSopenharmony_ci            (movingPhotoNodeSize.Height() - videoFrameSize.Height()) / HALF, videoFrameSize.Width(),
63323b3eb3cSopenharmony_ci            videoFrameSize.Height());
63423b3eb3cSopenharmony_ci    }
63523b3eb3cSopenharmony_ci
63623b3eb3cSopenharmony_ci    if (IsSupportImageAnalyzer() && isEnableAnalyzer_ && autoAndRepeatLevel_ == PlaybackMode::NONE) {
63723b3eb3cSopenharmony_ci        if (imageAnalyzerManager_ && !GetAnalyzerState()) {
63823b3eb3cSopenharmony_ci            StartImageAnalyzer();
63923b3eb3cSopenharmony_ci        } else {
64023b3eb3cSopenharmony_ci            Rect tmpRect;
64123b3eb3cSopenharmony_ci            auto padding = layoutProperty->CreatePaddingAndBorder();
64223b3eb3cSopenharmony_ci            auto imageFit = layoutProperty->GetObjectFitValue(ImageFit::COVER);
64323b3eb3cSopenharmony_ci            if (imageFit == ImageFit::COVER || imageFit == ImageFit::NONE) {
64423b3eb3cSopenharmony_ci                tmpRect = Rect(padding.left.value_or(0), padding.top.value_or(0),
64523b3eb3cSopenharmony_ci                               movingPhotoNodeSize.Width(), movingPhotoNodeSize.Height());
64623b3eb3cSopenharmony_ci            } else {
64723b3eb3cSopenharmony_ci                tmpRect = Rect(
64823b3eb3cSopenharmony_ci                    (movingPhotoNodeSize.Width() - videoFrameSize.Width()) / AVERAGE_VALUE + padding.left.value_or(0),
64923b3eb3cSopenharmony_ci                    (movingPhotoNodeSize.Height() - videoFrameSize.Height()) / AVERAGE_VALUE + padding.top.value_or(0),
65023b3eb3cSopenharmony_ci                    videoFrameSize.Width(), videoFrameSize.Height());
65123b3eb3cSopenharmony_ci            }
65223b3eb3cSopenharmony_ci            contentRect_ = tmpRect;
65323b3eb3cSopenharmony_ci            UpdateAnalyzerUIConfig(geometryNode);
65423b3eb3cSopenharmony_ci        }
65523b3eb3cSopenharmony_ci    }
65623b3eb3cSopenharmony_ci    if (IsSupportImageAnalyzer() && !isEnableAnalyzer_) {
65723b3eb3cSopenharmony_ci        DestroyAnalyzerOverlay();
65823b3eb3cSopenharmony_ci        LongPressEventModify(true);
65923b3eb3cSopenharmony_ci    }
66023b3eb3cSopenharmony_ci
66123b3eb3cSopenharmony_ci    auto host = GetHost();
66223b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(host, false);
66323b3eb3cSopenharmony_ci    host->MarkNeedSyncRenderTree();
66423b3eb3cSopenharmony_ci    auto movingPhoto = AceType::DynamicCast<MovingPhotoNode>(host);
66523b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(movingPhoto, false);
66623b3eb3cSopenharmony_ci    auto video = AceType::DynamicCast<FrameNode>(movingPhoto->GetVideo());
66723b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(video, false);
66823b3eb3cSopenharmony_ci    video->GetRenderContext()->SetClipToBounds(true);
66923b3eb3cSopenharmony_ci    return false;
67023b3eb3cSopenharmony_ci}
67123b3eb3cSopenharmony_ci
67223b3eb3cSopenharmony_ciSizeF MovingPhotoPattern::CalculateFitContain(const SizeF& rawSize, const SizeF& layoutSize)
67323b3eb3cSopenharmony_ci{
67423b3eb3cSopenharmony_ci    if (NearZero(rawSize.Height()) || NearZero(rawSize.Width()) || NearZero(layoutSize.Height())) {
67523b3eb3cSopenharmony_ci        return layoutSize;
67623b3eb3cSopenharmony_ci    }
67723b3eb3cSopenharmony_ci    double sourceRatio = rawSize.Width() / rawSize.Height();
67823b3eb3cSopenharmony_ci    double layoutRatio = layoutSize.Width() / layoutSize.Height();
67923b3eb3cSopenharmony_ci    if (sourceRatio < layoutRatio) {
68023b3eb3cSopenharmony_ci        float ratio = layoutSize.Height() / rawSize.Height();
68123b3eb3cSopenharmony_ci        return { rawSize.Width() * ratio, layoutSize.Height() };
68223b3eb3cSopenharmony_ci    } else {
68323b3eb3cSopenharmony_ci        float ratio = layoutSize.Width() / rawSize.Width();
68423b3eb3cSopenharmony_ci        return { layoutSize.Width(), rawSize.Height() * ratio };
68523b3eb3cSopenharmony_ci    }
68623b3eb3cSopenharmony_ci}
68723b3eb3cSopenharmony_ci
68823b3eb3cSopenharmony_ciSizeF MovingPhotoPattern::CalculateFitFill(const SizeF& layoutSize)
68923b3eb3cSopenharmony_ci{
69023b3eb3cSopenharmony_ci    return layoutSize;
69123b3eb3cSopenharmony_ci}
69223b3eb3cSopenharmony_ci
69323b3eb3cSopenharmony_ciSizeF MovingPhotoPattern::CalculateFitCover(const SizeF& rawSize, const SizeF& layoutSize)
69423b3eb3cSopenharmony_ci{
69523b3eb3cSopenharmony_ci    if (NearZero(rawSize.Height()) || NearZero(rawSize.Width()) || NearZero(layoutSize.Height())) {
69623b3eb3cSopenharmony_ci        return layoutSize;
69723b3eb3cSopenharmony_ci    }
69823b3eb3cSopenharmony_ci    double sourceRatio = rawSize.Width() / rawSize.Height();
69923b3eb3cSopenharmony_ci    double layoutRatio = layoutSize.Width() / layoutSize.Height();
70023b3eb3cSopenharmony_ci    float ratio = 1.0;
70123b3eb3cSopenharmony_ci    if (sourceRatio < layoutRatio) {
70223b3eb3cSopenharmony_ci        ratio = static_cast<float>(layoutSize.Width() / rawSize.Width());
70323b3eb3cSopenharmony_ci    } else {
70423b3eb3cSopenharmony_ci        ratio = static_cast<float>(layoutSize.Height() / rawSize.Height());
70523b3eb3cSopenharmony_ci    }
70623b3eb3cSopenharmony_ci    return { rawSize.Width() * ratio, rawSize.Height() * ratio};
70723b3eb3cSopenharmony_ci}
70823b3eb3cSopenharmony_ci
70923b3eb3cSopenharmony_ciSizeF MovingPhotoPattern::CalculateFitNone(const SizeF& rawSize)
71023b3eb3cSopenharmony_ci{
71123b3eb3cSopenharmony_ci    return rawSize;
71223b3eb3cSopenharmony_ci}
71323b3eb3cSopenharmony_ci
71423b3eb3cSopenharmony_ciSizeF MovingPhotoPattern::CalculateFitScaleDown(const SizeF& rawSize, const SizeF& layoutSize)
71523b3eb3cSopenharmony_ci{
71623b3eb3cSopenharmony_ci    if ((rawSize.Width() <= layoutSize.Width()) && (rawSize.Height() <= layoutSize.Height())) {
71723b3eb3cSopenharmony_ci        return CalculateFitNone(rawSize);
71823b3eb3cSopenharmony_ci    } else {
71923b3eb3cSopenharmony_ci        return CalculateFitContain(rawSize, layoutSize);
72023b3eb3cSopenharmony_ci    }
72123b3eb3cSopenharmony_ci}
72223b3eb3cSopenharmony_ci
72323b3eb3cSopenharmony_ciSizeF MovingPhotoPattern::CalculateFitAuto(const SizeF& rawSize, const SizeF& layoutSize)
72423b3eb3cSopenharmony_ci{
72523b3eb3cSopenharmony_ci    if (NearZero(rawSize.Width()) || NearZero(rawSize.Height())) {
72623b3eb3cSopenharmony_ci        return layoutSize;
72723b3eb3cSopenharmony_ci    }
72823b3eb3cSopenharmony_ci    if ((rawSize.Width() <= layoutSize.Width()) && (rawSize.Height() <= layoutSize.Height())) {
72923b3eb3cSopenharmony_ci        double widthRatio = layoutSize.Width() / rawSize.Width();
73023b3eb3cSopenharmony_ci        double heightRatio = layoutSize.Height() / rawSize.Height();
73123b3eb3cSopenharmony_ci        float ratio = static_cast<float>(std::min(widthRatio, heightRatio));
73223b3eb3cSopenharmony_ci        return { rawSize.Width() * ratio, rawSize.Height() * ratio };
73323b3eb3cSopenharmony_ci    } else if ((rawSize.Width() > layoutSize.Width()) && (rawSize.Height() <= layoutSize.Height())) {
73423b3eb3cSopenharmony_ci        return CalculateFitContain(rawSize, layoutSize);
73523b3eb3cSopenharmony_ci    } else {
73623b3eb3cSopenharmony_ci        return CalculateFitCover(rawSize, layoutSize);
73723b3eb3cSopenharmony_ci    }
73823b3eb3cSopenharmony_ci}
73923b3eb3cSopenharmony_ci
74023b3eb3cSopenharmony_ciSizeF MovingPhotoPattern::GetRawImageSize()
74123b3eb3cSopenharmony_ci{
74223b3eb3cSopenharmony_ci    auto host = GetHost();
74323b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(host, SizeF(-1, -1));
74423b3eb3cSopenharmony_ci    auto movingPhoto = AceType::DynamicCast<MovingPhotoNode>(host);
74523b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(movingPhoto, SizeF(-1, -1));
74623b3eb3cSopenharmony_ci    auto image = AceType::DynamicCast<FrameNode>(movingPhoto->GetImage());
74723b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(image, SizeF(-1, -1));
74823b3eb3cSopenharmony_ci    auto imagePattern = image->GetPattern<ImagePattern>();
74923b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(image, SizeF(-1, -1));
75023b3eb3cSopenharmony_ci    return imagePattern->GetRawImageSize();
75123b3eb3cSopenharmony_ci}
75223b3eb3cSopenharmony_ci
75323b3eb3cSopenharmony_ciSizeF MovingPhotoPattern::MeasureContentLayout(const SizeF& layoutSize,
75423b3eb3cSopenharmony_ci    const RefPtr<MovingPhotoLayoutProperty>& layoutProperty)
75523b3eb3cSopenharmony_ci{
75623b3eb3cSopenharmony_ci    if (!layoutProperty || !layoutProperty->HasVideoSize()) {
75723b3eb3cSopenharmony_ci        return layoutSize;
75823b3eb3cSopenharmony_ci    }
75923b3eb3cSopenharmony_ci
76023b3eb3cSopenharmony_ci    auto rawImageSize = GetRawImageSize();
76123b3eb3cSopenharmony_ci    auto imageFit = layoutProperty->GetObjectFitValue(ImageFit::COVER);
76223b3eb3cSopenharmony_ci    SizeF contentSize = { 0.0, 0.0 };
76323b3eb3cSopenharmony_ci    switch (imageFit) {
76423b3eb3cSopenharmony_ci        case ImageFit::CONTAIN:
76523b3eb3cSopenharmony_ci            contentSize = CalculateFitContain(rawImageSize, layoutSize);
76623b3eb3cSopenharmony_ci            break;
76723b3eb3cSopenharmony_ci        case ImageFit::FILL:
76823b3eb3cSopenharmony_ci            contentSize = CalculateFitFill(layoutSize);
76923b3eb3cSopenharmony_ci            break;
77023b3eb3cSopenharmony_ci        case ImageFit::COVER:
77123b3eb3cSopenharmony_ci            contentSize = CalculateFitCover(rawImageSize, layoutSize);
77223b3eb3cSopenharmony_ci            break;
77323b3eb3cSopenharmony_ci        case ImageFit::NONE:
77423b3eb3cSopenharmony_ci            contentSize = CalculateFitNone(rawImageSize);
77523b3eb3cSopenharmony_ci            break;
77623b3eb3cSopenharmony_ci        case ImageFit::SCALE_DOWN:
77723b3eb3cSopenharmony_ci            contentSize = CalculateFitScaleDown(rawImageSize, layoutSize);
77823b3eb3cSopenharmony_ci            break;
77923b3eb3cSopenharmony_ci        default:
78023b3eb3cSopenharmony_ci            contentSize = CalculateFitAuto(rawImageSize, layoutSize);
78123b3eb3cSopenharmony_ci    }
78223b3eb3cSopenharmony_ci
78323b3eb3cSopenharmony_ci    return contentSize;
78423b3eb3cSopenharmony_ci}
78523b3eb3cSopenharmony_ci
78623b3eb3cSopenharmony_civoid MovingPhotoPattern::OnMediaPlayerStatusChanged(PlaybackStatus status)
78723b3eb3cSopenharmony_ci{
78823b3eb3cSopenharmony_ci    currentPlayStatus_ = status;
78923b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "Player current status is %{public}d.", status);
79023b3eb3cSopenharmony_ci    switch (status) {
79123b3eb3cSopenharmony_ci        case PlaybackStatus::ERROR:
79223b3eb3cSopenharmony_ci            TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "Player current status is ERROR.");
79323b3eb3cSopenharmony_ci            FireMediaPlayerError();
79423b3eb3cSopenharmony_ci            break;
79523b3eb3cSopenharmony_ci        case PlaybackStatus::IDLE:
79623b3eb3cSopenharmony_ci            TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "Player current status is IDLE.");
79723b3eb3cSopenharmony_ci            break;
79823b3eb3cSopenharmony_ci        case PlaybackStatus::INITIALIZED:
79923b3eb3cSopenharmony_ci            TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "Player current status is INITIALIZED.");
80023b3eb3cSopenharmony_ci            OnMediaPlayerInitialized();
80123b3eb3cSopenharmony_ci            break;
80223b3eb3cSopenharmony_ci        case PlaybackStatus::PREPARED:
80323b3eb3cSopenharmony_ci            TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "Player current status is PREPARED.");
80423b3eb3cSopenharmony_ci            OnMediaPlayerPrepared();
80523b3eb3cSopenharmony_ci            break;
80623b3eb3cSopenharmony_ci        case PlaybackStatus::STARTED:
80723b3eb3cSopenharmony_ci            TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "Player current status is STARTED.");
80823b3eb3cSopenharmony_ci            OnStartedStatusCallback();
80923b3eb3cSopenharmony_ci            FireMediaPlayerStart();
81023b3eb3cSopenharmony_ci            break;
81123b3eb3cSopenharmony_ci        case PlaybackStatus::PAUSED:
81223b3eb3cSopenharmony_ci            TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "Player current status is PAUSED.");
81323b3eb3cSopenharmony_ci            FireMediaPlayerPause();
81423b3eb3cSopenharmony_ci            break;
81523b3eb3cSopenharmony_ci        case PlaybackStatus::STOPPED:
81623b3eb3cSopenharmony_ci            TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "Player current status is STOPPED.");
81723b3eb3cSopenharmony_ci            OnMediaPlayerStoped();
81823b3eb3cSopenharmony_ci            break;
81923b3eb3cSopenharmony_ci        case PlaybackStatus::PLAYBACK_COMPLETE:
82023b3eb3cSopenharmony_ci            TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "Player current status is PLAYBACK_COMPLETE.");
82123b3eb3cSopenharmony_ci            OnMediaPlayerCompletion();
82223b3eb3cSopenharmony_ci            break;
82323b3eb3cSopenharmony_ci        case PlaybackStatus::NONE:
82423b3eb3cSopenharmony_ci            TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "Player current status is NONE.");
82523b3eb3cSopenharmony_ci            break;
82623b3eb3cSopenharmony_ci        default:
82723b3eb3cSopenharmony_ci            TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "Invalid player status.");
82823b3eb3cSopenharmony_ci            break;
82923b3eb3cSopenharmony_ci    }
83023b3eb3cSopenharmony_ci}
83123b3eb3cSopenharmony_ci
83223b3eb3cSopenharmony_civoid MovingPhotoPattern::OnMediaPlayerInitialized()
83323b3eb3cSopenharmony_ci{
83423b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer OnMediaPlayerInitialized.");
83523b3eb3cSopenharmony_ci    if (!isSetAutoPlayPeriod_ && autoAndRepeatLevel_ == PlaybackMode::AUTO) {
83623b3eb3cSopenharmony_ci        isSetAutoPlayPeriod_ = true;
83723b3eb3cSopenharmony_ci        SetAutoPlayPeriod(autoPlayPeriodStartTime_, autoPlayPeriodEndTime_);
83823b3eb3cSopenharmony_ci    }
83923b3eb3cSopenharmony_ci    PrepareSurface();
84023b3eb3cSopenharmony_ci    if (mediaPlayer_->PrepareAsync() != PREPARE_RETURN) {
84123b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "prepare MediaPlayer failed.");
84223b3eb3cSopenharmony_ci    }
84323b3eb3cSopenharmony_ci}
84423b3eb3cSopenharmony_ci
84523b3eb3cSopenharmony_civoid MovingPhotoPattern::OnMediaPlayerPrepared()
84623b3eb3cSopenharmony_ci{
84723b3eb3cSopenharmony_ci    ContainerScope scope(instanceId_);
84823b3eb3cSopenharmony_ci    auto context = PipelineContext::GetCurrentContext();
84923b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
85023b3eb3cSopenharmony_ci    if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
85123b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null or invalid.");
85223b3eb3cSopenharmony_ci        return;
85323b3eb3cSopenharmony_ci    }
85423b3eb3cSopenharmony_ci    isPrepared_ = true;
85523b3eb3cSopenharmony_ci    Size videoSize = Size(mediaPlayer_->GetVideoWidth(), mediaPlayer_->GetVideoHeight());
85623b3eb3cSopenharmony_ci    auto host = GetHost();
85723b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
85823b3eb3cSopenharmony_ci    auto videoLayoutProperty = host->GetLayoutProperty<MovingPhotoLayoutProperty>();
85923b3eb3cSopenharmony_ci    CHECK_NULL_VOID(videoLayoutProperty);
86023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(mediaPlayer_);
86123b3eb3cSopenharmony_ci    videoLayoutProperty->UpdateVideoSize(
86223b3eb3cSopenharmony_ci        SizeF(static_cast<float>(videoSize.Width()), static_cast<float>(videoSize.Height())));
86323b3eb3cSopenharmony_ci    host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
86423b3eb3cSopenharmony_ci    UpdateMediaPlayerSpeed();
86523b3eb3cSopenharmony_ci    UpdateMediaPlayerMuted();
86623b3eb3cSopenharmony_ci    VisiblePlayback();
86723b3eb3cSopenharmony_ci}
86823b3eb3cSopenharmony_ci
86923b3eb3cSopenharmony_civoid MovingPhotoPattern::OnMediaPlayerStoped()
87023b3eb3cSopenharmony_ci{
87123b3eb3cSopenharmony_ci    isPlayByController_ = false;
87223b3eb3cSopenharmony_ci    FireMediaPlayerStop();
87323b3eb3cSopenharmony_ci}
87423b3eb3cSopenharmony_ci
87523b3eb3cSopenharmony_civoid MovingPhotoPattern::OnMediaPlayerCompletion()
87623b3eb3cSopenharmony_ci{
87723b3eb3cSopenharmony_ci    if (isPlayByController_ || autoAndRepeatLevel_ != PlaybackMode::NONE) {
87823b3eb3cSopenharmony_ci        isPlayByController_ = false;
87923b3eb3cSopenharmony_ci        StopAnimation();
88023b3eb3cSopenharmony_ci    }
88123b3eb3cSopenharmony_ci    FireMediaPlayerFinish();
88223b3eb3cSopenharmony_ci}
88323b3eb3cSopenharmony_ci
88423b3eb3cSopenharmony_civoid MovingPhotoPattern::HideImageNode()
88523b3eb3cSopenharmony_ci{
88623b3eb3cSopenharmony_ci    auto host = GetHost();
88723b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
88823b3eb3cSopenharmony_ci    auto movingPhoto = AceType::DynamicCast<MovingPhotoNode>(host);
88923b3eb3cSopenharmony_ci    CHECK_NULL_VOID(movingPhoto);
89023b3eb3cSopenharmony_ci    auto image = AceType::DynamicCast<FrameNode>(movingPhoto->GetImage());
89123b3eb3cSopenharmony_ci    CHECK_NULL_VOID(image);
89223b3eb3cSopenharmony_ci    auto imageLayoutProperty = image->GetLayoutProperty<ImageLayoutProperty>();
89323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageLayoutProperty);
89423b3eb3cSopenharmony_ci    imageLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
89523b3eb3cSopenharmony_ci    image->MarkModifyDone();
89623b3eb3cSopenharmony_ci}
89723b3eb3cSopenharmony_ci
89823b3eb3cSopenharmony_civoid MovingPhotoPattern::VisiblePlayback()
89923b3eb3cSopenharmony_ci{
90023b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto VisiblePlayback.");
90123b3eb3cSopenharmony_ci    if (!isVisible_) {
90223b3eb3cSopenharmony_ci        return;
90323b3eb3cSopenharmony_ci    }
90423b3eb3cSopenharmony_ci    if (historyAutoAndRepeatLevel_ != PlaybackMode::NONE &&
90523b3eb3cSopenharmony_ci        autoAndRepeatLevel_ == PlaybackMode::NONE) {
90623b3eb3cSopenharmony_ci        SelectPlaybackMode(historyAutoAndRepeatLevel_);
90723b3eb3cSopenharmony_ci    } else {
90823b3eb3cSopenharmony_ci        SelectPlaybackMode(autoAndRepeatLevel_);
90923b3eb3cSopenharmony_ci    }
91023b3eb3cSopenharmony_ci}
91123b3eb3cSopenharmony_ci
91223b3eb3cSopenharmony_civoid MovingPhotoPattern::SelectPlaybackMode(PlaybackMode mode)
91323b3eb3cSopenharmony_ci{
91423b3eb3cSopenharmony_ci    if (mode == PlaybackMode::REPEAT) {
91523b3eb3cSopenharmony_ci        StartRepeatPlay();
91623b3eb3cSopenharmony_ci    } else if (mode == PlaybackMode::AUTO) {
91723b3eb3cSopenharmony_ci        StartAutoPlay();
91823b3eb3cSopenharmony_ci    }
91923b3eb3cSopenharmony_ci}
92023b3eb3cSopenharmony_ci
92123b3eb3cSopenharmony_civoid MovingPhotoPattern::StartPlayback()
92223b3eb3cSopenharmony_ci{
92323b3eb3cSopenharmony_ci    if (currentPlayStatus_ == PlaybackStatus::STARTED || !isPrepared_) {
92423b3eb3cSopenharmony_ci        return;
92523b3eb3cSopenharmony_ci    }
92623b3eb3cSopenharmony_ci    if (autoAndRepeatLevel_ != PlaybackMode::NONE) {
92723b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "StartPlayback autoAndRepeatLevel_:%{public}d.",
92823b3eb3cSopenharmony_ci            autoAndRepeatLevel_);
92923b3eb3cSopenharmony_ci        return;
93023b3eb3cSopenharmony_ci    }
93123b3eb3cSopenharmony_ci    if (currentPlayStatus_ == PlaybackStatus::STOPPED) {
93223b3eb3cSopenharmony_ci        mediaPlayer_->PrepareAsync();
93323b3eb3cSopenharmony_ci    }
93423b3eb3cSopenharmony_ci    isPlayByController_ = true;
93523b3eb3cSopenharmony_ci    isFastKeyUp_ = false;
93623b3eb3cSopenharmony_ci    if (isSetAutoPlayPeriod_ && (currentPlayStatus_ == PlaybackStatus::PLAYBACK_COMPLETE ||
93723b3eb3cSopenharmony_ci        currentPlayStatus_ == PlaybackStatus::PAUSED)) {
93823b3eb3cSopenharmony_ci        int32_t duration = DURATION_FLAG;
93923b3eb3cSopenharmony_ci        mediaPlayer_->GetDuration(duration);
94023b3eb3cSopenharmony_ci        TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "StartPlayback duration:%{public}d.",
94123b3eb3cSopenharmony_ci            duration);
94223b3eb3cSopenharmony_ci        SetAutoPlayPeriod(PERIOD_START, duration);
94323b3eb3cSopenharmony_ci    }
94423b3eb3cSopenharmony_ci    Start();
94523b3eb3cSopenharmony_ci}
94623b3eb3cSopenharmony_ci
94723b3eb3cSopenharmony_civoid MovingPhotoPattern::StartAnimation()
94823b3eb3cSopenharmony_ci{
94923b3eb3cSopenharmony_ci    if (historyAutoAndRepeatLevel_ == PlaybackMode::REPEAT) {
95023b3eb3cSopenharmony_ci        if (!isFirstRepeatPlay_) {
95123b3eb3cSopenharmony_ci            return;
95223b3eb3cSopenharmony_ci        }
95323b3eb3cSopenharmony_ci        isFirstRepeatPlay_ = false;
95423b3eb3cSopenharmony_ci    }
95523b3eb3cSopenharmony_ci    auto host = GetHost();
95623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
95723b3eb3cSopenharmony_ci    auto movingPhoto = AceType::DynamicCast<MovingPhotoNode>(host);
95823b3eb3cSopenharmony_ci    CHECK_NULL_VOID(movingPhoto);
95923b3eb3cSopenharmony_ci    auto image = AceType::DynamicCast<FrameNode>(movingPhoto->GetImage());
96023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(image);
96123b3eb3cSopenharmony_ci    auto imageRsContext = image->GetRenderContext();
96223b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageRsContext);
96323b3eb3cSopenharmony_ci    auto video = AceType::DynamicCast<FrameNode>(movingPhoto->GetVideo());
96423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(video);
96523b3eb3cSopenharmony_ci    auto videoRsContext = video->GetRenderContext();
96623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(videoRsContext);
96723b3eb3cSopenharmony_ci
96823b3eb3cSopenharmony_ci    imageRsContext->UpdateOpacity(1.0);
96923b3eb3cSopenharmony_ci    imageRsContext->UpdateTransformScale({NORMAL_SCALE, NORMAL_SCALE});
97023b3eb3cSopenharmony_ci    videoRsContext->UpdateTransformScale({NORMAL_SCALE, NORMAL_SCALE});
97123b3eb3cSopenharmony_ci    auto movingPhotoPattern = WeakClaim(this);
97223b3eb3cSopenharmony_ci    AnimationOption animationOption;
97323b3eb3cSopenharmony_ci    animationOption.SetDuration(ANIMATION_DURATION_400);
97423b3eb3cSopenharmony_ci    animationOption.SetCurve(Curves::FRICTION);
97523b3eb3cSopenharmony_ci    animationOption.SetOnFinishEvent([movingPhotoPattern]() {
97623b3eb3cSopenharmony_ci        auto movingPhoto = movingPhotoPattern.Upgrade();
97723b3eb3cSopenharmony_ci        TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto StartAnimation OnFinishEvent.");
97823b3eb3cSopenharmony_ci        CHECK_NULL_VOID(movingPhoto);
97923b3eb3cSopenharmony_ci        if (movingPhoto->currentPlayStatus_ == PlaybackStatus::PAUSED
98023b3eb3cSopenharmony_ci            || movingPhoto->currentPlayStatus_ == PlaybackStatus::STOPPED
98123b3eb3cSopenharmony_ci            || !movingPhoto->startAnimationFlag_) {
98223b3eb3cSopenharmony_ci            return;
98323b3eb3cSopenharmony_ci        }
98423b3eb3cSopenharmony_ci        movingPhoto->HideImageNode();
98523b3eb3cSopenharmony_ci    });
98623b3eb3cSopenharmony_ci    startAnimationFlag_ = true;
98723b3eb3cSopenharmony_ci    AnimationUtils::Animate(animationOption,
98823b3eb3cSopenharmony_ci        [imageRsContext, videoRsContext, repeatFlag = historyAutoAndRepeatLevel_]() {
98923b3eb3cSopenharmony_ci            imageRsContext->UpdateOpacity(0.0);
99023b3eb3cSopenharmony_ci            imageRsContext->UpdateTransformScale({ZOOM_IN_SCALE, ZOOM_IN_SCALE});
99123b3eb3cSopenharmony_ci            if (repeatFlag == PlaybackMode::REPEAT) {
99223b3eb3cSopenharmony_ci                videoRsContext->UpdateTransformScale({NORMAL_SCALE, NORMAL_SCALE});
99323b3eb3cSopenharmony_ci            } else {
99423b3eb3cSopenharmony_ci                videoRsContext->UpdateTransformScale({ZOOM_IN_SCALE, ZOOM_IN_SCALE});
99523b3eb3cSopenharmony_ci            }
99623b3eb3cSopenharmony_ci        }, animationOption.GetOnFinishEvent());
99723b3eb3cSopenharmony_ci}
99823b3eb3cSopenharmony_ci
99923b3eb3cSopenharmony_civoid MovingPhotoPattern::StopPlayback()
100023b3eb3cSopenharmony_ci{
100123b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto StopPlayback");
100223b3eb3cSopenharmony_ci    isFastKeyUp_ = false;
100323b3eb3cSopenharmony_ci    isPlayByController_ = false;
100423b3eb3cSopenharmony_ci    Pause();
100523b3eb3cSopenharmony_ci    autoAndRepeatLevel_ = PlaybackMode::NONE;
100623b3eb3cSopenharmony_ci    if (historyAutoAndRepeatLevel_ != PlaybackMode::REPEAT) {
100723b3eb3cSopenharmony_ci        StopAnimation();
100823b3eb3cSopenharmony_ci    }
100923b3eb3cSopenharmony_ci}
101023b3eb3cSopenharmony_ci
101123b3eb3cSopenharmony_civoid MovingPhotoPattern::PausePlayback()
101223b3eb3cSopenharmony_ci{
101323b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto PausePlayback");
101423b3eb3cSopenharmony_ci    isFastKeyUp_ = false;
101523b3eb3cSopenharmony_ci    if (currentPlayStatus_ != PlaybackStatus::STARTED || !isPrepared_) {
101623b3eb3cSopenharmony_ci        return;
101723b3eb3cSopenharmony_ci    }
101823b3eb3cSopenharmony_ci    if (autoAndRepeatLevel_ != PlaybackMode::NONE) {
101923b3eb3cSopenharmony_ci        TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "PausePlayback autoAndRepeatLevel_:%{public}d.",
102023b3eb3cSopenharmony_ci            autoAndRepeatLevel_);
102123b3eb3cSopenharmony_ci        return;
102223b3eb3cSopenharmony_ci    }
102323b3eb3cSopenharmony_ci    isPlayByController_ = false;
102423b3eb3cSopenharmony_ci    Pause();
102523b3eb3cSopenharmony_ci    StopAnimation();
102623b3eb3cSopenharmony_ci}
102723b3eb3cSopenharmony_ci
102823b3eb3cSopenharmony_civoid MovingPhotoPattern::StopAnimation()
102923b3eb3cSopenharmony_ci{
103023b3eb3cSopenharmony_ci    startAnimationFlag_ = false;
103123b3eb3cSopenharmony_ci    if (historyAutoAndRepeatLevel_ == PlaybackMode::REPEAT) {
103223b3eb3cSopenharmony_ci        StopAnimationCallback();
103323b3eb3cSopenharmony_ci        return;
103423b3eb3cSopenharmony_ci    }
103523b3eb3cSopenharmony_ci    auto host = GetHost();
103623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
103723b3eb3cSopenharmony_ci    auto movingPhoto = AceType::DynamicCast<MovingPhotoNode>(host);
103823b3eb3cSopenharmony_ci    CHECK_NULL_VOID(movingPhoto);
103923b3eb3cSopenharmony_ci    auto image = AceType::DynamicCast<FrameNode>(movingPhoto->GetImage());
104023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(image);
104123b3eb3cSopenharmony_ci    auto imageLayoutProperty = image->GetLayoutProperty<ImageLayoutProperty>();
104223b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageLayoutProperty);
104323b3eb3cSopenharmony_ci    auto imageRsContext = image->GetRenderContext();
104423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageRsContext);
104523b3eb3cSopenharmony_ci    auto video = AceType::DynamicCast<FrameNode>(movingPhoto->GetVideo());
104623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(video);
104723b3eb3cSopenharmony_ci    auto videoRsContext = video->GetRenderContext();
104823b3eb3cSopenharmony_ci    CHECK_NULL_VOID(videoRsContext);
104923b3eb3cSopenharmony_ci    videoRsContext->UpdateTransformScale({ZOOM_IN_SCALE, ZOOM_IN_SCALE});
105023b3eb3cSopenharmony_ci    video->MarkModifyDone();
105123b3eb3cSopenharmony_ci
105223b3eb3cSopenharmony_ci    imageLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
105323b3eb3cSopenharmony_ci    imageRsContext->UpdateOpacity(0.0);
105423b3eb3cSopenharmony_ci    imageRsContext->UpdateTransformScale({ZOOM_IN_SCALE, ZOOM_IN_SCALE});
105523b3eb3cSopenharmony_ci    image->MarkModifyDone();
105623b3eb3cSopenharmony_ci    auto movingPhotoPattern = WeakClaim(this);
105723b3eb3cSopenharmony_ci    AnimationOption option;
105823b3eb3cSopenharmony_ci    option.SetDuration(ANIMATION_DURATION_300);
105923b3eb3cSopenharmony_ci    option.SetCurve(Curves::FRICTION);
106023b3eb3cSopenharmony_ci    option.SetOnFinishEvent([movingPhotoPattern]() {
106123b3eb3cSopenharmony_ci        auto movingPhoto = movingPhotoPattern.Upgrade();
106223b3eb3cSopenharmony_ci        CHECK_NULL_VOID(movingPhoto);
106323b3eb3cSopenharmony_ci        movingPhoto->StopAnimationCallback();
106423b3eb3cSopenharmony_ci    });
106523b3eb3cSopenharmony_ci    AnimationUtils::Animate(option, [imageRsContext, videoRsContext]() {
106623b3eb3cSopenharmony_ci            imageRsContext->UpdateOpacity(1.0);
106723b3eb3cSopenharmony_ci            imageRsContext->UpdateTransformScale({NORMAL_SCALE, NORMAL_SCALE});
106823b3eb3cSopenharmony_ci            videoRsContext->UpdateTransformScale({NORMAL_SCALE, NORMAL_SCALE});
106923b3eb3cSopenharmony_ci        }, option.GetOnFinishEvent());
107023b3eb3cSopenharmony_ci}
107123b3eb3cSopenharmony_ci
107223b3eb3cSopenharmony_civoid MovingPhotoPattern::StopAnimationCallback()
107323b3eb3cSopenharmony_ci{
107423b3eb3cSopenharmony_ci    Seek(0);
107523b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "StopAnimation OnFinishEvent:%{public}d.", autoAndRepeatLevel_);
107623b3eb3cSopenharmony_ci    if (needUpdateImageNode_) {
107723b3eb3cSopenharmony_ci        UpdateImageNode();
107823b3eb3cSopenharmony_ci        needUpdateImageNode_ = false;
107923b3eb3cSopenharmony_ci    }
108023b3eb3cSopenharmony_ci    if (autoAndRepeatLevel_ == PlaybackMode::REPEAT) {
108123b3eb3cSopenharmony_ci        StartRepeatPlay();
108223b3eb3cSopenharmony_ci    } else if (autoAndRepeatLevel_ == PlaybackMode::AUTO) {
108323b3eb3cSopenharmony_ci        autoAndRepeatLevel_ = PlaybackMode::NONE;
108423b3eb3cSopenharmony_ci    }
108523b3eb3cSopenharmony_ci    if (historyAutoAndRepeatLevel_ == PlaybackMode::AUTO) {
108623b3eb3cSopenharmony_ci        HandleImageAnalyzerMode();
108723b3eb3cSopenharmony_ci    }
108823b3eb3cSopenharmony_ci}
108923b3eb3cSopenharmony_ci
109023b3eb3cSopenharmony_civoid MovingPhotoPattern::AutoPlay(bool isAutoPlay)
109123b3eb3cSopenharmony_ci{
109223b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto AutoPlay: %{public}d.", isAutoPlay);
109323b3eb3cSopenharmony_ci    if (isAutoPlay) {
109423b3eb3cSopenharmony_ci        if (historyAutoAndRepeatLevel_ == PlaybackMode::AUTO) {
109523b3eb3cSopenharmony_ci            return;
109623b3eb3cSopenharmony_ci        }
109723b3eb3cSopenharmony_ci        isChangePlayMode_ = true;
109823b3eb3cSopenharmony_ci        if (autoAndRepeatLevel_ != PlaybackMode::REPEAT) {
109923b3eb3cSopenharmony_ci            historyAutoAndRepeatLevel_ = PlaybackMode::AUTO;
110023b3eb3cSopenharmony_ci            autoAndRepeatLevel_ = PlaybackMode::AUTO;
110123b3eb3cSopenharmony_ci            if (!isSetAutoPlayPeriod_ && (currentPlayStatus_ == PlaybackStatus::PLAYBACK_COMPLETE ||
110223b3eb3cSopenharmony_ci                currentPlayStatus_ == PlaybackStatus::PAUSED)) {
110323b3eb3cSopenharmony_ci                isSetAutoPlayPeriod_ = true;
110423b3eb3cSopenharmony_ci                SetAutoPlayPeriod(autoPlayPeriodStartTime_, autoPlayPeriodEndTime_);
110523b3eb3cSopenharmony_ci            }
110623b3eb3cSopenharmony_ci        }
110723b3eb3cSopenharmony_ci    }
110823b3eb3cSopenharmony_ci}
110923b3eb3cSopenharmony_ci
111023b3eb3cSopenharmony_civoid MovingPhotoPattern::StartAutoPlay()
111123b3eb3cSopenharmony_ci{
111223b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto StartAutoPlay in.");
111323b3eb3cSopenharmony_ci    isFastKeyUp_ = false;
111423b3eb3cSopenharmony_ci    if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
111523b3eb3cSopenharmony_ci        return;
111623b3eb3cSopenharmony_ci    }
111723b3eb3cSopenharmony_ci
111823b3eb3cSopenharmony_ci    if (currentPlayStatus_ == PlaybackStatus::STOPPED) {
111923b3eb3cSopenharmony_ci        mediaPlayer_->PrepareAsync();
112023b3eb3cSopenharmony_ci    }
112123b3eb3cSopenharmony_ci    Start();
112223b3eb3cSopenharmony_ci}
112323b3eb3cSopenharmony_ci
112423b3eb3cSopenharmony_civoid MovingPhotoPattern::StartRepeatPlay()
112523b3eb3cSopenharmony_ci{
112623b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto StartRepeatPlay in.");
112723b3eb3cSopenharmony_ci    isFastKeyUp_ = false;
112823b3eb3cSopenharmony_ci    if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
112923b3eb3cSopenharmony_ci        return;
113023b3eb3cSopenharmony_ci    }
113123b3eb3cSopenharmony_ci
113223b3eb3cSopenharmony_ci    if (currentPlayStatus_ == PlaybackStatus::STOPPED) {
113323b3eb3cSopenharmony_ci        mediaPlayer_->PrepareAsync();
113423b3eb3cSopenharmony_ci    }
113523b3eb3cSopenharmony_ci    if (!isFirstRepeatPlay_ && isSetAutoPlayPeriod_) {
113623b3eb3cSopenharmony_ci        int32_t duration = DURATION_FLAG;
113723b3eb3cSopenharmony_ci        mediaPlayer_->GetDuration(duration);
113823b3eb3cSopenharmony_ci        SetAutoPlayPeriod(PERIOD_START, duration);
113923b3eb3cSopenharmony_ci    }
114023b3eb3cSopenharmony_ci    Start();
114123b3eb3cSopenharmony_ci}
114223b3eb3cSopenharmony_ci
114323b3eb3cSopenharmony_civoid MovingPhotoPattern::RepeatPlay(bool isRepeatPlay)
114423b3eb3cSopenharmony_ci{
114523b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto RepeatPlay status: %{public}d.", isRepeatPlay);
114623b3eb3cSopenharmony_ci    if (isRepeatPlay && historyAutoAndRepeatLevel_ != PlaybackMode::REPEAT) {
114723b3eb3cSopenharmony_ci        isChangePlayMode_ = true;
114823b3eb3cSopenharmony_ci        isFirstRepeatPlay_ = true;
114923b3eb3cSopenharmony_ci    }
115023b3eb3cSopenharmony_ci    if (!isRepeatPlay && historyAutoAndRepeatLevel_ == PlaybackMode::REPEAT) {
115123b3eb3cSopenharmony_ci        isChangePlayMode_ = true;
115223b3eb3cSopenharmony_ci        historyAutoAndRepeatLevel_ = PlaybackMode::NONE;
115323b3eb3cSopenharmony_ci        Pause();
115423b3eb3cSopenharmony_ci        StopAnimation();
115523b3eb3cSopenharmony_ci    }
115623b3eb3cSopenharmony_ci    if (isRepeatPlay) {
115723b3eb3cSopenharmony_ci        historyAutoAndRepeatLevel_ = PlaybackMode::REPEAT;
115823b3eb3cSopenharmony_ci        autoAndRepeatLevel_ = PlaybackMode::REPEAT;
115923b3eb3cSopenharmony_ci    }
116023b3eb3cSopenharmony_ci}
116123b3eb3cSopenharmony_ci
116223b3eb3cSopenharmony_civoid MovingPhotoPattern::AutoPlayPeriod(int64_t startTime, int64_t endTime)
116323b3eb3cSopenharmony_ci{
116423b3eb3cSopenharmony_ci    if (startTime >= VIDEO_PLAYTIME_START_POSITION && startTime < endTime
116523b3eb3cSopenharmony_ci            && endTime <= VIDEO_PLAYTIME_END_POSITION) {
116623b3eb3cSopenharmony_ci        TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer set Period.");
116723b3eb3cSopenharmony_ci        autoPlayPeriodStartTime_ = startTime;
116823b3eb3cSopenharmony_ci        autoPlayPeriodEndTime_ = endTime;
116923b3eb3cSopenharmony_ci    }
117023b3eb3cSopenharmony_ci}
117123b3eb3cSopenharmony_ci
117223b3eb3cSopenharmony_civoid MovingPhotoPattern::SetAutoPlayPeriod(int64_t startTime, int64_t endTime)
117323b3eb3cSopenharmony_ci{
117423b3eb3cSopenharmony_ci    if (startTime < VIDEO_PLAYTIME_START_POSITION || startTime >= endTime
117523b3eb3cSopenharmony_ci            || endTime > VIDEO_PLAYTIME_END_POSITION) {
117623b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer SetAutoPlayPeriod error.");
117723b3eb3cSopenharmony_ci        return;
117823b3eb3cSopenharmony_ci    }
117923b3eb3cSopenharmony_ci    if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
118023b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null or invalid.");
118123b3eb3cSopenharmony_ci        return;
118223b3eb3cSopenharmony_ci    }
118323b3eb3cSopenharmony_ci
118423b3eb3cSopenharmony_ci    ContainerScope scope(instanceId_);
118523b3eb3cSopenharmony_ci    auto context = PipelineContext::GetCurrentContext();
118623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
118723b3eb3cSopenharmony_ci
118823b3eb3cSopenharmony_ci    mediaPlayer_->SetPlayRange(startTime, endTime);
118923b3eb3cSopenharmony_ci}
119023b3eb3cSopenharmony_ci
119123b3eb3cSopenharmony_civoid MovingPhotoPattern::HandleImageAnalyzerPlayCallBack()
119223b3eb3cSopenharmony_ci{
119323b3eb3cSopenharmony_ci    TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "HandleImageAnalyzerPlayCallBack start.");
119423b3eb3cSopenharmony_ci    isFastKeyUp_ = false;
119523b3eb3cSopenharmony_ci    if (currentPlayStatus_ == PlaybackStatus::STARTED || !isPrepared_ || isPlayByController_) {
119623b3eb3cSopenharmony_ci        return;
119723b3eb3cSopenharmony_ci    }
119823b3eb3cSopenharmony_ci    if (autoAndRepeatLevel_ != PlaybackMode::NONE) {
119923b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "HandleImageAnalyzerPlayCallBack auto&Repeat return.");
120023b3eb3cSopenharmony_ci        return;
120123b3eb3cSopenharmony_ci    }
120223b3eb3cSopenharmony_ci    if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
120323b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null or invalid.");
120423b3eb3cSopenharmony_ci        FireMediaPlayerError();
120523b3eb3cSopenharmony_ci        return;
120623b3eb3cSopenharmony_ci    }
120723b3eb3cSopenharmony_ci    if (currentPlayStatus_ == PlaybackStatus::STOPPED) {
120823b3eb3cSopenharmony_ci        mediaPlayer_->PrepareAsync();
120923b3eb3cSopenharmony_ci    }
121023b3eb3cSopenharmony_ci    if (isSetAutoPlayPeriod_ && (currentPlayStatus_ == PlaybackStatus::PLAYBACK_COMPLETE ||
121123b3eb3cSopenharmony_ci        currentPlayStatus_ == PlaybackStatus::PAUSED)) {
121223b3eb3cSopenharmony_ci        int32_t duration = DURATION_FLAG;
121323b3eb3cSopenharmony_ci        mediaPlayer_->GetDuration(duration);
121423b3eb3cSopenharmony_ci        SetAutoPlayPeriod(PERIOD_START, duration);
121523b3eb3cSopenharmony_ci    }
121623b3eb3cSopenharmony_ci    Start();
121723b3eb3cSopenharmony_ci}
121823b3eb3cSopenharmony_ci
121923b3eb3cSopenharmony_civoid MovingPhotoPattern::Start()
122023b3eb3cSopenharmony_ci{
122123b3eb3cSopenharmony_ci    if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
122223b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null or invalid.");
122323b3eb3cSopenharmony_ci        return;
122423b3eb3cSopenharmony_ci    }
122523b3eb3cSopenharmony_ci    if (currentPlayStatus_ == PlaybackStatus::STOPPED) {
122623b3eb3cSopenharmony_ci        mediaPlayer_->PrepareAsync();
122723b3eb3cSopenharmony_ci    }
122823b3eb3cSopenharmony_ci    ContainerScope scope(instanceId_);
122923b3eb3cSopenharmony_ci    auto context = PipelineContext::GetCurrentContext();
123023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
123123b3eb3cSopenharmony_ci
123223b3eb3cSopenharmony_ci    auto platformTask = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::BACKGROUND);
123323b3eb3cSopenharmony_ci    platformTask.PostTask(
123423b3eb3cSopenharmony_ci        [weak = WeakClaim(RawPtr(mediaPlayer_))] {
123523b3eb3cSopenharmony_ci            auto mediaPlayer = weak.Upgrade();
123623b3eb3cSopenharmony_ci            CHECK_NULL_VOID(mediaPlayer);
123723b3eb3cSopenharmony_ci            mediaPlayer->Play();
123823b3eb3cSopenharmony_ci        },
123923b3eb3cSopenharmony_ci        "ArkUIMovingPhotoStartPlay");
124023b3eb3cSopenharmony_ci}
124123b3eb3cSopenharmony_ci
124223b3eb3cSopenharmony_civoid MovingPhotoPattern::Pause()
124323b3eb3cSopenharmony_ci{
124423b3eb3cSopenharmony_ci    if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
124523b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null or invalid.");
124623b3eb3cSopenharmony_ci        return;
124723b3eb3cSopenharmony_ci    }
124823b3eb3cSopenharmony_ci    ContainerScope scope(instanceId_);
124923b3eb3cSopenharmony_ci    auto context = PipelineContext::GetCurrentContext();
125023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
125123b3eb3cSopenharmony_ci
125223b3eb3cSopenharmony_ci    auto platformTask = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::BACKGROUND);
125323b3eb3cSopenharmony_ci    platformTask.PostTask(
125423b3eb3cSopenharmony_ci        [weak = WeakClaim(RawPtr(mediaPlayer_))] {
125523b3eb3cSopenharmony_ci            auto mediaPlayer = weak.Upgrade();
125623b3eb3cSopenharmony_ci            CHECK_NULL_VOID(mediaPlayer);
125723b3eb3cSopenharmony_ci            mediaPlayer->Pause();
125823b3eb3cSopenharmony_ci        },
125923b3eb3cSopenharmony_ci        "ArkUIMovingPhotoPausePlay");
126023b3eb3cSopenharmony_ci}
126123b3eb3cSopenharmony_ci
126223b3eb3cSopenharmony_civoid MovingPhotoPattern::Stop()
126323b3eb3cSopenharmony_ci{
126423b3eb3cSopenharmony_ci    if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
126523b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null or invalid.");
126623b3eb3cSopenharmony_ci        return;
126723b3eb3cSopenharmony_ci    }
126823b3eb3cSopenharmony_ci    ContainerScope scope(instanceId_);
126923b3eb3cSopenharmony_ci    auto context = PipelineContext::GetCurrentContext();
127023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
127123b3eb3cSopenharmony_ci
127223b3eb3cSopenharmony_ci    auto platformTask = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::BACKGROUND);
127323b3eb3cSopenharmony_ci    platformTask.PostTask(
127423b3eb3cSopenharmony_ci        [weak = WeakClaim(RawPtr(mediaPlayer_))] {
127523b3eb3cSopenharmony_ci            auto mediaPlayer = weak.Upgrade();
127623b3eb3cSopenharmony_ci            CHECK_NULL_VOID(mediaPlayer);
127723b3eb3cSopenharmony_ci            mediaPlayer->Stop();
127823b3eb3cSopenharmony_ci        },
127923b3eb3cSopenharmony_ci        "ArkUIMovingPhotoStopPlay");
128023b3eb3cSopenharmony_ci}
128123b3eb3cSopenharmony_ci
128223b3eb3cSopenharmony_civoid MovingPhotoPattern::Seek(int32_t position)
128323b3eb3cSopenharmony_ci{
128423b3eb3cSopenharmony_ci    if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
128523b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null or invalid.");
128623b3eb3cSopenharmony_ci        return;
128723b3eb3cSopenharmony_ci    }
128823b3eb3cSopenharmony_ci    ContainerScope scope(instanceId_);
128923b3eb3cSopenharmony_ci    auto context = PipelineContext::GetCurrentContext();
129023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
129123b3eb3cSopenharmony_ci
129223b3eb3cSopenharmony_ci    auto platformTask = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::BACKGROUND);
129323b3eb3cSopenharmony_ci    platformTask.PostTask(
129423b3eb3cSopenharmony_ci        [weak = WeakClaim(RawPtr(mediaPlayer_)), pos = position] {
129523b3eb3cSopenharmony_ci            auto mediaPlayer = weak.Upgrade();
129623b3eb3cSopenharmony_ci            CHECK_NULL_VOID(mediaPlayer);
129723b3eb3cSopenharmony_ci            mediaPlayer->Seek(pos, SeekMode::SEEK_PREVIOUS_SYNC);
129823b3eb3cSopenharmony_ci        },
129923b3eb3cSopenharmony_ci        "ArkUIMovingPhotoSeek");
130023b3eb3cSopenharmony_ci}
130123b3eb3cSopenharmony_ci
130223b3eb3cSopenharmony_civoid MovingPhotoPattern::UpdateMediaPlayerSpeed()
130323b3eb3cSopenharmony_ci{
130423b3eb3cSopenharmony_ci    if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
130523b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null or invalid.");
130623b3eb3cSopenharmony_ci        return;
130723b3eb3cSopenharmony_ci    }
130823b3eb3cSopenharmony_ci    ContainerScope scope(instanceId_);
130923b3eb3cSopenharmony_ci    auto context = PipelineContext::GetCurrentContext();
131023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
131123b3eb3cSopenharmony_ci    auto platformTask = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::BACKGROUND);
131223b3eb3cSopenharmony_ci    platformTask.PostTask(
131323b3eb3cSopenharmony_ci        [weak = WeakClaim(RawPtr(mediaPlayer_))] {
131423b3eb3cSopenharmony_ci            auto mediaPlayer = weak.Upgrade();
131523b3eb3cSopenharmony_ci            CHECK_NULL_VOID(mediaPlayer);
131623b3eb3cSopenharmony_ci            mediaPlayer->SetPlaybackSpeed(static_cast<float>(NORMAL_PLAY_SPEED));
131723b3eb3cSopenharmony_ci        },
131823b3eb3cSopenharmony_ci        "ArkUIMovingPhotoUpdateSpeed");
131923b3eb3cSopenharmony_ci}
132023b3eb3cSopenharmony_ci
132123b3eb3cSopenharmony_civoid MovingPhotoPattern::UpdateMediaPlayerMuted()
132223b3eb3cSopenharmony_ci{
132323b3eb3cSopenharmony_ci    if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
132423b3eb3cSopenharmony_ci        TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null or invalid.");
132523b3eb3cSopenharmony_ci        return;
132623b3eb3cSopenharmony_ci    }
132723b3eb3cSopenharmony_ci    ContainerScope scope(instanceId_);
132823b3eb3cSopenharmony_ci    float volume = isMuted_ ? 0.0f : 1.0f;
132923b3eb3cSopenharmony_ci    auto context = PipelineContext::GetCurrentContext();
133023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
133123b3eb3cSopenharmony_ci    auto platformTask = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::BACKGROUND);
133223b3eb3cSopenharmony_ci    platformTask.PostTask(
133323b3eb3cSopenharmony_ci        [weak = WeakClaim(RawPtr(mediaPlayer_)), videoVolume = volume] {
133423b3eb3cSopenharmony_ci            auto mediaPlayer = weak.Upgrade();
133523b3eb3cSopenharmony_ci            CHECK_NULL_VOID(mediaPlayer);
133623b3eb3cSopenharmony_ci            mediaPlayer->SetVolume(videoVolume, videoVolume);
133723b3eb3cSopenharmony_ci        },
133823b3eb3cSopenharmony_ci        "ArkUIMovingPhotoUpdateMuted");
133923b3eb3cSopenharmony_ci}
134023b3eb3cSopenharmony_ci
134123b3eb3cSopenharmony_civoid MovingPhotoPattern::OnAreaChangedInner()
134223b3eb3cSopenharmony_ci{
134323b3eb3cSopenharmony_ci    if (!SystemProperties::GetExtSurfaceEnabled()) {
134423b3eb3cSopenharmony_ci        return;
134523b3eb3cSopenharmony_ci    }
134623b3eb3cSopenharmony_ci    auto host = GetHost();
134723b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
134823b3eb3cSopenharmony_ci    auto geometryNode = host->GetGeometryNode();
134923b3eb3cSopenharmony_ci    CHECK_NULL_VOID(geometryNode);
135023b3eb3cSopenharmony_ci    auto videoNodeSize = geometryNode->GetContentSize();
135123b3eb3cSopenharmony_ci    auto layoutProperty = GetLayoutProperty<MovingPhotoLayoutProperty>();
135223b3eb3cSopenharmony_ci    CHECK_NULL_VOID(layoutProperty);
135323b3eb3cSopenharmony_ci    auto videoFrameSize = MeasureContentLayout(videoNodeSize, layoutProperty);
135423b3eb3cSopenharmony_ci    auto transformRelativeOffset = host->GetTransformRelativeOffset();
135523b3eb3cSopenharmony_ci
135623b3eb3cSopenharmony_ci    Rect rect = Rect(transformRelativeOffset.GetX() + (videoNodeSize.Width() - videoFrameSize.Width()) / HALF,
135723b3eb3cSopenharmony_ci        transformRelativeOffset.GetY() + (videoNodeSize.Height() - videoFrameSize.Height()) / HALF,
135823b3eb3cSopenharmony_ci        videoFrameSize.Width(), videoFrameSize.Height());
135923b3eb3cSopenharmony_ci    if (renderSurface_ && (rect != lastBoundsRect_)) {
136023b3eb3cSopenharmony_ci        renderSurface_->SetExtSurfaceBounds(rect.Left(), rect.Top(), rect.Width(), rect.Height());
136123b3eb3cSopenharmony_ci        lastBoundsRect_ = rect;
136223b3eb3cSopenharmony_ci    }
136323b3eb3cSopenharmony_ci}
136423b3eb3cSopenharmony_ci
136523b3eb3cSopenharmony_civoid MovingPhotoPattern::OnVisibleChange(bool isVisible)
136623b3eb3cSopenharmony_ci{
136723b3eb3cSopenharmony_ci    CHECK_NULL_VOID(mediaPlayer_);
136823b3eb3cSopenharmony_ci    if (!isVisible) {
136923b3eb3cSopenharmony_ci        StopPlayback();
137023b3eb3cSopenharmony_ci    }
137123b3eb3cSopenharmony_ci}
137223b3eb3cSopenharmony_ci
137323b3eb3cSopenharmony_civoid MovingPhotoPattern::OnWindowHide()
137423b3eb3cSopenharmony_ci{
137523b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto OnWindowHide.");
137623b3eb3cSopenharmony_ci    if (historyAutoAndRepeatLevel_ == PlaybackMode::AUTO) {
137723b3eb3cSopenharmony_ci        PausePlayback();
137823b3eb3cSopenharmony_ci    } else if (historyAutoAndRepeatLevel_ == PlaybackMode::REPEAT) {
137923b3eb3cSopenharmony_ci        StopPlayback();
138023b3eb3cSopenharmony_ci        return;
138123b3eb3cSopenharmony_ci    }
138223b3eb3cSopenharmony_ci    auto host = GetHost();
138323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
138423b3eb3cSopenharmony_ci    auto movingPhoto = AceType::DynamicCast<MovingPhotoNode>(host);
138523b3eb3cSopenharmony_ci    CHECK_NULL_VOID(movingPhoto);
138623b3eb3cSopenharmony_ci    auto image = AceType::DynamicCast<FrameNode>(movingPhoto->GetImage());
138723b3eb3cSopenharmony_ci    CHECK_NULL_VOID(image);
138823b3eb3cSopenharmony_ci    auto imageLayoutProperty = image->GetLayoutProperty<ImageLayoutProperty>();
138923b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageLayoutProperty);
139023b3eb3cSopenharmony_ci    imageLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
139123b3eb3cSopenharmony_ci    auto rsContext = image->GetRenderContext();
139223b3eb3cSopenharmony_ci    CHECK_NULL_VOID(rsContext);
139323b3eb3cSopenharmony_ci    rsContext->UpdateOpacity(1.0);
139423b3eb3cSopenharmony_ci    image->MarkModifyDone();
139523b3eb3cSopenharmony_ci}
139623b3eb3cSopenharmony_ci
139723b3eb3cSopenharmony_civoid MovingPhotoPattern::OnWindowShow()
139823b3eb3cSopenharmony_ci{
139923b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto OnWindowShow.");
140023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(mediaPlayer_);
140123b3eb3cSopenharmony_ci    if (autoAndRepeatLevel_ == PlaybackMode::REPEAT && currentPlayStatus_ == PlaybackStatus::STOPPED) {
140223b3eb3cSopenharmony_ci        mediaPlayer_->PrepareAsync();
140323b3eb3cSopenharmony_ci    }
140423b3eb3cSopenharmony_ci}
140523b3eb3cSopenharmony_ci
140623b3eb3cSopenharmony_civoid MovingPhotoPattern::RegisterVisibleAreaChange()
140723b3eb3cSopenharmony_ci{
140823b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto RegisterVisibleAreaChange.");
140923b3eb3cSopenharmony_ci    if (hasVisibleChangeRegistered_) {
141023b3eb3cSopenharmony_ci        return;
141123b3eb3cSopenharmony_ci    }
141223b3eb3cSopenharmony_ci    auto pipeline = PipelineContext::GetCurrentContextSafely();
141323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(pipeline);
141423b3eb3cSopenharmony_ci    auto callback = [weak = WeakClaim(this)](bool visible, double ratio) {
141523b3eb3cSopenharmony_ci        auto pattern = weak.Upgrade();
141623b3eb3cSopenharmony_ci        CHECK_NULL_VOID(pattern);
141723b3eb3cSopenharmony_ci        pattern->isVisible_ = visible;
141823b3eb3cSopenharmony_ci        pattern->VisibleAreaCallback(visible);
141923b3eb3cSopenharmony_ci    };
142023b3eb3cSopenharmony_ci    auto host = GetHost();
142123b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
142223b3eb3cSopenharmony_ci    std::vector<double> ratioList = {1.0};
142323b3eb3cSopenharmony_ci    pipeline->AddVisibleAreaChangeNode(host, ratioList, callback, false);
142423b3eb3cSopenharmony_ci    hasVisibleChangeRegistered_ = true;
142523b3eb3cSopenharmony_ci}
142623b3eb3cSopenharmony_ci
142723b3eb3cSopenharmony_civoid MovingPhotoPattern::VisibleAreaCallback(bool visible)
142823b3eb3cSopenharmony_ci{
142923b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto VisibleAreaCallback:%{public}d.", visible);
143023b3eb3cSopenharmony_ci    if (visible) {
143123b3eb3cSopenharmony_ci        if (historyAutoAndRepeatLevel_ == PlaybackMode::AUTO) {
143223b3eb3cSopenharmony_ci            SetAutoPlayPeriod(autoPlayPeriodStartTime_, autoPlayPeriodEndTime_);
143323b3eb3cSopenharmony_ci        }
143423b3eb3cSopenharmony_ci        MediaResetToPlay();
143523b3eb3cSopenharmony_ci    } else {
143623b3eb3cSopenharmony_ci        if (historyAutoAndRepeatLevel_ == PlaybackMode::AUTO) {
143723b3eb3cSopenharmony_ci            PausePlayback();
143823b3eb3cSopenharmony_ci        } else if (historyAutoAndRepeatLevel_ == PlaybackMode::REPEAT) {
143923b3eb3cSopenharmony_ci            StopPlayback();
144023b3eb3cSopenharmony_ci        }
144123b3eb3cSopenharmony_ci    }
144223b3eb3cSopenharmony_ci}
144323b3eb3cSopenharmony_ci
144423b3eb3cSopenharmony_civoid MovingPhotoPattern::EnableAnalyzer(bool enable)
144523b3eb3cSopenharmony_ci{
144623b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto EnableAnalyzer:%{public}d.", enable);
144723b3eb3cSopenharmony_ci    isEnableAnalyzer_ = enable;
144823b3eb3cSopenharmony_ci    if (!isEnableAnalyzer_) {
144923b3eb3cSopenharmony_ci        DestroyAnalyzerOverlay();
145023b3eb3cSopenharmony_ci        LongPressEventModify(true);
145123b3eb3cSopenharmony_ci        return;
145223b3eb3cSopenharmony_ci    }
145323b3eb3cSopenharmony_ci
145423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(!imageAnalyzerManager_);
145523b3eb3cSopenharmony_ci    auto host = GetHost();
145623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
145723b3eb3cSopenharmony_ci    imageAnalyzerManager_ = std::make_shared<ImageAnalyzerManager>(host, ImageAnalyzerHolder::MOVINGPHOTO);
145823b3eb3cSopenharmony_ci}
145923b3eb3cSopenharmony_ci
146023b3eb3cSopenharmony_civoid MovingPhotoPattern::SetImageAIOptions(void* options)
146123b3eb3cSopenharmony_ci{
146223b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto SetImageAIOptions");
146323b3eb3cSopenharmony_ci    if (!imageAnalyzerManager_) {
146423b3eb3cSopenharmony_ci        imageAnalyzerManager_ = std::make_shared<ImageAnalyzerManager>(GetHost(), ImageAnalyzerHolder::MOVINGPHOTO);
146523b3eb3cSopenharmony_ci    }
146623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageAnalyzerManager_);
146723b3eb3cSopenharmony_ci    imageAnalyzerManager_->SetImageAIOptions(options);
146823b3eb3cSopenharmony_ci}
146923b3eb3cSopenharmony_ci
147023b3eb3cSopenharmony_cibool MovingPhotoPattern::IsSupportImageAnalyzer()
147123b3eb3cSopenharmony_ci{
147223b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto IsSupportImageAnalyzer");
147323b3eb3cSopenharmony_ci    auto host = GetHost();
147423b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(host, false);
147523b3eb3cSopenharmony_ci    auto layoutProperty = host->GetLayoutProperty<MovingPhotoLayoutProperty>();
147623b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(layoutProperty, false);
147723b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(imageAnalyzerManager_, false);
147823b3eb3cSopenharmony_ci    return imageAnalyzerManager_->IsSupportImageAnalyzerFeature();
147923b3eb3cSopenharmony_ci}
148023b3eb3cSopenharmony_ci
148123b3eb3cSopenharmony_cibool MovingPhotoPattern::ShouldUpdateImageAnalyzer()
148223b3eb3cSopenharmony_ci{
148323b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto ShouldUpdateImageAnalyzer");
148423b3eb3cSopenharmony_ci    auto layoutProperty = GetLayoutProperty<MovingPhotoLayoutProperty>();
148523b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(layoutProperty, false);
148623b3eb3cSopenharmony_ci    const auto& constraint = layoutProperty->GetCalcLayoutConstraint();
148723b3eb3cSopenharmony_ci    if (!constraint || !constraint->selfIdealSize.has_value() || !constraint->selfIdealSize->IsValid()) {
148823b3eb3cSopenharmony_ci        return false;
148923b3eb3cSopenharmony_ci    }
149023b3eb3cSopenharmony_ci    auto selfIdealSize = constraint->selfIdealSize;
149123b3eb3cSopenharmony_ci    if (!selfIdealSize->PercentWidth() && !selfIdealSize->PercentHeight()) {
149223b3eb3cSopenharmony_ci        return false;
149323b3eb3cSopenharmony_ci    }
149423b3eb3cSopenharmony_ci    auto imageFit = layoutProperty->GetObjectFit().value_or(ImageFit::COVER);
149523b3eb3cSopenharmony_ci    if (imageFit != ImageFit::COVER && imageFit != ImageFit::NONE) {
149623b3eb3cSopenharmony_ci        return false;
149723b3eb3cSopenharmony_ci    }
149823b3eb3cSopenharmony_ci    return true;
149923b3eb3cSopenharmony_ci}
150023b3eb3cSopenharmony_ci
150123b3eb3cSopenharmony_civoid MovingPhotoPattern::StartImageAnalyzer()
150223b3eb3cSopenharmony_ci{
150323b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto StartImageAnalyzer");
150423b3eb3cSopenharmony_ci    if (!IsSupportImageAnalyzer() || !imageAnalyzerManager_) {
150523b3eb3cSopenharmony_ci        return;
150623b3eb3cSopenharmony_ci    }
150723b3eb3cSopenharmony_ci
150823b3eb3cSopenharmony_ci    if (imageAnalyzerManager_->IsOverlayCreated()) {
150923b3eb3cSopenharmony_ci        DestroyAnalyzerOverlay();
151023b3eb3cSopenharmony_ci        LongPressEventModify(true);
151123b3eb3cSopenharmony_ci    }
151223b3eb3cSopenharmony_ci
151323b3eb3cSopenharmony_ci    ContainerScope scope(instanceId_);
151423b3eb3cSopenharmony_ci    auto host = GetHost();
151523b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
151623b3eb3cSopenharmony_ci    auto context = host->GetContext();
151723b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
151823b3eb3cSopenharmony_ci    auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
151923b3eb3cSopenharmony_ci    uiTaskExecutor.PostDelayedTask([weak = WeakClaim(this)] {
152023b3eb3cSopenharmony_ci        auto pattern = weak.Upgrade();
152123b3eb3cSopenharmony_ci        CHECK_NULL_VOID(pattern);
152223b3eb3cSopenharmony_ci        pattern->CreateAnalyzerOverlay();
152323b3eb3cSopenharmony_ci        }, ANALYZER_DELAY_TIME, "ArkUIMovingPhotoCreateAnalyzerOverlay");
152423b3eb3cSopenharmony_ci    LongPressEventModify(false);
152523b3eb3cSopenharmony_ci}
152623b3eb3cSopenharmony_ci
152723b3eb3cSopenharmony_civoid MovingPhotoPattern::CreateAnalyzerOverlay()
152823b3eb3cSopenharmony_ci{
152923b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto CreateAnalyzerOverlay");
153023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageAnalyzerManager_);
153123b3eb3cSopenharmony_ci    if (!IsSupportImageAnalyzer() || !imageAnalyzerManager_->IsOverlayCreated()) {
153223b3eb3cSopenharmony_ci        return;
153323b3eb3cSopenharmony_ci    }
153423b3eb3cSopenharmony_ci    GetPixelMap();
153523b3eb3cSopenharmony_ci    int64_t coverPosition = GetUriCoverPosition();
153623b3eb3cSopenharmony_ci    auto onCanPlay = [weak = AceType::WeakClaim(this)](bool canPlay) {
153723b3eb3cSopenharmony_ci        auto pattern = weak.Upgrade();
153823b3eb3cSopenharmony_ci        CHECK_NULL_VOID(pattern);
153923b3eb3cSopenharmony_ci        pattern->HandleAnalyzerPlayEvent(canPlay);
154023b3eb3cSopenharmony_ci    };
154123b3eb3cSopenharmony_ci    auto host = GetHost();
154223b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
154323b3eb3cSopenharmony_ci    auto geometryNode = host->GetGeometryNode();
154423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(geometryNode);
154523b3eb3cSopenharmony_ci    auto movingPhotoNodeSize = geometryNode->GetContentSize();
154623b3eb3cSopenharmony_ci    MovingPhotoAnalyzerInfo info = {uri_, coverPosition,
154723b3eb3cSopenharmony_ci                                    movingPhotoNodeSize.Width(),
154823b3eb3cSopenharmony_ci                                    movingPhotoNodeSize.Height()};
154923b3eb3cSopenharmony_ci    imageAnalyzerManager_->SetOnCanPlayCallback(std::move(onCanPlay));
155023b3eb3cSopenharmony_ci    imageAnalyzerManager_->CreateMovingPhotoAnalyzerOverlay(pixelMap_, info);
155123b3eb3cSopenharmony_ci}
155223b3eb3cSopenharmony_ci
155323b3eb3cSopenharmony_civoid MovingPhotoPattern::StartUpdateImageAnalyzer()
155423b3eb3cSopenharmony_ci{
155523b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto StartUpdateImageAnalyzer");
155623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageAnalyzerManager_);
155723b3eb3cSopenharmony_ci    if (!imageAnalyzerManager_->IsOverlayCreated()) {
155823b3eb3cSopenharmony_ci        return;
155923b3eb3cSopenharmony_ci    }
156023b3eb3cSopenharmony_ci
156123b3eb3cSopenharmony_ci    UpdateOverlayVisibility(VisibleType::GONE);
156223b3eb3cSopenharmony_ci    ContainerScope scope(instanceId_);
156323b3eb3cSopenharmony_ci    auto host = GetHost();
156423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
156523b3eb3cSopenharmony_ci    auto context = host->GetContext();
156623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
156723b3eb3cSopenharmony_ci    auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
156823b3eb3cSopenharmony_ci    uiTaskExecutor.PostDelayedTask([weak = WeakClaim(this)] {
156923b3eb3cSopenharmony_ci        auto pattern = weak.Upgrade();
157023b3eb3cSopenharmony_ci        CHECK_NULL_VOID(pattern);
157123b3eb3cSopenharmony_ci        if (!pattern->isContentSizeChanged_) {
157223b3eb3cSopenharmony_ci            return;
157323b3eb3cSopenharmony_ci        }
157423b3eb3cSopenharmony_ci        pattern->UpdateAnalyzerOverlay();
157523b3eb3cSopenharmony_ci        pattern->isContentSizeChanged_ = false;
157623b3eb3cSopenharmony_ci        }, ANALYZER_CAPTURE_DELAY_TIME, "ArkUIMovingPhotoUpdateAnalyzerOverlay");
157723b3eb3cSopenharmony_ci    isContentSizeChanged_ = true;
157823b3eb3cSopenharmony_ci}
157923b3eb3cSopenharmony_ci
158023b3eb3cSopenharmony_civoid MovingPhotoPattern::UpdateAnalyzerOverlay()
158123b3eb3cSopenharmony_ci{
158223b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto UpdateAnalyzerOverlay");
158323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageAnalyzerManager_);
158423b3eb3cSopenharmony_ci    if (!IsSupportImageAnalyzer() || !imageAnalyzerManager_->IsOverlayCreated()) {
158523b3eb3cSopenharmony_ci        return;
158623b3eb3cSopenharmony_ci    }
158723b3eb3cSopenharmony_ci    GetPixelMap();
158823b3eb3cSopenharmony_ci    int64_t coverPosition = GetUriCoverPosition();
158923b3eb3cSopenharmony_ci    UpdateOverlayVisibility(VisibleType::VISIBLE);
159023b3eb3cSopenharmony_ci    auto host = GetHost();
159123b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
159223b3eb3cSopenharmony_ci    auto geometryNode = host->GetGeometryNode();
159323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(geometryNode);
159423b3eb3cSopenharmony_ci    auto movingPhotoNodeSize = geometryNode->GetContentSize();
159523b3eb3cSopenharmony_ci    MovingPhotoAnalyzerInfo info = {uri_, coverPosition,
159623b3eb3cSopenharmony_ci                                    movingPhotoNodeSize.Width(),
159723b3eb3cSopenharmony_ci                                    movingPhotoNodeSize.Height()};
159823b3eb3cSopenharmony_ci    imageAnalyzerManager_->UpdateMovingPhotoAnalyzerOverlay(pixelMap_, info);
159923b3eb3cSopenharmony_ci}
160023b3eb3cSopenharmony_ci
160123b3eb3cSopenharmony_civoid MovingPhotoPattern::UpdateAnalyzerUIConfig(const RefPtr<NG::GeometryNode>& geometryNode)
160223b3eb3cSopenharmony_ci{
160323b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto UpdateAnalyzerUIConfig");
160423b3eb3cSopenharmony_ci    if (IsSupportImageAnalyzer()) {
160523b3eb3cSopenharmony_ci        auto layoutProperty = GetLayoutProperty<MovingPhotoLayoutProperty>();
160623b3eb3cSopenharmony_ci        CHECK_NULL_VOID(layoutProperty);
160723b3eb3cSopenharmony_ci        auto padding  = layoutProperty->CreatePaddingAndBorder();
160823b3eb3cSopenharmony_ci        OffsetF contentOffset = { contentRect_.Left() - padding.left.value_or(0),
160923b3eb3cSopenharmony_ci                                  contentRect_.Top() - padding.top.value_or(0) };
161023b3eb3cSopenharmony_ci        PixelMapInfo info = { contentRect_.GetSize().Width(), contentRect_.GetSize().Height(), contentOffset };
161123b3eb3cSopenharmony_ci        CHECK_NULL_VOID(imageAnalyzerManager_);
161223b3eb3cSopenharmony_ci        imageAnalyzerManager_->UpdateAnalyzerUIConfig(geometryNode, info);
161323b3eb3cSopenharmony_ci    }
161423b3eb3cSopenharmony_ci}
161523b3eb3cSopenharmony_ci
161623b3eb3cSopenharmony_civoid MovingPhotoPattern::DestroyAnalyzerOverlay()
161723b3eb3cSopenharmony_ci{
161823b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto DestroyAnalyzerOverlay");
161923b3eb3cSopenharmony_ci    CHECK_NULL_VOID(imageAnalyzerManager_);
162023b3eb3cSopenharmony_ci    imageAnalyzerManager_->DestroyAnalyzerOverlay();
162123b3eb3cSopenharmony_ci}
162223b3eb3cSopenharmony_ci
162323b3eb3cSopenharmony_cibool MovingPhotoPattern::GetAnalyzerState()
162423b3eb3cSopenharmony_ci{
162523b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto GetAnalyzerState");
162623b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(imageAnalyzerManager_, false);
162723b3eb3cSopenharmony_ci    return imageAnalyzerManager_->IsOverlayCreated();
162823b3eb3cSopenharmony_ci}
162923b3eb3cSopenharmony_ci
163023b3eb3cSopenharmony_civoid MovingPhotoPattern::UpdateOverlayVisibility(VisibleType type)
163123b3eb3cSopenharmony_ci{
163223b3eb3cSopenharmony_ci    auto host = GetHost();
163323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(host);
163423b3eb3cSopenharmony_ci    auto overlayNode = host->GetOverlayNode();
163523b3eb3cSopenharmony_ci    CHECK_NULL_VOID(overlayNode);
163623b3eb3cSopenharmony_ci    auto prop = overlayNode->GetLayoutProperty();
163723b3eb3cSopenharmony_ci    CHECK_NULL_VOID(prop);
163823b3eb3cSopenharmony_ci    prop->UpdateVisibility(type);
163923b3eb3cSopenharmony_ci}
164023b3eb3cSopenharmony_ci
164123b3eb3cSopenharmony_civoid MovingPhotoPattern::GetPixelMap()
164223b3eb3cSopenharmony_ci{
164323b3eb3cSopenharmony_ci    auto layoutProperty = GetLayoutProperty<MovingPhotoLayoutProperty>();
164423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(layoutProperty);
164523b3eb3cSopenharmony_ci    if (!layoutProperty->HasMovingPhotoUri() || !layoutProperty->HasVideoSource()) {
164623b3eb3cSopenharmony_ci        TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "GetPixelMap MovingPhoto source is null.");
164723b3eb3cSopenharmony_ci        return;
164823b3eb3cSopenharmony_ci    }
164923b3eb3cSopenharmony_ci    auto pipeline = PipelineBase::GetCurrentContext();
165023b3eb3cSopenharmony_ci    CHECK_NULL_VOID(pipeline);
165123b3eb3cSopenharmony_ci    auto dataProvider = AceType::DynamicCast<DataProviderManagerStandard>(pipeline->GetDataProviderManager());
165223b3eb3cSopenharmony_ci    CHECK_NULL_VOID(dataProvider);
165323b3eb3cSopenharmony_ci    std::string imageSrc = dataProvider->GetMovingPhotoImagePath(uri_);
165423b3eb3cSopenharmony_ci    std::string thumbnailUrl = uri_ + THUMBNAIL_MEDIUM_JOINT + imageSrc;
165523b3eb3cSopenharmony_ci    void* pixelMapMediauniquePtr = dataProvider->GetDataProviderThumbnailResFromUri(thumbnailUrl);
165623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(pixelMapMediauniquePtr);
165723b3eb3cSopenharmony_ci    auto pixelMap = PixelMap::CreatePixelMapFromDataAbility(pixelMapMediauniquePtr);
165823b3eb3cSopenharmony_ci    CHECK_NULL_VOID(pixelMap);
165923b3eb3cSopenharmony_ci    pixelMap_ = pixelMap;
166023b3eb3cSopenharmony_ci}
166123b3eb3cSopenharmony_ci
166223b3eb3cSopenharmony_ciint64_t MovingPhotoPattern::GetUriCoverPosition()
166323b3eb3cSopenharmony_ci{
166423b3eb3cSopenharmony_ci    auto pipeline = PipelineBase::GetCurrentContext();
166523b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(pipeline, -1);
166623b3eb3cSopenharmony_ci    auto dataProvider = AceType::DynamicCast<DataProviderManagerStandard>(pipeline->GetDataProviderManager());
166723b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(dataProvider, -1);
166823b3eb3cSopenharmony_ci    std::vector<std::string> columns = {COVER_POSITION};
166923b3eb3cSopenharmony_ci    auto result = dataProvider->GetMovingPhotoCoverPosition(IMAGE_URI, uri_, columns);
167023b3eb3cSopenharmony_ci    return result;
167123b3eb3cSopenharmony_ci}
167223b3eb3cSopenharmony_ci
167323b3eb3cSopenharmony_civoid MovingPhotoPattern::HandleAnalyzerPlayEvent(bool canPlay)
167423b3eb3cSopenharmony_ci{
167523b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "MovingPhoto HandleAnalyzerPlayEvent:%{public}d", canPlay);
167623b3eb3cSopenharmony_ci    if (isAnalyzerPlaying_ && !canPlay) {
167723b3eb3cSopenharmony_ci        Pause();
167823b3eb3cSopenharmony_ci        StopAnimation();
167923b3eb3cSopenharmony_ci    }
168023b3eb3cSopenharmony_ci    isAnalyzerPlaying_ = canPlay;
168123b3eb3cSopenharmony_ci    if (canPlay) {
168223b3eb3cSopenharmony_ci        HandleImageAnalyzerPlayCallBack();
168323b3eb3cSopenharmony_ci    }
168423b3eb3cSopenharmony_ci}
168523b3eb3cSopenharmony_ci
168623b3eb3cSopenharmony_ciMovingPhotoPattern::~MovingPhotoPattern()
168723b3eb3cSopenharmony_ci{
168823b3eb3cSopenharmony_ci    if (IsSupportImageAnalyzer()) {
168923b3eb3cSopenharmony_ci        TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "~MovingPhotoPattern DestroyAnalyzerOverlay.");
169023b3eb3cSopenharmony_ci        DestroyAnalyzerOverlay();
169123b3eb3cSopenharmony_ci    }
169223b3eb3cSopenharmony_ci    if (fd_ > 0) {
169323b3eb3cSopenharmony_ci        close(fd_);
169423b3eb3cSopenharmony_ci    }
169523b3eb3cSopenharmony_ci}
169623b3eb3cSopenharmony_ci} // namespace OHOS::Ace::NG