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