1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/components_ng/pattern/security_component/security_component_pattern.h"
17 #include "base/log/ace_scoring_log.h"
18 #include "core/components_ng/base/inspector_filter.h"
19 #include "core/components_ng/pattern/button/button_layout_property.h"
20 #include "core/components_ng/pattern/button/button_pattern.h"
21 #include "core/components_ng/pattern/image/image_pattern.h"
22 #ifdef SECURITY_COMPONENT_ENABLE
23 #include "core/components_ng/pattern/security_component/security_component_handler.h"
24 #endif
25 #include "core/components_ng/pattern/security_component/security_component_log.h"
26 #include "core/components_ng/pattern/security_component/security_component_theme.h"
27 #include "core/components_ng/pattern/text/text_layout_property.h"
28 #include "core/components/common/layout/constants.h"
29 #include "core/components_v2/inspector/inspector_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 #endif
39 }
SecurityComponentPattern()40 SecurityComponentPattern::SecurityComponentPattern()
41 {
42 #ifdef SECURITY_COMPONENT_ENABLE
43 uiEventHandler_ = OHOS::AppExecFwk::EventHandler::Current();
44 #endif
45 }
46
~SecurityComponentPattern()47 SecurityComponentPattern::~SecurityComponentPattern()
48 {
49 #ifdef SECURITY_COMPONENT_ENABLE
50 UnregisterSecurityComponent();
51 #endif
52 }
53
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)54 bool SecurityComponentPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty,
55 const DirtySwapConfig& config)
56 {
57 CHECK_NULL_RETURN(dirty, false);
58 return !(config.skipMeasure || dirty->SkipMeasureContent());
59 }
60
SetNodeHitTestMode(RefPtr<FrameNode> & node,HitTestMode mode)61 void SecurityComponentPattern::SetNodeHitTestMode(RefPtr<FrameNode>& node, HitTestMode mode)
62 {
63 if (node == nullptr) {
64 return;
65 }
66 auto gestureHub = node->GetOrCreateGestureEventHub();
67 CHECK_NULL_VOID(gestureHub);
68 gestureHub->SetHitTestMode(mode);
69 }
70
OnKeyEvent(const KeyEvent & event)71 bool SecurityComponentPattern::OnKeyEvent(const KeyEvent& event)
72 {
73 if (event.action != KeyAction::DOWN) {
74 return false;
75 }
76 if ((event.code == KeyCode::KEY_SPACE) || (event.code == KeyCode::KEY_ENTER) ||
77 (event.code == KeyCode::KEY_NUMPAD_ENTER)) {
78 auto frameNode = GetHost();
79 CHECK_NULL_RETURN(frameNode, false);
80 int32_t res = 1;
81 #ifdef SECURITY_COMPONENT_ENABLE
82 res = ReportSecurityComponentClickEvent(event);
83 if (res == Security::SecurityComponent::SC_SERVICE_ERROR_WAIT_FOR_DIALOG_CLOSE) {
84 res = static_cast<int32_t>(SecurityComponentHandleResult::DROP_CLICK);
85 } else if (res != 0) {
86 SC_LOG_ERROR("ReportSecurityComponentClickEvent failed, errno %{public}d", res);
87 res = 1;
88 }
89 #endif
90 auto jsonNode = JsonUtil::Create(true);
91 CHECK_NULL_RETURN(jsonNode, false);
92 jsonNode->Put("handleRes", res);
93 std::shared_ptr<JsonValue> jsonShrd(jsonNode.release());
94 auto gestureEventHub = frameNode->GetOrCreateGestureEventHub();
95 gestureEventHub->ActClick(jsonShrd);
96 return true;
97 }
98 return false;
99 }
100
InitOnKeyEvent(RefPtr<FrameNode> & secCompNode)101 void SecurityComponentPattern::InitOnKeyEvent(RefPtr<FrameNode>& secCompNode)
102 {
103 if (isSetOnKeyEvent) {
104 return;
105 }
106 auto focusHub = secCompNode->GetOrCreateFocusHub();
107 auto onKeyEvent = [wp = WeakClaim(this)](const KeyEvent& event) -> bool {
108 auto pattern = wp.Upgrade();
109 if (!pattern) {
110 return false;
111 }
112 return pattern->OnKeyEvent(event);
113 };
114 focusHub->SetOnKeyEventInternal(std::move(onKeyEvent));
115 isSetOnKeyEvent = true;
116 }
117
IsParentMenu(RefPtr<FrameNode> & secCompNode)118 bool SecurityComponentPattern::IsParentMenu(RefPtr<FrameNode>& secCompNode)
119 {
120 auto parent = secCompNode->GetParent();
121 while (parent != nullptr) {
122 if (parent->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
123 return true;
124 }
125 parent = parent->GetParent();
126 }
127 return false;
128 }
129
HandleClickEventFromTouch(const TouchEventInfo & info)130 void SecurityComponentPattern::HandleClickEventFromTouch(const TouchEventInfo& info)
131 {
132 #ifdef SECURITY_COMPONENT_ENABLE
133 auto host = GetHost();
134 CHECK_NULL_VOID(host);
135
136 if (!IsParentMenu(host)) {
137 return;
138 }
139
140 auto pointerEvent = info.GetPointerEvent();
141 CHECK_NULL_VOID(pointerEvent);
142
143 int32_t pointerId = pointerEvent->GetPointerId();
144 MMI::PointerEvent::PointerItem item;
145 if (!pointerEvent->GetPointerItem(pointerId, item)) {
146 SC_LOG_WARN("Get pointer item failed");
147 return;
148 }
149
150 GestureEvent gestureInfo;
151 gestureInfo.SetDisplayX(item.GetDisplayX());
152 gestureInfo.SetDisplayY(item.GetDisplayY());
153 gestureInfo.SetPointerEvent(info.GetPointerEvent());
154 int res = ReportSecurityComponentClickEvent(gestureInfo);
155 if (res == Security::SecurityComponent::SC_SERVICE_ERROR_WAIT_FOR_DIALOG_CLOSE) {
156 return;
157 }
158 if (res != 0) {
159 SC_LOG_WARN("ReportSecurityComponentClickEvent failed, errno %{public}d", res);
160 res = 1;
161 }
162 auto jsonNode = JsonUtil::Create(true);
163 CHECK_NULL_VOID(jsonNode);
164 jsonNode->Put("handleRes", res);
165 std::shared_ptr<JsonValue> jsonShrd(jsonNode.release());
166 auto gestureEventHub = host->GetOrCreateGestureEventHub();
167 gestureEventHub->ActClick(jsonShrd);
168 #endif
169 }
170
171 // When security component is a child node of menu wrapper, the menu is immediately hidden
172 // after being touched, and then the security component will trigger a click event.
173 // However, it will be considered to have been triggered in a hidden state,
174 // Therefore, we should report click event on UP touch event.
OnTouch(const TouchEventInfo & info)175 void SecurityComponentPattern::OnTouch(const TouchEventInfo& info)
176 {
177 auto touchType = info.GetTouches().front().GetTouchType();
178 if (touchType == TouchType::DOWN) {
179 lastTouchOffset_ = std::make_unique<Offset>(info.GetTouches().front().GetLocalLocation());
180 } else if (touchType == TouchType::UP) {
181 auto touchUpOffset = info.GetTouches().front().GetLocalLocation();
182 if (lastTouchOffset_ &&
183 (touchUpOffset - *lastTouchOffset_).GetDistance() <= DEFAULT_SECURITY_COMPONENT_CLICK_DISTANCE) {
184 HandleClickEventFromTouch(info);
185 }
186 lastTouchOffset_.reset();
187 }
188 }
189
InitOnTouch(RefPtr<FrameNode> & secCompNode)190 void SecurityComponentPattern::InitOnTouch(RefPtr<FrameNode>& secCompNode)
191 {
192 if (onTouchListener_ != nullptr) {
193 return;
194 }
195 auto gestureHub = secCompNode->GetOrCreateGestureEventHub();
196 CHECK_NULL_VOID(gestureHub);
197
198 auto touchCallback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
199 auto pattern = weak.Upgrade();
200 CHECK_NULL_VOID(pattern);
201 pattern->OnTouch(info);
202 };
203 onTouchListener_ = MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
204 gestureHub->AddTouchEvent(onTouchListener_);
205 }
206
InitOnClick(RefPtr<FrameNode> & secCompNode,RefPtr<FrameNode> & icon,RefPtr<FrameNode> & text,RefPtr<FrameNode> & button)207 void SecurityComponentPattern::InitOnClick(RefPtr<FrameNode>& secCompNode, RefPtr<FrameNode>& icon,
208 RefPtr<FrameNode>& text, RefPtr<FrameNode>& button)
209 {
210 if (clickListener_ != nullptr) {
211 return;
212 }
213 auto secCompGesture = secCompNode->GetOrCreateGestureEventHub();
214 CHECK_NULL_VOID(secCompGesture);
215 auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
216 #ifdef SECURITY_COMPONENT_ENABLE
217 auto buttonPattern = weak.Upgrade();
218 CHECK_NULL_VOID(buttonPattern);
219 auto frameNode = buttonPattern->GetHost();
220 CHECK_NULL_VOID(frameNode);
221 if (info.GetSecCompHandleEvent()) {
222 return;
223 }
224 auto jsonNode = JsonUtil::Create(true);
225 CHECK_NULL_VOID(jsonNode);
226 std::shared_ptr<JsonValue> jsonShrd(jsonNode.release());
227 int32_t res;
228 // if info.GetPointerEvent() is null, device may in screen read mode
229 // otherwise, this event should be dropped in menu
230 if (buttonPattern->IsParentMenu(frameNode) && info.GetPointerEvent() != nullptr) {
231 res = static_cast<int32_t>(SecurityComponentHandleResult::DROP_CLICK);
232 } else {
233 res = buttonPattern->ReportSecurityComponentClickEvent(info);
234 if (res == Security::SecurityComponent::SC_SERVICE_ERROR_WAIT_FOR_DIALOG_CLOSE) {
235 res = static_cast<int32_t>(SecurityComponentHandleResult::DROP_CLICK);
236 } else if (res != 0) {
237 SC_LOG_WARN("ReportSecurityComponentClickEvent failed, errno %{public}d", res);
238 res = static_cast<int32_t>(SecurityComponentHandleResult::CLICK_GRANT_FAILED);
239 }
240 }
241 jsonShrd->Put("handleRes", res);
242 info.SetSecCompHandleEvent(jsonShrd);
243 #endif
244 };
245
246 clickListener_ = MakeRefPtr<ClickEvent>(std::move(clickCallback));
247 secCompGesture->AddClickEvent(clickListener_);
248 SetNodeHitTestMode(icon, HitTestMode::HTMTRANSPARENT);
249 SetNodeHitTestMode(text, HitTestMode::HTMTRANSPARENT);
250 }
251
ToJsonValueIconNode(std::unique_ptr<JsonValue> & json,const RefPtr<FrameNode> & iconNode,const InspectorFilter & filter) const252 void SecurityComponentPattern::ToJsonValueIconNode(std::unique_ptr<JsonValue>& json, const RefPtr<FrameNode>& iconNode,
253 const InspectorFilter& filter) const
254 {
255 auto iconProp = iconNode->GetLayoutProperty<ImageLayoutProperty>();
256 CHECK_NULL_VOID(iconProp);
257 json->PutExtAttr("iconSize",
258 iconProp->GetCalcLayoutConstraint()->selfIdealSize->Width()->GetDimension().ToString().c_str(), filter);
259 json->PutExtAttr("iconColor", iconProp->GetImageSourceInfo().value().GetFillColor().
260 value_or(Color::WHITE).ColorToString().c_str(), filter);
261 }
262
ToJsonValueTextNode(std::unique_ptr<JsonValue> & json,const RefPtr<FrameNode> & textNode,const InspectorFilter & filter) const263 void SecurityComponentPattern::ToJsonValueTextNode(std::unique_ptr<JsonValue>& json, const RefPtr<FrameNode>& textNode,
264 const InspectorFilter& filter) const
265 {
266 auto textProp = textNode->GetLayoutProperty<TextLayoutProperty>();
267 CHECK_NULL_VOID(textProp);
268 json->PutExtAttr("fontSize", textProp->GetFontSize().value_or(Dimension(0.0)).ToString().c_str(), filter);
269 json->PutExtAttr("fontWeight", V2::ConvertWrapFontWeightToStirng(
270 textProp->GetFontWeight().value_or(FontWeight::NORMAL)).c_str(), filter);
271 json->PutExtAttr("fontFamily", "HarmonyOS Sans", filter);
272 json->PutExtAttr("fontStyle",
273 static_cast<int64_t>(textProp->GetItalicFontStyle().value_or(Ace::FontStyle::NORMAL)), filter);
274 json->PutExtAttr("fontColor", textProp->GetTextColor().value_or(Color::WHITE).ColorToString().c_str(), filter);
275 }
276
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const277 void SecurityComponentPattern::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
278 {
279 /* no fixed attr below, just return */
280 if (filter.IsFastFilter()) {
281 ToJsonValueRect(json, filter);
282 return;
283 }
284 auto node = GetHost();
285 CHECK_NULL_VOID(node);
286
287 auto layoutProperty = AceType::DynamicCast<SecurityComponentLayoutProperty>(node->GetLayoutProperty());
288 CHECK_NULL_VOID(layoutProperty);
289 json->PutExtAttr("text", layoutProperty->GetSecurityComponentDescription().value_or(0), filter);
290 json->PutExtAttr("icon", layoutProperty->GetIconStyle().value_or(0), filter);
291 json->PutExtAttr("buttonType", layoutProperty->GetBackgroundType().value_or(0), filter);
292 json->PutExtAttr("layoutDirection", static_cast<int64_t>(
293 layoutProperty->GetTextIconLayoutDirection().value_or(SecurityComponentLayoutDirection::VERTICAL)), filter);
294 json->PutExtAttr("type", node->GetTag().c_str(), filter);
295
296 RefPtr<FrameNode> iconNode = GetSecCompChildNode(node, V2::IMAGE_ETS_TAG);
297 if (iconNode != nullptr) {
298 ToJsonValueIconNode(json, iconNode, filter);
299 }
300 RefPtr<FrameNode> textNode = GetSecCompChildNode(node, V2::TEXT_ETS_TAG);
301 if (textNode != nullptr) {
302 ToJsonValueTextNode(json, textNode, filter);
303 }
304 auto paddingJson = JsonUtil::Create(true);
305 CHECK_NULL_VOID(paddingJson);
306 paddingJson->Put("top", layoutProperty->GetBackgroundTopPadding().value_or(Dimension(0.0)).ToString().c_str());
307 paddingJson->Put("bottom",
308 layoutProperty->GetBackgroundBottomPadding().value_or(Dimension(0.0)).ToString().c_str());
309 paddingJson->Put("left", layoutProperty->GetBackgroundLeftPadding().value_or(Dimension(0.0)).ToString().c_str());
310 paddingJson->Put("right", layoutProperty->GetBackgroundRightPadding().value_or(Dimension(0.0)).ToString().c_str());
311 json->PutExtAttr("padding", paddingJson, filter);
312 json->PutExtAttr("textIconSpace",
313 layoutProperty->GetTextIconSpace().value_or(Dimension(0.0)).ToString().c_str(), filter);
314 ToJsonValueRect(json, filter);
315 }
316
ToJsonValueRect(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const317 void SecurityComponentPattern::ToJsonValueRect(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
318 {
319 /* no fixed attr below, just return */
320 if (filter.IsFastFilter()) {
321 return;
322 }
323 auto node = GetHost();
324 CHECK_NULL_VOID(node);
325
326 RefPtr<FrameNode> buttonNode = GetSecCompChildNode(node, V2::BUTTON_ETS_TAG);
327 if (buttonNode != nullptr) {
328 const auto& renderContext = buttonNode->GetRenderContext();
329 CHECK_NULL_VOID(renderContext);
330 json->PutExtAttr("backgroundColor",
331 renderContext->GetBackgroundColor().value().ColorToString().c_str(), filter);
332 json->PutExtAttr("borderColor",
333 renderContext->GetBorderColor()->leftColor.value_or(Color::BLACK).ColorToString().c_str(), filter);
334 json->PutExtAttr("borderStyle",
335 static_cast<int>(renderContext->GetBorderStyle()->styleLeft.value_or(BorderStyle::NONE)), filter);
336 auto bgProp = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
337 CHECK_NULL_VOID(bgProp);
338 const auto& borderWidth = bgProp->GetBorderWidthProperty();
339 if (borderWidth != nullptr) {
340 json->PutExtAttr("borderWidth",
341 borderWidth->leftDimen.value_or(Dimension(0.0)).ToString().c_str(), filter);
342 }
343 auto borderRadius = bgProp->GetBorderRadius();
344 if (borderRadius.has_value()) {
345 json->PutExtAttr("borderRadius", borderRadius->radiusTopLeft.value_or(Dimension(0.0, DimensionUnit::VP)).
346 ToString().c_str(), filter);
347 } else {
348 json->PutExtAttr("borderRadius", "0.00vp", filter);
349 }
350 }
351 }
352
GetFocusPattern() const353 FocusPattern SecurityComponentPattern::GetFocusPattern() const
354 {
355 auto frameNode = GetHost();
356 RefPtr<FrameNode> buttonNode = GetSecCompChildNode(frameNode, V2::BUTTON_ETS_TAG);
357 if (buttonNode != nullptr) {
358 auto buttonPattern = buttonNode->GetPattern<ButtonPattern>();
359 return buttonPattern->GetFocusPattern();
360 }
361
362 return { FocusType::NODE, true, FocusStyleType::OUTER_BORDER };
363 }
364
UpdateIconProperty(RefPtr<FrameNode> & scNode,RefPtr<FrameNode> & iconNode)365 void SecurityComponentPattern::UpdateIconProperty(RefPtr<FrameNode>& scNode, RefPtr<FrameNode>& iconNode)
366 {
367 auto iconLayoutProp = iconNode->GetLayoutProperty<ImageLayoutProperty>();
368 auto scLayoutProp = scNode->GetLayoutProperty<SecurityComponentLayoutProperty>();
369 CHECK_NULL_VOID(scLayoutProp);
370 if (scLayoutProp->GetIconSize().has_value()) {
371 auto iconSize = scLayoutProp->GetIconSize().value();
372 iconLayoutProp->UpdateUserDefinedIdealSize(CalcSize(NG::CalcLength(iconSize), NG::CalcLength(iconSize)));
373 }
374
375 auto scPaintProp = scNode->GetPaintProperty<SecurityComponentPaintProperty>();
376 CHECK_NULL_VOID(scPaintProp);
377 if (scPaintProp->GetIconColor().has_value() && iconLayoutProp->GetImageSourceInfo().has_value()) {
378 auto iconSrcInfo = iconLayoutProp->GetImageSourceInfo().value();
379 iconSrcInfo.SetFillColor(scPaintProp->GetIconColor().value());
380 iconLayoutProp->UpdateImageSourceInfo(iconSrcInfo);
381 }
382 }
383
UpdateTextProperty(RefPtr<FrameNode> & scNode,RefPtr<FrameNode> & textNode)384 void SecurityComponentPattern::UpdateTextProperty(RefPtr<FrameNode>& scNode, RefPtr<FrameNode>& textNode)
385 {
386 auto scLayoutProp = scNode->GetLayoutProperty<SecurityComponentLayoutProperty>();
387 auto textLayoutProp = textNode->GetLayoutProperty<TextLayoutProperty>();
388 if (scLayoutProp->GetFontSize().has_value()) {
389 textLayoutProp->UpdateFontSize(scLayoutProp->GetFontSize().value());
390 }
391 if (scLayoutProp->GetFontStyle().has_value()) {
392 textLayoutProp->UpdateItalicFontStyle(scLayoutProp->GetFontStyle().value());
393 }
394 if (scLayoutProp->GetFontWeight().has_value()) {
395 textLayoutProp->UpdateFontWeight(scLayoutProp->GetFontWeight().value());
396 }
397 if (scLayoutProp->GetFontFamily().has_value()) {
398 textLayoutProp->UpdateFontFamily(scLayoutProp->GetFontFamily().value());
399 }
400 auto scPaintProp = scNode->GetPaintProperty<SecurityComponentPaintProperty>();
401 if (scPaintProp->GetFontColor().has_value()) {
402 textLayoutProp->UpdateTextColor(scPaintProp->GetFontColor().value());
403 }
404 }
405
UpdateButtonProperty(RefPtr<FrameNode> & scNode,RefPtr<FrameNode> & buttonNode)406 void SecurityComponentPattern::UpdateButtonProperty(RefPtr<FrameNode>& scNode, RefPtr<FrameNode>& buttonNode)
407 {
408 auto scLayoutProp = scNode->GetLayoutProperty<SecurityComponentLayoutProperty>();
409 auto scPaintProp = scNode->GetPaintProperty<SecurityComponentPaintProperty>();
410 auto buttonLayoutProp = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
411 const auto& buttonRender = buttonNode->GetRenderContext();
412 CHECK_NULL_VOID(buttonRender);
413
414 if (scLayoutProp->GetBackgroundBorderWidth().has_value()) {
415 BorderWidthProperty widthProp;
416 widthProp.SetBorderWidth(scLayoutProp->GetBackgroundBorderWidth().value());
417 buttonLayoutProp->UpdateBorderWidth(widthProp);
418 }
419
420 if (scPaintProp->GetBackgroundBorderStyle().has_value()) {
421 BorderStyleProperty style;
422 style.SetBorderStyle(scPaintProp->GetBackgroundBorderStyle().value());
423 buttonRender->UpdateBorderStyle(style);
424 }
425 if (scLayoutProp->GetBackgroundBorderRadius().has_value()) {
426 buttonLayoutProp->UpdateBorderRadius(
427 BorderRadiusProperty(scLayoutProp->GetBackgroundBorderRadius().value()));
428 }
429 if (scPaintProp->GetBackgroundColor().has_value()) {
430 buttonRender->UpdateBackgroundColor(scPaintProp->GetBackgroundColor().value());
431 }
432 if (scPaintProp->GetBackgroundBorderColor().has_value()) {
433 BorderColorProperty borderColor;
434 borderColor.SetColor(scPaintProp->GetBackgroundBorderColor().value());
435 buttonRender->UpdateBorderColor(borderColor);
436 }
437 }
438
OnModifyDone()439 void SecurityComponentPattern::OnModifyDone()
440 {
441 auto frameNode = GetHost();
442 CHECK_NULL_VOID(frameNode);
443
444 RefPtr<FrameNode> iconNode = GetSecCompChildNode(frameNode, V2::IMAGE_ETS_TAG);
445 if (iconNode != nullptr) {
446 UpdateIconProperty(frameNode, iconNode);
447 iconNode->MarkModifyDone();
448 }
449
450 RefPtr<FrameNode> textNode = GetSecCompChildNode(frameNode, V2::TEXT_ETS_TAG);
451 if (textNode != nullptr) {
452 UpdateTextProperty(frameNode, textNode);
453 textNode->MarkModifyDone();
454 }
455
456 RefPtr<FrameNode> buttonNode = GetSecCompChildNode(frameNode, V2::BUTTON_ETS_TAG);
457 if (buttonNode != nullptr) {
458 UpdateButtonProperty(frameNode, buttonNode);
459 buttonNode->MarkModifyDone();
460 }
461
462 InitOnClick(frameNode, iconNode, textNode, buttonNode);
463 InitOnKeyEvent(frameNode);
464 InitAppearCallback(frameNode);
465 InitOnTouch(frameNode);
466 }
467
IsFontColorSet()468 bool SecurityComponentPattern::IsFontColorSet()
469 {
470 auto frameNode = GetHost();
471 CHECK_NULL_RETURN(frameNode, false);
472 auto prop = frameNode->GetLayoutProperty<SecurityComponentLayoutProperty>();
473 if (prop && prop->GetIsFontColorSet().has_value()) {
474 return prop->GetIsFontColorSet().value();
475 }
476 return false;
477 }
478
OnColorConfigurationUpdate()479 void SecurityComponentPattern::OnColorConfigurationUpdate()
480 {
481 auto node = GetHost();
482 CHECK_NULL_VOID(node);
483 node->SetNeedCallChildrenUpdate(IsFontColorSet());
484 }
485
InitAppearCallback(RefPtr<FrameNode> & frameNode)486 void SecurityComponentPattern::InitAppearCallback(RefPtr<FrameNode>& frameNode)
487 {
488 if (isAppearCallback_) {
489 return;
490 }
491 auto eventHub = frameNode->GetEventHub<EventHub>();
492 CHECK_NULL_VOID(eventHub);
493
494 auto context = frameNode->GetContextRefPtr();
495 CHECK_NULL_VOID(context);
496 auto instanceId = context->GetInstanceId();
497 auto onAppear = [weak = WeakClaim(this), instanceId]() {
498 ContainerScope scope(instanceId);
499 #ifdef SECURITY_COMPONENT_ENABLE
500 auto securityComponentPattern = weak.Upgrade();
501 CHECK_NULL_VOID(securityComponentPattern);
502 securityComponentPattern->isAppear_ = true;
503 securityComponentPattern->RegisterSecurityComponent();
504 #endif
505 };
506
507 auto onDisAppear = [weak = WeakClaim(this)]() {
508 #ifdef SECURITY_COMPONENT_ENABLE
509 auto securityComponentPattern = weak.Upgrade();
510 CHECK_NULL_VOID(securityComponentPattern);
511 securityComponentPattern->isAppear_ = false;
512 securityComponentPattern->UnregisterSecurityComponent();
513 #endif
514 };
515 eventHub->SetOnAppear(std::move(onAppear));
516 eventHub->SetOnDisappear(std::move(onDisAppear));
517 isAppearCallback_ = true;
518 }
519
OnWindowHide()520 void SecurityComponentPattern::OnWindowHide()
521 {
522 #ifdef SECURITY_COMPONENT_ENABLE
523 UnregisterSecurityComponent();
524 #endif
525 }
526
OnWindowShow()527 void SecurityComponentPattern::OnWindowShow()
528 {
529 #ifdef SECURITY_COMPONENT_ENABLE
530 if (!isAppear_) {
531 return;
532 }
533 RegisterSecurityComponent();
534 #endif
535 }
536
537 #ifdef SECURITY_COMPONENT_ENABLE
RegisterSecurityComponentRetry()538 void SecurityComponentPattern::RegisterSecurityComponentRetry()
539 {
540 auto frameNode = GetHost();
541 CHECK_NULL_VOID(frameNode);
542 // service is shutdowning, try to load it.
543 int32_t retryCount = MAX_RETRY_TIMES;
544 while (retryCount > 0) {
545 int32_t res = SecurityComponentHandler::RegisterSecurityComponent(frameNode, scId_);
546 if (res == Security::SecurityComponent::SCErrCode::SC_OK) {
547 regStatus_ = SecurityComponentRegisterStatus::REGISTERED;
548 return;
549 } else if (res != Security::SecurityComponent::SCErrCode::SC_SERVICE_ERROR_SERVICE_NOT_EXIST) {
550 SC_LOG_WARN("Register security component failed, err %{public}d.", res);
551 regStatus_ = SecurityComponentRegisterStatus::UNREGISTERED;
552 return;
553 }
554
555 retryCount--;
556 std::this_thread::sleep_for(std::chrono::milliseconds(REGISTER_RETRY_INTERVAL));
557 }
558 regStatus_ = SecurityComponentRegisterStatus::UNREGISTERED;
559 SC_LOG_WARN("Register security component failed, retry %{public}d", MAX_RETRY_TIMES);
560 }
561
RegisterSecurityComponent()562 void SecurityComponentPattern::RegisterSecurityComponent()
563 {
564 if (regStatus_ == SecurityComponentRegisterStatus::REGISTERED ||
565 regStatus_ == SecurityComponentRegisterStatus::REGISTERING) {
566 return;
567 }
568
569 if (SecurityComponentHandler::IsSecurityComponentServiceExist()) {
570 RegisterSecurityComponentRetry();
571 return;
572 }
573 regStatus_ = SecurityComponentRegisterStatus::REGISTERING;
574 auto taskExecutor = Container::CurrentTaskExecutor();
575 CHECK_NULL_VOID(taskExecutor);
576 auto frameNode = GetHost();
577 CHECK_NULL_VOID(frameNode);
578 auto pipeline = frameNode->GetContextRefPtr();
579 CHECK_NULL_VOID(pipeline);
580 taskExecutor->PostTask(
581 [weak = WeakClaim(this), weakContext = WeakPtr(pipeline)] {
582 if (!SecurityComponentHandler::LoadSecurityComponentService()) {
583 SC_LOG_WARN("load security component service failed.");
584 return;
585 }
586 auto context = weakContext.Upgrade();
587 CHECK_NULL_VOID(context);
588 auto taskExecutor = context->GetTaskExecutor();
589 CHECK_NULL_VOID(taskExecutor);
590 taskExecutor->PostTask(
591 [weak, instanceID = context->GetInstanceId()] {
592 ContainerScope scope(instanceID);
593 auto pattern = weak.Upgrade();
594 CHECK_NULL_VOID(pattern);
595 if (pattern->regStatus_ != SecurityComponentRegisterStatus::REGISTERING) {
596 return;
597 }
598
599 pattern->RegisterSecurityComponentRetry();
600 },
601 TaskExecutor::TaskType::UI, "ArkUISecurityComponentRegisterRetry");
602 },
603 TaskExecutor::TaskType::BACKGROUND, "ArkUISecurityComponentRegister");
604 }
605
UnregisterSecurityComponent()606 void SecurityComponentPattern::UnregisterSecurityComponent()
607 {
608 if (regStatus_ == SecurityComponentRegisterStatus::REGISTERED) {
609 SecurityComponentHandler::UnregisterSecurityComponent(scId_);
610 } else {
611 SC_LOG_INFO("security component has not registered, regStatus %{public}d.", regStatus_);
612 }
613 regStatus_ = SecurityComponentRegisterStatus::UNREGISTERED;
614 scId_ = -1;
615 }
616
DoTriggerOnclick(int32_t result)617 void SecurityComponentPattern::DoTriggerOnclick(int32_t result)
618 {
619 auto host = GetHost();
620 CHECK_NULL_VOID(host);
621 auto jsonNode = JsonUtil::Create(true);
622 CHECK_NULL_VOID(jsonNode);
623 if (result != 0) {
624 jsonNode->Put("handleRes", static_cast<int32_t>(SecurityComponentHandleResult::CLICK_GRANT_FAILED));
625 } else {
626 jsonNode->Put("handleRes", static_cast<int32_t>(SecurityComponentHandleResult::CLICK_SUCCESS));
627 }
628
629 std::shared_ptr<JsonValue> jsonShrd(jsonNode.release());
630 auto gestureEventHub = host->GetOrCreateGestureEventHub();
631 CHECK_NULL_VOID(gestureEventHub);
632 gestureEventHub->ActClick(jsonShrd);
633 }
634
DelayReleaseNode(RefPtr<FrameNode> & node)635 void SecurityComponentPattern::DelayReleaseNode(RefPtr<FrameNode>& node)
636 {
637 if (uiEventHandler_ == nullptr) {
638 SC_LOG_WARN("UIEventHandler invalid");
639 return;
640 }
641 uiEventHandler_->PostTask(
642 [nodeInner = std::move(node)]() { return; },
643 DELAY_RELEASE_MILLSEC);
644 }
645
CreateFirstUseDialogCloseFunc(RefPtr<FrameNode> & frameNode,RefPtr<PipelineContext> & pipeline,const std::string & taskName)646 std::function<int32_t(int32_t)> SecurityComponentPattern::CreateFirstUseDialogCloseFunc(
647 RefPtr<FrameNode>& frameNode, RefPtr<PipelineContext>& pipeline, const std::string& taskName)
648 {
649 return [weak = WeakClaim(this), weakContext = WeakPtr(pipeline),
650 node = frameNode, taskName = taskName](int32_t result) mutable {
651 auto pattern = weak.Upgrade();
652 if (pattern == nullptr) {
653 return -1;
654 }
655 auto context = weakContext.Upgrade();
656 if (context == nullptr) {
657 pattern->DelayReleaseNode(node);
658 return -1;
659 }
660 auto taskExecutor = context->GetTaskExecutor();
661 if (taskExecutor == nullptr) {
662 pattern->DelayReleaseNode(node);
663 return -1;
664 }
665 taskExecutor->PostTask(
666 [weak, instanceId = context->GetInstanceId(), result, nodeInner = std::move(node)] {
667 if (result == static_cast<int32_t>(SecurityComponentHandleResult::GRANT_CANCEL)) {
668 return;
669 }
670 ContainerScope scope(instanceId);
671 auto pattern = weak.Upgrade();
672 if (pattern == nullptr) {
673 return;
674 }
675 pattern->DoTriggerOnclick(result);
676 },
677 TaskExecutor::TaskType::UI, taskName);
678 return 0;
679 };
680 }
681
ReportSecurityComponentClickEvent(GestureEvent & event)682 int32_t SecurityComponentPattern::ReportSecurityComponentClickEvent(GestureEvent& event)
683 {
684 if (regStatus_ == SecurityComponentRegisterStatus::UNREGISTERED) {
685 SC_LOG_WARN("ClickEventHandler: security component has not registered.");
686 return -1;
687 }
688 auto frameNode = GetHost();
689 CHECK_NULL_RETURN(frameNode, -1);
690 if (regStatus_ == SecurityComponentRegisterStatus::REGISTERING) {
691 RegisterSecurityComponentRetry();
692 }
693 if (regStatus_ != SecurityComponentRegisterStatus::REGISTERED) {
694 SC_LOG_WARN("ClickEventHandler: security component try to register failed.");
695 return -1;
696 }
697
698 auto pipeline = frameNode->GetContextRefPtr();
699 CHECK_NULL_RETURN(pipeline, -1);
700 std::function<void (int32_t)> OnClickAfterFirstUseDialog;
701 if (frameNode->GetTag() == V2::PASTE_BUTTON_ETS_TAG) {
702 OnClickAfterFirstUseDialog = [] (int32_t) {};
703 return SecurityComponentHandler::ReportSecurityComponentClickEvent(scId_,
704 frameNode, event, std::move(OnClickAfterFirstUseDialog));
705 }
706
707 OnClickAfterFirstUseDialog = CreateFirstUseDialogCloseFunc(
708 frameNode, pipeline, "ArkUISecurityComponentGestureTriggerOnClick");
709
710 return SecurityComponentHandler::ReportSecurityComponentClickEvent(scId_,
711 frameNode, event, std::move(OnClickAfterFirstUseDialog));
712 }
713
ReportSecurityComponentClickEvent(const KeyEvent & event)714 int32_t SecurityComponentPattern::ReportSecurityComponentClickEvent(const KeyEvent& event)
715 {
716 if (regStatus_ == SecurityComponentRegisterStatus::UNREGISTERED) {
717 SC_LOG_WARN("KeyEventHandler: security component has not registered.");
718 return -1;
719 }
720 auto frameNode = GetHost();
721 CHECK_NULL_RETURN(frameNode, -1);
722 if (regStatus_ == SecurityComponentRegisterStatus::REGISTERING) {
723 RegisterSecurityComponentRetry();
724 }
725 if (regStatus_ != SecurityComponentRegisterStatus::REGISTERED) {
726 SC_LOG_WARN("KeyEventHandler: security component try to register failed.");
727 return -1;
728 }
729
730 auto pipeline = frameNode->GetContextRefPtr();
731 CHECK_NULL_RETURN(pipeline, -1);
732 std::function<void (int32_t)> OnClickAfterFirstUseDialog;
733 if (frameNode->GetTag() == V2::PASTE_BUTTON_ETS_TAG) {
734 OnClickAfterFirstUseDialog = [] (int32_t) {};
735 return SecurityComponentHandler::ReportSecurityComponentClickEvent(scId_,
736 frameNode, event, std::move(OnClickAfterFirstUseDialog));
737 }
738
739 OnClickAfterFirstUseDialog = CreateFirstUseDialogCloseFunc(
740 frameNode, pipeline, "ArkUISecurityComponentKeyTriggerOnClick");
741
742 return SecurityComponentHandler::ReportSecurityComponentClickEvent(scId_,
743 frameNode, event, std::move(OnClickAfterFirstUseDialog));
744 }
745 #endif
746 } // namespace OHOS::Ace::NG
747