• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_pattern.h"
17 #include "core/components_ng/pattern/button/button_pattern.h"
18 #ifdef SECURITY_COMPONENT_ENABLE
19 #include "core/components_ng/pattern/security_component/security_component_handler.h"
20 #endif
21 #include "core/components_ng/pattern/security_component/security_component_log.h"
22 #include "core/components/common/layout/constants.h"
23 #ifdef SECURITY_COMPONENT_ENABLE
24 #include "pointer_event.h"
25 #endif
26 
27 namespace OHOS::Ace::NG {
28 namespace {
29 #ifdef SECURITY_COMPONENT_ENABLE
30 const int32_t DELAY_RELEASE_MILLSEC = 10;
31 static std::unordered_map<uint64_t, RefPtr<FrameNode>> g_scNodeMap;
32 static std::vector<uint64_t> g_omittedNodeIndex;
33 static uint64_t g_scIndex = 0;
34 static std::mutex g_scMutex;
35 const std::string SYSTEM_INTERNAL_ERROR_MESSAGE = "system internal error";
36 #endif
37 }
SecurityComponentPattern()38 SecurityComponentPattern::SecurityComponentPattern()
39 {
40 #ifdef SECURITY_COMPONENT_ENABLE
41     uiEventHandler_ = OHOS::AppExecFwk::EventHandler::Current();
42 #endif
43 }
44 
~SecurityComponentPattern()45 SecurityComponentPattern::~SecurityComponentPattern()
46 {
47 #ifdef SECURITY_COMPONENT_ENABLE
48     UnregisterSecurityComponent();
49 #endif
50 }
51 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)52 bool SecurityComponentPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty,
53     const DirtySwapConfig& config)
54 {
55     CHECK_NULL_RETURN(dirty, false);
56     return !(config.skipMeasure || dirty->SkipMeasureContent());
57 }
58 
SetNodeHitTestMode(RefPtr<FrameNode> & node,HitTestMode mode)59 void SecurityComponentPattern::SetNodeHitTestMode(RefPtr<FrameNode>& node, HitTestMode mode)
60 {
61     if (node == nullptr) {
62         return;
63     }
64     auto gestureHub = node->GetOrCreateGestureEventHub();
65     CHECK_NULL_VOID(gestureHub);
66     gestureHub->SetHitTestMode(mode);
67 }
68 
OnLanguageConfigurationUpdate()69 void SecurityComponentPattern::OnLanguageConfigurationUpdate()
70 {
71     auto node = GetHost();
72     CHECK_NULL_VOID(node);
73     auto textNode = GetSecCompChildNode(node, V2::TEXT_ETS_TAG);
74     CHECK_NULL_VOID(textNode);
75     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
76     CHECK_NULL_VOID(textLayoutProperty);
77     auto layoutProperty = AceType::DynamicCast<SecurityComponentLayoutProperty>(node->GetLayoutProperty());
78     if (layoutProperty && layoutProperty->GetTextStyle().has_value()) {
79         auto textStyle = layoutProperty->GetTextStyle().value();
80         if (textStyle != static_cast<int32_t>(SecurityComponentDescription::TEXT_NULL)) {
81             auto pipeline = textNode->GetContextRefPtr();
82             CHECK_NULL_VOID(pipeline);
83             auto theme = pipeline->GetTheme<SecurityComponentTheme>();
84             CHECK_NULL_VOID(theme);
85 
86             std::string text;
87             if (node->GetTag() == V2::PASTE_BUTTON_ETS_TAG) {
88                 text = theme->GetPasteDescriptions(textStyle);
89             } else if (node->GetTag() == V2::LOCATION_BUTTON_ETS_TAG) {
90                 text = theme->GetLocationDescriptions(textStyle);
91             } else if (node->GetTag() == V2::SAVE_BUTTON_ETS_TAG) {
92                 text = theme->GetSaveDescriptions(textStyle);
93             }
94 
95             textLayoutProperty->UpdateContent(text);
96         }
97     }
98 }
99 
OnKeyEvent(const KeyEvent & event)100 bool SecurityComponentPattern::OnKeyEvent(const KeyEvent& event)
101 {
102     if (event.action != KeyAction::DOWN) {
103         return false;
104     }
105     if ((event.code == KeyCode::KEY_SPACE) || (event.code == KeyCode::KEY_ENTER) ||
106         (event.code == KeyCode::KEY_NUMPAD_ENTER)) {
107         auto frameNode = GetHost();
108         CHECK_NULL_RETURN(frameNode, false);
109         int32_t res = 1;
110 #ifdef SECURITY_COMPONENT_ENABLE
111         res = ReportSecurityComponentClickEvent(event);
112         if (res == Security::SecurityComponent::SC_SERVICE_ERROR_WAIT_FOR_DIALOG_CLOSE) {
113             res = static_cast<int32_t>(SecurityComponentHandleResult::DROP_CLICK);
114         } else if (res != 0) {
115             SC_LOG_ERROR("ReportSecurityComponentClickEvent failed, errno %{public}d", res);
116             res = 1;
117         }
118 #endif
119         auto jsonNode = JsonUtil::Create(true);
120         CHECK_NULL_RETURN(jsonNode, false);
121         jsonNode->Put("handleRes", res);
122         std::shared_ptr<JsonValue> jsonShrd(jsonNode.release());
123         auto gestureEventHub = frameNode->GetOrCreateGestureEventHub();
124         gestureEventHub->ActClick(jsonShrd);
125         return true;
126     }
127     return false;
128 }
129 
InitOnKeyEvent(RefPtr<FrameNode> & secCompNode)130 void SecurityComponentPattern::InitOnKeyEvent(RefPtr<FrameNode>& secCompNode)
131 {
132     if (isSetOnKeyEvent) {
133         return;
134     }
135     auto focusHub = secCompNode->GetOrCreateFocusHub();
136     auto onKeyEvent = [wp = WeakClaim(this)](const KeyEvent& event) -> bool {
137         auto pattern = wp.Upgrade();
138         if (!pattern) {
139             return false;
140         }
141         return pattern->OnKeyEvent(event);
142     };
143     focusHub->SetOnKeyEventInternal(std::move(onKeyEvent));
144     isSetOnKeyEvent = true;
145 }
146 
IsParentMenu(RefPtr<FrameNode> & secCompNode)147 bool SecurityComponentPattern::IsParentMenu(RefPtr<FrameNode>& secCompNode)
148 {
149     auto parent = secCompNode->GetParent();
150     while (parent != nullptr) {
151         if (parent->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
152             return true;
153         }
154         parent = parent->GetParent();
155     }
156     return false;
157 }
158 
HandleClickEventFromTouch(const TouchEventInfo & info)159 void SecurityComponentPattern::HandleClickEventFromTouch(const TouchEventInfo& info)
160 {
161 #ifdef SECURITY_COMPONENT_ENABLE
162     auto host = GetHost();
163     CHECK_NULL_VOID(host);
164 
165     if (!IsParentMenu(host)) {
166         return;
167     }
168 
169     auto pointerEvent = info.GetPointerEvent();
170     CHECK_NULL_VOID(pointerEvent);
171 
172     int32_t pointerId = pointerEvent->GetPointerId();
173     MMI::PointerEvent::PointerItem item;
174     if (!pointerEvent->GetPointerItem(pointerId, item)) {
175         SC_LOG_WARN("Get pointer item failed");
176         return;
177     }
178 
179     GestureEvent gestureInfo;
180     gestureInfo.SetDisplayX(item.GetDisplayX());
181     gestureInfo.SetDisplayY(item.GetDisplayY());
182     gestureInfo.SetPointerEvent(info.GetPointerEvent());
183     std::string message;
184     int res = ReportSecurityComponentClickEvent(gestureInfo, message);
185     if (res == Security::SecurityComponent::SC_SERVICE_ERROR_WAIT_FOR_DIALOG_CLOSE) {
186         return;
187     }
188     if (res != 0) {
189         SC_LOG_WARN("ReportSecurityComponentClickEvent failed, errno %{public}d", res);
190         res = 1;
191     }
192     auto jsonNode = JsonUtil::Create(true);
193     CHECK_NULL_VOID(jsonNode);
194     jsonNode->Put("handleRes", res);
195     std::shared_ptr<JsonValue> jsonShrd(jsonNode.release());
196     auto gestureEventHub = host->GetOrCreateGestureEventHub();
197     gestureEventHub->ActClick(jsonShrd);
198 #endif
199 }
200 
201 // When security component is a child node of menu wrapper, the menu is immediately hidden
202 // after being touched, and then the security component will trigger a click event.
203 // However, it will be considered to have been triggered in a hidden state,
204 // Therefore, we should report click event on UP touch event.
OnTouch(const TouchEventInfo & info)205 void SecurityComponentPattern::OnTouch(const TouchEventInfo& info)
206 {
207     auto touchType = info.GetTouches().front().GetTouchType();
208     if (touchType == TouchType::DOWN) {
209         lastTouchOffset_ = std::make_unique<Offset>(info.GetTouches().front().GetLocalLocation());
210     } else if (touchType == TouchType::UP) {
211         auto touchUpOffset = info.GetTouches().front().GetLocalLocation();
212         if (lastTouchOffset_ &&
213             (touchUpOffset - *lastTouchOffset_).GetDistance() <= DEFAULT_SECURITY_COMPONENT_CLICK_DISTANCE) {
214             HandleClickEventFromTouch(info);
215         }
216         lastTouchOffset_.reset();
217     }
218 }
219 
InitOnTouch(RefPtr<FrameNode> & secCompNode)220 void SecurityComponentPattern::InitOnTouch(RefPtr<FrameNode>& secCompNode)
221 {
222     if (onTouchListener_ != nullptr) {
223         return;
224     }
225     auto gestureHub = secCompNode->GetOrCreateGestureEventHub();
226     CHECK_NULL_VOID(gestureHub);
227 
228     auto touchCallback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
229         auto pattern = weak.Upgrade();
230         CHECK_NULL_VOID(pattern);
231         pattern->OnTouch(info);
232     };
233     onTouchListener_ = MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
234     gestureHub->AddTouchEvent(onTouchListener_);
235 }
236 
InitOnClick(RefPtr<FrameNode> & secCompNode,RefPtr<FrameNode> & icon,RefPtr<FrameNode> & text,RefPtr<FrameNode> & button)237 void SecurityComponentPattern::InitOnClick(RefPtr<FrameNode>& secCompNode, RefPtr<FrameNode>& icon,
238     RefPtr<FrameNode>& text, RefPtr<FrameNode>& button)
239 {
240     if (clickListener_ != nullptr) {
241         return;
242     }
243     auto secCompGesture = secCompNode->GetOrCreateGestureEventHub();
244     CHECK_NULL_VOID(secCompGesture);
245     auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
246 #ifdef SECURITY_COMPONENT_ENABLE
247         auto buttonPattern = weak.Upgrade();
248         CHECK_NULL_VOID(buttonPattern);
249         auto frameNode = buttonPattern->GetHost();
250         CHECK_NULL_VOID(frameNode);
251         if (info.GetSecCompHandleEvent()) {
252             return;
253         }
254         auto jsonNode = JsonUtil::Create(true);
255         CHECK_NULL_VOID(jsonNode);
256         std::shared_ptr<JsonValue> jsonShrd(jsonNode.release());
257         int32_t res;
258         int32_t code = SecurityComponentErrorCode::SUCCESS;
259         std::string message;
260         // if info.GetPointerEvent() is null, device may in screen read mode
261         // otherwise, this event should be dropped in menu
262         if (buttonPattern->IsParentMenu(frameNode) && info.GetPointerEvent() != nullptr) {
263             res = static_cast<int32_t>(SecurityComponentHandleResult::DROP_CLICK);
264         } else {
265             res = buttonPattern->ReportSecurityComponentClickEvent(info, message);
266             code = res;
267             if (res == Security::SecurityComponent::SC_SERVICE_ERROR_WAIT_FOR_DIALOG_CLOSE) {
268                 res = static_cast<int32_t>(SecurityComponentHandleResult::DROP_CLICK);
269             } else if (res != 0) {
270                 SC_LOG_WARN("ReportSecurityComponentClickEvent failed, errno %{public}d", res);
271                 res = static_cast<int32_t>(SecurityComponentHandleResult::CLICK_GRANT_FAILED);
272             }
273         }
274         buttonPattern->HandleReportSecCompClickEventResult(code, message);
275         jsonShrd->Put("handleRes", res);
276         jsonShrd->Put("code", code);
277         jsonShrd->Put("message", message.c_str());
278         info.SetSecCompHandleEvent(jsonShrd);
279 #endif
280     };
281 
282     clickListener_ = MakeRefPtr<ClickEvent>(std::move(clickCallback));
283     secCompGesture->AddClickEvent(clickListener_);
284     SetNodeHitTestMode(icon, HitTestMode::HTMTRANSPARENT);
285     SetNodeHitTestMode(text, HitTestMode::HTMTRANSPARENT);
286 }
287 
ToJsonValueIconNode(std::unique_ptr<JsonValue> & json,const RefPtr<FrameNode> & iconNode,const InspectorFilter & filter) const288 void SecurityComponentPattern::ToJsonValueIconNode(std::unique_ptr<JsonValue>& json, const RefPtr<FrameNode>& iconNode,
289     const InspectorFilter& filter) const
290 {
291     auto node = GetHost();
292     CHECK_NULL_VOID(node);
293     auto* pipeline = node->GetContextWithCheck();
294     CHECK_NULL_VOID(pipeline);
295     auto theme = pipeline->GetTheme<SecurityComponentTheme>();
296     CHECK_NULL_VOID(theme);
297     auto iconProp = iconNode->GetLayoutProperty<ImageLayoutProperty>();
298     CHECK_NULL_VOID(iconProp);
299     CHECK_NULL_VOID(iconProp->GetCalcLayoutConstraint());
300     // GetDimension would ret a empty dimension when width is empty
301     auto width = iconProp->GetCalcLayoutConstraint()->selfIdealSize->Width();
302     if (width.has_value()) {
303         json->PutExtAttr("iconSize", width->GetDimension().ToString().c_str(), filter);
304     } else {
305         json->PutExtAttr("iconSize", theme->GetIconSize().ToString().c_str(), filter);
306     }
307     json->PutExtAttr("iconColor", iconProp->GetImageSourceInfo()->GetFillColor().
308         value_or(theme->GetIconColor()).ColorToString().c_str(), filter);
309 }
310 
ToJsonValueSymbolIconNode(std::unique_ptr<JsonValue> & json,const RefPtr<FrameNode> & symbolIconNode,const InspectorFilter & filter) const311 void SecurityComponentPattern::ToJsonValueSymbolIconNode(std::unique_ptr<JsonValue>& json,
312     const RefPtr<FrameNode>& symbolIconNode, const InspectorFilter& filter) const
313 {
314     CHECK_NULL_VOID(symbolIconNode);
315     auto iconProp = symbolIconNode->GetLayoutProperty<TextLayoutProperty>();
316     CHECK_NULL_VOID(iconProp);
317     json->PutExtAttr("iconSize",
318         iconProp->GetFontSize().value_or(Dimension(0, DimensionUnit::VP)).ToString().c_str(), filter);
319     json->PutExtAttr("iconColor",
320         V2::ConvertSymbolColorToString(iconProp->GetSymbolColorListValue({})).c_str(), filter);
321 }
322 
ToJsonValueTextNode(std::unique_ptr<JsonValue> & json,const RefPtr<FrameNode> & textNode,const InspectorFilter & filter) const323 void SecurityComponentPattern::ToJsonValueTextNode(std::unique_ptr<JsonValue>& json, const RefPtr<FrameNode>& textNode,
324     const InspectorFilter& filter) const
325 {
326     auto node = GetHost();
327     CHECK_NULL_VOID(node);
328     auto* pipeline = node->GetContextWithCheck();
329     CHECK_NULL_VOID(pipeline);
330     auto theme = pipeline->GetTheme<SecurityComponentTheme>();
331     CHECK_NULL_VOID(theme);
332     auto textProp = textNode->GetLayoutProperty<TextLayoutProperty>();
333     CHECK_NULL_VOID(textProp);
334     json->PutExtAttr("fontSize", textProp->GetFontSize().value_or(theme->GetFontSize()).ToString().c_str(), filter);
335     json->PutExtAttr("fontWeight", V2::ConvertWrapFontWeightToStirng(
336         textProp->GetFontWeight().value_or(FontWeight::NORMAL)).c_str(), filter);
337     json->PutExtAttr("fontFamily", "HarmonyOS Sans", filter);
338     json->PutExtAttr("fontStyle",
339         static_cast<int64_t>(textProp->GetItalicFontStyle().value_or(Ace::FontStyle::NORMAL)), filter);
340     json->PutExtAttr("fontColor",
341         textProp->GetTextColor().value_or(theme->GetFontColor()).ColorToString().c_str(), filter);
342 }
343 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const344 void SecurityComponentPattern::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
345 {
346     /* no fixed attr below, just return */
347     if (filter.IsFastFilter()) {
348         ToJsonValueRect(json, filter);
349         return;
350     }
351     auto node = GetHost();
352     CHECK_NULL_VOID(node);
353     auto* pipeline = node->GetContextWithCheck();
354     CHECK_NULL_VOID(pipeline);
355     auto theme = pipeline->GetTheme<SecurityComponentTheme>();
356     CHECK_NULL_VOID(theme);
357 
358     auto layoutProperty = AceType::DynamicCast<SecurityComponentLayoutProperty>(node->GetLayoutProperty());
359     CHECK_NULL_VOID(layoutProperty);
360     json->PutExtAttr("text", layoutProperty->GetSecurityComponentDescription().value_or(0), filter);
361     json->PutExtAttr("icon", layoutProperty->GetIconStyle().value_or(0), filter);
362     json->PutExtAttr("buttonType", layoutProperty->GetBackgroundType().value_or(0), filter);
363     json->PutExtAttr("layoutDirection", static_cast<int64_t>(
364         layoutProperty->GetTextIconLayoutDirection().value_or(SecurityComponentLayoutDirection::VERTICAL)), filter);
365     json->PutExtAttr("type", node->GetTag().c_str(), filter);
366 
367     RefPtr<FrameNode> iconNode = GetSecCompChildNode(node, V2::IMAGE_ETS_TAG);
368     if (iconNode != nullptr) {
369         ToJsonValueIconNode(json, iconNode, filter);
370     }
371     RefPtr<FrameNode> symbolIconNode = GetSecCompChildNode(node, V2::SYMBOL_ETS_TAG);
372     if (symbolIconNode != nullptr) {
373         ToJsonValueSymbolIconNode(json, symbolIconNode, filter);
374     }
375     RefPtr<FrameNode> textNode = GetSecCompChildNode(node, V2::TEXT_ETS_TAG);
376     if (textNode != nullptr) {
377         ToJsonValueTextNode(json, textNode, filter);
378     }
379     auto paddingJson = JsonUtil::Create(true);
380     CHECK_NULL_VOID(paddingJson);
381     paddingJson->Put("top",
382         layoutProperty->GetBackgroundTopPadding().value_or(theme->GetBackgroundTopPadding()).ToString().c_str());
383     paddingJson->Put("bottom",
384         layoutProperty->GetBackgroundBottomPadding().value_or(theme->GetBackgroundBottomPadding()).ToString().c_str());
385     paddingJson->Put("left",
386         layoutProperty->GetBackgroundLeftPadding().value_or(theme->GetBackgroundLeftPadding()).ToString().c_str());
387     paddingJson->Put("right",
388         layoutProperty->GetBackgroundRightPadding().value_or(theme->GetBackgroundRightPadding()).ToString().c_str());
389     json->PutExtAttr("padding", paddingJson, filter);
390     json->PutExtAttr("textIconSpace",
391         layoutProperty->GetTextIconSpace().value_or(theme->GetTextIconSpace()).ToString().c_str(), filter);
392     ToJsonValueRect(json, filter);
393 }
394 
ToJsonValueRect(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const395 void SecurityComponentPattern::ToJsonValueRect(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
396 {
397     /* no fixed attr below, just return */
398     if (filter.IsFastFilter()) {
399         return;
400     }
401     auto node = GetHost();
402     CHECK_NULL_VOID(node);
403     auto* pipeline = node->GetContextWithCheck();
404     CHECK_NULL_VOID(pipeline);
405     auto theme = pipeline->GetTheme<SecurityComponentTheme>();
406     CHECK_NULL_VOID(theme);
407 
408     RefPtr<FrameNode> buttonNode = GetSecCompChildNode(node, V2::BUTTON_ETS_TAG);
409     if (buttonNode != nullptr) {
410         const auto& renderContext = buttonNode->GetRenderContext();
411         CHECK_NULL_VOID(renderContext);
412         if (renderContext->HasBackgroundColor()) {
413             json->PutExtAttr("backgroundColor",
414                 renderContext->GetBackgroundColor().value().ColorToString().c_str(), filter);
415         } else {
416             json->PutExtAttr("backgroundColor", theme->GetBackgroundColor().ColorToString().c_str(), filter);
417         }
418         if (renderContext->HasBorderColor()) {
419             json->PutExtAttr("borderColor",
420                 renderContext->GetBorderColor()->leftColor.value_or(Color::BLACK).ColorToString().c_str(), filter);
421         } else {
422             json->PutExtAttr("borderColor", theme->GetBorderColor().ColorToString().c_str(), filter);
423         }
424         if (renderContext->HasBorderStyle()) {
425             json->PutExtAttr("borderStyle",
426                 static_cast<int>(renderContext->GetBorderStyle()->styleLeft.value_or(BorderStyle::NONE)), filter);
427         } else {
428             json->PutExtAttr("borderStyle", static_cast<int>(BorderStyle::NONE), filter);
429         }
430         auto bgProp = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
431         CHECK_NULL_VOID(bgProp);
432         const auto& borderWidth = bgProp->GetBorderWidthProperty();
433         if (borderWidth != nullptr) {
434             json->PutExtAttr("borderWidth",
435                 borderWidth->leftDimen.value_or(theme->GetBorderWidth()).ToString().c_str(), filter);
436         }
437         auto borderRadius = bgProp->GetBorderRadius();
438         if (borderRadius.has_value()) {
439             json->PutExtAttr("borderRadius", borderRadius->radiusTopLeft.value_or(theme->GetBorderRadius()).
440                 ToString().c_str(), filter);
441         } else {
442             json->PutExtAttr("borderRadius", theme->GetBorderRadius().ToString().c_str(), filter);
443         }
444     }
445 }
446 
GetFocusPattern() const447 FocusPattern SecurityComponentPattern::GetFocusPattern() const
448 {
449     auto frameNode = GetHost();
450     RefPtr<FrameNode> buttonNode = GetSecCompChildNode(frameNode, V2::BUTTON_ETS_TAG);
451     if (buttonNode != nullptr) {
452         auto buttonPattern = buttonNode->GetPattern<ButtonPattern>();
453         return buttonPattern->GetFocusPattern();
454     }
455 
456     return { FocusType::NODE, true, FocusStyleType::OUTER_BORDER };
457 }
458 
UpdateIconProperty(RefPtr<FrameNode> & scNode,RefPtr<FrameNode> & iconNode)459 void SecurityComponentPattern::UpdateIconProperty(RefPtr<FrameNode>& scNode, RefPtr<FrameNode>& iconNode)
460 {
461     auto iconLayoutProp = iconNode->GetLayoutProperty<ImageLayoutProperty>();
462     auto scLayoutProp = scNode->GetLayoutProperty<SecurityComponentLayoutProperty>();
463     CHECK_NULL_VOID(scLayoutProp);
464     if (scLayoutProp->GetIconSize().has_value()) {
465         auto iconSize = scLayoutProp->GetIconSize().value();
466         iconLayoutProp->UpdateUserDefinedIdealSize(CalcSize(NG::CalcLength(iconSize), NG::CalcLength(iconSize)));
467     }
468 
469     auto scPaintProp = scNode->GetPaintProperty<SecurityComponentPaintProperty>();
470     CHECK_NULL_VOID(scPaintProp);
471     if (scPaintProp->GetIconColor().has_value() && iconLayoutProp->GetImageSourceInfo().has_value()) {
472         auto iconSrcInfo = iconLayoutProp->GetImageSourceInfo().value();
473         iconSrcInfo.SetFillColor(scPaintProp->GetIconColor().value());
474         iconLayoutProp->UpdateImageSourceInfo(iconSrcInfo);
475     }
476 }
477 
UpdateTextProperty(RefPtr<FrameNode> & scNode,RefPtr<FrameNode> & textNode)478 void SecurityComponentPattern::UpdateTextProperty(RefPtr<FrameNode>& scNode, RefPtr<FrameNode>& textNode)
479 {
480     auto scLayoutProp = scNode->GetLayoutProperty<SecurityComponentLayoutProperty>();
481     auto textLayoutProp = textNode->GetLayoutProperty<TextLayoutProperty>();
482     if (scLayoutProp->GetFontSize().has_value()) {
483         textLayoutProp->UpdateFontSize(scLayoutProp->GetFontSize().value());
484     }
485     if (scLayoutProp->GetFontStyle().has_value()) {
486         textLayoutProp->UpdateItalicFontStyle(scLayoutProp->GetFontStyle().value());
487     }
488     if (scLayoutProp->GetFontWeight().has_value()) {
489         textLayoutProp->UpdateFontWeight(scLayoutProp->GetFontWeight().value());
490     }
491     if (scLayoutProp->GetFontFamily().has_value()) {
492         textLayoutProp->UpdateFontFamily(scLayoutProp->GetFontFamily().value());
493     }
494     auto scPaintProp = scNode->GetPaintProperty<SecurityComponentPaintProperty>();
495     if (scPaintProp->GetFontColor().has_value()) {
496         textLayoutProp->UpdateTextColor(scPaintProp->GetFontColor().value());
497     }
498     if (scLayoutProp->GetMaxFontScale().has_value()) {
499         textLayoutProp->UpdateMaxFontScale(scLayoutProp->GetMaxFontScale().value());
500     }
501     if (scLayoutProp->GetMinFontScale().has_value()) {
502         textLayoutProp->UpdateMinFontScale(scLayoutProp->GetMinFontScale().value());
503     }
504     if (scLayoutProp->GetMaxLines().has_value()) {
505         textLayoutProp->UpdateMaxLines(scLayoutProp->GetMaxLines().value());
506     }
507     if (scLayoutProp->GetAdaptMaxFontSize().has_value()) {
508         textLayoutProp->UpdateAdaptMaxFontSize(scLayoutProp->GetAdaptMaxFontSize().value());
509     }
510     if (scLayoutProp->GetAdaptMinFontSize().has_value()) {
511         textLayoutProp->UpdateAdaptMinFontSize(scLayoutProp->GetAdaptMinFontSize().value());
512     }
513     if (scLayoutProp->GetHeightAdaptivePolicy().has_value()) {
514         textLayoutProp->UpdateHeightAdaptivePolicy(scLayoutProp->GetHeightAdaptivePolicy().value());
515     }
516 }
517 
HandleEnabled()518 void SecurityComponentPattern::HandleEnabled()
519 {
520     auto host = GetHost();
521     CHECK_NULL_VOID(host);
522     auto eventHub = host->GetEventHub<EventHub>();
523     CHECK_NULL_VOID(eventHub);
524     auto enabled = eventHub->IsEnabled();
525     auto renderContext = host->GetRenderContext();
526     CHECK_NULL_VOID(renderContext);
527     auto* pipeline = host->GetContextWithCheck();
528     CHECK_NULL_VOID(pipeline);
529     auto theme = pipeline->GetTheme<SecurityComponentTheme>();
530     CHECK_NULL_VOID(theme);
531     auto alpha = theme->GetBgDisabledAlpha();
532     auto originalOpacity = renderContext->GetOpacityValue(1.0);
533     renderContext->OnOpacityUpdate(enabled ? originalOpacity : alpha * originalOpacity);
534 }
535 
UpdateButtonProperty(RefPtr<FrameNode> & scNode,RefPtr<FrameNode> & buttonNode)536 void SecurityComponentPattern::UpdateButtonProperty(RefPtr<FrameNode>& scNode, RefPtr<FrameNode>& buttonNode)
537 {
538     auto scLayoutProp = scNode->GetLayoutProperty<SecurityComponentLayoutProperty>();
539     auto scPaintProp = scNode->GetPaintProperty<SecurityComponentPaintProperty>();
540     auto buttonLayoutProp = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
541     const auto& buttonRender = buttonNode->GetRenderContext();
542     CHECK_NULL_VOID(buttonRender);
543     auto buttonEventHub = buttonNode->GetEventHub<ButtonEventHub>();
544     CHECK_NULL_VOID(buttonEventHub);
545 
546     if (scLayoutProp->GetBackgroundBorderWidth().has_value()) {
547         BorderWidthProperty widthProp;
548         widthProp.SetBorderWidth(scLayoutProp->GetBackgroundBorderWidth().value());
549         buttonLayoutProp->UpdateBorderWidth(widthProp);
550     }
551 
552     if (scPaintProp->GetBackgroundBorderStyle().has_value()) {
553         BorderStyleProperty style;
554         style.SetBorderStyle(scPaintProp->GetBackgroundBorderStyle().value());
555         buttonRender->UpdateBorderStyle(style);
556     }
557     if (scLayoutProp->GetBackgroundBorderRadius().has_value()) {
558         buttonLayoutProp->UpdateBorderRadius(
559             BorderRadiusProperty(scLayoutProp->GetBackgroundBorderRadius().value()));
560     }
561     if (scPaintProp->GetBackgroundColor().has_value()) {
562         buttonRender->UpdateBackgroundColor(scPaintProp->GetBackgroundColor().value());
563     }
564     if (scPaintProp->GetBackgroundBorderColor().has_value()) {
565         BorderColorProperty borderColor;
566         borderColor.SetColor(scPaintProp->GetBackgroundBorderColor().value());
567         buttonRender->UpdateBorderColor(borderColor);
568     }
569     if (scLayoutProp->GetStateEffect().has_value()) {
570         buttonEventHub->SetStateEffect(scLayoutProp->GetStateEffect().value());
571     }
572     if (scLayoutProp->GetHoverEffect().has_value()) {
573         auto inputHub = buttonEventHub->GetOrCreateInputEventHub();
574         CHECK_NULL_VOID(inputHub);
575         inputHub->SetHoverEffect(scLayoutProp->GetHoverEffect().value());
576     }
577     HandleEnabled();
578 }
579 
OnModifyDone()580 void SecurityComponentPattern::OnModifyDone()
581 {
582     auto frameNode = GetHost();
583     CHECK_NULL_VOID(frameNode);
584 
585     RefPtr<FrameNode> iconNode = GetSecCompChildNode(frameNode, V2::IMAGE_ETS_TAG);
586     if (iconNode != nullptr) {
587         UpdateIconProperty(frameNode, iconNode);
588         iconNode->MarkModifyDone();
589     }
590 
591     RefPtr<FrameNode> textNode = GetSecCompChildNode(frameNode, V2::TEXT_ETS_TAG);
592     if (textNode != nullptr) {
593         UpdateTextProperty(frameNode, textNode);
594         textNode->MarkModifyDone();
595     }
596 
597     RefPtr<FrameNode> buttonNode = GetSecCompChildNode(frameNode, V2::BUTTON_ETS_TAG);
598     if (buttonNode != nullptr) {
599         UpdateButtonProperty(frameNode, buttonNode);
600         buttonNode->MarkModifyDone();
601     }
602 
603     InitOnClick(frameNode, iconNode, textNode, buttonNode);
604     InitOnKeyEvent(frameNode);
605     InitAppearCallback(frameNode);
606     InitOnTouch(frameNode);
607 }
608 
IsFontColorSet()609 bool SecurityComponentPattern::IsFontColorSet()
610 {
611     auto frameNode = GetHost();
612     CHECK_NULL_RETURN(frameNode, false);
613     auto prop = frameNode->GetLayoutProperty<SecurityComponentLayoutProperty>();
614     if (prop && prop->GetIsFontColorSet().has_value()) {
615         return prop->GetIsFontColorSet().value();
616     }
617     return false;
618 }
619 
OnColorConfigurationUpdate()620 void SecurityComponentPattern::OnColorConfigurationUpdate()
621 {
622     auto node = GetHost();
623     CHECK_NULL_VOID(node);
624     node->SetNeedCallChildrenUpdate(IsFontColorSet());
625 }
626 
InitAppearCallback(RefPtr<FrameNode> & frameNode)627 void SecurityComponentPattern::InitAppearCallback(RefPtr<FrameNode>& frameNode)
628 {
629     if (isAppearCallback_) {
630         return;
631     }
632     auto eventHub = frameNode->GetEventHub<EventHub>();
633     CHECK_NULL_VOID(eventHub);
634 
635     auto context = frameNode->GetContextRefPtr();
636     CHECK_NULL_VOID(context);
637     auto instanceId = context->GetInstanceId();
638     auto onAppear = [weak = WeakClaim(this), instanceId]() {
639         ContainerScope scope(instanceId);
640 #ifdef SECURITY_COMPONENT_ENABLE
641         auto securityComponentPattern = weak.Upgrade();
642         CHECK_NULL_VOID(securityComponentPattern);
643         securityComponentPattern->isAppear_ = true;
644         securityComponentPattern->RegisterSecurityComponent();
645 #endif
646     };
647 
648     auto onDisAppear = [weak = WeakClaim(this)]() {
649 #ifdef SECURITY_COMPONENT_ENABLE
650         auto securityComponentPattern = weak.Upgrade();
651         CHECK_NULL_VOID(securityComponentPattern);
652         securityComponentPattern->isAppear_ = false;
653         securityComponentPattern->UnregisterSecurityComponent();
654 #endif
655     };
656     eventHub->SetOnAppear(std::move(onAppear));
657     eventHub->SetOnDisappear(std::move(onDisAppear));
658     isAppearCallback_ = true;
659 }
660 
OnWindowHide()661 void SecurityComponentPattern::OnWindowHide()
662 {
663 #ifdef SECURITY_COMPONENT_ENABLE
664     UnregisterSecurityComponent();
665 #endif
666 }
667 
OnWindowShow()668 void SecurityComponentPattern::OnWindowShow()
669 {
670 #ifdef SECURITY_COMPONENT_ENABLE
671     if (!isAppear_) {
672         return;
673     }
674     RegisterSecurityComponent();
675 #endif
676 }
677 
678 #ifdef SECURITY_COMPONENT_ENABLE
RegisterSecurityComponentRetry()679 void SecurityComponentPattern::RegisterSecurityComponentRetry()
680 {
681     auto frameNode = GetHost();
682     CHECK_NULL_VOID(frameNode);
683     // service is shutdowning, try to load it.
684     int32_t retryCount = MAX_RETRY_TIMES;
685     while (retryCount > 0) {
686         int32_t res = SecurityComponentHandler::RegisterSecurityComponent(frameNode, scId_);
687         if (res == Security::SecurityComponent::SCErrCode::SC_OK) {
688             regStatus_ = SecurityComponentRegisterStatus::REGISTERED;
689             return;
690         } else if (res != Security::SecurityComponent::SCErrCode::SC_SERVICE_ERROR_SERVICE_NOT_EXIST) {
691             SC_LOG_WARN("Register security component failed, err %{public}d.", res);
692             regStatus_ = SecurityComponentRegisterStatus::UNREGISTERED;
693             return;
694         }
695 
696         retryCount--;
697         std::this_thread::sleep_for(std::chrono::milliseconds(REGISTER_RETRY_INTERVAL));
698     }
699     regStatus_ = SecurityComponentRegisterStatus::UNREGISTERED;
700     SC_LOG_WARN("Register security component failed, retry %{public}d", MAX_RETRY_TIMES);
701 }
702 
RegisterSecurityComponent()703 void SecurityComponentPattern::RegisterSecurityComponent()
704 {
705     if (regStatus_ == SecurityComponentRegisterStatus::REGISTERED ||
706         regStatus_ == SecurityComponentRegisterStatus::REGISTERING) {
707         return;
708     }
709 
710     if (SecurityComponentHandler::IsSecurityComponentServiceExist()) {
711         RegisterSecurityComponentRetry();
712         return;
713     }
714     regStatus_ = SecurityComponentRegisterStatus::REGISTERING;
715     auto taskExecutor = Container::CurrentTaskExecutor();
716     CHECK_NULL_VOID(taskExecutor);
717     auto frameNode = GetHost();
718     CHECK_NULL_VOID(frameNode);
719     auto pipeline = frameNode->GetContextRefPtr();
720     CHECK_NULL_VOID(pipeline);
721     taskExecutor->PostTask(
722         [weak = WeakClaim(this), weakContext = WeakPtr(pipeline)] {
723             if (!SecurityComponentHandler::LoadSecurityComponentService()) {
724                 SC_LOG_WARN("load security component service failed.");
725                 return;
726             }
727             auto context = weakContext.Upgrade();
728             CHECK_NULL_VOID(context);
729             auto taskExecutor = context->GetTaskExecutor();
730             CHECK_NULL_VOID(taskExecutor);
731             taskExecutor->PostTask(
732                 [weak, instanceID = context->GetInstanceId()] {
733                     ContainerScope scope(instanceID);
734                     auto pattern = weak.Upgrade();
735                     CHECK_NULL_VOID(pattern);
736                     if (pattern->regStatus_ != SecurityComponentRegisterStatus::REGISTERING) {
737                         return;
738                     }
739 
740                     pattern->RegisterSecurityComponentRetry();
741                 },
742                 TaskExecutor::TaskType::UI, "ArkUISecurityComponentRegisterRetry");
743         },
744         TaskExecutor::TaskType::BACKGROUND, "ArkUISecurityComponentRegister");
745 }
746 
UnregisterSecurityComponent()747 void SecurityComponentPattern::UnregisterSecurityComponent()
748 {
749     if (regStatus_ == SecurityComponentRegisterStatus::REGISTERED) {
750         SecurityComponentHandler::UnregisterSecurityComponent(scId_);
751     } else {
752         SC_LOG_INFO("security component has not registered, regStatus %{public}d.", regStatus_);
753     }
754     regStatus_ = SecurityComponentRegisterStatus::UNREGISTERED;
755     scId_ = -1;
756 }
757 
DoTriggerOnclick(int32_t result)758 void SecurityComponentPattern::DoTriggerOnclick(int32_t result)
759 {
760     auto host = GetHost();
761     CHECK_NULL_VOID(host);
762     auto jsonNode = JsonUtil::Create(true);
763     CHECK_NULL_VOID(jsonNode);
764     if (result != 0) {
765         jsonNode->Put("handleRes", static_cast<int32_t>(SecurityComponentHandleResult::CLICK_GRANT_FAILED));
766     } else {
767         jsonNode->Put("handleRes", static_cast<int32_t>(SecurityComponentHandleResult::CLICK_SUCCESS));
768     }
769 
770     std::shared_ptr<JsonValue> jsonShrd(jsonNode.release());
771     auto gestureEventHub = host->GetOrCreateGestureEventHub();
772     CHECK_NULL_VOID(gestureEventHub);
773     gestureEventHub->ActClick(jsonShrd);
774 }
775 
DelayReleaseNode(uint64_t index)776 void SecurityComponentPattern::DelayReleaseNode(uint64_t index)
777 {
778     if (uiEventHandler_ == nullptr) {
779         SC_LOG_WARN("UIEventHandler invalid");
780         return;
781     }
782     bool res = uiEventHandler_->PostTask([index] {
783         std::lock_guard<std::mutex> lock(g_scMutex);
784         g_scNodeMap.erase(index);
785         if (g_omittedNodeIndex.size() != 0) {
786             for (auto item : g_omittedNodeIndex) {
787                 g_scNodeMap.erase(item);
788             }
789             g_omittedNodeIndex.clear();
790         }
791         SC_LOG_INFO("Security component frameNode cached size: %{public}zu, index: %{public}" PRId64,
792             g_scNodeMap.size(), index);
793         return;
794     },
795     DELAY_RELEASE_MILLSEC);
796     if (!res) {
797         SC_LOG_ERROR("Security component post task failed.");
798         g_omittedNodeIndex.push_back(index);
799     }
800 }
801 
CreateFirstUseDialogCloseFunc(RefPtr<FrameNode> & frameNode,RefPtr<PipelineContext> & pipeline,const std::string & taskName)802 std::function<int32_t(int32_t)> SecurityComponentPattern::CreateFirstUseDialogCloseFunc(
803     RefPtr<FrameNode>& frameNode, RefPtr<PipelineContext>& pipeline, const std::string& taskName)
804 {
805     return [weak = WeakClaim(this), weakContext = WeakPtr(pipeline),
806         node = frameNode, taskName = taskName](int32_t result) mutable {
807         std::lock_guard<std::mutex> lock(g_scMutex);
808         g_scNodeMap[++g_scIndex] = std::move(node);
809         auto pattern = weak.Upgrade();
810         if (pattern == nullptr) {
811             return -1;
812         }
813         auto context = weakContext.Upgrade();
814         if (context == nullptr) {
815             pattern->DelayReleaseNode(g_scIndex);
816             return -1;
817         }
818         auto taskExecutor = context->GetTaskExecutor();
819         if (taskExecutor == nullptr) {
820             pattern->DelayReleaseNode(g_scIndex);
821             return -1;
822         }
823         bool res = taskExecutor->PostTask(
824             [weak, instanceId = context->GetInstanceId(), result, index = g_scIndex] {
825                 ContainerScope scope(instanceId);
826                 std::lock_guard<std::mutex> lock(g_scMutex);
827                 SC_LOG_INFO("Security component frameNode cached size: %{public}zu, index: %{public}" PRId64,
828                     g_scNodeMap.size(), index);
829                 if (g_omittedNodeIndex.size() != 0) {
830                     for (auto item : g_omittedNodeIndex) {
831                         g_scNodeMap.erase(item);
832                     }
833                     g_omittedNodeIndex.clear();
834                 }
835                 if (result == static_cast<int32_t>(SecurityComponentHandleResult::GRANT_CANCEL)) {
836                     g_scNodeMap.erase(index);
837                     return;
838                 }
839                 auto pattern = weak.Upgrade();
840                 if (pattern == nullptr) {
841                     g_scNodeMap.erase(index);
842                     return;
843                 }
844                 pattern->DoTriggerOnclick(result);
845                 g_scNodeMap.erase(index);
846             },
847             TaskExecutor::TaskType::UI, taskName);
848         if (!res) {
849             SC_LOG_ERROR("Security component post task failed.");
850             g_omittedNodeIndex.push_back(g_scIndex);
851         }
852         return 0;
853     };
854 }
855 
ReportSecurityComponentClickEvent(GestureEvent & event,std::string & message)856 int32_t SecurityComponentPattern::ReportSecurityComponentClickEvent(GestureEvent& event, std::string& message)
857 {
858     if (regStatus_ == SecurityComponentRegisterStatus::UNREGISTERED) {
859         SC_LOG_WARN("ClickEventHandler: security component has not registered.");
860         return -1;
861     }
862     auto frameNode = GetHost();
863     CHECK_NULL_RETURN(frameNode, -1);
864     if (regStatus_ == SecurityComponentRegisterStatus::REGISTERING) {
865         RegisterSecurityComponentRetry();
866     }
867     if (regStatus_ != SecurityComponentRegisterStatus::REGISTERED) {
868         SC_LOG_WARN("ClickEventHandler: security component try to register failed.");
869         return -1;
870     }
871 
872     auto pipeline = frameNode->GetContextRefPtr();
873     CHECK_NULL_RETURN(pipeline, -1);
874     std::function<void (int32_t)> OnClickAfterFirstUseDialog;
875     if (frameNode->GetTag() == V2::PASTE_BUTTON_ETS_TAG) {
876         OnClickAfterFirstUseDialog = [] (int32_t) {};
877         return SecurityComponentHandler::ReportSecurityComponentClickEvent(scId_,
878             frameNode, event, std::move(OnClickAfterFirstUseDialog), message);
879     }
880 
881     OnClickAfterFirstUseDialog = CreateFirstUseDialogCloseFunc(
882         frameNode, pipeline, "ArkUISecurityComponentGestureTriggerOnClick");
883 
884     return SecurityComponentHandler::ReportSecurityComponentClickEvent(scId_,
885         frameNode, event, std::move(OnClickAfterFirstUseDialog), message);
886 }
887 
ReportSecurityComponentClickEvent(const KeyEvent & event)888 int32_t SecurityComponentPattern::ReportSecurityComponentClickEvent(const KeyEvent& event)
889 {
890     if (regStatus_ == SecurityComponentRegisterStatus::UNREGISTERED) {
891         SC_LOG_WARN("KeyEventHandler: security component has not registered.");
892         return -1;
893     }
894     auto frameNode = GetHost();
895     CHECK_NULL_RETURN(frameNode, -1);
896     if (regStatus_ == SecurityComponentRegisterStatus::REGISTERING) {
897         RegisterSecurityComponentRetry();
898     }
899     if (regStatus_ != SecurityComponentRegisterStatus::REGISTERED) {
900         SC_LOG_WARN("KeyEventHandler: security component try to register failed.");
901         return -1;
902     }
903 
904     auto pipeline = frameNode->GetContextRefPtr();
905     CHECK_NULL_RETURN(pipeline, -1);
906     std::function<void (int32_t)> OnClickAfterFirstUseDialog;
907     if (frameNode->GetTag() == V2::PASTE_BUTTON_ETS_TAG) {
908         OnClickAfterFirstUseDialog = [] (int32_t) {};
909         return SecurityComponentHandler::ReportSecurityComponentClickEvent(scId_,
910             frameNode, event, std::move(OnClickAfterFirstUseDialog));
911     }
912 
913     OnClickAfterFirstUseDialog = CreateFirstUseDialogCloseFunc(
914         frameNode, pipeline, "ArkUISecurityComponentKeyTriggerOnClick");
915 
916     return SecurityComponentHandler::ReportSecurityComponentClickEvent(scId_,
917         frameNode, event, std::move(OnClickAfterFirstUseDialog));
918 }
919 
HandleReportSecCompClickEventResult(int32_t & code,std::string & message)920 void SecurityComponentPattern::HandleReportSecCompClickEventResult(int32_t& code, std::string& message)
921 {
922     if (!message.empty()) {
923         code = SecurityComponentErrorCode::PROPERTY_SETING_ERROR;
924     }
925 
926     if (code != SecurityComponentErrorCode::SUCCESS && message.empty()) {
927         message = SYSTEM_INTERNAL_ERROR_MESSAGE;
928         code = SecurityComponentErrorCode::SYSTEM_INTERNAL_ERROR;
929     }
930 }
931 #endif
932 } // namespace OHOS::Ace::NG
933