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