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