diff --git a/adapter/ohos/entrance/ui_content_impl.cpp b/adapter/ohos/entrance/ui_content_impl.cpp index 183b1b9549f91930baec31e8285de98780087a6f..8b8d3a4668474dbf4f6ac3942bcb8b2fdd0e21e6 100644 --- a/adapter/ohos/entrance/ui_content_impl.cpp +++ b/adapter/ohos/entrance/ui_content_impl.cpp @@ -495,6 +495,22 @@ bool ParseAvoidAreasUpdate(const RefPtr& context, return false; } +std::map ParseAvoidAreasToMap( + const std::map& avoidAreas) +{ + std::map safeAvoidAreas; + for (auto& avoidArea : avoidAreas) { + if (avoidArea.first == OHOS::Rosen::AvoidAreaType::TYPE_SYSTEM) { + safeAvoidAreas[NG::SafeAreaAvoidType::TYPE_SYSTEM] = ConvertAvoidArea(avoidArea.second); + } else if (avoidArea.first == OHOS::Rosen::AvoidAreaType::TYPE_NAVIGATION_INDICATOR) { + safeAvoidAreas[NG::SafeAreaAvoidType::TYPE_NAVIGATION_INDICATOR] = ConvertAvoidArea(avoidArea.second); + } else if (avoidArea.first == OHOS::Rosen::AvoidAreaType::TYPE_CUTOUT) { + safeAvoidAreas[NG::SafeAreaAvoidType::TYPE_CUTOUT] = ConvertAvoidArea(avoidArea.second); + } + } + return safeAvoidAreas; +} + void AvoidAreasUpdateOnUIExtension(const RefPtr& context, const std::map& avoidAreas) { @@ -508,21 +524,18 @@ void AvoidAreasUpdateOnUIExtension(const RefPtr& context, } } -void UpdateSafeArea(const RefPtr& pipelineContext, +std::map UpdateSafeArea(const RefPtr& pipelineContext, const std::map& avoidAreas, - const ViewportConfig& config, - const RefPtr& container) + const ViewportConfig& config) { - CHECK_NULL_VOID(container); - CHECK_NULL_VOID(pipelineContext); + CHECK_NULL_RETURN(pipelineContext, {}); auto context = AceType::DynamicCast(pipelineContext); - CHECK_NULL_VOID(context); + CHECK_NULL_RETURN(context, {}); auto safeAreaManager = context->GetSafeAreaManager(); - CHECK_NULL_VOID(safeAreaManager); - uint32_t keyboardHeight = safeAreaManager->GetKeyboardInset().Length(); - safeAreaManager->UpdateKeyboardSafeArea(keyboardHeight, config.Height()); - ParseAvoidAreasUpdate(context, avoidAreas, config); + CHECK_NULL_RETURN(safeAreaManager, {}); + auto safeAreaMap = ParseAvoidAreasToMap(avoidAreas); AvoidAreasUpdateOnUIExtension(context, avoidAreas); + return safeAreaMap; } void ClearAllMenuPopup(int32_t instanceId, WindowChangeType type) @@ -3958,8 +3971,8 @@ void UIContentImpl::UpdateViewportConfigWithAnimation(const ViewportConfig& conf taskId, viewportConfigMgr = viewportConfigMgr_]() { container->SetWindowPos(config.Left(), config.Top()); auto pipelineContext = container->GetPipelineContext(); + auto avoidAreaMap = UpdateSafeArea(pipelineContext, avoidAreas, config); if (pipelineContext) { - UpdateSafeArea(pipelineContext, avoidAreas, config, container); if (reason != OHOS::Rosen::WindowSizeChangeReason::ROOT_SCENE_CHANGE) { pipelineContext->SetDisplayWindowRectInfo( Rect(Offset(config.Left(), config.Top()), Size(config.Width(), config.Height()))); @@ -3987,15 +4000,19 @@ void UIContentImpl::UpdateViewportConfigWithAnimation(const ViewportConfig& conf CHECK_NULL_VOID(aceView); Platform::AceViewOhos::TransformHintChanged(aceView, config.TransformHint()); if (isDynamicRender && animationOpt.IsValid()) { - AnimationUtils::Animate(animationOpt, [pipelineContext, aceView, config, reason, rsTransaction] { + AnimationUtils::Animate(animationOpt, [pipelineContext, aceView, config, reason, rsTransaction, avoidAreaMap] { ContainerScope scope(aceView->GetInstanceId()); Platform::AceViewOhos::SurfaceChanged(aceView, config.Width(), config.Height(), config.Orientation(), static_cast(reason), rsTransaction); pipelineContext->OnSurfaceChanged( - config.Width(), config.Height(), static_cast(reason), rsTransaction); + config.Width(), config.Height(), static_cast(reason), rsTransaction, avoidAreaMap); pipelineContext->FlushUITasks(true); }, nullptr, nullptr, pipelineContext); } else { + auto context = AceType::DynamicCast(pipelineContext); + if (context) { + context->FlushSafeArea(config.Width(), config.Height(), avoidAreaMap); + } Platform::AceViewOhos::SurfaceChanged(aceView, config.Width(), config.Height(), config.Orientation(), static_cast(reason), rsTransaction); } diff --git a/frameworks/core/pipeline/pipeline_base.h b/frameworks/core/pipeline/pipeline_base.h index 05b2efb60e845ebdb7eae32d07ab3ae90810be12..062ec8c623942e285124b52cbf44b4523edfd07e 100644 --- a/frameworks/core/pipeline/pipeline_base.h +++ b/frameworks/core/pipeline/pipeline_base.h @@ -270,7 +270,8 @@ public: virtual void OnSurfaceChanged(int32_t width, int32_t height, WindowSizeChangeReason type = WindowSizeChangeReason::UNDEFINED, - const std::shared_ptr& rsTransaction = nullptr) = 0; + const std::shared_ptr& rsTransaction = nullptr, + const std::map& safeAvoidArea = {}) = 0; virtual void OnSurfacePositionChanged(int32_t posX, int32_t posY) = 0; diff --git a/frameworks/core/pipeline/pipeline_context.cpp b/frameworks/core/pipeline/pipeline_context.cpp index afeff23ac3650721326e74c54a77c9c38dbc83b2..aee7d4b3c67ac4b2da0407eb175d0cf051fa82fb 100644 --- a/frameworks/core/pipeline/pipeline_context.cpp +++ b/frameworks/core/pipeline/pipeline_context.cpp @@ -2146,7 +2146,7 @@ void PipelineContext::WindowSizeChangeAnimate(int32_t width, int32_t height, Win } void PipelineContext::OnSurfaceChanged(int32_t width, int32_t height, WindowSizeChangeReason type, - const std::shared_ptr& rsTransaction) + const std::shared_ptr& rsTransaction, const std::map& safeAvoidArea) { CHECK_RUN_ON(UI); if (width_ == width && height_ == height && type == WindowSizeChangeReason::CUSTOM_ANIMATION) { diff --git a/frameworks/core/pipeline/pipeline_context.h b/frameworks/core/pipeline/pipeline_context.h index efa7ae6238a84f5384c10c3d80f39256c945b50c..ccb56d565543fc635fa4c9baf95b690dbd9c8989 100644 --- a/frameworks/core/pipeline/pipeline_context.h +++ b/frameworks/core/pipeline/pipeline_context.h @@ -261,7 +261,8 @@ public: void OnSurfaceChanged( int32_t width, int32_t height, WindowSizeChangeReason type = WindowSizeChangeReason::UNDEFINED, - const std::shared_ptr& rsTransaction = nullptr) override; + const std::shared_ptr& rsTransaction = nullptr, + const std::map& safeAvoidArea = {}) override; void OnSurfacePositionChanged(int32_t posX, int32_t posY) override; diff --git a/frameworks/core/pipeline_ng/pipeline_context.cpp b/frameworks/core/pipeline_ng/pipeline_context.cpp index 3af2560f70b102311b6e4ec40e7d11aaf06ffd1b..199fc387b05c8de2c3745badaaec15b63d7657aa 100755 --- a/frameworks/core/pipeline_ng/pipeline_context.cpp +++ b/frameworks/core/pipeline_ng/pipeline_context.cpp @@ -1695,8 +1695,31 @@ const RefPtr& PipelineContext::GetFullScreenManager() return fullScreenManager_; } +bool PipelineContext::FlushSafeArea( + int32_t width, int32_t height, std::map safeAvoidAreas) +{ + bool safeAreaUpdated = false; + for (auto& avoidArea : safeAvoidAreas) { + if (avoidArea.first == NG::SafeAreaAvoidType::TYPE_SYSTEM) { + safeAreaUpdated |= safeAreaManager_->UpdateSystemSafeArea(avoidArea.second); + } else if (avoidArea.first == NG::SafeAreaAvoidType::TYPE_NAVIGATION_INDICATOR) { + safeAreaUpdated |= safeAreaManager_->UpdateNavSafeArea(avoidArea.second); + } else if (avoidArea.first == NG::SafeAreaAvoidType::TYPE_CUTOUT) { + safeAreaUpdated |= safeAreaManager_->UpdateCutoutSafeArea( + avoidArea.second, NG::OptionalSize(width, height)); + } + } + uint32_t keyboardHeight = safeAreaManager_->GetKeyboardInset().Length(); + safeAreaManager_->UpdateKeyboardSafeArea(keyboardHeight, height); + if (safeAreaUpdated) { + SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_AVOID_AREA); + return true; + } + return false; +} + void PipelineContext::OnSurfaceChanged(int32_t width, int32_t height, WindowSizeChangeReason type, - const std::shared_ptr& rsTransaction) + const std::shared_ptr& rsTransaction, const std::map& safeAvoidArea) { ACE_SCOPED_TRACE("PipelineContext::OnSurfaceChanged"); CHECK_RUN_ON(UI); @@ -1730,8 +1753,9 @@ void PipelineContext::OnSurfaceChanged(int32_t width, int32_t height, WindowSize UpdateSizeChangeReason(type, rsTransaction); #ifdef ENABLE_ROSEN_BACKEND - StartWindowSizeChangeAnimate(width, height, type, rsTransaction); + StartWindowSizeChangeAnimate(width, height, type, rsTransaction, safeAvoidArea); #else + FlushSafeArea(width, height,safeAvoidArea); SetRootRect(width, height, 0.0); #endif } @@ -1824,7 +1848,7 @@ void PipelineContext::OnTransformHintChanged(uint32_t transform) } void PipelineContext::StartWindowSizeChangeAnimate(int32_t width, int32_t height, WindowSizeChangeReason type, - const std::shared_ptr& rsTransaction) + const std::shared_ptr& rsTransaction, const std::map& safeAvoidArea) { static const bool IsWindowSizeAnimationEnabled = SystemProperties::IsWindowSizeAnimationEnabled(); if (!IsWindowSizeAnimationEnabled) { @@ -1834,26 +1858,27 @@ void PipelineContext::StartWindowSizeChangeAnimate(int32_t width, int32_t height switch (type) { case WindowSizeChangeReason::FULL_TO_SPLIT: case WindowSizeChangeReason::FULL_TO_FLOATING: { - StartFullToMultWindowAnimation(width, height, type, rsTransaction); + StartFullToMultWindowAnimation(width, height, type, rsTransaction, safeAvoidArea); break; } case WindowSizeChangeReason::RECOVER: case WindowSizeChangeReason::MAXIMIZE: { - StartWindowMaximizeAnimation(width, height, rsTransaction); + StartWindowMaximizeAnimation(width, height, rsTransaction, safeAvoidArea); break; } case WindowSizeChangeReason::MAXIMIZE_TO_SPLIT: case WindowSizeChangeReason::SPLIT_TO_MAXIMIZE: { - StartSplitWindowAnimation(width, height, type, rsTransaction); + StartSplitWindowAnimation(width, height, type, rsTransaction, safeAvoidArea); break; } case WindowSizeChangeReason::MAXIMIZE_IN_IMPLICT: case WindowSizeChangeReason::RECOVER_IN_IMPLICIT: { - MaximizeInImplictAnimation(width, height, type, rsTransaction); + MaximizeInImplictAnimation(width, height, type, rsTransaction, safeAvoidArea); break; } case WindowSizeChangeReason::ROTATION: { safeAreaManager_->UpdateKeyboardOffset(0.0); + FlushSafeArea(width, height,safeAvoidArea); SetRootRect(width, height, 0.0); FlushUITasks(); if (textFieldManager_) { @@ -1877,6 +1902,7 @@ void PipelineContext::StartWindowSizeChangeAnimate(int32_t width, int32_t height case WindowSizeChangeReason::RESIZE: case WindowSizeChangeReason::UNDEFINED: default: { + FlushSafeArea(width, height,safeAvoidArea); SetRootRect(width, height, 0.0f); } } @@ -1928,7 +1954,8 @@ void PipelineContext::PostKeyboardAvoidTask() } void PipelineContext::StartWindowMaximizeAnimation( - int32_t width, int32_t height, const std::shared_ptr& rsTransaction) + int32_t width, int32_t height, const std::shared_ptr& rsTransaction, + const std::map& safeAvoidArea) { TAG_LOGI(AceLogTag::ACE_ANIMATION, "Root node start RECOVER/MAXIMIZE animation, width = %{public}d, height = %{public}d", width, height); @@ -1950,9 +1977,10 @@ void PipelineContext::StartWindowMaximizeAnimation( auto curve = Curves::EASE_OUT; option.SetCurve(curve); auto weak = WeakClaim(this); - Animate(option, curve, [width, height, weak]() { + Animate(option, curve, [width, height, weak, safeAvoidArea]() { auto pipeline = weak.Upgrade(); CHECK_NULL_VOID(pipeline); + pipeline->FlushSafeArea(width, height,safeAvoidArea); pipeline->SetRootRect(width, height, 0.0); pipeline->FlushUITasks(); }); @@ -1963,8 +1991,9 @@ void PipelineContext::StartWindowMaximizeAnimation( #endif } -void PipelineContext::StartFullToMultWindowAnimation(int32_t width, int32_t height, WindowSizeChangeReason type, - const std::shared_ptr& rsTransaction) +void PipelineContext::StartFullToMultWindowAnimation(int32_t width, int32_t height, + WindowSizeChangeReason type, const std::shared_ptr& rsTransaction, + const std::map& safeAvoidArea) { TAG_LOGI(AceLogTag::ACE_ANIMATION, "Root node start multiple window animation, type = %{public}d, width = %{public}d, height = %{public}d", type, @@ -1985,9 +2014,10 @@ void PipelineContext::StartFullToMultWindowAnimation(int32_t width, int32_t heig auto springMotion = AceType::MakeRefPtr(response, dampingFraction, 0); option.SetCurve(springMotion); auto weak = WeakClaim(this); - Animate(option, springMotion, [width, height, weak]() { + Animate(option, springMotion, [width, height, weak, safeAvoidArea]() { auto pipeline = weak.Upgrade(); CHECK_NULL_VOID(pipeline); + pipeline->FlushSafeArea(width, height,safeAvoidArea); pipeline->SetRootRect(width, height, 0.0); pipeline->FlushUITasks(); }); @@ -1999,7 +2029,8 @@ void PipelineContext::StartFullToMultWindowAnimation(int32_t width, int32_t heig } void PipelineContext::StartSplitWindowAnimation(int32_t width, int32_t height, WindowSizeChangeReason type, - const std::shared_ptr& rsTransaction) + const std::shared_ptr& rsTransaction, + const std::map& safeAvoidArea) { TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "Root node start split window animation, type = %{public}d, width = %{public}d, height = %{public}d", type, @@ -2013,9 +2044,10 @@ void PipelineContext::StartSplitWindowAnimation(int32_t width, int32_t height, W auto curve = AceType::MakeRefPtr(0.0f, 1.0f, 300.0f, 33.0f); AnimationOption option; option.SetCurve(curve); - Animate(option, curve, [width, height, weak = WeakClaim(this)]() { + Animate(option, curve, [width, height, weak = WeakClaim(this), safeAvoidArea]() { auto pipeline = weak.Upgrade(); CHECK_NULL_VOID(pipeline); + pipeline->FlushSafeArea(width, height,safeAvoidArea); pipeline->SetRootRect(width, height, 0.0); pipeline->FlushUITasks(); }); @@ -2027,7 +2059,8 @@ void PipelineContext::StartSplitWindowAnimation(int32_t width, int32_t height, W } void PipelineContext::MaximizeInImplictAnimation(int32_t width, int32_t height, WindowSizeChangeReason type, - const std::shared_ptr& rsTransaction) + const std::shared_ptr& rsTransaction, + const std::map& safeAvoidArea) { TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "Maximize window in implict animation, type = %{public}d, width = %{public}d, height = %{public}d", type, @@ -2041,9 +2074,10 @@ void PipelineContext::MaximizeInImplictAnimation(int32_t width, int32_t height, auto curve = AceType::MakeRefPtr(0.0f, 1.0f, 300.0f, 33.0f); AnimationOption option; option.SetCurve(curve); - Animate(option, curve, [width, height, weak = WeakClaim(this)]() { + Animate(option, curve, [width, height, weak = WeakClaim(this), safeAvoidArea]() { auto pipeline = weak.Upgrade(); CHECK_NULL_VOID(pipeline); + pipeline->FlushSafeArea(width, height,safeAvoidArea); pipeline->SetRootRect(width, height, 0.0); pipeline->FlushUITasks(); }); diff --git a/frameworks/core/pipeline_ng/pipeline_context.h b/frameworks/core/pipeline_ng/pipeline_context.h index 064381617d58e25df2a1be211df2776aa4a3af7d..d482cd7d8859f6cc4c8da40aa0eafe2d3031bc42 100755 --- a/frameworks/core/pipeline_ng/pipeline_context.h +++ b/frameworks/core/pipeline_ng/pipeline_context.h @@ -355,7 +355,8 @@ public: void OnSurfaceChanged(int32_t width, int32_t height, WindowSizeChangeReason type = WindowSizeChangeReason::UNDEFINED, - const std::shared_ptr& rsTransaction = nullptr) override; + const std::shared_ptr& rsTransaction = nullptr, + const std::map& safeAvoidArea = {}) override; void OnLayoutCompleted(const std::string& componentId); void OnDrawCompleted(const std::string& componentId); @@ -388,6 +389,9 @@ public: void AddIgnoreLayoutSafeAreaBundle(IgnoreLayoutSafeAreaBundle&& bundle); + bool FlushSafeArea( + int32_t width, int32_t height, std::map safeAvoidAreas); + void AddLayoutNode(const RefPtr& layoutNode); void AddDirtyRenderNode(const RefPtr& dirty); @@ -1286,15 +1290,20 @@ public: protected: void StartWindowSizeChangeAnimate(int32_t width, int32_t height, WindowSizeChangeReason type, - const std::shared_ptr& rsTransaction = nullptr); - void StartWindowMaximizeAnimation( - int32_t width, int32_t height, const std::shared_ptr& rsTransaction = nullptr); + const std::shared_ptr& rsTransaction = nullptr, + const std::map& safeAvoidArea = {}); + void StartWindowMaximizeAnimation(int32_t width, int32_t height, + const std::shared_ptr& rsTransaction = nullptr, + const std::map& safeAvoidArea = {}); void StartFullToMultWindowAnimation(int32_t width, int32_t height, WindowSizeChangeReason type, - const std::shared_ptr& rsTransaction = nullptr); + const std::shared_ptr& rsTransaction = nullptr, + const std::map& safeAvoidArea = {}); void StartSplitWindowAnimation(int32_t width, int32_t height, WindowSizeChangeReason type, - const std::shared_ptr& rsTransaction = nullptr); + const std::shared_ptr& rsTransaction = nullptr, + const std::map& safeAvoidArea = {}); void MaximizeInImplictAnimation(int32_t width, int32_t height, WindowSizeChangeReason type, - const std::shared_ptr& rsTransaction = nullptr); + const std::shared_ptr& rsTransaction = nullptr, + const std::map& safeAvoidArea = {}); void FlushVsync(uint64_t nanoTimestamp, uint64_t frameCount) override; void FlushPipelineWithoutAnimation() override; diff --git a/interfaces/inner_api/ace_kit/include/ui/properties/safe_area_insets.h b/interfaces/inner_api/ace_kit/include/ui/properties/safe_area_insets.h index 964e3ef708e36635122dcd6075ce5e470a390212..817db136b80d5c7385058d53bdba343736fdc710 100644 --- a/interfaces/inner_api/ace_kit/include/ui/properties/safe_area_insets.h +++ b/interfaces/inner_api/ace_kit/include/ui/properties/safe_area_insets.h @@ -319,5 +319,18 @@ struct IgnoreLayoutSafeAreaOpts { return index > EDGE_MASK_LIMIT ? 0 : LayoutEdgeEnum[index]; } }; + +/** + * @brief Enumerates avoid area type. + */ +enum class SafeAreaAvoidType : uint32_t { + TYPE_START = 0, + TYPE_SYSTEM = TYPE_START, // area of SystemUI + TYPE_CUTOUT, // cutout of screen + TYPE_SYSTEM_GESTURE, // area for system gesture + TYPE_KEYBOARD, // area for soft input keyboard + TYPE_NAVIGATION_INDICATOR, // area for navigation indicator + TYPE_END, +}; } // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_INTERFACES_INNER_API_ACE_KIT_INCLUDE_BASE_PROPERTIES_SAFE_AREA_INSETS_H \ No newline at end of file diff --git a/test/mock/core/pipeline/mock_pipeline_context.cpp b/test/mock/core/pipeline/mock_pipeline_context.cpp index cf52445ca5d33d510c6239fad17710febcf908d5..3d8a903104a2824896ed7795a47585f1954b3f71 100644 --- a/test/mock/core/pipeline/mock_pipeline_context.cpp +++ b/test/mock/core/pipeline/mock_pipeline_context.cpp @@ -592,7 +592,8 @@ void PipelineContext::OnRawKeyboardChangedCallback() {} void PipelineContext::OnFoldDisplayModeChange(FoldDisplayMode foldDisplayMode) {} void PipelineContext::OnSurfaceChanged(int32_t width, int32_t height, WindowSizeChangeReason type, - const std::shared_ptr& rsTransaction) + const std::shared_ptr& rsTransaction, + const std::map& safeAvoidArea) {} void PipelineContext::OnLayoutCompleted(const std::string& componentId) {}