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