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