• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "core/components_ng/pattern/navigation/navigation_pattern.h"
19 #include "core/components_ng/pattern/navigation/navigation_stack.h"
20 #include "core/components_ng/pattern/navrouter/navdestination_pattern.h"
21 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
22 
23 namespace OHOS::Ace::NG {
24 namespace {
GetNavigationId(const RefPtr<NavDestinationPattern> & pattern)25 std::string GetNavigationId(const RefPtr<NavDestinationPattern>& pattern)
26 {
27     CHECK_NULL_RETURN(pattern, "");
28     return pattern->GetNavigationId();
29 }
30 } // namespace
31 
GetInstance()32 UIObserverHandler& UIObserverHandler::GetInstance()
33 {
34     static UIObserverHandler instance;
35     return instance;
36 }
37 
NotifyNavigationStateChange(const WeakPtr<AceType> & weakPattern,NavDestinationState state)38 void UIObserverHandler::NotifyNavigationStateChange(const WeakPtr<AceType>& weakPattern, NavDestinationState state)
39 {
40     CHECK_NULL_VOID(navigationHandleFunc_);
41     auto ref = weakPattern.Upgrade();
42     CHECK_NULL_VOID(ref);
43     auto pattern = AceType::DynamicCast<NavDestinationPattern>(ref);
44     CHECK_NULL_VOID(pattern);
45     auto context = pattern->GetNavDestinationContext();
46     CHECK_NULL_VOID(context);
47     auto pathInfo = pattern->GetNavPathInfo();
48     CHECK_NULL_VOID(pathInfo);
49     auto host = AceType::DynamicCast<NavDestinationGroupNode>(pattern->GetHost());
50     CHECK_NULL_VOID(host);
51     NavDestinationMode mode = host->GetNavDestinationMode();
52     auto uniqueId = host->GetId();
53     if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
54         if (state == NavDestinationState::ON_SHOWN || state == NavDestinationState::ON_HIDDEN) {
55             NavDestinationInfo info(GetNavigationId(pattern), pattern->GetName(), state);
56             navigationHandleFunc_(info);
57         }
58         return;
59     }
60     // api 17 trigger onActive and onInactive observer
61     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_SEVENTEEN) && (
62         state == NavDestinationState::ON_ACTIVE || state == NavDestinationState::ON_INACTIVE)) {
63         return;
64     }
65     pathInfo->OpenScope();
66     NavDestinationInfo info(GetNavigationId(pattern), pattern->GetName(), state, context->GetIndex(),
67         pathInfo->GetParamObj(), std::to_string(pattern->GetNavDestinationId()), mode, uniqueId);
68     navigationHandleFunc_(info);
69     pathInfo->CloseScope();
70 }
71 
NotifyScrollEventStateChange(const WeakPtr<AceType> & weakPattern,ScrollEventType eventType)72 void UIObserverHandler::NotifyScrollEventStateChange(const WeakPtr<AceType>& weakPattern, ScrollEventType eventType)
73 {
74     auto ref = weakPattern.Upgrade();
75     CHECK_NULL_VOID(ref);
76     auto pattern = AceType::DynamicCast<ScrollablePattern>(ref);
77     CHECK_NULL_VOID(pattern);
78     auto host = pattern->GetHost();
79     CHECK_NULL_VOID(host);
80     if (eventType == ScrollEventType::SCROLL_START) {
81         host->AddFrameNodeChangeInfoFlag(FRAME_NODE_CHANGE_START_SCROLL);
82     } else if (eventType == ScrollEventType::SCROLL_STOP) {
83         host->AddFrameNodeChangeInfoFlag(FRAME_NODE_CHANGE_END_SCROLL);
84     }
85     std::string id = host->GetInspectorId().value_or("");
86     int32_t uniqueId = host->GetId();
87     float offset = pattern->GetTotalOffset();
88     CHECK_NULL_VOID(scrollEventHandleFunc_);
89     scrollEventHandleFunc_(id, uniqueId, eventType, offset);
90 }
91 
NotifyRouterPageStateChange(const RefPtr<PageInfo> & pageInfo,RouterPageState state)92 void UIObserverHandler::NotifyRouterPageStateChange(const RefPtr<PageInfo>& pageInfo, RouterPageState state)
93 {
94     CHECK_NULL_VOID(pageInfo);
95     CHECK_NULL_VOID(routerPageHandleFunc_);
96     napi_value context = GetUIContextValue();
97     AbilityContextInfo info = {
98         AceApplicationInfo::GetInstance().GetAbilityName(),
99         AceApplicationInfo::GetInstance().GetProcessName(),
100         Container::Current()->GetModuleName()
101     };
102     int32_t index = pageInfo->GetPageIndex();
103     std::string name = pageInfo->GetPageUrl();
104     std::string path = pageInfo->GetPagePath();
105     std::string pageId = std::to_string(pageInfo->GetPageId());
106     RouterPageInfoNG routerPageInfo(context, index, name, path, state, pageId);
107     routerPageHandleFunc_(info, routerPageInfo);
108 }
109 
NotifyDensityChange(double density)110 void UIObserverHandler::NotifyDensityChange(double density)
111 {
112     CHECK_NULL_VOID(densityHandleFunc_);
113     AbilityContextInfo info = {
114         AceApplicationInfo::GetInstance().GetAbilityName(),
115         AceApplicationInfo::GetInstance().GetProcessName(),
116         Container::Current()->GetModuleName()
117     };
118     densityHandleFunc_(info, density);
119 }
120 
NotifyWillClick(const GestureEvent & gestureEventInfo,const ClickInfo & clickInfo,const RefPtr<FrameNode> & frameNode)121 void UIObserverHandler::NotifyWillClick(
122     const GestureEvent& gestureEventInfo, const ClickInfo& clickInfo, const RefPtr<FrameNode>& frameNode)
123 {
124     CHECK_NULL_VOID(frameNode);
125     CHECK_NULL_VOID(willClickHandleFunc_);
126     auto container = Container::Current();
127     CHECK_NULL_VOID(container);
128     AbilityContextInfo info = {
129         AceApplicationInfo::GetInstance().GetAbilityName(),
130         AceApplicationInfo::GetInstance().GetProcessName(),
131         container->GetModuleName()
132     };
133     willClickHandleFunc_(info, gestureEventInfo, clickInfo, frameNode);
134 }
135 
NotifyDidClick(const GestureEvent & gestureEventInfo,const ClickInfo & clickInfo,const RefPtr<FrameNode> & frameNode)136 void UIObserverHandler::NotifyDidClick(
137     const GestureEvent& gestureEventInfo, const ClickInfo& clickInfo, const RefPtr<FrameNode>& frameNode)
138 {
139     CHECK_NULL_VOID(frameNode);
140     CHECK_NULL_VOID(didClickHandleFunc_);
141     auto container = Container::Current();
142     CHECK_NULL_VOID(container);
143     AbilityContextInfo info = {
144         AceApplicationInfo::GetInstance().GetAbilityName(),
145         AceApplicationInfo::GetInstance().GetProcessName(),
146         container->GetModuleName()
147     };
148     didClickHandleFunc_(info, gestureEventInfo, clickInfo, frameNode);
149 }
150 
NotifyPanGestureStateChange(const GestureEvent & gestureEventInfo,const RefPtr<PanRecognizer> & current,const RefPtr<FrameNode> & frameNode,const PanGestureInfo & panGestureInfo)151 void UIObserverHandler::NotifyPanGestureStateChange(const GestureEvent& gestureEventInfo,
152     const RefPtr<PanRecognizer>& current, const RefPtr<FrameNode>& frameNode, const PanGestureInfo& panGestureInfo)
153 {
154     CHECK_NULL_VOID(frameNode);
155     CHECK_NULL_VOID(panGestureHandleFunc_);
156     auto getCurrent = Container::Current();
157     CHECK_NULL_VOID(getCurrent);
158     AbilityContextInfo info = { AceApplicationInfo::GetInstance().GetAbilityName(),
159         AceApplicationInfo::GetInstance().GetProcessName(), getCurrent->GetModuleName() };
160 
161     panGestureHandleFunc_(info, gestureEventInfo, current, frameNode, panGestureInfo);
162 }
163 
NotifyTabContentStateUpdate(const TabContentInfo & info)164 void UIObserverHandler::NotifyTabContentStateUpdate(const TabContentInfo& info)
165 {
166     CHECK_NULL_VOID(tabContentStateHandleFunc_);
167     tabContentStateHandleFunc_(info);
168 }
169 
GetHandleNavDestinationSwitchFunc()170 UIObserverHandler::NavDestinationSwitchHandleFunc UIObserverHandler::GetHandleNavDestinationSwitchFunc()
171 {
172     return navDestinationSwitchHandleFunc_;
173 }
174 
GetNavDestinationInfo(const RefPtr<UINode> & current)175 std::shared_ptr<NavDestinationInfo> UIObserverHandler::GetNavDestinationInfo(const RefPtr<UINode>& current)
176 {
177     auto nav = AceType::DynamicCast<FrameNode>(current);
178     CHECK_NULL_RETURN(nav, nullptr);
179     auto pattern = nav->GetPattern<NavDestinationPattern>();
180     CHECK_NULL_RETURN(pattern, nullptr);
181     auto host = AceType::DynamicCast<NavDestinationGroupNode>(pattern->GetHost());
182     CHECK_NULL_RETURN(host, nullptr);
183     auto pathInfo = pattern->GetNavPathInfo();
184     CHECK_NULL_RETURN(pathInfo, nullptr);
185     NavDestinationState state = NavDestinationState::NONE;
186     NavDestinationMode mode = host->GetNavDestinationMode();
187     auto uniqueId = host->GetId();
188     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
189         state = pattern->GetNavDestinationState();
190         if (state == NavDestinationState::NONE) {
191             return nullptr;
192         }
193     } else {
194         state = pattern->GetIsOnShow() ? NavDestinationState::ON_SHOWN : NavDestinationState::ON_HIDDEN;
195     }
196     return std::make_shared<NavDestinationInfo>(
197         GetNavigationId(pattern), pattern->GetName(),
198         state, host->GetIndex(), pathInfo->GetParamObj(), std::to_string(pattern->GetNavDestinationId()),
199         mode, uniqueId);
200 }
201 
GetNavigationState(const RefPtr<AceType> & node)202 std::shared_ptr<NavDestinationInfo> UIObserverHandler::GetNavigationState(const RefPtr<AceType>& node)
203 {
204     CHECK_NULL_RETURN(node, nullptr);
205     auto current = AceType::DynamicCast<UINode>(node);
206     while (current) {
207         if (current->GetTag() == V2::NAVDESTINATION_VIEW_ETS_TAG) {
208             break;
209         }
210         current = current->GetParent();
211     }
212     CHECK_NULL_RETURN(current, nullptr);
213     return GetNavDestinationInfo(current);
214 }
215 
GetNavigationInnerState(const RefPtr<AceType> & node)216 std::shared_ptr<NavDestinationInfo> UIObserverHandler::GetNavigationInnerState(const RefPtr<AceType>& node)
217 {
218     CHECK_NULL_RETURN(node, nullptr);
219     auto current = AceType::DynamicCast<UINode>(node);
220     while (current) {
221         if (current->GetTag() == V2::NAVDESTINATION_VIEW_ETS_TAG &&
222             current->GetParent()->GetTag() == V2::NAVIGATION_CONTENT_ETS_TAG) {
223             break;
224         }
225         current = current->GetFirstChild();
226     }
227     CHECK_NULL_RETURN(current, nullptr);
228     return GetNavDestinationInfo(current);
229 }
230 
GetNavigationOuterState(const RefPtr<AceType> & node)231 std::shared_ptr<NavDestinationInfo> UIObserverHandler::GetNavigationOuterState(const RefPtr<AceType>& node)
232 {
233     CHECK_NULL_RETURN(node, nullptr);
234     auto current = AceType::DynamicCast<UINode>(node);
235     while (current) {
236         CHECK_NULL_RETURN(current->GetParent(), nullptr);
237         if (current->GetTag() == V2::NAVDESTINATION_VIEW_ETS_TAG &&
238             current->GetParent()->GetTag() == V2::NAVIGATION_CONTENT_ETS_TAG) {
239             break;
240         }
241         current = current->GetParent();
242     }
243     CHECK_NULL_RETURN(current, nullptr);
244     return GetNavDestinationInfo(current);
245 }
246 
GetScrollEventState(const RefPtr<AceType> & node)247 std::shared_ptr<ScrollEventInfo> UIObserverHandler::GetScrollEventState(const RefPtr<AceType>& node)
248 {
249     CHECK_NULL_RETURN(node, nullptr);
250     auto current = AceType::DynamicCast<UINode>(node);
251     while (current) {
252         if (current->GetTag() == V2::SCROLL_ETS_TAG) {
253             break;
254         }
255         current = current->GetParent();
256     }
257     CHECK_NULL_RETURN(current, nullptr);
258     auto nav = AceType::DynamicCast<FrameNode>(current);
259     CHECK_NULL_RETURN(nav, nullptr);
260     std::string id = nav->GetInspectorId().value_or("");
261     int32_t uniqueId = nav->GetId();
262     auto pattern = nav->GetPattern<ScrollablePattern>();
263     CHECK_NULL_RETURN(pattern, nullptr);
264     return std::make_shared<ScrollEventInfo>(
265         id,
266         uniqueId,
267         ScrollEventType::SCROLL_START,
268         pattern->GetTotalOffset());
269 }
270 
GetRouterPageState(const RefPtr<AceType> & node)271 std::shared_ptr<RouterPageInfoNG> UIObserverHandler::GetRouterPageState(const RefPtr<AceType>& node)
272 {
273     CHECK_NULL_RETURN(node, nullptr);
274     auto current = AceType::DynamicCast<UINode>(node);
275     while (current) {
276         if (current->GetTag() == V2::PAGE_ETS_TAG) {
277             break;
278         }
279         current = current->GetParent();
280     }
281     CHECK_NULL_RETURN(current, nullptr);
282     auto routerPage = AceType::DynamicCast<FrameNode>(current);
283     CHECK_NULL_RETURN(routerPage, nullptr);
284     auto pattern = routerPage->GetPattern<PagePattern>();
285     CHECK_NULL_RETURN(pattern, nullptr);
286     auto pageInfo = pattern->GetPageInfo();
287     int32_t index = pageInfo->GetPageIndex();
288     std::string name = pageInfo->GetPageUrl();
289     std::string path = pageInfo->GetPagePath();
290     std::string pageId = std::to_string(pageInfo->GetPageId());
291     return std::make_shared<RouterPageInfoNG>(
292         GetUIContextValue(),
293         index,
294         name,
295         path,
296         RouterPageState(pattern->GetPageState()),
297         pageId);
298 }
299 
HandleDrawCommandSendCallBack()300 void UIObserverHandler::HandleDrawCommandSendCallBack()
301 {
302     CHECK_NULL_VOID(drawCommandSendHandleFunc_);
303     ACE_LAYOUT_SCOPED_TRACE("drawCommandSend");
304     auto container = Container::Current();
305     CHECK_NULL_VOID(container);
306     auto taskExecutor = container->GetTaskExecutor();
307     CHECK_NULL_VOID(taskExecutor);
308     taskExecutor->PostTask(
309         [callback = drawCommandSendHandleFunc_] { callback(); },
310         TaskExecutor::TaskType::JS, "ArkUIObserverDrawCommandSend");
311 }
312 
HandleLayoutDoneCallBack()313 void UIObserverHandler::HandleLayoutDoneCallBack()
314 {
315     CHECK_NULL_VOID(layoutDoneHandleFunc_);
316     ACE_LAYOUT_SCOPED_TRACE("layoutDone");
317     layoutDoneHandleFunc_();
318 }
319 
NotifyNavDestinationSwitch(std::optional<NavDestinationInfo> && from,std::optional<NavDestinationInfo> && to,NavigationOperation operation)320 void UIObserverHandler::NotifyNavDestinationSwitch(std::optional<NavDestinationInfo>&& from,
321     std::optional<NavDestinationInfo>&& to, NavigationOperation operation)
322 {
323     CHECK_NULL_VOID(navDestinationSwitchHandleFunc_);
324     AbilityContextInfo info = {
325         AceApplicationInfo::GetInstance().GetAbilityName(),
326         AceApplicationInfo::GetInstance().GetProcessName(),
327         Container::Current()->GetModuleName()
328     };
329     NavDestinationSwitchInfo switchInfo(GetUIContextValue(), std::forward<std::optional<NavDestinationInfo>>(from),
330         std::forward<std::optional<NavDestinationInfo>>(to), operation);
331     navDestinationSwitchHandleFunc_(info, switchInfo);
332 }
333 
SetHandleNavigationChangeFunc(NavigationHandleFunc func)334 void UIObserverHandler::SetHandleNavigationChangeFunc(NavigationHandleFunc func)
335 {
336     navigationHandleFunc_ = func;
337 }
338 
SetHandleScrollEventChangeFunc(ScrollEventHandleFunc func)339 void UIObserverHandler::SetHandleScrollEventChangeFunc(ScrollEventHandleFunc func)
340 {
341     scrollEventHandleFunc_ = func;
342 }
343 
SetHandleRouterPageChangeFunc(RouterPageHandleFunc func)344 void UIObserverHandler::SetHandleRouterPageChangeFunc(RouterPageHandleFunc func)
345 {
346     routerPageHandleFunc_ = func;
347 }
348 
SetHandleDensityChangeFunc(DensityHandleFunc func)349 void UIObserverHandler::SetHandleDensityChangeFunc(DensityHandleFunc func)
350 {
351     densityHandleFunc_ = func;
352 }
353 
SetDrawCommandSendHandleFunc(DrawCommandSendHandleFunc func)354 void UIObserverHandler::SetDrawCommandSendHandleFunc(DrawCommandSendHandleFunc func)
355 {
356     drawCommandSendHandleFunc_ = func;
357 }
358 
SetLayoutDoneHandleFunc(LayoutDoneHandleFunc func)359 void UIObserverHandler::SetLayoutDoneHandleFunc(LayoutDoneHandleFunc func)
360 {
361     layoutDoneHandleFunc_ = func;
362 }
363 
SetHandleNavDestinationSwitchFunc(NavDestinationSwitchHandleFunc func)364 void UIObserverHandler::SetHandleNavDestinationSwitchFunc(NavDestinationSwitchHandleFunc func)
365 {
366     navDestinationSwitchHandleFunc_ = func;
367 }
368 
SetWillClickFunc(WillClickHandleFunc func)369 void UIObserverHandler::SetWillClickFunc(WillClickHandleFunc func)
370 {
371     willClickHandleFunc_ = func;
372 }
373 
SetDidClickFunc(DidClickHandleFunc func)374 void UIObserverHandler::SetDidClickFunc(DidClickHandleFunc func)
375 {
376     didClickHandleFunc_ = func;
377 }
378 
SetPanGestureHandleFunc(PanGestureHandleFunc func)379 void UIObserverHandler::SetPanGestureHandleFunc(PanGestureHandleFunc func)
380 {
381     panGestureHandleFunc_ = func;
382 }
383 
SetHandleTabContentStateUpdateFunc(TabContentStateHandleFunc func)384 void UIObserverHandler::SetHandleTabContentStateUpdateFunc(TabContentStateHandleFunc func)
385 {
386     tabContentStateHandleFunc_ = func;
387 }
388 
GetUIContextValue()389 napi_value UIObserverHandler::GetUIContextValue()
390 {
391     auto container = Container::Current();
392     CHECK_NULL_RETURN(container, nullptr);
393     auto frontend = container->GetFrontend();
394     CHECK_NULL_RETURN(frontend, nullptr);
395     return frontend->GetContextValue();
396 }
397 } // namespace OHOS::Ace::NG
398