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 #include "core/components_ng/pattern/security_component/security_component_model_ng.h"
17
18 #include "base/i18n/localization.h"
19 #include "base/log/ace_scoring_log.h"
20 #include "base/utils/utils.h"
21 #include "core/components/common/properties/text_style.h"
22 #include "core/components_ng/base/frame_node.h"
23 #include "core/components_ng/base/view_stack_processor.h"
24 #include "core/components_ng/pattern/button/button_layout_property.h"
25 #include "core/components_ng/pattern/button/button_pattern.h"
26 #include "core/components_ng/pattern/image/image_model_ng.h"
27 #include "core/components_ng/pattern/image/image_pattern.h"
28 #ifdef SECURITY_COMPONENT_ENABLE
29 #include "core/components_ng/pattern/security_component/security_component_handler.h"
30 #endif
31 #include "core/components_ng/pattern/security_component/security_component_log.h"
32 #include "core/components_ng/pattern/security_component/security_component_pattern.h"
33 #include "core/components_ng/pattern/security_component/security_component_theme.h"
34 #include "core/components_ng/pattern/text/text_pattern.h"
35 #include "core/components_v2/inspector/inspector_constants.h"
36 #include "core/pipeline_ng/pipeline_context.h"
37
38 namespace OHOS::Ace::NG {
39 const static uint8_t DEFAULT_TRANSPARENCY_THRESHOLD = 0x1A;
40 const static uint8_t FULL_TRANSPARENCY_VALUE = 0xFF;
41 const static std::set<uint32_t> RELEASE_ATTRIBUTE_LIST = {
42 0x0C000000,
43 };
GetTheme()44 RefPtr<SecurityComponentTheme> SecurityComponentModelNG::GetTheme()
45 {
46 auto pipeline = PipelineContext::GetCurrentContextSafely();
47 CHECK_NULL_RETURN(pipeline, nullptr);
48 return pipeline->GetTheme<SecurityComponentTheme>();
49 }
50
InitLayoutProperty(RefPtr<FrameNode> & node,int32_t text,int32_t icon,int32_t backgroundType)51 void SecurityComponentModelNG::InitLayoutProperty(RefPtr<FrameNode>& node, int32_t text, int32_t icon,
52 int32_t backgroundType)
53 {
54 auto property = node->GetLayoutProperty<SecurityComponentLayoutProperty>();
55 CHECK_NULL_VOID(property);
56 auto secCompTheme = GetTheme();
57 CHECK_NULL_VOID(secCompTheme);
58 property->UpdateSecurityComponentDescription(text);
59 property->UpdateIconStyle(icon);
60 property->UpdateBackgroundType(backgroundType);
61
62 if ((text == static_cast<int32_t>(SecurityComponentDescription::TEXT_NULL)) ||
63 (icon == static_cast<int32_t>(SecurityComponentIconStyle::ICON_NULL))) {
64 property->UpdateTextIconSpace(Dimension(0.0));
65 }
66
67 if (backgroundType == BUTTON_TYPE_NULL) {
68 property->UpdateBackgroundLeftPadding(secCompTheme->GetPaddingWithoutBg());
69 property->UpdateBackgroundRightPadding(secCompTheme->GetPaddingWithoutBg());
70 property->UpdateBackgroundTopPadding(secCompTheme->GetPaddingWithoutBg());
71 property->UpdateBackgroundBottomPadding(secCompTheme->GetPaddingWithoutBg());
72 }
73
74 property->UpdateTextIconLayoutDirection(SecurityComponentLayoutDirection::HORIZONTAL);
75 }
76
CreateNode(const std::string & tag,int32_t nodeId,SecurityComponentElementStyle & style,const std::function<RefPtr<Pattern> (void)> & patternCreator,bool isArkuiComponent)77 RefPtr<FrameNode> SecurityComponentModelNG::CreateNode(const std::string& tag, int32_t nodeId,
78 SecurityComponentElementStyle& style,
79 const std::function<RefPtr<Pattern>(void)>& patternCreator, bool isArkuiComponent)
80 {
81 ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", tag.c_str(), nodeId);
82 auto frameNode = FrameNode::GetOrCreateFrameNode(tag, nodeId, patternCreator);
83 CHECK_NULL_RETURN(frameNode, nullptr);
84
85 if (frameNode->GetChildren().empty()) {
86 bool isButtonVisible = (style.backgroundType != BUTTON_TYPE_NULL);
87 auto buttonNode = FrameNode::CreateFrameNode(
88 V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
89 AceType::MakeRefPtr<ButtonPattern>());
90 buttonNode->SetInternal();
91
92 if (isButtonVisible) {
93 SetDefaultBackgroundButton(buttonNode, style.backgroundType);
94 } else {
95 SetInvisibleBackgroundButton(buttonNode);
96 }
97 frameNode->AddChild(buttonNode);
98
99 if (style.icon != static_cast<int32_t>(SecurityComponentIconStyle::ICON_NULL)) {
100 auto imageIcon = FrameNode::CreateFrameNode(
101 V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
102 imageIcon->SetInternal();
103 InternalResource::ResourceId iconId;
104 if (GetIconResource(style.icon, iconId)) {
105 SetDefaultIconStyle(imageIcon, iconId, isButtonVisible);
106 }
107 frameNode->AddChild(imageIcon);
108 }
109
110 if (style.text != static_cast<int32_t>(SecurityComponentDescription::TEXT_NULL)) {
111 auto textNode = FrameNode::CreateFrameNode(
112 V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
113 CHECK_NULL_RETURN(textNode, nullptr);
114 textNode->SetInternal();
115 std::string textStr = "";
116 GetTextResource(style.text, textStr);
117 SetDefaultTextStyle(textNode, textStr, isButtonVisible);
118 frameNode->AddChild(textNode);
119 }
120 InitLayoutProperty(frameNode, style.text, style.icon, style.backgroundType);
121 }
122 auto property = frameNode->GetLayoutProperty<SecurityComponentLayoutProperty>();
123 CHECK_NULL_RETURN(property, nullptr);
124 property->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE);
125 property->UpdateIsArkuiComponent(isArkuiComponent);
126 auto pipeline = AceType::DynamicCast<PipelineContext>(PipelineBase::GetCurrentContextSafely());
127 CHECK_NULL_RETURN(pipeline, nullptr);
128 pipeline->AddWindowStateChangedCallback(nodeId);
129 return frameNode;
130 }
131
CreateCommon(const std::string & tag,int32_t text,int32_t icon,int32_t backgroundType,const std::function<RefPtr<Pattern> (void)> & patternCreator,bool isArkuiComponent)132 void SecurityComponentModelNG::CreateCommon(const std::string& tag, int32_t text, int32_t icon,
133 int32_t backgroundType, const std::function<RefPtr<Pattern>(void)>& patternCreator, bool isArkuiComponent)
134 {
135 auto stack = ViewStackProcessor::GetInstance();
136 auto nodeId = stack->ClaimNodeId();
137 SecurityComponentElementStyle style = {
138 .text = text,
139 .icon = icon,
140 .backgroundType = backgroundType
141 };
142 auto frameNode = CreateNode(tag, nodeId, style, patternCreator, isArkuiComponent);
143 CHECK_NULL_VOID(frameNode);
144 stack->Push(frameNode);
145 }
146
SetDefaultTextStyle(const RefPtr<FrameNode> & textNode,const std::string & text,bool isButtonVisible)147 void SecurityComponentModelNG::SetDefaultTextStyle(const RefPtr<FrameNode>& textNode, const std::string& text,
148 bool isButtonVisible)
149 {
150 auto secCompTheme = GetTheme();
151 CHECK_NULL_VOID(secCompTheme);
152 auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
153 CHECK_NULL_VOID(textLayoutProperty);
154 textLayoutProperty->UpdateContent(text);
155 textLayoutProperty->UpdateMaxLines(secCompTheme->GetDefaultTextMaxLines());
156 textLayoutProperty->UpdateFontSize(secCompTheme->GetFontSize());
157 textLayoutProperty->UpdateItalicFontStyle(Ace::FontStyle::NORMAL);
158 textLayoutProperty->UpdateFontWeight(FontWeight::MEDIUM);
159 textLayoutProperty->UpdateHeightAdaptivePolicy(TextHeightAdaptivePolicy::MAX_LINES_FIRST);
160
161 if (isButtonVisible) {
162 textLayoutProperty->UpdateTextColor(secCompTheme->GetFontColor());
163 } else {
164 textLayoutProperty->UpdateTextColor(secCompTheme->GetFontColorNoBg());
165 }
166 }
167
SetDefaultIconStyle(const RefPtr<FrameNode> & imageNode,InternalResource::ResourceId id,bool isButtonVisible)168 void SecurityComponentModelNG::SetDefaultIconStyle(const RefPtr<FrameNode>& imageNode, InternalResource::ResourceId id,
169 bool isButtonVisible)
170 {
171 auto secCompTheme = GetTheme();
172 CHECK_NULL_VOID(secCompTheme);
173 ImageSourceInfo imageSourceInfo;
174 imageSourceInfo.SetResourceId(id);
175 if (isButtonVisible) {
176 imageSourceInfo.SetFillColor(secCompTheme->GetIconColor());
177 } else {
178 imageSourceInfo.SetFillColor(secCompTheme->GetIconColorNoBg());
179 }
180
181 auto iconProp = imageNode->GetLayoutProperty<ImageLayoutProperty>();
182 CHECK_NULL_VOID(iconProp);
183 iconProp->UpdateImageSourceInfo(imageSourceInfo);
184 iconProp->UpdateUserDefinedIdealSize(
185 CalcSize(NG::CalcLength(secCompTheme->GetIconSize()), NG::CalcLength(secCompTheme->GetIconSize())));
186 // default follow text direction
187 ImageModelNG::SetMatchTextDirection(Referenced::RawPtr(imageNode), true);
188 }
189
SetDefaultBackgroundButton(const RefPtr<FrameNode> & buttonNode,int32_t type)190 void SecurityComponentModelNG::SetDefaultBackgroundButton(const RefPtr<FrameNode>& buttonNode,
191 int32_t type)
192 {
193 auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
194 CHECK_NULL_VOID(buttonLayoutProperty);
195 const auto& renderContext = buttonNode->GetRenderContext();
196 CHECK_NULL_VOID(renderContext);
197 auto secCompTheme = GetTheme();
198 CHECK_NULL_VOID(secCompTheme);
199
200 BorderColorProperty borderColor;
201 borderColor.SetColor(secCompTheme->GetBorderColor());
202 renderContext->UpdateBorderColor(borderColor);
203 BorderWidthProperty widthProp;
204 widthProp.SetBorderWidth(secCompTheme->GetBorderWidth());
205 buttonLayoutProperty->UpdateBorderWidth(widthProp);
206 BorderStyleProperty style;
207 style.SetBorderStyle(BorderStyle::NONE);
208 renderContext->UpdateBorderStyle(style);
209 auto buttonRadius = secCompTheme->GetBorderRadius();
210 buttonLayoutProperty->UpdateBorderRadius(BorderRadiusProperty(buttonRadius));
211 renderContext->UpdateBackgroundColor(secCompTheme->GetBackgroundColor());
212 buttonLayoutProperty->UpdateType(static_cast<ButtonType>(type));
213 }
214
SetInvisibleBackgroundButton(const RefPtr<FrameNode> & buttonNode)215 void SecurityComponentModelNG::SetInvisibleBackgroundButton(const RefPtr<FrameNode>& buttonNode)
216 {
217 auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
218 CHECK_NULL_VOID(buttonLayoutProperty);
219 const auto& renderContext = buttonNode->GetRenderContext();
220 CHECK_NULL_VOID(renderContext);
221 renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
222 buttonLayoutProperty->UpdateType(ButtonType::NORMAL);
223 }
224
225 template<typename T>
GetChildLayoutProprty(const std::string & tag)226 RefPtr<T> GetChildLayoutProprty(const std::string& tag)
227 {
228 auto node = GetCurSecCompChildNode(tag);
229 CHECK_NULL_RETURN(node, nullptr);
230 return node->GetLayoutProperty<T>();
231 }
232
IsBackgroundVisible()233 bool SecurityComponentModelNG::IsBackgroundVisible()
234 {
235 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
236 CHECK_NULL_RETURN(frameNode, false);
237 auto prop = frameNode->GetLayoutProperty<SecurityComponentLayoutProperty>();
238 if (prop) {
239 return (prop->GetBackgroundType() != BUTTON_TYPE_NULL);
240 }
241 return false;
242 }
243
IsArkuiComponent()244 bool SecurityComponentModelNG::IsArkuiComponent()
245 {
246 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
247 CHECK_NULL_RETURN(frameNode, false);
248 auto prop = frameNode->GetLayoutProperty<SecurityComponentLayoutProperty>();
249 if (prop && prop->GetIsArkuiComponent().has_value()) {
250 return prop->GetIsArkuiComponent().value();
251 }
252 return false;
253 }
254
NotifyFontColorSet()255 void SecurityComponentModelNG::NotifyFontColorSet()
256 {
257 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
258 CHECK_NULL_VOID(frameNode);
259 auto prop = frameNode->GetLayoutProperty<SecurityComponentLayoutProperty>();
260 CHECK_NULL_VOID(prop);
261 prop->UpdateIsFontColorSet(true);
262 }
263
IsInReleaseList(uint32_t value)264 bool SecurityComponentModelNG::IsInReleaseList(uint32_t value)
265 {
266 return (RELEASE_ATTRIBUTE_LIST.find(value) != RELEASE_ATTRIBUTE_LIST.end());
267 }
268
IsBelowThreshold(const Color & value)269 bool SecurityComponentModelNG::IsBelowThreshold(const Color& value)
270 {
271 return value.GetAlpha() < DEFAULT_TRANSPARENCY_THRESHOLD;
272 }
273
SetIconSize(const Dimension & value)274 void SecurityComponentModelNG::SetIconSize(const Dimension& value)
275 {
276 ACE_UPDATE_LAYOUT_PROPERTY(SecurityComponentLayoutProperty, IconSize, value);
277 }
278
SetIconColor(const Color & value)279 void SecurityComponentModelNG::SetIconColor(const Color& value)
280 {
281 ACE_UPDATE_PAINT_PROPERTY(SecurityComponentPaintProperty, IconColor, value);
282 }
283
SetFontSize(const Dimension & value)284 void SecurityComponentModelNG::SetFontSize(const Dimension& value)
285 {
286 ACE_UPDATE_LAYOUT_PROPERTY(SecurityComponentLayoutProperty, FontSize, value);
287 }
288
SetFontStyle(const Ace::FontStyle & value)289 void SecurityComponentModelNG::SetFontStyle(const Ace::FontStyle& value)
290 {
291 ACE_UPDATE_LAYOUT_PROPERTY(SecurityComponentLayoutProperty, FontStyle, value);
292 }
293
SetFontWeight(const FontWeight & value)294 void SecurityComponentModelNG::SetFontWeight(const FontWeight& value)
295 {
296 ACE_UPDATE_LAYOUT_PROPERTY(SecurityComponentLayoutProperty, FontWeight, value);
297 }
298
SetFontFamily(const std::vector<std::string> & fontFamilies)299 void SecurityComponentModelNG::SetFontFamily(const std::vector<std::string>& fontFamilies)
300 {
301 ACE_UPDATE_LAYOUT_PROPERTY(SecurityComponentLayoutProperty, FontFamily, fontFamilies);
302 }
303
SetFontColor(const Color & value)304 void SecurityComponentModelNG::SetFontColor(const Color& value)
305 {
306 ACE_UPDATE_PAINT_PROPERTY(SecurityComponentPaintProperty, FontColor, value);
307 NotifyFontColorSet();
308 }
309
SetBackgroundColor(const Color & value)310 void SecurityComponentModelNG::SetBackgroundColor(const Color& value)
311 {
312 if (!IsBackgroundVisible()) {
313 SC_LOG_WARN("background is not exist");
314 return;
315 }
316
317 bool res = false;
318 #ifdef SECURITY_COMPONENT_ENABLE
319 res = SecurityComponentHandler::IsSystemAppCalling();
320 #endif
321 Color resColor = value;
322 if (!res && !IsInReleaseList(resColor.GetValue()) && !IsArkuiComponent() && IsBelowThreshold(value)) {
323 resColor = value.ChangeAlpha(FULL_TRANSPARENCY_VALUE);
324 }
325 ACE_UPDATE_PAINT_PROPERTY(SecurityComponentPaintProperty, BackgroundColor, resColor);
326 }
327
SetBackgroundBorderWidth(const Dimension & value)328 void SecurityComponentModelNG::SetBackgroundBorderWidth(const Dimension& value)
329 {
330 if (!IsBackgroundVisible()) {
331 SC_LOG_WARN("background is not exist");
332 return;
333 }
334
335 ACE_UPDATE_LAYOUT_PROPERTY(SecurityComponentLayoutProperty, BackgroundBorderWidth, value);
336 }
337
SetBackgroundBorderColor(const Color & value)338 void SecurityComponentModelNG::SetBackgroundBorderColor(const Color& value)
339 {
340 if (!IsBackgroundVisible()) {
341 SC_LOG_WARN("background is not exist");
342 return;
343 }
344 ACE_UPDATE_PAINT_PROPERTY(SecurityComponentPaintProperty, BackgroundBorderColor, value);
345 }
346
SetBackgroundBorderStyle(const BorderStyle & value)347 void SecurityComponentModelNG::SetBackgroundBorderStyle(const BorderStyle& value)
348 {
349 if (!IsBackgroundVisible()) {
350 SC_LOG_WARN("background is not exist");
351 return;
352 }
353 ACE_UPDATE_PAINT_PROPERTY(SecurityComponentPaintProperty, BackgroundBorderStyle, value);
354 }
355
SetBackgroundBorderRadius(const Dimension & value)356 void SecurityComponentModelNG::SetBackgroundBorderRadius(const Dimension& value)
357 {
358 if (!IsBackgroundVisible()) {
359 SC_LOG_WARN("background is not exist");
360 return;
361 }
362
363 ACE_UPDATE_LAYOUT_PROPERTY(SecurityComponentLayoutProperty, BackgroundBorderRadius, value);
364 }
365
SetBackgroundPadding(const std::optional<Dimension> & left,const std::optional<Dimension> & right,const std::optional<Dimension> & top,const std::optional<Dimension> & bottom)366 void SecurityComponentModelNG::SetBackgroundPadding(const std::optional<Dimension>& left,
367 const std::optional<Dimension>& right, const std::optional<Dimension>& top,
368 const std::optional<Dimension>& bottom)
369 {
370 if (!IsBackgroundVisible()) {
371 SC_LOG_WARN("Can not set background padding without background");
372 return;
373 }
374
375 auto secCompTheme = GetTheme();
376 CHECK_NULL_VOID(secCompTheme);
377 if (left.has_value()) {
378 ACE_UPDATE_LAYOUT_PROPERTY(SecurityComponentLayoutProperty,
379 BackgroundLeftPadding, left.value());
380 }
381
382 if (right.has_value()) {
383 ACE_UPDATE_LAYOUT_PROPERTY(SecurityComponentLayoutProperty,
384 BackgroundRightPadding, right.value());
385 }
386 if (top.has_value()) {
387 ACE_UPDATE_LAYOUT_PROPERTY(SecurityComponentLayoutProperty,
388 BackgroundTopPadding, top.value());
389 }
390
391 if (bottom.has_value()) {
392 ACE_UPDATE_LAYOUT_PROPERTY(SecurityComponentLayoutProperty,
393 BackgroundBottomPadding, bottom.value());
394 }
395 }
396
SetBackgroundPadding(const std::optional<Dimension> & padding)397 void SecurityComponentModelNG::SetBackgroundPadding(const std::optional<Dimension>& padding)
398 {
399 SetBackgroundPadding(padding, padding, padding, padding);
400 }
401
SetTextIconSpace(const Dimension & value)402 void SecurityComponentModelNG::SetTextIconSpace(const Dimension& value)
403 {
404 if ((GetCurSecCompChildNode(V2::TEXT_ETS_TAG) == nullptr) ||
405 (GetCurSecCompChildNode(V2::IMAGE_ETS_TAG) == nullptr)) {
406 SC_LOG_WARN("Can not set text icon padding without text and icon");
407 return;
408 }
409 ACE_UPDATE_LAYOUT_PROPERTY(SecurityComponentLayoutProperty, TextIconSpace, value);
410 }
411
SetTextIconLayoutDirection(const SecurityComponentLayoutDirection & value)412 void SecurityComponentModelNG::SetTextIconLayoutDirection(const SecurityComponentLayoutDirection& value)
413 {
414 ACE_UPDATE_LAYOUT_PROPERTY(SecurityComponentLayoutProperty, TextIconLayoutDirection, value);
415 }
416 } // namespace OHOS::Ace::NG
417