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