1 /*
2  * Copyright (c) 2022-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/form/form_pattern.h"
17 
18 #include "form_constants.h"
19 #include "form_info_base.h"
20 #include "locale_config.h"
21 #include "locale_info.h"
22 #include "pointer_event.h"
23 #include "transaction/rs_interfaces.h"
24 
25 #include "adapter/ohos/osal/resource_adapter_impl_v2.h"
26 #include "base/geometry/dimension.h"
27 #include "base/i18n/localization.h"
28 #include "base/log/log_wrapper.h"
29 #include "base/utils/string_utils.h"
30 #include "base/utils/system_properties.h"
31 #include "base/utils/time_util.h"
32 #include "base/utils/utils.h"
33 #include "core/common/form_manager.h"
34 #include "core/common/frontend.h"
35 #include "core/common/resource/resource_manager.h"
36 #include "core/components/form/resource/form_manager_delegate.h"
37 #include "core/components/form/sub_container.h"
38 #include "core/components_ng/pattern/form/form_event_hub.h"
39 #include "core/components_ng/pattern/form/form_layout_property.h"
40 #include "core/components_ng/pattern/form/form_node.h"
41 #include "core/components_ng/pattern/form/form_theme.h"
42 #include "core/components_ng/pattern/image/image_layout_property.h"
43 #include "core/components_ng/pattern/image/image_pattern.h"
44 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
45 #include "core/components_ng/pattern/shape/rect_pattern.h"
46 #include "core/components_ng/pattern/symbol/constants.h"
47 #include "core/components_ng/pattern/text/text_pattern.h"
48 #include "core/components_ng/property/property.h"
49 #include "core/components_ng/render/adapter/rosen_render_context.h"
50 #include "core/pipeline_ng/pipeline_context.h"
51 
52 #if OHOS_STANDARD_SYSTEM
53 #include "form_info.h"
54 #endif
55 
56 #include "core/common/udmf/udmf_client.h"
57 static const int64_t MAX_NUMBER_OF_JS = 0x20000000000000;
58 
59 namespace OHOS::Ace::NG {
60 namespace {
61 constexpr double FORM_CLICK_OPEN_LIMIT_DISTANCE = 20.0;
62 constexpr uint32_t DELAY_TIME_FOR_FORM_SUBCONTAINER_CACHE = 30000;
63 constexpr uint32_t DELAY_TIME_FOR_FORM_SNAPSHOT_3S = 3000;
64 constexpr uint32_t DELAY_TIME_FOR_FORM_SNAPSHOT_EXTRA = 200;
65 constexpr uint32_t DELAY_TIME_FOR_SET_NON_TRANSPARENT = 70;
66 constexpr uint32_t DELAY_TIME_FOR_DELETE_IMAGE_NODE = 100;
67 constexpr uint32_t DELAY_TIME_FOR_RESET_MANUALLY_CLICK_FLAG = 3000;
68 constexpr double ARC_RADIUS_TO_DIAMETER = 2.0;
69 constexpr double NON_TRANSPARENT_VAL = 1.0;
70 constexpr double TRANSPARENT_VAL = 0;
71 constexpr int32_t MAX_CLICK_DURATION = 500000000; // ns
72 constexpr int32_t DOUBLE = 2;
73 constexpr char FORM_DIMENSION_SPLITTER = '*';
74 constexpr int32_t FORM_SHAPE_CIRCLE = 2;
75 constexpr double TIME_LIMIT_FONT_SIZE_BASE = 18.0;
76 constexpr double TIBETAN_TIME_LIMIT_FONT_SIZE_BASE = 9.0;
77 constexpr char TIME_LIMIT_RESOURCE_NAME[] = "form_disable_time_limit";
78 constexpr float MAX_FONT_SCALE = 1.3f;
79 constexpr uint32_t FORBIDDEN_BG_COLOR_DARK = 0xFF2E3033;
80 constexpr uint32_t FORBIDDEN_BG_COLOR_LIGHT = 0xFFD1D1D6;
81 constexpr double TEXT_TRANSPARENT_VAL = 0.9;
82 constexpr int32_t FORM_DIMENSION_MIN_HEIGHT = 1;
83 
84 class FormSnapshotCallback : public Rosen::SurfaceCaptureCallback {
85 public:
FormSnapshotCallback(const WeakPtr<FormPattern> & node)86     explicit FormSnapshotCallback(const WeakPtr<FormPattern>& node) : weakFormPattern_(node) {}
87     ~FormSnapshotCallback() override = default;
OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelMap)88     void OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelMap) override
89     {
90         auto formPattern_ = weakFormPattern_.Upgrade();
91         CHECK_NULL_VOID(formPattern_);
92         formPattern_->OnSnapshot(pixelMap);
93     }
94 
95 private:
96     WeakPtr<FormPattern> weakFormPattern_ = nullptr;
97 };
98 } // namespace
99 
FormPattern()100 FormPattern::FormPattern()
101 {
102     ACE_SCOPED_TRACE("FormCreate");
103 }
104 
105 FormPattern::~FormPattern() = default;
106 
OnAttachToFrameNode()107 void FormPattern::OnAttachToFrameNode()
108 {
109     auto host = GetHost();
110     CHECK_NULL_VOID(host);
111     host->GetRenderContext()->SetClipToFrame(true);
112     host->GetRenderContext()->SetClipToBounds(true);
113     host->GetRenderContext()->UpdateRenderGroup(true);
114     // Init the render context for RSSurfaceNode from FRS.
115     externalRenderContext_ = RenderContext::Create();
116     // for external RSNode, name is meaningless.
117     static RenderContext::ContextParam param = { RenderContext::ContextType::EXTERNAL, std::nullopt };
118     externalRenderContext_->InitContext(false, param);
119     InitFormManagerDelegate();
120     auto eventHub = host->GetEventHub<FormEventHub>();
121     CHECK_NULL_VOID(eventHub);
122     eventHub->SetOnCache([weak = WeakClaim(this)]() {
123         auto pattern = weak.Upgrade();
124         CHECK_NULL_VOID(pattern);
125         auto host = pattern->GetHost();
126         CHECK_NULL_VOID(host);
127         auto context = host->GetContextRefPtr();
128         CHECK_NULL_VOID(context);
129         auto subContainer = pattern->GetSubContainer();
130         CHECK_NULL_VOID(subContainer);
131         auto uiTaskExecutor =
132             SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
133         auto id = subContainer->GetRunningCardId();
134         TAG_LOGI(AceLogTag::ACE_FORM, "FormPattern::OnAttachToFrameNode, cardId: %{public}" PRId64, id);
135         FormManager::GetInstance().AddSubContainer(id, subContainer);
136         uiTaskExecutor.PostDelayedTask(
137             [id, nodeId = subContainer->GetNodeId()] {
138                 auto cachedSubContainer = FormManager::GetInstance().GetSubContainer(id);
139                 if (cachedSubContainer != nullptr && cachedSubContainer->GetNodeId() == nodeId) {
140                     FormManager::GetInstance().RemoveSubContainer(id);
141                 }
142             },
143             DELAY_TIME_FOR_FORM_SUBCONTAINER_CACHE, "ArkUIFormRemoveSubContainer");
144     });
145 
146     InitClickEvent();
147 
148     scopeId_ = Container::CurrentId();
149 }
150 
InitClickEvent()151 void FormPattern::InitClickEvent()
152 {
153     // Init click event for static form.
154     auto host = GetHost();
155     CHECK_NULL_VOID(host);
156     auto gestureEventHub = host->GetOrCreateGestureEventHub();
157     auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
158         auto formPattern = weak.Upgrade();
159         TAG_LOGI(AceLogTag::ACE_FORM, "gestureEvent - clickCallback");
160         CHECK_NULL_VOID(formPattern);
161         formPattern->HandleStaticFormEvent(
162             { static_cast<float>(info.GetLocalLocation().GetX()), static_cast<float>(info.GetLocalLocation().GetY()) });
163     };
164     auto clickEvent = AceType::MakeRefPtr<ClickEvent>(std::move(clickCallback));
165     gestureEventHub->AddClickEvent(clickEvent);
166 
167     // check touch duration in click event
168     auto touchCallback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
169         auto formPattern = weak.Upgrade();
170         CHECK_NULL_VOID(formPattern);
171         auto touchType = info.GetTouches().front().GetTouchType();
172         if (touchType == TouchType::DOWN) {
173             formPattern->HandleTouchDownEvent(info);
174             return;
175         }
176         if (touchType == TouchType::UP || touchType == TouchType::CANCEL) {
177             formPattern->HandleTouchUpEvent(info);
178             return;
179         }
180     };
181     auto touchEvent = AceType::MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
182     gestureEventHub->AddTouchEvent(touchEvent);
183 }
184 
HandleTouchDownEvent(const TouchEventInfo & event)185 void FormPattern::HandleTouchDownEvent(const TouchEventInfo& event)
186 {
187     touchDownTime_ = event.GetTimeStamp();
188     shouldResponseClick_ = true;
189     if (!event.GetTouches().empty()) {
190         lastTouchLocation_ = event.GetTouches().front().GetScreenLocation();
191     }
192 }
193 
HandleTouchUpEvent(const TouchEventInfo & event)194 void FormPattern::HandleTouchUpEvent(const TouchEventInfo& event)
195 {
196     auto duration = event.GetTimeStamp().time_since_epoch().count() - touchDownTime_.time_since_epoch().count();
197     if (duration > MAX_CLICK_DURATION) {
198         TAG_LOGI(AceLogTag::ACE_FORM, "reject click. duration is %{public}lld.", duration);
199         shouldResponseClick_ = false;
200         return;
201     }
202     if (event.GetTouches().empty()) {
203         return;
204     }
205     auto distance = event.GetTouches().front().GetScreenLocation() - lastTouchLocation_;
206     if (distance.GetDistance() > FORM_CLICK_OPEN_LIMIT_DISTANCE) {
207         shouldResponseClick_ = false;
208     }
209 }
210 
HandleUnTrustForm()211 void FormPattern::HandleUnTrustForm()
212 {
213     auto host = GetHost();
214     CHECK_NULL_VOID(host);
215     if (externalRenderContext_) {
216         auto renderContext = DynamicCast<NG::RosenRenderContext>(host->GetRenderContext());
217         CHECK_NULL_VOID(renderContext);
218         renderContext->RemoveChild(externalRenderContext_);
219     }
220 
221     isUnTrust_ = true;
222     isLoaded_ = true;
223     if (!isJsCard_) {
224         RequestFormInfo info;
225         if (ShouldLoadFormSkeleton(false, info)) {
226             LoadFormSkeleton(true);
227         }
228     }
229 
230     host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
231     auto parent = host->GetParent();
232     CHECK_NULL_VOID(parent);
233     parent->MarkNeedSyncRenderTree();
234     parent->RebuildRenderContextTree();
235     host->GetRenderContext()->RequestNextFrame();
236 }
237 
UpdateBackgroundColorWhenUnTrustForm()238 void FormPattern::UpdateBackgroundColorWhenUnTrustForm()
239 {
240     if (!isUnTrust_) {
241         return;
242     }
243 
244     if (colorMode != SystemProperties::GetColorMode()) {
245         colorMode = SystemProperties::GetColorMode();
246         HandleUnTrustForm();
247     }
248 }
249 
HandleSnapshot(uint32_t delayTime)250 void FormPattern::HandleSnapshot(uint32_t delayTime)
251 {
252     auto pipeline = PipelineContext::GetCurrentContext();
253     CHECK_NULL_VOID(pipeline);
254     auto executor = pipeline->GetTaskExecutor();
255     CHECK_NULL_VOID(executor);
256     snapshotTimestamp_ = GetCurrentTimestamp();
257     if (isDynamic_) {
258         if (formChildrenNodeMap_.find(FormChildNodeType::FORM_STATIC_IMAGE_NODE) != formChildrenNodeMap_.end()) {
259             executor->RemoveTask(TaskExecutor::TaskType::UI, "ArkUIFormSetNonTransparentAfterRecover");
260             executor->RemoveTask(TaskExecutor::TaskType::UI, "ArkUIFormDeleteImageNodeAfterRecover");
261             RemoveFrsNode();
262             ReleaseRenderer();
263             UnregisterAccessibility();
264             isSnapshot_ = true;
265             needSnapshotAgain_ = false;
266             return;
267         }
268     }
269 
270     executor->PostDelayedTask(
271         [weak = WeakClaim(this), delayTime]() mutable {
272             auto form = weak.Upgrade();
273             CHECK_NULL_VOID(form);
274             int64_t currentTime = GetCurrentTimestamp();
275             if (currentTime - form->snapshotTimestamp_ < delayTime) {
276                 TAG_LOGD(AceLogTag::ACE_FORM, "another snapshot task has been posted.");
277                 return;
278             }
279             form->TakeSurfaceCaptureForUI();
280         },
281         TaskExecutor::TaskType::UI, delayTime, "ArkUIFormTakeSurfaceCapture");
282 }
283 
HandleStaticFormEvent(const PointF & touchPoint)284 void FormPattern::HandleStaticFormEvent(const PointF& touchPoint)
285 {
286     if (formLinkInfos_.empty() || isDynamic_ || !shouldResponseClick_) {
287         return;
288     }
289     TAG_LOGI(AceLogTag::ACE_FORM, "StaticFrom click.");
290     for (const auto& info : formLinkInfos_) {
291         auto linkInfo = JsonUtil::ParseJsonString(info);
292         CHECK_NULL_VOID(linkInfo);
293         auto action = linkInfo->GetValue("action")->GetString();
294         auto rectStr = linkInfo->GetValue("formLinkRect")->GetString();
295         RectF linkRect = RectF::FromString(rectStr);
296         if (linkRect.IsInRegion(touchPoint)) {
297             OnActionEvent(action);
298             break;
299         }
300     }
301 }
302 
HandleEnableForm(const bool enable)303 void FormPattern::HandleEnableForm(const bool enable)
304 {
305     TAG_LOGI(AceLogTag::ACE_FORM, "FormPattern::HandleEnableForm, enable = %{public}d", enable);
306     if (enable) {
307         RemoveDisableFormStyle(cardInfo_);
308     } else {
309         LoadDisableFormStyle(cardInfo_);
310     }
311 }
312 
TakeSurfaceCaptureForUI()313 void FormPattern::TakeSurfaceCaptureForUI()
314 {
315     if (isFrsNodeDetached_) {
316         TAG_LOGI(AceLogTag::ACE_FORM, "Frs node is detached, cancel snapshot.");
317         return;
318     }
319 
320     if (isDynamic_) {
321         formLinkInfos_.clear();
322     }
323     TAG_LOGI(AceLogTag::ACE_FORM, "Static-form take snapshot.");
324     auto host = GetHost();
325     CHECK_NULL_VOID(host);
326     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
327     CHECK_NULL_VOID(layoutProperty);
328     auto renderContext = host->GetRenderContext();
329     auto visible = layoutProperty->GetVisibleType().value_or(VisibleType::VISIBLE);
330     auto opacity = renderContext->GetOpacityValue(NON_TRANSPARENT_VAL);
331     if (visible == VisibleType::INVISIBLE || visible == VisibleType::GONE || opacity == TRANSPARENT_VAL) {
332         TAG_LOGI(AceLogTag::ACE_FORM, "The form is invisible, TakeSurfaceCaptureForUI later.");
333         needSnapshotAgain_ = true;
334         return;
335     }
336 
337     if (formChildrenNodeMap_.find(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE)
338         == formChildrenNodeMap_.end()) {
339         SnapshotSurfaceNode();
340         return;
341     }
342     UpdateChildNodeOpacity(FormChildNodeType::FORM_SURFACE_NODE, NON_TRANSPARENT_VAL);
343     host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
344     auto context = host->GetContext();
345     CHECK_NULL_VOID(context);
346     auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
347     uiTaskExecutor.PostDelayedTask(
348         [weak = WeakClaim(this)] {
349             auto pattern = weak.Upgrade();
350             CHECK_NULL_VOID(pattern);
351             pattern->SnapshotSurfaceNode();
352         },
353         DELAY_TIME_FOR_FORM_SNAPSHOT_EXTRA, "ArkUIFormDelaySnapshotSurfaceNode");
354 }
355 
SnapshotSurfaceNode()356 void FormPattern::SnapshotSurfaceNode()
357 {
358     auto externalContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
359     CHECK_NULL_VOID(externalContext);
360     auto rsNode = externalContext->GetRSNode();
361     CHECK_NULL_VOID(rsNode);
362     auto& rsInterface = Rosen::RSInterfaces::GetInstance();
363     rsInterface.TakeSurfaceCaptureForUI(rsNode, std::make_shared<FormSnapshotCallback>(WeakClaim(this)));
364 }
365 
OnSnapshot(std::shared_ptr<Media::PixelMap> pixelMap)366 void FormPattern::OnSnapshot(std::shared_ptr<Media::PixelMap> pixelMap)
367 {
368     ContainerScope scope(scopeId_);
369     auto host = GetHost();
370     CHECK_NULL_VOID(host);
371     auto context = host->GetContext();
372     CHECK_NULL_VOID(context);
373     auto uiTaskExecutor =
374         SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
375     uiTaskExecutor.PostTask([weak = WeakClaim(this), pixelMap] {
376         auto formPattern = weak.Upgrade();
377         CHECK_NULL_VOID(formPattern);
378         formPattern->HandleOnSnapshot(pixelMap);
379         }, "ArkUIFormHandleOnSnapshot");
380 }
381 
HandleOnSnapshot(std::shared_ptr<Media::PixelMap> pixelMap)382 void FormPattern::HandleOnSnapshot(std::shared_ptr<Media::PixelMap> pixelMap)
383 {
384     TAG_LOGI(AceLogTag::ACE_FORM, "call.");
385     CHECK_NULL_VOID(pixelMap);
386     pixelMap_ = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
387     UpdateStaticCard();
388     isSnapshot_ = true;
389     needSnapshotAgain_ = false;
390 }
391 
OnAccessibilityChildTreeRegister(uint32_t windowId,int32_t treeId,int64_t accessibilityId)392 void FormPattern::OnAccessibilityChildTreeRegister(uint32_t windowId, int32_t treeId, int64_t accessibilityId)
393 {
394     TAG_LOGD(AceLogTag::ACE_FORM, "call, treeId: %{public}d, id: %{public}" PRId64, treeId, accessibilityId);
395     if (formManagerBridge_ == nullptr) {
396         TAG_LOGE(AceLogTag::ACE_FORM, "formManagerBridge_ is null");
397         return;
398     }
399     formManagerBridge_->OnAccessibilityChildTreeRegister(windowId, treeId, accessibilityId);
400 }
401 
OnAccessibilityChildTreeDeregister()402 void FormPattern::OnAccessibilityChildTreeDeregister()
403 {
404     TAG_LOGD(AceLogTag::ACE_FORM, "call.");
405     if (formManagerBridge_ == nullptr) {
406         TAG_LOGE(AceLogTag::ACE_FORM, "formManagerBridge_ is null");
407         return;
408     }
409     formManagerBridge_->OnAccessibilityChildTreeDeregister();
410 }
411 
OnAccessibilityDumpChildInfo(const std::vector<std::string> & params,std::vector<std::string> & info)412 void FormPattern::OnAccessibilityDumpChildInfo(const std::vector<std::string>& params, std::vector<std::string>& info)
413 {
414     TAG_LOGD(AceLogTag::ACE_FORM, "call.");
415     if (formManagerBridge_ == nullptr) {
416         TAG_LOGE(AceLogTag::ACE_FORM, "formManagerBridge_ is null");
417         return;
418     }
419     formManagerBridge_->OnAccessibilityDumpChildInfo(params, info);
420 }
421 
GetAccessibilitySessionAdapter()422 RefPtr<AccessibilitySessionAdapter> FormPattern::GetAccessibilitySessionAdapter()
423 {
424     return accessibilitySessionAdapter_;
425 }
426 
UpdateStaticCard()427 void FormPattern::UpdateStaticCard()
428 {
429     // 1. Use imageNode to display pixelMap
430     UpdateImageNode();
431     // 2. Remove FrsNode from formNode
432     RemoveFrsNode();
433     // 3. Release renderer obj
434     ReleaseRenderer();
435     // 4. clear form node ChildTree register flag.  can do register again
436     UnregisterAccessibility();
437 }
438 
SetNonTransparentAfterRecover()439 void FormPattern::SetNonTransparentAfterRecover()
440 {
441     ACE_FUNCTION_TRACE();
442     // set frs node non transparent
443     if (formChildrenNodeMap_.find(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE)
444         == formChildrenNodeMap_.end()) {
445         UpdateChildNodeOpacity(FormChildNodeType::FORM_SURFACE_NODE, NON_TRANSPARENT_VAL);
446         //update form after updateChildNodeOpacity
447         auto host = GetHost();
448         CHECK_NULL_VOID(host);
449         host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
450         TAG_LOGI(AceLogTag::ACE_FORM, "setOpacity:1");
451     } else {
452         TAG_LOGW(AceLogTag::ACE_FORM, "has forbidden node");
453     }
454 }
455 
DeleteImageNodeAfterRecover(bool needHandleCachedClick)456 void FormPattern::DeleteImageNodeAfterRecover(bool needHandleCachedClick)
457 {
458     ACE_FUNCTION_TRACE();
459     auto host = GetHost();
460     CHECK_NULL_VOID(host);
461     auto renderContext = host->GetRenderContext();
462     CHECK_NULL_VOID(renderContext);
463 
464     // delete image rs node and frame node
465     RemoveFormChildNode(FormChildNodeType::FORM_STATIC_IMAGE_NODE);
466 
467     host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
468     auto parent = host->GetParent();
469     CHECK_NULL_VOID(parent);
470     parent->MarkNeedSyncRenderTree();
471     parent->RebuildRenderContextTree();
472     renderContext->RequestNextFrame();
473 
474     // handle cached pointer event
475     if (needHandleCachedClick && formManagerBridge_) {
476         formManagerBridge_->HandleCachedClickEvents();
477     }
478 }
479 
CreateImageNode()480 RefPtr<FrameNode> FormPattern::CreateImageNode()
481 {
482     auto host = GetHost();
483     CHECK_NULL_RETURN(host, nullptr);
484     auto formNode = DynamicCast<FormNode>(host);
485     CHECK_NULL_RETURN(formNode, nullptr);
486     auto imageId = formNode->GetImageId();
487     RefPtr<FrameNode> imageNode = FrameNode::CreateFrameNode(V2::IMAGE_ETS_TAG, imageId,
488         AceType::MakeRefPtr<ImagePattern>());
489     CHECK_NULL_RETURN(imageNode, nullptr);
490     AddFormChildNode(FormChildNodeType::FORM_STATIC_IMAGE_NODE, imageNode);
491     auto imagePattern = imageNode->GetPattern<ImagePattern>();
492     CHECK_NULL_RETURN(imagePattern, nullptr);
493     imagePattern->SetSyncLoad(true);
494     RefPtr<FrameNode> disableStyleRootNode = GetFormChildNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE);
495     disableStyleRootNode == nullptr ? host->AddChild(imageNode) :
496         host->AddChildBefore(imageNode, disableStyleRootNode);
497     auto eventHub = imageNode->GetOrCreateGestureEventHub();
498     if (eventHub != nullptr) {
499         eventHub->RemoveDragEvent();
500     }
501     return imageNode;
502 }
503 
UpdateImageNode()504 void FormPattern::UpdateImageNode()
505 {
506     ContainerScope scope(scopeId_);
507     CHECK_NULL_VOID(pixelMap_);
508     auto host = GetHost();
509     CHECK_NULL_VOID(host);
510     RemoveFormChildNode(FormChildNodeType::FORM_STATIC_IMAGE_NODE);
511     auto imageNode = CreateImageNode();
512     CHECK_NULL_VOID(imageNode);
513     auto pixelLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
514     CHECK_NULL_VOID(pixelLayoutProperty);
515     auto pixelSourceInfo = ImageSourceInfo(pixelMap_);
516 
517     auto width = static_cast<float>(cardInfo_.width.Value()) - cardInfo_.borderWidth * DOUBLE;
518     auto height = static_cast<float>(cardInfo_.height.Value()) - cardInfo_.borderWidth * DOUBLE;
519     CalcSize idealSize = { CalcLength(width), CalcLength(height) };
520     MeasureProperty layoutConstraint;
521     layoutConstraint.selfIdealSize = idealSize;
522     layoutConstraint.maxSize = idealSize;
523     imageNode->UpdateLayoutConstraint(layoutConstraint);
524     pixelLayoutProperty->UpdateImageSourceInfo(pixelSourceInfo);
525     auto externalContext = DynamicCast<NG::RosenRenderContext>(imageNode->GetRenderContext());
526     CHECK_NULL_VOID(externalContext);
527     externalContext->SetVisible(true);
528     if (formChildrenNodeMap_.find(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE)
529         != formChildrenNodeMap_.end()) {
530         externalContext->SetOpacity(TRANSPARENT_VAL);
531     }
532     imageNode->MarkModifyDone();
533     imageNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
534 }
535 
RemoveFrsNode()536 void FormPattern::RemoveFrsNode()
537 {
538     ContainerScope scope(scopeId_);
539     CHECK_NULL_VOID(externalRenderContext_);
540     auto host = GetHost();
541     CHECK_NULL_VOID(host);
542     auto renderContext = DynamicCast<NG::RosenRenderContext>(host->GetRenderContext());
543     CHECK_NULL_VOID(renderContext);
544     renderContext->RemoveChild(externalRenderContext_);
545 
546     host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
547     auto parent = host->GetParent();
548     CHECK_NULL_VOID(parent);
549     parent->MarkNeedSyncRenderTree();
550     parent->RebuildRenderContextTree();
551     host->GetRenderContext()->RequestNextFrame();
552 }
553 
ReleaseRenderer()554 void FormPattern::ReleaseRenderer()
555 {
556     ContainerScope scope(scopeId_);
557     CHECK_NULL_VOID(formManagerBridge_);
558     formManagerBridge_->ReleaseRenderer();
559 }
560 
OnRebuildFrame()561 void FormPattern::OnRebuildFrame()
562 {
563     if (isSnapshot_) {
564         return;
565     }
566 
567     auto host = GetHost();
568     CHECK_NULL_VOID(host);
569     auto renderContext = host->GetRenderContext();
570     CHECK_NULL_VOID(renderContext);
571     renderContext->AddChild(externalRenderContext_, 0);
572 }
573 
OnVisibleChange(bool isVisible)574 void FormPattern::OnVisibleChange(bool isVisible)
575 {
576     isVisible_ = isVisible;
577 }
578 
OnModifyDone()579 void FormPattern::OnModifyDone()
580 {
581     Pattern::OnModifyDone();
582     auto host = GetHost();
583     CHECK_NULL_VOID(host);
584     auto gestureEventHub = host->GetOrCreateGestureEventHub();
585     CHECK_NULL_VOID(gestureEventHub);
586     // FormComponent do not response to user's onClick callback.
587     gestureEventHub->ClearUserOnClick();
588 
589     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
590     CHECK_NULL_VOID(layoutProperty);
591     auto &&layoutConstraint = layoutProperty->GetCalcLayoutConstraint();
592     CHECK_NULL_VOID(layoutConstraint);
593     auto size = layoutConstraint->selfIdealSize;
594     CHECK_NULL_VOID(size);
595     auto sizeWidth = size->Width();
596     auto sizeHeight = size->Height();
597     CHECK_NULL_VOID(sizeWidth);
598     CHECK_NULL_VOID(sizeHeight);
599     auto width = sizeWidth->GetDimension();
600     auto height = sizeHeight->GetDimension();
601     if (width.Unit() == DimensionUnit::PERCENT || height.Unit() == DimensionUnit::PERCENT) {
602         /**
603          * If DimensionUnit is DimensionUnit::PERCENT, it need parentNode-size to calculate formNode-size.
604          * However, the parentNode-size cannot be obtained in the current callback function,
605          * so HandleFormComponent in OnDirtyLayoutWrapperSwap function.
606          */
607         return;
608     }
609     // Convert DimensionUnit to DimensionUnit::PX
610     auto info = layoutProperty->GetRequestFormInfo().value_or(RequestFormInfo());
611     TAG_LOGI(AceLogTag::ACE_FORM, "FormPattern::OnModifyDone, info.id: %{public}" PRId64, info.id);
612     info.width = Dimension(width.ConvertToPx());
613     info.height = Dimension(height.ConvertToPx());
614     auto &&borderWidthProperty = layoutProperty->GetBorderWidthProperty();
615     float borderWidth = 0.0f;
616     if (borderWidthProperty && borderWidthProperty->topDimen) {
617         borderWidth = borderWidthProperty->topDimen->ConvertToPx();
618     }
619     info.borderWidth = borderWidth;
620     layoutProperty->UpdateRequestFormInfo(info);
621     UpdateBackgroundColorWhenUnTrustForm();
622     info.obscuredMode = isFormObscured_;
623     info.obscuredMode |= CheckFormBundleForbidden(info.bundleName);
624     HandleFormComponent(info);
625 
626     auto accessibilityProperty = host->GetAccessibilityProperty<AccessibilityProperty>();
627     CHECK_NULL_VOID(accessibilityProperty);
628     accessibilityProperty->SetAccessibilityLevel(AccessibilityProperty::Level::NO_STR);
629 }
630 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)631 bool FormPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
632 {
633     if (config.skipMeasure && config.skipLayout) {
634         return false;
635     }
636     isBeenLayout_ = true;
637     auto size = dirty->GetGeometryNode()->GetFrameSize();
638     auto host = GetHost();
639     CHECK_NULL_RETURN(host, false);
640     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
641     CHECK_NULL_RETURN(layoutProperty, false);
642     auto info = layoutProperty->GetRequestFormInfo().value_or(RequestFormInfo());
643     info.width = Dimension(size.Width());
644     info.height = Dimension(size.Height());
645     if (std::isinf(info.width.Value()) || std::isnan(info.width.Value()) || std::isinf(info.height.Value())
646         || std::isnan(info.height.Value())) {
647         TAG_LOGE(AceLogTag::ACE_FORM, "size invalid, width:%{public}f height:%{public}f",
648             info.width.Value(), info.height.Value());
649         return false;
650     }
651     auto &&borderWidthProperty = layoutProperty->GetBorderWidthProperty();
652     float borderWidth = 0.0f;
653     if (borderWidthProperty && borderWidthProperty->topDimen) {
654         borderWidth = borderWidthProperty->topDimen->ConvertToPx();
655     }
656     info.borderWidth = borderWidth;
657     layoutProperty->UpdateRequestFormInfo(info);
658 
659     UpdateBackgroundColorWhenUnTrustForm();
660     info.obscuredMode = isFormObscured_;
661     info.obscuredMode |= CheckFormBundleForbidden(info.bundleName);
662     HandleFormComponent(info);
663     return true;
664 }
665 
HandleFormComponent(const RequestFormInfo & info)666 void FormPattern::HandleFormComponent(const RequestFormInfo& info)
667 {
668     if (info.bundleName != cardInfo_.bundleName || info.abilityName != cardInfo_.abilityName ||
669         info.moduleName != cardInfo_.moduleName || info.cardName != cardInfo_.cardName ||
670         info.dimension != cardInfo_.dimension || info.renderingMode != cardInfo_.renderingMode) {
671         AddFormComponent(info);
672     } else {
673         UpdateFormComponent(info);
674     }
675 }
676 
AddFormComponent(const RequestFormInfo & info)677 void FormPattern::AddFormComponent(const RequestFormInfo& info)
678 {
679     ACE_FUNCTION_TRACE();
680     auto host = GetHost();
681     CHECK_NULL_VOID(host);
682     // When cardInfo has changed, it will call AddForm in Fwk
683     // If the width or height equal to zero, it will not
684     if (NonPositive(info.width.Value()) || NonPositive(info.height.Value())) {
685         TAG_LOGW(AceLogTag::ACE_FORM, "Invalid form size.");
686         return;
687     }
688     TAG_LOGI(AceLogTag::ACE_FORM, "width: %{public}f   height: %{public}f  borderWidth: %{public}f",
689         info.width.Value(), info.height.Value(), info.borderWidth);
690     cardInfo_ = info;
691     if (info.dimension == static_cast<int32_t>(OHOS::AppExecFwk::Constants::Dimension::DIMENSION_1_1)
692         || info.shape == FORM_SHAPE_CIRCLE) {
693         BorderRadiusProperty borderRadius;
694         Dimension diameter = std::min(info.width, info.height);
695         borderRadius.SetRadius(diameter / ARC_RADIUS_TO_DIAMETER);
696         host->GetRenderContext()->UpdateBorderRadius(borderRadius);
697     }
698     isJsCard_ = true;
699 #if OHOS_STANDARD_SYSTEM
700     AppExecFwk::FormInfo formInfo;
701     if (FormManagerDelegate::GetFormInfo(info.bundleName, info.moduleName, info.cardName, formInfo) &&
702         formInfo.uiSyntax == AppExecFwk::FormType::ETS) {
703         isJsCard_ = false;
704     }
705 #endif
706 
707     CreateCardContainer();
708     if (host->IsDraggable()) {
709         EnableDrag();
710     }
711 
712 #if OHOS_STANDARD_SYSTEM
713     if (!isJsCard_ && ShouldLoadFormSkeleton(formInfo.transparencyEnabled, info)) {
714         LoadFormSkeleton();
715     }
716 #endif
717 
718     if (!formManagerBridge_) {
719         TAG_LOGE(AceLogTag::ACE_FORM, "Form manager delegate is nullptr.");
720         return;
721     }
722 #if OHOS_STANDARD_SYSTEM
723     formManagerBridge_->AddForm(host->GetContextRefPtr(), info, formInfo);
724 #else
725     formManagerBridge_->AddForm(host->GetContextRefPtr(), info);
726 #endif
727 
728     if (!formInfo.transparencyEnabled && CheckFormBundleForbidden(info.bundleName)) {
729         LoadDisableFormStyle(info);
730     }
731 }
732 
UpdateFormComponent(const RequestFormInfo & info)733 void FormPattern::UpdateFormComponent(const RequestFormInfo& info)
734 {
735     auto host = GetHost();
736     CHECK_NULL_VOID(host);
737     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
738     CHECK_NULL_VOID(layoutProperty);
739     if (cardInfo_.allowUpdate != info.allowUpdate) {
740         cardInfo_.allowUpdate = info.allowUpdate;
741         if (subContainer_) {
742             subContainer_->SetAllowUpdate(cardInfo_.allowUpdate);
743         }
744         if (formManagerBridge_) {
745             formManagerBridge_->SetAllowUpdate(cardInfo_.allowUpdate);
746         }
747     }
748     if (cardInfo_.width != info.width || cardInfo_.height != info.height || cardInfo_.borderWidth != info.borderWidth) {
749         UpdateFormComponentSize(info);
750     }
751     if (cardInfo_.obscuredMode != info.obscuredMode) {
752         cardInfo_.obscuredMode = info.obscuredMode;
753         if (formManagerBridge_) {
754             formManagerBridge_->SetObscured(info.obscuredMode);
755         }
756     }
757     if (isLoaded_) {
758         auto visible = layoutProperty->GetVisibleType().value_or(VisibleType::VISIBLE);
759         layoutProperty->UpdateVisibility(visible);
760         if (!isDynamic_ && !isSnapshot_ && needSnapshotAgain_) {
761             auto renderContext = host->GetRenderContext();
762             CHECK_NULL_VOID(renderContext);
763             auto opacity = renderContext->GetOpacityValue(NON_TRANSPARENT_VAL);
764             TAG_LOGI(AceLogTag::ACE_FORM, "Static-form, current opacity: %{public}f, visible: %{public}d",
765                 opacity, static_cast<int>(visible));
766             if (visible == VisibleType::VISIBLE && opacity == NON_TRANSPARENT_VAL) {
767                 HandleSnapshot(DELAY_TIME_FOR_FORM_SNAPSHOT_3S);
768             }
769         }
770     }
771     UpdateTimeLimitFontCfg();
772     UpdateConfiguration();
773 }
774 
UpdateFormComponentSize(const RequestFormInfo & info)775 void FormPattern::UpdateFormComponentSize(const RequestFormInfo& info)
776 {
777     TAG_LOGI(AceLogTag::ACE_FORM, "update size, width: %{public}f   height: %{public}f  borderWidth: %{public}f",
778         info.width.Value(), info.height.Value(), info.borderWidth);
779     cardInfo_.width = info.width;
780     cardInfo_.height = info.height;
781     cardInfo_.borderWidth = info.borderWidth;
782     auto externalRenderContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
783     CHECK_NULL_VOID(externalRenderContext);
784 
785     externalRenderContext->SetBounds(round(cardInfo_.borderWidth), round(cardInfo_.borderWidth),
786         round(cardInfo_.width.Value() - cardInfo_.borderWidth * DOUBLE),
787         round(cardInfo_.height.Value() - cardInfo_.borderWidth * DOUBLE));
788 
789     if (formManagerBridge_) {
790         formManagerBridge_->NotifySurfaceChange(info.width.Value(), info.height.Value(), info.borderWidth);
791     } else {
792         TAG_LOGE(AceLogTag::ACE_FORM, "form manager delagate is nullptr, card id is %{public}" PRId64 ".",
793             cardInfo_.id);
794     }
795 
796     auto imageNode = GetFormChildNode(FormChildNodeType::FORM_STATIC_IMAGE_NODE);
797     auto disableStyleRootNode = GetFormChildNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE);
798     if (imageNode != nullptr || disableStyleRootNode != nullptr) {
799         auto width = static_cast<float>(info.width.Value()) - info.borderWidth * DOUBLE;
800         auto height = static_cast<float>(info.height.Value()) - info.borderWidth * DOUBLE;
801         CalcSize idealSize = { CalcLength(width), CalcLength(height) };
802         MeasureProperty layoutConstraint;
803         layoutConstraint.selfIdealSize = idealSize;
804         layoutConstraint.maxSize = idealSize;
805         if (imageNode != nullptr) {
806             imageNode->UpdateLayoutConstraint(layoutConstraint);
807         }
808         if (disableStyleRootNode != nullptr) {
809             disableStyleRootNode->UpdateLayoutConstraint(layoutConstraint);
810         }
811     }
812 
813     auto formSkeletonNode = GetFormChildNode(FormChildNodeType::FORM_SKELETON_NODE);
814     if (formSkeletonNode) {
815         LoadFormSkeleton(true);
816     }
817 
818     if (info.dimension == static_cast<int32_t>(OHOS::AppExecFwk::Constants::Dimension::DIMENSION_1_1)) {
819         BorderRadiusProperty borderRadius;
820         Dimension diameter = std::min(info.width, info.height);
821         borderRadius.SetRadius(diameter / ARC_RADIUS_TO_DIAMETER);
822         GetHost()->GetRenderContext()->UpdateBorderRadius(borderRadius);
823     }
824     if (subContainer_) {
825         subContainer_->SetFormPattern(WeakClaim(this));
826         subContainer_->UpdateRootElementSize();
827         subContainer_->UpdateSurfaceSizeWithAnimathion();
828     }
829 }
830 
UpdateTimeLimitFontCfg()831 void FormPattern::UpdateTimeLimitFontCfg()
832 {
833     auto columnNode = GetFormChildNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE);
834     CHECK_NULL_VOID(columnNode);
835     auto renderContext = columnNode->GetRenderContext();
836     CHECK_NULL_VOID(renderContext);
837     renderContext->UpdateBackgroundColor(SystemProperties::GetColorMode() == ColorMode::DARK ?
838         Color(FORBIDDEN_BG_COLOR_DARK) : Color(FORBIDDEN_BG_COLOR_LIGHT));
839 
840     auto textNode = GetFormChildNode(FormChildNodeType::FORM_FORBIDDEN_TEXT_NODE);
841     CHECK_NULL_VOID(textNode);
842     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
843     CHECK_NULL_VOID(textLayoutProperty);
844 
845     Dimension fontSize(GetTimeLimitFontSize());
846     if (!textLayoutProperty->GetFontSize().has_value() ||
847         !NearEqual(textLayoutProperty->GetFontSize().value(), fontSize)) {
848         TAG_LOGD(AceLogTag::ACE_FORM, "bundleName = %{public}s, id: %{public}" PRId64 ", UpdateFontSize:%{public}f.",
849             cardInfo_.bundleName.c_str(), cardInfo_.id, fontSize.Value());
850         textLayoutProperty->UpdateFontSize(fontSize);
851         textNode->MarkModifyDone();
852         textNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
853     }
854 }
855 
LoadDisableFormStyle(const RequestFormInfo & info,bool isRefresh)856 void FormPattern::LoadDisableFormStyle(const RequestFormInfo& info, bool isRefresh)
857 {
858     if (IsMaskEnableForm(info)) {
859         if (!formManagerBridge_) {
860             TAG_LOGE(AceLogTag::ACE_FORM, "LoadDisableFormStyle failed, form manager deleget is null!");
861             return;
862         }
863 
864         formManagerBridge_->SetObscured(false);
865         return;
866     }
867 
868     if (!isRefresh && GetFormChildNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE) != nullptr &&
869         GetFormChildNode(FormChildNodeType::FORM_FORBIDDEN_TEXT_NODE) != nullptr) {
870         TAG_LOGW(AceLogTag::ACE_FORM, "Form disable style node already exist.");
871         return;
872     }
873 
874     TAG_LOGI(AceLogTag::ACE_FORM, "FormPattern::LoadDisableFormStyle");
875     RemoveFormChildNode(FormChildNodeType::FORM_FORBIDDEN_TEXT_NODE);
876     RemoveFormChildNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE);
877     int32_t dimension = cardInfo_.dimension;
878     int32_t dimensionHeight = GetFormDimensionHeight(dimension);
879     if (dimensionHeight <= 0) {
880         TAG_LOGE(AceLogTag::ACE_FORM, "LoadDisableFormStyle failed, invalid dimensionHeight!");
881         return;
882     }
883 
884     auto columnNode = CreateColumnNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE);
885     CHECK_NULL_VOID(columnNode);
886     auto renderContext = columnNode->GetRenderContext();
887     CHECK_NULL_VOID(renderContext);
888     renderContext->UpdateBackgroundColor(SystemProperties::GetColorMode() == ColorMode::DARK ?
889         Color(FORBIDDEN_BG_COLOR_DARK) : Color(FORBIDDEN_BG_COLOR_LIGHT));
890 
891     auto textNode = CreateTimeLimitNode();
892     CHECK_NULL_VOID(textNode);
893     textNode->MarkModifyDone();
894     textNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
895     columnNode->MarkModifyDone();
896     columnNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
897 
898     auto host = GetHost();
899     CHECK_NULL_VOID(host);
900     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
901     CHECK_NULL_VOID(layoutProperty);
902     auto visible = layoutProperty->GetVisibleType().value_or(VisibleType::VISIBLE);
903     layoutProperty->UpdateVisibility(visible);
904 
905     UpdateChildNodeOpacity(FormChildNodeType::FORM_SURFACE_NODE, TRANSPARENT_VAL);
906     UpdateChildNodeOpacity(FormChildNodeType::FORM_STATIC_IMAGE_NODE, TRANSPARENT_VAL);
907     UpdateChildNodeOpacity(FormChildNodeType::FORM_SKELETON_NODE, TRANSPARENT_VAL);
908 }
909 
RemoveDisableFormStyle(const RequestFormInfo & info)910 void FormPattern::RemoveDisableFormStyle(const RequestFormInfo& info)
911 {
912     if (!IsMaskEnableForm(info)) {
913         UpdateChildNodeOpacity(FormChildNodeType::FORM_SURFACE_NODE, NON_TRANSPARENT_VAL);
914         UpdateChildNodeOpacity(FormChildNodeType::FORM_STATIC_IMAGE_NODE, NON_TRANSPARENT_VAL);
915         UpdateChildNodeOpacity(FormChildNodeType::FORM_SKELETON_NODE, CONTENT_BG_OPACITY);
916         RemoveFormChildNode(FormChildNodeType::FORM_FORBIDDEN_TEXT_NODE);
917         RemoveFormChildNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE);
918         return;
919     }
920     if (!formManagerBridge_) {
921         TAG_LOGE(AceLogTag::ACE_FORM, "RemoveDisableFormStyle failed, form manager deleget is null!");
922         return;
923     }
924     formManagerBridge_->SetObscured(false);
925 }
926 
LoadFormSkeleton(bool isRefresh)927 void FormPattern::LoadFormSkeleton(bool isRefresh)
928 {
929     TAG_LOGI(AceLogTag::ACE_FORM, "LoadFormSkeleton");
930     if (!isRefresh && GetFormChildNode(FormChildNodeType::FORM_SKELETON_NODE) != nullptr) {
931         TAG_LOGW(AceLogTag::ACE_FORM, "LoadFormSkeleton failed, repeat load!");
932         return;
933     }
934 
935     int32_t dimension = cardInfo_.dimension;
936     int32_t dimensionHeight = GetFormDimensionHeight(dimension);
937     if (dimensionHeight <= 0) {
938         TAG_LOGE(AceLogTag::ACE_FORM, "LoadFormSkeleton failed, invalid dimensionHeight!");
939         return;
940     }
941 
942     RemoveFormChildNode(FormChildNodeType::FORM_SKELETON_NODE);
943     auto columnNode = CreateColumnNode(FormChildNodeType::FORM_SKELETON_NODE);
944     CHECK_NULL_VOID(columnNode);
945     double cardWidth = cardInfo_.width.Value();
946     double cardHeight = cardInfo_.height.Value();
947     auto colorMode = SystemProperties::GetColorMode();
948     bool isDarkMode = colorMode == ColorMode::DARK;
949     std::shared_ptr<FormSkeletonParams> params = std::make_shared<FormSkeletonParams>(cardWidth,
950         cardHeight, dimension, dimensionHeight, isDarkMode);
951     CreateSkeletonView(columnNode, params, dimensionHeight);
952 
953     auto renderContext = columnNode->GetRenderContext();
954     if (renderContext != nullptr) {
955         BlurStyleOption styleOption;
956         styleOption.blurStyle = static_cast<BlurStyle>(static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK));
957         renderContext->UpdateBackBlurStyle(styleOption);
958         renderContext->UpdateBackgroundColor(isDarkMode ?
959             Color(CONTENT_BG_COLOR_DARK) : Color(CONTENT_BG_COLOR_LIGHT));
960         double opacity = formChildrenNodeMap_.find(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE)
961             != formChildrenNodeMap_.end() ? TRANSPARENT_VAL : CONTENT_BG_OPACITY;
962         renderContext->SetOpacity(opacity);
963     }
964     columnNode->MarkModifyDone();
965     columnNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
966 
967     auto host = GetHost();
968     CHECK_NULL_VOID(host);
969     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
970     CHECK_NULL_VOID(layoutProperty);
971     auto visible = layoutProperty->GetVisibleType().value_or(VisibleType::VISIBLE);
972     layoutProperty->UpdateVisibility(visible);
973 }
974 
ShouldLoadFormSkeleton(bool isTransparencyEnabled,const RequestFormInfo & info)975 bool FormPattern::ShouldLoadFormSkeleton(bool isTransparencyEnabled, const RequestFormInfo &info)
976 {
977     auto wantWrap = info.wantWrap;
978     if (isUnTrust_) {
979         return true;
980     }
981 
982     if (!wantWrap ||
983         !wantWrap->GetWant().GetBoolParam(OHOS::AppExecFwk::Constants::FORM_ENABLE_SKELETON_KEY, false)) {
984         TAG_LOGD(AceLogTag::ACE_FORM, "LoadFormSkeleton ignored, not enable.");
985         return false;
986     }
987 
988     if (isTransparencyEnabled) {
989         auto color = wantWrap->GetWant().GetStringParam(OHOS::AppExecFwk::Constants::PARAM_FORM_TRANSPARENCY_KEY);
990         Color bgColor;
991         if (Color::ParseColorString(color, bgColor) && bgColor == Color::TRANSPARENT) {
992             TAG_LOGD(AceLogTag::ACE_FORM, "LoadFormSkeleton ignored, bgColor: %{public}s", color.c_str());
993             return false;
994         }
995     }
996 
997     if (info.renderingMode ==
998         static_cast<int32_t>(OHOS::AppExecFwk::Constants::RenderingMode::SINGLE_COLOR)) {
999         TAG_LOGD(AceLogTag::ACE_FORM, "LoadFormSkeleton ignored, single mode.");
1000         return false;
1001     }
1002     return true;
1003 }
1004 
GetFormDimensionHeight(int32_t dimension)1005 int32_t FormPattern::GetFormDimensionHeight(int32_t dimension)
1006 {
1007     auto iter = OHOS::AppExecFwk::Constants::DIMENSION_MAP.
1008         find(static_cast<OHOS::AppExecFwk::Constants::Dimension>(dimension));
1009     if (iter == OHOS::AppExecFwk::Constants::DIMENSION_MAP.end()) {
1010         TAG_LOGE(AceLogTag::ACE_FORM, "GetFormDimensionHeight failed, invalid dimension: %{public}d",
1011             dimension);
1012         return 0;
1013     }
1014 
1015     std::string formDimensionStr = iter->second;
1016     std::stringstream streamDimension(formDimensionStr);
1017     std::string dimensionHeightStr;
1018     if (!std::getline(streamDimension, dimensionHeightStr, FORM_DIMENSION_SPLITTER)) {
1019         TAG_LOGE(AceLogTag::ACE_FORM, "GetFormDimensionHeight failed!");
1020         return 0;
1021     }
1022     return StringUtils::StringToInt(dimensionHeightStr);
1023 }
1024 
CreateTimeLimitNode()1025 RefPtr<FrameNode> FormPattern::CreateTimeLimitNode()
1026 {
1027     auto host = GetHost();
1028     CHECK_NULL_RETURN(host, nullptr);
1029 
1030     std::string content;
1031     GetTimeLimitResource(content);
1032     TAG_LOGI(AceLogTag::ACE_FORM, "GetTimeLimitContent, content = %{public}s", content.c_str());
1033 
1034     RefPtr<FrameNode> textNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG,
1035         ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
1036     CHECK_NULL_RETURN(textNode, nullptr);
1037     AddFormChildNode(FormChildNodeType::FORM_FORBIDDEN_TEXT_NODE, textNode);
1038     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
1039     CHECK_NULL_RETURN(textLayoutProperty, nullptr);
1040 
1041     auto width = static_cast<float>(cardInfo_.width.Value()) - cardInfo_.borderWidth * DOUBLE;
1042     auto height = static_cast<float>(cardInfo_.height.Value()) - cardInfo_.borderWidth * DOUBLE;
1043     CalcSize idealSize = { CalcLength(width), CalcLength(height) };
1044     MeasureProperty layoutConstraint;
1045     layoutConstraint.selfIdealSize = idealSize;
1046     layoutConstraint.maxSize = idealSize;
1047     textNode->UpdateLayoutConstraint(layoutConstraint);
1048     textLayoutProperty->UpdateContent(content);
1049     textLayoutProperty->UpdateFontWeight(FontWeight::BOLDER);
1050     Dimension fontSize(GetTimeLimitFontSize());
1051     textLayoutProperty->UpdateFontSize(fontSize);
1052     textLayoutProperty->UpdateTextColor(SystemProperties::GetColorMode() == ColorMode::DARK ?
1053         Color::WHITE : Color::BLACK);
1054     textLayoutProperty->UpdateTextAlign(TextAlign::CENTER);
1055     auto externalContext = DynamicCast<NG::RosenRenderContext>(textNode->GetRenderContext());
1056     CHECK_NULL_RETURN(externalContext, nullptr);
1057     externalContext->SetVisible(true);
1058     externalContext->SetOpacity(TEXT_TRANSPARENT_VAL);
1059     host->AddChild(textNode);
1060     return textNode;
1061 }
1062 
CreateSkeletonView(const RefPtr<FrameNode> & parent,const std::shared_ptr<FormSkeletonParams> & params,int32_t dimensionHeight)1063 void FormPattern::CreateSkeletonView(const RefPtr<FrameNode>& parent,
1064     const std::shared_ptr<FormSkeletonParams>& params, int32_t dimensionHeight)
1065 {
1066     float lineHeight = params->GetLineHeight();
1067     uint32_t fillColor = params->GetFillColor();
1068     float lineMarginLeft = params->GetLineMarginLeft();
1069 
1070     // 1. Set title line
1071     MarginProperty titleMargin;
1072     titleMargin.top = CalcLength(params->GetTitleMarginTop());
1073     titleMargin.left = CalcLength(lineMarginLeft);
1074     CalcSize titleIdealSize = { CalcLength(params->GetTitleLineWidth()), CalcLength(lineHeight) };
1075     auto titleLineNode = CreateRectNode(parent, titleIdealSize, titleMargin,
1076         fillColor, params->GetTitleOpacity());
1077     CHECK_NULL_VOID(titleLineNode);
1078 
1079     // 2. Set content lines
1080     for (int32_t i = 0; i < params->GetContentLineNum(); i++) {
1081         MarginProperty contentMargin;
1082         contentMargin.top = CalcLength(i == 0 ? params->GetTitleContentMargins() :
1083             params->GetContentMargins());
1084         contentMargin.left = CalcLength(lineMarginLeft);
1085         CalcSize contentIdealSize = { CalcLength(params->GetLineWidth()), CalcLength(lineHeight) };
1086         auto contentLineNode = CreateRectNode(parent, contentIdealSize, contentMargin,
1087             fillColor, params->GetContentOpacity());
1088         CHECK_NULL_VOID(contentLineNode);
1089     }
1090 
1091     // 3. Set ending line if form dimension height greater than 1
1092     if (dimensionHeight > 1) {
1093         MarginProperty endingMargin;
1094         endingMargin.top = CalcLength(params->GetEndingLineMarginTop());
1095         endingMargin.left = CalcLength(lineMarginLeft);
1096         CalcSize endingIdealSize = { CalcLength(params->GetEndingLineWidth()), CalcLength(lineHeight) };
1097         auto endingLineNode = CreateRectNode(parent, endingIdealSize, endingMargin,
1098             fillColor, params->GetContentOpacity());
1099         CHECK_NULL_VOID(endingLineNode);
1100     }
1101 }
1102 
CreateColumnNode(FormChildNodeType formChildNodeType)1103 RefPtr<FrameNode> FormPattern::CreateColumnNode(FormChildNodeType formChildNodeType)
1104 {
1105     auto host = GetHost();
1106     CHECK_NULL_RETURN(host, nullptr);
1107     RefPtr<FrameNode> columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG,
1108         ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<LinearLayoutPattern>(true));
1109     CHECK_NULL_RETURN(columnNode, nullptr);
1110     AddFormChildNode(formChildNodeType, columnNode);
1111     auto width = static_cast<float>(cardInfo_.width.Value());
1112     auto height = static_cast<float>(cardInfo_.height.Value());
1113     CalcSize idealSize = { CalcLength(width), CalcLength(height) };
1114     MeasureProperty layoutConstraint;
1115     layoutConstraint.selfIdealSize = idealSize;
1116     layoutConstraint.maxSize = idealSize;
1117     columnNode->UpdateLayoutConstraint(layoutConstraint);
1118 
1119     auto layoutProperty = columnNode->GetLayoutProperty<LinearLayoutProperty>();
1120     CHECK_NULL_RETURN(layoutProperty, nullptr);
1121     layoutProperty->UpdateCrossAxisAlign(FlexAlign::FLEX_START);
1122 
1123     host->AddChild(columnNode);
1124     return columnNode;
1125 }
1126 
CreateRectNode(const RefPtr<FrameNode> & parent,const CalcSize & idealSize,const MarginProperty & margin,uint32_t fillColor,double opacity)1127 RefPtr<FrameNode> FormPattern::CreateRectNode(const RefPtr<FrameNode>& parent, const CalcSize& idealSize,
1128     const MarginProperty& margin, uint32_t fillColor, double opacity)
1129 {
1130     auto rectNode = FrameNode::CreateFrameNode(V2::RECT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1131         AceType::MakeRefPtr<RectPattern>());
1132     MeasureProperty layoutConstraint;
1133     layoutConstraint.selfIdealSize = idealSize;
1134     layoutConstraint.maxSize = idealSize;
1135     rectNode->UpdateLayoutConstraint(layoutConstraint);
1136 
1137     rectNode->GetLayoutProperty()->UpdateMargin(margin);
1138 
1139     auto paintProperty = rectNode->GetPaintProperty<RectPaintProperty>();
1140     CHECK_NULL_RETURN(paintProperty, nullptr);
1141     paintProperty->UpdateFill(Color(fillColor));
1142     paintProperty->UpdateFillOpacity(opacity);
1143 
1144     paintProperty->UpdateTopLeftRadius(NG::Radius(RECT_RADIUS));
1145     paintProperty->UpdateTopRightRadius(NG::Radius(RECT_RADIUS));
1146     paintProperty->UpdateBottomLeftRadius(NG::Radius(RECT_RADIUS));
1147     paintProperty->UpdateBottomRightRadius(NG::Radius(RECT_RADIUS));
1148 
1149     rectNode->MountToParent(parent);
1150     rectNode->MarkDirtyNode();
1151 
1152     return rectNode;
1153 }
1154 
InitFormManagerDelegate()1155 void FormPattern::InitFormManagerDelegate()
1156 {
1157     if (formManagerBridge_) {
1158         return;
1159     }
1160 
1161     auto host = GetHost();
1162     CHECK_NULL_VOID(host);
1163     auto context = host->GetContextRefPtr();
1164     CHECK_NULL_VOID(context);
1165     formManagerBridge_ = AceType::MakeRefPtr<FormManagerDelegate>(context);
1166     formManagerBridge_->AddRenderDelegate();
1167     formManagerBridge_->RegisterRenderDelegateEvent();
1168     auto formUtils = FormManager::GetInstance().GetFormUtils();
1169     if (formUtils) {
1170         formManagerBridge_->SetFormUtils(formUtils);
1171     }
1172     int32_t instanceID = context->GetInstanceId();
1173     accessibilitySessionAdapter_ = AceType::MakeRefPtr<AccessibilitySessionAdapterForm>(formManagerBridge_);
1174     formManagerBridge_->AddFormAcquireCallback([weak = WeakClaim(this), instanceID](int64_t id, const std::string& path,
1175                                                    const std::string& module, const std::string& data,
1176                                                    const std::map<std::string, sptr<AppExecFwk::FormAshmem>>&
1177                                                        imageDataMap,
1178                                                    const AppExecFwk::FormJsInfo& formJsInfo,
1179                                                    const FrontendType& frontendType, const FrontendType& uiSyntax) {
1180         ContainerScope scope(instanceID);
1181         auto form = weak.Upgrade();
1182         CHECK_NULL_VOID(form);
1183         auto host = form->GetHost();
1184         CHECK_NULL_VOID(host);
1185         auto context = host->GetContext();
1186         CHECK_NULL_VOID(context);
1187         auto uiTaskExecutor =
1188             SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1189         uiTaskExecutor.PostTask([id, path, module, data, imageDataMap, formJsInfo, weak, instanceID, frontendType,
1190                                     uiSyntax] {
1191             ContainerScope scope(instanceID);
1192             auto form = weak.Upgrade();
1193             CHECK_NULL_VOID(form);
1194             auto container = form->GetSubContainer();
1195             CHECK_NULL_VOID(container);
1196             container->SetWindowConfig({ formJsInfo.formWindow.designWidth, formJsInfo.formWindow.autoDesignWidth });
1197             container->RunCard(id, path, module, data, imageDataMap, formJsInfo.formSrc, frontendType, uiSyntax);
1198             }, "ArkUIFormRunCard");
1199     });
1200 
1201     formManagerBridge_->AddFormUpdateCallback(
1202         [weak = WeakClaim(this), instanceID](int64_t id, const std::string& data,
1203             const std::map<std::string, sptr<AppExecFwk::FormAshmem>>& imageDataMap) {
1204             ContainerScope scope(instanceID);
1205             auto form = weak.Upgrade();
1206             CHECK_NULL_VOID(form);
1207             auto host = form->GetHost();
1208             CHECK_NULL_VOID(host);
1209             auto context = host->GetContext();
1210             CHECK_NULL_VOID(context);
1211             auto uiTaskExecutor =
1212                 SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1213             uiTaskExecutor.PostTask([id, data, imageDataMap, weak, instanceID] {
1214                 ContainerScope scope(instanceID);
1215                 auto form = weak.Upgrade();
1216                 CHECK_NULL_VOID(form);
1217                 if (form->ISAllowUpdate()) {
1218                     form->GetSubContainer()->UpdateCard(data, imageDataMap);
1219                 }
1220                 }, "ArkUIFormUpdateCard");
1221         });
1222 
1223     formManagerBridge_->AddFormErrorCallback(
1224         [weak = WeakClaim(this), instanceID](const std::string& code, const std::string& msg) {
1225             ContainerScope scope(instanceID);
1226             auto form = weak.Upgrade();
1227             CHECK_NULL_VOID(form);
1228             auto host = form->GetHost();
1229             CHECK_NULL_VOID(host);
1230             auto context = host->GetContext();
1231             CHECK_NULL_VOID(context);
1232             auto uiTaskExecutor =
1233                 SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1234             uiTaskExecutor.PostTask([code, msg, weak, instanceID] {
1235                 ContainerScope scope(instanceID);
1236                 auto form = weak.Upgrade();
1237                 CHECK_NULL_VOID(form);
1238                 form->FireOnErrorEvent(code, msg);
1239                 }, "ArkUIFormFireErrorEvent");
1240         });
1241 
1242     formManagerBridge_->AddFormUninstallCallback([weak = WeakClaim(this), instanceID](int64_t formId) {
1243         ContainerScope scope(instanceID);
1244         auto form = weak.Upgrade();
1245         CHECK_NULL_VOID(form);
1246         auto host = form->GetHost();
1247         CHECK_NULL_VOID(host);
1248         auto context = host->GetContext();
1249         CHECK_NULL_VOID(context);
1250         auto uiTaskExecutor =
1251             SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1252         uiTaskExecutor.PostTask([formId, weak, instanceID] {
1253             ContainerScope scope(instanceID);
1254             auto form = weak.Upgrade();
1255             CHECK_NULL_VOID(form);
1256             form->FireOnUninstallEvent(formId);
1257             }, "ArkUIFormFireUninstallEvent");
1258     });
1259 
1260     formManagerBridge_->AddFormSurfaceNodeCallback(
1261         [weak = WeakClaim(this), instanceID](
1262             const std::shared_ptr<Rosen::RSSurfaceNode>& node, const AAFwk::Want& want) {
1263             ContainerScope scope(instanceID);
1264             auto pipeline = PipelineContext::GetCurrentContext();
1265             CHECK_NULL_VOID(pipeline);
1266             auto executor = pipeline->GetTaskExecutor();
1267             CHECK_NULL_VOID(executor);
1268             auto uiTaskExecutor =
1269                 SingleTaskExecutor::Make(executor, TaskExecutor::TaskType::UI);
1270             uiTaskExecutor.PostTask([weak, instanceID, node, want] {
1271                 ContainerScope scope(instanceID);
1272                 auto form = weak.Upgrade();
1273                 CHECK_NULL_VOID(form);
1274                 form->FireFormSurfaceNodeCallback(node, want);
1275                 }, "ArkUIFormFireSurfaceNodeCallback");
1276         });
1277 
1278     formManagerBridge_->AddFormSurfaceChangeCallback([weak = WeakClaim(this), instanceID](float width, float height,
1279         float borderWidth) {
1280         ContainerScope scope(instanceID);
1281         auto form = weak.Upgrade();
1282         CHECK_NULL_VOID(form);
1283         auto host = form->GetHost();
1284         CHECK_NULL_VOID(host);
1285         auto context = host->GetContext();
1286         CHECK_NULL_VOID(context);
1287         auto uiTaskExecutor =
1288             SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1289         uiTaskExecutor.PostTask([weak, instanceID, width, height, borderWidth] {
1290             ContainerScope scope(instanceID);
1291             auto form = weak.Upgrade();
1292             CHECK_NULL_VOID(form);
1293             form->FireFormSurfaceChangeCallback(width, height, borderWidth);
1294             }, "ArkUIFormFireSurfaceChange");
1295     });
1296 
1297     formManagerBridge_->AddFormSurfaceDetachCallback([weak = WeakClaim(this), instanceID]() {
1298             ContainerScope scope(instanceID);
1299             auto formPattern = weak.Upgrade();
1300             CHECK_NULL_VOID(formPattern);
1301             formPattern->FireFormSurfaceDetachCallback();
1302         });
1303 
1304     formManagerBridge_->AddActionEventHandle([weak = WeakClaim(this), instanceID](const std::string& action) {
1305         ContainerScope scope(instanceID);
1306         TAG_LOGI(AceLogTag::ACE_FORM, "Card receive action event, action: %{public}zu", action.length());
1307         auto formPattern = weak.Upgrade();
1308         CHECK_NULL_VOID(formPattern);
1309         formPattern->OnActionEvent(action);
1310     });
1311 
1312     formManagerBridge_->AddUnTrustFormCallback([weak = WeakClaim(this), instanceID]() {
1313         ContainerScope scope(instanceID);
1314         auto formPattern = weak.Upgrade();
1315         CHECK_NULL_VOID(formPattern);
1316         auto host = formPattern->GetHost();
1317         CHECK_NULL_VOID(host);
1318         auto context = host->GetContext();
1319         CHECK_NULL_VOID(context);
1320         auto uiTaskExecutor =
1321             SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1322         uiTaskExecutor.PostTask([weak, instanceID] {
1323             ContainerScope scope(instanceID);
1324             auto formPattern = weak.Upgrade();
1325             CHECK_NULL_VOID(formPattern);
1326             formPattern->HandleUnTrustForm();
1327             }, "ArkUIFormHandleUnTrust");
1328     });
1329 
1330     formManagerBridge_->AddSnapshotCallback([weak = WeakClaim(this), instanceID](const uint32_t& delayTime) {
1331         ContainerScope scope(instanceID);
1332         auto formPattern = weak.Upgrade();
1333         CHECK_NULL_VOID(formPattern);
1334         formPattern->HandleSnapshot(delayTime);
1335     });
1336 
1337     formManagerBridge_->AddFormLinkInfoUpdateCallback(
1338         [weak = WeakClaim(this), instanceID](const std::vector<std::string>& infos) {
1339             ContainerScope scope(instanceID);
1340             auto formPattern = weak.Upgrade();
1341             CHECK_NULL_VOID(formPattern);
1342             formPattern->SetFormLinkInfos(infos);
1343         });
1344 
1345     formManagerBridge_->AddGetRectRelativeToWindowCallback(
1346         [weak = WeakClaim(this), instanceID](int32_t &top, int32_t &left) {
1347             ContainerScope scope(instanceID);
1348             auto context = PipelineContext::GetCurrentContextSafely();
1349             CHECK_NULL_VOID(context);
1350             auto uiTaskExecutor =
1351                 SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1352             uiTaskExecutor.PostSyncTask([weak, instanceID, &top, &left] {
1353                 ContainerScope scope(instanceID);
1354                 auto form = weak.Upgrade();
1355                 CHECK_NULL_VOID(form);
1356                 form->GetRectRelativeToWindow(top, left);
1357                 }, "ArkUIFormGetRectRelativeToWindow");
1358         });
1359 
1360     formManagerBridge_->AddEnableFormCallback([weak = WeakClaim(this), instanceID](const bool enable) {
1361         ContainerScope scope(instanceID);
1362         auto formPattern = weak.Upgrade();
1363         CHECK_NULL_VOID(formPattern);
1364         auto host = formPattern->GetHost();
1365         CHECK_NULL_VOID(host);
1366         auto context = host->GetContext();
1367         CHECK_NULL_VOID(context);
1368         auto uiTaskExecutor =
1369             SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1370         uiTaskExecutor.PostTask([weak, instanceID, enable] {
1371             ContainerScope scope(instanceID);
1372             auto formPattern = weak.Upgrade();
1373             CHECK_NULL_VOID(formPattern);
1374             formPattern->HandleEnableForm(enable);
1375             }, "ArkUIFormHandleEnableForm");
1376         });
1377 
1378     const std::function<void(bool isRotate,
1379         const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)>& callback = [this](bool isRotate,
1380         const std::shared_ptr<Rosen::RSTransaction>& rsTransaction) {
1381         FormManager::GetInstance().NotifyIsSizeChangeByRotate(isRotate, rsTransaction);
1382     };
1383     context->SetSizeChangeByRotateCallback(callback);
1384 }
1385 
GetRectRelativeToWindow(int32_t & top,int32_t & left)1386 void FormPattern::GetRectRelativeToWindow(int32_t &top, int32_t &left)
1387 {
1388     auto host = GetHost();
1389     CHECK_NULL_VOID(host);
1390     auto rect = host->GetTransformRectRelativeToWindow();
1391     top = rect.Top();
1392     left = rect.Left();
1393     TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "elementId: %{public}" PRId64 ", top: %{public}d, left: %{public}d",
1394         host->GetAccessibilityId(), top, left);
1395 }
1396 
ProcDeleteImageNode(const AAFwk::Want & want)1397 void FormPattern::ProcDeleteImageNode(const AAFwk::Want& want)
1398 {
1399     if (want.GetBoolParam(OHOS::AppExecFwk::Constants::FORM_IS_RECOVER_FORM, false)) {
1400         DelayDeleteImageNode(want.GetBoolParam(
1401             OHOS::AppExecFwk::Constants::FORM_IS_RECOVER_FORM_TO_HANDLE_CLICK_EVENT, false));
1402     } else {
1403         RemoveFormChildNode(FormChildNodeType::FORM_STATIC_IMAGE_NODE);
1404     }
1405 }
1406 
AttachRSNode(const std::shared_ptr<Rosen::RSSurfaceNode> & node,const AAFwk::Want & want)1407 void FormPattern::AttachRSNode(const std::shared_ptr<Rosen::RSSurfaceNode>& node, const AAFwk::Want& want)
1408 {
1409     auto host = GetHost();
1410     CHECK_NULL_VOID(host);
1411     auto externalRenderContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
1412     CHECK_NULL_VOID(externalRenderContext);
1413     externalRenderContext->SetRSNode(node);
1414     float boundWidth = cardInfo_.width.Value() - cardInfo_.borderWidth * DOUBLE;
1415     float boundHeight = cardInfo_.height.Value() - cardInfo_.borderWidth * DOUBLE;
1416     if (isBeenLayout_) {
1417         auto geometryNode = host->GetGeometryNode();
1418         CHECK_NULL_VOID(geometryNode);
1419         auto size = geometryNode->GetFrameSize();
1420         boundWidth = size.Width() - cardInfo_.borderWidth * DOUBLE;
1421         boundHeight = size.Height() - cardInfo_.borderWidth * DOUBLE;
1422     }
1423     externalRenderContext->SetBounds(round(cardInfo_.borderWidth), round(cardInfo_.borderWidth),
1424         round(boundWidth), round(boundHeight));
1425 
1426     bool isRecover = want.GetBoolParam(OHOS::AppExecFwk::Constants::FORM_IS_RECOVER_FORM, false);
1427     if (isRecover || formChildrenNodeMap_.find(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE)
1428         != formChildrenNodeMap_.end()) {
1429         TAG_LOGI(AceLogTag::ACE_FORM, "surfaceNode: %{public}s setOpacity:0", std::to_string(node->GetId()).c_str());
1430         externalRenderContext->SetOpacity(TRANSPARENT_VAL);
1431     } else {
1432         TAG_LOGI(AceLogTag::ACE_FORM, "surfaceNode: %{public}s setOpacity:1", std::to_string(node->GetId()).c_str());
1433         externalRenderContext->SetOpacity(NON_TRANSPARENT_VAL);
1434     }
1435 
1436     auto renderContext = host->GetRenderContext();
1437     CHECK_NULL_VOID(renderContext);
1438     renderContext->AddChild(externalRenderContext, 0);
1439 }
1440 
FireFormSurfaceNodeCallback(const std::shared_ptr<Rosen::RSSurfaceNode> & node,const AAFwk::Want & want)1441 void FormPattern::FireFormSurfaceNodeCallback(
1442     const std::shared_ptr<Rosen::RSSurfaceNode>& node, const AAFwk::Want& want)
1443 {
1444     ACE_FUNCTION_TRACE();
1445     CHECK_NULL_VOID(node);
1446     node->CreateNodeInRenderThread();
1447 
1448     AttachRSNode(node, want);
1449     RemoveFormChildNode(FormChildNodeType::FORM_SKELETON_NODE);
1450 
1451     auto host = GetHost();
1452     CHECK_NULL_VOID(host);
1453     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
1454     CHECK_NULL_VOID(layoutProperty);
1455     auto visible = layoutProperty->GetVisibleType().value_or(VisibleType::VISIBLE);
1456     TAG_LOGI(AceLogTag::ACE_FORM, "VisibleType: %{public}d, surfaceNode: %{public}s",
1457         static_cast<int32_t>(visible), std::to_string(node->GetId()).c_str());
1458     layoutProperty->UpdateVisibility(visible);
1459 
1460     isLoaded_ = true;
1461     isUnTrust_ = false;
1462     isFrsNodeDetached_ = false;
1463     isDynamic_ = want.GetBoolParam(OHOS::AppExecFwk::Constants::FORM_IS_DYNAMIC, false);
1464 
1465     ProcDeleteImageNode(want);
1466 
1467     host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
1468     auto parent = host->GetParent();
1469     CHECK_NULL_VOID(parent);
1470     parent->MarkNeedSyncRenderTree();
1471     parent->RebuildRenderContextTree();
1472     auto renderContext = host->GetRenderContext();
1473     CHECK_NULL_VOID(renderContext);
1474     renderContext->RequestNextFrame();
1475     OnLoadEvent();
1476 
1477     auto formNode = DynamicCast<FormNode>(host);
1478     CHECK_NULL_VOID(formNode);
1479     formNode->NotifyAccessibilityChildTreeRegister();
1480 }
1481 
DelayDeleteImageNode(bool needHandleCachedClick)1482 void FormPattern::DelayDeleteImageNode(bool needHandleCachedClick)
1483 {
1484     auto host = GetHost();
1485     CHECK_NULL_VOID(host);
1486     auto context = host->GetContext();
1487     CHECK_NULL_VOID(context);
1488 
1489     auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1490     uiTaskExecutor.PostDelayedTask(
1491         [weak = WeakClaim(this)] {
1492             auto pattern = weak.Upgrade();
1493             CHECK_NULL_VOID(pattern);
1494             pattern->SetNonTransparentAfterRecover();
1495         },
1496         DELAY_TIME_FOR_SET_NON_TRANSPARENT, "ArkUIFormSetNonTransparentAfterRecover");
1497     uiTaskExecutor.PostDelayedTask(
1498         [weak = WeakClaim(this), needHandleCachedClick] {
1499             auto pattern = weak.Upgrade();
1500             CHECK_NULL_VOID(pattern);
1501             pattern->DeleteImageNodeAfterRecover(needHandleCachedClick);
1502         },
1503         DELAY_TIME_FOR_DELETE_IMAGE_NODE, "ArkUIFormDeleteImageNodeAfterRecover");
1504 }
1505 
FireFormSurfaceChangeCallback(float width,float height,float borderWidth)1506 void FormPattern::FireFormSurfaceChangeCallback(float width, float height, float borderWidth)
1507 {
1508     auto externalRenderContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
1509     CHECK_NULL_VOID(externalRenderContext);
1510     externalRenderContext->SetBounds(round(borderWidth), round(borderWidth), round(width - borderWidth * DOUBLE),
1511         round(height - borderWidth * DOUBLE));
1512     auto host = GetHost();
1513     CHECK_NULL_VOID(host);
1514     auto renderContext = host->GetRenderContext();
1515     CHECK_NULL_VOID(renderContext);
1516     isUnTrust_ = false;
1517     host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
1518     auto parent = host->GetParent();
1519     CHECK_NULL_VOID(parent);
1520     parent->MarkNeedSyncRenderTree();
1521     parent->RebuildRenderContextTree();
1522     renderContext->RequestNextFrame();
1523 }
1524 
FireFormSurfaceDetachCallback()1525 void FormPattern::FireFormSurfaceDetachCallback()
1526 {
1527     TAG_LOGI(AceLogTag::ACE_FORM, "FireFormSurfaceDetachCallback isFrsNodeDetached:%{public}d", isFrsNodeDetached_);
1528     isFrsNodeDetached_ = true;
1529 }
1530 
CreateCardContainer()1531 void FormPattern::CreateCardContainer()
1532 {
1533     auto host = GetHost();
1534     CHECK_NULL_VOID(host);
1535     auto context = host->GetContextRefPtr();
1536     CHECK_NULL_VOID(context);
1537     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
1538     CHECK_NULL_VOID(layoutProperty);
1539     auto hasContainer = false;
1540     RemoveSubContainer();
1541     if (cardInfo_.id != 0 && Container::IsCurrentUseNewPipeline()) {
1542         auto subContainer = FormManager::GetInstance().GetSubContainer(cardInfo_.id);
1543         if (subContainer && context->GetInstanceId() == subContainer->GetInstanceId() &&
1544             subContainer->GetCardType() == FrontendType::JS_CARD) {
1545             subContainer_ = subContainer;
1546             FormManager::GetInstance().RemoveSubContainer(cardInfo_.id);
1547             hasContainer = true;
1548         }
1549     }
1550     if (!subContainer_) {
1551         subContainer_ = AceType::MakeRefPtr<SubContainer>(context, context->GetInstanceId());
1552     }
1553     CHECK_NULL_VOID(subContainer_);
1554     subContainer_->SetFormPattern(WeakClaim(this));
1555     subContainer_->Initialize();
1556     subContainer_->SetNodeId(host->GetId());
1557 
1558     subContainer_->AddFormAcquireCallback([weak = WeakClaim(this)](int64_t id) {
1559         auto pattern = weak.Upgrade();
1560         CHECK_NULL_VOID(pattern);
1561         auto host = pattern->GetHost();
1562         CHECK_NULL_VOID(host);
1563         auto context = host->GetContext();
1564         CHECK_NULL_VOID(context);
1565         auto uiTaskExecutor =
1566             SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1567         uiTaskExecutor.PostTask([id, weak] {
1568             auto pattern = weak.Upgrade();
1569             CHECK_NULL_VOID(pattern);
1570             pattern->FireOnAcquiredEvent(id);
1571             }, "ArkUIFormFireAcquiredEvent");
1572     });
1573 
1574     subContainer_->SetFormLoadCallback([weak = WeakClaim(this)]() {
1575         auto pattern = weak.Upgrade();
1576         CHECK_NULL_VOID(pattern);
1577         pattern->OnLoadEvent();
1578     });
1579 
1580     subContainer_->AddFormVisiableCallback([weak = WeakClaim(this)]() {
1581         auto pattern = weak.Upgrade();
1582         CHECK_NULL_VOID(pattern);
1583         auto host = pattern->GetHost();
1584         CHECK_NULL_VOID(host);
1585         auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
1586         CHECK_NULL_VOID(layoutProperty);
1587         auto visible = layoutProperty->GetVisibleType().value_or(VisibleType::VISIBLE);
1588         layoutProperty->UpdateVisibility(visible);
1589         pattern->isLoaded_ = true;
1590     });
1591 
1592     if (hasContainer) {
1593         subContainer_->RunSameCard();
1594     }
1595 }
1596 
AttachJsRSNode(const std::shared_ptr<Rosen::RSNode> & jsNode)1597 void FormPattern::AttachJsRSNode(const std::shared_ptr<Rosen::RSNode> &jsNode)
1598 {
1599     auto host = GetHost();
1600     CHECK_NULL_VOID(host);
1601     auto externalRenderContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
1602     CHECK_NULL_VOID(externalRenderContext);
1603     externalRenderContext->SetRSNode(jsNode);
1604 
1605     auto renderContext = host->GetRenderContext();
1606     CHECK_NULL_VOID(renderContext);
1607     renderContext->AddChild(externalRenderContext, 0);
1608 }
1609 
GetDrawDelegate()1610 std::unique_ptr<DrawDelegate> FormPattern::GetDrawDelegate()
1611 {
1612     auto drawDelegate = std::make_unique<DrawDelegate>();
1613 #ifdef ENABLE_ROSEN_BACKEND
1614     drawDelegate->SetDrawRSFrameCallback(
1615         [weak = WeakClaim(this)](std::shared_ptr<RSNode>& node, const Rect& /* dirty */) {
1616             CHECK_NULL_VOID(node);
1617             auto form = weak.Upgrade();
1618             CHECK_NULL_VOID(form);
1619             auto host = form->GetHost();
1620             CHECK_NULL_VOID(host);
1621             auto context = DynamicCast<NG::RosenRenderContext>(host->GetRenderContext());
1622             CHECK_NULL_VOID(context);
1623             auto rsNode = context->GetRSNode();
1624             CHECK_NULL_VOID(rsNode);
1625             form->AttachJsRSNode(node);
1626             host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
1627         });
1628 
1629     drawDelegate->SetDrawRSFrameByRenderContextCallback(
1630         [weak = WeakClaim(this)](RefPtr<OHOS::Ace::NG::RenderContext>& renderContext) {
1631             auto context = DynamicCast<NG::RosenRenderContext>(renderContext);
1632             CHECK_NULL_VOID(context);
1633             auto node = context->GetRSNode();
1634             CHECK_NULL_VOID(node);
1635             auto form = weak.Upgrade();
1636             CHECK_NULL_VOID(form);
1637             auto host = form->GetHost();
1638             CHECK_NULL_VOID(host);
1639             auto formContext = DynamicCast<NG::RosenRenderContext>(host->GetRenderContext());
1640             CHECK_NULL_VOID(formContext);
1641             auto rsNode = formContext->GetRSNode();
1642             CHECK_NULL_VOID(rsNode);
1643             form->AttachJsRSNode(node);
1644             host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
1645         });
1646 #endif
1647     return drawDelegate;
1648 }
1649 
FireOnErrorEvent(const std::string & code,const std::string & msg) const1650 void FormPattern::FireOnErrorEvent(const std::string& code, const std::string& msg) const
1651 {
1652     auto host = GetHost();
1653     CHECK_NULL_VOID(host);
1654     auto eventHub = host->GetEventHub<FormEventHub>();
1655     CHECK_NULL_VOID(eventHub);
1656     auto json = JsonUtil::Create(true);
1657     json->Put("errcode", code.c_str());
1658     json->Put("msg", msg.c_str());
1659     eventHub->FireOnError(json->ToString());
1660 }
1661 
FireOnUninstallEvent(int64_t id) const1662 void FormPattern::FireOnUninstallEvent(int64_t id) const
1663 {
1664     auto host = GetHost();
1665     CHECK_NULL_VOID(host);
1666     auto eventHub = host->GetEventHub<FormEventHub>();
1667     CHECK_NULL_VOID(eventHub);
1668     int64_t uninstallFormId = id < MAX_NUMBER_OF_JS ? id : -1;
1669     auto json = JsonUtil::Create(true);
1670     json->Put("id", std::to_string(uninstallFormId).c_str());
1671     json->Put("idString", std::to_string(id).c_str());
1672     eventHub->FireOnUninstall(json->ToString());
1673 }
1674 
FireOnAcquiredEvent(int64_t id) const1675 void FormPattern::FireOnAcquiredEvent(int64_t id) const
1676 {
1677     auto host = GetHost();
1678     CHECK_NULL_VOID(host);
1679     auto eventHub = host->GetEventHub<FormEventHub>();
1680     CHECK_NULL_VOID(eventHub);
1681     int64_t onAcquireFormId = id < MAX_NUMBER_OF_JS ? id : -1;
1682     auto json = JsonUtil::Create(true);
1683     json->Put("id", std::to_string(onAcquireFormId).c_str());
1684     json->Put("idString", std::to_string(id).c_str());
1685     eventHub->FireOnAcquired(json->ToString());
1686 }
1687 
FireOnRouterEvent(const std::unique_ptr<JsonValue> & action)1688 void FormPattern::FireOnRouterEvent(const std::unique_ptr<JsonValue>& action)
1689 {
1690     auto host = GetHost();
1691     CHECK_NULL_VOID(host);
1692     auto eventHub = host->GetEventHub<FormEventHub>();
1693     CHECK_NULL_VOID(eventHub);
1694     auto json = JsonUtil::Create(true);
1695     json->Put("action", action);
1696     eventHub->FireOnRouter(json->ToString());
1697 }
1698 
FireOnLoadEvent() const1699 void FormPattern::FireOnLoadEvent() const
1700 {
1701     auto host = GetHost();
1702     CHECK_NULL_VOID(host);
1703     auto eventHub = host->GetEventHub<FormEventHub>();
1704     CHECK_NULL_VOID(eventHub);
1705     eventHub->FireOnLoad("");
1706 }
1707 
OnLoadEvent()1708 void FormPattern::OnLoadEvent()
1709 {
1710     ACE_FUNCTION_TRACE();
1711     isSnapshot_ = false;
1712     auto host = GetHost();
1713     CHECK_NULL_VOID(host);
1714     auto context = host->GetContext();
1715     CHECK_NULL_VOID(context);
1716     auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1717     uiTaskExecutor.PostTask([weak = WeakClaim(this)] {
1718         auto pattern = weak.Upgrade();
1719         CHECK_NULL_VOID(pattern);
1720         pattern->FireOnLoadEvent();
1721         }, "ArkUIFormFireLoadEvent");
1722 }
1723 
OnActionEvent(const std::string & action)1724 void FormPattern::OnActionEvent(const std::string& action)
1725 {
1726     TAG_LOGI(AceLogTag::ACE_FORM, "formPattern receive actionEvent");
1727     if (!formManagerBridge_) {
1728         TAG_LOGE(AceLogTag::ACE_FORM, "OnActionEvent failed, form manager deleget is null!");
1729         return;
1730     }
1731     auto eventAction = JsonUtil::ParseJsonString(action);
1732     if (!eventAction->IsValid()) {
1733         return;
1734     }
1735 
1736     auto actionType = eventAction->GetValue("action");
1737     if (!actionType->IsValid()) {
1738         return;
1739     }
1740 
1741     auto type = actionType->GetString();
1742     if (type != "router" && type != "message" && type != "call") {
1743         return;
1744     }
1745 
1746     RemoveDelayResetManuallyClickFlagTask();
1747     auto subContainer = GetSubContainer();
1748     if (!isManuallyClick_ && subContainer->GetUISyntaxType() == FrontendType::ETS_CARD) {
1749         if ("router" == type && !AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
1750             TAG_LOGI(AceLogTag::ACE_FORM, "postcardaction is not manually click.");
1751             return;
1752         }
1753     }
1754 
1755     if ("router" == type) {
1756         isManuallyClick_ = false;
1757         auto host = GetHost();
1758         CHECK_NULL_VOID(host);
1759         auto context = host->GetContext();
1760         CHECK_NULL_VOID(context);
1761         auto uiTaskExecutor =
1762             SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1763         if (uiTaskExecutor.IsRunOnCurrentThread()) {
1764             FireOnRouterEvent(eventAction);
1765         } else {
1766             uiTaskExecutor.PostTask([weak = WeakClaim(this), action] {
1767                 auto pattern = weak.Upgrade();
1768                 CHECK_NULL_VOID(pattern);
1769                 auto eventAction = JsonUtil::ParseJsonString(action);
1770                 TAG_LOGI(AceLogTag::ACE_FORM, "UI task execute begin.");
1771                 pattern->FireOnRouterEvent(eventAction);
1772                 }, "ArkUIFormFireRouterEvent");
1773         }
1774     }
1775 
1776     formManagerBridge_->OnActionEvent(action);
1777 }
1778 
ISAllowUpdate() const1779 bool FormPattern::ISAllowUpdate() const
1780 {
1781     auto host = GetHost();
1782     CHECK_NULL_RETURN(host, true);
1783     auto property = host->GetLayoutProperty<FormLayoutProperty>();
1784     CHECK_NULL_RETURN(property, true);
1785     auto formInfo = property->GetRequestFormInfo();
1786     CHECK_NULL_RETURN(property, true);
1787     return formInfo->allowUpdate;
1788 }
1789 
GetSubContainer() const1790 const RefPtr<SubContainer>& FormPattern::GetSubContainer() const
1791 {
1792     return subContainer_;
1793 }
1794 
DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,SerializedGesture & serializedGesture)1795 void FormPattern::DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
1796     SerializedGesture& serializedGesture)
1797 {
1798     CHECK_NULL_VOID(pointerEvent);
1799     CHECK_NULL_VOID(formManagerBridge_);
1800 
1801     if (OHOS::MMI::PointerEvent::POINTER_ACTION_DOWN == pointerEvent->GetPointerAction()) {
1802         isManuallyClick_ = true;
1803         DelayResetManuallyClickFlag();
1804     }
1805 
1806     if (!isVisible_) {
1807         auto pointerAction = pointerEvent->GetPointerAction();
1808         if (pointerAction == OHOS::MMI::PointerEvent::POINTER_ACTION_UP ||
1809             pointerAction == OHOS::MMI::PointerEvent::POINTER_ACTION_PULL_UP ||
1810             pointerAction == OHOS::MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW ||
1811             pointerAction == OHOS::MMI::PointerEvent::POINTER_ACTION_CANCEL) {
1812             // still dispatch 'up' or 'cancel' event to finish this pointer event
1813             formManagerBridge_->DispatchPointerEvent(pointerEvent, serializedGesture);
1814         } else {
1815             TAG_LOGD(AceLogTag::ACE_FORM, "form invisible, not dispatch pointerEvent: %{public}d.", pointerAction);
1816         }
1817         return;
1818     }
1819     formManagerBridge_->DispatchPointerEvent(pointerEvent, serializedGesture);
1820 }
1821 
RemoveSubContainer()1822 void FormPattern::RemoveSubContainer()
1823 {
1824     auto host = GetHost();
1825     auto eventHub = host->GetEventHub<FormEventHub>();
1826     if (eventHub) {
1827         eventHub->FireOnCache();
1828     }
1829     subContainer_.Reset();
1830 }
1831 
EnableDrag()1832 void FormPattern::EnableDrag()
1833 {
1834     auto host = GetHost();
1835     CHECK_NULL_VOID(host);
1836 
1837     auto dragStart = [weak = WeakClaim(this)](const RefPtr<OHOS::Ace::DragEvent>& event,
1838                          const std::string& /* extraParams */) -> DragDropInfo {
1839         DragDropInfo info;
1840 
1841         auto form = weak.Upgrade();
1842         CHECK_NULL_RETURN(form, info);
1843         auto subcontainer = form->GetSubContainer();
1844         CHECK_NULL_RETURN(subcontainer, info);
1845 
1846         RefPtr<UnifiedData> unifiedData = UdmfClient::GetInstance()->CreateUnifiedData();
1847         UdmfClient::GetInstance()->AddFormRecord(unifiedData, subcontainer->GetRunningCardId(), form->cardInfo_);
1848         event->SetData(unifiedData);
1849 
1850         info.extraInfo = "card drag";
1851         return info;
1852     };
1853     auto eventHub = GetHost()->GetEventHub<EventHub>();
1854     CHECK_NULL_VOID(eventHub);
1855     eventHub->SetDefaultOnDragStart(std::move(dragStart));
1856 }
1857 
UpdateConfiguration()1858 void FormPattern::UpdateConfiguration()
1859 {
1860     auto localeTag = AceApplicationInfo::GetInstance().GetLocaleTag();
1861     if (localeTag != localeTag_ && subContainer_) {
1862         localeTag_ = localeTag;
1863         subContainer_->UpdateConfiguration();
1864     }
1865 }
1866 
OnLanguageConfigurationUpdate()1867 void FormPattern::OnLanguageConfigurationUpdate()
1868 {
1869     RefPtr<FrameNode> textNode = GetFormChildNode(FormChildNodeType::FORM_FORBIDDEN_TEXT_NODE);
1870     CHECK_NULL_VOID(textNode);
1871     auto host = GetHost();
1872     CHECK_NULL_VOID(host);
1873     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
1874     CHECK_NULL_VOID(textLayoutProperty);
1875     std::string content;
1876     GetTimeLimitResource(content);
1877     textLayoutProperty->UpdateContent(content);
1878 
1879     Dimension fontSize(GetTimeLimitFontSize());
1880     if (!textLayoutProperty->GetFontSize().has_value() ||
1881         !NearEqual(textLayoutProperty->GetFontSize().value(), fontSize)) {
1882         textLayoutProperty->UpdateFontSize(fontSize);
1883     }
1884 }
1885 
GetTimeLimitResource(std::string & content)1886 void FormPattern::GetTimeLimitResource(std::string &content)
1887 {
1888     std::shared_ptr<Global::Resource::ResourceManager> sysResMgr(Global::Resource::CreateResourceManager());
1889     if (sysResMgr == nullptr) {
1890         TAG_LOGE(AceLogTag::ACE_FORM, "init sysMgr failed!");
1891         return;
1892     }
1893     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
1894     if (resConfig == nullptr) {
1895         TAG_LOGE(AceLogTag::ACE_FORM, "init resConfig failed!");
1896         return;
1897     }
1898 
1899     sysResMgr->GetResConfig(*resConfig);
1900     UErrorCode status = U_ZERO_ERROR;
1901     std::string language = Global::I18n::LocaleConfig::GetSystemLanguage();
1902     icu::Locale locale = icu::Locale::forLanguageTag(language, status);
1903     if (status != U_ZERO_ERROR) {
1904         TAG_LOGE(AceLogTag::ACE_FORM, "forLanguageTag failed, errCode:%{public}d", status);
1905         return;
1906     }
1907 
1908     resConfig->SetLocaleInfo(locale.getLanguage(), locale.getScript(), locale.getCountry());
1909     Global::Resource::RState state = sysResMgr->UpdateResConfig(*resConfig);
1910     if (state != Global::Resource::RState::SUCCESS) {
1911         TAG_LOGE(AceLogTag::ACE_FORM, "UpdateResConfig failed! errcode:%{public}d.", state);
1912         return;
1913     }
1914     sysResMgr->GetStringByName(TIME_LIMIT_RESOURCE_NAME, content);
1915     isTibetanLanguage_ = language == "bo"? true : false;
1916 }
1917 
AddFormChildNode(FormChildNodeType formChildNodeType,const RefPtr<FrameNode> child)1918 void FormPattern::AddFormChildNode(FormChildNodeType formChildNodeType, const RefPtr<FrameNode> child)
1919 {
1920     auto iter = formChildrenNodeMap_.find(formChildNodeType);
1921     if (iter == formChildrenNodeMap_.end()) {
1922         formChildrenNodeMap_.insert(std::make_pair(formChildNodeType, child));
1923     } else {
1924         formChildrenNodeMap_[formChildNodeType] = child;
1925     }
1926 }
1927 
RemoveFormChildNode(FormChildNodeType formChildNodeType)1928 void FormPattern::RemoveFormChildNode(FormChildNodeType formChildNodeType)
1929 {
1930     RefPtr<FrameNode> childNode = GetFormChildNode(formChildNodeType);
1931     CHECK_NULL_VOID(childNode);
1932 
1933     ContainerScope scope(scopeId_);
1934     auto host = GetHost();
1935     CHECK_NULL_VOID(host);
1936     auto renderContext = host->GetRenderContext();
1937     if (renderContext == nullptr) {
1938         TAG_LOGE(AceLogTag::ACE_FORM, "Remove child node: %{public}d failed, null context.",
1939             formChildNodeType);
1940         return;
1941     }
1942     renderContext->RemoveChild(childNode->GetRenderContext());
1943     host->RemoveChild(childNode);
1944     TAG_LOGI(AceLogTag::ACE_FORM, "Remove child node: %{public}d sucessfully.",
1945         formChildNodeType);
1946     formChildrenNodeMap_.erase(formChildNodeType);
1947     host->MarkModifyDone();
1948     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1949 }
1950 
GetFormChildNode(FormChildNodeType formChildNodeType) const1951 RefPtr<FrameNode> FormPattern::GetFormChildNode(FormChildNodeType formChildNodeType) const
1952 {
1953     auto iter = formChildrenNodeMap_.find(formChildNodeType);
1954     if (iter == formChildrenNodeMap_.end()) {
1955         return nullptr;
1956     }
1957 
1958     return iter->second;
1959 }
1960 
GetTimeLimitFontSize()1961 double FormPattern::GetTimeLimitFontSize()
1962 {
1963     float fontScale = SystemProperties::GetFontScale();
1964     if (fontScale > MAX_FONT_SCALE) {
1965         fontScale = MAX_FONT_SCALE;
1966     }
1967     double density = PipelineBase::GetCurrentDensity();
1968     TAG_LOGD(AceLogTag::ACE_FORM, "Density is %{public}f, font scale is %{public}f.",
1969         density, fontScale);
1970 
1971     int32_t dimensionHeight = GetFormDimensionHeight(cardInfo_.dimension);
1972     if (dimensionHeight == FORM_DIMENSION_MIN_HEIGHT && isTibetanLanguage_) {
1973         return TIBETAN_TIME_LIMIT_FONT_SIZE_BASE * density * fontScale;
1974     } else {
1975         return TIME_LIMIT_FONT_SIZE_BASE * density * fontScale;
1976     }
1977 }
1978 
IsMaskEnableForm(const RequestFormInfo & info)1979 bool FormPattern::IsMaskEnableForm(const RequestFormInfo& info)
1980 {
1981     return info.shape == FORM_SHAPE_CIRCLE || info.renderingMode ==
1982         static_cast<int32_t>(OHOS::AppExecFwk::Constants::RenderingMode::SINGLE_COLOR) ||
1983         info.dimension == static_cast<int32_t>(OHOS::AppExecFwk::Constants::Dimension::DIMENSION_1_1);
1984 }
1985 
UpdateChildNodeOpacity(FormChildNodeType formChildNodeType,double opacity)1986 void FormPattern::UpdateChildNodeOpacity(FormChildNodeType formChildNodeType, double opacity)
1987 {
1988     TAG_LOGI(AceLogTag::ACE_FORM, "formChildNodeType: %{public}d, opacity: %{public}f.",
1989         static_cast<int32_t>(formChildNodeType), opacity);
1990     if (formChildNodeType == FormChildNodeType::FORM_SURFACE_NODE) {
1991         auto externalRenderContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
1992         CHECK_NULL_VOID(externalRenderContext);
1993         externalRenderContext->OnOpacityUpdate(opacity);
1994     } else if (formChildNodeType == FormChildNodeType::FORM_STATIC_IMAGE_NODE ||
1995         formChildNodeType == FormChildNodeType::FORM_SKELETON_NODE) {
1996         auto childNode = GetFormChildNode(formChildNodeType);
1997         CHECK_NULL_VOID(childNode);
1998         auto renderContext = DynamicCast<NG::RosenRenderContext>(childNode->GetRenderContext());
1999         CHECK_NULL_VOID(renderContext);
2000         renderContext->OnOpacityUpdate(opacity);
2001     }
2002 }
2003 
UnregisterAccessibility()2004 void FormPattern::UnregisterAccessibility()
2005 {
2006     auto host = GetHost();
2007     CHECK_NULL_VOID(host);
2008     auto formNode = DynamicCast<FormNode>(host);
2009     CHECK_NULL_VOID(formNode);
2010     formNode->ClearAccessibilityChildTreeRegisterFlag();
2011 }
2012 
CheckFormBundleForbidden(const std::string & bundleName)2013 bool FormPattern::CheckFormBundleForbidden(const std::string &bundleName)
2014 {
2015     CHECK_NULL_RETURN(formManagerBridge_, false);
2016     return formManagerBridge_->CheckFormBundleForbidden(bundleName);
2017 }
2018 
DelayResetManuallyClickFlag()2019 void FormPattern::DelayResetManuallyClickFlag()
2020 {
2021     auto host = GetHost();
2022     CHECK_NULL_VOID(host);
2023     auto context = host->GetContext();
2024     CHECK_NULL_VOID(context);
2025     auto executor = context->GetTaskExecutor();
2026     CHECK_NULL_VOID(executor);
2027     std::string nodeIdStr = std::to_string(host->GetId());
2028     executor->PostDelayedTask(
2029         [weak = WeakClaim(this)] {
2030             auto pattern = weak.Upgrade();
2031             CHECK_NULL_VOID(pattern);
2032             pattern->isManuallyClick_ = false;
2033         },
2034         TaskExecutor::TaskType::UI, DELAY_TIME_FOR_RESET_MANUALLY_CLICK_FLAG,
2035         std::string("ArkUIFormResetManuallyClickFlag").append(nodeIdStr));
2036 }
2037 
RemoveDelayResetManuallyClickFlagTask()2038 void FormPattern::RemoveDelayResetManuallyClickFlagTask()
2039 {
2040     auto host = GetHost();
2041     CHECK_NULL_VOID(host);
2042     auto context = host->GetContext();
2043     CHECK_NULL_VOID(context);
2044     auto executor = context->GetTaskExecutor();
2045     CHECK_NULL_VOID(executor);
2046     std::string nodeIdStr = std::to_string(host->GetId());
2047     executor->RemoveTask(TaskExecutor::TaskType::UI, std::string("ArkUIFormResetManuallyClickFlag").append(nodeIdStr));
2048 }
2049 } // namespace OHOS::Ace::NG
2050