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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_DISTRIBUTE_UI_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_DISTRIBUTE_UI_H
18 
19 #include <cstdint>
20 #include <functional>
21 #include <set>
22 
23 #include "interfaces/inner_api/ace/serializeable_object.h"
24 
25 #include "base/json/node_object.h"
26 #include "core/components_ng/base/ui_node.h"
27 #include "core/event/touch_event.h"
28 
29 #define CHECK_NULL_BREAK(ptr)                                       \
30     if (!(ptr)) {                                                   \
31         break;                                                      \
32     }
33 
34 #define CHECK_NULL_CONTINUE(ptr)                                    \
35     if (!(ptr)) {                                                   \
36         continue;                                                   \
37     }
38 
39 namespace OHOS::Ace::NG {
40 class DistributedUI {
41 public:
42     enum UpdateType : uint8_t {
43         PAGE_UPDATE = 0,
44         PAGE_CHANGE = 1,
45     };
46 
47     enum StateMachine : uint8_t {
48         INIT = 0,
49         SOURCE_START = 1,
50         SINK_START = 2,
51         STOP = 3,
52     };
53 
54     enum OperationType : uint8_t {
55         OP_ADD = 0,
56         OP_MODIFY = 1,
57         OP_DELETE = 2,
58     };
59 
60     DistributedUI() = default;
61     ~DistributedUI() = default;
62 
63     // for distribute UI source
64     SerializeableObjectArray DumpUITree();
65     void SubscribeUpdate(const std::function<void(int32_t, SerializeableObjectArray&)>& onUpdate);
66     void UnSubscribeUpdate();
67     void ProcessSerializeableInputEvent(const SerializeableObjectArray& array);
68 
69     // for distribute UI sink
70     void RestoreUITree(const SerializeableObjectArray& array);
71     void UpdateUITree(const SerializeableObjectArray& array);
72     void SubscribeInputEventProcess(const std::function<void(SerializeableObjectArray&)>& onEvent);
73     void UnSubscribeInputEventProcess();
74 
75     // internal APIs for distribute UI source
76     void AddDeletedNode(int32_t nodeId);
77     void AddNewNode(int32_t nodeId);
78     void AddDirtyCustomNode(int32_t nodeId);
79     void AddDirtyRenderNode(int32_t nodeId);
80     void AddDirtyLayoutNode(int32_t nodeId);
81     void OnTreeUpdate();
82     void OnPageChanged(int32_t pageId);
83     int32_t GetCurrentPageId();
84 
85     // internal APIs for distribute UI sink
86     void BypassEvent(const TouchEvent& point, bool isSubPipe);
87     bool IsSinkMode();
88     void ApplyOneUpdate();
89 
90 private:
91     void DumpDirtyRenderNodes(SerializeableObjectArray& objectArray);
92     void DumpDirtyLayoutNodes(SerializeableObjectArray& objectArray);
93     void DumpNewNodes(SerializeableObjectArray& objectArray);
94     void DumpDelNodes(SerializeableObjectArray& objectArray);
95     SerializeableObjectArray DumpUpdate();
96     void ResetDirtyNodes();
97     bool IsNewNode(int32_t nodeId);
98     bool ReadyToDumpUpdate();
99 
100     void SetIdMapping(int32_t srcNodeId, int32_t sinkNodeId);
101     int32_t GetIdMapping(int32_t srcNodeId);
102     void AddNodeHash(int32_t nodeId, std::size_t hashValue);
103     void DelNodeHash(int32_t nodeId);
104     bool IsRecordHash(int32_t nodeId, std::size_t hashValue);
105     void DumpNode(const RefPtr<NG::UINode>& node, int depth, OperationType op, std::unique_ptr<NodeObject>& nodeObject);
106     void DumpTreeInner(const RefPtr<NG::UINode>& node, SerializeableObjectArray& objectArray, int depth);
107     RefPtr<UINode> RestoreNode(const std::unique_ptr<NodeObject>& nodeObject);
108     void AttachToTree(RefPtr<UINode> root, RefPtr<UINode> uiNode, const std::unique_ptr<NodeObject>& nodeObject);
109     void AddNode(const std::unique_ptr<NodeObject>& nodeObject, RefPtr<FrameNode> pageRootNode);
110     void ModNode(const std::unique_ptr<NodeObject>& nodeObject);
111     void DelNode(const std::unique_ptr<NodeObject>& nodeObject);
112     void UpdateUITreeInner(SerializeableObjectArray& nodeArray);
113     void RestoreUITreeInner(const SerializeableObjectArray& nodeArray);
114     bool IsInCurrentPage(RefPtr<NG::UINode> node, int32_t pageId);
115 
116     std::set<int32_t, std::greater<int32_t>> deletedNodes_;
117     std::set<int32_t> newNodes_;
118     std::set<int32_t> dirtyCustomNodes_;
119     std::set<int32_t> dirtyLayoutNodes_;
120     std::set<int32_t> dirtyRenderNodes_;
121     bool pageChangeFlag_ = false;
122     int32_t currentPageId_ = 0;
123     std::function<void(UpdateType, SerializeableObjectArray&)> onUpdateCb_;
124     std::function<void(SerializeableObjectArray&)> onEventCb_;
125     StateMachine status_ = StateMachine::INIT;
126     std::list<SerializeableObjectArray> pendingUpdates_;
127 
128     std::unordered_map<int32_t, int32_t> nodeIdMapping_;
129     std::unordered_map<int32_t, std::size_t> nodeHashs_;
130     std::list<RefPtr<NG::UINode>> sinkPageChildren_;
131 };
132 } // namespace OHOS::Ace::NG
133 
134 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_DISTRIBUTE_UI_H
135