support router

Signed-off-by: dujingcheng <dujingcheng@huawei.com>
Change-Id: Idcad09086c52dd9666fbe0f3dd3ac7a13a412c9f
This commit is contained in:
dujingcheng 2024-07-31 06:33:03 +00:00
parent 7092078d6f
commit 961b7e32ad
6 changed files with 157 additions and 6 deletions

View File

@ -2803,9 +2803,9 @@ int32_t UIContentImpl::CreateModalUIExtension(
TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
"[%{public}s][%{public}s][%{public}d]: create modal page, "
"sessionId=%{public}d, isProhibitBack=%{public}d, isAsyncModalBinding=%{public}d, "
"isAllowedBeCovered=%{public}d",
"isAllowedBeCovered=%{public}d, prohibitedRemoveByRouter=%{public}d",
bundleName_.c_str(), moduleName_.c_str(), instanceId_, sessionId, config.isProhibitBack,
config.isAsyncModalBinding, config.isAllowedBeCovered);
config.isAsyncModalBinding, config.isAllowedBeCovered, config.prohibitedRemoveByRouter);
return sessionId;
}

View File

@ -155,6 +155,21 @@ public:
return isExecuteOnDisappear_;
}
bool IsUIExtension() const
{
return isUIExtension_;
}
void SetProhibitedRemoveByRouter(bool prohibitedRemoveByRouter)
{
prohibitedRemoveByRouter_ = prohibitedRemoveByRouter;
}
bool IsProhibitedRemoveByRouter() const
{
return prohibitedRemoveByRouter_;
}
bool AvoidKeyboard() const override
{
// If UIExtensionComponent uses ModalPage, ModalPage will avoid KeyBoard.
@ -187,6 +202,7 @@ public:
private:
void OnAttachToFrameNode() override;
bool isUIExtension_ = false;
bool prohibitedRemoveByRouter_ = false;
int32_t targetId_ = -1;
ModalTransition type_ = ModalTransition::DEFAULT;
bool hasTransitionEffect_ = false;

View File

@ -31,11 +31,13 @@ struct ModalStyle {
std::optional<ModalTransition> modalTransition;
std::optional<Color> backgroundColor;
bool isUIExtension = false;
bool prohibitedRemoveByRouter = false;
bool operator==(const ModalStyle& modelStyle) const
{
return !(modalTransition != modelStyle.modalTransition || backgroundColor != modelStyle.backgroundColor ||
isUIExtension != modelStyle.isUIExtension);
isUIExtension != modelStyle.isUIExtension ||
prohibitedRemoveByRouter != modelStyle.prohibitedRemoveByRouter);
}
};
} // namespace OHOS::Ace::NG

View File

@ -3107,6 +3107,25 @@ bool OverlayManager::RemoveModalInOverlay()
}
bool OverlayManager::RemoveAllModalInOverlay()
{
if (modalStack_.empty()) {
return true;
}
auto topModalNode = modalStack_.top().Upgrade();
bool isModalUiextensionNode = IsModalUiextensionNode(topModalNode);
bool isProhibitedRemoveByRouter = IsProhibitedRemoveByRouter(topModalNode);
TAG_LOGI(AceLogTag::ACE_OVERLAY,
"isModalUiextensionNode: %{public}d, isProhibitedRemoveByRouter: %{public}d,",
isModalUiextensionNode, isProhibitedRemoveByRouter);
if (isModalUiextensionNode && isProhibitedRemoveByRouter) {
return RemoveAllModalInOverlayByList();
}
return RemoveAllModalInOverlayByStack();
}
bool OverlayManager::RemoveAllModalInOverlayByStack()
{
while (!modalStack_.empty()) {
auto topModalNode = modalStack_.top().Upgrade();
@ -3148,6 +3167,108 @@ bool OverlayManager::RemoveAllModalInOverlay()
return true;
}
bool OverlayManager::RemoveAllModalInOverlayByList()
{
TAG_LOGI(AceLogTag::ACE_OVERLAY,
"RemoveAllModalInOverlayByList modalStack size: %{public}zu, "
"modalList size: %{public}zu", modalStack_.size(), modalList_.size());
if (modalStack_.size() != modalList_.size()) {
TAG_LOGI(AceLogTag::ACE_OVERLAY,
"Not RemoveAllModalInOverlayByList due to modalStack not same with modalList.");
return true;
}
bool ret = OnRemoveAllModalInOverlayByList();
// To keep the modalStack consistent with the modalList
AfterRemoveAllModalInOverlayByList();
return ret;
}
bool OverlayManager::OnRemoveAllModalInOverlayByList()
{
auto modalIter = modalList_.begin();
while (modalIter != modalList_.end()) {
auto topModalNode = (*modalIter).Upgrade();
if (!topModalNode) {
modalIter = modalList_.erase(modalIter);
continue;
}
if (IsModalUiextensionNode(topModalNode)) {
break;
}
auto rootNode = FindWindowScene(topModalNode);
CHECK_NULL_RETURN(rootNode, true);
auto builder = AceType::DynamicCast<FrameNode>(topModalNode->GetFirstChild());
CHECK_NULL_RETURN(builder, false);
ModalPageLostFocus(topModalNode);
if (!ModalExitProcess(topModalNode)) {
modalIter = modalList_.erase(modalIter);
continue;
}
if (topModalNode->GetTag() == V2::MODAL_PAGE_TAG) {
auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
CHECK_NULL_RETURN(modalPattern, false);
auto modalTransition = modalPattern->GetType();
if (modalTransition == ModalTransition::NONE || builder->GetRenderContext()->HasDisappearTransition()) {
// Fire shown event of navdestination under the disappeared modal
FireNavigationStateChange(true);
}
}
auto sheetPattern = topModalNode->GetPattern<SheetPresentationPattern>();
if (topModalNode->GetTag() == V2::SHEET_PAGE_TAG && sheetPattern) {
sheetMap_.erase(sheetPattern->GetSheetKey());
}
modalIter = modalList_.erase(modalIter);
}
return true;
}
void OverlayManager::AfterRemoveAllModalInOverlayByList()
{
TAG_LOGI(AceLogTag::ACE_OVERLAY,
"AfterRemoveAllModalInOverlayByList modalList size: %{public}zu", modalList_.size());
std::stack<WeakPtr<FrameNode>> modalStack;
modalStack_.swap(modalStack);
for (auto modal = modalList_.begin(); modal != modalList_.end(); ++modal) {
modalStack_.push(*modal);
}
}
bool OverlayManager::IsModalUiextensionNode(const RefPtr<FrameNode>& topModalNode)
{
if (topModalNode == nullptr) {
TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is null,");
return false;
}
if (topModalNode->GetTag() != V2::MODAL_PAGE_TAG) {
TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is not modalPage");
return false;
}
auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
CHECK_NULL_RETURN(modalPattern, false);
return modalPattern->IsUIExtension();
}
bool OverlayManager::IsProhibitedRemoveByRouter(const RefPtr<FrameNode>& topModalNode)
{
if (topModalNode == nullptr) {
TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is null,");
return false;
}
if (topModalNode->GetTag() != V2::MODAL_PAGE_TAG) {
TAG_LOGI(AceLogTag::ACE_OVERLAY, "topModalNode is not modalPage");
return false;
}
auto modalPattern = topModalNode->GetPattern<ModalPresentationPattern>();
CHECK_NULL_RETURN(modalPattern, false);
return modalPattern->IsProhibitedRemoveByRouter();
}
bool OverlayManager::ModalExitProcess(const RefPtr<FrameNode>& topModalNode)
{
auto rootNode = FindWindowScene(topModalNode);
@ -3511,6 +3632,7 @@ void OverlayManager::HandleModalShow(std::function<void(const std::string&)>&& c
modalPagePattern->UpdateOnAppear(std::move(onAppear));
modalPagePattern->UpdateOnWillDismiss(std::move(contentCoverParam.onWillDismiss));
modalPagePattern->UpdateUIExtensionMode(modalStyle.isUIExtension);
modalPagePattern->SetProhibitedRemoveByRouter(modalStyle.prohibitedRemoveByRouter);
modalPagePattern->SetHasTransitionEffect(contentCoverParam.transitionEffect != nullptr);
modalNode->GetRenderContext()->UpdateChainedTransition(contentCoverParam.transitionEffect);
modalStack_.push(WeakClaim(RawPtr(modalNode)));
@ -3520,8 +3642,9 @@ void OverlayManager::HandleModalShow(std::function<void(const std::string&)>&& c
modalNode->AddChild(builder);
if (!isAllowedBeCovered_ && modalNode->GetParent()) {
TAG_LOGI(AceLogTag::ACE_OVERLAY,
"modalNode->GetParent() %{public}d mark IsProhibitedAddChildNode when sessionId %{public}d.",
modalNode->GetParent()->GetId(), targetId);
"modalNode->GetParent() %{public}d mark IsProhibitedAddChildNode when sessionId %{public}d,"
"prohibitedRemoveByRouter: %{public}d.",
modalNode->GetParent()->GetId(), targetId, modalStyle.prohibitedRemoveByRouter);
if (AddCurSessionId(targetId)) {
modalNode->GetParent()->UpdateModalUiextensionCount(true);
}
@ -5540,6 +5663,7 @@ int32_t OverlayManager::CreateModalUIExtension(
ModalStyle modalStyle;
modalStyle.modalTransition = NG::ModalTransition::NONE;
modalStyle.isUIExtension = true;
modalStyle.prohibitedRemoveByRouter = config.prohibitedRemoveByRouter;
SetIsAllowedBeCovered(config.isAllowedBeCovered);
// Convert the sessionId into a negative number to distinguish it from the targetId of other modal pages
BindContentCover(true, nullptr, std::move(buildNodeFunc), modalStyle, nullptr, nullptr, nullptr, nullptr,
@ -5548,6 +5672,7 @@ int32_t OverlayManager::CreateModalUIExtension(
} else {
auto bindModalCallback = [weak = WeakClaim(this), buildNodeFunc, sessionId, id = Container::CurrentId(),
isAllowedBeCovered = config.isAllowedBeCovered,
prohibitedRemoveByRouter = config.prohibitedRemoveByRouter,
doAfterAsyncModalBinding = std::move(config.doAfterAsyncModalBinding)]() {
ContainerScope scope(id);
auto overlayManager = weak.Upgrade();
@ -5556,6 +5681,7 @@ int32_t OverlayManager::CreateModalUIExtension(
ModalStyle modalStyle;
modalStyle.modalTransition = NG::ModalTransition::NONE;
modalStyle.isUIExtension = true;
modalStyle.prohibitedRemoveByRouter = prohibitedRemoveByRouter;
overlayManager->BindContentCover(true, nullptr, std::move(buildNodeFunc), modalStyle, nullptr, nullptr,
nullptr, nullptr, ContentCoverParam(), nullptr, -(sessionId));
overlayManager->SetIsAllowedBeCovered(true);

View File

@ -237,6 +237,12 @@ public:
bool RemoveMenu(const RefPtr<FrameNode>& overlay);
bool RemoveModalInOverlay();
bool RemoveAllModalInOverlay();
bool RemoveAllModalInOverlayByStack();
bool RemoveAllModalInOverlayByList();
bool OnRemoveAllModalInOverlayByList();
void AfterRemoveAllModalInOverlayByList();
bool IsModalUiextensionNode(const RefPtr<FrameNode>& topModalNode);
bool IsProhibitedRemoveByRouter(const RefPtr<FrameNode>& topModalNode);
bool RemoveOverlayInSubwindow();
void RegisterOnHideDialog(std::function<void()> callback)

View File

@ -33,7 +33,8 @@ struct ModalUIExtensionConfig {
bool isProhibitBack = false;
bool isAsyncModalBinding = false;
bool isAllowedBeCovered = false;
std::function<void()> doAfterAsyncModalBinding;
std::function<void()> doAfterAsyncModalBinding = nullptr;
bool prohibitedRemoveByRouter = false;
};
struct ModalUIExtensionCallbacks {