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