• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_PATTERN_H
18 
19 #include <optional>
20 
21 #include "base/geometry/ng/rect_t.h"
22 #include "base/memory/ace_type.h"
23 #include "base/memory/referenced.h"
24 #include "base/utils/noncopyable.h"
25 #include "base/view_data/view_data_wrap.h"
26 #include "core/common/recorder/event_recorder.h"
27 #include "core/components_ng/base/frame_node.h"
28 #include "core/components_ng/event/event_hub.h"
29 #include "core/components_ng/layout/layout_property.h"
30 #include "core/components_ng/property/property.h"
31 #include "core/components_ng/render/node_paint_method.h"
32 #include "core/components_ng/render/paint_property.h"
33 #include "core/event/pointer_event.h"
34 
35 namespace OHOS::Accessibility {
36 class AccessibilityElementInfo;
37 class AccessibilityEventInfo;
38 }
39 
40 namespace OHOS::Ace::NG {
41 struct DirtySwapConfig {
42     bool frameSizeChange = false;
43     bool frameOffsetChange = false;
44     bool contentSizeChange = false;
45     bool contentOffsetChange = false;
46     bool skipMeasure = false;
47     bool skipLayout = false;
48 };
49 
50 class ScrollingListener : public AceType {
51     DECLARE_ACE_TYPE(ScrollingListener, AceType);
52 
53 public:
ScrollingListener(std::function<void ()> && callback)54     explicit ScrollingListener(std::function<void()>&& callback) : callback_(std::move(callback)) {}
55 
56     ~ScrollingListener() override = default;
57 
NotifyScrollingEvent()58     void NotifyScrollingEvent()
59     {
60         if (callback_) {
61             callback_();
62         }
63     }
64 
65 private:
66     std::function<void()> callback_;
67 };
68 
69 // Pattern is the base class for different measure, layout and paint behavior.
70 class Pattern : public virtual AceType {
71     DECLARE_ACE_TYPE(Pattern, AceType);
72 
73 public:
74     Pattern() = default;
75     ~Pattern() override = default;
76 
77     // atomic node is like button, image, custom node and so on.
78     // In ets UI compiler, the atomic node does not Add Pop function, only have Create function.
IsAtomicNode()79     virtual bool IsAtomicNode() const
80     {
81         return true;
82     }
83 
StopExpandMark()84     virtual bool StopExpandMark()
85     {
86         return false;
87     }
88 
89     // The pattern needs softkeyboard is like search, rich editor, text area, text field pattern.
NeedSoftKeyboard()90     virtual bool NeedSoftKeyboard() const
91     {
92         return false;
93     }
94 
DefaultSupportDrag()95     virtual bool DefaultSupportDrag()
96     {
97         return false;
98     }
99 
GetContextParam()100     virtual std::optional<RenderContext::ContextParam> GetContextParam() const
101     {
102         return std::nullopt;
103     }
104 
DetachFromFrameNode(FrameNode * frameNode)105     void DetachFromFrameNode(FrameNode* frameNode)
106     {
107         OnDetachFromFrameNode(frameNode);
108         frameNode_.Reset();
109     }
110 
AttachToFrameNode(const WeakPtr<FrameNode> & frameNode)111     void AttachToFrameNode(const WeakPtr<FrameNode>& frameNode)
112     {
113         if (frameNode_ == frameNode) {
114             return;
115         }
116         frameNode_ = frameNode;
117         OnAttachToFrameNode();
118     }
119 
CreateAccessibilityProperty()120     virtual RefPtr<AccessibilityProperty> CreateAccessibilityProperty()
121     {
122         return MakeRefPtr<AccessibilityProperty>();
123     }
124 
CreatePaintProperty()125     virtual RefPtr<PaintProperty> CreatePaintProperty()
126     {
127         return MakeRefPtr<PaintProperty>();
128     }
129 
CreateLayoutProperty()130     virtual RefPtr<LayoutProperty> CreateLayoutProperty()
131     {
132         return MakeRefPtr<LayoutProperty>();
133     }
134 
CreateLayoutAlgorithm()135     virtual RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm()
136     {
137         return MakeRefPtr<BoxLayoutAlgorithm>();
138     }
139 
CreateNodePaintMethod()140     virtual RefPtr<NodePaintMethod> CreateNodePaintMethod()
141     {
142         return nullptr;
143     }
144 
GetOverridePaintRect()145     virtual std::optional<RectF> GetOverridePaintRect() const
146     {
147         return std::nullopt;
148     }
149 
CreateEventHub()150     virtual RefPtr<EventHub> CreateEventHub()
151     {
152         return MakeRefPtr<EventHub>();
153     }
154 
OnContextAttached()155     virtual void OnContextAttached() {}
156 
OnModifyDone()157     virtual void OnModifyDone()
158     {
159 #if (defined(__aarch64__) || defined(__x86_64__))
160         FrameNode::PostTask(
161             [weak = WeakClaim(this)]() {
162                 if (Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
163                     auto pattern = weak.Upgrade();
164                     CHECK_NULL_VOID(pattern);
165                     pattern->OnAfterModifyDone();
166                 }
167             },
168             TaskExecutor::TaskType::UI);
169         if (IsNeedInitClickEventRecorder()) {
170             InitClickEventRecorder();
171         }
172 #endif
173         auto frameNode = frameNode_.Upgrade();
174         auto children = frameNode->GetChildren();
175         if (children.empty()) {
176             return;
177         }
178         auto renderContext = frameNode->GetRenderContext();
179         if (!renderContext->HasForegroundColor() && !renderContext->HasForegroundColorStrategy()) {
180             return;
181         }
182         std::list<RefPtr<FrameNode>> childrenList {};
183         std::queue<RefPtr<FrameNode>> queue {};
184         queue.emplace(frameNode);
185         RefPtr<FrameNode> parentNode;
186         while (!queue.empty()) {
187             parentNode = queue.front();
188             queue.pop();
189             auto childs = parentNode->GetChildren();
190             if (childs.empty()) {
191                 continue;
192             }
193             for (auto child : childs) {
194                 if (!AceType::InstanceOf<NG::FrameNode>(child)) {
195                     continue;
196                 }
197                 auto childFrameNode = AceType::DynamicCast<FrameNode>(child);
198                 auto childRenderContext = childFrameNode->GetRenderContext();
199                 if (childRenderContext->HasForegroundColorFlag() && childRenderContext->GetForegroundColorFlagValue()) {
200                     continue;
201                 }
202                 queue.emplace(childFrameNode);
203                 childrenList.emplace_back(childFrameNode);
204             }
205         }
206         bool isForegroundColor = renderContext->HasForegroundColor();
207         for (auto child : childrenList) {
208             auto childRenderContext = child->GetRenderContext();
209             if (!childRenderContext->HasForegroundColor() && !childRenderContext->HasForegroundColorStrategy()) {
210                 if (isForegroundColor) {
211                     childRenderContext->UpdateForegroundColor(renderContext->GetForegroundColorValue());
212                     childRenderContext->ResetForegroundColorStrategy();
213                     childRenderContext->UpdateForegroundColorFlag(false);
214                 } else {
215                     childRenderContext->UpdateForegroundColorStrategy(renderContext->GetForegroundColorStrategyValue());
216                     childRenderContext->ResetForegroundColor();
217                     childRenderContext->UpdateForegroundColorFlag(false);
218                 }
219             } else {
220                 if (!childRenderContext->HasForegroundColorFlag()) {
221                     continue;
222                 }
223                 if (childRenderContext->GetForegroundColorFlagValue()) {
224                     continue;
225                 }
226                 if (isForegroundColor) {
227                     childRenderContext->UpdateForegroundColor(renderContext->GetForegroundColorValue());
228                     childRenderContext->ResetForegroundColorStrategy();
229                     childRenderContext->UpdateForegroundColorFlag(false);
230                 } else {
231                     childRenderContext->UpdateForegroundColorStrategy(renderContext->GetForegroundColorStrategyValue());
232                     childRenderContext->ResetForegroundColor();
233                     childRenderContext->UpdateForegroundColorFlag(false);
234                 }
235             }
236         }
237     }
238 
OnAfterModifyDone()239     virtual void OnAfterModifyDone() {}
240 
OnMountToParentDone()241     virtual void OnMountToParentDone() {}
242 
IsRootPattern()243     virtual bool IsRootPattern() const
244     {
245         return false;
246     }
247 
IsMeasureBoundary()248     virtual bool IsMeasureBoundary() const
249     {
250         return false;
251     }
252 
IsRenderBoundary()253     virtual bool IsRenderBoundary() const
254     {
255         return true;
256     }
257 
UpdateScrollOffset(SizeF)258     virtual void UpdateScrollOffset(SizeF /* frameSize */) {}
259 
260     // TODO: for temp use, need to delete this.
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> &,bool,bool)261     virtual bool OnDirtyLayoutWrapperSwap(
262         const RefPtr<LayoutWrapper>& /*dirty*/, bool /*skipMeasure*/, bool /*skipLayout*/)
263     {
264         return false;
265     }
266 
267     // Called on main thread to check if need rerender of the content.
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> &,const DirtySwapConfig &)268     virtual bool OnDirtyLayoutWrapperSwap(
269         const RefPtr<LayoutWrapper>& /*dirty*/, const DirtySwapConfig& /*changeConfig*/)
270     {
271         return false;
272     }
273 
UsResRegion()274     virtual bool UsResRegion()
275     {
276         return true;
277     }
278 
GetHostFrameSize()279     std::optional<SizeF> GetHostFrameSize() const
280     {
281         auto frameNode = frameNode_.Upgrade();
282         if (!frameNode) {
283             return std::nullopt;
284         }
285         return frameNode->GetGeometryNode()->GetMarginFrameSize();
286     }
287 
GetHostFrameOffset()288     std::optional<OffsetF> GetHostFrameOffset() const
289     {
290         auto frameNode = frameNode_.Upgrade();
291         if (!frameNode) {
292             return std::nullopt;
293         }
294         return frameNode->GetGeometryNode()->GetFrameOffset();
295     }
296 
GetHostFrameGlobalOffset()297     std::optional<OffsetF> GetHostFrameGlobalOffset() const
298     {
299         auto frameNode = frameNode_.Upgrade();
300         if (!frameNode) {
301             return std::nullopt;
302         }
303         return frameNode->GetGeometryNode()->GetFrameOffset() + frameNode->GetGeometryNode()->GetParentGlobalOffset();
304     }
305 
GetHostContentSize()306     std::optional<SizeF> GetHostContentSize() const
307     {
308         auto frameNode = frameNode_.Upgrade();
309         if (!frameNode) {
310             return std::nullopt;
311         }
312         const auto& content = frameNode->GetGeometryNode()->GetContent();
313         if (!content) {
314             return std::nullopt;
315         }
316         return content->GetRect().GetSize();
317     }
318 
GetHost()319     RefPtr<FrameNode> GetHost() const
320     {
321         return frameNode_.Upgrade();
322     }
323 
DumpInfo()324     virtual void DumpInfo() {}
DumpAdvanceInfo()325     virtual void DumpAdvanceInfo() {}
DumpViewDataPageNode(RefPtr<ViewDataWrap> viewDataWrap)326     virtual void DumpViewDataPageNode(RefPtr<ViewDataWrap> viewDataWrap) {}
NotifyFillRequestSuccess(RefPtr<PageNodeInfoWrap> nodeWrap,AceAutoFillType autoFillType)327     virtual void NotifyFillRequestSuccess(RefPtr<PageNodeInfoWrap> nodeWrap, AceAutoFillType autoFillType) {}
NotifyFillRequestFailed(int32_t errCode)328     virtual void NotifyFillRequestFailed(int32_t errCode) {}
CheckAutoSave()329     virtual bool CheckAutoSave()
330     {
331         return false;
332     }
333 
334     template<typename T>
GetLayoutProperty()335     RefPtr<T> GetLayoutProperty() const
336     {
337         auto host = GetHost();
338         CHECK_NULL_RETURN(host, nullptr);
339         return DynamicCast<T>(host->GetLayoutProperty<T>());
340     }
341 
342     template<typename T>
GetPaintProperty()343     RefPtr<T> GetPaintProperty() const
344     {
345         auto host = GetHost();
346         CHECK_NULL_RETURN(host, nullptr);
347         return DynamicCast<T>(host->GetPaintProperty<T>());
348     }
349 
350     template<typename T>
GetEventHub()351     RefPtr<T> GetEventHub() const
352     {
353         auto host = GetHost();
354         CHECK_NULL_RETURN(host, nullptr);
355         return DynamicCast<T>(host->GetEventHub<T>());
356     }
357 
358     // Called after frameNode RebuildRenderContextTree.
OnRebuildFrame()359     virtual void OnRebuildFrame() {}
360     // Called before frameNode CreateLayoutWrapper.
BeforeCreateLayoutWrapper()361     virtual void BeforeCreateLayoutWrapper() {}
362     // Called before frameNode CreatePaintWrapper.
BeforeCreatePaintWrapper()363     virtual void BeforeCreatePaintWrapper() {}
364 
GetFocusPattern()365     virtual FocusPattern GetFocusPattern() const
366     {
367         return { FocusType::DISABLE, false, FocusStyleType::NONE };
368     }
369 
GetScopeFocusAlgorithm()370     virtual ScopeFocusAlgorithm GetScopeFocusAlgorithm()
371     {
372         return ScopeFocusAlgorithm();
373     }
374 
ScrollToNode(const RefPtr<FrameNode> & focusFrameNode)375     virtual bool ScrollToNode(const RefPtr<FrameNode>& focusFrameNode)
376     {
377         return false;
378     }
379 
GetFocusNodeIndex(const RefPtr<FocusHub> & focusNode)380     virtual int32_t GetFocusNodeIndex(const RefPtr<FocusHub>& focusNode)
381     {
382         return -1;
383     }
384 
ScrollToFocusNodeIndex(int32_t index)385     virtual void ScrollToFocusNodeIndex(int32_t index) {}
386 
387     // out of viewport or visible is none or gone.
OnInActive()388     virtual void OnInActive() {}
OnActive()389     virtual void OnActive() {}
390 
391     // called by window life cycle.
OnWindowShow()392     virtual void OnWindowShow() {}
OnWindowHide()393     virtual void OnWindowHide() {}
OnWindowFocused()394     virtual void OnWindowFocused() {}
OnWindowUnfocused()395     virtual void OnWindowUnfocused() {}
OnPixelRoundFinish(const SizeF & pixelGridRoundSize)396     virtual void OnPixelRoundFinish(const SizeF& pixelGridRoundSize) {}
OnWindowSizeChanged(int32_t width,int32_t height,WindowSizeChangeReason type)397     virtual void OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type) {}
OnNotifyMemoryLevel(int32_t level)398     virtual void OnNotifyMemoryLevel(int32_t level) {}
399 
400     // get XTS inspector value
ToJsonValue(std::unique_ptr<JsonValue> & json)401     virtual void ToJsonValue(std::unique_ptr<JsonValue>& json) const {}
402 
403     // call by recycle framework.
OnRecycle()404     virtual void OnRecycle() {}
OnReuse()405     virtual void OnReuse() {}
406 
OnAttachToMainTree()407     virtual void OnAttachToMainTree() {}
OnAttachToBuilderNode(NodeStatus nodeStatus)408     virtual void OnAttachToBuilderNode(NodeStatus nodeStatus) {}
409 
OnDetachFromMainTree()410     virtual void OnDetachFromMainTree() {}
411 
FromJson(const std::unique_ptr<JsonValue> & json)412     virtual void FromJson(const std::unique_ptr<JsonValue>& json) {}
413 
OnAreaChangedInner()414     virtual void OnAreaChangedInner() {}
OnVisibleChange(bool isVisible)415     virtual void OnVisibleChange(bool isVisible) {}
ProvideRestoreInfo()416     virtual std::string ProvideRestoreInfo()
417     {
418         return "";
419     }
420 
OnRestoreInfo(const std::string & restoreInfo)421     virtual void OnRestoreInfo(const std::string& restoreInfo) {}
422 
IsNeedAdjustByAspectRatio()423     virtual bool IsNeedAdjustByAspectRatio()
424     {
425         auto host = GetHost();
426         CHECK_NULL_RETURN(host, false);
427         auto layoutProperty = host->GetLayoutProperty();
428         CHECK_NULL_RETURN(host, false);
429         return layoutProperty->HasAspectRatio();
430     }
431 
OnTouchTestHit(SourceType hitTestType)432     virtual void OnTouchTestHit(SourceType hitTestType) {}
433 
GetDragRecordSize()434     virtual int32_t GetDragRecordSize()
435     {
436         return -1;
437     }
438 
HandleOnDragStatusCallback(const DragEventType & dragEventType,const RefPtr<NotifyDragEvent> & notifyDragEvent)439     virtual void HandleOnDragStatusCallback(
440         const DragEventType& dragEventType, const RefPtr<NotifyDragEvent>& notifyDragEvent) {};
441 
HandleDragEvent(const PointerEvent & info)442     virtual void HandleDragEvent(const PointerEvent& info) {};
OnLanguageConfigurationUpdate()443     virtual void OnLanguageConfigurationUpdate() {}
OnColorConfigurationUpdate()444     virtual void OnColorConfigurationUpdate() {}
OnDirectionConfigurationUpdate()445     virtual void OnDirectionConfigurationUpdate() {}
OnDpiConfigurationUpdate()446     virtual void OnDpiConfigurationUpdate() {}
OnIconConfigurationUpdate()447     virtual void OnIconConfigurationUpdate() {}
448 
ShouldDelayChildPressedState()449     virtual bool ShouldDelayChildPressedState() const
450     {
451         return false;
452     }
453 
RegisterScrollingListener(const RefPtr<ScrollingListener> listener)454     virtual void RegisterScrollingListener(const RefPtr<ScrollingListener> listener) {}
FireAndCleanScrollingListener()455     virtual void FireAndCleanScrollingListener() {}
CleanScrollingListener()456     virtual void CleanScrollingListener() {}
ResetDragOption()457     virtual void ResetDragOption() {}
458 
WrapExtensionAbilityId(int64_t extensionOffset,int64_t abilityId)459     virtual int64_t WrapExtensionAbilityId(int64_t extensionOffset, int64_t abilityId)
460     {
461         return -1;
462     }
463 
SearchExtensionElementInfoByAccessibilityId(int64_t elementId,int32_t mode,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & output)464     virtual void SearchExtensionElementInfoByAccessibilityId(int64_t elementId, int32_t mode,
465         int64_t baseParent, std::list<Accessibility::AccessibilityElementInfo>& output) {}
SearchElementInfosByText(int64_t elementId,const std::string & text,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & output)466     virtual void SearchElementInfosByText(int64_t elementId, const std::string& text,
467         int64_t baseParent, std::list<Accessibility::AccessibilityElementInfo>& output) {}
FindFocusedElementInfo(int64_t elementId,int32_t focusType,int64_t baseParent,Accessibility::AccessibilityElementInfo & output)468     virtual void FindFocusedElementInfo(int64_t elementId, int32_t focusType,
469         int64_t baseParent, Accessibility::AccessibilityElementInfo& output) {}
FocusMoveSearch(int64_t elementId,int32_t direction,int64_t baseParent,Accessibility::AccessibilityElementInfo & output)470     virtual void FocusMoveSearch(int64_t elementId, int32_t direction,
471         int64_t baseParent, Accessibility::AccessibilityElementInfo& output) {}
TransferExecuteAction(int64_t elementId,const std::map<std::string,std::string> & actionArguments,int32_t action,int64_t offset)472     virtual bool TransferExecuteAction(
473         int64_t elementId, const std::map<std::string, std::string>& actionArguments, int32_t action, int64_t offset)
474     {
475         return false;
476     }
477 
GetUiExtensionId()478     virtual int32_t GetUiExtensionId()
479     {
480         return -1;
481     }
482 
GetLongPressEventRecorder()483     GestureEventFunc GetLongPressEventRecorder()
484     {
485         auto longPressCallback = [weak = WeakClaim(this)](GestureEvent& info) {
486             if (!Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
487                 return;
488             }
489             auto pattern = weak.Upgrade();
490             CHECK_NULL_VOID(pattern);
491             auto host = pattern->GetHost();
492             CHECK_NULL_VOID(host);
493             auto inspectorId = host->GetInspectorId().value_or("");
494             auto text = host->GetAccessibilityProperty<NG::AccessibilityProperty>()->GetAccessibilityText(true);
495             auto desc = host->GetAutoEventParamValue("");
496             if (inspectorId.empty() && text.empty() && desc.empty()) {
497                 return;
498             }
499 
500             Recorder::EventParamsBuilder builder;
501             builder.SetId(inspectorId)
502                 .SetType(host->GetTag())
503                 .SetEventType(Recorder::LONG_PRESS)
504                 .SetText(text)
505                 .SetDescription(desc);
506             Recorder::EventRecorder::Get().OnEvent(std::move(builder));
507         };
508         return longPressCallback;
509     }
510 
511 protected:
OnAttachToFrameNode()512     virtual void OnAttachToFrameNode() {}
OnDetachFromFrameNode(FrameNode * frameNode)513     virtual void OnDetachFromFrameNode(FrameNode* frameNode) {}
514 
IsNeedInitClickEventRecorder()515     virtual bool IsNeedInitClickEventRecorder() const
516     {
517         return false;
518     }
519 
InitClickEventRecorder()520     void InitClickEventRecorder()
521     {
522         if (clickCallback_) {
523             return;
524         }
525 
526         auto host = GetHost();
527         CHECK_NULL_VOID(host);
528         auto gesture = host->GetOrCreateGestureEventHub();
529         CHECK_NULL_VOID(gesture);
530         if (!gesture->IsClickable()) {
531             return;
532         }
533 
534         auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
535             if (!Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
536                 return;
537             }
538             auto pattern = weak.Upgrade();
539             CHECK_NULL_VOID(pattern);
540             auto host = pattern->GetHost();
541             CHECK_NULL_VOID(host);
542             auto inspectorId = host->GetInspectorId().value_or("");
543             auto text = host->GetAccessibilityProperty<NG::AccessibilityProperty>()->GetAccessibilityText(true);
544             auto desc = host->GetAutoEventParamValue("");
545             if (inspectorId.empty() && text.empty() && desc.empty()) {
546                 return;
547             }
548 
549             Recorder::EventParamsBuilder builder;
550             builder.SetId(inspectorId).SetType(host->GetTag()).SetText(text).SetDescription(desc);
551             Recorder::EventRecorder::Get().OnClick(std::move(builder));
552         };
553         clickCallback_ = MakeRefPtr<ClickEvent>(std::move(clickCallback));
554         gesture->AddClickEvent(clickCallback_);
555     }
556 
557     WeakPtr<FrameNode> frameNode_;
558     RefPtr<ClickEvent> clickCallback_;
559 
560 private:
561     ACE_DISALLOW_COPY_AND_MOVE(Pattern);
562 };
563 } // namespace OHOS::Ace::NG
564 
565 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_PATTERN_H
566