• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/entrance/ace_container.h"
26 #include "adapter/ohos/osal/resource_adapter_impl_v2.h"
27 #include "base/geometry/dimension.h"
28 #include "base/i18n/localization.h"
29 #include "base/log/event_report.h"
30 #include "base/log/log_wrapper.h"
31 #include "base/utils/string_utils.h"
32 #include "base/utils/system_properties.h"
33 #include "core/common/form_manager.h"
34 #include "core/components/form/resource/form_manager_delegate.h"
35 #include "core/components_ng/pattern/form/form_node.h"
36 #include "core/components_ng/pattern/shape/rect_pattern.h"
37 #include "core/components_ng/pattern/text/text_pattern.h"
38 #include "core/components_ng/render/adapter/rosen_render_context.h"
39 #include "render_service_client/core/ui/rs_ui_director.h"
40 
41 #if OHOS_STANDARD_SYSTEM
42 #include "form_info.h"
43 #endif
44 
45 #include "core/common/udmf/udmf_client.h"
46 #include "form_pattern.h"
47 
48 static const int64_t MAX_NUMBER_OF_JS = 0x20000000000000;
49 
50 namespace OHOS::Ace::NG {
51 namespace {
52 constexpr double FORM_CLICK_OPEN_LIMIT_DISTANCE = 20.0;
53 constexpr uint32_t DELAY_TIME_FOR_FORM_SUBCONTAINER_CACHE = 30000;
54 constexpr uint32_t DELAY_TIME_FOR_FORM_SNAPSHOT_3S = 3000;
55 constexpr uint32_t DELAY_TIME_FOR_FORM_SNAPSHOT_EXTRA = 200;
56 constexpr uint32_t DELAY_TIME_FOR_SET_NON_TRANSPARENT = 70;
57 constexpr uint32_t DELAY_TIME_FOR_DELETE_IMAGE_NODE = 100;
58 constexpr uint32_t STATIC_FORM_DELAY_TIME_FOR_DELETE_IMAGE_NODE = 300;
59 constexpr uint32_t DELAY_TIME_FOR_RESET_MANUALLY_CLICK_FLAG = 3000;
60 constexpr double ARC_RADIUS_TO_DIAMETER = 2.0;
61 constexpr double NON_TRANSPARENT_VAL = 1.0;
62 constexpr double TRANSPARENT_VAL = 0;
63 constexpr int32_t MAX_CLICK_DURATION = 500000000; // ns
64 constexpr int32_t DOUBLE = 2;
65 constexpr char FORM_DIMENSION_SPLITTER = '*';
66 constexpr int32_t FORM_SHAPE_CIRCLE = 2;
67 constexpr double TIME_LIMIT_FONT_SIZE_BASE = 14.0;
68 #ifdef ARKUI_WEARABLE
69 constexpr double FORBIDDEN_ICON_STYLE = 64.0;
70 #else
71 constexpr double FORBIDDEN_ICON_STYLE = 32.0;
72 constexpr double FORBIDDEN_ICON_STYLE_1_2 = 24.0;
73 #endif
74 constexpr double TIBETAN_TIME_LIMIT_FONT_SIZE_BASE = 9.0;
75 constexpr double ONE_DIMENSION_TIME_LIMIT_FONT_SIZE_BASE = 14.0;
76 constexpr float MAX_FONT_SCALE = 1.3f;
77 constexpr char TIME_LIMIT_RESOURCE_NAME[] = "form_disable_time_limit";
78 constexpr char APP_LOCKED_RESOURCE_NAME[] = "form_disable_app_locked";
79 constexpr float FORBIDDEN_STYLE_PADDING = 12;
80 constexpr uint32_t ROOT_BG_COLOR_DARK = 0xFF2E3033;
81 constexpr uint32_t ROOT_BG_COLOR_LIGHT = 0xFFF1F3F5;
82 constexpr uint32_t ICON_COLOR_DARK = 0x66ffffff;
83 constexpr uint32_t ICON_COLOR_LIGHT = 0x26000000;
84 constexpr uint32_t FONT_COLOR_DARK = 0x66ffffff;
85 constexpr uint32_t FONT_COLOR_LIGHT = 0x66182431;
86 constexpr float FORBIDDEN_STYLE_SPACE = 8;
87 constexpr int32_t FORM_DIMENSION_MIN_HEIGHT = 1;
88 constexpr int32_t FORM_UNLOCK_ANIMATION_DUATION = 250;
89 constexpr int32_t FORM_UNLOCK_ANIMATION_DELAY = 200;
90 constexpr int32_t FORM_COMPONENT_UPDATE_VALID_DURATION = 1000;
91 constexpr uint32_t DELAY_TIME_FOR_FORM_SNAPSHOT_10S = 10000;
92 constexpr char NO_FORM_DUMP[] = "-noform";
93 constexpr char PID_FLAG[] = "pidflag";
94 
95 class FormSnapshotCallback : public Rosen::SurfaceCaptureCallback {
96 public:
FormSnapshotCallback(const WeakPtr<FormPattern> & node)97     explicit FormSnapshotCallback(const WeakPtr<FormPattern>& node) : weakFormPattern_(node) {}
98     ~FormSnapshotCallback() override = default;
OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelMap)99     void OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelMap) override
100     {
101         auto formPattern_ = weakFormPattern_.Upgrade();
102         CHECK_NULL_VOID(formPattern_);
103         auto subContainer = formPattern_->GetSubContainer();
104         if (subContainer != nullptr && pixelMap != nullptr) {
105             auto formId = subContainer->GetRunningCardId();
106             TAG_LOGI(AceLogTag::ACE_FORM,
107                 "formImage height: %{public}d, width: %{public}d, size:%{public}d, formId: %{public}" PRId64,
108                 pixelMap->GetHeight(), pixelMap->GetWidth(), pixelMap->GetByteCount(), formId);
109         }
110         formPattern_->OnSnapshot(pixelMap);
111     }
OnSurfaceCaptureHDR(std::shared_ptr<Media::PixelMap> pixelMap,std::shared_ptr<Media::PixelMap> hdrPixelMap)112     void OnSurfaceCaptureHDR(std::shared_ptr<Media::PixelMap> pixelMap,
113         std::shared_ptr<Media::PixelMap> hdrPixelMap) override {}
114 private:
115     WeakPtr<FormPattern> weakFormPattern_ = nullptr;
116 };
117 
PostTask(const TaskExecutor::Task & task,TaskExecutor::TaskType type,const std::string & name)118 void PostTask(const TaskExecutor::Task& task, TaskExecutor::TaskType type, const std::string& name)
119 {
120     auto pipeline = PipelineBase::GetCurrentContext();
121     CHECK_NULL_VOID(pipeline);
122     auto taskExecutor = pipeline->GetTaskExecutor();
123     CHECK_NULL_VOID(taskExecutor);
124     taskExecutor->PostTask(task, type, name, PriorityType::HIGH);
125 }
126 
PostUITask(const TaskExecutor::Task & task,const std::string & name)127 void PostUITask(const TaskExecutor::Task& task, const std::string& name)
128 {
129     PostTask(task, TaskExecutor::TaskType::UI, name);
130 }
131 
PostBgTask(const TaskExecutor::Task & task,const std::string & name)132 void PostBgTask(const TaskExecutor::Task& task, const std::string& name)
133 {
134     PostTask(task, TaskExecutor::TaskType::BACKGROUND, name);
135 }
136 
GetCurrentTimestamp()137 int64_t GetCurrentTimestamp()
138 {
139     auto nowSys = std::chrono::steady_clock::now();
140     auto epoch = nowSys.time_since_epoch();
141     return static_cast<int64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(epoch).count());
142 }
143 } // namespace
144 
FormPattern()145 FormPattern::FormPattern()
146 {
147     ACE_SCOPED_TRACE("FormCreate");
148 }
149 
150 FormPattern::~FormPattern() = default;
151 
OnAttachToFrameNode()152 void FormPattern::OnAttachToFrameNode()
153 {
154     auto host = GetHost();
155     CHECK_NULL_VOID(host);
156     host->GetRenderContext()->SetClipToFrame(true);
157     host->GetRenderContext()->SetClipToBounds(true);
158     host->GetRenderContext()->UpdateRenderGroup(true);
159     // Init the render context for RSSurfaceNode from FRS.
160     externalRenderContext_ = RenderContext::Create();
161     // for external RSNode, name is meaningless.
162     static RenderContext::ContextParam param = { RenderContext::ContextType::EXTERNAL, std::nullopt };
163     externalRenderContext_->InitContext(false, param);
164     InitFormManagerDelegate();
165     auto eventHub = host->GetOrCreateEventHub<FormEventHub>();
166     CHECK_NULL_VOID(eventHub);
167     eventHub->SetOnCache([weak = WeakClaim(this)]() {
168         auto pattern = weak.Upgrade();
169         CHECK_NULL_VOID(pattern);
170         auto host = pattern->GetHost();
171         CHECK_NULL_VOID(host);
172         auto context = host->GetContextRefPtr();
173         CHECK_NULL_VOID(context);
174         auto subContainer = pattern->GetSubContainer();
175         CHECK_NULL_VOID(subContainer);
176         auto uiTaskExecutor =
177             SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
178         auto id = subContainer->GetRunningCardId();
179         TAG_LOGI(AceLogTag::ACE_FORM, "FormPattern::OnAttachToFrameNode, cardId: %{public}" PRId64, id);
180         FormManager::GetInstance().AddSubContainer(id, subContainer);
181         uiTaskExecutor.PostDelayedTask(
182             [id, nodeId = subContainer->GetNodeId()] {
183                 auto cachedSubContainer = FormManager::GetInstance().GetSubContainer(id);
184                 if (cachedSubContainer != nullptr && cachedSubContainer->GetNodeId() == nodeId) {
185                     FormManager::GetInstance().RemoveSubContainer(id);
186                 }
187             },
188             DELAY_TIME_FOR_FORM_SUBCONTAINER_CACHE, "ArkUIFormRemoveSubContainer");
189     });
190 
191     InitClickEvent();
192 
193     scopeId_ = Container::CurrentId();
194     EventReport::StartFormModifyTimeoutReportTimer(cardInfo_.id, cardInfo_.bundleName, cardInfo_.cardName);
195 }
196 
InitClickEvent()197 void FormPattern::InitClickEvent()
198 {
199     // Init click event for static form.
200     auto host = GetHost();
201     CHECK_NULL_VOID(host);
202     auto gestureEventHub = host->GetOrCreateGestureEventHub();
203     auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
204         auto formPattern = weak.Upgrade();
205         TAG_LOGI(AceLogTag::ACE_FORM, "gestureEvent - clickCallback");
206         CHECK_NULL_VOID(formPattern);
207         formPattern->HandleStaticFormEvent(
208             { static_cast<float>(info.GetLocalLocation().GetX()), static_cast<float>(info.GetLocalLocation().GetY()) });
209     };
210     auto clickEvent = AceType::MakeRefPtr<ClickEvent>(std::move(clickCallback));
211     gestureEventHub->AddClickEvent(clickEvent);
212 
213     // check touch duration in click event
214     auto touchCallback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
215         auto formPattern = weak.Upgrade();
216         CHECK_NULL_VOID(formPattern);
217         auto touchType = info.GetTouches().front().GetTouchType();
218         if (touchType == TouchType::DOWN) {
219             formPattern->HandleTouchDownEvent(info);
220             return;
221         }
222         if (touchType == TouchType::UP || touchType == TouchType::CANCEL) {
223             formPattern->HandleTouchUpEvent(info);
224             return;
225         }
226     };
227     auto touchEvent = AceType::MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
228     gestureEventHub->AddTouchEvent(touchEvent);
229 }
230 
HandleTouchDownEvent(const TouchEventInfo & event)231 void FormPattern::HandleTouchDownEvent(const TouchEventInfo& event)
232 {
233     TAG_LOGI(AceLogTag::ACE_FORM, "handle touch down.");
234     touchDownTime_ = event.GetTimeStamp();
235     shouldResponseClick_ = true;
236     if (!event.GetTouches().empty()) {
237         lastTouchLocation_ = event.GetTouches().front().GetScreenLocation();
238     }
239 }
240 
HandleTouchUpEvent(const TouchEventInfo & event)241 void FormPattern::HandleTouchUpEvent(const TouchEventInfo& event)
242 {
243     auto duration = event.GetTimeStamp().time_since_epoch().count() - touchDownTime_.time_since_epoch().count();
244     if (duration > MAX_CLICK_DURATION) {
245         TAG_LOGI(AceLogTag::ACE_FORM, "reject click. duration is %{public}lld.", duration);
246         shouldResponseClick_ = false;
247         return;
248     }
249     if (event.GetTouches().empty()) {
250         return;
251     }
252     auto distance = event.GetTouches().front().GetScreenLocation() - lastTouchLocation_;
253     if (distance.GetDistance() > FORM_CLICK_OPEN_LIMIT_DISTANCE) {
254         TAG_LOGI(AceLogTag::ACE_FORM, "reject click. distance exceeded the limit.");
255         shouldResponseClick_ = false;
256     }
257 }
258 
HandleUnTrustForm()259 void FormPattern::HandleUnTrustForm()
260 {
261     auto host = GetHost();
262     CHECK_NULL_VOID(host);
263     if (externalRenderContext_) {
264         auto renderContext = DynamicCast<NG::RosenRenderContext>(host->GetRenderContext());
265         CHECK_NULL_VOID(renderContext);
266         renderContext->RemoveChild(externalRenderContext_);
267     }
268 
269     isUnTrust_ = true;
270     isLoaded_ = true;
271     if (!isJsCard_) {
272         RequestFormInfo info;
273         if (ShouldLoadFormSkeleton(false, info)) {
274             LoadFormSkeleton(true);
275         }
276     }
277 
278     host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
279     auto parent = host->GetParent();
280     CHECK_NULL_VOID(parent);
281     parent->MarkNeedSyncRenderTree();
282     parent->RebuildRenderContextTree();
283     host->GetRenderContext()->RequestNextFrame();
284 }
285 
UpdateBackgroundColorWhenUnTrustForm()286 void FormPattern::UpdateBackgroundColorWhenUnTrustForm()
287 {
288     if (!isUnTrust_) {
289         return;
290     }
291 
292     if (colorMode != Container::CurrentColorMode()) {
293         colorMode = Container::CurrentColorMode();
294         HandleUnTrustForm();
295     }
296 }
297 
HandleSnapshot(uint32_t delayTime,const std::string & nodeIdStr)298 void FormPattern::HandleSnapshot(uint32_t delayTime, const std::string& nodeIdStr)
299 {
300     auto pipeline = PipelineContext::GetCurrentContext();
301     CHECK_NULL_VOID(pipeline);
302     auto executor = pipeline->GetTaskExecutor();
303     CHECK_NULL_VOID(executor);
304     snapshotTimestamp_ = GetCurrentTimestamp();
305     if (isDynamic_) {
306         if (formChildrenNodeMap_.find(FormChildNodeType::FORM_STATIC_IMAGE_NODE) != formChildrenNodeMap_.end()) {
307             executor->RemoveTask(TaskExecutor::TaskType::UI, "ArkUIFormSetNonTransparentAfterRecover_" + nodeIdStr);
308             executor->RemoveTask(TaskExecutor::TaskType::UI, "ArkUIFormDeleteImageNodeAfterRecover_" + nodeIdStr);
309             RemoveFrsNode();
310             ReleaseRenderer();
311             UnregisterAccessibility();
312             isSnapshot_ = true;
313             needSnapshotAgain_ = false;
314             return;
315         }
316     }
317 
318     isStaticFormSnaping_ = true;
319     executor->PostDelayedTask(
320         [weak = WeakClaim(this), delayTime]() mutable {
321             auto form = weak.Upgrade();
322             CHECK_NULL_VOID(form);
323             int64_t currentTime = GetCurrentTimestamp();
324             if (currentTime - form->snapshotTimestamp_ < delayTime) {
325                 TAG_LOGW(AceLogTag::ACE_FORM, "another snapshot task has been posted.");
326                 return;
327             }
328             form->isStaticFormSnaping_ = false;
329             form->TakeSurfaceCaptureForUI();
330         },
331         TaskExecutor::TaskType::UI, delayTime, "ArkUIFormTakeSurfaceCapture_" + nodeIdStr);
332 }
333 
HandleStaticFormEvent(const PointF & touchPoint)334 void FormPattern::HandleStaticFormEvent(const PointF& touchPoint)
335 {
336     if (formLinkInfos_.empty()) {
337         TAG_LOGE(AceLogTag::ACE_FORM, "formLinkInfos_ empty.");
338         return;
339     }
340     if (isDynamic_) {
341         TAG_LOGE(AceLogTag::ACE_FORM, "dynamic form.");
342         return;
343     }
344     if (!shouldResponseClick_) {
345         TAG_LOGE(AceLogTag::ACE_FORM, "shouldResponseClick_ is false.");
346         return;
347     }
348     TAG_LOGI(AceLogTag::ACE_FORM, "StaticFrom click.");
349     for (const auto& info : formLinkInfos_) {
350         auto linkInfo = JsonUtil::ParseJsonString(info);
351         CHECK_NULL_VOID(linkInfo);
352         auto action = linkInfo->GetValue("action")->GetString();
353         auto rectStr = linkInfo->GetValue("formLinkRect")->GetString();
354         RectF linkRect = RectF::FromString(rectStr);
355         if (linkRect.IsInRegion(touchPoint)) {
356             OnActionEvent(action);
357             break;
358         }
359     }
360 }
361 
HandleEnableForm(const bool enable)362 void FormPattern::HandleEnableForm(const bool enable)
363 {
364     TAG_LOGI(AceLogTag::ACE_FORM, "FormPattern::HandleEnableForm, enable = %{public}d", enable);
365     auto newFormSpecialStyle = formSpecialStyle_;
366     newFormSpecialStyle.SetIsForbiddenByParentControl(!enable);
367     HandleFormStyleOperation(newFormSpecialStyle);
368 }
369 
TakeSurfaceCaptureForUI()370 void FormPattern::TakeSurfaceCaptureForUI()
371 {
372     if (isFrsNodeDetached_) {
373         TAG_LOGI(AceLogTag::ACE_FORM, "Frs node is detached, cancel snapshot.");
374         return;
375     }
376 
377     if (isDynamic_) {
378         formLinkInfos_.clear();
379         TAG_LOGI(AceLogTag::ACE_FORM, "formLinkInfos_ clear.");
380     }
381     TAG_LOGI(AceLogTag::ACE_FORM, "Static-form take snapshot.");
382     auto host = GetHost();
383     CHECK_NULL_VOID(host);
384     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
385     CHECK_NULL_VOID(layoutProperty);
386     auto renderContext = host->GetRenderContext();
387     auto visible = layoutProperty->GetVisibleType().value_or(VisibleType::VISIBLE);
388     auto opacity = renderContext->GetOpacityValue(NON_TRANSPARENT_VAL);
389     if (visible == VisibleType::INVISIBLE || visible == VisibleType::GONE || opacity == TRANSPARENT_VAL) {
390         TAG_LOGI(AceLogTag::ACE_FORM, "The form is invisible, TakeSurfaceCaptureForUI later.");
391         needSnapshotAgain_ = true;
392         return;
393     }
394 
395     if (formChildrenNodeMap_.find(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE)
396         == formChildrenNodeMap_.end()) {
397         SnapshotSurfaceNode();
398         return;
399     }
400     UpdateChildNodeOpacity(FormChildNodeType::FORM_SURFACE_NODE, NON_TRANSPARENT_VAL);
401     host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
402     auto context = host->GetContext();
403     CHECK_NULL_VOID(context);
404     auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
405     uiTaskExecutor.PostDelayedTask(
406         [weak = WeakClaim(this)] {
407             auto pattern = weak.Upgrade();
408             CHECK_NULL_VOID(pattern);
409             pattern->SnapshotSurfaceNode();
410         },
411         DELAY_TIME_FOR_FORM_SNAPSHOT_EXTRA, "ArkUIFormDelaySnapshotSurfaceNode");
412 }
413 
SnapshotSurfaceNode()414 void FormPattern::SnapshotSurfaceNode()
415 {
416     auto externalContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
417     CHECK_NULL_VOID(externalContext);
418     auto rsNode = externalContext->GetRSNode();
419     CHECK_NULL_VOID(rsNode);
420     externalContext->AddRsNodeForCapture();
421     auto& rsInterface = Rosen::RSInterfaces::GetInstance();
422     rsInterface.TakeSurfaceCaptureForUI(rsNode, std::make_shared<FormSnapshotCallback>(WeakClaim(this)));
423 }
424 
OnSnapshot(std::shared_ptr<Media::PixelMap> pixelMap)425 void FormPattern::OnSnapshot(std::shared_ptr<Media::PixelMap> pixelMap)
426 {
427     ContainerScope scope(scopeId_);
428     auto host = GetHost();
429     CHECK_NULL_VOID(host);
430     auto context = host->GetContext();
431     CHECK_NULL_VOID(context);
432     auto uiTaskExecutor =
433         SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
434     uiTaskExecutor.PostTask([weak = WeakClaim(this), pixelMap] {
435         auto formPattern = weak.Upgrade();
436         CHECK_NULL_VOID(formPattern);
437         formPattern->HandleOnSnapshot(pixelMap);
438         }, "ArkUIFormHandleOnSnapshot");
439 }
440 
HandleOnSnapshot(std::shared_ptr<Media::PixelMap> pixelMap)441 void FormPattern::HandleOnSnapshot(std::shared_ptr<Media::PixelMap> pixelMap)
442 {
443     TAG_LOGI(AceLogTag::ACE_FORM, "call.");
444     CHECK_NULL_VOID(pixelMap);
445     pixelMap_ = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
446     UpdateStaticCard();
447     isSnapshot_ = true;
448     needSnapshotAgain_ = false;
449 }
450 
OnAccessibilityChildTreeRegister(uint32_t windowId,int32_t treeId,int64_t accessibilityId)451 void FormPattern::OnAccessibilityChildTreeRegister(uint32_t windowId, int32_t treeId, int64_t accessibilityId)
452 {
453     TAG_LOGD(AceLogTag::ACE_FORM, "call, treeId: %{public}d, id: %{public}" PRId64, treeId, accessibilityId);
454     if (formManagerBridge_ == nullptr) {
455         TAG_LOGE(AceLogTag::ACE_FORM, "formManagerBridge_ is null");
456         return;
457     }
458     formManagerBridge_->OnAccessibilityChildTreeRegister(windowId, treeId, accessibilityId);
459 }
460 
OnAccessibilityChildTreeDeregister()461 void FormPattern::OnAccessibilityChildTreeDeregister()
462 {
463     TAG_LOGD(AceLogTag::ACE_FORM, "call.");
464     if (formManagerBridge_ == nullptr) {
465         TAG_LOGE(AceLogTag::ACE_FORM, "formManagerBridge_ is null");
466         return;
467     }
468     formManagerBridge_->OnAccessibilityChildTreeDeregister();
469 }
470 
OnAccessibilityDumpChildInfo(const std::vector<std::string> & params,std::vector<std::string> & info)471 void FormPattern::OnAccessibilityDumpChildInfo(const std::vector<std::string>& params, std::vector<std::string>& info)
472 {
473     TAG_LOGD(AceLogTag::ACE_FORM, "call.");
474     if (formManagerBridge_ == nullptr) {
475         TAG_LOGE(AceLogTag::ACE_FORM, "formManagerBridge_ is null");
476         return;
477     }
478     formManagerBridge_->OnAccessibilityDumpChildInfo(params, info);
479 }
480 
GetAccessibilitySessionAdapter()481 RefPtr<AccessibilitySessionAdapter> FormPattern::GetAccessibilitySessionAdapter()
482 {
483     return accessibilitySessionAdapter_;
484 }
485 
UpdateStaticCard()486 void FormPattern::UpdateStaticCard()
487 {
488     // 1. Use imageNode to display pixelMap
489     UpdateImageNode();
490     // 2. Remove FrsNode from formNode
491     RemoveFrsNode();
492     // 3. Release renderer obj
493     ReleaseRenderer();
494     // 4. clear form node ChildTree register flag.  can do register again
495     UnregisterAccessibility();
496 }
497 
SetNonTransparentAfterRecover()498 void FormPattern::SetNonTransparentAfterRecover()
499 {
500     ACE_FUNCTION_TRACE();
501     // set frs node non transparent
502     if (formChildrenNodeMap_.find(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE)
503         == formChildrenNodeMap_.end()) {
504         UpdateChildNodeOpacity(FormChildNodeType::FORM_SURFACE_NODE, NON_TRANSPARENT_VAL);
505         //update form after updateChildNodeOpacity
506         auto host = GetHost();
507         CHECK_NULL_VOID(host);
508         host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
509         TAG_LOGI(AceLogTag::ACE_FORM, "setOpacity:1");
510     } else {
511         TAG_LOGW(AceLogTag::ACE_FORM, "has forbidden node");
512     }
513 }
514 
DeleteImageNodeAfterRecover(bool needHandleCachedClick)515 void FormPattern::DeleteImageNodeAfterRecover(bool needHandleCachedClick)
516 {
517     ACE_FUNCTION_TRACE();
518     auto host = GetHost();
519     CHECK_NULL_VOID(host);
520     auto renderContext = host->GetRenderContext();
521     CHECK_NULL_VOID(renderContext);
522 
523     // delete image rs node and frame node
524     RemoveFormChildNode(FormChildNodeType::FORM_STATIC_IMAGE_NODE);
525 
526     host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
527     auto parent = host->GetParent();
528     CHECK_NULL_VOID(parent);
529     parent->MarkNeedSyncRenderTree();
530     parent->RebuildRenderContextTree();
531     renderContext->RequestNextFrame();
532 
533     // handle cached pointer event
534     if (needHandleCachedClick && formManagerBridge_) {
535         formManagerBridge_->HandleCachedClickEvents();
536     }
537 }
538 
CreateImageNode()539 RefPtr<FrameNode> FormPattern::CreateImageNode()
540 {
541     auto host = GetHost();
542     CHECK_NULL_RETURN(host, nullptr);
543     auto formNode = DynamicCast<FormNode>(host);
544     CHECK_NULL_RETURN(formNode, nullptr);
545     auto imageId = formNode->GetImageId();
546     auto subContainer = GetSubContainer();
547     if (subContainer != nullptr) {
548         auto formId = subContainer->GetRunningCardId();
549         TAG_LOGI(AceLogTag::ACE_FORM, "CreateImageNode imageId: %{public}d, formId: %{public}" PRId64,
550             imageId, formId);
551     }
552     RefPtr<FrameNode> imageNode = FrameNode::CreateFrameNode(V2::IMAGE_ETS_TAG, imageId,
553         AceType::MakeRefPtr<ImagePattern>());
554     CHECK_NULL_RETURN(imageNode, nullptr);
555     AddFormChildNode(FormChildNodeType::FORM_STATIC_IMAGE_NODE, imageNode);
556     auto imagePattern = imageNode->GetPattern<ImagePattern>();
557     CHECK_NULL_RETURN(imagePattern, nullptr);
558     imagePattern->SetSyncLoad(true);
559     RefPtr<FrameNode> disableStyleRootNode = GetFormChildNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE);
560     disableStyleRootNode == nullptr ? host->AddChild(imageNode) :
561         host->AddChildBefore(imageNode, disableStyleRootNode);
562     auto eventHub = imageNode->GetOrCreateGestureEventHub();
563     if (eventHub != nullptr) {
564         eventHub->RemoveDragEvent();
565     }
566     return imageNode;
567 }
568 
UpdateImageNode()569 void FormPattern::UpdateImageNode()
570 {
571     ContainerScope scope(scopeId_);
572     CHECK_NULL_VOID(pixelMap_);
573     auto host = GetHost();
574     CHECK_NULL_VOID(host);
575     RemoveFormChildNode(FormChildNodeType::FORM_STATIC_IMAGE_NODE);
576     auto imageNode = CreateImageNode();
577     CHECK_NULL_VOID(imageNode);
578     auto pixelLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
579     CHECK_NULL_VOID(pixelLayoutProperty);
580     auto pixelSourceInfo = ImageSourceInfo(pixelMap_);
581 
582     auto width = static_cast<float>(cardInfo_.width.Value()) - cardInfo_.borderWidth * DOUBLE;
583     auto height = static_cast<float>(cardInfo_.height.Value()) - cardInfo_.borderWidth * DOUBLE;
584     CalcSize idealSize = { CalcLength(width), CalcLength(height) };
585     MeasureProperty layoutConstraint;
586     layoutConstraint.selfIdealSize = idealSize;
587     layoutConstraint.maxSize = idealSize;
588     imageNode->UpdateLayoutConstraint(layoutConstraint);
589     pixelLayoutProperty->UpdateImageSourceInfo(pixelSourceInfo);
590     auto externalContext = DynamicCast<NG::RosenRenderContext>(imageNode->GetRenderContext());
591     CHECK_NULL_VOID(externalContext);
592     externalContext->SetVisible(true);
593     if (formChildrenNodeMap_.find(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE)
594         != formChildrenNodeMap_.end()) {
595         externalContext->SetOpacity(TRANSPARENT_VAL);
596     }
597     imageNode->MarkModifyDone();
598     imageNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
599 }
600 
RemoveFrsNode()601 void FormPattern::RemoveFrsNode()
602 {
603     ContainerScope scope(scopeId_);
604     CHECK_NULL_VOID(externalRenderContext_);
605     auto host = GetHost();
606     CHECK_NULL_VOID(host);
607     auto renderContext = DynamicCast<NG::RosenRenderContext>(host->GetRenderContext());
608     CHECK_NULL_VOID(renderContext);
609     renderContext->RemoveChild(externalRenderContext_);
610 
611     host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
612     auto parent = host->GetParent();
613     CHECK_NULL_VOID(parent);
614     parent->MarkNeedSyncRenderTree();
615     parent->RebuildRenderContextTree();
616     host->GetRenderContext()->RequestNextFrame();
617 }
618 
ReleaseRenderer()619 void FormPattern::ReleaseRenderer()
620 {
621     ContainerScope scope(scopeId_);
622     CHECK_NULL_VOID(formManagerBridge_);
623     formManagerBridge_->ReleaseRenderer();
624 }
625 
OnRebuildFrame()626 void FormPattern::OnRebuildFrame()
627 {
628     if (isSnapshot_) {
629         return;
630     }
631 
632     if (isSkeletonAnimEnable_ && !isTransparencyEnable_ && !ShouldAddChildAtReuildFrame()) {
633         TAG_LOGW(AceLogTag::ACE_FORM, "should not add child");
634         return;
635     }
636 
637     auto host = GetHost();
638     CHECK_NULL_VOID(host);
639     auto renderContext = host->GetRenderContext();
640     CHECK_NULL_VOID(renderContext);
641     renderContext->AddChild(externalRenderContext_, 0);
642 }
643 
OnVisibleChange(bool isVisible)644 void FormPattern::OnVisibleChange(bool isVisible)
645 {
646     isVisible_ = isVisible;
647 }
648 
OnModifyDone()649 void FormPattern::OnModifyDone()
650 {
651     EventReport::StopFormModifyTimeoutReportTimer(cardInfo_.id);
652     Pattern::OnModifyDone();
653     auto host = GetHost();
654     CHECK_NULL_VOID(host);
655     auto gestureEventHub = host->GetOrCreateGestureEventHub();
656     CHECK_NULL_VOID(gestureEventHub);
657     // FormComponent do not response to user's onClick callback.
658     gestureEventHub->ClearUserOnClick();
659 
660     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
661     CHECK_NULL_VOID(layoutProperty);
662     auto &&layoutConstraint = layoutProperty->GetCalcLayoutConstraint();
663     CHECK_NULL_VOID(layoutConstraint);
664     auto size = layoutConstraint->selfIdealSize;
665     CHECK_NULL_VOID(size);
666     auto sizeWidth = size->Width();
667     auto sizeHeight = size->Height();
668     CHECK_NULL_VOID(sizeWidth);
669     CHECK_NULL_VOID(sizeHeight);
670     auto width = sizeWidth->GetDimension();
671     auto height = sizeHeight->GetDimension();
672     if (width.Unit() == DimensionUnit::PERCENT || height.Unit() == DimensionUnit::PERCENT) {
673         /**
674          * If DimensionUnit is DimensionUnit::PERCENT, it need parentNode-size to calculate formNode-size.
675          * However, the parentNode-size cannot be obtained in the current callback function,
676          * so HandleFormComponent in OnDirtyLayoutWrapperSwap function.
677          */
678         return;
679     }
680     // Convert DimensionUnit to DimensionUnit::PX
681     auto info = layoutProperty->GetRequestFormInfo().value_or(RequestFormInfo());
682     TAG_LOGI(AceLogTag::ACE_FORM,
683         "FormPattern::OnModifyDone, info.id: %{public}" PRId64 ", info.index: %{public}" PRId64, info.id, info.index);
684     info.width = Dimension(width.ConvertToPx());
685     info.height = Dimension(height.ConvertToPx());
686     auto &&borderWidthProperty = layoutProperty->GetBorderWidthProperty();
687     float borderWidth = 0.0f;
688     if (borderWidthProperty && borderWidthProperty->topDimen) {
689         borderWidth = borderWidthProperty->topDimen->ConvertToPx();
690     }
691     info.borderWidth = borderWidth;
692     layoutProperty->UpdateRequestFormInfo(info);
693     UpdateBackgroundColorWhenUnTrustForm();
694     info.obscuredMode = isFormObscured_;
695     info.obscuredMode |= formSpecialStyle_.IsForbidden() || formSpecialStyle_.IsLocked();
696     auto wantWrap = info.wantWrap;
697     if (wantWrap) {
698         bool isEnable = wantWrap->GetWant().GetBoolParam(OHOS::AppExecFwk::Constants::FORM_ENABLE_SKELETON_KEY, false);
699         TAG_LOGD(AceLogTag::ACE_FORM, "FORM_ENABLE_SKELETON_KEY %{public}d", isEnable);
700     }
701     HandleFormComponent(info);
702 
703     auto accessibilityProperty = host->GetAccessibilityProperty<AccessibilityProperty>();
704     CHECK_NULL_VOID(accessibilityProperty);
705     accessibilityProperty->SetAccessibilityLevel(AccessibilityProperty::Level::NO_STR);
706 }
707 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)708 bool FormPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
709 {
710     if (config.skipMeasure && config.skipLayout) {
711         return false;
712     }
713     isBeenLayout_ = true;
714     auto size = dirty->GetGeometryNode()->GetFrameSize();
715     auto host = GetHost();
716     CHECK_NULL_RETURN(host, false);
717     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
718     CHECK_NULL_RETURN(layoutProperty, false);
719     auto info = layoutProperty->GetRequestFormInfo().value_or(RequestFormInfo());
720     info.width = Dimension(size.Width());
721     info.height = Dimension(size.Height());
722     if (std::isinf(info.width.Value()) || std::isnan(info.width.Value()) || std::isinf(info.height.Value())
723         || std::isnan(info.height.Value())) {
724         TAG_LOGE(AceLogTag::ACE_FORM, "size invalid, width:%{public}f height:%{public}f",
725             info.width.Value(), info.height.Value());
726         return false;
727     }
728     auto &&borderWidthProperty = layoutProperty->GetBorderWidthProperty();
729     float borderWidth = 0.0f;
730     if (borderWidthProperty && borderWidthProperty->topDimen) {
731         borderWidth = borderWidthProperty->topDimen->ConvertToPx();
732     }
733     info.borderWidth = borderWidth;
734     layoutProperty->UpdateRequestFormInfo(info);
735     info.obscuredMode = isFormObscured_;
736     info.obscuredMode |= formSpecialStyle_.IsForbidden() || formSpecialStyle_.IsLocked();
737     UpdateBackgroundColorWhenUnTrustForm();
738     HandleFormComponent(info);
739     return true;
740 }
741 
HandleFormComponent(RequestFormInfo & info)742 void FormPattern::HandleFormComponent(RequestFormInfo& info)
743 {
744     ACE_FUNCTION_TRACE();
745     if (info.bundleName != cardInfo_.bundleName || info.abilityName != cardInfo_.abilityName ||
746         info.moduleName != cardInfo_.moduleName || info.cardName != cardInfo_.cardName ||
747         info.dimension != cardInfo_.dimension || info.renderingMode != cardInfo_.renderingMode) {
748         info.obscuredMode |= (CheckFormBundleForbidden(info.bundleName) ||
749             IsFormBundleProtected(info.bundleName, info.id));
750         AddFormComponent(info);
751     } else {
752         UpdateFormComponent(info);
753     }
754 }
755 
AddFormComponent(const RequestFormInfo & info)756 void FormPattern::AddFormComponent(const RequestFormInfo& info)
757 {
758     ACE_FUNCTION_TRACE();
759     auto host = GetHost();
760     CHECK_NULL_VOID(host);
761     // When cardInfo has changed, it will call AddForm in Fwk
762     // If the width or height equal to zero, it will not
763     if (NonPositive(info.width.Value()) || NonPositive(info.height.Value())) {
764         TAG_LOGW(AceLogTag::ACE_FORM, "Invalid form size.");
765         return;
766     }
767     TAG_LOGW(AceLogTag::ACE_FORM, "width: %{public}f   height: %{public}f  borderWidth: %{public}f",
768         info.width.Value(), info.height.Value(), info.borderWidth);
769     cardInfo_ = info;
770     if (info.dimension == static_cast<int32_t>(OHOS::AppExecFwk::Constants::Dimension::DIMENSION_1_1)
771         || info.shape == FORM_SHAPE_CIRCLE) {
772         BorderRadiusProperty borderRadius;
773         Dimension diameter = std::min(info.width, info.height);
774         borderRadius.SetRadius(diameter / ARC_RADIUS_TO_DIAMETER);
775         host->GetRenderContext()->UpdateBorderRadius(borderRadius);
776     }
777     isJsCard_ = true;
778     RefPtr<PipelineContext> pipeline = host->GetContextRefPtr();
779     PostBgTask([weak = WeakClaim(this), info, pipeline] {
780             auto pattern = weak.Upgrade();
781             CHECK_NULL_VOID(pattern);
782             pattern->AddFormComponentTask(info, pipeline);
783         }, "ArkUIAddFormComponent");
784 }
785 
AddFormComponentTask(const RequestFormInfo & info,RefPtr<PipelineContext> pipeline)786 void FormPattern::AddFormComponentTask(const RequestFormInfo& info, RefPtr<PipelineContext> pipeline)
787 {
788 #if OHOS_STANDARD_SYSTEM
789     AppExecFwk::FormInfo formInfo;
790     if (FormManagerDelegate::GetFormInfo(info.bundleName, info.moduleName, info.cardName, formInfo) &&
791         formInfo.uiSyntax == AppExecFwk::FormType::ETS) {
792         isJsCard_ = false;
793     }
794     formSpecialStyle_.SetIsMultiAppForm(formInfo);
795 #endif
796 
797     AddFormComponentUI(formInfo.transparencyEnabled, info);
798 
799     if (!formManagerBridge_) {
800         TAG_LOGE(AceLogTag::ACE_FORM, "Form manager delegate is nullptr.");
801         return;
802     }
803 #if OHOS_STANDARD_SYSTEM
804     formManagerBridge_->AddForm(pipeline, info, formInfo);
805 #else
806     formManagerBridge_->AddForm(pipeline, info);
807 #endif
808 
809     bool isFormBundleForbidden = CheckFormBundleForbidden(info.bundleName);
810     bool isFormProtected = IsFormBundleProtected(info.bundleName, info.id);
811     if (!info.exemptAppLock && (isFormProtected || isFormBundleForbidden))  {
812         auto newFormSpecialStyle = formSpecialStyle_;
813         newFormSpecialStyle.SetIsLockedByAppLock(isFormProtected);
814         newFormSpecialStyle.SetIsForbiddenByParentControl(isFormBundleForbidden);
815         newFormSpecialStyle.SetInitDone();
816         PostUITask([weak = WeakClaim(this), info, newFormSpecialStyle] {
817             ACE_SCOPED_TRACE("ArkUILoadDisableFormStyle");
818             auto pattern = weak.Upgrade();
819             CHECK_NULL_VOID(pattern);
820             pattern->HandleFormStyleOperation(newFormSpecialStyle, info);
821             }, "ArkUILoadDisableFormStyle");
822     } else {
823         formSpecialStyle_.SetInitDone();
824     }
825 }
826 
AddFormComponentUI(bool isTransparencyEnabled,const RequestFormInfo & info)827 void FormPattern::AddFormComponentUI(bool isTransparencyEnabled, const RequestFormInfo& info)
828 {
829     PostUITask([weak = WeakClaim(this), isTransparencyEnabled, info, isJsCard = isJsCard_] {
830         ACE_SCOPED_TRACE("ArkUIAddFormComponentUI");
831         auto pattern = weak.Upgrade();
832         CHECK_NULL_VOID(pattern);
833         auto host = pattern->GetHost();
834         CHECK_NULL_VOID(host);
835         pattern->CreateCardContainer();
836         if (host->IsDraggable()) {
837             pattern->EnableDrag();
838         }
839 
840 #if OHOS_STANDARD_SYSTEM
841         pattern->SetTransparencyConfig(isTransparencyEnabled, info);
842         pattern->SetSkeletonEnableConfig(info);
843         if (!isJsCard && !pattern->isTransparencyEnable_
844             && pattern->ShouldLoadFormSkeleton(isTransparencyEnabled, info)) {
845             pattern->LoadFormSkeleton();
846         }
847 #endif
848         }, "ArkUIAddFormComponentUI");
849 }
850 
SetParamForWantTask(const RequestFormInfo & info)851 void FormPattern::SetParamForWantTask(const RequestFormInfo& info)
852 {
853     PostBgTask([weak = WeakClaim(this), info] {
854         ACE_SCOPED_TRACE("ArkUISetParamForWant");
855         auto pattern = weak.Upgrade();
856         CHECK_NULL_VOID(pattern);
857         pattern->formManagerBridge_->SetParamForWant(info);
858         pattern->ReAddStaticFormSnapshotTimer();
859         }, "ArkUISetParamForWant");
860 }
861 
UpdateFormComponent(const RequestFormInfo & info)862 void FormPattern::UpdateFormComponent(const RequestFormInfo& info)
863 {
864     if (formManagerBridge_) {
865 #if OHOS_STANDARD_SYSTEM
866         SetParamForWantTask(info);
867 #endif
868     }
869     auto host = GetHost();
870     CHECK_NULL_VOID(host);
871     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
872     CHECK_NULL_VOID(layoutProperty);
873     if (cardInfo_.allowUpdate != info.allowUpdate) {
874         cardInfo_.allowUpdate = info.allowUpdate;
875         if (subContainer_) {
876             subContainer_->SetAllowUpdate(cardInfo_.allowUpdate);
877         }
878         if (formManagerBridge_) {
879             formManagerBridge_->SetAllowUpdate(cardInfo_.allowUpdate);
880         }
881     }
882     if (cardInfo_.width != info.width || cardInfo_.height != info.height || cardInfo_.borderWidth != info.borderWidth) {
883         UpdateFormComponentSize(info);
884     }
885     if (cardInfo_.obscuredMode != info.obscuredMode) {
886         cardInfo_.obscuredMode = info.obscuredMode;
887         if (formManagerBridge_) {
888             formManagerBridge_->SetObscured(info.obscuredMode);
889         }
890     }
891     if (isLoaded_) {
892         auto visible = layoutProperty->GetVisibleType().value_or(VisibleType::VISIBLE);
893         layoutProperty->UpdateVisibility(visible);
894         if (!isDynamic_ && !isSnapshot_ && needSnapshotAgain_) {
895             auto renderContext = host->GetRenderContext();
896             CHECK_NULL_VOID(renderContext);
897             auto opacity = renderContext->GetOpacityValue(NON_TRANSPARENT_VAL);
898             std::string nodeIdStr = std::to_string(host->GetId());
899             TAG_LOGI(AceLogTag::ACE_FORM,
900                 "Static-form, current opacity: %{public}f, visible: %{public}d, nodeId: %{public}s.",
901                 opacity, static_cast<int>(visible), nodeIdStr.c_str());
902             if (visible == VisibleType::VISIBLE && opacity == NON_TRANSPARENT_VAL) {
903                 HandleSnapshot(DELAY_TIME_FOR_FORM_SNAPSHOT_3S, nodeIdStr);
904             }
905         }
906     }
907     UpdateSpecialStyleCfg();
908     UpdateConfiguration();
909 }
910 
UpdateFormComponentSize(const RequestFormInfo & info)911 void FormPattern::UpdateFormComponentSize(const RequestFormInfo& info)
912 {
913     TAG_LOGI(AceLogTag::ACE_FORM,
914         "update size, id: %{public}" PRId64 "  width: %{public}f  height: %{public}f  borderWidth: %{public}f",
915         info.id, info.width.Value(), info.height.Value(), info.borderWidth);
916     cardInfo_.width = info.width;
917     cardInfo_.height = info.height;
918     cardInfo_.borderWidth = info.borderWidth;
919     auto externalRenderContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
920     CHECK_NULL_VOID(externalRenderContext);
921 
922     externalRenderContext->SetBounds(round(cardInfo_.borderWidth), round(cardInfo_.borderWidth),
923         round(cardInfo_.width.Value() - cardInfo_.borderWidth * DOUBLE),
924         round(cardInfo_.height.Value() - cardInfo_.borderWidth * DOUBLE));
925 
926     if (formManagerBridge_) {
927         formManagerBridge_->NotifySurfaceChange(info.width.Value(), info.height.Value(), info.borderWidth);
928     } else {
929         TAG_LOGE(AceLogTag::ACE_FORM, "form manager delagate is nullptr, card id is %{public}" PRId64 ".",
930             cardInfo_.id);
931     }
932 
933     auto imageNode = GetFormChildNode(FormChildNodeType::FORM_STATIC_IMAGE_NODE);
934     auto disableStyleRootNode = GetFormChildNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE);
935     if (imageNode != nullptr || disableStyleRootNode != nullptr) {
936         auto width = static_cast<float>(info.width.Value()) - info.borderWidth * DOUBLE;
937         auto height = static_cast<float>(info.height.Value()) - info.borderWidth * DOUBLE;
938         CalcSize idealSize = { CalcLength(width), CalcLength(height) };
939         MeasureProperty layoutConstraint;
940         layoutConstraint.selfIdealSize = idealSize;
941         layoutConstraint.maxSize = idealSize;
942         if (imageNode != nullptr) {
943             imageNode->UpdateLayoutConstraint(layoutConstraint);
944         }
945         if (disableStyleRootNode != nullptr) {
946             disableStyleRootNode->UpdateLayoutConstraint(layoutConstraint);
947         }
948     }
949 
950     auto formSkeletonNode = GetFormChildNode(FormChildNodeType::FORM_SKELETON_NODE);
951     if (formSkeletonNode) {
952         LoadFormSkeleton(true);
953     }
954 
955     if (info.dimension == static_cast<int32_t>(OHOS::AppExecFwk::Constants::Dimension::DIMENSION_1_1)) {
956         BorderRadiusProperty borderRadius;
957         Dimension diameter = std::min(info.width, info.height);
958         borderRadius.SetRadius(diameter / ARC_RADIUS_TO_DIAMETER);
959         GetHost()->GetRenderContext()->UpdateBorderRadius(borderRadius);
960     }
961     if (subContainer_) {
962         subContainer_->SetFormPattern(WeakClaim(this));
963         subContainer_->UpdateRootElementSize();
964         subContainer_->UpdateSurfaceSizeWithAnimathion();
965     }
966 }
967 
UpdateSpecialStyleCfg()968 void FormPattern::UpdateSpecialStyleCfg()
969 {
970     auto columnNode = GetFormChildNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE);
971     CHECK_NULL_VOID(columnNode);
972     auto renderContext = columnNode->GetRenderContext();
973     CHECK_NULL_VOID(renderContext);
974     UpdateForbiddenRootNodeStyle(renderContext);
975     auto attribution = formSpecialStyle_.GetFormStyleAttribution();
976     if (attribution == FormStyleAttribution::PARENT_CONTROL) {
977         UpdateForbiddenIcon(FormChildNodeType::TIME_LIMIT_IMAGE_NODE);
978         UpdateForbiddenText(FormChildNodeType::TIME_LIMIT_TEXT_NODE);
979     }
980     if (attribution == FormStyleAttribution::APP_LOCK) {
981         UpdateForbiddenIcon(FormChildNodeType::APP_LOCKED_IMAGE_NODE);
982         UpdateForbiddenText(FormChildNodeType::APP_LOCKED_TEXT_NODE);
983     }
984 }
985 
UpdateForbiddenText(FormChildNodeType nodeType)986 void FormPattern::UpdateForbiddenText(FormChildNodeType nodeType)
987 {
988     auto textNode = GetFormChildNode(nodeType);
989     CHECK_NULL_VOID(textNode);
990     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
991     CHECK_NULL_VOID(textLayoutProperty);
992     auto context = GetContext();
993     CHECK_NULL_VOID(context);
994     auto isNeedUpdate = false;
995     auto currentColor = textLayoutProperty->GetTextColor();
996     auto newColor = context->GetColorMode() == ColorMode::DARK ? Color(FONT_COLOR_DARK) : Color(FONT_COLOR_LIGHT);
997     if (currentColor != newColor) {
998         textLayoutProperty->UpdateTextColor(newColor);
999         isNeedUpdate = true;
1000     }
1001     Dimension fontSize(GetTimeLimitFontSize());
1002     if (!textLayoutProperty->GetFontSize().has_value() ||
1003         !NearEqual(textLayoutProperty->GetFontSize().value(), fontSize)) {
1004         TAG_LOGD(AceLogTag::ACE_FORM, "bundleName = %{public}s, id: %{public}" PRId64 ", UpdateFontSize:%{public}f.",
1005             cardInfo_.bundleName.c_str(), cardInfo_.id, fontSize.Value());
1006         textLayoutProperty->UpdateFontSize(fontSize);
1007         isNeedUpdate = true;
1008     }
1009     if (isNeedUpdate) {
1010         textNode->MarkModifyDone();
1011         textNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1012     }
1013 }
1014 
UpdateForbiddenIcon(FormChildNodeType nodeType)1015 void FormPattern::UpdateForbiddenIcon(FormChildNodeType nodeType)
1016 {
1017     auto node = GetFormChildNode(nodeType);
1018     CHECK_NULL_VOID(node);
1019     auto imageLayoutProperty = node->GetLayoutProperty<ImageLayoutProperty>();
1020     CHECK_NULL_VOID(imageLayoutProperty);
1021     auto sourceInfo = imageLayoutProperty->GetImageSourceInfo();
1022     CHECK_NULL_VOID(sourceInfo);
1023     auto currentColor = sourceInfo->GetFillColor();
1024     auto context = GetContext();
1025     CHECK_NULL_VOID(context);
1026     auto newColor = context->GetColorMode() == ColorMode::DARK ? Color(ICON_COLOR_DARK) : Color(ICON_COLOR_LIGHT);
1027     if (currentColor != newColor) {
1028         sourceInfo->SetFillColor(newColor);
1029         imageLayoutProperty->UpdateImageSourceInfo(sourceInfo.value());
1030         auto imageRenderProperty = node->GetPaintProperty<ImageRenderProperty>();
1031         CHECK_NULL_VOID(imageRenderProperty);
1032         imageRenderProperty->UpdateSvgFillColor(newColor);
1033         node->MarkModifyDone();
1034         node->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1035     }
1036 }
1037 
LoadDisableFormStyle(const RequestFormInfo & info,bool isRefresh)1038 void FormPattern::LoadDisableFormStyle(const RequestFormInfo& info, bool isRefresh)
1039 {
1040     if (IsMaskEnableForm(info)) {
1041         if (!formManagerBridge_) {
1042             TAG_LOGE(AceLogTag::ACE_FORM, "LoadDisableFormStyle failed, form manager deleget is null!");
1043             return;
1044         }
1045 
1046         formManagerBridge_->SetObscured(isFormObscured_);
1047         return;
1048     }
1049 
1050     if (!isRefresh && GetFormChildNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE) != nullptr) {
1051         TAG_LOGW(AceLogTag::ACE_FORM, "Form disable style node already exist.");
1052         return;
1053     }
1054 
1055     TAG_LOGI(AceLogTag::ACE_FORM, "FormPattern::LoadDisableFormStyle");
1056     RemoveFormChildNode(FormChildNodeType::APP_LOCKED_IMAGE_NODE);
1057     RemoveFormChildNode(FormChildNodeType::APP_LOCKED_TEXT_NODE);
1058     RemoveFormChildNode(FormChildNodeType::TIME_LIMIT_TEXT_NODE);
1059     RemoveFormChildNode(FormChildNodeType::TIME_LIMIT_IMAGE_NODE);
1060     RemoveFormChildNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE);
1061     int32_t dimensionHeight = GetFormDimensionHeight(cardInfo_.dimension);
1062     if (dimensionHeight <= 0) {
1063         TAG_LOGE(AceLogTag::ACE_FORM, "LoadDisableFormStyle failed, invalid dimensionHeight!");
1064         return;
1065     }
1066 
1067     RefPtr<FrameNode> rootNode = nullptr;
1068 #ifdef ARKUI_WEARABLE
1069     rootNode =  CreateColumnNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE);
1070 #else
1071     if (cardInfo_.dimension == static_cast<int32_t>(OHOS::AppExecFwk::Constants::Dimension::DIMENSION_1_2)) {
1072         rootNode = CreateRowNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE);
1073     } else {
1074         rootNode = CreateColumnNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE);
1075     }
1076 #endif
1077     CHECK_NULL_VOID(rootNode);
1078     auto renderContext = rootNode->GetRenderContext();
1079     CHECK_NULL_VOID(renderContext);
1080     UpdateForbiddenRootNodeStyle(renderContext);
1081 
1082     rootNode->MarkModifyDone();
1083     rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1084 
1085     auto host = GetHost();
1086     CHECK_NULL_VOID(host);
1087     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
1088     CHECK_NULL_VOID(layoutProperty);
1089     auto visible = layoutProperty->GetVisibleType().value_or(VisibleType::VISIBLE);
1090     layoutProperty->UpdateVisibility(visible);
1091 
1092     UpdateChildNodeOpacity(FormChildNodeType::FORM_SURFACE_NODE, TRANSPARENT_VAL);
1093     UpdateChildNodeOpacity(FormChildNodeType::FORM_STATIC_IMAGE_NODE, TRANSPARENT_VAL);
1094     UpdateChildNodeOpacity(FormChildNodeType::FORM_SKELETON_NODE, TRANSPARENT_VAL);
1095 }
1096 
CreateIconNode(bool isRowStyle)1097 RefPtr<FrameNode> FormPattern::CreateIconNode(bool isRowStyle)
1098 {
1099     auto attribution = formSpecialStyle_.GetFormStyleAttribution();
1100     RefPtr<FrameNode> imageNode = nullptr;
1101     if (attribution == FormStyleAttribution::PARENT_CONTROL) {
1102         imageNode = CreateForbiddenImageNode(InternalResource::ResourceId::IC_TIME_LIMIT_SVG, isRowStyle);
1103         AddFormChildNode(FormChildNodeType::TIME_LIMIT_IMAGE_NODE, imageNode);
1104     }
1105     if (attribution == FormStyleAttribution::APP_LOCK) {
1106         imageNode = CreateForbiddenImageNode(InternalResource::ResourceId::APP_LOCK_SVG, isRowStyle);
1107         AddFormChildNode(FormChildNodeType::APP_LOCKED_IMAGE_NODE, imageNode);
1108     }
1109     return imageNode;
1110 }
1111 
CreateTextNode(bool isRowStyle)1112 RefPtr<FrameNode> FormPattern::CreateTextNode(bool isRowStyle)
1113 {
1114     auto attribution = formSpecialStyle_.GetFormStyleAttribution();
1115     RefPtr<FrameNode> textNode = nullptr;
1116     if (attribution == FormStyleAttribution::PARENT_CONTROL) {
1117         textNode = CreateForbiddenTextNode(TIME_LIMIT_RESOURCE_NAME, isRowStyle);
1118         AddFormChildNode(FormChildNodeType::TIME_LIMIT_TEXT_NODE, textNode);
1119     }
1120     if (attribution == FormStyleAttribution::APP_LOCK) {
1121         textNode = CreateForbiddenTextNode(APP_LOCKED_RESOURCE_NAME, isRowStyle);
1122         AddFormChildNode(FormChildNodeType::APP_LOCKED_TEXT_NODE, textNode);
1123     }
1124     return textNode;
1125 }
1126 
RemoveDisableFormStyle(const RequestFormInfo & info)1127 void FormPattern::RemoveDisableFormStyle(const RequestFormInfo& info)
1128 {
1129     if (!IsMaskEnableForm(info)) {
1130         UpdateChildNodeOpacity(FormChildNodeType::FORM_SURFACE_NODE, NON_TRANSPARENT_VAL);
1131         UpdateChildNodeOpacity(FormChildNodeType::FORM_STATIC_IMAGE_NODE, NON_TRANSPARENT_VAL);
1132         UpdateChildNodeOpacity(FormChildNodeType::FORM_SKELETON_NODE, CONTENT_BG_OPACITY);
1133         RemoveFormChildNode(FormChildNodeType::APP_LOCKED_IMAGE_NODE);
1134         RemoveFormChildNode(FormChildNodeType::APP_LOCKED_TEXT_NODE);
1135         RemoveFormChildNode(FormChildNodeType::TIME_LIMIT_TEXT_NODE);
1136         RemoveFormChildNode(FormChildNodeType::TIME_LIMIT_IMAGE_NODE);
1137         RemoveFormChildNode(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE);
1138         return;
1139     }
1140     if (!formManagerBridge_) {
1141         TAG_LOGE(AceLogTag::ACE_FORM, "RemoveDisableFormStyle failed, form manager deleget is null!");
1142         return;
1143     }
1144     formManagerBridge_->SetObscured(isFormObscured_);
1145 }
1146 
LoadFormSkeleton(bool isRefresh)1147 void FormPattern::LoadFormSkeleton(bool isRefresh)
1148 {
1149     TAG_LOGI(AceLogTag::ACE_FORM, "LoadFormSkeleton");
1150     if (!isRefresh && GetFormChildNode(FormChildNodeType::FORM_SKELETON_NODE) != nullptr) {
1151         TAG_LOGW(AceLogTag::ACE_FORM, "LoadFormSkeleton failed, repeat load!");
1152         return;
1153     }
1154 
1155     int32_t dimension = cardInfo_.dimension;
1156     int32_t dimensionHeight = GetFormDimensionHeight(dimension);
1157     if (dimensionHeight <= 0) {
1158         TAG_LOGE(AceLogTag::ACE_FORM, "LoadFormSkeleton failed, invalid dimensionHeight!");
1159         return;
1160     }
1161 
1162     RemoveFormChildNode(FormChildNodeType::FORM_SKELETON_NODE);
1163     auto columnNode = CreateColumnNode(FormChildNodeType::FORM_SKELETON_NODE);
1164     CHECK_NULL_VOID(columnNode);
1165     double cardWidth = cardInfo_.width.Value();
1166     double cardHeight = cardInfo_.height.Value();
1167     auto colorMode = Container::CurrentColorMode();
1168     bool isDarkMode = colorMode == ColorMode::DARK;
1169     std::shared_ptr<FormSkeletonParams> params = std::make_shared<FormSkeletonParams>(cardWidth,
1170         cardHeight, dimension, dimensionHeight, isDarkMode);
1171     CreateSkeletonView(columnNode, params, dimensionHeight);
1172 
1173     auto renderContext = columnNode->GetRenderContext();
1174     if (renderContext != nullptr) {
1175         Color colorStyle = isDarkMode ? Color(CONTENT_BG_COLOR_DARK) : Color(CONTENT_BG_COLOR_LIGHT);
1176         if (SystemProperties::IsFormSkeletonBlurEnabled() && !isUnTrust_) {
1177             BlurStyleOption styleOption;
1178             styleOption.blurStyle = static_cast<BlurStyle>(static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK));
1179             renderContext->UpdateBackBlurStyle(styleOption);
1180         } else {
1181             colorStyle = isDarkMode ?
1182                 Color(CONTENT_BG_COLOR_DARK_WITHOUT_BLUR) : Color(CONTENT_BG_COLOR_LIGHT_WITHOUT_BLUR);
1183         }
1184         renderContext->UpdateBackgroundColor(colorStyle);
1185         double opacity = formChildrenNodeMap_.find(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE)
1186             != formChildrenNodeMap_.end() ? TRANSPARENT_VAL : CONTENT_BG_OPACITY;
1187         renderContext->SetOpacity(opacity);
1188     }
1189     columnNode->MarkModifyDone();
1190     columnNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1191 
1192     auto host = GetHost();
1193     CHECK_NULL_VOID(host);
1194     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
1195     CHECK_NULL_VOID(layoutProperty);
1196     auto visible = layoutProperty->GetVisibleType().value_or(VisibleType::VISIBLE);
1197     layoutProperty->UpdateVisibility(visible);
1198 }
1199 
ShouldLoadFormSkeleton(bool isTransparencyEnabled,const RequestFormInfo & info)1200 bool FormPattern::ShouldLoadFormSkeleton(bool isTransparencyEnabled, const RequestFormInfo &info)
1201 {
1202     auto wantWrap = info.wantWrap;
1203     if (isUnTrust_) {
1204         return true;
1205     }
1206 
1207     if (!wantWrap ||
1208         !wantWrap->GetWant().GetBoolParam(OHOS::AppExecFwk::Constants::FORM_ENABLE_SKELETON_KEY, false)) {
1209         TAG_LOGD(AceLogTag::ACE_FORM, "LoadFormSkeleton ignored, not enable.");
1210         return false;
1211     }
1212 
1213     if (isTransparencyEnabled && wantWrap) {
1214         auto color = wantWrap->GetWant().GetStringParam(OHOS::AppExecFwk::Constants::PARAM_FORM_TRANSPARENCY_KEY);
1215         Color bgColor;
1216         if (Color::ParseColorString(color, bgColor) && bgColor == Color::TRANSPARENT) {
1217             TAG_LOGD(AceLogTag::ACE_FORM, "LoadFormSkeleton ignored, bgColor: %{public}s", color.c_str());
1218             return false;
1219         }
1220     }
1221 
1222     if (info.renderingMode ==
1223         static_cast<int32_t>(OHOS::AppExecFwk::Constants::RenderingMode::SINGLE_COLOR)) {
1224         TAG_LOGD(AceLogTag::ACE_FORM, "LoadFormSkeleton ignored, single mode.");
1225         return false;
1226     }
1227     return true;
1228 }
1229 
GetFormDimensionHeight(int32_t dimension)1230 int32_t FormPattern::GetFormDimensionHeight(int32_t dimension)
1231 {
1232     auto iter = OHOS::AppExecFwk::Constants::DIMENSION_MAP.
1233         find(static_cast<OHOS::AppExecFwk::Constants::Dimension>(dimension));
1234     if (iter == OHOS::AppExecFwk::Constants::DIMENSION_MAP.end()) {
1235         TAG_LOGE(AceLogTag::ACE_FORM, "GetFormDimensionHeight failed, invalid dimension: %{public}d",
1236             dimension);
1237         return 0;
1238     }
1239 
1240     std::string formDimensionStr = iter->second;
1241     std::stringstream streamDimension(formDimensionStr);
1242     std::string dimensionHeightStr;
1243     if (!std::getline(streamDimension, dimensionHeightStr, FORM_DIMENSION_SPLITTER)) {
1244         TAG_LOGE(AceLogTag::ACE_FORM, "GetFormDimensionHeight failed!");
1245         return 0;
1246     }
1247     return StringUtils::StringToInt(dimensionHeightStr);
1248 }
1249 
CreateForbiddenTextNode(std::string resourceName,bool isRowStyle)1250 RefPtr<FrameNode> FormPattern::CreateForbiddenTextNode(std::string resourceName, bool isRowStyle)
1251 {
1252     std::string content;
1253     GetResourceContent(resourceName, content);
1254     TAG_LOGI(AceLogTag::ACE_FORM, "GetTimeLimitContent, content = %{public}s", content.c_str());
1255 
1256     RefPtr<FrameNode> textNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG,
1257         ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
1258     CHECK_NULL_RETURN(textNode, nullptr);
1259     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
1260     CHECK_NULL_RETURN(textLayoutProperty, nullptr);
1261     if (isRowStyle) {
1262         // The text content occupies all the remaining space in the ROW component.
1263         textLayoutProperty->UpdateLayoutWeight(1);
1264         textLayoutProperty->UpdateHeightAdaptivePolicy(TextHeightAdaptivePolicy::LAYOUT_CONSTRAINT_FIRST);
1265     }
1266     textLayoutProperty->UpdateContent(content);
1267     textLayoutProperty->UpdateFontWeight(FontWeight::MEDIUM);
1268     Dimension fontSize(GetTimeLimitFontSize());
1269     textLayoutProperty->UpdateFontSize(fontSize);
1270     auto context = GetContext();
1271     CHECK_NULL_RETURN(context, nullptr);
1272     textLayoutProperty->UpdateTextColor(
1273         context->GetColorMode() == ColorMode::DARK ? Color(FONT_COLOR_DARK) : Color(FONT_COLOR_LIGHT));
1274     textLayoutProperty->UpdateTextAlign(isRowStyle ? TextAlign::START : TextAlign::CENTER);
1275     auto externalContext = DynamicCast<NG::RosenRenderContext>(textNode->GetRenderContext());
1276     CHECK_NULL_RETURN(externalContext, nullptr);
1277     externalContext->SetVisible(true);
1278     externalContext->SetOpacity(1);
1279     textNode->MarkModifyDone();
1280     textNode->MarkDirtyNode();
1281     return textNode;
1282 }
1283 
CreateForbiddenImageNode(InternalResource::ResourceId resourceId,bool isRowStyle)1284 RefPtr<FrameNode> FormPattern::CreateForbiddenImageNode(InternalResource::ResourceId resourceId, bool isRowStyle)
1285 {
1286     auto host = GetHost();
1287     CHECK_NULL_RETURN(host, nullptr);
1288     int32_t imageNodeId = ElementRegister::GetInstance()->MakeUniqueId();
1289     auto imageNode = FrameNode::CreateFrameNode(V2::IMAGE_ETS_TAG, imageNodeId, AceType::MakeRefPtr<ImagePattern>());
1290     CHECK_NULL_RETURN(imageNode, nullptr);
1291     auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
1292     CHECK_NULL_RETURN(imageLayoutProperty, nullptr);
1293     auto info = ImageSourceInfo("");
1294     info.SetResourceId(resourceId);
1295     auto context = host->GetContext();
1296     CHECK_NULL_RETURN(context, nullptr);
1297     auto newColor = context->GetColorMode() == ColorMode::DARK ? Color(ICON_COLOR_DARK) : Color(ICON_COLOR_LIGHT);
1298     info.SetFillColor(newColor);
1299     imageLayoutProperty->UpdateImageSourceInfo(info);
1300     auto imageRenderProperty = imageNode->GetPaintProperty<ImageRenderProperty>();
1301     CHECK_NULL_RETURN(imageRenderProperty, nullptr);
1302     imageRenderProperty->UpdateSvgFillColor(newColor);
1303 #ifdef ARKUI_WEARABLE
1304     CalcSize idealSize = { CalcLength(FORBIDDEN_ICON_STYLE, DimensionUnit::PX),
1305         CalcLength(FORBIDDEN_ICON_STYLE, DimensionUnit::PX) };
1306 #else
1307     double iconSize = isRowStyle ? FORBIDDEN_ICON_STYLE_1_2 : FORBIDDEN_ICON_STYLE;
1308     CalcSize idealSize = { CalcLength(iconSize, DimensionUnit::VP),
1309         CalcLength(iconSize, DimensionUnit::VP) };
1310 #endif
1311     imageLayoutProperty->UpdateUserDefinedIdealSize(idealSize);
1312     auto externalContext = DynamicCast<NG::RosenRenderContext>(imageNode->GetRenderContext());
1313     CHECK_NULL_RETURN(externalContext, nullptr);
1314     externalContext->SetVisible(true);
1315     externalContext->SetOpacity(1);
1316     imageNode->MarkModifyDone();
1317     imageNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1318     return imageNode;
1319 }
1320 
CreateSkeletonView(const RefPtr<FrameNode> & parent,const std::shared_ptr<FormSkeletonParams> & params,int32_t dimensionHeight)1321 void FormPattern::CreateSkeletonView(
1322     const RefPtr<FrameNode>& parent, const std::shared_ptr<FormSkeletonParams>& params, int32_t dimensionHeight)
1323 {
1324     float lineHeight = params->GetLineHeight();
1325     uint32_t fillColor = params->GetFillColor();
1326     float lineMarginLeft = params->GetLineMarginLeft();
1327 
1328     // 1. Set title line
1329     MarginProperty titleMargin;
1330     titleMargin.top = CalcLength(params->GetTitleMarginTop());
1331     titleMargin.left = CalcLength(lineMarginLeft);
1332     CalcSize titleIdealSize = { CalcLength(params->GetTitleLineWidth()), CalcLength(lineHeight) };
1333     auto titleLineNode = CreateRectNode(parent, titleIdealSize, titleMargin,
1334         fillColor, params->GetTitleOpacity());
1335     CHECK_NULL_VOID(titleLineNode);
1336 
1337     // 2. Set content lines
1338     for (int32_t i = 0; i < params->GetContentLineNum(); i++) {
1339         MarginProperty contentMargin;
1340         contentMargin.top = CalcLength(i == 0 ? params->GetTitleContentMargins() :
1341             params->GetContentMargins());
1342         contentMargin.left = CalcLength(lineMarginLeft);
1343         CalcSize contentIdealSize = { CalcLength(params->GetLineWidth()), CalcLength(lineHeight) };
1344         auto contentLineNode = CreateRectNode(parent, contentIdealSize, contentMargin,
1345             fillColor, params->GetContentOpacity());
1346         CHECK_NULL_VOID(contentLineNode);
1347     }
1348 
1349     // 3. Set ending line if form dimension height greater than 1
1350     if (dimensionHeight > 1) {
1351         MarginProperty endingMargin;
1352         endingMargin.top = CalcLength(params->GetEndingLineMarginTop());
1353         endingMargin.left = CalcLength(lineMarginLeft);
1354         CalcSize endingIdealSize = { CalcLength(params->GetEndingLineWidth()), CalcLength(lineHeight) };
1355         auto endingLineNode = CreateRectNode(parent, endingIdealSize, endingMargin,
1356             fillColor, params->GetContentOpacity());
1357         CHECK_NULL_VOID(endingLineNode);
1358     }
1359 }
1360 
CreateRowNode(FormChildNodeType formChildNodeType)1361 RefPtr<FrameNode> FormPattern::CreateRowNode(FormChildNodeType formChildNodeType)
1362 {
1363     auto host = GetHost();
1364     CHECK_NULL_RETURN(host, nullptr);
1365     RefPtr<FrameNode> rowNode = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG,
1366         ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<LinearLayoutPattern>(false));
1367     CHECK_NULL_RETURN(rowNode, nullptr);
1368     AddFormChildNode(formChildNodeType, rowNode);
1369     auto width = static_cast<float>(cardInfo_.width.Value());
1370     auto height = static_cast<float>(cardInfo_.height.Value());
1371     CalcSize idealSize = { CalcLength(width), CalcLength(height) };
1372     MeasureProperty layoutConstraint;
1373     layoutConstraint.selfIdealSize = idealSize;
1374     layoutConstraint.maxSize = idealSize;
1375     rowNode->UpdateLayoutConstraint(layoutConstraint);
1376 
1377     auto layoutProperty = rowNode->GetLayoutProperty<LinearLayoutProperty>();
1378     CHECK_NULL_RETURN(layoutProperty, nullptr);
1379     PaddingProperty padding;
1380     padding.left = CalcLength(FORBIDDEN_STYLE_PADDING, DimensionUnit::VP);
1381     padding.right = CalcLength(FORBIDDEN_STYLE_PADDING, DimensionUnit::VP);
1382     layoutProperty->UpdatePadding(padding);
1383     layoutProperty->UpdateMainAxisAlign(FlexAlign::FLEX_START);
1384     auto space = Dimension(FORBIDDEN_STYLE_SPACE, DimensionUnit::VP);
1385     layoutProperty->UpdateSpace(space);
1386 
1387     rowNode->AddChild(CreateIconNode(true));
1388     rowNode->AddChild(CreateTextNode(true));
1389     host->AddChild(rowNode);
1390     return rowNode;
1391 }
1392 
CreateColumnNode(FormChildNodeType formChildNodeType)1393 RefPtr<FrameNode> FormPattern::CreateColumnNode(FormChildNodeType formChildNodeType)
1394 {
1395     auto host = GetHost();
1396     CHECK_NULL_RETURN(host, nullptr);
1397     RefPtr<FrameNode> columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG,
1398         ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<LinearLayoutPattern>(true));
1399     CHECK_NULL_RETURN(columnNode, nullptr);
1400     AddFormChildNode(formChildNodeType, columnNode);
1401     auto width = static_cast<float>(cardInfo_.width.Value());
1402     auto height = static_cast<float>(cardInfo_.height.Value());
1403     CalcSize idealSize = { CalcLength(width), CalcLength(height) };
1404     MeasureProperty layoutConstraint;
1405     layoutConstraint.selfIdealSize = idealSize;
1406     layoutConstraint.maxSize = idealSize;
1407     columnNode->UpdateLayoutConstraint(layoutConstraint);
1408 
1409     auto layoutProperty = columnNode->GetLayoutProperty<LinearLayoutProperty>();
1410     CHECK_NULL_RETURN(layoutProperty, nullptr);
1411     if (formChildNodeType == FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE) {
1412         layoutProperty->UpdateCrossAxisAlign(FlexAlign::CENTER);
1413         layoutProperty->UpdateMainAxisAlign(FlexAlign::CENTER);
1414         auto space = Dimension(8, DimensionUnit::VP);
1415         layoutProperty->UpdateSpace(space);
1416         PaddingProperty padding;
1417         padding.left = CalcLength(FORBIDDEN_STYLE_PADDING, DimensionUnit::VP);
1418         padding.right = CalcLength(FORBIDDEN_STYLE_PADDING, DimensionUnit::VP);
1419         layoutProperty->UpdatePadding(padding);
1420 
1421         columnNode->AddChild(CreateIconNode(false));
1422 #ifndef ARKUI_WEARABLE
1423         columnNode->AddChild(CreateTextNode(false));
1424 #endif
1425     } else {
1426         layoutProperty->UpdateCrossAxisAlign(FlexAlign::FLEX_START);
1427     }
1428     host->AddChild(columnNode);
1429     return columnNode;
1430 }
1431 
CreateRectNode(const RefPtr<FrameNode> & parent,const CalcSize & idealSize,const MarginProperty & margin,uint32_t fillColor,double opacity)1432 RefPtr<FrameNode> FormPattern::CreateRectNode(const RefPtr<FrameNode>& parent, const CalcSize& idealSize,
1433     const MarginProperty& margin, uint32_t fillColor, double opacity)
1434 {
1435     auto rectNode = FrameNode::CreateFrameNode(V2::RECT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1436         AceType::MakeRefPtr<RectPattern>());
1437     MeasureProperty layoutConstraint;
1438     layoutConstraint.selfIdealSize = idealSize;
1439     layoutConstraint.maxSize = idealSize;
1440     rectNode->UpdateLayoutConstraint(layoutConstraint);
1441 
1442     rectNode->GetLayoutProperty()->UpdateMargin(margin);
1443 
1444     auto paintProperty = rectNode->GetPaintProperty<RectPaintProperty>();
1445     CHECK_NULL_RETURN(paintProperty, nullptr);
1446     paintProperty->UpdateFill(Color(fillColor));
1447     paintProperty->UpdateFillOpacity(opacity);
1448 
1449     paintProperty->UpdateTopLeftRadius(NG::Radius(RECT_RADIUS));
1450     paintProperty->UpdateTopRightRadius(NG::Radius(RECT_RADIUS));
1451     paintProperty->UpdateBottomLeftRadius(NG::Radius(RECT_RADIUS));
1452     paintProperty->UpdateBottomRightRadius(NG::Radius(RECT_RADIUS));
1453 
1454     rectNode->MountToParent(parent);
1455     rectNode->MarkDirtyNode();
1456 
1457     return rectNode;
1458 }
1459 
InitFormManagerDelegate()1460 void FormPattern::InitFormManagerDelegate()
1461 {
1462     if (formManagerBridge_) {
1463         return;
1464     }
1465 
1466     auto host = GetHost();
1467     CHECK_NULL_VOID(host);
1468     auto context = host->GetContextRefPtr();
1469     CHECK_NULL_VOID(context);
1470     auto pipeline = host->GetContext();
1471     CHECK_NULL_VOID(pipeline);
1472     formManagerBridge_ = AceType::MakeRefPtr<FormManagerDelegate>(context);
1473     CHECK_NULL_VOID(formManagerBridge_);
1474     formManagerBridge_->AddRenderDelegate();
1475     formManagerBridge_->RegisterRenderDelegateEvent();
1476     if (SystemProperties::GetMultiInstanceEnabled()) {
1477         TAG_LOGI(AceLogTag::ACE_FORM, "GetMultiInstanceEnabled is true");
1478         GetRSUIContext();
1479         formManagerBridge_->SetRSUIContext(rsUIContext_);
1480     }
1481     auto formUtils = FormManager::GetInstance().GetFormUtils();
1482     if (formUtils) {
1483         formManagerBridge_->SetFormUtils(formUtils);
1484     }
1485     int32_t instanceID = context->GetInstanceId();
1486     accessibilitySessionAdapter_ = AceType::MakeRefPtr<AccessibilitySessionAdapterForm>(formManagerBridge_);
1487     formManagerBridge_->AddFormAcquireCallback([weak = WeakClaim(this), instanceID, pipeline](int64_t id,
1488                                                    const std::string& path,
1489                                                    const std::string& module, const std::string& data,
1490                                                    const std::map<std::string, sptr<AppExecFwk::FormAshmem>>&
1491                                                        imageDataMap,
1492                                                    const AppExecFwk::FormJsInfo& formJsInfo,
1493                                                    const FrontendType& frontendType, const FrontendType& uiSyntax) {
1494         ContainerScope scope(instanceID);
1495         CHECK_NULL_VOID(pipeline);
1496         auto uiTaskExecutor =
1497             SingleTaskExecutor::Make(pipeline->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1498         uiTaskExecutor.PostTask([id, path, module, data, imageDataMap, formJsInfo, weak, instanceID, frontendType,
1499                                     uiSyntax] {
1500             ContainerScope scope(instanceID);
1501             auto form = weak.Upgrade();
1502             CHECK_NULL_VOID(form);
1503             auto container = form->GetSubContainer();
1504             CHECK_NULL_VOID(container);
1505             container->SetWindowConfig({ formJsInfo.formWindow.designWidth, formJsInfo.formWindow.autoDesignWidth });
1506             container->RunCard(id, path, module, data, imageDataMap, formJsInfo.formSrc, frontendType, uiSyntax);
1507             }, "ArkUIFormRunCard");
1508     });
1509 
1510     InitAddFormUpdateAndErrorCallback(instanceID);
1511     InitAddUninstallAndSurfaceNodeCallback(instanceID);
1512     InitAddFormSurfaceChangeAndDetachCallback(instanceID);
1513     InitAddUnTrustAndSnapshotCallback(instanceID);
1514     InitOtherCallback(instanceID);
1515     InitUpdateFormDoneCallback(instanceID);
1516     const std::function<void(bool isRotate, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)>& callback =
1517         [this](bool isRotate, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction) {
1518             FormManager::GetInstance().NotifyIsSizeChangeByRotate(isRotate, rsTransaction);
1519         };
1520     context->SetSizeChangeByRotateCallback(callback);
1521 }
1522 
GetRectRelativeToWindow(AccessibilityParentRectInfo & parentRectInfo)1523 void FormPattern::GetRectRelativeToWindow(AccessibilityParentRectInfo& parentRectInfo)
1524 {
1525     auto host = GetHost();
1526     CHECK_NULL_VOID(host);
1527     auto rect = host->GetTransformRectRelativeToWindow();
1528     VectorF finalScale = host->GetTransformScaleRelativeToWindow();
1529     parentRectInfo.top = static_cast<int32_t>(rect.Top());
1530     parentRectInfo.left = static_cast<int32_t>(rect.Left());
1531     parentRectInfo.scaleX = finalScale.x;
1532     parentRectInfo.scaleY = finalScale.y;
1533 
1534     auto pipeline = host->GetContextRefPtr();
1535     if (pipeline) {
1536         auto accessibilityManager = pipeline->GetAccessibilityManager();
1537         if (accessibilityManager) {
1538             parentRectInfo = accessibilityManager->GetTransformRectInfoRelativeToWindow(host, pipeline);
1539         } else {
1540             auto windowRect = pipeline->GetDisplayWindowRectInfo();
1541             parentRectInfo.top += static_cast<int32_t>(windowRect.Top());
1542             parentRectInfo.left += static_cast<int32_t>(windowRect.Left());
1543         }
1544     }
1545 
1546     TAG_LOGD(AceLogTag::ACE_ACCESSIBILITY, "elementId: %{public}" PRId64 ", top: %{public}d, left: %{public}d",
1547         host->GetAccessibilityId(), parentRectInfo.top, parentRectInfo.left);
1548 }
1549 
ProcDeleteImageNode(const AAFwk::Want & want)1550 void FormPattern::ProcDeleteImageNode(const AAFwk::Want& want)
1551 {
1552     if (want.GetBoolParam(OHOS::AppExecFwk::Constants::FORM_IS_RECOVER_FORM, false)) {
1553         DelayDeleteImageNode(want.GetBoolParam(
1554             OHOS::AppExecFwk::Constants::FORM_IS_RECOVER_FORM_TO_HANDLE_CLICK_EVENT, false));
1555     } else {
1556         DelayRemoveFormChildNode(FormChildNodeType::FORM_STATIC_IMAGE_NODE);
1557     }
1558 }
1559 
DelayRemoveFormChildNode(FormChildNodeType formChildNodeType)1560 void FormPattern::DelayRemoveFormChildNode(FormChildNodeType formChildNodeType)
1561 {
1562     auto host = GetHost();
1563     CHECK_NULL_VOID(host);
1564     auto context = host->GetContext();
1565     CHECK_NULL_VOID(context);
1566     std::string nodeIdStr = std::to_string(host->GetId());
1567     auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1568     uiTaskExecutor.PostDelayedTask(
1569         [weak = WeakClaim(this), formChildNodeType] {
1570             auto pattern = weak.Upgrade();
1571             CHECK_NULL_VOID(pattern);
1572             pattern->RemoveFormChildNode(formChildNodeType);
1573         },
1574         STATIC_FORM_DELAY_TIME_FOR_DELETE_IMAGE_NODE, "DelayRemoveFormChildNode" + nodeIdStr);
1575 }
1576 
AttachRSNode(const std::shared_ptr<Rosen::RSSurfaceNode> & node,const AAFwk::Want & want)1577 void FormPattern::AttachRSNode(const std::shared_ptr<Rosen::RSSurfaceNode>& node, const AAFwk::Want& want)
1578 {
1579     auto host = GetHost();
1580     CHECK_NULL_VOID(host);
1581     auto externalRenderContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
1582     CHECK_NULL_VOID(externalRenderContext);
1583     externalRenderContext->SetRSNode(node);
1584     float boundWidth = cardInfo_.width.Value() - cardInfo_.borderWidth * DOUBLE;
1585     float boundHeight = cardInfo_.height.Value() - cardInfo_.borderWidth * DOUBLE;
1586     if (isBeenLayout_) {
1587         auto geometryNode = host->GetGeometryNode();
1588         CHECK_NULL_VOID(geometryNode);
1589         auto size = geometryNode->GetFrameSize();
1590         boundWidth = size.Width() - cardInfo_.borderWidth * DOUBLE;
1591         boundHeight = size.Height() - cardInfo_.borderWidth * DOUBLE;
1592     }
1593     TAG_LOGI(AceLogTag::ACE_FORM,
1594         "attach rs node, id: %{public}" PRId64 "  width: %{public}f  height: %{public}f  borderWidth: %{public}f",
1595         cardInfo_.id, boundWidth, boundHeight, cardInfo_.borderWidth);
1596     externalRenderContext->SetBounds(round(cardInfo_.borderWidth), round(cardInfo_.borderWidth),
1597         round(boundWidth), round(boundHeight));
1598 
1599     bool isRecover = want.GetBoolParam(OHOS::AppExecFwk::Constants::FORM_IS_RECOVER_FORM, false);
1600     if (isRecover || (isSkeletonAnimEnable_ && !isTransparencyEnable_) ||
1601         formChildrenNodeMap_.find(FormChildNodeType::FORM_FORBIDDEN_ROOT_NODE) != formChildrenNodeMap_.end()) {
1602         TAG_LOGI(AceLogTag::ACE_FORM, "surfaceNode: %{public}s setOpacity:0,%{public}d,"
1603                                   "%{public}d,%{public}d",
1604             std::to_string(node->GetId()).c_str(),
1605             isRecover,
1606             isSkeletonAnimEnable_,
1607             isTransparencyEnable_);
1608         externalRenderContext->SetOpacity(TRANSPARENT_VAL);
1609     } else {
1610         TAG_LOGI(AceLogTag::ACE_FORM, "surfaceNode: %{public}s setOpacity:1,%{public}d,"
1611                                   "%{public}d,%{public}d",
1612             std::to_string(node->GetId()).c_str(),
1613             isRecover,
1614             isSkeletonAnimEnable_,
1615             isTransparencyEnable_);
1616         externalRenderContext->SetOpacity(NON_TRANSPARENT_VAL);
1617     }
1618 
1619     auto renderContext = host->GetRenderContext();
1620     CHECK_NULL_VOID(renderContext);
1621     renderContext->AddChild(externalRenderContext, 0);
1622 }
1623 
FireFormSurfaceNodeCallback(const std::shared_ptr<Rosen::RSSurfaceNode> & node,const AAFwk::Want & want)1624 void FormPattern::FireFormSurfaceNodeCallback(
1625     const std::shared_ptr<Rosen::RSSurfaceNode>& node, const AAFwk::Want& want)
1626 {
1627     ACE_FUNCTION_TRACE();
1628     CHECK_NULL_VOID(node);
1629     bool isEnableSkeleton = isSkeletonAnimEnable_;
1630     TAG_LOGI(AceLogTag::ACE_FORM, "FireFormSurfaceNodeCallback %{public}d, %{public}d",
1631         isTransparencyEnable_, isEnableSkeleton);
1632     if (SystemProperties::GetMultiInstanceEnabled()) {
1633         TAG_LOGD(AceLogTag::ACE_FORM, "GetMultiInstanceEnabled is true");
1634         node->SetRSUIContext(rsUIContext_);
1635     }
1636     node->CreateNodeInRenderThread();
1637 
1638     // do anim only when skeleton enable and transparency
1639     AttachRSNode(node, want);
1640     if (!isEnableSkeleton) {
1641         RemoveFormChildNode(FormChildNodeType::FORM_SKELETON_NODE);
1642     }
1643 
1644     auto host = GetHost();
1645     CHECK_NULL_VOID(host);
1646     isDynamic_ = want.GetBoolParam(OHOS::AppExecFwk::Constants::FORM_IS_DYNAMIC, false);
1647     UpdateFormBaseConfig(isDynamic_);
1648 
1649     ProcDeleteImageNode(want);
1650 
1651     host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
1652     auto parent = host->GetParent();
1653     CHECK_NULL_VOID(parent);
1654     parent->MarkNeedSyncRenderTree();
1655     parent->RebuildRenderContextTree();
1656     auto renderContext = host->GetRenderContext();
1657     CHECK_NULL_VOID(renderContext);
1658     renderContext->RequestNextFrame();
1659     OnLoadEvent();
1660 
1661     auto formNode = DynamicCast<FormNode>(host);
1662     CHECK_NULL_VOID(formNode);
1663     formNode->NotifyAccessibilityChildTreeRegister();
1664 
1665     if (isEnableSkeleton && !isTransparencyEnable_) {
1666         TAG_LOGI(AceLogTag::ACE_FORM, "FireFormSurfaceNodeCallback delay %{public}d,%{public}d",
1667             isTransparencyEnable_, isEnableSkeleton);
1668         auto context = host->GetContext();
1669         CHECK_NULL_VOID(context);
1670         if (!ShouldDoSkeletonAnimation()) {
1671             TAG_LOGE(AceLogTag::ACE_FORM, "not do skeleton animation");
1672             SetExternalRenderOpacity(NON_TRANSPARENT_VAL);
1673             return;
1674         }
1675         std::string nodeIdStr = std::to_string(host->GetId());
1676         auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1677         uiTaskExecutor.PostDelayedTask(
1678             [weak = WeakClaim(this)] {
1679                 auto pattern = weak.Upgrade();
1680                 CHECK_NULL_VOID(pattern);
1681                 pattern->DoSkeletonAnimation();
1682             }, FORM_UNLOCK_ANIMATION_DELAY, "DoSkeletonAnimation_" + nodeIdStr);
1683     }
1684 }
1685 
DelayDeleteImageNode(bool needHandleCachedClick)1686 void FormPattern::DelayDeleteImageNode(bool needHandleCachedClick)
1687 {
1688     auto host = GetHost();
1689     CHECK_NULL_VOID(host);
1690     auto context = host->GetContext();
1691     CHECK_NULL_VOID(context);
1692     std::string nodeIdStr = std::to_string(host->GetId());
1693     auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1694     uiTaskExecutor.PostDelayedTask(
1695         [weak = WeakClaim(this)] {
1696             auto pattern = weak.Upgrade();
1697             CHECK_NULL_VOID(pattern);
1698             pattern->SetNonTransparentAfterRecover();
1699         },
1700         DELAY_TIME_FOR_SET_NON_TRANSPARENT, "ArkUIFormSetNonTransparentAfterRecover_" + nodeIdStr);
1701     uiTaskExecutor.PostDelayedTask(
1702         [weak = WeakClaim(this), needHandleCachedClick] {
1703             auto pattern = weak.Upgrade();
1704             CHECK_NULL_VOID(pattern);
1705             pattern->DeleteImageNodeAfterRecover(needHandleCachedClick);
1706         },
1707         DELAY_TIME_FOR_DELETE_IMAGE_NODE, "ArkUIFormDeleteImageNodeAfterRecover_" + nodeIdStr);
1708 }
1709 
FireFormSurfaceChangeCallback(float width,float height,float borderWidth)1710 void FormPattern::FireFormSurfaceChangeCallback(float width, float height, float borderWidth)
1711 {
1712     auto externalRenderContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
1713     CHECK_NULL_VOID(externalRenderContext);
1714     TAG_LOGI(AceLogTag::ACE_FORM,
1715         "FireFormSurfaceChangeCallback, "
1716         "id: %{public}" PRId64 "  width: %{public}f  height: %{public}f  borderWidth: %{public}f",
1717         cardInfo_.id, width, height, borderWidth);
1718     externalRenderContext->SetBounds(round(borderWidth), round(borderWidth), round(width - borderWidth * DOUBLE),
1719         round(height - borderWidth * DOUBLE));
1720     auto host = GetHost();
1721     CHECK_NULL_VOID(host);
1722     auto renderContext = host->GetRenderContext();
1723     CHECK_NULL_VOID(renderContext);
1724     isUnTrust_ = false;
1725     host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
1726     auto parent = host->GetParent();
1727     CHECK_NULL_VOID(parent);
1728     parent->MarkNeedSyncRenderTree();
1729     parent->RebuildRenderContextTree();
1730     renderContext->RequestNextFrame();
1731 }
1732 
FireFormSurfaceDetachCallback()1733 void FormPattern::FireFormSurfaceDetachCallback()
1734 {
1735     TAG_LOGI(AceLogTag::ACE_FORM, "FireFormSurfaceDetachCallback isFrsNodeDetached:%{public}d", isFrsNodeDetached_);
1736     isFrsNodeDetached_ = true;
1737 }
1738 
CreateCardContainer()1739 void FormPattern::CreateCardContainer()
1740 {
1741     auto host = GetHost();
1742     CHECK_NULL_VOID(host);
1743     auto context = host->GetContextRefPtr();
1744     CHECK_NULL_VOID(context);
1745     auto pipeline = host->GetContext();
1746     CHECK_NULL_VOID(pipeline);
1747     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
1748     CHECK_NULL_VOID(layoutProperty);
1749     auto hasContainer = false;
1750     RemoveSubContainer();
1751     if (cardInfo_.id != 0 && Container::IsCurrentUseNewPipeline()) {
1752         auto subContainer = FormManager::GetInstance().GetSubContainer(cardInfo_.id);
1753         if (subContainer && context->GetInstanceId() == subContainer->GetInstanceId() &&
1754             subContainer->GetCardType() == FrontendType::JS_CARD) {
1755             subContainer_ = subContainer;
1756             FormManager::GetInstance().RemoveSubContainer(cardInfo_.id);
1757             hasContainer = true;
1758         }
1759     }
1760     if (!subContainer_) {
1761         subContainer_ = AceType::MakeRefPtr<SubContainer>(context, context->GetInstanceId());
1762     }
1763     enhancesSubContainer(hasContainer);
1764 }
1765 
AttachJsRSNode(const std::shared_ptr<Rosen::RSNode> & jsNode)1766 void FormPattern::AttachJsRSNode(const std::shared_ptr<Rosen::RSNode> &jsNode)
1767 {
1768     auto host = GetHost();
1769     CHECK_NULL_VOID(host);
1770     auto externalRenderContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
1771     CHECK_NULL_VOID(externalRenderContext);
1772     externalRenderContext->SetRSNode(jsNode);
1773 
1774     auto renderContext = host->GetRenderContext();
1775     CHECK_NULL_VOID(renderContext);
1776     renderContext->AddChild(externalRenderContext, 0);
1777 }
1778 
GetDrawDelegate()1779 std::unique_ptr<DrawDelegate> FormPattern::GetDrawDelegate()
1780 {
1781     auto drawDelegate = std::make_unique<DrawDelegate>();
1782 #ifdef ENABLE_ROSEN_BACKEND
1783     auto host = GetHost();
1784     drawDelegate->SetDrawRSFrameCallback(
1785         [weak = WeakClaim(this), host](std::shared_ptr<RSNode>& node, const Rect& /* dirty */) {
1786             CHECK_NULL_VOID(host);
1787             CHECK_NULL_VOID(node);
1788             auto form = weak.Upgrade();
1789             CHECK_NULL_VOID(form);
1790             auto context = DynamicCast<NG::RosenRenderContext>(host->GetRenderContext());
1791             CHECK_NULL_VOID(context);
1792             auto rsNode = context->GetRSNode();
1793             CHECK_NULL_VOID(rsNode);
1794             form->AttachJsRSNode(node);
1795             host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
1796         });
1797 
1798     drawDelegate->SetDrawRSFrameByRenderContextCallback(
1799         [weak = WeakClaim(this), host](RefPtr<OHOS::Ace::NG::RenderContext>& renderContext) {
1800             auto context = DynamicCast<NG::RosenRenderContext>(renderContext);
1801             CHECK_NULL_VOID(context);
1802             auto node = context->GetRSNode();
1803             CHECK_NULL_VOID(node);
1804             auto form = weak.Upgrade();
1805             CHECK_NULL_VOID(form);
1806             auto formContext = DynamicCast<NG::RosenRenderContext>(host->GetRenderContext());
1807             CHECK_NULL_VOID(formContext);
1808             auto rsNode = formContext->GetRSNode();
1809             CHECK_NULL_VOID(rsNode);
1810             form->AttachJsRSNode(node);
1811             host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
1812         });
1813 #endif
1814     return drawDelegate;
1815 }
1816 
FireOnErrorEvent(const std::string & code,const std::string & msg) const1817 void FormPattern::FireOnErrorEvent(const std::string& code, const std::string& msg) const
1818 {
1819     auto host = GetHost();
1820     CHECK_NULL_VOID(host);
1821     auto eventHub = host->GetOrCreateEventHub<FormEventHub>();
1822     CHECK_NULL_VOID(eventHub);
1823     auto json = JsonUtil::Create(true);
1824     json->Put("errcode", code.c_str());
1825     json->Put("msg", msg.c_str());
1826     eventHub->FireOnError(json->ToString());
1827 }
1828 
FireOnUninstallEvent(int64_t id) const1829 void FormPattern::FireOnUninstallEvent(int64_t id) const
1830 {
1831     auto host = GetHost();
1832     CHECK_NULL_VOID(host);
1833     auto eventHub = host->GetOrCreateEventHub<FormEventHub>();
1834     CHECK_NULL_VOID(eventHub);
1835     int64_t uninstallFormId = id < MAX_NUMBER_OF_JS ? id : -1;
1836     auto json = JsonUtil::Create(true);
1837     json->Put("id", std::to_string(uninstallFormId).c_str());
1838     json->Put("idString", std::to_string(id).c_str());
1839     json->Put("isLocked", formSpecialStyle_.IsLockedByAppLock());
1840     eventHub->FireOnUninstall(json->ToString());
1841 }
1842 
FireOnAcquiredEvent(int64_t id) const1843 void FormPattern::FireOnAcquiredEvent(int64_t id) const
1844 {
1845     auto host = GetHost();
1846     CHECK_NULL_VOID(host);
1847     auto eventHub = host->GetOrCreateEventHub<FormEventHub>();
1848     CHECK_NULL_VOID(eventHub);
1849     int64_t onAcquireFormId = id < MAX_NUMBER_OF_JS ? id : -1;
1850     auto json = JsonUtil::Create(true);
1851     json->Put("id", std::to_string(onAcquireFormId).c_str());
1852     json->Put("idString", std::to_string(id).c_str());
1853     bool isLocked = formSpecialStyle_.IsInited() ?
1854         formSpecialStyle_.IsLockedByAppLock() :
1855         (!IsFormBundleExempt(id) && !formSpecialStyle_.IsMultiAppForm());
1856     json->Put("isLocked", isLocked);
1857     eventHub->FireOnAcquired(json->ToString());
1858 }
1859 
FireOnRouterEvent(const std::unique_ptr<JsonValue> & action)1860 void FormPattern::FireOnRouterEvent(const std::unique_ptr<JsonValue>& action)
1861 {
1862     auto host = GetHost();
1863     CHECK_NULL_VOID(host);
1864     auto eventHub = host->GetOrCreateEventHub<FormEventHub>();
1865     CHECK_NULL_VOID(eventHub);
1866     auto json = JsonUtil::Create(true);
1867     json->Put("action", action);
1868     eventHub->FireOnRouter(json->ToString());
1869 }
1870 
FireOnLoadEvent() const1871 void FormPattern::FireOnLoadEvent() const
1872 {
1873     auto host = GetHost();
1874     CHECK_NULL_VOID(host);
1875     auto eventHub = host->GetOrCreateEventHub<FormEventHub>();
1876     CHECK_NULL_VOID(eventHub);
1877     eventHub->FireOnLoad("");
1878 }
1879 
OnLoadEvent()1880 void FormPattern::OnLoadEvent()
1881 {
1882     ACE_FUNCTION_TRACE();
1883     isSnapshot_ = false;
1884     auto host = GetHost();
1885     CHECK_NULL_VOID(host);
1886     auto context = host->GetContext();
1887     CHECK_NULL_VOID(context);
1888     auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1889     uiTaskExecutor.PostTask([weak = WeakClaim(this)] {
1890         auto pattern = weak.Upgrade();
1891         CHECK_NULL_VOID(pattern);
1892         pattern->FireOnLoadEvent();
1893         }, "ArkUIFormFireLoadEvent");
1894 }
1895 
OnActionEvent(const std::string & action)1896 void FormPattern::OnActionEvent(const std::string& action)
1897 {
1898     TAG_LOGI(AceLogTag::ACE_FORM, "formPattern receive actionEvent");
1899     if (!formManagerBridge_) {
1900         TAG_LOGE(AceLogTag::ACE_FORM, "OnActionEvent failed, form manager deleget is null!");
1901         return;
1902     }
1903     auto eventAction = JsonUtil::ParseJsonString(action);
1904     if (!eventAction->IsValid()) {
1905         return;
1906     }
1907 
1908     auto actionType = eventAction->GetValue("action");
1909     if (!actionType->IsValid()) {
1910         return;
1911     }
1912 
1913     auto type = actionType->GetString();
1914     if (type != "router" && type != "message" && type != "call") {
1915         return;
1916     }
1917 
1918     RemoveDelayResetManuallyClickFlagTask();
1919     auto subContainer = GetSubContainer();
1920     CHECK_NULL_VOID(subContainer);
1921     if (!isManuallyClick_ && subContainer->GetUISyntaxType() == FrontendType::ETS_CARD) {
1922         EventReport::ReportNonManualPostCardActionInfo(cardInfo_.cardName, cardInfo_.bundleName, cardInfo_.abilityName,
1923             cardInfo_.moduleName, cardInfo_.dimension);
1924         if ("router" == type && !AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
1925             TAG_LOGI(AceLogTag::ACE_FORM, "postcardaction is not manually click.");
1926             return;
1927         }
1928     }
1929 
1930     if ("router" == type) {
1931         isManuallyClick_ = false;
1932         auto host = GetHost();
1933         CHECK_NULL_VOID(host);
1934         auto context = host->GetContext();
1935         CHECK_NULL_VOID(context);
1936         auto uiTaskExecutor =
1937             SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1938         if (uiTaskExecutor.IsRunOnCurrentThread()) {
1939             FireOnRouterEvent(eventAction);
1940         } else {
1941             uiTaskExecutor.PostTask([weak = WeakClaim(this), action] {
1942                 auto pattern = weak.Upgrade();
1943                 CHECK_NULL_VOID(pattern);
1944                 auto eventAction = JsonUtil::ParseJsonString(action);
1945                 TAG_LOGI(AceLogTag::ACE_FORM, "UI task execute begin.");
1946                 pattern->FireOnRouterEvent(eventAction);
1947                 }, "ArkUIFormFireRouterEvent");
1948         }
1949     }
1950 
1951     formManagerBridge_->OnActionEvent(action);
1952 }
1953 
ISAllowUpdate() const1954 bool FormPattern::ISAllowUpdate() const
1955 {
1956     auto host = GetHost();
1957     CHECK_NULL_RETURN(host, true);
1958     auto property = host->GetLayoutProperty<FormLayoutProperty>();
1959     CHECK_NULL_RETURN(property, true);
1960     auto formInfo = property->GetRequestFormInfo();
1961     CHECK_NULL_RETURN(property, true);
1962     return formInfo->allowUpdate;
1963 }
1964 
GetSubContainer() const1965 const RefPtr<SubContainer>& FormPattern::GetSubContainer() const
1966 {
1967     return subContainer_;
1968 }
1969 
DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,SerializedGesture & serializedGesture)1970 void FormPattern::DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
1971     SerializedGesture& serializedGesture)
1972 {
1973     CHECK_NULL_VOID(pointerEvent);
1974     CHECK_NULL_VOID(formManagerBridge_);
1975 
1976     if (OHOS::MMI::PointerEvent::POINTER_ACTION_DOWN == pointerEvent->GetPointerAction()) {
1977         isManuallyClick_ = true;
1978         DelayResetManuallyClickFlag();
1979     }
1980     if (!isVisible_) {
1981         auto pointerAction = pointerEvent->GetPointerAction();
1982         if (pointerAction == OHOS::MMI::PointerEvent::POINTER_ACTION_UP ||
1983             pointerAction == OHOS::MMI::PointerEvent::POINTER_ACTION_PULL_UP ||
1984             pointerAction == OHOS::MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW ||
1985             pointerAction == OHOS::MMI::PointerEvent::POINTER_ACTION_CANCEL) {
1986             // still dispatch 'up' or 'cancel' event to finish this pointer event
1987             formManagerBridge_->DispatchPointerEvent(pointerEvent, serializedGesture);
1988         } else {
1989             TAG_LOGD(AceLogTag::ACE_FORM, "form invisible, not dispatch pointerEvent: %{public}d.", pointerAction);
1990         }
1991         return;
1992     }
1993     formManagerBridge_->DispatchPointerEvent(pointerEvent, serializedGesture);
1994 }
1995 
RemoveSubContainer()1996 void FormPattern::RemoveSubContainer()
1997 {
1998     auto host = GetHost();
1999     auto eventHub = host->GetOrCreateEventHub<FormEventHub>();
2000     if (eventHub) {
2001         eventHub->FireOnCache();
2002     }
2003     subContainer_.Reset();
2004 }
2005 
EnableDrag()2006 void FormPattern::EnableDrag()
2007 {
2008     auto host = GetHost();
2009     CHECK_NULL_VOID(host);
2010 
2011     auto dragStart = [weak = WeakClaim(this)](const RefPtr<OHOS::Ace::DragEvent>& event,
2012                          const std::string& /* extraParams */) -> DragDropInfo {
2013         DragDropInfo info;
2014 
2015         auto form = weak.Upgrade();
2016         CHECK_NULL_RETURN(form, info);
2017         auto subcontainer = form->GetSubContainer();
2018         CHECK_NULL_RETURN(subcontainer, info);
2019 
2020         RefPtr<UnifiedData> unifiedData = UdmfClient::GetInstance()->CreateUnifiedData();
2021         UdmfClient::GetInstance()->AddFormRecord(unifiedData, subcontainer->GetRunningCardId(), form->cardInfo_);
2022         event->SetData(unifiedData);
2023 
2024         info.extraInfo = "card drag";
2025         return info;
2026     };
2027     auto eventHub = GetHost()->GetOrCreateEventHub<EventHub>();
2028     CHECK_NULL_VOID(eventHub);
2029     eventHub->SetDefaultOnDragStart(std::move(dragStart));
2030 }
2031 
UpdateConfiguration()2032 void FormPattern::UpdateConfiguration()
2033 {
2034     auto localeTag = AceApplicationInfo::GetInstance().GetLocaleTag();
2035     if (localeTag != localeTag_ && subContainer_) {
2036         localeTag_ = localeTag;
2037         subContainer_->UpdateConfiguration();
2038     }
2039 }
2040 
OnLanguageConfigurationUpdate()2041 void FormPattern::OnLanguageConfigurationUpdate()
2042 {
2043     RefPtr<FrameNode> textNode = nullptr;
2044     std::string content;
2045     if (formSpecialStyle_.GetFormStyleAttribution() != FormStyleAttribution::PARENT_CONTROL) {
2046         GetResourceContent(APP_LOCKED_RESOURCE_NAME, content);
2047         textNode = GetFormChildNode(FormChildNodeType::APP_LOCKED_TEXT_NODE);
2048     } else {
2049         GetResourceContent(TIME_LIMIT_RESOURCE_NAME, content);
2050         textNode = GetFormChildNode(FormChildNodeType::TIME_LIMIT_TEXT_NODE);
2051     }
2052     CHECK_NULL_VOID(textNode);
2053     auto host = GetHost();
2054     CHECK_NULL_VOID(host);
2055     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
2056     CHECK_NULL_VOID(textLayoutProperty);
2057     textLayoutProperty->UpdateContent(content);
2058 
2059     Dimension fontSize(GetTimeLimitFontSize());
2060     if (!textLayoutProperty->GetFontSize().has_value() ||
2061         !NearEqual(textLayoutProperty->GetFontSize().value(), fontSize)) {
2062         textLayoutProperty->UpdateFontSize(fontSize);
2063     }
2064 }
2065 
GetResourceContent(std::string resourceName,std::string & content)2066 void FormPattern::GetResourceContent(std::string resourceName, std::string &content)
2067 {
2068     std::shared_ptr<Global::Resource::ResourceManager> sysResMgr(Global::Resource::CreateResourceManager());
2069     if (sysResMgr == nullptr) {
2070         TAG_LOGE(AceLogTag::ACE_FORM, "init sysMgr failed!");
2071         return;
2072     }
2073     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
2074     if (resConfig == nullptr) {
2075         TAG_LOGE(AceLogTag::ACE_FORM, "init resConfig failed!");
2076         return;
2077     }
2078 
2079     sysResMgr->GetResConfig(*resConfig);
2080     UErrorCode status = U_ZERO_ERROR;
2081     std::string language = Global::I18n::LocaleConfig::GetSystemLanguage();
2082     icu::Locale locale = icu::Locale::forLanguageTag(language, status);
2083     if (status != U_ZERO_ERROR) {
2084         TAG_LOGE(AceLogTag::ACE_FORM, "forLanguageTag failed, errCode:%{public}d", status);
2085         return;
2086     }
2087 
2088     resConfig->SetLocaleInfo(locale.getLanguage(), locale.getScript(), locale.getCountry());
2089     Global::Resource::RState state = sysResMgr->UpdateResConfig(*resConfig);
2090     if (state != Global::Resource::RState::SUCCESS) {
2091         TAG_LOGE(AceLogTag::ACE_FORM, "UpdateResConfig failed! errcode:%{public}d.", state);
2092         return;
2093     }
2094     sysResMgr->GetStringByName(resourceName.c_str(), content);
2095     isTibetanLanguage_ = language == "bo"? true : false;
2096 }
2097 
AddFormChildNode(FormChildNodeType formChildNodeType,const RefPtr<FrameNode> child)2098 void FormPattern::AddFormChildNode(FormChildNodeType formChildNodeType, const RefPtr<FrameNode> child)
2099 {
2100     auto iter = formChildrenNodeMap_.find(formChildNodeType);
2101     if (iter == formChildrenNodeMap_.end()) {
2102         formChildrenNodeMap_.insert(std::make_pair(formChildNodeType, child));
2103     } else {
2104         formChildrenNodeMap_[formChildNodeType] = child;
2105     }
2106 }
2107 
RemoveFormChildNode(FormChildNodeType formChildNodeType)2108 void FormPattern::RemoveFormChildNode(FormChildNodeType formChildNodeType)
2109 {
2110     RefPtr<FrameNode> childNode = GetFormChildNode(formChildNodeType);
2111     CHECK_NULL_VOID(childNode);
2112 
2113     ContainerScope scope(scopeId_);
2114     auto host = GetHost();
2115     CHECK_NULL_VOID(host);
2116     auto renderContext = host->GetRenderContext();
2117     if (renderContext == nullptr) {
2118         TAG_LOGE(AceLogTag::ACE_FORM, "Remove child node: %{public}d failed, null context.",
2119             formChildNodeType);
2120         return;
2121     }
2122     renderContext->RemoveChild(childNode->GetRenderContext());
2123 
2124     if (formChildNodeType == FormChildNodeType::FORM_STATIC_IMAGE_NODE) {
2125         auto formNode = DynamicCast<FormNode>(host);
2126         auto subContainer = GetSubContainer();
2127         if (subContainer != nullptr && formNode != nullptr) {
2128             auto imageId = formNode->GetImageId();
2129             auto formId = subContainer->GetRunningCardId();
2130             TAG_LOGI(AceLogTag::ACE_FORM, "RemoveImageNode imageId: %{public}d, formId: %{public}" PRId64,
2131                 imageId, formId);
2132         }
2133     }
2134     host->RemoveChild(childNode);
2135     TAG_LOGI(AceLogTag::ACE_FORM, "Remove child node: %{public}d sucessfully.",
2136         formChildNodeType);
2137     formChildrenNodeMap_.erase(formChildNodeType);
2138     host->MarkModifyDone();
2139     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2140 }
2141 
GetFormChildNode(FormChildNodeType formChildNodeType) const2142 RefPtr<FrameNode> FormPattern::GetFormChildNode(FormChildNodeType formChildNodeType) const
2143 {
2144     auto iter = formChildrenNodeMap_.find(formChildNodeType);
2145     if (iter == formChildrenNodeMap_.end()) {
2146         return nullptr;
2147     }
2148 
2149     return iter->second;
2150 }
2151 
GetTimeLimitFontSize()2152 double FormPattern::GetTimeLimitFontSize()
2153 {
2154     float fontScale = SystemProperties::GetFontScale();
2155     if (fontScale > MAX_FONT_SCALE) {
2156         fontScale = MAX_FONT_SCALE;
2157     }
2158     double density = PipelineBase::GetCurrentDensity();
2159     TAG_LOGD(AceLogTag::ACE_FORM, "Density is %{public}f, font scale is %{public}f.",
2160         density, fontScale);
2161 
2162     int32_t dimensionHeight = GetFormDimensionHeight(cardInfo_.dimension);
2163     if (dimensionHeight == FORM_DIMENSION_MIN_HEIGHT) {
2164         if (isTibetanLanguage_) {
2165             return TIBETAN_TIME_LIMIT_FONT_SIZE_BASE * density * fontScale;
2166         }
2167         return ONE_DIMENSION_TIME_LIMIT_FONT_SIZE_BASE * density * fontScale;
2168     } else {
2169         return TIME_LIMIT_FONT_SIZE_BASE * density * fontScale;
2170     }
2171 }
2172 
IsMaskEnableForm(const RequestFormInfo & info)2173 bool FormPattern::IsMaskEnableForm(const RequestFormInfo& info)
2174 {
2175 #ifdef ARKUI_WEARABLE
2176     return false;
2177 #else
2178     return info.shape == FORM_SHAPE_CIRCLE || info.renderingMode ==
2179         static_cast<int32_t>(OHOS::AppExecFwk::Constants::RenderingMode::SINGLE_COLOR) ||
2180         info.dimension == static_cast<int32_t>(OHOS::AppExecFwk::Constants::Dimension::DIMENSION_1_1);
2181 #endif
2182 }
2183 
UpdateChildNodeOpacity(FormChildNodeType formChildNodeType,double opacity)2184 void FormPattern::UpdateChildNodeOpacity(FormChildNodeType formChildNodeType, double opacity)
2185 {
2186     TAG_LOGI(AceLogTag::ACE_FORM, "formChildNodeType: %{public}d, opacity: %{public}f.",
2187         static_cast<int32_t>(formChildNodeType), opacity);
2188     if (formChildNodeType == FormChildNodeType::FORM_SURFACE_NODE) {
2189         auto externalRenderContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
2190         CHECK_NULL_VOID(externalRenderContext);
2191         externalRenderContext->OnOpacityUpdate(opacity);
2192     } else if (formChildNodeType == FormChildNodeType::FORM_STATIC_IMAGE_NODE ||
2193         formChildNodeType == FormChildNodeType::FORM_SKELETON_NODE) {
2194         auto childNode = GetFormChildNode(formChildNodeType);
2195         CHECK_NULL_VOID(childNode);
2196         auto renderContext = DynamicCast<NG::RosenRenderContext>(childNode->GetRenderContext());
2197         CHECK_NULL_VOID(renderContext);
2198         renderContext->OnOpacityUpdate(opacity);
2199     }
2200 }
2201 
UnregisterAccessibility()2202 void FormPattern::UnregisterAccessibility()
2203 {
2204     auto host = GetHost();
2205     CHECK_NULL_VOID(host);
2206     auto formNode = DynamicCast<FormNode>(host);
2207     CHECK_NULL_VOID(formNode);
2208     formNode->ClearAccessibilityChildTreeRegisterFlag();
2209 }
2210 
CheckFormBundleForbidden(const std::string & bundleName)2211 bool FormPattern::CheckFormBundleForbidden(const std::string &bundleName)
2212 {
2213     CHECK_NULL_RETURN(formManagerBridge_, false);
2214     return formManagerBridge_->CheckFormBundleForbidden(bundleName);
2215 }
2216 
DelayResetManuallyClickFlag()2217 void FormPattern::DelayResetManuallyClickFlag()
2218 {
2219     auto host = GetHost();
2220     CHECK_NULL_VOID(host);
2221     auto context = host->GetContext();
2222     CHECK_NULL_VOID(context);
2223     auto executor = context->GetTaskExecutor();
2224     CHECK_NULL_VOID(executor);
2225     std::string nodeIdStr = std::to_string(host->GetId());
2226     executor->RemoveTask(TaskExecutor::TaskType::UI, std::string("ArkUIFormResetManuallyClickFlag").append(nodeIdStr));
2227     executor->PostDelayedTask(
2228         [weak = WeakClaim(this)] {
2229             auto pattern = weak.Upgrade();
2230             CHECK_NULL_VOID(pattern);
2231             pattern->isManuallyClick_ = false;
2232         },
2233         TaskExecutor::TaskType::UI, DELAY_TIME_FOR_RESET_MANUALLY_CLICK_FLAG,
2234         std::string("ArkUIFormResetManuallyClickFlag").append(nodeIdStr));
2235 }
2236 
RemoveDelayResetManuallyClickFlagTask()2237 void FormPattern::RemoveDelayResetManuallyClickFlagTask()
2238 {
2239     auto host = GetHost();
2240     CHECK_NULL_VOID(host);
2241     auto context = host->GetContext();
2242     CHECK_NULL_VOID(context);
2243     auto executor = context->GetTaskExecutor();
2244     CHECK_NULL_VOID(executor);
2245     std::string nodeIdStr = std::to_string(host->GetId());
2246     executor->RemoveTask(TaskExecutor::TaskType::UI, std::string("ArkUIFormResetManuallyClickFlag").append(nodeIdStr));
2247 }
2248 
SetTransparencyConfig(bool isTransparencyForm,const RequestFormInfo & info)2249 void FormPattern::SetTransparencyConfig(bool isTransparencyForm, const RequestFormInfo& info)
2250 {
2251     if (!isTransparencyForm) {
2252         isTransparencyEnable_ = false;
2253         return;
2254     }
2255     auto wantWrap = info.wantWrap;
2256     if (wantWrap) {
2257         auto color = wantWrap->GetWant().GetStringParam(OHOS::AppExecFwk::Constants::PARAM_FORM_TRANSPARENCY_KEY);
2258         Color bgColor;
2259         if (Color::ParseColorString(color, bgColor) && bgColor == Color::TRANSPARENT) {
2260             TAG_LOGD(AceLogTag::ACE_FORM, "Parse color, bg color: %{public}s.", color.c_str());
2261             isTransparencyEnable_ = true;
2262         }
2263     }
2264 }
2265 
SetSkeletonEnableConfig(const RequestFormInfo & info)2266 void FormPattern::SetSkeletonEnableConfig(const RequestFormInfo &info)
2267 {
2268     auto wantWrap = info.wantWrap;
2269     if (wantWrap) {
2270         isSkeletonAnimEnable_ = wantWrap->GetWant().GetBoolParam(
2271             OHOS::AppExecFwk::Constants::FORM_ENABLE_SKELETON_KEY, false);
2272         TAG_LOGI(AceLogTag::ACE_FORM, "FORM_ENABLE_SKELETON_KEY: %{public}d.", isSkeletonAnimEnable_);
2273     }
2274 }
2275 
SetExternalRenderOpacity(double opacity)2276 void FormPattern::SetExternalRenderOpacity(double opacity)
2277 {
2278     auto externalRenderContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
2279     CHECK_NULL_VOID(externalRenderContext);
2280     externalRenderContext->SetOpacity(opacity);
2281 }
2282 
ShouldDoSkeletonAnimation()2283 bool FormPattern::ShouldDoSkeletonAnimation()
2284 {
2285     auto host = GetHost();
2286     CHECK_NULL_RETURN(host, false);
2287     std::list<RefPtr<UINode>> children = host->GetChildren();
2288     if (children.size() <= 0) {
2289         TAG_LOGE(AceLogTag::ACE_FORM, "Cur form component's children is empty.");
2290         return false;
2291     }
2292 
2293     auto skeletonNode = GetFormChildNode(FormChildNodeType::FORM_SKELETON_NODE);
2294     if (skeletonNode == nullptr) {
2295          TAG_LOGE(AceLogTag::ACE_FORM, "Cur form component's has no skeleton.");
2296         return false;
2297     }
2298     std::string lastChildTag = skeletonNode->GetTag();
2299     if (lastChildTag != V2::COLUMN_ETS_TAG) {
2300         TAG_LOGE(AceLogTag::ACE_FORM, "Cur form component's last child is not skeleton.");
2301         return false;
2302     }
2303     return true;
2304 }
2305 
DoSkeletonAnimation()2306 void FormPattern::DoSkeletonAnimation()
2307 {
2308     ACE_FUNCTION_TRACE();
2309     TAG_LOGD(AceLogTag::ACE_FORM, "DoSkeletonAnimation");
2310     ContainerScope scope(scopeId_);
2311     auto host = GetHost();
2312     CHECK_NULL_VOID(host);
2313     auto skeletonNode = GetFormChildNode(FormChildNodeType::FORM_SKELETON_NODE);
2314     if (!ShouldDoSkeletonAnimation()) {
2315         TAG_LOGE(AceLogTag::ACE_FORM, "should not do skeleton anim");
2316         SetExternalRenderOpacity(NON_TRANSPARENT_VAL);
2317         return;
2318     }
2319 
2320     std::function<void()> finishCallback = [weak = WeakClaim(this)]() {
2321         auto pattern = weak.Upgrade();
2322         CHECK_NULL_VOID(pattern);
2323         pattern->RemoveFormChildNode(FormChildNodeType::FORM_SKELETON_NODE);
2324         TAG_LOGD(AceLogTag::ACE_FORM, "DoSkeletonAnimation finishCallBack");
2325     };
2326 
2327     auto context = PipelineContext::GetCurrentContext();
2328     CHECK_NULL_VOID(context);
2329     AnimationOption option = AnimationOption();
2330     option.SetDuration(FORM_UNLOCK_ANIMATION_DUATION);
2331     option.SetCurve(Curves::FRICTION);
2332     AnimationOption optionAlpha = AnimationOption();
2333     optionAlpha.SetCurve(Curves::SHARP);
2334 
2335     context->OpenImplicitAnimation(option, option.GetCurve(), finishCallback);
2336     host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2337     context->FlushUITasks();
2338 
2339     optionAlpha.SetDuration(FORM_UNLOCK_ANIMATION_DUATION);
2340     auto externalRenderContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
2341     CHECK_NULL_VOID(externalRenderContext);
2342     externalRenderContext->OpacityAnimation(optionAlpha, 0, 1);
2343 
2344     auto lastFrameChild = AceType::DynamicCast<FrameNode>(skeletonNode);
2345     CHECK_NULL_VOID(lastFrameChild);
2346     RefPtr<OHOS::Ace::NG::RenderContext> childRenderContext = lastFrameChild->GetRenderContext();
2347     CHECK_NULL_VOID(childRenderContext);
2348     childRenderContext->OpacityAnimation(optionAlpha, 1, 0);
2349     context->CloseImplicitAnimation();
2350 }
2351 
UpdateFormBaseConfig(bool isDynamic)2352 void FormPattern::UpdateFormBaseConfig(bool isDynamic)
2353 {
2354     auto host = GetHost();
2355     CHECK_NULL_VOID(host);
2356     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
2357     CHECK_NULL_VOID(layoutProperty);
2358     auto visible = layoutProperty->GetVisibleType().value_or(VisibleType::VISIBLE);
2359     TAG_LOGI(AceLogTag::ACE_FORM, "VisibleType: %{public}d, isDynamic: %{public}d",
2360         static_cast<int32_t>(visible), isDynamic);
2361     layoutProperty->UpdateVisibility(visible);
2362     isLoaded_ = true;
2363     isUnTrust_ = false;
2364     isFrsNodeDetached_ = false;
2365     isDynamic_ = isDynamic;
2366 }
2367 
InitAddFormUpdateAndErrorCallback(int32_t instanceID)2368 void FormPattern::InitAddFormUpdateAndErrorCallback(int32_t instanceID)
2369 {
2370     auto host = GetHost();
2371     CHECK_NULL_VOID(host);
2372     auto pipeline = host->GetContext();
2373 
2374     formManagerBridge_->AddFormUpdateCallback(
2375         [weak = WeakClaim(this), instanceID, pipeline](int64_t id, const std::string& data,
2376             const std::map<std::string, sptr<AppExecFwk::FormAshmem>>& imageDataMap) {
2377             ContainerScope scope(instanceID);
2378             CHECK_NULL_VOID(pipeline);
2379             auto uiTaskExecutor = SingleTaskExecutor::Make(pipeline->GetTaskExecutor(), TaskExecutor::TaskType::UI);
2380             uiTaskExecutor.PostTask(
2381                 [id, data, imageDataMap, weak, instanceID] {
2382                     ContainerScope scope(instanceID);
2383                     auto form = weak.Upgrade();
2384                     CHECK_NULL_VOID(form);
2385                     if (form->ISAllowUpdate()) {
2386                         form->GetSubContainer()->UpdateCard(data, imageDataMap);
2387                     }
2388                 },
2389                 "ArkUIFormUpdateCard");
2390         });
2391 
2392     formManagerBridge_->AddFormErrorCallback(
2393         [weak = WeakClaim(this), instanceID, pipeline](const std::string& code, const std::string& msg) {
2394             ContainerScope scope(instanceID);
2395             CHECK_NULL_VOID(pipeline);
2396             auto uiTaskExecutor = SingleTaskExecutor::Make(pipeline->GetTaskExecutor(), TaskExecutor::TaskType::UI);
2397             uiTaskExecutor.PostTask(
2398                 [code, msg, weak, instanceID] {
2399                     ContainerScope scope(instanceID);
2400                     auto form = weak.Upgrade();
2401                     CHECK_NULL_VOID(form);
2402                     form->FireOnErrorEvent(code, msg);
2403                 },
2404                 "ArkUIFormFireErrorEvent");
2405         });
2406 }
2407 
2408 
InitAddUninstallAndSurfaceNodeCallback(int32_t instanceID)2409 void FormPattern::InitAddUninstallAndSurfaceNodeCallback(int32_t instanceID)
2410 {
2411     auto host = GetHost();
2412     CHECK_NULL_VOID(host);
2413     auto pipeline = host->GetContext();
2414     formManagerBridge_->AddFormUninstallCallback([weak = WeakClaim(this), instanceID, pipeline](int64_t formId) {
2415         ContainerScope scope(instanceID);
2416         CHECK_NULL_VOID(pipeline);
2417         auto uiTaskExecutor = SingleTaskExecutor::Make(pipeline->GetTaskExecutor(), TaskExecutor::TaskType::UI);
2418         uiTaskExecutor.PostTask(
2419             [formId, weak, instanceID] {
2420                 ContainerScope scope(instanceID);
2421                 auto form = weak.Upgrade();
2422                 CHECK_NULL_VOID(form);
2423                 form->FireOnUninstallEvent(formId);
2424             },
2425             "ArkUIFormFireUninstallEvent");
2426     });
2427 
2428     formManagerBridge_->AddFormSurfaceNodeCallback(
2429         [weak = WeakClaim(this), instanceID](
2430             const std::shared_ptr<Rosen::RSSurfaceNode>& node, const AAFwk::Want& want) {
2431             ContainerScope scope(instanceID);
2432             auto pipeline = PipelineContext::GetCurrentContext();
2433             CHECK_NULL_VOID(pipeline);
2434             auto executor = pipeline->GetTaskExecutor();
2435             CHECK_NULL_VOID(executor);
2436             auto uiTaskExecutor = SingleTaskExecutor::Make(executor, TaskExecutor::TaskType::UI);
2437             uiTaskExecutor.PostTask(
2438                 [weak, instanceID, node, want] {
2439                     ContainerScope scope(instanceID);
2440                     auto form = weak.Upgrade();
2441                     CHECK_NULL_VOID(form);
2442                     form->FireFormSurfaceNodeCallback(node, want);
2443                 },
2444                 "ArkUIFormFireSurfaceNodeCallback");
2445         });
2446 }
2447 
InitAddFormSurfaceChangeAndDetachCallback(int32_t instanceID)2448 void FormPattern::InitAddFormSurfaceChangeAndDetachCallback(int32_t instanceID)
2449 {
2450     auto host = GetHost();
2451     CHECK_NULL_VOID(host);
2452     auto pipeline = host->GetContext();
2453 
2454     formManagerBridge_->AddFormSurfaceChangeCallback(
2455         [weak = WeakClaim(this), instanceID, pipeline](float width, float height, float borderWidth) {
2456             ContainerScope scope(instanceID);
2457             CHECK_NULL_VOID(pipeline);
2458             auto uiTaskExecutor = SingleTaskExecutor::Make(pipeline->GetTaskExecutor(), TaskExecutor::TaskType::UI);
2459             uiTaskExecutor.PostTask(
2460                 [weak, instanceID, width, height, borderWidth] {
2461                     ContainerScope scope(instanceID);
2462                     auto form = weak.Upgrade();
2463                     CHECK_NULL_VOID(form);
2464                     form->FireFormSurfaceChangeCallback(width, height, borderWidth);
2465                 },
2466                 "ArkUIFormFireSurfaceChange");
2467         });
2468 
2469     formManagerBridge_->AddFormSurfaceDetachCallback([weak = WeakClaim(this), instanceID]() {
2470         ContainerScope scope(instanceID);
2471         auto formPattern = weak.Upgrade();
2472         CHECK_NULL_VOID(formPattern);
2473         formPattern->FireFormSurfaceDetachCallback();
2474     });
2475 
2476     formManagerBridge_->AddActionEventHandle([weak = WeakClaim(this), instanceID](const std::string& action) {
2477         ContainerScope scope(instanceID);
2478         TAG_LOGI(AceLogTag::ACE_FORM, "Card receive action event, action: %{public}zu", action.length());
2479         auto formPattern = weak.Upgrade();
2480         CHECK_NULL_VOID(formPattern);
2481         formPattern->OnActionEvent(action);
2482     });
2483 }
2484 
InitAddUnTrustAndSnapshotCallback(int32_t instanceID)2485 void FormPattern::InitAddUnTrustAndSnapshotCallback(int32_t instanceID)
2486 {
2487     auto host = GetHost();
2488     CHECK_NULL_VOID(host);
2489     auto pipeline = host->GetContext();
2490     formManagerBridge_->AddUnTrustFormCallback([weak = WeakClaim(this), instanceID, pipeline]() {
2491         ContainerScope scope(instanceID);
2492         CHECK_NULL_VOID(pipeline);
2493         auto uiTaskExecutor = SingleTaskExecutor::Make(pipeline->GetTaskExecutor(), TaskExecutor::TaskType::UI);
2494         uiTaskExecutor.PostTask(
2495             [weak, instanceID] {
2496                 ContainerScope scope(instanceID);
2497                 auto formPattern = weak.Upgrade();
2498                 CHECK_NULL_VOID(formPattern);
2499                 formPattern->HandleUnTrustForm();
2500             },
2501             "ArkUIFormHandleUnTrust");
2502     });
2503 
2504     formManagerBridge_->AddSnapshotCallback([weak = WeakClaim(this), instanceID](const uint32_t& delayTime) {
2505         ContainerScope scope(instanceID);
2506         auto formPattern = weak.Upgrade();
2507         CHECK_NULL_VOID(formPattern);
2508         auto host = formPattern->GetHost();
2509         CHECK_NULL_VOID(host);
2510         std::string nodeIdStr = std::to_string(host->GetId());
2511         formPattern->HandleSnapshot(delayTime, nodeIdStr);
2512     });
2513 
2514     formManagerBridge_->AddFormLinkInfoUpdateCallback(
2515         [weak = WeakClaim(this), instanceID](const std::vector<std::string>& infos) {
2516             ContainerScope scope(instanceID);
2517             auto formPattern = weak.Upgrade();
2518             CHECK_NULL_VOID(formPattern);
2519             formPattern->SetFormLinkInfos(infos);
2520         });
2521 }
2522 
2523 
InitOtherCallback(int32_t instanceID)2524 void FormPattern::InitOtherCallback(int32_t instanceID)
2525 {
2526     auto host = GetHost();
2527     CHECK_NULL_VOID(host);
2528     auto pipeline = host->GetContext();
2529     formManagerBridge_->AddGetRectRelativeToWindowCallback(
2530         [weak = WeakClaim(this), instanceID](AccessibilityParentRectInfo& parentRectInfo) {
2531             ContainerScope scope(instanceID);
2532             auto context = PipelineContext::GetCurrentContextSafely();
2533             CHECK_NULL_VOID(context);
2534             auto uiTaskExecutor =
2535                 SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
2536             uiTaskExecutor.PostSyncTask([weak, instanceID, &parentRectInfo] {
2537                 ContainerScope scope(instanceID);
2538                 auto form = weak.Upgrade();
2539                 CHECK_NULL_VOID(form);
2540                 form->GetRectRelativeToWindow(parentRectInfo);
2541                 }, "ArkUIFormGetRectRelativeToWindow");
2542         });
2543 
2544     formManagerBridge_->AddEnableFormCallback([weak = WeakClaim(this), instanceID, pipeline](const bool enable) {
2545         ContainerScope scope(instanceID);
2546         CHECK_NULL_VOID(pipeline);
2547         auto uiTaskExecutor =
2548             SingleTaskExecutor::Make(pipeline->GetTaskExecutor(), TaskExecutor::TaskType::UI);
2549         uiTaskExecutor.PostTask([weak, instanceID, enable] {
2550             ContainerScope scope(instanceID);
2551             auto formPattern = weak.Upgrade();
2552             CHECK_NULL_VOID(formPattern);
2553             formPattern->HandleEnableForm(enable);
2554             }, "ArkUIFormHandleEnableForm");
2555         });
2556 
2557     formManagerBridge_->AddLockFormCallback([weak = WeakClaim(this), instanceID, pipeline](const bool lock) {
2558         ContainerScope scope(instanceID);
2559         CHECK_NULL_VOID(pipeline);
2560         auto uiTaskExecutor =
2561             SingleTaskExecutor::Make(pipeline->GetTaskExecutor(), TaskExecutor::TaskType::UI);
2562         uiTaskExecutor.PostTask([weak, instanceID, lock] {
2563             ContainerScope scope(instanceID);
2564             auto formPattern = weak.Upgrade();
2565             CHECK_NULL_VOID(formPattern);
2566             formPattern->HandleLockEvent(lock);
2567             }, "ArkUIFormHandleLockForm");
2568         });
2569 }
2570 
InitUpdateFormDoneCallback(int32_t instanceID)2571 void FormPattern::InitUpdateFormDoneCallback(int32_t instanceID)
2572 {
2573     auto host = GetHost();
2574     CHECK_NULL_VOID(host);
2575     auto pipeline = host->GetContext();
2576     formManagerBridge_->AddFormUpdateDoneCallback([weak = WeakClaim(this), instanceID, pipeline](const int64_t formId) {
2577         ContainerScope scope(instanceID);
2578         CHECK_NULL_VOID(pipeline);
2579         auto uiTaskExecutor =
2580             SingleTaskExecutor::Make(pipeline->GetTaskExecutor(), TaskExecutor::TaskType::UI);
2581         uiTaskExecutor.PostTask([formId, weak, instanceID] {
2582             ContainerScope scope(instanceID);
2583             auto formPattern = weak.Upgrade();
2584             CHECK_NULL_VOID(formPattern);
2585             formPattern->FireOnUpdateFormDone(formId);
2586             }, "ArkUIFormFireUpdateDoneEvent");
2587     });
2588 }
2589 
enhancesSubContainer(bool hasContainer)2590 void FormPattern::enhancesSubContainer(bool hasContainer)
2591 {
2592     CHECK_NULL_VOID(subContainer_);
2593     auto host = GetHost();
2594     CHECK_NULL_VOID(host);
2595     auto context = host->GetContextRefPtr();
2596     CHECK_NULL_VOID(context);
2597     auto pipeline = host->GetContext();
2598     CHECK_NULL_VOID(pipeline);
2599     auto layoutProperty = host->GetLayoutProperty<FormLayoutProperty>();
2600     CHECK_NULL_VOID(layoutProperty);
2601 
2602     subContainer_->SetFormPattern(WeakClaim(this));
2603     subContainer_->Initialize();
2604     subContainer_->SetNodeId(host->GetId());
2605 
2606     subContainer_->AddFormAcquireCallback([weak = WeakClaim(this), pipeline](int64_t id) {
2607         CHECK_NULL_VOID(pipeline);
2608         auto uiTaskExecutor =
2609             SingleTaskExecutor::Make(pipeline->GetTaskExecutor(), TaskExecutor::TaskType::UI);
2610         uiTaskExecutor.PostTask([id, weak] {
2611             auto pattern = weak.Upgrade();
2612             CHECK_NULL_VOID(pattern);
2613             pattern->FireOnAcquiredEvent(id);
2614             }, "ArkUIFormFireAcquiredEvent");
2615     });
2616 
2617     subContainer_->SetFormLoadCallback([weak = WeakClaim(this)]() {
2618         auto pattern = weak.Upgrade();
2619         CHECK_NULL_VOID(pattern);
2620         pattern->OnLoadEvent();
2621     });
2622 
2623     subContainer_->AddFormVisiableCallback([weak = WeakClaim(this), layoutProperty]() {
2624         auto pattern = weak.Upgrade();
2625         CHECK_NULL_VOID(pattern);
2626         CHECK_NULL_VOID(layoutProperty);
2627         auto visible = layoutProperty->GetVisibleType().value_or(VisibleType::VISIBLE);
2628         layoutProperty->UpdateVisibility(visible);
2629         pattern->isLoaded_ = true;
2630     });
2631 
2632     if (hasContainer) {
2633         subContainer_->RunSameCard();
2634     }
2635 }
2636 
ShouldAddChildAtReuildFrame()2637 bool FormPattern::ShouldAddChildAtReuildFrame()
2638 {
2639     auto externalRenderContext = DynamicCast<NG::RosenRenderContext>(GetExternalRenderContext());
2640     CHECK_NULL_RETURN(externalRenderContext, true);
2641     auto externalRsNode = externalRenderContext->GetRSNode();
2642     if (externalRsNode) {
2643         auto externalParentRsNode = externalRsNode->GetParent();
2644         if (externalParentRsNode) {
2645             uint32_t externalParentRsNodeId = externalParentRsNode->GetId();
2646             TAG_LOGW(AceLogTag::ACE_FORM, "external Parent RsNode Id:%{public}d", externalParentRsNodeId);
2647             if (externalParentRsNodeId != 0) {
2648                 return false;
2649             }
2650         }
2651     } else {
2652         TAG_LOGW(AceLogTag::ACE_FORM, "external RsNode is null");
2653     }
2654     return true;
2655 }
2656 
GetFormDumpInfo(std::vector<std::string> & dumpInfo)2657 bool FormPattern::GetFormDumpInfo(std::vector<std::string> &dumpInfo)
2658 {
2659     ACE_FUNCTION_TRACE();
2660     TAG_LOGI(AceLogTag::ACE_FORM, "dump form info in string format");
2661     if (formManagerBridge_ == nullptr) {
2662         TAG_LOGE(AceLogTag::ACE_FORM, "formManagerBridge_ is null");
2663         return false;
2664     }
2665 
2666     auto container = Platform::AceContainer::GetContainer(Container::CurrentId());
2667     if (!container) {
2668         TAG_LOGE(AceLogTag::ACE_FORM, "container is null");
2669         return false;
2670     }
2671     std::vector<std::string> params = container->GetUieParams();
2672     // Use -noform to choose not dump form info
2673     if (std::find(params.begin(), params.end(), NO_FORM_DUMP) != params.end()) {
2674         TAG_LOGE(AceLogTag::ACE_FORM, "Not Support Dump Form Info");
2675         return false;
2676     }
2677     auto host = GetHost();
2678     CHECK_NULL_RETURN(host, false);
2679     auto dumpNodeIter = std::find(params.begin(), params.end(), std::to_string(host->GetId()));
2680     if (dumpNodeIter != params.end()) {
2681         params.erase(dumpNodeIter);
2682     }
2683     if (!container->IsFormRender()) {
2684         params.push_back(PID_FLAG);
2685     }
2686     params.push_back(std::to_string(getpid()));
2687     formManagerBridge_->NotifyFormDump(params, dumpInfo);
2688     return true;
2689 }
2690 
DumpInfo()2691 void FormPattern::DumpInfo()
2692 {
2693     std::vector<std::string> dumpInfo;
2694     if (!GetFormDumpInfo(dumpInfo)) {
2695         return;
2696     }
2697     for (const std::string& info : dumpInfo) {
2698         DumpLog::GetInstance().AddDesc("Form info: ", info);
2699     }
2700 }
2701 
DumpInfo(std::unique_ptr<JsonValue> & json)2702 void FormPattern::DumpInfo(std::unique_ptr<JsonValue>& json)
2703 {
2704     std::vector<std::string> dumpInfo;
2705     if (!GetFormDumpInfo(dumpInfo)) {
2706         return;
2707     }
2708     for (const std::string& info : dumpInfo) {
2709         json->Put("Form info: ", info.c_str());
2710     }
2711 }
2712 
IsFormBundleExempt(int64_t formId) const2713 bool FormPattern::IsFormBundleExempt(int64_t formId) const
2714 {
2715     CHECK_NULL_RETURN(formManagerBridge_, false);
2716     return formManagerBridge_->IsFormBundleExempt(formId);
2717 }
2718 
IsFormBundleProtected(const std::string & bundleName,int64_t formId) const2719 bool FormPattern::IsFormBundleProtected(const std::string& bundleName, int64_t formId) const
2720 {
2721     CHECK_NULL_RETURN(formManagerBridge_, false);
2722     return formManagerBridge_->IsFormBundleProtected(bundleName, formId);
2723 }
2724 
HandleLockEvent(bool isLock)2725 void FormPattern::HandleLockEvent(bool isLock)
2726 {
2727     if (cardInfo_.exemptAppLock) {
2728         TAG_LOGW(AceLogTag::ACE_FORM, "Is funInteraction form, no need continue.");
2729         return;
2730     }
2731     auto newFormSpecialStyle = formSpecialStyle_;
2732     newFormSpecialStyle.SetIsLockedByAppLock(isLock);
2733     HandleFormStyleOperation(newFormSpecialStyle);
2734 }
2735 
HandleFormStyleOperation(const FormSpecialStyle & newFormSpecialStyle,const RequestFormInfo & info)2736 void FormPattern::HandleFormStyleOperation(const FormSpecialStyle& newFormSpecialStyle, const RequestFormInfo& info)
2737 {
2738     auto formOperation = formSpecialStyle_.GetOperationToNewFormStyle(newFormSpecialStyle);
2739     TAG_LOGW(AceLogTag::ACE_FORM, "HandleFormStyleOperation formSpecialStyle_:%{public}d, new:%{public}d,",
2740         static_cast<int32_t>(formSpecialStyle_.GetFormStyleAttribution()),
2741         static_cast<int32_t>(newFormSpecialStyle.GetFormStyleAttribution()));
2742     formSpecialStyle_ = newFormSpecialStyle;
2743     switch (formOperation) {
2744         case FormOperation::KEEP:
2745             TAG_LOGI(AceLogTag::ACE_FORM, "KEEP");
2746             return;
2747         case FormOperation::UNLOAD:
2748             TAG_LOGI(AceLogTag::ACE_FORM, "UNLOAD");
2749             RemoveDisableFormStyle(info);
2750             break;
2751         case FormOperation::LOAD:
2752             TAG_LOGI(AceLogTag::ACE_FORM, "LOAD");
2753             LoadDisableFormStyle(info);
2754             break;
2755         case FormOperation::REFRESH:
2756             TAG_LOGI(AceLogTag::ACE_FORM, "REFRESH");
2757             LoadDisableFormStyle(info, true);
2758     }
2759 }
2760 
HandleFormStyleOperation(const FormSpecialStyle & newFormSpecialStyle)2761 void FormPattern::HandleFormStyleOperation(const FormSpecialStyle& newFormSpecialStyle)
2762 {
2763   HandleFormStyleOperation(newFormSpecialStyle, cardInfo_);
2764 }
2765 
UpdateForbiddenRootNodeStyle(const RefPtr<RenderContext> & renderContext)2766 void FormPattern::UpdateForbiddenRootNodeStyle(const RefPtr<RenderContext> &renderContext)
2767 {
2768     auto context = GetContext();
2769     CHECK_NULL_VOID(context);
2770 
2771     Color colorStyle = context->GetColorMode() == ColorMode::DARK ?
2772         Color(ROOT_BG_COLOR_DARK) : Color(ROOT_BG_COLOR_LIGHT);
2773     renderContext->UpdateBackgroundColor(colorStyle);
2774 }
2775 
ReAddStaticFormSnapshotTimer()2776 void FormPattern::ReAddStaticFormSnapshotTimer()
2777 {
2778     if (isDynamic_) {
2779         return;
2780     }
2781 
2782     int64_t currentTime = GetCurrentTimestamp();
2783     if (updateFormComponentTimestamp_ == 0 || !isStaticFormSnaping_) {
2784         updateFormComponentTimestamp_ = currentTime;
2785         return;
2786     }
2787 
2788     if (currentTime - updateFormComponentTimestamp_ < FORM_COMPONENT_UPDATE_VALID_DURATION) {
2789         return;
2790     }
2791 
2792     updateFormComponentTimestamp_ = currentTime;
2793     TAG_LOGI(AceLogTag::ACE_FORM, "ReAddStaticFormSnapshotTimer.");
2794     auto host = GetHost();
2795     CHECK_NULL_VOID(host);
2796     auto pipeline = PipelineContext::GetCurrentContext();
2797     CHECK_NULL_VOID(pipeline);
2798     auto executor = pipeline->GetTaskExecutor();
2799     CHECK_NULL_VOID(executor);
2800     std::string nodeIdStr = std::to_string(host->GetId());
2801     executor->RemoveTask(TaskExecutor::TaskType::UI, "ArkUIFormTakeSurfaceCapture_" + nodeIdStr);
2802     HandleSnapshot(DELAY_TIME_FOR_FORM_SNAPSHOT_10S, nodeIdStr);
2803 }
2804 
FireOnUpdateFormDone(int64_t id) const2805 void FormPattern::FireOnUpdateFormDone(int64_t id) const
2806 {
2807     TAG_LOGD(AceLogTag::ACE_FORM, "fire form update done:%{public}" PRId64, id);
2808     auto host = GetHost();
2809     CHECK_NULL_VOID(host);
2810     auto eventHub = host->GetOrCreateEventHub<FormEventHub>();
2811     CHECK_NULL_VOID(eventHub);
2812     int64_t onUpdateFormId = id < MAX_NUMBER_OF_JS ? id : -1;
2813     auto json = JsonUtil::Create(true);
2814     json->Put("id", std::to_string(onUpdateFormId).c_str());
2815     json->Put("idString", std::to_string(id).c_str());
2816     eventHub->FireOnUpdate(json->ToString());
2817 }
2818 
GetRSUIContext()2819 void FormPattern::GetRSUIContext()
2820 {
2821     auto host = GetHost();
2822     CHECK_NULL_VOID(host);
2823     NG::PipelineContext* pipeline = host->GetContext();
2824     if (!pipeline) {
2825         TAG_LOGE(AceLogTag::ACE_FORM, "FormPattern: pipeline is nullptr");
2826         return;
2827     }
2828     std::shared_ptr<Rosen::RSUIDirector> rsUIDirector = pipeline->GetRSUIDirector();
2829     if (!rsUIDirector) {
2830         TAG_LOGE(AceLogTag::ACE_FORM, "FormPattern: rsUIDirector is nullptr");
2831         return;
2832     }
2833     rsUIContext_ = rsUIDirector->GetRSUIContext();
2834     if (!rsUIContext_) {
2835         TAG_LOGE(AceLogTag::ACE_FORM, "FormPattern: rsUIContext_ is nullptr");
2836     }
2837 }
2838 } // namespace OHOS::Ace::NG
2839