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