• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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