add safeArea

Signed-off-by: zhangrongjie <zhangrongjie4@huawei.com>
Change-Id: Ia86fac3a1d7478ec3295a9703389a8ce0e36f755
This commit is contained in:
zhangrongjie 2023-04-04 14:02:18 +00:00
parent 3457863b69
commit d668f7abda
19 changed files with 263 additions and 4 deletions

View File

@ -700,6 +700,7 @@ void AceAbility::OnSizeChange(const OHOS::Rosen::Rect& rect, OHOS::Rosen::Window
if (pipelineContext) {
pipelineContext->SetDisplayWindowRectInfo(
Rect(Offset(rect.posX_, rect.posY_), Size(rect.width_, rect.height_)));
pipelineContext->SetIsLayoutFullScreen(Ability::GetWindow()->IsLayoutFullScreen());
}
auto taskExecutor = container->GetTaskExecutor();
CHECK_NULL_VOID(taskExecutor);

View File

@ -1113,6 +1113,11 @@ void AceContainer::AttachView(std::shared_ptr<Window> window, AceView* view, dou
pipelineContext_->SetIsRightToLeft(AceApplicationInfo::GetInstance().IsRightToLeft());
pipelineContext_->SetWindowId(windowId);
pipelineContext_->SetWindowModal(windowModal_);
if (uiWindow_) {
auto windowType = uiWindow_->GetType();
pipelineContext_->SetIsAppWindow(
windowType < Rosen::WindowType::SYSTEM_WINDOW_BASE && windowType >= Rosen::WindowType::APP_WINDOW_BASE);
}
if (installationFree_) {
pipelineContext_->SetInstallationFree(installationFree_);
pipelineContext_->SetSharePanelCallback(std::move(sharePanelCallback_));
@ -1357,6 +1362,60 @@ void AceContainer::InitWindowCallback()
rect.SetRect(windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_);
return rect;
});
pipelineContext_->SetGetViewSafeAreaImpl([window = uiWindow_, this]() -> SafeAreaEdgeInserts {
return SetViewSafeArea(window);
});
}
// Get SafeArea by Window
SafeAreaEdgeInserts AceContainer::SetViewSafeArea(sptr<OHOS::Rosen::Window> window)
{
SafeAreaEdgeInserts viewSafeArea;
CHECK_NULL_RETURN_NOLOG(window, viewSafeArea);
Rosen::AvoidArea systemAvoidArea;
Rosen::AvoidArea cutoutAvoidArea;
Rosen::WMError systemRet = window->GetAvoidAreaByType(Rosen::AvoidAreaType::TYPE_SYSTEM, systemAvoidArea);
Rosen::WMError cutoutRet = window->GetAvoidAreaByType(Rosen::AvoidAreaType::TYPE_CUTOUT, cutoutAvoidArea);
Rect topRect;
Rect leftRect;
Rect rightRect;
Rect bottomRect;
if (systemRet == Rosen::WMError::WM_OK) {
topRect = Rect(static_cast<double>(systemAvoidArea.topRect_.posX_),
static_cast<double>(systemAvoidArea.topRect_.posY_), static_cast<double>(systemAvoidArea.topRect_.width_),
static_cast<double>(systemAvoidArea.topRect_.height_));
leftRect = Rect(static_cast<double>(systemAvoidArea.leftRect_.posX_),
static_cast<double>(systemAvoidArea.leftRect_.posY_), static_cast<double>(systemAvoidArea.leftRect_.width_),
static_cast<double>(systemAvoidArea.leftRect_.height_));
rightRect = Rect(static_cast<double>(systemAvoidArea.rightRect_.posX_),
static_cast<double>(systemAvoidArea.rightRect_.posY_),
static_cast<double>(systemAvoidArea.rightRect_.width_),
static_cast<double>(systemAvoidArea.rightRect_.height_));
bottomRect = Rect(static_cast<double>(systemAvoidArea.bottomRect_.posX_),
static_cast<double>(systemAvoidArea.bottomRect_.posY_),
static_cast<double>(systemAvoidArea.bottomRect_.width_),
static_cast<double>(systemAvoidArea.bottomRect_.height_));
}
if (cutoutRet == Rosen::WMError::WM_OK) {
topRect.CombineRect(Rect(static_cast<double>(cutoutAvoidArea.topRect_.posX_),
static_cast<double>(cutoutAvoidArea.topRect_.posY_), static_cast<double>(cutoutAvoidArea.topRect_.width_),
static_cast<double>(cutoutAvoidArea.topRect_.height_)));
leftRect.CombineRect(Rect(static_cast<double>(cutoutAvoidArea.leftRect_.posX_),
static_cast<double>(cutoutAvoidArea.leftRect_.posY_), static_cast<double>(cutoutAvoidArea.leftRect_.width_),
static_cast<double>(cutoutAvoidArea.leftRect_.height_)));
rightRect.CombineRect(Rect(static_cast<double>(cutoutAvoidArea.rightRect_.posX_),
static_cast<double>(cutoutAvoidArea.rightRect_.posY_),
static_cast<double>(cutoutAvoidArea.rightRect_.width_),
static_cast<double>(cutoutAvoidArea.rightRect_.height_)));
bottomRect.CombineRect(Rect(static_cast<double>(cutoutAvoidArea.bottomRect_.posX_),
static_cast<double>(cutoutAvoidArea.bottomRect_.posY_),
static_cast<double>(cutoutAvoidArea.bottomRect_.width_),
static_cast<double>(cutoutAvoidArea.bottomRect_.height_)));
}
viewSafeArea.SetRect(leftRect, topRect, rightRect, bottomRect);
return viewSafeArea;
}
std::shared_ptr<OHOS::AbilityRuntime::Context> AceContainer::GetAbilityContextByModule(

View File

@ -410,6 +410,8 @@ private:
void InitializeTask();
void InitWindowCallback();
SafeAreaEdgeInserts SetViewSafeArea(sptr<OHOS::Rosen::Window> window);
void AttachView(std::shared_ptr<Window> window, AceView* view, double density, int32_t width, int32_t height,
int32_t windowId, UIEnvCallback callback = nullptr);
void SetUIWindowInner(sptr<OHOS::Rosen::Window> uiWindow);

View File

@ -29,6 +29,7 @@
#include "service_extension_context.h"
#include "adapter/ohos/osal/pixel_map_ohos.h"
#include "core/pipeline_ng/pipeline_context.h"
#ifdef ENABLE_ROSEN_BACKEND
#include "render_service_client/core/ui/rs_ui_director.h"
@ -1431,12 +1432,13 @@ void UIContentImpl::UpdateViewportConfig(const ViewportConfig& config, OHOS::Ros
auto taskExecutor = container->GetTaskExecutor();
CHECK_NULL_VOID(taskExecutor);
taskExecutor->PostTask(
[config, container, reason, rsTransaction]() {
[config, container, reason, rsTransaction, rsWindow = window_]() {
container->SetWindowPos(config.Left(), config.Top());
auto pipelineContext = container->GetPipelineContext();
if (pipelineContext) {
pipelineContext->SetDisplayWindowRectInfo(
Rect(Offset(config.Left(), config.Top()), Size(config.Width(), config.Height())));
pipelineContext->SetIsLayoutFullScreen(rsWindow->IsLayoutFullScreen());
}
auto aceView = static_cast<Platform::AceViewOhos*>(container->GetAceView());
CHECK_NULL_VOID(aceView);
@ -1448,6 +1450,23 @@ void UIContentImpl::UpdateViewportConfig(const ViewportConfig& config, OHOS::Ros
TaskExecutor::TaskType::PLATFORM);
}
void UIContentImpl::SetIgnoreViewSafeArea(bool ignoreViewSafeArea)
{
LOGI("UIContentImpl: SetIgnoreViewSafeArea:%{public}u", ignoreViewSafeArea);
auto container = AceEngine::Get().GetContainer(instanceId_);
CHECK_NULL_VOID(container);
ContainerScope scope(instanceId_);
auto taskExecutor = container->GetTaskExecutor();
CHECK_NULL_VOID(taskExecutor);
taskExecutor->PostSyncTask(
[container, ignoreSafeArea = ignoreViewSafeArea]() {
auto pipelineContext = container->GetPipelineContext();
CHECK_NULL_VOID(pipelineContext);
pipelineContext->SetIgnoreViewSafeArea(ignoreSafeArea);
},
TaskExecutor::TaskType::UI);
}
void UIContentImpl::UpdateWindowMode(OHOS::Rosen::WindowMode mode, bool hasDeco)
{
LOGI("UIContentImpl: UpdateWindowMode, window mode is %{public}d, hasDeco is %{public}d", mode, hasDeco);

View File

@ -65,6 +65,7 @@ public:
const std::shared_ptr<OHOS::Rosen::RSTransaction> rsTransaction = nullptr) override;
void UpdateWindowMode(OHOS::Rosen::WindowMode mode, bool hasDeco = true) override;
void HideWindowTitleButton(bool hideSplit, bool hideMaximize, bool hideMinimize) override;
void SetIgnoreViewSafeArea(bool ignoreViewSafeArea) override;
// Window color
uint32_t GetBackgroundColor() override;

View File

@ -413,6 +413,23 @@ private:
double height_ = 0.0;
};
struct SafeAreaEdgeInserts {
SafeAreaEdgeInserts() = default;
void SetRect(Rect leftRect, Rect topRect, Rect rightRect, Rect bottomRect)
{
leftRect_ = leftRect;
topRect_ = topRect;
rightRect_ = rightRect;
bottomRect_ = bottomRect;
}
Rect leftRect_;
Rect topRect_;
Rect rightRect_;
Rect bottomRect_;
};
} // namespace OHOS::Ace
#endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_RECT_H

View File

@ -18,6 +18,7 @@
#include <memory>
#include "base/geometry/ng/rect_t.h"
#include "base/thread/task_executor.h"
#include "base/utils/macros.h"
#include "base/utils/noncopyable.h"
@ -139,6 +140,20 @@ public:
return rect;
}
void SetGetViewSafeAreaImpl(std::function<SafeAreaEdgeInserts()>&& callback)
{
viewSafeAreaImpl_ = std::move(callback);
}
SafeAreaEdgeInserts GetCurrentViewSafeArea() const
{
SafeAreaEdgeInserts viewSafeArea;
if (viewSafeAreaImpl_) {
viewSafeArea = viewSafeAreaImpl_();
}
return viewSafeArea;
}
virtual void SetDrawTextAsBitmap(bool useBitmap) {}
virtual float GetRefreshRate() const
@ -151,6 +166,18 @@ public:
return lastRequestVsyncTime_;
}
SafeAreaEdgeInserts GetSafeArea() const
{
return viewSafeArea_;
}
void SetSafeArea(SafeAreaEdgeInserts viewSafeArea)
{
viewSafeArea_ = viewSafeArea;
}
SafeAreaEdgeInserts viewSafeArea_;
protected:
bool isRequestVsync_ = false;
bool onShow_ = true;
@ -171,6 +198,7 @@ protected:
private:
std::function<Rect()> windowRectImpl_;
std::function<SafeAreaEdgeInserts()> viewSafeAreaImpl_;
std::unique_ptr<PlatformWindow> platformWindow_;
ACE_DISALLOW_COPY_AND_MOVE(Window);

View File

@ -17,19 +17,38 @@
#include <optional>
#include "base/geometry/ng/offset_t.h"
#include "base/geometry/ng/size_t.h"
#include "base/geometry/size.h"
#include "base/utils/utils.h"
#include "core/common/window.h"
#include "core/components_ng/base/frame_node.h"
#include "core/components_ng/layout/layout_wrapper.h"
#include "core/components_ng/property/measure_property.h"
#include "core/components_ng/property/measure_utils.h"
#include "core/components_ng/property/property.h"
#include "core/pipeline/pipeline_base.h"
namespace OHOS::Ace::NG {
void BoxLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
{
auto layoutConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint();
auto pipeline = OHOS::Ace::PipelineBase::GetCurrentContext();
if (pipeline && pipeline->GetIsAppWindow() && pipeline->GetIsLayoutFullScreen()) {
auto layoutProperty = layoutWrapper->GetLayoutProperty();
if (layoutProperty) {
auto safeArea = layoutProperty->GetSafeArea();
SizeF maxSize { layoutConstraint.maxSize.Width() - safeArea.leftRect_.Width() - safeArea.rightRect_.Width(),
layoutConstraint.maxSize.Height() - safeArea.topRect_.Height() - safeArea.bottomRect_.Height() };
SizeF percentReference {
layoutConstraint.percentReference.Width() - safeArea.leftRect_.Width() - safeArea.rightRect_.Width(),
layoutConstraint.percentReference.Height() - safeArea.topRect_.Height() - safeArea.bottomRect_.Height()
};
layoutConstraint.UpdateMaxSizeWithCheck(maxSize);
layoutConstraint.UpdatePercentReference(percentReference);
}
}
for (auto&& child : layoutWrapper->GetAllChildrenWithBuild()) {
child->Measure(layoutConstraint);
}
@ -132,7 +151,16 @@ void BoxLayoutAlgorithm::PerformMeasureSelfWithChildList(
}
frameSize.UpdateIllegalSizeWithCheck(SizeF { 0.0f, 0.0f });
} while (false);
auto pipeline = OHOS::Ace::PipelineBase::GetCurrentContext();
if (pipeline && pipeline->GetIsAppWindow() && pipeline->GetIsLayoutFullScreen()) {
auto layoutProperty = layoutWrapper->GetLayoutProperty();
if (layoutProperty) {
auto safeArea = layoutProperty->GetSafeArea();
frameSize.UpdateSizeWithCheck(
SizeF { frameSize.Width().value() - safeArea.leftRect_.Width() - safeArea.rightRect_.Width(),
frameSize.Height().value() - safeArea.topRect_.Height() - safeArea.bottomRect_.Height() });
}
}
layoutWrapper->GetGeometryNode()->SetFrameSize(frameSize.ConvertToSizeT());
}
@ -157,9 +185,22 @@ void BoxLayoutAlgorithm::PerformLayout(LayoutWrapper* layoutWrapper)
align = layoutWrapper->GetLayoutProperty()->GetPositionProperty()->GetAlignment().value_or(align);
}
// Update child position.
auto pipeline = OHOS::Ace::PipelineBase::GetCurrentContext();
for (const auto& child : layoutWrapper->GetAllChildrenWithBuild()) {
auto translate =
Alignment::GetAlignPosition(size, child->GetGeometryNode()->GetMarginFrameSize(), align) + paddingOffset;
SizeF childSize = child->GetGeometryNode()->GetMarginFrameSize();
auto layoutProperty = child->GetLayoutProperty();
SafeAreaEdgeInserts safeArea;
if (layoutProperty) {
safeArea = layoutProperty->GetSafeArea();
}
if (pipeline && pipeline->GetIsAppWindow() && pipeline->GetIsLayoutFullScreen()) {
childSize += SizeF { safeArea.leftRect_.Width() + safeArea.rightRect_.Width(),
safeArea.topRect_.Height() + safeArea.bottomRect_.Height() };
}
auto translate = Alignment::GetAlignPosition(size, childSize, align) + paddingOffset;
if (pipeline && pipeline->GetIsAppWindow() && pipeline->GetIsLayoutFullScreen()) {
translate += OffsetF { safeArea.leftRect_.Width(), safeArea.topRect_.Height() };
}
child->GetGeometryNode()->SetMarginFrameOffset(translate);
}
// Update content position.

View File

@ -146,6 +146,7 @@ void LayoutProperty::UpdateLayoutProperty(const LayoutProperty* layoutProperty)
measureType_ = layoutProperty->measureType_;
layoutDirection_ = layoutProperty->layoutDirection_;
propertyChangeFlag_ = layoutProperty->propertyChangeFlag_;
safeArea_ = layoutProperty->safeArea_;
#ifdef ENABLE_DRAG_FRAMEWORK
propIsBindOverlay_ = layoutProperty->propIsBindOverlay_;
#endif // ENABLE_DRAG_FRAMEWORK

View File

@ -50,6 +50,7 @@ class ACE_EXPORT LayoutProperty : public Property {
DECLARE_ACE_TYPE(LayoutProperty, Property);
public:
LayoutProperty() = default;
~LayoutProperty() override = default;
@ -371,6 +372,16 @@ public:
(layoutProperty->gridProperty_) ? std::make_unique<GridProperty>(*layoutProperty->gridProperty_) : nullptr;
}
SafeAreaEdgeInserts GetSafeArea() const
{
return safeArea_;
}
void SetSafeArea(SafeAreaEdgeInserts safeArea)
{
safeArea_ = safeArea;
}
protected:
void UpdateLayoutProperty(const LayoutProperty* layoutProperty);
@ -402,6 +413,7 @@ private:
WeakPtr<FrameNode> host_;
SafeAreaEdgeInserts safeArea_;
ACE_DISALLOW_COPY_AND_MOVE(LayoutProperty);
};
} // namespace OHOS::Ace::NG

View File

@ -375,6 +375,11 @@ void StageManager::FirePageShow(const RefPtr<UINode>& node, PageTransitionType t
CHECK_NULL_VOID(pageNode);
auto pagePattern = pageNode->GetPattern<PagePattern>();
CHECK_NULL_VOID(pagePattern);
auto layoutProperty = pageNode->GetLayoutProperty();
auto pipeline = PipelineBase::GetCurrentContext();
if (pipeline && !pipeline->GetIgnoreViewSafeArea() && layoutProperty) {
layoutProperty->SetSafeArea(pipeline->GetCurrentViewSafeArea());
}
pagePattern->OnShow();
// With or without a page transition, we need to make the coming page visible first
pagePattern->ProcessShowState();

View File

@ -693,6 +693,10 @@ public:
Rect GetCurrentWindowRect() const;
virtual void SetGetViewSafeAreaImpl(std::function<SafeAreaEdgeInserts()>&& callback) = 0;
virtual SafeAreaEdgeInserts GetCurrentViewSafeArea() const = 0;
void SetPluginOffset(const Offset& offset)
{
pluginOffset_ = offset;
@ -788,6 +792,36 @@ public:
void RemoveFormVsyncCallback(int32_t formWindowId);
void SetIsLayoutFullScreen(bool isLayoutFullScreen)
{
isLayoutFullScreen_ = isLayoutFullScreen;
}
bool GetIsLayoutFullScreen() const
{
return isLayoutFullScreen_;
}
void SetIsAppWindow(bool isAppWindow)
{
isAppWindow_ = isAppWindow;
}
bool GetIsAppWindow() const
{
return isAppWindow_;
}
void SetIgnoreViewSafeArea(bool ignoreViewSafeArea)
{
ignoreViewSafeArea_ = ignoreViewSafeArea;
}
bool GetIgnoreViewSafeArea() const
{
return ignoreViewSafeArea_;
}
protected:
void TryCallNextFrameLayoutCallback()
{
@ -818,6 +852,9 @@ protected:
bool isFormRender_ = false;
bool isRightToLeft_ = false;
bool isFullWindow_ = false;
bool isLayoutFullScreen_ = false;
bool isAppWindow_ = true;
bool ignoreViewSafeArea_ = false;
bool installationFree_ = false;
bool isSubPipeline_ = false;

View File

@ -295,6 +295,10 @@ public:
Rect GetStageRect() const;
Rect GetPageRect() const;
void SetGetViewSafeAreaImpl(std::function<SafeAreaEdgeInserts()>&& callback) override {};
SafeAreaEdgeInserts GetCurrentViewSafeArea() const override { return SafeAreaEdgeInserts(); };
bool IsSurfaceReady() const
{
return isSurfaceReady_;

View File

@ -27,6 +27,7 @@
#endif
#include "base/geometry/ng/offset_t.h"
#include "base/geometry/ng/rect_t.h"
#include "base/log/ace_trace.h"
#include "base/log/ace_tracker.h"
#include "base/log/dump_log.h"
@ -622,6 +623,21 @@ void PipelineContext::SetRootRect(double width, double height, double offset)
}
}
void PipelineContext::SetGetViewSafeAreaImpl(std::function<SafeAreaEdgeInserts()>&& callback)
{
if (window_) {
window_->SetGetViewSafeAreaImpl(std::move(callback));
}
}
SafeAreaEdgeInserts PipelineContext::GetCurrentViewSafeArea() const
{
if (window_) {
return window_->GetCurrentViewSafeArea();
}
return {};
}
void PipelineContext::OnVirtualKeyboardHeightChange(float keyboardHeight)
{
CHECK_RUN_ON(UI);

View File

@ -21,6 +21,7 @@
#include <list>
#include <utility>
#include "base/geometry/ng/rect_t.h"
#include "base/log/frame_info.h"
#include "base/memory/referenced.h"
#include "core/common/frontend.h"
@ -185,6 +186,10 @@ public:
void SetRootRect(double width, double height, double offset) override;
void SetGetViewSafeAreaImpl(std::function<SafeAreaEdgeInserts()>&& callback) override;
SafeAreaEdgeInserts GetCurrentViewSafeArea() const override;
const RefPtr<FullScreenManager>& GetFullScreenManager();
const RefPtr<StageManager>& GetStageManager();

View File

@ -105,6 +105,13 @@ void PipelineContext::OnSurfaceDensityChanged(double density) {}
void PipelineContext::SetRootRect(double width, double height, double offset) {}
void PipelineContext::SetGetViewSafeAreaImpl(std::function<SafeAreaEdgeInserts()>&& callback) {}
SafeAreaEdgeInserts PipelineContext::GetCurrentViewSafeArea() const
{
return {};
}
void PipelineContext::FlushBuild() {}
void PipelineContext::NotifyMemoryLevel(int32_t level) {}

View File

@ -87,6 +87,8 @@ public:
MOCK_CONST_METHOD1(OnDumpInfo, bool(const std::vector<std::string>& params));
MOCK_METHOD2(FlushVsync, void(uint64_t nanoTimestamp, uint32_t frameCount));
MOCK_METHOD3(SetRootRect, void(double width, double height, double offset));
MOCK_METHOD1(SetGetViewSafeAreaImpl, void(std::function<SafeAreaEdgeInserts()>&& callback));
MOCK_CONST_METHOD0(GetCurrentViewSafeArea, SafeAreaEdgeInserts());
MOCK_METHOD0(FlushPipelineWithoutAnimation, void());
MOCK_METHOD0(FlushPipelineImmediately, void());
MOCK_METHOD1(OnVirtualKeyboardHeightChange, void(float keyboardHeight));

View File

@ -104,6 +104,7 @@ public:
const std::shared_ptr<OHOS::Rosen::RSTransaction> rsTransaction = nullptr) = 0;
virtual void UpdateWindowMode(OHOS::Rosen::WindowMode mode, bool hasDeco = true) = 0;
virtual void HideWindowTitleButton(bool hideSplit, bool hideMaximize, bool hideMinimize) = 0;
virtual void SetIgnoreViewSafeArea(bool ignoreViewSafeArea) = 0;
// Window color
virtual uint32_t GetBackgroundColor() = 0;

View File

@ -66,6 +66,7 @@ public:
const std::shared_ptr<OHOS::Rosen::RSTransaction> rsTransaction));
MOCK_METHOD2(UpdateWindowMode, void(OHOS::Rosen::WindowMode mode, bool hasDeco));
MOCK_METHOD3(HideWindowTitleButton, void(bool hideSplit, bool hideMaximize, bool hideMinimize));
MOCK_METHOD1(SetIgnoreViewSafeArea, void(bool ignoreViewSafeArea));
MOCK_METHOD0(GetBackgroundColor, uint32_t());
MOCK_METHOD1(SetBackgroundColor, void(uint32_t color));
MOCK_METHOD2(DumpInfo, void(const std::vector<std::string>& params, std::vector<std::string>& info));