1 /*
2  * Copyright (c) 2023 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 
16 #include "core/components_ng/base/observer_handler.h"
17 
18 #include "base/utils/utils.h"
19 #include "core/components_ng/pattern/navrouter/navdestination_pattern.h"
20 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
21 
22 namespace OHOS::Ace::NG {
23 namespace {
GetNavigationId(const RefPtr<NavDestinationPattern> & pattern)24 std::string GetNavigationId(const RefPtr<NavDestinationPattern>& pattern)
25 {
26     CHECK_NULL_RETURN(pattern, "");
27     return pattern->GetNavigationId();
28 }
29 } // namespace
30 
GetInstance()31 UIObserverHandler& UIObserverHandler::GetInstance()
32 {
33     static UIObserverHandler instance;
34     return instance;
35 }
36 
NotifyNavigationStateChange(const WeakPtr<AceType> & weakPattern,NavDestinationState state)37 void UIObserverHandler::NotifyNavigationStateChange(const WeakPtr<AceType>& weakPattern, NavDestinationState state)
38 {
39     CHECK_NULL_VOID(navigationHandleFunc_);
40     auto ref = weakPattern.Upgrade();
41     CHECK_NULL_VOID(ref);
42     auto pattern = AceType::DynamicCast<NavDestinationPattern>(ref);
43     CHECK_NULL_VOID(pattern);
44     auto context = pattern->GetNavDestinationContext();
45     CHECK_NULL_VOID(context);
46     auto pathInfo = pattern->GetNavPathInfo();
47     CHECK_NULL_VOID(pathInfo);
48     if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
49         if (state == NavDestinationState::ON_SHOWN || state == NavDestinationState::ON_HIDDEN) {
50             NavDestinationInfo info(GetNavigationId(pattern), pattern->GetName(), state);
51             navigationHandleFunc_(info);
52         }
53         return;
54     }
55     NavDestinationInfo info(GetNavigationId(pattern), pattern->GetName(), state, context->GetIndex(),
56         pathInfo->GetParamObj(), std::to_string(pattern->GetNavDestinationId()));
57     navigationHandleFunc_(info);
58 }
59 
NotifyScrollEventStateChange(const WeakPtr<AceType> & weakPattern,ScrollEventType eventType)60 void UIObserverHandler::NotifyScrollEventStateChange(const WeakPtr<AceType>& weakPattern, ScrollEventType eventType)
61 {
62     auto ref = weakPattern.Upgrade();
63     CHECK_NULL_VOID(ref);
64     auto pattern = AceType::DynamicCast<ScrollablePattern>(ref);
65     CHECK_NULL_VOID(pattern);
66     auto host = pattern->GetHost();
67     CHECK_NULL_VOID(host);
68     if (eventType == ScrollEventType::SCROLL_START) {
69         host->AddFrameNodeChangeInfoFlag(FRAME_NODE_CHANGE_START_SCROLL);
70     } else if (eventType == ScrollEventType::SCROLL_STOP) {
71         host->AddFrameNodeChangeInfoFlag(FRAME_NODE_CHANGE_END_SCROLL);
72     }
73     std::string id = host->GetInspectorId().value_or("");
74     int32_t uniqueId = host->GetId();
75     float offset = pattern->GetTotalOffset();
76     CHECK_NULL_VOID(scrollEventHandleFunc_);
77     scrollEventHandleFunc_(id, uniqueId, eventType, offset);
78 }
79 
NotifyRouterPageStateChange(const RefPtr<PageInfo> & pageInfo,RouterPageState state)80 void UIObserverHandler::NotifyRouterPageStateChange(const RefPtr<PageInfo>& pageInfo, RouterPageState state)
81 {
82     CHECK_NULL_VOID(pageInfo);
83     CHECK_NULL_VOID(routerPageHandleFunc_);
84     napi_value context = GetUIContextValue();
85     AbilityContextInfo info = {
86         AceApplicationInfo::GetInstance().GetAbilityName(),
87         AceApplicationInfo::GetInstance().GetProcessName(),
88         Container::Current()->GetModuleName()
89     };
90     int32_t index = pageInfo->GetPageIndex();
91     std::string name = pageInfo->GetPageUrl();
92     std::string path = pageInfo->GetPagePath();
93     std::string pageId = std::to_string(pageInfo->GetPageId());
94     RouterPageInfoNG routerPageInfo(context, index, name, path, state, pageId);
95     routerPageHandleFunc_(info, routerPageInfo);
96 }
97 
NotifyDensityChange(double density)98 void UIObserverHandler::NotifyDensityChange(double density)
99 {
100     CHECK_NULL_VOID(densityHandleFunc_);
101     AbilityContextInfo info = {
102         AceApplicationInfo::GetInstance().GetAbilityName(),
103         AceApplicationInfo::GetInstance().GetProcessName(),
104         Container::Current()->GetModuleName()
105     };
106     densityHandleFunc_(info, density);
107 }
108 
NotifyWillClick(const GestureEvent & gestureEventInfo,const ClickInfo & clickInfo,const RefPtr<FrameNode> & frameNode)109 void UIObserverHandler::NotifyWillClick(
110     const GestureEvent& gestureEventInfo, const ClickInfo& clickInfo, const RefPtr<FrameNode>& frameNode)
111 {
112     CHECK_NULL_VOID(frameNode);
113     CHECK_NULL_VOID(willClickHandleFunc_);
114     AbilityContextInfo info = {
115         AceApplicationInfo::GetInstance().GetAbilityName(),
116         AceApplicationInfo::GetInstance().GetProcessName(),
117         Container::Current()->GetModuleName()
118     };
119     willClickHandleFunc_(info, gestureEventInfo, clickInfo, frameNode);
120 }
121 
NotifyDidClick(const GestureEvent & gestureEventInfo,const ClickInfo & clickInfo,const RefPtr<FrameNode> & frameNode)122 void UIObserverHandler::NotifyDidClick(
123     const GestureEvent& gestureEventInfo, const ClickInfo& clickInfo, const RefPtr<FrameNode>& frameNode)
124 {
125     CHECK_NULL_VOID(frameNode);
126     CHECK_NULL_VOID(didClickHandleFunc_);
127     AbilityContextInfo info = {
128         AceApplicationInfo::GetInstance().GetAbilityName(),
129         AceApplicationInfo::GetInstance().GetProcessName(),
130         Container::Current()->GetModuleName()
131     };
132     didClickHandleFunc_(info, gestureEventInfo, clickInfo, frameNode);
133 }
134 
NotifyTabContentStateUpdate(const TabContentInfo & info)135 void UIObserverHandler::NotifyTabContentStateUpdate(const TabContentInfo& info)
136 {
137     CHECK_NULL_VOID(tabContentStateHandleFunc_);
138     tabContentStateHandleFunc_(info);
139 }
140 
GetHandleNavDestinationSwitchFunc()141 UIObserverHandler::NavDestinationSwitchHandleFunc UIObserverHandler::GetHandleNavDestinationSwitchFunc()
142 {
143     return navDestinationSwitchHandleFunc_;
144 }
145 
GetNavigationState(const RefPtr<AceType> & node)146 std::shared_ptr<NavDestinationInfo> UIObserverHandler::GetNavigationState(const RefPtr<AceType>& node)
147 {
148     CHECK_NULL_RETURN(node, nullptr);
149     auto current = AceType::DynamicCast<UINode>(node);
150     while (current) {
151         if (current->GetTag() == V2::NAVDESTINATION_VIEW_ETS_TAG) {
152             break;
153         }
154         current = current->GetParent();
155     }
156     CHECK_NULL_RETURN(current, nullptr);
157     auto nav = AceType::DynamicCast<FrameNode>(current);
158     CHECK_NULL_RETURN(nav, nullptr);
159     auto pattern = nav->GetPattern<NavDestinationPattern>();
160     CHECK_NULL_RETURN(pattern, nullptr);
161     auto host = AceType::DynamicCast<NavDestinationGroupNode>(pattern->GetHost());
162     CHECK_NULL_RETURN(host, nullptr);
163     auto pathInfo = pattern->GetNavPathInfo();
164     CHECK_NULL_RETURN(pathInfo, nullptr);
165     NavDestinationState state = NavDestinationState::NONE;
166     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
167         state = pattern->GetNavDestinationState();
168         if (state == NavDestinationState::NONE) {
169             return nullptr;
170         }
171     } else {
172         state = pattern->GetIsOnShow() ? NavDestinationState::ON_SHOWN : NavDestinationState::ON_HIDDEN;
173     }
174     return std::make_shared<NavDestinationInfo>(
175         GetNavigationId(pattern), pattern->GetName(),
176         state, host->GetIndex(), pathInfo->GetParamObj(), std::to_string(pattern->GetNavDestinationId()));
177 }
178 
GetScrollEventState(const RefPtr<AceType> & node)179 std::shared_ptr<ScrollEventInfo> UIObserverHandler::GetScrollEventState(const RefPtr<AceType>& node)
180 {
181     CHECK_NULL_RETURN(node, nullptr);
182     auto current = AceType::DynamicCast<UINode>(node);
183     while (current) {
184         if (current->GetTag() == V2::SCROLL_ETS_TAG) {
185             break;
186         }
187         current = current->GetParent();
188     }
189     CHECK_NULL_RETURN(current, nullptr);
190     auto nav = AceType::DynamicCast<FrameNode>(current);
191     CHECK_NULL_RETURN(nav, nullptr);
192     std::string id = nav->GetInspectorId().value_or("");
193     int32_t uniqueId = nav->GetId();
194     auto pattern = nav->GetPattern<ScrollablePattern>();
195     CHECK_NULL_RETURN(pattern, nullptr);
196     return std::make_shared<ScrollEventInfo>(
197         id,
198         uniqueId,
199         ScrollEventType::SCROLL_START,
200         pattern->GetTotalOffset());
201 }
202 
GetRouterPageState(const RefPtr<AceType> & node)203 std::shared_ptr<RouterPageInfoNG> UIObserverHandler::GetRouterPageState(const RefPtr<AceType>& node)
204 {
205     CHECK_NULL_RETURN(node, nullptr);
206     auto current = AceType::DynamicCast<UINode>(node);
207     while (current) {
208         if (current->GetTag() == V2::PAGE_ETS_TAG) {
209             break;
210         }
211         current = current->GetParent();
212     }
213     CHECK_NULL_RETURN(current, nullptr);
214     auto routerPage = AceType::DynamicCast<FrameNode>(current);
215     CHECK_NULL_RETURN(routerPage, nullptr);
216     auto pattern = routerPage->GetPattern<PagePattern>();
217     CHECK_NULL_RETURN(pattern, nullptr);
218     auto pageInfo = pattern->GetPageInfo();
219     int32_t index = pageInfo->GetPageIndex();
220     std::string name = pageInfo->GetPageUrl();
221     std::string path = pageInfo->GetPagePath();
222     std::string pageId = std::to_string(pageInfo->GetPageId());
223     return std::make_shared<RouterPageInfoNG>(
224         GetUIContextValue(),
225         index,
226         name,
227         path,
228         RouterPageState(pattern->GetPageState()),
229         pageId);
230 }
231 
HandleDrawCommandSendCallBack()232 void UIObserverHandler::HandleDrawCommandSendCallBack()
233 {
234     CHECK_NULL_VOID(drawCommandSendHandleFunc_);
235     ACE_LAYOUT_SCOPED_TRACE("drawCommandSend");
236     drawCommandSendHandleFunc_();
237 }
238 
HandleLayoutDoneCallBack()239 void UIObserverHandler::HandleLayoutDoneCallBack()
240 {
241     CHECK_NULL_VOID(layoutDoneHandleFunc_);
242     ACE_LAYOUT_SCOPED_TRACE("layoutDone");
243     layoutDoneHandleFunc_();
244 }
245 
NotifyNavDestinationSwitch(std::optional<NavDestinationInfo> && from,std::optional<NavDestinationInfo> && to,NavigationOperation operation)246 void UIObserverHandler::NotifyNavDestinationSwitch(std::optional<NavDestinationInfo>&& from,
247     std::optional<NavDestinationInfo>&& to, NavigationOperation operation)
248 {
249     CHECK_NULL_VOID(navDestinationSwitchHandleFunc_);
250     AbilityContextInfo info = {
251         AceApplicationInfo::GetInstance().GetAbilityName(),
252         AceApplicationInfo::GetInstance().GetProcessName(),
253         Container::Current()->GetModuleName()
254     };
255     NavDestinationSwitchInfo switchInfo(GetUIContextValue(), std::forward<std::optional<NavDestinationInfo>>(from),
256         std::forward<std::optional<NavDestinationInfo>>(to), operation);
257     navDestinationSwitchHandleFunc_(info, switchInfo);
258 }
259 
SetHandleNavigationChangeFunc(NavigationHandleFunc func)260 void UIObserverHandler::SetHandleNavigationChangeFunc(NavigationHandleFunc func)
261 {
262     navigationHandleFunc_ = func;
263 }
264 
SetHandleScrollEventChangeFunc(ScrollEventHandleFunc func)265 void UIObserverHandler::SetHandleScrollEventChangeFunc(ScrollEventHandleFunc func)
266 {
267     scrollEventHandleFunc_ = func;
268 }
269 
SetHandleRouterPageChangeFunc(RouterPageHandleFunc func)270 void UIObserverHandler::SetHandleRouterPageChangeFunc(RouterPageHandleFunc func)
271 {
272     routerPageHandleFunc_ = func;
273 }
274 
SetHandleDensityChangeFunc(DensityHandleFunc func)275 void UIObserverHandler::SetHandleDensityChangeFunc(DensityHandleFunc func)
276 {
277     densityHandleFunc_ = func;
278 }
279 
SetDrawCommandSendHandleFunc(DrawCommandSendHandleFunc func)280 void UIObserverHandler::SetDrawCommandSendHandleFunc(DrawCommandSendHandleFunc func)
281 {
282     drawCommandSendHandleFunc_ = func;
283 }
284 
SetLayoutDoneHandleFunc(LayoutDoneHandleFunc func)285 void UIObserverHandler::SetLayoutDoneHandleFunc(LayoutDoneHandleFunc func)
286 {
287     layoutDoneHandleFunc_ = func;
288 }
289 
SetHandleNavDestinationSwitchFunc(NavDestinationSwitchHandleFunc func)290 void UIObserverHandler::SetHandleNavDestinationSwitchFunc(NavDestinationSwitchHandleFunc func)
291 {
292     navDestinationSwitchHandleFunc_ = func;
293 }
294 
SetWillClickFunc(WillClickHandleFunc func)295 void UIObserverHandler::SetWillClickFunc(WillClickHandleFunc func)
296 {
297     willClickHandleFunc_ = func;
298 }
299 
SetDidClickFunc(DidClickHandleFunc func)300 void UIObserverHandler::SetDidClickFunc(DidClickHandleFunc func)
301 {
302     didClickHandleFunc_ = func;
303 }
304 
SetHandleTabContentStateUpdateFunc(TabContentStateHandleFunc func)305 void UIObserverHandler::SetHandleTabContentStateUpdateFunc(TabContentStateHandleFunc func)
306 {
307     tabContentStateHandleFunc_ = func;
308 }
309 
GetUIContextValue()310 napi_value UIObserverHandler::GetUIContextValue()
311 {
312     auto container = Container::Current();
313     CHECK_NULL_RETURN(container, nullptr);
314     auto frontend = container->GetFrontend();
315     CHECK_NULL_RETURN(frontend, nullptr);
316     return frontend->GetContextValue();
317 }
318 } // namespace OHOS::Ace::NG
319