1 /*
2 * Copyright (c) 2024 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/interfaces/native/node/extension_companion_node.h"
17
18 #include "core/interfaces/native/node/view_model.h"
19
20 namespace {
21
22 constexpr int NUM_0 = 0;
23 constexpr int NUM_1 = 1;
24 constexpr int NUM_2 = 2;
25 constexpr int NUM_3 = 3;
26 constexpr int NUM_4 = 4;
27 constexpr int NUM_5 = 5;
28 constexpr int NUM_32 = 32;
29
30 } // namespace
31
32 namespace OHOS::Ace::NG {
33
34 const std::vector<ArkUIAPINodeFlags> NODE_FLAGS = { ArkUIAPINodeFlags::CUSTOM_MEASURE, ArkUIAPINodeFlags::CUSTOM_LAYOUT,
35 ArkUIAPINodeFlags::CUSTOM_DRAW, ArkUIAPINodeFlags::CUSTOM_FOREGROUND_DRAW, ArkUIAPINodeFlags::CUSTOM_OVERLAY_DRAW,
36 ArkUIAPINodeFlags::CUSTOM_DRAW_FRONT, ArkUIAPINodeFlags::CUSTOM_DRAW_BEHIND };
37
GetCanvas()38 ArkUICanvasHandle ExtensionCompanionNode::GetCanvas()
39 {
40 return reinterpret_cast<ArkUICanvasHandle>(0x123456789aLL);
41 }
42
Arg(ArkUI_Float32 f32)43 ArkUIEventCallbackArg ExtensionCompanionNode::Arg(ArkUI_Float32 f32)
44 {
45 ArkUIEventCallbackArg result;
46 result.f32 = f32;
47 return result;
48 }
49
Arg(ArkUI_Int32 i32)50 ArkUIEventCallbackArg ExtensionCompanionNode::Arg(ArkUI_Int32 i32)
51 {
52 ArkUIEventCallbackArg result;
53 result.i32 = i32;
54 return result;
55 }
56
GetPeerId() const57 ArkUI_Int32 ExtensionCompanionNode::GetPeerId() const
58 {
59 return peerId_;
60 }
61
GetCallbackId() const62 ArkUI_Int32 ExtensionCompanionNode::GetCallbackId() const
63 {
64 return customCallbackId_;
65 }
66
SetCallbackId(ArkUIVMContext context,int id)67 void ExtensionCompanionNode::SetCallbackId(ArkUIVMContext context, int id)
68 {
69 context_ = context;
70 customCallbackId_ = id;
71 }
72
SetExtraParam(ArkUI_Int32 type,void * extraParam)73 void ExtensionCompanionNode::SetExtraParam(ArkUI_Int32 type, void* extraParam)
74 {
75 for (const auto& flag : NODE_FLAGS) {
76 if (static_cast<uint32_t>(type) & flag) {
77 auto it = extraParamMap_.find(flag);
78 if (it != extraParamMap_.end()) {
79 it->second = extraParam;
80 } else {
81 extraParamMap_.emplace(flag, extraParam);
82 }
83 }
84 }
85 }
86
GetExtraParam(ArkUI_Int32 type)87 ArkUI_Int64 ExtensionCompanionNode::GetExtraParam(ArkUI_Int32 type)
88 {
89 auto it = extraParamMap_.find(type);
90 if (it != extraParamMap_.end()) {
91 return reinterpret_cast<ArkUI_Int64>(it->second);
92 }
93 return reinterpret_cast<ArkUI_Int64>(nullptr);
94 }
95
EraseExtraParam(ArkUI_Int32 type)96 void ExtensionCompanionNode::EraseExtraParam(ArkUI_Int32 type)
97 {
98 for (const auto& flag : NODE_FLAGS) {
99 if (static_cast<uint32_t>(type) & flag) {
100 auto it = extraParamMap_.find(type);
101 if (it != extraParamMap_.end()) {
102 extraParamMap_.erase(it);
103 }
104 }
105 }
106 }
107
OnMeasure(const ExtensionLayoutConstraint & layoutConstraint)108 void ExtensionCompanionNode::OnMeasure(const ExtensionLayoutConstraint& layoutConstraint)
109 {
110 if (flags_ & ArkUIAPINodeFlags::CUSTOM_MEASURE) {
111 // call extension logic to manager side.
112 ArkUICustomNodeEvent event;
113 event.kind = ArkUIAPINodeFlags::CUSTOM_MEASURE;
114 event.extraParam = GetExtraParam(static_cast<ArkUI_Int32>(ArkUIAPINodeFlags::CUSTOM_MEASURE));
115 event.data[NUM_0] = layoutConstraint.minWidth;
116 event.data[NUM_1] = layoutConstraint.minHeight;
117 event.data[NUM_2] = layoutConstraint.maxWidth;
118 event.data[NUM_3] = layoutConstraint.maxHeight;
119 event.data[NUM_4] = layoutConstraint.parentIdealWidth;
120 event.data[NUM_5] = layoutConstraint.parentIdealHeight;
121 SendArkUIAsyncCustomEvent(&event);
122 } else {
123 // call origin measure.
124 InnerMeasure(layoutConstraint);
125 }
126 }
127
OnLayout(int32_t width,int32_t height,int32_t positionX,int32_t positionY)128 void ExtensionCompanionNode::OnLayout(int32_t width, int32_t height, int32_t positionX, int32_t positionY)
129 {
130 if (flags_ & ArkUIAPINodeFlags::CUSTOM_LAYOUT) {
131 ArkUICustomNodeEvent event;
132 event.kind = ArkUIAPINodeFlags::CUSTOM_LAYOUT;
133 event.extraParam = GetExtraParam(static_cast<ArkUI_Int32>(ArkUIAPINodeFlags::CUSTOM_LAYOUT));
134 event.data[NUM_0] = positionX;
135 event.data[NUM_1] = positionY;
136 event.data[NUM_2] = width;
137 event.data[NUM_3] = height;
138 SendArkUIAsyncCustomEvent(&event);
139 } else {
140 InnerLayout(width, height, positionX, positionY);
141 }
142 }
143
OnDraw(DrawingContext & context)144 void ExtensionCompanionNode::OnDraw(DrawingContext& context)
145 {
146 if (flags_ & ArkUIAPINodeFlags::CUSTOM_DRAW_BEHIND) {
147 auto canvas = reinterpret_cast<uintptr_t>(&context.canvas);
148 ArkUICustomNodeEvent eventDrawBehind;
149 eventDrawBehind.kind = ArkUIAPINodeFlags::CUSTOM_DRAW_BEHIND;
150 eventDrawBehind.extraParam = GetExtraParam(static_cast<ArkUI_Int32>(ArkUIAPINodeFlags::CUSTOM_DRAW_BEHIND));
151 eventDrawBehind.data[NUM_0] = (ArkUI_Int32)(canvas & 0xffffffff);
152 eventDrawBehind.data[NUM_1] = (ArkUI_Int32)((static_cast<uint64_t>(canvas) >> NUM_32) & 0xffffffff);
153 eventDrawBehind.data[NUM_2] = context.width;
154 eventDrawBehind.data[NUM_3] = context.height;
155 eventDrawBehind.canvas = reinterpret_cast<intptr_t>(&context.canvas);
156 SendArkUIAsyncCustomEvent(&eventDrawBehind);
157 }
158
159 if (flags_ & ArkUIAPINodeFlags::CUSTOM_DRAW) {
160 // call extension logic to manager side.
161 auto canvas = reinterpret_cast<uintptr_t>(&context.canvas);
162 ArkUICustomNodeEvent event;
163 event.kind = ArkUIAPINodeFlags::CUSTOM_DRAW;
164 event.extraParam = GetExtraParam(static_cast<ArkUI_Int32>(ArkUIAPINodeFlags::CUSTOM_DRAW));
165 event.data[NUM_0] = (ArkUI_Int32)(canvas & 0xffffffff);
166 event.data[NUM_1] =
167 (ArkUI_Int32)((static_cast<uint64_t>(canvas) >> NUM_32) & 0xffffffff);
168 event.data[NUM_2] = context.width;
169 event.data[NUM_3] = context.height;
170 event.canvas = reinterpret_cast<intptr_t>(&context.canvas);
171 SendArkUIAsyncCustomEvent(&event);
172 } else {
173 InnerDraw(context);
174 }
175
176 if (flags_ & ArkUIAPINodeFlags::CUSTOM_DRAW_FRONT) {
177 auto canvas = reinterpret_cast<uintptr_t>(&context.canvas);
178 ArkUICustomNodeEvent eventDrawFront;
179 eventDrawFront.kind = ArkUIAPINodeFlags::CUSTOM_DRAW_FRONT;
180 eventDrawFront.extraParam = GetExtraParam(static_cast<ArkUI_Int32>(ArkUIAPINodeFlags::CUSTOM_DRAW_FRONT));
181 eventDrawFront.data[NUM_0] = (ArkUI_Int32)(canvas & 0xffffffff);
182 eventDrawFront.data[NUM_1] = (ArkUI_Int32)((static_cast<uint64_t>(canvas) >> NUM_32) & 0xffffffff);
183 eventDrawFront.data[NUM_2] = context.width;
184 eventDrawFront.data[NUM_3] = context.height;
185 eventDrawFront.canvas = reinterpret_cast<intptr_t>(&context.canvas);
186 SendArkUIAsyncCustomEvent(&eventDrawFront);
187 }
188 }
189
OnForegroundDraw(DrawingContext & context)190 void ExtensionCompanionNode::OnForegroundDraw(DrawingContext& context)
191 {
192 if (flags_ & ArkUIAPINodeFlags::CUSTOM_FOREGROUND_DRAW) {
193 // call extension logic to manager side.
194 auto canvas = reinterpret_cast<uintptr_t>(&context.canvas);
195 ArkUICustomNodeEvent event;
196 event.kind = ArkUIAPINodeFlags::CUSTOM_FOREGROUND_DRAW;
197 event.extraParam = GetExtraParam(static_cast<ArkUI_Int32>(ArkUIAPINodeFlags::CUSTOM_FOREGROUND_DRAW));
198 event.data[NUM_0] = (ArkUI_Int32)(canvas & 0xffffffff);
199 event.data[NUM_1] =
200 (ArkUI_Int32)((static_cast<uint64_t>(canvas) >> NUM_32) & 0xffffffff);
201 event.data[NUM_2] = context.width;
202 event.data[NUM_3] = context.height;
203 event.canvas = reinterpret_cast<intptr_t>(&context.canvas);
204 SendArkUIAsyncCustomEvent(&event);
205 } else {
206 InnerForegroundDraw(context);
207 }
208 }
209
OnOverlayDraw(DrawingContext & context)210 void ExtensionCompanionNode::OnOverlayDraw(DrawingContext& context)
211 {
212 if (flags_ & ArkUIAPINodeFlags::CUSTOM_OVERLAY_DRAW) {
213 // call extension logic to manager side.
214 auto canvas = reinterpret_cast<uintptr_t>(&context.canvas);
215 ArkUICustomNodeEvent event;
216 event.kind = ArkUIAPINodeFlags::CUSTOM_OVERLAY_DRAW;
217 event.extraParam = GetExtraParam(static_cast<ArkUI_Int32>(ArkUIAPINodeFlags::CUSTOM_OVERLAY_DRAW));
218 event.data[NUM_0] = (ArkUI_Int32)(canvas & 0xffffffff);
219 event.data[NUM_1] =
220 (ArkUI_Int32)((static_cast<uint64_t>(canvas) >> NUM_32) & 0xffffffff);
221 event.data[NUM_2] = context.width;
222 event.data[NUM_3] = context.height;
223 event.canvas = reinterpret_cast<intptr_t>(&context.canvas);
224 SendArkUIAsyncCustomEvent(&event);
225 } else {
226 InnerOverlayDraw(context);
227 }
228 }
229
HasCustomerMeasure() const230 bool ExtensionCompanionNode::HasCustomerMeasure() const
231 {
232 return (flags_ & ArkUIAPINodeFlags::CUSTOM_MEASURE) != 0;
233 }
234
HasCustomerLayout() const235 bool ExtensionCompanionNode::HasCustomerLayout() const
236 {
237 return (flags_ & ArkUIAPINodeFlags::CUSTOM_LAYOUT) != 0;
238 }
239
NeedRender() const240 bool ExtensionCompanionNode::NeedRender() const
241 {
242 ArkUI_Uint32 mask = ArkUIAPINodeFlags::CUSTOM_OVERLAY_DRAW | ArkUIAPINodeFlags::CUSTOM_FOREGROUND_DRAW |
243 ArkUIAPINodeFlags::CUSTOM_DRAW | ArkUIAPINodeFlags::CUSTOM_DRAW_FRONT |
244 ArkUIAPINodeFlags::CUSTOM_DRAW_BEHIND;
245 return (flags_ & mask) != 0;
246 }
247 } // namespace OHOS::Ace::NG