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