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