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