1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "frameworks/core/components_ng/pattern/navrouter/navdestination_event_hub.h"
16 
17 #include "core/common/container.h"
18 #include "frameworks/core/components_ng/pattern/navrouter/navdestination_group_node.h"
19 #include "frameworks/core/components_ng/pattern/navrouter/navdestination_pattern.h"
20 namespace OHOS::Ace::NG {
FireOnDisappear()21 void NavDestinationEventHub::FireOnDisappear()
22 {
23     auto navDestination = AceType::DynamicCast<NavDestinationGroupNode>(GetFrameNode());
24     CHECK_NULL_VOID(navDestination);
25     if (navDestination->GetIsAnimated()) {
26         auto pattern = navDestination->GetPattern<NavDestinationPattern>();
27         CHECK_NULL_VOID(pattern);
28         state_ = NavDestinationState::ON_DISAPPEAR;
29         UIObserverHandler::GetInstance().NotifyNavigationStateChange(pattern, NavDestinationState::ON_DISAPPEAR);
30         FireDisappearCallback();
31         pattern->SetCustomNode(nullptr);
32         return;
33     }
34     auto pipelineContext = PipelineContext::GetCurrentContext();
35     CHECK_NULL_VOID(pipelineContext);
36     pipelineContext->AddAfterLayoutTask([destination = navDestination]() {
37         auto eventHub = destination->GetEventHub<NavDestinationEventHub>();
38         CHECK_NULL_VOID(eventHub);
39         auto pattern = destination->GetPattern<NavDestinationPattern>();
40         CHECK_NULL_VOID(pattern);
41         eventHub->state_ = NavDestinationState::ON_DISAPPEAR;
42         UIObserverHandler::GetInstance().NotifyNavigationStateChange(pattern, NavDestinationState::ON_DISAPPEAR);
43         eventHub->FireDisappearCallback();
44         pattern->SetCustomNode(nullptr);
45     });
46 }
47 
FireAutoSave()48 void NavDestinationEventHub::FireAutoSave()
49 {
50     auto node = GetFrameNode();
51     CHECK_NULL_VOID(node);
52     if (!node->NeedRequestAutoSave()) {
53         return;
54     }
55     auto container = Container::Current();
56     CHECK_NULL_VOID(container);
57     container->RequestAutoSave(node);
58 }
59 
FireOnShownEvent(const std::string & name,const std::string & param)60 void NavDestinationEventHub::FireOnShownEvent(const std::string& name, const std::string& param)
61 {
62     TAG_LOGI(AceLogTag::ACE_NAVIGATION, "%{public}s lifecycle change to onShown state.", name_.c_str());
63     state_= NavDestinationState::ON_SHOWN;
64     UIObserverHandler::GetInstance().NotifyNavigationStateChange(GetNavDestinationPattern(),
65         NavDestinationState::ON_SHOWN);
66     if (onShownEvent_) {
67         auto onShownEvent = onShownEvent_;
68         onShownEvent();
69     }
70     if (!onHiddenChange_.empty()) {
71         FireOnHiddenChange(true);
72     }
73     if (Recorder::EventRecorder::Get().IsPageRecordEnable()) {
74         auto host = GetFrameNode();
75         CHECK_NULL_VOID(host);
76         auto id = host->GetInspectorIdValue("");
77         Recorder::EventParamsBuilder builder;
78         builder.SetId(id)
79             .SetText(name)
80             .SetExtra(Recorder::KEY_PAGE_PARAM, param)
81             .SetDescription(host->GetAutoEventParamValue(""));
82         Recorder::EventRecorder::Get().OnNavDstShow(std::move(builder));
83     }
84 }
85 
FireOnHiddenEvent(const std::string & name)86 void NavDestinationEventHub::FireOnHiddenEvent(const std::string& name)
87 {
88     TAG_LOGI(AceLogTag::ACE_NAVIGATION, "%{public}s lifecycle chang to onHidden state.", name_.c_str());
89     state_ = NavDestinationState::ON_HIDDEN;
90     UIObserverHandler::GetInstance().NotifyNavigationStateChange(GetNavDestinationPattern(),
91         NavDestinationState::ON_HIDDEN);
92     if (onHiddenEvent_) {
93         onHiddenEvent_();
94     }
95     if (!onHiddenChange_.empty()) {
96         FireOnHiddenChange(false);
97     }
98     if (Recorder::EventRecorder::Get().IsPageRecordEnable()) {
99         auto host = GetFrameNode();
100         CHECK_NULL_VOID(host);
101         auto id = host->GetInspectorIdValue("");
102         Recorder::EventParamsBuilder builder;
103         builder.SetId(id).SetText(name).SetDescription(host->GetAutoEventParamValue(""));
104         Recorder::EventRecorder::Get().OnNavDstHide(std::move(builder));
105     }
106 }
107 
FireOnAppear()108 void NavDestinationEventHub::FireOnAppear()
109 {
110     TAG_LOGI(AceLogTag::ACE_NAVIGATION, "%{public}s lifecycle change to onAppear state.", name_.c_str());
111     auto onAppearAction = [weakEventHub = WeakClaim(this)]() {
112         auto eventHub = weakEventHub.Upgrade();
113         CHECK_NULL_VOID(eventHub);
114         eventHub->state_ = NavDestinationState::ON_APPEAR;
115         UIObserverHandler::GetInstance().NotifyNavigationStateChange(eventHub->GetNavDestinationPattern(),
116             NavDestinationState::ON_APPEAR);
117         if (eventHub->onAppear_) {
118             auto onAppear = eventHub->onAppear_;
119             onAppear();
120         }
121         if (eventHub->onJSFrameNodeAppear_) {
122             auto onJSFrameNodeAppear = eventHub->onJSFrameNodeAppear_;
123             onJSFrameNodeAppear();
124         }
125     };
126     auto navdestination = AceType::DynamicCast<NavDestinationGroupNode>(GetFrameNode());
127     // if navdestination is created from recovery, it need trigger onAppear immediately
128     if (navdestination && navdestination->NeedAppearFromRecovery()) {
129         navdestination->SetNeedAppearFromRecovery(false);
130         onAppearAction();
131         return;
132     }
133     auto pipeline = PipelineContext::GetCurrentContext();
134     CHECK_NULL_VOID(pipeline);
135     auto navigationManager = pipeline->GetNavigationManager();
136     auto navDestination = AceType::DynamicCast<NavDestinationGroupNode>(GetFrameNode());
137     CHECK_NULL_VOID(navDestination);
138     auto pattern = navDestination->GetPattern<NavDestinationPattern>();
139     CHECK_NULL_VOID(pattern);
140     if (pattern->GetNavigationNode()) {
141         navigationManager->AddNavigationUpdateCallback(std::move(onAppearAction));
142     } else {
143         EventHub::FireOnAppear();
144     }
145 }
146 
FireOnWillAppear()147 void NavDestinationEventHub::FireOnWillAppear()
148 {
149     TAG_LOGI(AceLogTag::ACE_NAVIGATION, "%{public}s lifecycle change to onWillAppear state.", name_.c_str());
150     state_ = NavDestinationState::ON_WILL_APPEAR;
151     UIObserverHandler::GetInstance().NotifyNavigationStateChange(GetNavDestinationPattern(),
152         NavDestinationState::ON_WILL_APPEAR);
153     if (onWillAppear_) {
154         onWillAppear_();
155     }
156 }
157 
FireOnWillShow()158 void NavDestinationEventHub::FireOnWillShow()
159 {
160     TAG_LOGI(AceLogTag::ACE_NAVIGATION, "%{public}s lifecycle change to onWillShow state.", name_.c_str());
161     state_ = NavDestinationState::ON_WILL_SHOW;
162     UIObserverHandler::GetInstance().NotifyNavigationStateChange(GetNavDestinationPattern(),
163         NavDestinationState::ON_WILL_SHOW);
164     if (onWillShow_) {
165         onWillShow_();
166     }
167 }
168 
FireOnWillHide()169 void NavDestinationEventHub::FireOnWillHide()
170 {
171     TAG_LOGI(AceLogTag::ACE_NAVIGATION, "%{public}s lifecycle change to onWillHide state.", name_.c_str());
172     state_ = NavDestinationState::ON_WILL_HIDE;
173     UIObserverHandler::GetInstance().NotifyNavigationStateChange(GetNavDestinationPattern(),
174         NavDestinationState::ON_WILL_HIDE);
175     if (onWillHide_) {
176         onWillHide_();
177     }
178 
179     FireAutoSave();
180 }
181 
FireOnWillDisAppear()182 void NavDestinationEventHub::FireOnWillDisAppear()
183 {
184     TAG_LOGI(AceLogTag::ACE_NAVIGATION, "%{public}s lifecycle change to onWillDisappear state.", name_.c_str());
185     state_ = NavDestinationState::ON_WILL_DISAPPEAR;
186     UIObserverHandler::GetInstance().NotifyNavigationStateChange(GetNavDestinationPattern(),
187         NavDestinationState::ON_WILL_DISAPPEAR);
188     if (onWillDisAppear_) {
189         onWillDisAppear_();
190     }
191 }
192 
FireOnBackPressedEvent()193 bool NavDestinationEventHub::FireOnBackPressedEvent()
194 {
195     if (onBackPressedEvent_) {
196         TAG_LOGI(AceLogTag::ACE_NAVIGATION, "navDestination backButton press is happening.");
197         return onBackPressedEvent_();
198     }
199     return false;
200 }
201 }