1 /*
2  * Copyright (c) 2021-2024 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 "adapter/ohos/entrance/ace_container.h"
17 
18 #include <cerrno>
19 #include <fstream>
20 #include <functional>
21 #include <memory>
22 #include <regex>
23 
24 #include "ability_context.h"
25 #include "ability_info.h"
26 #include "auto_fill_manager.h"
27 #include "js_native_api.h"
28 #include "pointer_event.h"
29 #include "scene_board_judgement.h"
30 #include "ui_extension_context.h"
31 #include "window_manager.h"
32 #include "wm/wm_common.h"
33 #include "root_scene.h"
34 #include "ws_common.h"
35 
36 #include "adapter/ohos/entrance/ace_application_info.h"
37 #include "adapter/ohos/entrance/ace_view_ohos.h"
38 #include "adapter/ohos/entrance/cj_utils/cj_utils.h"
39 #include "adapter/ohos/entrance/data_ability_helper_standard.h"
40 #include "adapter/ohos/entrance/file_asset_provider_impl.h"
41 #include "adapter/ohos/entrance/hap_asset_provider_impl.h"
42 #include "adapter/ohos/entrance/ui_content_impl.h"
43 #include "adapter/ohos/entrance/utils.h"
44 #include "adapter/ohos/osal/resource_adapter_impl_v2.h"
45 #include "adapter/ohos/osal/system_bar_style_ohos.h"
46 #include "adapter/ohos/osal/view_data_wrap_ohos.h"
47 #include "adapter/ohos/osal/window_utils.h"
48 #include "base/i18n/localization.h"
49 #include "base/json/json_util.h"
50 #include "base/log/ace_trace.h"
51 #include "base/log/dump_log.h"
52 #include "base/log/event_report.h"
53 #include "base/log/frame_report.h"
54 #include "base/log/jank_frame_report.h"
55 #include "base/log/log.h"
56 #include "base/log/log_wrapper.h"
57 #include "base/subwindow/subwindow_manager.h"
58 #include "base/thread/background_task_executor.h"
59 #include "base/thread/task_executor.h"
60 #include "base/utils/device_config.h"
61 #include "base/utils/system_properties.h"
62 #include "base/utils/time_util.h"
63 #include "base/utils/utils.h"
64 #include "bridge/card_frontend/card_frontend.h"
65 #include "bridge/card_frontend/form_frontend_declarative.h"
66 #include "bridge/common/utils/engine_helper.h"
67 #include "bridge/declarative_frontend/declarative_frontend.h"
68 #include "bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h"
69 #include "bridge/js_frontend/engine/common/js_engine_loader.h"
70 #include "bridge/js_frontend/js_frontend.h"
71 #include "core/common/ace_application_info.h"
72 #include "core/common/ace_engine.h"
73 #include "core/common/asset_manager_impl.h"
74 #include "core/common/container.h"
75 #include "core/common/container_consts.h"
76 #include "core/common/container_scope.h"
77 #include "core/common/platform_window.h"
78 #include "core/common/plugin_manager.h"
79 #include "core/common/resource/resource_manager.h"
80 #include "core/common/task_executor_impl.h"
81 #include "core/common/text_field_manager.h"
82 #include "core/common/window.h"
83 #include "core/components/theme/theme_constants.h"
84 #include "core/components/theme/theme_manager_impl.h"
85 #include "core/components_ng/pattern/text_field/text_field_manager.h"
86 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
87 #include "core/components_ng/render/adapter/form_render_window.h"
88 #include "core/components_ng/render/adapter/rosen_window.h"
89 
90 #if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
91 #include "adapter/ohos/entrance/ace_rosen_sync_task.h"
92 #endif
93 
94 namespace OHOS::Ace::Platform {
95 namespace {
96 constexpr uint32_t DIRECTION_KEY = 0b1000;
97 constexpr uint32_t DENSITY_KEY = 0b0100;
98 constexpr uint32_t POPUPSIZE_HEIGHT = 0;
99 constexpr uint32_t POPUPSIZE_WIDTH = 0;
100 constexpr int32_t SEARCH_ELEMENT_TIMEOUT_TIME = 1500;
101 constexpr int32_t POPUP_CALCULATE_RATIO = 2;
102 constexpr int32_t POPUP_EDGE_INTERVAL = 48;
103 constexpr uint32_t DEFAULT_WINDOW_TYPE = 1;
104 const char ENABLE_DEBUG_BOUNDARY_KEY[] = "persist.ace.debug.boundary.enabled";
105 const char ENABLE_TRACE_LAYOUT_KEY[] = "persist.ace.trace.layout.enabled";
106 const char ENABLE_TRACE_INPUTEVENT_KEY[] = "persist.ace.trace.inputevent.enabled";
107 const char ENABLE_SECURITY_DEVELOPERMODE_KEY[] = "const.security.developermode.state";
108 const char ENABLE_DEBUG_STATEMGR_KEY[] = "persist.ace.debug.statemgr.enabled";
109 const char ENABLE_PERFORMANCE_MONITOR_KEY[] = "persist.ace.performance.monitor.enabled";
110 std::mutex g_mutexFormRenderFontFamily;
111 
112 #ifdef _ARM64_
113 const std::string ASSET_LIBARCH_PATH = "/lib/arm64";
114 #else
115 const std::string ASSET_LIBARCH_PATH = "/lib/arm";
116 #endif
117 
118 #ifndef NG_BUILD
119 constexpr char ARK_ENGINE_SHARED_LIB[] = "libace_engine_ark.z.so";
GetEngineSharedLibrary()120 const char* GetEngineSharedLibrary()
121 {
122     return ARK_ENGINE_SHARED_LIB;
123 }
124 #endif
125 
126 constexpr char DECLARATIVE_ARK_ENGINE_SHARED_LIB[] = "libace_engine_declarative_ark.z.so";
GetDeclarativeSharedLibrary()127 const char* GetDeclarativeSharedLibrary()
128 {
129     return DECLARATIVE_ARK_ENGINE_SHARED_LIB;
130 }
131 
InitResourceAndThemeManager(const RefPtr<PipelineBase>& pipelineContext, const RefPtr<AssetManager>& assetManager, const ColorScheme& colorScheme, const ResourceInfo& resourceInfo, const std::shared_ptr<OHOS::AbilityRuntime::Context>& context, const std::shared_ptr<OHOS::AppExecFwk::AbilityInfo>& abilityInfo, bool clearCache = false)132 void InitResourceAndThemeManager(const RefPtr<PipelineBase>& pipelineContext, const RefPtr<AssetManager>& assetManager,
133     const ColorScheme& colorScheme, const ResourceInfo& resourceInfo,
134     const std::shared_ptr<OHOS::AbilityRuntime::Context>& context,
135     const std::shared_ptr<OHOS::AppExecFwk::AbilityInfo>& abilityInfo, bool clearCache = false)
136 {
137     std::string bundleName = "";
138     std::string moduleName = "";
139     if (context) {
140         bundleName = context->GetBundleName();
141         moduleName = context->GetHapModuleInfo()->name;
142     } else if (abilityInfo) {
143         bundleName = abilityInfo->bundleName;
144         moduleName = abilityInfo->moduleName;
145     }
146 
147     RefPtr<ResourceAdapter> resourceAdapter = nullptr;
148     if (context && context->GetResourceManager()) {
149         resourceAdapter = AceType::MakeRefPtr<ResourceAdapterImplV2>(context->GetResourceManager(), resourceInfo);
150     } else if (ResourceManager::GetInstance().IsResourceAdapterRecord(bundleName, moduleName)) {
151         resourceAdapter = ResourceManager::GetInstance().GetResourceAdapter(bundleName, moduleName);
152     }
153 
154     if (resourceAdapter == nullptr) {
155         resourceAdapter = ResourceAdapter::CreateV2();
156         resourceAdapter->Init(resourceInfo);
157     }
158 
159     ThemeConstants::InitDeviceType();
160     auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>(resourceAdapter);
161     pipelineContext->SetThemeManager(themeManager);
162     themeManager->SetColorScheme(colorScheme);
163     themeManager->LoadCustomTheme(assetManager);
164     themeManager->LoadResourceThemes();
165 
166     if (clearCache) {
167         ResourceManager::GetInstance().Reset();
168     }
169 
170     auto defaultBundleName = "";
171     auto defaultModuleName = "";
172     ResourceManager::GetInstance().AddResourceAdapter(defaultBundleName, defaultModuleName, resourceAdapter, true);
173     if (!bundleName.empty() && !moduleName.empty()) {
174         ResourceManager::GetInstance().RegisterMainResourceAdapter(bundleName, moduleName, resourceAdapter);
175     }
176 }
177 
EncodeBundleAndModule(const std::string& bundleName, const std::string& moduleName)178 std::string EncodeBundleAndModule(const std::string& bundleName, const std::string& moduleName)
179 {
180     return bundleName + " " + moduleName;
181 }
182 
DecodeBundleAndModule(const std::string& encode, std::string& bundleName, std::string& moduleName)183 void DecodeBundleAndModule(const std::string& encode, std::string& bundleName, std::string& moduleName)
184 {
185     std::vector<std::string> tokens;
186     StringUtils::StringSplitter(encode, ' ', tokens);
187     bundleName = tokens[0];
188     moduleName = tokens[1];
189 }
190 
ReleaseStorageReference(void* sharedRuntime, NativeReference* storage)191 void ReleaseStorageReference(void* sharedRuntime, NativeReference* storage)
192 {
193     if (sharedRuntime && storage) {
194         auto nativeEngine = reinterpret_cast<NativeEngine*>(sharedRuntime);
195         auto env = reinterpret_cast<napi_env>(nativeEngine);
196         napi_delete_reference(env, reinterpret_cast<napi_ref>(storage));
197     }
198 }
199 } // namespace
200 
AceContainer(int32_t instanceId, FrontendType type, std::shared_ptr<OHOS::AppExecFwk::Ability> aceAbility, std::unique_ptr<PlatformEventCallback> callback, bool useCurrentEventRunner, bool useNewPipeline)201 AceContainer::AceContainer(int32_t instanceId, FrontendType type, std::shared_ptr<OHOS::AppExecFwk::Ability> aceAbility,
202     std::unique_ptr<PlatformEventCallback> callback, bool useCurrentEventRunner, bool useNewPipeline)
203     : instanceId_(instanceId), type_(type), aceAbility_(aceAbility), useCurrentEventRunner_(useCurrentEventRunner)
204 {
205     ACE_DCHECK(callback);
206     if (useNewPipeline) {
207         SetUseNewPipeline();
208         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
209             SetUsePartialUpdate();
210         }
211     }
212     InitializeTask();
213     platformEventCallback_ = std::move(callback);
214     useStageModel_ = false;
215     auto ability = aceAbility_.lock();
216     if (ability) {
217         abilityInfo_ = ability->GetAbilityInfo();
218     }
219 }
220 
AceContainer(int32_t instanceId, FrontendType type, std::weak_ptr<OHOS::AbilityRuntime::Context> runtimeContext, std::weak_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo, std::unique_ptr<PlatformEventCallback> callback, bool useCurrentEventRunner, bool isSubAceContainer, bool useNewPipeline)221 AceContainer::AceContainer(int32_t instanceId, FrontendType type,
222     std::weak_ptr<OHOS::AbilityRuntime::Context> runtimeContext,
223     std::weak_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo, std::unique_ptr<PlatformEventCallback> callback,
224     bool useCurrentEventRunner, bool isSubAceContainer, bool useNewPipeline)
225     : instanceId_(instanceId), type_(type), runtimeContext_(std::move(runtimeContext)),
226       abilityInfo_(std::move(abilityInfo)), useCurrentEventRunner_(useCurrentEventRunner),
227       isSubContainer_(isSubAceContainer)
228 {
229     ACE_DCHECK(callback);
230     if (useNewPipeline) {
231         SetUseNewPipeline();
232         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
233             SetUsePartialUpdate();
234         }
235     }
236     if (!isSubContainer_) {
237         InitializeTask();
238     }
239     platformEventCallback_ = std::move(callback);
240     useStageModel_ = true;
241 }
242 
243 // for DynamicComponent
AceContainer(int32_t instanceId, FrontendType type, std::weak_ptr<OHOS::AbilityRuntime::Context> runtimeContext, std::weak_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo, std::unique_ptr<PlatformEventCallback> callback, std::shared_ptr<TaskWrapper> taskWrapper, bool useCurrentEventRunner, bool isSubAceContainer, bool useNewPipeline)244 AceContainer::AceContainer(int32_t instanceId, FrontendType type,
245     std::weak_ptr<OHOS::AbilityRuntime::Context> runtimeContext,
246     std::weak_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo, std::unique_ptr<PlatformEventCallback> callback,
247     std::shared_ptr<TaskWrapper> taskWrapper,
248     bool useCurrentEventRunner, bool isSubAceContainer, bool useNewPipeline)
249     : instanceId_(instanceId), type_(type), runtimeContext_(std::move(runtimeContext)),
250       abilityInfo_(std::move(abilityInfo)), useCurrentEventRunner_(useCurrentEventRunner),
251       isSubContainer_(isSubAceContainer)
252 {
253     ACE_DCHECK(callback);
254     if (useNewPipeline) {
255         SetUseNewPipeline();
256         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
257             SetUsePartialUpdate();
258         }
259     }
260     if (!isSubContainer_) {
261         InitializeTask(taskWrapper);
262     }
263     platformEventCallback_ = std::move(callback);
264     useStageModel_ = true;
265 }
266 
~AceContainer()267 AceContainer::~AceContainer()
268 {
269     std::lock_guard lock(destructMutex_);
270     LOGI("Container Destroyed");
271 }
272 
InitializeTask(std::shared_ptr<TaskWrapper> taskWrapper)273 void AceContainer::InitializeTask(std::shared_ptr<TaskWrapper> taskWrapper)
274 {
275     RefPtr<TaskExecutorImpl> taskExecutorImpl;
276     if (taskWrapper != nullptr) {
277         taskExecutorImpl = Referenced::MakeRefPtr<TaskExecutorImpl>(taskWrapper);
278     } else {
279         taskExecutorImpl = Referenced::MakeRefPtr<TaskExecutorImpl>();
280     }
281     taskExecutorImpl->InitPlatformThread(useCurrentEventRunner_);
282     taskExecutor_ = taskExecutorImpl;
283     // No need to create JS Thread for DECLARATIVE_JS
284     if (type_ == FrontendType::DECLARATIVE_JS || type_ == FrontendType::DECLARATIVE_CJ) {
285         GetSettings().useUIAsJSThread = true;
286     } else {
287         taskExecutorImpl->InitJsThread();
288     }
289 }
290 
IsKeyboard()291 bool AceContainer::IsKeyboard()
292 {
293     if (uiWindow_ == nullptr) {
294         return false;
295     }
296     return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT;
297 }
298 
Initialize()299 void AceContainer::Initialize()
300 {
301     ContainerScope scope(instanceId_);
302     // For DECLARATIVE_JS frontend use UI as JS Thread, so InitializeFrontend after UI thread created.
303     if (type_ != FrontendType::DECLARATIVE_JS && type_ != FrontendType::DECLARATIVE_CJ) {
304         InitializeFrontend();
305     }
306 }
307 
MaybeRelease()308 bool AceContainer::MaybeRelease()
309 {
310     CHECK_NULL_RETURN(taskExecutor_, true);
311     if (taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::PLATFORM)) {
312         LOGI("Destroy AceContainer on PLATFORM thread.");
313         return true;
314     } else {
315         std::lock_guard lock(destructMutex_);
316         LOGI("Post Destroy AceContainer Task to PLATFORM thread.");
317         return !taskExecutor_->PostTask(
318             [this] { delete this; }, TaskExecutor::TaskType::PLATFORM, "ArkUIAceContainerDestroy");
319     }
320 }
321 
Destroy()322 void AceContainer::Destroy()
323 {
324     LOGI("AceContainer Destroy begin");
325     ContainerScope scope(instanceId_);
326     RemoveWatchSystemParameter();
327 
328     ReleaseResourceAdapter();
329     if (pipelineContext_ && taskExecutor_) {
330         // 1. Destroy Pipeline on UI thread.
331         RefPtr<PipelineBase> context;
332         {
333             std::lock_guard<std::mutex> lock(pipelineMutex_);
334             context.Swap(pipelineContext_);
335         }
336         auto uiTask = [context]() { context->Destroy(); };
337         if (GetSettings().usePlatformAsUIThread) {
338             uiTask();
339         } else {
340             taskExecutor_->PostTask(uiTask, TaskExecutor::TaskType::UI, "ArkUIPipelineDestroy");
341         }
342 
343         if (isSubContainer_) {
344             // SubAceContainer just return.
345             return;
346         }
347 
348         // 2. Destroy Frontend on JS thread.
349         RefPtr<Frontend> frontend;
350         {
351             std::lock_guard<std::mutex> lock(frontendMutex_);
352             frontend.Swap(frontend_);
353         }
354         auto jsTask = [frontend]() {
355             auto lock = frontend->GetLock();
356             frontend->Destroy();
357         };
358         frontend->UpdateState(Frontend::State::ON_DESTROY);
359         if (GetSettings().usePlatformAsUIThread && GetSettings().useUIAsJSThread) {
360             jsTask();
361         } else {
362             taskExecutor_->PostTask(jsTask, TaskExecutor::TaskType::JS, "ArkUIFrontendDestroy");
363         }
364     }
365     DestroyToastSubwindow(instanceId_);
366     resRegister_.Reset();
367     assetManager_.Reset();
368 }
369 
DestroyView()370 void AceContainer::DestroyView()
371 {
372     ContainerScope scope(instanceId_);
373     std::lock_guard<std::mutex> lock(viewMutex_);
374     aceView_ = nullptr;
375 }
376 
InitializeFrontend()377 void AceContainer::InitializeFrontend()
378 {
379     auto aceAbility = aceAbility_.lock();
380     if (type_ == FrontendType::JS) {
381 #ifndef NG_BUILD
382         frontend_ = Frontend::Create();
383         auto jsFrontend = AceType::DynamicCast<JsFrontend>(frontend_);
384         auto& loader = Framework::JsEngineLoader::Get(GetEngineSharedLibrary());
385         auto jsEngine = loader.CreateJsEngine(instanceId_);
386         jsEngine->AddExtraNativeObject("ability", aceAbility.get());
387         EngineHelper::AddEngine(instanceId_, jsEngine);
388         jsFrontend->SetJsEngine(jsEngine);
389         jsFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
390         jsFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
391 #endif
392     } else if (type_ == FrontendType::JS_CARD) {
393 #ifndef NG_BUILD
394         AceApplicationInfo::GetInstance().SetCardType();
395         frontend_ = AceType::MakeRefPtr<CardFrontend>();
396 #endif
397     } else if (type_ == FrontendType::DECLARATIVE_JS) {
398         if (isFormRender_) {
399 #ifdef FORM_SUPPORTED
400             LOGI("Init Form Frontend");
401             frontend_ = AceType::MakeRefPtr<FormFrontendDeclarative>();
402             auto cardFrontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
403             auto& loader = Framework::JsEngineLoader::GetDeclarative(GetDeclarativeSharedLibrary());
404             RefPtr<Framework::JsEngine> jsEngine;
405             if (GetSettings().usingSharedRuntime) {
406                 jsEngine = loader.CreateJsEngineUsingSharedRuntime(instanceId_, sharedRuntime_);
407             } else {
408                 jsEngine = loader.CreateJsEngine(instanceId_);
409             }
410             jsEngine->AddExtraNativeObject("ability", aceAbility.get());
411             EngineHelper::AddEngine(instanceId_, jsEngine);
412             cardFrontend->SetJsEngine(jsEngine);
413             cardFrontend->SetPageProfile(pageProfile_);
414             cardFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
415             cardFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
416             // Card front
417             cardFrontend->SetRunningCardId(0); // ArkTsCard : nodeId, Host->FMS->FRS->innersdk
418             cardFrontend->SetIsFormRender(true);
419 #endif
420         } else if (!isSubContainer_) {
421 #ifdef NG_BUILD
422             frontend_ = AceType::MakeRefPtr<DeclarativeFrontendNG>();
423             auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontendNG>(frontend_);
424 #else
425             frontend_ = AceType::MakeRefPtr<DeclarativeFrontend>();
426             auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
427 #endif
428             auto& loader = Framework::JsEngineLoader::GetDeclarative(GetDeclarativeSharedLibrary());
429             RefPtr<Framework::JsEngine> jsEngine;
430             if (GetSettings().usingSharedRuntime) {
431                 jsEngine = loader.CreateJsEngineUsingSharedRuntime(instanceId_, sharedRuntime_);
432             } else {
433                 jsEngine = loader.CreateJsEngine(instanceId_);
434             }
435             jsEngine->AddExtraNativeObject("ability", aceAbility.get());
436             auto pageUrlCheckFunc = [id = instanceId_](const std::string& url, const std::function<void()>& callback,
437                 const std::function<void(int32_t, const std::string&)>& silentInstallErrorCallBack) {
438                 ContainerScope scope(id);
439                 auto container = Container::Current();
440                 CHECK_NULL_VOID(container);
441                 auto pageUrlChecker = container->GetPageUrlChecker();
442                 CHECK_NULL_VOID(pageUrlChecker);
443                 pageUrlChecker->LoadPageUrl(url, callback, silentInstallErrorCallBack);
444             };
445             jsEngine->SetPageUrlCheckFunc(std::move(pageUrlCheckFunc));
446             EngineHelper::AddEngine(instanceId_, jsEngine);
447             declarativeFrontend->SetJsEngine(jsEngine);
448             declarativeFrontend->SetPageProfile(pageProfile_);
449             declarativeFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
450             declarativeFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
451         } else {
452             frontend_ = OHOS::Ace::Platform::AceContainer::GetContainer(parentId_)->GetFrontend();
453             return;
454         }
455     } else if (type_ == FrontendType::DECLARATIVE_CJ) {
456         LOGD("cj Frontend");
457         if (!isSubContainer_) {
458             auto cjFrontend = CJUtils::LoadCjFrontend(useNewPipeline_, useStageModel_);
459             if (cjFrontend == nullptr) {
460                 LOGE("Create cj frontend failed.");
461             }
462             frontend_ = AceType::Claim(reinterpret_cast<Frontend*>(cjFrontend));
463         } else {
464             frontend_ = OHOS::Ace::Platform::AceContainer::GetContainer(parentId_)->GetFrontend();
465             return;
466         }
467     } else {
468         LOGE("Frontend type not supported");
469         EventReport::SendAppStartException(AppStartExcepType::FRONTEND_TYPE_ERR);
470         return;
471     }
472     ACE_DCHECK(frontend_);
473     auto abilityInfo = abilityInfo_.lock();
474     std::shared_ptr<AppExecFwk::AbilityInfo> info = aceAbility ? aceAbility->GetAbilityInfo() : abilityInfo;
475     if (info && info->isLauncherAbility) {
476         frontend_->DisallowPopLastPage();
477     }
478     frontend_->Initialize(type_, taskExecutor_);
479 }
480 
GetContainer(int32_t instanceId)481 RefPtr<AceContainer> AceContainer::GetContainer(int32_t instanceId)
482 {
483     auto container = AceEngine::Get().GetContainer(instanceId);
484     CHECK_NULL_RETURN(container, nullptr);
485     auto aceContainer = AceType::DynamicCast<AceContainer>(container);
486     return aceContainer;
487 }
488 
RemoveOverlayBySubwindowManager(int32_t instanceId)489 bool AceContainer::RemoveOverlayBySubwindowManager(int32_t instanceId)
490 {
491     auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(instanceId);
492     if (subwindow) {
493         if (subwindow->GetShown()) {
494             auto subContainerId = SubwindowManager::GetInstance()->GetSubContainerId(instanceId);
495             if (subContainerId < 0) {
496                 return false;
497             }
498             ContainerScope scope(subContainerId);
499             auto overlayManager = subwindow->GetOverlayManager();
500             CHECK_NULL_RETURN(overlayManager, false);
501             return overlayManager->RemoveOverlayInSubwindow();
502         }
503     }
504     return false;
505 }
506 
OnBackPressed(int32_t instanceId)507 bool AceContainer::OnBackPressed(int32_t instanceId)
508 {
509     auto container = AceEngine::Get().GetContainer(instanceId);
510     CHECK_NULL_RETURN(container, false);
511     // When the container is for overlay, it need close the overlay first.
512     if (container->IsSubContainer()) {
513 #ifdef NG_BUILD
514         TAG_LOGI(AceLogTag::ACE_UIEVENT, "back press for remove overlay node");
515         ContainerScope scope(instanceId);
516         auto subPipelineContext = DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
517         CHECK_NULL_RETURN(subPipelineContext, false);
518         auto overlayManager = subPipelineContext->GetOverlayManager();
519         CHECK_NULL_RETURN(overlayManager, false);
520         return overlayManager->RemoveOverlayInSubwindow();
521 #else
522         if (container->IsUseNewPipeline()) {
523             TAG_LOGI(AceLogTag::ACE_UIEVENT, "back press for remove overlay node");
524             ContainerScope scope(instanceId);
525             auto subPipelineContext = DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
526             CHECK_NULL_RETURN(subPipelineContext, false);
527             auto textfieldMgr = DynamicCast<NG::TextFieldManagerNG>(subPipelineContext->GetTextFieldManager());
528             if (textfieldMgr) {
529                 auto lastRequestKeyboardNodeId = textfieldMgr->GetLastRequestKeyboardId();
530                 auto lastRequestKeyboardNode = DynamicCast<NG::FrameNode>(
531                     ElementRegister::GetInstance()->GetUINodeById(lastRequestKeyboardNodeId));
532                 if (lastRequestKeyboardNode && lastRequestKeyboardNode->GetPageId() == -1 &&
533                     textfieldMgr->OnBackPressed()) {
534                     LOGI("textfield consumed backpressed event");
535                     return true;
536                 }
537             }
538             auto overlayManager = subPipelineContext->GetOverlayManager();
539             CHECK_NULL_RETURN(overlayManager, false);
540             if (overlayManager->RemoveOverlayInSubwindow()) {
541                 TAG_LOGI(AceLogTag::ACE_UIEVENT, "subwindow consumed backpressed event");
542                 return true;
543             }
544             instanceId = SubwindowManager::GetInstance()->GetParentContainerId(instanceId);
545         } else {
546             SubwindowManager::GetInstance()->CloseMenu();
547             TAG_LOGI(AceLogTag::ACE_UIEVENT, "Menu consumed backpressed event");
548             return true;
549         }
550 #endif
551     }
552     // remove overlay through SubwindowManager if subwindow unfocused.
553     if (RemoveOverlayBySubwindowManager(instanceId)) {
554         TAG_LOGI(AceLogTag::ACE_UIEVENT, "subwindow consumed backpressed event");
555         return true;
556     }
557     ContainerScope scope(instanceId);
558     auto context = container->GetPipelineContext();
559     CHECK_NULL_RETURN(context, false);
560     if (context->PopPageStackOverlay()) {
561         return true;
562     }
563     return context->CallRouterBackToPopPage();
564 }
565 
OnShow(int32_t instanceId)566 void AceContainer::OnShow(int32_t instanceId)
567 {
568     auto container = AceEngine::Get().GetContainer(instanceId);
569     CHECK_NULL_VOID(container);
570     ContainerScope scope(instanceId);
571     auto taskExecutor = container->GetTaskExecutor();
572     CHECK_NULL_VOID(taskExecutor);
573     if (!container->UpdateState(Frontend::State::ON_SHOW)) {
574         return;
575     }
576 
577     auto jsTask = [container, front = container->GetFrontend()]() {
578         if (front && !container->IsSubContainer()) {
579             front->UpdateState(Frontend::State::ON_SHOW);
580             front->OnShow();
581         }
582     };
583 
584     auto uiTask = [container]() {
585         std::unordered_map<int64_t, WeakPtr<Frontend>> cardFrontendMap;
586         container->GetCardFrontendMap(cardFrontendMap);
587         for (const auto& [_, weakCardFront] : cardFrontendMap) {
588             auto cardFront = weakCardFront.Upgrade();
589             if (!cardFront) {
590                 LOGE("cardFront is null");
591                 continue;
592             }
593             cardFront->OnShow();
594         }
595         auto pipelineBase = container->GetPipelineContext();
596         CHECK_NULL_VOID(pipelineBase);
597         pipelineBase->OnShow();
598         pipelineBase->SetForegroundCalled(true);
599     };
600 
601     // stege model needn't post task when already run on UI
602     if (container->GetSettings().useUIAsJSThread && taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
603         jsTask();
604         uiTask();
605     } else {
606         taskExecutor->PostTask(jsTask, TaskExecutor::TaskType::JS, "ArkUIFrontendShow");
607         taskExecutor->PostTask(uiTask, TaskExecutor::TaskType::UI, "ArkUICardFrontendShow");
608     }
609 }
610 
OnHide(int32_t instanceId)611 void AceContainer::OnHide(int32_t instanceId)
612 {
613     auto container = AceEngine::Get().GetContainer(instanceId);
614     CHECK_NULL_VOID(container);
615     ContainerScope scope(instanceId);
616     auto taskExecutor = container->GetTaskExecutor();
617     CHECK_NULL_VOID(taskExecutor);
618     if (!container->UpdateState(Frontend::State::ON_HIDE)) {
619         return;
620     }
621     std::unordered_map<int64_t, WeakPtr<Frontend>> cardFrontendMap;
622     container->GetCardFrontendMap(cardFrontendMap);
623 
624     auto jsTask = [container, front = container->GetFrontend(), cardFrontendMap]() {
625         if (front && !container->IsSubContainer()) {
626             front->UpdateState(Frontend::State::ON_HIDE);
627             front->OnHide();
628             front->TriggerGarbageCollection();
629         }
630         for (const auto& [_, weakCardFront] : cardFrontendMap) {
631             auto cardFront = weakCardFront.Upgrade();
632             if (!cardFront) {
633                 LOGE("cardFront is null");
634                 continue;
635             }
636             cardFront->TriggerGarbageCollection();
637         }
638     };
639 
640     auto uiTask = [container, cardFrontendMap]() {
641         for (const auto& [_, weakCardFront] : cardFrontendMap) {
642             auto cardFront = weakCardFront.Upgrade();
643             if (!cardFront) {
644                 LOGE("cardFront is null");
645                 continue;
646             }
647             cardFront->OnHide();
648         }
649         auto pipelineBase = container->GetPipelineContext();
650         CHECK_NULL_VOID(pipelineBase);
651         pipelineBase->OnHide();
652     };
653 
654     // stege model needn't post task when already run on UI
655     if (container->GetSettings().useUIAsJSThread && taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
656         jsTask();
657         uiTask();
658     } else {
659         taskExecutor->PostTask(jsTask, TaskExecutor::TaskType::JS, "ArkUIFrontendHide");
660         taskExecutor->PostTask(uiTask, TaskExecutor::TaskType::UI, "ArkUICardFrontendHide");
661     }
662 }
663 
OnActive(int32_t instanceId)664 void AceContainer::OnActive(int32_t instanceId)
665 {
666     auto container = AceEngine::Get().GetContainer(instanceId);
667     CHECK_NULL_VOID(container);
668     ContainerScope scope(instanceId);
669     auto taskExecutor = container->GetTaskExecutor();
670     CHECK_NULL_VOID(taskExecutor);
671 
672     auto front = container->GetFrontend();
673     if (front && !container->IsSubContainer()) {
674         WeakPtr<Frontend> weakFrontend = front;
675         taskExecutor->PostTask(
676             [weakFrontend, instanceId]() {
677                 auto frontend = weakFrontend.Upgrade();
678                 if (frontend) {
679                     ContainerScope scope(instanceId);
680                     frontend->UpdateState(Frontend::State::ON_ACTIVE);
681                     frontend->OnActive();
682                 }
683             },
684             TaskExecutor::TaskType::JS, "ArkUIFrontendActive");
685     }
686 
687     taskExecutor->PostTask(
688         [container]() {
689             auto pipelineContext = container->GetPipelineContext();
690             if (!pipelineContext) {
691                 LOGE("pipeline context is null, OnActive failed.");
692                 return;
693             }
694             ContainerScope scope(container->GetInstanceId());
695             pipelineContext->WindowFocus(true);
696             pipelineContext->ChangeDarkModeBrightness();
697         },
698         TaskExecutor::TaskType::UI, "ArkUIWindowFocus");
699 }
700 
OnInactive(int32_t instanceId)701 void AceContainer::OnInactive(int32_t instanceId)
702 {
703     auto container = AceEngine::Get().GetContainer(instanceId);
704     CHECK_NULL_VOID(container);
705     ContainerScope scope(instanceId);
706     auto taskExecutor = container->GetTaskExecutor();
707     CHECK_NULL_VOID(taskExecutor);
708 
709     auto front = container->GetFrontend();
710     if (front && !container->IsSubContainer()) {
711         WeakPtr<Frontend> weakFrontend = front;
712         taskExecutor->PostTask(
713             [weakFrontend, instanceId]() {
714                 auto frontend = weakFrontend.Upgrade();
715                 if (frontend) {
716                     ContainerScope scope(instanceId);
717                     frontend->UpdateState(Frontend::State::ON_INACTIVE);
718                     frontend->OnInactive();
719                 }
720             },
721             TaskExecutor::TaskType::JS, "ArkUIFrontendInactive");
722     }
723 
724     taskExecutor->PostTask(
725         [container]() {
726             auto pipelineContext = container->GetPipelineContext();
727             if (!pipelineContext) {
728                 LOGE("pipeline context is null, OnInactive failed.");
729                 return;
730             }
731             ContainerScope scope(container->GetInstanceId());
732             pipelineContext->WindowFocus(false);
733             pipelineContext->ChangeDarkModeBrightness();
734             if (container->IsScenceBoardWindow()) {
735                 JankFrameReport::GetInstance().FlushRecord();
736             }
737         },
738         TaskExecutor::TaskType::UI, "ArkUIWindowUnfocus");
739 }
740 
OnNewWant(int32_t instanceId, const std::string& data)741 void AceContainer::OnNewWant(int32_t instanceId, const std::string& data)
742 {
743     auto container = AceEngine::Get().GetContainer(instanceId);
744     CHECK_NULL_VOID(container);
745     ContainerScope scope(instanceId);
746     auto front = container->GetFrontend();
747     CHECK_NULL_VOID(front);
748     front->OnNewWant(data);
749 }
750 
OnStartContinuation(int32_t instanceId)751 bool AceContainer::OnStartContinuation(int32_t instanceId)
752 {
753     auto container = AceEngine::Get().GetContainer(instanceId);
754     CHECK_NULL_RETURN(container, false);
755     ContainerScope scope(instanceId);
756     auto front = container->GetFrontend();
757     CHECK_NULL_RETURN(front, false);
758     return front->OnStartContinuation();
759 }
760 
OnSaveData(int32_t instanceId)761 std::string AceContainer::OnSaveData(int32_t instanceId)
762 {
763     std::string result = "false";
764     auto container = AceEngine::Get().GetContainer(instanceId);
765     CHECK_NULL_RETURN(container, result);
766     ContainerScope scope(instanceId);
767     auto front = container->GetFrontend();
768     CHECK_NULL_RETURN(front, result);
769     front->OnSaveData(result);
770     return result;
771 }
772 
OnRestoreData(int32_t instanceId, const std::string& data)773 bool AceContainer::OnRestoreData(int32_t instanceId, const std::string& data)
774 {
775     auto container = AceEngine::Get().GetContainer(instanceId);
776     CHECK_NULL_RETURN(container, false);
777     ContainerScope scope(instanceId);
778     auto front = container->GetFrontend();
779     CHECK_NULL_RETURN(front, false);
780     return front->OnRestoreData(data);
781 }
782 
OnCompleteContinuation(int32_t instanceId, int result)783 void AceContainer::OnCompleteContinuation(int32_t instanceId, int result)
784 {
785     auto container = AceEngine::Get().GetContainer(instanceId);
786     CHECK_NULL_VOID(container);
787     ContainerScope scope(instanceId);
788     auto front = container->GetFrontend();
789     CHECK_NULL_VOID(front);
790     front->OnCompleteContinuation(result);
791 }
792 
OnRemoteTerminated(int32_t instanceId)793 void AceContainer::OnRemoteTerminated(int32_t instanceId)
794 {
795     auto container = AceEngine::Get().GetContainer(instanceId);
796     CHECK_NULL_VOID(container);
797     ContainerScope scope(instanceId);
798     auto front = container->GetFrontend();
799     CHECK_NULL_VOID(front);
800     front->OnRemoteTerminated();
801 }
802 
OnConfigurationUpdated(int32_t instanceId, const std::string& configuration)803 void AceContainer::OnConfigurationUpdated(int32_t instanceId, const std::string& configuration)
804 {
805     auto container = AceEngine::Get().GetContainer(instanceId);
806     CHECK_NULL_VOID(container);
807     ContainerScope scope(instanceId);
808     auto front = container->GetFrontend();
809     CHECK_NULL_VOID(front);
810     front->OnConfigurationUpdated(configuration);
811 }
812 
OnNewRequest(int32_t instanceId, const std::string& data)813 void AceContainer::OnNewRequest(int32_t instanceId, const std::string& data)
814 {
815     auto container = AceEngine::Get().GetContainer(instanceId);
816     CHECK_NULL_VOID(container);
817     ContainerScope scope(instanceId);
818     auto front = container->GetFrontend();
819     CHECK_NULL_VOID(front);
820     front->OnNewRequest(data);
821 }
822 
InitializeCallback()823 void AceContainer::InitializeCallback()
824 {
825     ACE_FUNCTION_TRACE();
826 
827     ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
828     auto&& touchEventCallback = [context = pipelineContext_, id = instanceId_](
829                                     const TouchEvent& event, const std::function<void()>& markProcess,
830                                     const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
831         ContainerScope scope(id);
832         context->CheckAndLogLastReceivedTouchEventInfo(event.touchEventId, event.type);
833         auto touchTask = [context, event, markProcess, node]() {
834             if (event.type == TouchType::HOVER_ENTER || event.type == TouchType::HOVER_MOVE ||
835                 event.type == TouchType::HOVER_EXIT || event.type == TouchType::HOVER_CANCEL) {
836                 context->OnAccessibilityHoverEvent(event, node);
837             } else if (event.IsPenHoverEvent()) {
838                 context->OnPenHoverEvent(event, node);
839             } else {
840                 if (node) {
841                     context->OnTouchEvent(event, node);
842                 } else {
843                     context->OnTouchEvent(event);
844                 }
845             }
846             CHECK_NULL_VOID(markProcess);
847             markProcess();
848             context->CheckAndLogLastConsumedTouchEventInfo(event.touchEventId, event.type);
849         };
850         auto uiTaskRunner = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
851         if (uiTaskRunner.IsRunOnCurrentThread()) {
852             touchTask();
853             return;
854         }
855         context->GetTaskExecutor()->PostTask(
856             touchTask, TaskExecutor::TaskType::UI, "ArkUIAceContainerTouchEvent", PriorityType::VIP);
857     };
858     aceView_->RegisterTouchEventCallback(touchEventCallback);
859 
860     auto&& mouseEventCallback = [context = pipelineContext_, id = instanceId_](
861                                     const MouseEvent& event, const std::function<void()>& markProcess,
862                                     const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
863         ContainerScope scope(id);
864         context->CheckAndLogLastReceivedMouseEventInfo(event.touchEventId, event.action);
865         auto mouseTask = [context, event, markProcess, node]() {
866             if (node) {
867                 context->OnMouseEvent(event, node);
868             } else {
869                 context->OnMouseEvent(event);
870             }
871             CHECK_NULL_VOID(markProcess);
872             markProcess();
873             context->CheckAndLogLastConsumedMouseEventInfo(event.touchEventId, event.action);
874         };
875         auto uiTaskRunner = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
876         if (uiTaskRunner.IsRunOnCurrentThread()) {
877             mouseTask();
878             return;
879         }
880         context->GetTaskExecutor()->PostTask(
881             mouseTask, TaskExecutor::TaskType::UI, "ArkUIAceContainerMouseEvent", PriorityType::VIP);
882     };
883     aceView_->RegisterMouseEventCallback(mouseEventCallback);
884 
885     auto&& axisEventCallback = [context = pipelineContext_, id = instanceId_](
886                                    const AxisEvent& event, const std::function<void()>& markProcess,
887                                    const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
888         ContainerScope scope(id);
889         context->CheckAndLogLastReceivedAxisEventInfo(event.touchEventId, event.action);
890         auto axisTask = [context, event, markProcess, node]() {
891             if (node) {
892                 context->OnAxisEvent(event, node);
893             } else {
894                 context->OnAxisEvent(event);
895             }
896             CHECK_NULL_VOID(markProcess);
897             markProcess();
898             context->CheckAndLogLastConsumedAxisEventInfo(event.touchEventId, event.action);
899         };
900         auto uiTaskRunner = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
901         if (uiTaskRunner.IsRunOnCurrentThread()) {
902             axisTask();
903             return;
904         }
905         context->GetTaskExecutor()->PostTask(
906             axisTask, TaskExecutor::TaskType::UI, "ArkUIAceContainerAxisEvent", PriorityType::VIP);
907     };
908     aceView_->RegisterAxisEventCallback(axisEventCallback);
909 
910     auto&& keyEventCallback = [context = pipelineContext_, id = instanceId_](const KeyEvent& event) {
911         ContainerScope scope(id);
912         bool result = false;
913         context->GetTaskExecutor()->PostSyncTask(
914             [context, event, &result, id]() {
915                 ContainerScope scope(id);
916                 result = context->OnKeyEvent(event);
917             },
918             TaskExecutor::TaskType::UI, "ArkUIAceContainerKeyEvent", PriorityType::VIP);
919         return result;
920     };
921     aceView_->RegisterKeyEventCallback(keyEventCallback);
922 
923     auto&& rotationEventCallback = [context = pipelineContext_, id = instanceId_](const RotationEvent& event) {
924         ContainerScope scope(id);
925         bool result = false;
926         context->GetTaskExecutor()->PostSyncTask(
927             [context, event, &result]() { result = context->OnRotationEvent(event); },
928             TaskExecutor::TaskType::UI, "ArkUIAceContainerRotationEvent");
929         return result;
930     };
931     aceView_->RegisterRotationEventCallback(rotationEventCallback);
932 
933     auto&& viewChangeCallback = [context = pipelineContext_, id = instanceId_](int32_t width, int32_t height,
934                                     WindowSizeChangeReason type,
935                                     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction) {
936         ContainerScope scope(id);
937         ACE_SCOPED_TRACE("ViewChangeCallback(%d, %d)", width, height);
938 
939         if (type != WindowSizeChangeReason::ROTATION) {
940             context->SetSurfaceChangeMsg(width, height, type, rsTransaction);
941             context->RequestFrame();
942             return;
943         }
944         context->ResetSurfaceChangeMsg();
945 
946         auto callback = [context, width, height, type, rsTransaction, id]() {
947             context->OnSurfaceChanged(width, height, type, rsTransaction);
948             if (type == WindowSizeChangeReason::ROTATION) {
949                 auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(id);
950                 CHECK_NULL_VOID(subwindow);
951                 subwindow->ResizeWindow();
952             }
953         };
954         auto container = Container::Current();
955         CHECK_NULL_VOID(container);
956         auto taskExecutor = container->GetTaskExecutor();
957         CHECK_NULL_VOID(taskExecutor);
958         if ((container->IsUseStageModel() && type == WindowSizeChangeReason::ROTATION) ||
959             taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
960             callback();
961         } else {
962             taskExecutor->PostTask(callback, TaskExecutor::TaskType::UI, "ArkUISubwindowResizeWindow");
963         }
964     };
965     aceView_->RegisterViewChangeCallback(viewChangeCallback);
966 
967     auto&& viewPositionChangeCallback = [context = pipelineContext_, id = instanceId_](int32_t posX, int32_t posY) {
968         ContainerScope scope(id);
969         ACE_SCOPED_TRACE("ViewPositionChangeCallback(%d, %d)", posX, posY);
970         context->GetTaskExecutor()->PostTask(
971             [context, posX, posY]() { context->OnSurfacePositionChanged(posX, posY); },
972             TaskExecutor::TaskType::UI, "ArkUISurfacePositionChanged");
973     };
974     aceView_->RegisterViewPositionChangeCallback(viewPositionChangeCallback);
975 
976     auto&& densityChangeCallback = [context = pipelineContext_, id = instanceId_](double density) {
977         ContainerScope scope(id);
978         ACE_SCOPED_TRACE("DensityChangeCallback(%lf)", density);
979         auto callback = [context, density, id]() {
980             context->OnSurfaceDensityChanged(density);
981             if (context->IsDensityChanged()) {
982                 auto container = Container::GetContainer(id);
983                 CHECK_NULL_VOID(container);
984                 auto aceContainer = DynamicCast<AceContainer>(container);
985                 CHECK_NULL_VOID(aceContainer);
986                 aceContainer->UpdateResourceDensity(density);
987                 aceContainer->NotifyDensityUpdate();
988             }
989         };
990         auto taskExecutor = context->GetTaskExecutor();
991         CHECK_NULL_VOID(taskExecutor);
992         if (taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
993             callback();
994         } else {
995             taskExecutor->PostTask(callback, TaskExecutor::TaskType::UI, "ArkUISurfaceDensityChanged");
996         }
997     };
998     aceView_->RegisterDensityChangeCallback(densityChangeCallback);
999 
1000     auto&& transformHintChangeCallback = [context = pipelineContext_, id = instanceId_](uint32_t transform) {
1001         ContainerScope scope(id);
1002         ACE_SCOPED_TRACE("TransformHintChangeCallback(%d)", transform);
1003         auto callback = [context, transform]() { context->OnTransformHintChanged(transform); };
1004         auto taskExecutor = context->GetTaskExecutor();
1005         CHECK_NULL_VOID(taskExecutor);
1006         if (taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
1007             callback();
1008         } else {
1009             taskExecutor->PostTask(callback, TaskExecutor::TaskType::UI, "ArkUITransformHintChanged");
1010         }
1011     };
1012     aceView_->RegisterTransformHintChangeCallback(transformHintChangeCallback);
1013 
1014     auto&& systemBarHeightChangeCallback = [context = pipelineContext_, id = instanceId_](
1015                                                double statusBar, double navigationBar) {
1016         ContainerScope scope(id);
1017         ACE_SCOPED_TRACE("SystemBarHeightChangeCallback(%lf, %lf)", statusBar, navigationBar);
1018         context->GetTaskExecutor()->PostTask(
1019             [context, statusBar, navigationBar]() { context->OnSystemBarHeightChanged(statusBar, navigationBar); },
1020             TaskExecutor::TaskType::UI, "ArkUISystemBarHeightChanged");
1021     };
1022     aceView_->RegisterSystemBarHeightChangeCallback(systemBarHeightChangeCallback);
1023 
1024     auto&& surfaceDestroyCallback = [context = pipelineContext_, id = instanceId_]() {
1025         ContainerScope scope(id);
1026         context->GetTaskExecutor()->PostTask(
1027             [context]() { context->OnSurfaceDestroyed(); }, TaskExecutor::TaskType::UI, "ArkUISurfaceDestroyed");
1028     };
1029     aceView_->RegisterSurfaceDestroyCallback(surfaceDestroyCallback);
1030     InitDragEventCallback();
1031 }
1032 
InitDragEventCallback()1033 void AceContainer::InitDragEventCallback()
1034 {
1035     if (!isFormRender_) {
1036         auto&& dragEventCallback = [context = pipelineContext_, id = instanceId_](const PointerEvent& pointerEvent,
1037                                        const DragEventAction& action, const RefPtr<NG::FrameNode>& node) {
1038             ContainerScope scope(id);
1039             CHECK_NULL_VOID(context);
1040             auto callback = [context, pointerEvent, action, node]() {
1041                 context->OnDragEvent(pointerEvent, action, node);
1042             };
1043             auto taskExecutor = context->GetTaskExecutor();
1044             CHECK_NULL_VOID(taskExecutor);
1045             auto uiTaskRunner = SingleTaskExecutor::Make(taskExecutor, TaskExecutor::TaskType::UI);
1046             if (uiTaskRunner.IsRunOnCurrentThread()) {
1047                 callback();
1048                 return;
1049             }
1050             taskExecutor->PostTask(
1051                 callback, TaskExecutor::TaskType::UI, "ArkUIAceContainerDragEvent", PriorityType::VIP);
1052         };
1053         aceView_->RegisterDragEventCallback(dragEventCallback);
1054     }
1055 }
1056 
CreateContainer(int32_t instanceId, FrontendType type, const std::string& instanceName, std::shared_ptr<OHOS::AppExecFwk::Ability> aceAbility, std::unique_ptr<PlatformEventCallback> callback, bool useCurrentEventRunner, bool useNewPipeline)1057 void AceContainer::CreateContainer(int32_t instanceId, FrontendType type, const std::string& instanceName,
1058     std::shared_ptr<OHOS::AppExecFwk::Ability> aceAbility, std::unique_ptr<PlatformEventCallback> callback,
1059     bool useCurrentEventRunner, bool useNewPipeline)
1060 {
1061     auto aceContainer = AceType::MakeRefPtr<AceContainer>(
1062         instanceId, type, aceAbility, std::move(callback), useCurrentEventRunner, useNewPipeline);
1063     AceEngine::Get().AddContainer(instanceId, aceContainer);
1064     aceContainer->Initialize();
1065     ContainerScope scope(instanceId);
1066     auto front = aceContainer->GetFrontend();
1067     if (front) {
1068         front->UpdateState(Frontend::State::ON_CREATE);
1069         front->SetJsMessageDispatcher(aceContainer);
1070     }
1071 
1072     auto jsFront = AceType::DynamicCast<JsFrontend>(front);
1073     CHECK_NULL_VOID(jsFront);
1074     jsFront->SetInstanceName(instanceName);
1075 }
1076 
DestroyContainer(int32_t instanceId, const std::function<void()>& destroyCallback)1077 void AceContainer::DestroyContainer(int32_t instanceId, const std::function<void()>& destroyCallback)
1078 {
1079     SubwindowManager::GetInstance()->CloseDialog(instanceId);
1080     auto container = AceEngine::Get().GetContainer(instanceId);
1081     CHECK_NULL_VOID(container);
1082     container->Destroy();
1083     // unregister watchdog before stop thread to avoid UI_BLOCK report
1084     AceEngine::Get().UnRegisterFromWatchDog(instanceId);
1085     auto taskExecutor = container->GetTaskExecutor();
1086     CHECK_NULL_VOID(taskExecutor);
1087 
1088     taskExecutor->PostSyncTask([] { LOGI("Wait UI thread..."); }, TaskExecutor::TaskType::UI, "ArkUIWaitLog");
1089     taskExecutor->PostSyncTask([] { LOGI("Wait JS thread..."); }, TaskExecutor::TaskType::JS, "ArkUIWaitLog");
1090 
1091     container->DestroyView(); // Stop all threads(ui,gpu,io) for current ability.
1092     auto removeContainerTask = [instanceId, destroyCallback] {
1093         LOGI("Remove on Platform thread...");
1094         EngineHelper::RemoveEngine(instanceId);
1095         AceEngine::Get().RemoveContainer(instanceId);
1096         CHECK_NULL_VOID(destroyCallback);
1097         destroyCallback();
1098     };
1099     if (container->GetSettings().usePlatformAsUIThread) {
1100         removeContainerTask();
1101     } else {
1102         taskExecutor->PostTask(removeContainerTask, TaskExecutor::TaskType::PLATFORM, "ArkUIAceContainerRemove");
1103     }
1104 }
1105 
SetView(const RefPtr<AceView>& view, double density, int32_t width, int32_t height, sptr<OHOS::Rosen::Window> rsWindow, UIEnvCallback callback)1106 void AceContainer::SetView(const RefPtr<AceView>& view, double density, int32_t width, int32_t height,
1107     sptr<OHOS::Rosen::Window> rsWindow, UIEnvCallback callback)
1108 {
1109     CHECK_NULL_VOID(view);
1110     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(view->GetInstanceId()));
1111     CHECK_NULL_VOID(container);
1112 #ifdef ENABLE_ROSEN_BACKEND
1113     auto taskExecutor = container->GetTaskExecutor();
1114     CHECK_NULL_VOID(taskExecutor);
1115     auto window = std::make_shared<NG::RosenWindow>(rsWindow, taskExecutor, view->GetInstanceId());
1116 #else
1117     auto platformWindow = PlatformWindow::Create(view);
1118     CHECK_NULL_VOID(platformWindow);
1119     auto window = std::make_shared<Window>(std::move(platformWindow));
1120 #endif
1121     AceContainer::SetUIWindow(view->GetInstanceId(), rsWindow);
1122     container->AttachView(window, view, density, width, height, rsWindow->GetWindowId(), callback);
1123 }
1124 
SetViewNew( const RefPtr<AceView>& view, double density, float width, float height, sptr<OHOS::Rosen::Window> rsWindow)1125 UIContentErrorCode AceContainer::SetViewNew(
1126     const RefPtr<AceView>& view, double density, float width, float height, sptr<OHOS::Rosen::Window> rsWindow)
1127 {
1128 #ifdef ENABLE_ROSEN_BACKEND
1129     CHECK_NULL_RETURN(view, UIContentErrorCode::NULL_POINTER);
1130     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(view->GetInstanceId()));
1131     CHECK_NULL_RETURN(container, UIContentErrorCode::NULL_POINTER);
1132     auto taskExecutor = container->GetTaskExecutor();
1133     CHECK_NULL_RETURN(taskExecutor, UIContentErrorCode::NULL_POINTER);
1134     AceContainer::SetUIWindow(view->GetInstanceId(), rsWindow);
1135 
1136     if (container->isFormRender_) {
1137         auto window = std::make_shared<FormRenderWindow>(taskExecutor, view->GetInstanceId());
1138         container->AttachView(window, view, density, width, height, view->GetInstanceId(), nullptr);
1139     } else {
1140         auto window = std::make_shared<NG::RosenWindow>(rsWindow, taskExecutor, view->GetInstanceId());
1141         container->AttachView(window, view, density, width, height, rsWindow->GetWindowId(), nullptr);
1142     }
1143 
1144     return UIContentErrorCode::NO_ERRORS;
1145 #endif
1146 }
1147 
SetUIWindow(int32_t instanceId, sptr<OHOS::Rosen::Window> uiWindow)1148 void AceContainer::SetUIWindow(int32_t instanceId, sptr<OHOS::Rosen::Window> uiWindow)
1149 {
1150     CHECK_NULL_VOID(uiWindow);
1151     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1152     CHECK_NULL_VOID(container);
1153     container->SetUIWindowInner(uiWindow);
1154 }
1155 
GetUIWindow(int32_t instanceId)1156 sptr<OHOS::Rosen::Window> AceContainer::GetUIWindow(int32_t instanceId)
1157 {
1158     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1159     CHECK_NULL_RETURN(container, nullptr);
1160     return container->GetUIWindowInner();
1161 }
1162 
GetAbility(int32_t instanceId)1163 OHOS::AppExecFwk::Ability* AceContainer::GetAbility(int32_t instanceId)
1164 {
1165     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1166     CHECK_NULL_RETURN(container, nullptr);
1167     return container->GetAbilityInner().lock().get();
1168 }
1169 
GetRuntimeContext(int32_t instanceId)1170 OHOS::AbilityRuntime::Context* AceContainer::GetRuntimeContext(int32_t instanceId)
1171 {
1172     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1173     CHECK_NULL_RETURN(container, nullptr);
1174     return container->GetRuntimeContextInner().lock().get();
1175 }
1176 
RunPage( int32_t instanceId, const std::string& content, const std::string& params, bool isNamedRouter)1177 UIContentErrorCode AceContainer::RunPage(
1178     int32_t instanceId, const std::string& content, const std::string& params, bool isNamedRouter)
1179 {
1180     auto container = AceEngine::Get().GetContainer(instanceId);
1181     CHECK_NULL_RETURN(container, UIContentErrorCode::NULL_POINTER);
1182 
1183     auto aceContainer = DynamicCast<AceContainer>(container);
1184     CHECK_NULL_RETURN(aceContainer, UIContentErrorCode::NULL_POINTER);
1185     bool isStageModel = aceContainer->IsUseStageModel();
1186     bool isFormRender = aceContainer->IsFormRender();
1187     if (isStageModel && content.size() == 0) {
1188         return UIContentErrorCode::NULL_URL;
1189     }
1190 
1191     ContainerScope scope(instanceId);
1192     auto front = container->GetFrontend();
1193     CHECK_NULL_RETURN(front, UIContentErrorCode::NULL_POINTER);
1194 
1195     if (front->GetType() != FrontendType::DECLARATIVE_CJ && !isFormRender && !isNamedRouter &&
1196         isStageModel && !CheckUrlValid(content, container->GetHapPath())) {
1197         return UIContentErrorCode::INVALID_URL;
1198     }
1199 
1200     if (isNamedRouter) {
1201         return front->RunPageByNamedRouter(content, params);
1202     }
1203 
1204     return front->RunPage(content, params);
1205 }
1206 
RunPage( int32_t instanceId, const std::shared_ptr<std::vector<uint8_t>>& content, const std::string& params)1207 UIContentErrorCode AceContainer::RunPage(
1208     int32_t instanceId, const std::shared_ptr<std::vector<uint8_t>>& content, const std::string& params)
1209 {
1210     auto container = AceEngine::Get().GetContainer(instanceId);
1211     CHECK_NULL_RETURN(container, UIContentErrorCode::NULL_POINTER);
1212     ContainerScope scope(instanceId);
1213     auto front = container->GetFrontend();
1214     CHECK_NULL_RETURN(front, UIContentErrorCode::NULL_POINTER);
1215     return front->RunPage(content, params);
1216 }
1217 
RunDynamicPage( int32_t instanceId, const std::string& content, const std::string& params, const std::string& entryPoint)1218 bool AceContainer::RunDynamicPage(
1219     int32_t instanceId, const std::string& content, const std::string& params, const std::string& entryPoint)
1220 {
1221     auto container = AceEngine::Get().GetContainer(instanceId);
1222     CHECK_NULL_RETURN(container, false);
1223     ContainerScope scope(instanceId);
1224     auto front = container->GetFrontend();
1225     CHECK_NULL_RETURN(front, false);
1226     front->RunDynamicPage(content, params, entryPoint);
1227     return true;
1228 }
1229 
PushPage(int32_t instanceId, const std::string& content, const std::string& params)1230 bool AceContainer::PushPage(int32_t instanceId, const std::string& content, const std::string& params)
1231 {
1232     auto container = AceEngine::Get().GetContainer(instanceId);
1233     CHECK_NULL_RETURN(container, false);
1234     ContainerScope scope(instanceId);
1235     auto front = container->GetFrontend();
1236     CHECK_NULL_RETURN(front, false);
1237     front->PushPage(content, params);
1238     return true;
1239 }
1240 
UpdatePage(int32_t instanceId, int32_t pageId, const std::string& content)1241 bool AceContainer::UpdatePage(int32_t instanceId, int32_t pageId, const std::string& content)
1242 {
1243     auto container = AceEngine::Get().GetContainer(instanceId);
1244     CHECK_NULL_RETURN(container, false);
1245     ContainerScope scope(instanceId);
1246     auto context = container->GetPipelineContext();
1247     CHECK_NULL_RETURN(context, false);
1248     return context->CallRouterBackToPopPage();
1249 }
1250 
1251 class FillRequestCallback : public AbilityRuntime::IFillRequestCallback {
1252 public:
FillRequestCallback(WeakPtr<NG::PipelineContext> pipelineContext, const RefPtr<NG::FrameNode>& node, AceAutoFillType autoFillType, bool isNative = true)1253     FillRequestCallback(WeakPtr<NG::PipelineContext> pipelineContext, const RefPtr<NG::FrameNode>& node,
1254         AceAutoFillType autoFillType, bool isNative = true)
1255         : pipelineContext_(pipelineContext), node_(node), autoFillType_(autoFillType), isNative_(isNative) {}
1256     virtual ~FillRequestCallback() = default;
1257     void OnFillRequestSuccess(const AbilityBase::ViewData& viewData) override
1258     {
1259         TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called, pageUrl=[%{private}s]", viewData.pageUrl.c_str());
1260         auto pipelineContext = pipelineContext_.Upgrade();
1261         CHECK_NULL_VOID(pipelineContext);
1262         auto taskExecutor = pipelineContext->GetTaskExecutor();
1263         CHECK_NULL_VOID(taskExecutor);
1264         auto viewDataWrap = ViewDataWrap::CreateViewDataWrap(viewData);
1265         CHECK_NULL_VOID(viewDataWrap);
1266         if (!isNative_) {
1267             auto node = node_.Upgrade();
1268             CHECK_NULL_VOID(node);
1269             taskExecutor->PostTask(
1270                 [viewDataWrap, node, autoFillType = autoFillType_]() {
1271                     if (node) {
1272                         node->NotifyFillRequestSuccess(viewDataWrap, nullptr, autoFillType);
1273                     }
1274                 },
1275                 TaskExecutor::TaskType::UI, "ArkUINotifyWebFillRequestSuccess");
1276             return;
1277         }
1278 
1279         taskExecutor->PostTask(
1280             [viewDataWrap, pipelineContext, autoFillType = autoFillType_]() {
1281                 if (pipelineContext) {
1282                     pipelineContext->NotifyFillRequestSuccess(autoFillType, viewDataWrap);
1283                 }
1284             },
1285             TaskExecutor::TaskType::UI, "ArkUINotifyFillRequestSuccess");
1286     }
1287 
1288     void OnFillRequestFailed(int32_t errCode, const std::string& fillContent, bool isPopup) override
1289     {
1290         TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called, errCode: %{public}d", errCode);
1291         auto pipelineContext = pipelineContext_.Upgrade();
1292         CHECK_NULL_VOID(pipelineContext);
1293         auto node = node_.Upgrade();
1294         CHECK_NULL_VOID(node);
1295         auto taskExecutor = pipelineContext->GetTaskExecutor();
1296         CHECK_NULL_VOID(taskExecutor);
1297         taskExecutor->PostTask(
1298             [errCode, pipelineContext, node, fillContent, isPopup]() {
1299                 if (pipelineContext) {
1300                     pipelineContext->NotifyFillRequestFailed(node, errCode, fillContent, isPopup);
1301                 }
1302             },
1303             TaskExecutor::TaskType::UI, "ArkUINotifyFillRequestFailed");
1304     }
1305 
1306     void onPopupConfigWillUpdate(AbilityRuntime::AutoFill::AutoFillCustomConfig& config) override
1307     {
1308         // Non-native component like web/xcomponent
1309         // The offset needs to be calculated based on the placement
1310         if (isNative_ || !config.targetSize.has_value() || !config.placement.has_value()) {
1311             return;
1312         }
1313         AbilityRuntime::AutoFill::PopupOffset offset;
1314         offset.deltaX = GetPopupConfigWillUpdateX(config);
1315         offset.deltaY = GetPopupConfigWillUpdateY(config);
1316         TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "PopupOffset x:%{public}f,y:%{public}f", offset.deltaX, offset.deltaY);
1317         config.targetOffset = offset;
1318         config.placement = AbilityRuntime::AutoFill::PopupPlacement::BOTTOM;
1319     }
1320 
SetFocusedRect(AbilityBase::Rect rect)1321     void SetFocusedRect(AbilityBase::Rect rect)
1322     {
1323         rect_ = rect;
1324     }
1325 
SetWindowRect(Rosen::Rect rect)1326     void SetWindowRect(Rosen::Rect rect)
1327     {
1328         windowRect_ = rect;
1329     }
1330 private:
GetPopupConfigWillUpdateY(AbilityRuntime::AutoFill::AutoFillCustomConfig& config)1331     double GetPopupConfigWillUpdateY(AbilityRuntime::AutoFill::AutoFillCustomConfig& config)
1332     {
1333         auto node = node_.Upgrade();
1334         CHECK_NULL_RETURN(node, 0);
1335         auto rectf = node->GetRectWithRender();
1336         double deltaY = 0;
1337         AbilityRuntime::AutoFill::PopupPlacement placement = config.placement.value();
1338         AbilityRuntime::AutoFill::PopupSize size = config.targetSize.value();
1339 
1340         auto trans = node->GetTransformRelativeOffset();
1341         auto bottomAvoidHeight = GetBottomAvoidHeight();
1342 
1343         bool isBottom = placement == AbilityRuntime::AutoFill::PopupPlacement::BOTTOM ||
1344                 placement == AbilityRuntime::AutoFill::PopupPlacement::BOTTOM_LEFT ||
1345                 placement == AbilityRuntime::AutoFill::PopupPlacement::BOTTOM_RIGHT;
1346 
1347         if ((windowRect_.height_ - rectf.Height() - trans.GetY()) >
1348             (size.height + POPUP_EDGE_INTERVAL + bottomAvoidHeight)) {
1349             // popup will display at the bottom of the container
1350             if (isBottom) {
1351                 deltaY = rect_.top + rect_.height - rectf.Height() - trans.GetY();
1352             } else {
1353                 deltaY = rect_.top - rectf.Height() - size.height - trans.GetY() - POPUP_EDGE_INTERVAL;
1354             }
1355         } else {
1356             // popup will display in the middle of the container
1357             if (isBottom) {
1358                 deltaY = rect_.top + rect_.height -
1359                     ((rectf.Height() - size.height) / POPUP_CALCULATE_RATIO) - trans.GetY();
1360             } else {
1361                 deltaY = rect_.top - ((rectf.Height() + size.height) / POPUP_CALCULATE_RATIO) - trans.GetY();
1362             }
1363         }
1364         return deltaY;
1365     }
1366 
GetPopupConfigWillUpdateX(AbilityRuntime::AutoFill::AutoFillCustomConfig& config)1367     double GetPopupConfigWillUpdateX(AbilityRuntime::AutoFill::AutoFillCustomConfig& config)
1368     {
1369         auto node = node_.Upgrade();
1370         CHECK_NULL_RETURN(node, 0);
1371         auto rectf = node->GetRectWithRender();
1372         double deltaX = 0;
1373         AbilityRuntime::AutoFill::PopupPlacement placement = config.placement.value();
1374         AbilityRuntime::AutoFill::PopupSize size = config.targetSize.value();
1375 
1376         if (placement == AbilityRuntime::AutoFill::PopupPlacement::TOP_LEFT ||
1377             placement == AbilityRuntime::AutoFill::PopupPlacement::BOTTOM_LEFT) {
1378             double edgeDist = (rectf.Width() - size.width) / POPUP_CALCULATE_RATIO;
1379             deltaX = rect_.left - edgeDist;
1380             if (deltaX > edgeDist) {
1381                 deltaX = edgeDist;
1382             }
1383             if (rect_.left + size.width > windowRect_.width_) {
1384                 deltaX = windowRect_.width_ - size.width - edgeDist;
1385             }
1386             if (edgeDist + size.width > windowRect_.width_) {
1387                 deltaX = 0;
1388             }
1389         }
1390 
1391         if (placement == AbilityRuntime::AutoFill::PopupPlacement::TOP_RIGHT ||
1392             placement == AbilityRuntime::AutoFill::PopupPlacement::BOTTOM_RIGHT) {
1393             double edgeDist = (rectf.Width() - size.width) / POPUP_CALCULATE_RATIO;
1394             deltaX = edgeDist + rect_.left + rect_.width - rectf.Width();
1395             if ((deltaX < -DBL_EPSILON) && (std::fabs(deltaX) > edgeDist)) {
1396                 deltaX = -edgeDist;
1397             }
1398         }
1399         return deltaX;
1400     }
1401 
GetBottomAvoidHeight()1402     uint32_t GetBottomAvoidHeight()
1403     {
1404         auto containerId = Container::CurrentId();
1405         RefPtr<NG::PipelineContext> pipelineContext;
1406         if (containerId >= MIN_SUBCONTAINER_ID) {
1407             auto parentContainerId = SubwindowManager::GetInstance()->GetParentContainerId(containerId);
1408             auto parentContainer = AceEngine::Get().GetContainer(parentContainerId);
1409             CHECK_NULL_RETURN(parentContainer, 0);
1410             pipelineContext = AceType::DynamicCast<NG::PipelineContext>(parentContainer->GetPipelineContext());
1411         } else {
1412             pipelineContext = NG::PipelineContext::GetCurrentContext();
1413         }
1414         CHECK_NULL_RETURN(pipelineContext, 0);
1415         auto safeAreaManager = pipelineContext->GetSafeAreaManager();
1416         CHECK_NULL_RETURN(safeAreaManager, 0);
1417         return safeAreaManager->GetSystemSafeArea().bottom_.Length();
1418     }
1419 
1420     WeakPtr<NG::PipelineContext> pipelineContext_ = nullptr;
1421     WeakPtr<NG::FrameNode> node_ = nullptr;
1422     AceAutoFillType autoFillType_ = AceAutoFillType::ACE_UNSPECIFIED;
1423     bool isNative_ = true;
1424     AbilityBase::Rect rect_;
1425     Rosen::Rect windowRect_ { 0, 0, 0, 0 };
1426 };
1427 
UpdatePopupUIExtension(const RefPtr<NG::FrameNode>& node, uint32_t autoFillSessionId, bool isNative)1428 bool AceContainer::UpdatePopupUIExtension(const RefPtr<NG::FrameNode>& node,
1429     uint32_t autoFillSessionId, bool isNative)
1430 {
1431     CHECK_NULL_RETURN(node, false);
1432     CHECK_NULL_RETURN(uiWindow_, false);
1433     auto uiContent = uiWindow_->GetUIContent();
1434     auto uiContentImpl = reinterpret_cast<UIContentImpl*>(uiContent);
1435     CHECK_NULL_RETURN(uiContentImpl, false);
1436     auto viewDataWrap = ViewDataWrap::CreateViewDataWrap();
1437     auto autoFillContainerNode = node->GetFirstAutoFillContainerNode();
1438     uiContentImpl->DumpViewData(autoFillContainerNode, viewDataWrap, true);
1439     auto viewDataWrapOhos = AceType::DynamicCast<ViewDataWrapOhos>(viewDataWrap);
1440     CHECK_NULL_RETURN(viewDataWrapOhos, false);
1441     auto viewData = viewDataWrapOhos->GetViewData();
1442     if (!isNative) {
1443         OverwritePageNodeInfo(node, viewData);
1444     }
1445     AbilityRuntime::AutoFillManager::GetInstance().UpdateCustomPopupUIExtension(autoFillSessionId, viewData);
1446     return true;
1447 }
1448 
ClosePopupUIExtension(uint32_t autoFillSessionId)1449 bool AceContainer::ClosePopupUIExtension(uint32_t autoFillSessionId)
1450 {
1451     AbilityRuntime::AutoFillManager::GetInstance().CloseUIExtension(autoFillSessionId);
1452     return true;
1453 }
1454 
PlaceHolderToType(const std::string& onePlaceHolder)1455 HintToTypeWrap AceContainer::PlaceHolderToType(const std::string& onePlaceHolder)
1456 {
1457     HintToTypeWrap hintToTypeWrap;
1458     auto viewDataWrap = ViewDataWrap::CreateViewDataWrap();
1459     CHECK_NULL_RETURN(viewDataWrap, hintToTypeWrap);
1460     auto viewDataWrapOhos = AceType::DynamicCast<ViewDataWrapOhos>(viewDataWrap);
1461     CHECK_NULL_RETURN(viewDataWrapOhos, hintToTypeWrap);
1462     std::vector<std::string> placeHolder;
1463     std::vector<int> intType;
1464     std::vector<std::string> metadata;
1465     placeHolder.push_back(onePlaceHolder);
1466     auto isSuccess = viewDataWrapOhos->LoadHint2Type(placeHolder, intType, metadata);
1467     if (!isSuccess) {
1468         TAG_LOGE(AceLogTag::ACE_AUTO_FILL, "Load Hint2Type Failed !");
1469         return hintToTypeWrap;
1470     }
1471     if (intType.empty()) {
1472         return hintToTypeWrap;
1473     }
1474     hintToTypeWrap.autoFillType = static_cast<AceAutoFillType>(viewDataWrapOhos->HintToAutoFillType(intType[0]));
1475     if (!metadata.empty()) {
1476         hintToTypeWrap.metadata = metadata[0];
1477     }
1478     return hintToTypeWrap;
1479 }
1480 
FillAutoFillViewData(const RefPtr<NG::FrameNode> &node, RefPtr<ViewDataWrap> &viewDataWrap)1481 void AceContainer::FillAutoFillViewData(const RefPtr<NG::FrameNode> &node, RefPtr<ViewDataWrap> &viewDataWrap)
1482 {
1483     CHECK_NULL_VOID(node);
1484     CHECK_NULL_VOID(viewDataWrap);
1485     auto nodeInfoWraps = viewDataWrap->GetPageNodeInfoWraps();
1486     auto pattern = node->GetPattern<NG::TextFieldPattern>();
1487     CHECK_NULL_VOID(pattern);
1488     auto autoFillUserName = pattern->GetAutoFillUserName();
1489     auto autoFillNewPassword = pattern->GetAutoFillNewPassword();
1490     if (!autoFillUserName.empty()) {
1491         for (auto nodeInfoWrap : nodeInfoWraps) {
1492             if (!nodeInfoWrap) {
1493                 continue;
1494             }
1495             auto metadataObject = JsonUtil::ParseJsonString(nodeInfoWrap->GetMetadata());
1496             if (nodeInfoWrap->GetAutoFillType() == AceAutoFillType::ACE_USER_NAME) {
1497                 nodeInfoWrap->SetValue(autoFillUserName);
1498                 viewDataWrap->SetUserSelected(true);
1499                 break;
1500             } else if (nodeInfoWrap->GetAutoFillType() == AceAutoFillType::ACE_UNSPECIFIED && metadataObject &&
1501                        metadataObject->Contains("type")) {
1502                 metadataObject->Put("username", autoFillUserName.c_str());
1503                 nodeInfoWrap->SetMetadata(metadataObject->ToString());
1504                 viewDataWrap->SetUserSelected(true);
1505             }
1506         }
1507         pattern->SetAutoFillUserName("");
1508     }
1509     if (!autoFillNewPassword.empty()) {
1510         for (auto nodeInfoWrap : nodeInfoWraps) {
1511             if (nodeInfoWrap && nodeInfoWrap->GetAutoFillType() == AceAutoFillType::ACE_NEW_PASSWORD) {
1512                 nodeInfoWrap->SetValue(autoFillNewPassword);
1513                 pattern->SetAutoFillNewPassword("");
1514                 break;
1515             }
1516         }
1517     }
1518 }
1519 
OverwritePageNodeInfo(const RefPtr<NG::FrameNode>& frameNode, AbilityBase::ViewData& viewData)1520 void AceContainer::OverwritePageNodeInfo(const RefPtr<NG::FrameNode>& frameNode,
1521     AbilityBase::ViewData& viewData)
1522 {
1523     // Non-native component like web/xcomponent, does not have PageNodeInfo
1524     CHECK_NULL_VOID(frameNode);
1525     auto pattern = frameNode->GetPattern();
1526     CHECK_NULL_VOID(pattern);
1527     std::vector<AbilityBase::PageNodeInfo> nodeInfos;
1528     auto viewDataWrap = ViewDataWrap::CreateViewDataWrap();
1529     pattern->DumpViewDataPageNode(viewDataWrap);
1530     auto infos = viewDataWrap->GetPageNodeInfoWraps();
1531     for (const auto& info : infos) {
1532         if (!info) {
1533             continue;
1534         }
1535         AbilityBase::PageNodeInfo node;
1536         node.id = info->GetId();
1537         node.depth = -1;
1538         node.autoFillType = static_cast<AbilityBase::AutoFillType>(info->GetAutoFillType());
1539         node.isFocus = info->GetIsFocus();
1540         node.value = info->GetValue();
1541         node.placeholder = info->GetPlaceholder();
1542         node.metadata = info->GetMetadata();
1543         NG::RectF rectF = info->GetPageNodeRect();
1544         node.rect.left = rectF.GetX();
1545         node.rect.top = rectF.GetY();
1546         node.rect.width = rectF.Width();
1547         node.rect.height = rectF.Height();
1548         nodeInfos.emplace_back(node);
1549     }
1550     viewData.nodes = nodeInfos;
1551     viewData.pageUrl = viewDataWrap->GetPageUrl();
1552 }
1553 
FillAutoFillCustomConfig(const RefPtr<NG::FrameNode>& node, AbilityRuntime::AutoFill::AutoFillCustomConfig& customConfig, bool isNative)1554 void FillAutoFillCustomConfig(const RefPtr<NG::FrameNode>& node,
1555     AbilityRuntime::AutoFill::AutoFillCustomConfig& customConfig, bool isNative)
1556 {
1557     CHECK_NULL_VOID(node);
1558     AbilityRuntime::AutoFill::PopupSize popupSize;
1559     popupSize.height = POPUPSIZE_HEIGHT;
1560     popupSize.width = POPUPSIZE_WIDTH;
1561     customConfig.targetSize = popupSize;
1562     customConfig.isShowInSubWindow = false;
1563     customConfig.nodeId = node->GetId();
1564     customConfig.isEnableArrow = false;
1565     if (!isNative) {
1566         // web component will manually destroy the popup
1567         customConfig.isAutoCancel = true;
1568     }
1569 }
1570 
GetFocusedElementRect(const AbilityBase::ViewData& viewData, AbilityBase::Rect& rect)1571 void GetFocusedElementRect(const AbilityBase::ViewData& viewData, AbilityBase::Rect& rect)
1572 {
1573     for (const auto& info : viewData.nodes) {
1574         if (info.isFocus) {
1575             rect = info.rect;
1576         }
1577     }
1578 }
1579 
RequestAutoFill(const RefPtr<NG::FrameNode>& node, AceAutoFillType autoFillType, bool isNewPassWord, bool& isPopup, uint32_t& autoFillSessionId, bool isNative)1580 bool AceContainer::RequestAutoFill(const RefPtr<NG::FrameNode>& node, AceAutoFillType autoFillType,
1581     bool isNewPassWord, bool& isPopup, uint32_t& autoFillSessionId, bool isNative)
1582 {
1583     TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called, autoFillType: %{public}d", static_cast<int32_t>(autoFillType));
1584     auto pipelineContext = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
1585     CHECK_NULL_RETURN(node, false);
1586     CHECK_NULL_RETURN(pipelineContext, false);
1587     CHECK_NULL_RETURN(uiWindow_, false);
1588     auto uiContent = uiWindow_->GetUIContent();
1589     CHECK_NULL_RETURN(uiContent, false);
1590     auto uiContentImpl = reinterpret_cast<UIContentImpl*>(uiContent);
1591     CHECK_NULL_RETURN(uiContentImpl, false);
1592     auto viewDataWrap = ViewDataWrap::CreateViewDataWrap();
1593     CHECK_NULL_RETURN(viewDataWrap, false);
1594     auto autoFillContainerNode = node->GetFirstAutoFillContainerNode();
1595     uiContentImpl->DumpViewData(autoFillContainerNode, viewDataWrap, true);
1596     FillAutoFillViewData(node, viewDataWrap);
1597     auto callback = std::make_shared<FillRequestCallback>(pipelineContext, node, autoFillType, isNative);
1598     auto viewDataWrapOhos = AceType::DynamicCast<ViewDataWrapOhos>(viewDataWrap);
1599     CHECK_NULL_RETURN(viewDataWrapOhos, false);
1600     auto viewData = viewDataWrapOhos->GetViewData();
1601     TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "isNewPassWord is: %{public}d", isNewPassWord);
1602     if (isNewPassWord) {
1603         callback->OnFillRequestSuccess(viewData);
1604         return true;
1605     }
1606     if (!isNative) {
1607         OverwritePageNodeInfo(node, viewData);
1608         AbilityBase::Rect rect;
1609         GetFocusedElementRect(viewData, rect);
1610         callback->SetFocusedRect(rect);
1611         callback->SetWindowRect(uiWindow_->GetRect());
1612     }
1613     AbilityRuntime::AutoFill::AutoFillCustomConfig customConfig;
1614     FillAutoFillCustomConfig(node, customConfig, isNative);
1615     AbilityRuntime::AutoFill::AutoFillRequest autoFillRequest;
1616     autoFillRequest.config = customConfig;
1617     autoFillRequest.autoFillType = static_cast<AbilityBase::AutoFillType>(autoFillType);
1618     autoFillRequest.autoFillCommand = AbilityRuntime::AutoFill::AutoFillCommand::FILL;
1619     autoFillRequest.viewData = viewData;
1620     AbilityRuntime::AutoFill::AutoFillResult result;
1621     if (AbilityRuntime::AutoFillManager::GetInstance().RequestAutoFill(
1622         uiContent, autoFillRequest, callback, result) != 0) {
1623         return false;
1624     }
1625     isPopup = result.isPopup;
1626     autoFillSessionId = result.autoFillSessionId;
1627     return true;
1628 }
1629 
IsNeedToCreatePopupWindow(const AceAutoFillType& autoFillType)1630 bool AceContainer::IsNeedToCreatePopupWindow(const AceAutoFillType& autoFillType)
1631 {
1632     return AbilityRuntime::AutoFillManager::GetInstance().IsNeedToCreatePopupWindow(
1633         static_cast<AbilityBase::AutoFillType>(autoFillType));
1634 }
1635 
1636 class SaveRequestCallback : public AbilityRuntime::ISaveRequestCallback {
1637 public:
SaveRequestCallback(WeakPtr<NG::PipelineContext> pipelineContext, const std::function<void()>& onFinish)1638     SaveRequestCallback(WeakPtr<NG::PipelineContext> pipelineContext, const std::function<void()>& onFinish)
1639         : pipelineContext_(pipelineContext), onFinish_(onFinish) {}
1640     virtual ~SaveRequestCallback() = default;
1641     void OnSaveRequestSuccess() override
1642     {
1643         TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called");
1644         ProcessOnFinish();
1645     }
1646 
1647     void OnSaveRequestFailed() override
1648     {
1649         TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called");
1650         ProcessOnFinish();
1651     }
1652 
ProcessOnFinish()1653     void ProcessOnFinish()
1654     {
1655         if (!onFinish_) {
1656             return;
1657         }
1658         auto pipelineContext = pipelineContext_.Upgrade();
1659         CHECK_NULL_VOID(pipelineContext);
1660         auto taskExecutor = pipelineContext->GetTaskExecutor();
1661         CHECK_NULL_VOID(taskExecutor);
1662         taskExecutor->PostTask(
1663             [onFinish = std::move(onFinish_)]() mutable {
1664                 if (onFinish) {
1665                     onFinish();
1666                     onFinish = nullptr;
1667                 }
1668             },
1669             TaskExecutor::TaskType::UI, "ProcessOnFinish");
1670     }
1671 private:
1672     WeakPtr<NG::PipelineContext> pipelineContext_ = nullptr;
1673     std::function<void()> onFinish_;
1674 };
1675 
RequestAutoSave(const RefPtr<NG::FrameNode>& node, const std::function<void()>& onFinish, const std::function<void()>& onUIExtNodeBindingCompleted, bool isNative, int32_t instanceId)1676 bool AceContainer::RequestAutoSave(const RefPtr<NG::FrameNode>& node, const std::function<void()>& onFinish,
1677     const std::function<void()>& onUIExtNodeBindingCompleted, bool isNative, int32_t instanceId)
1678 {
1679     TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called");
1680     CHECK_NULL_RETURN(uiWindow_, false);
1681     auto uiContent = uiWindow_->GetUIContent();
1682     auto uiContentImpl = reinterpret_cast<UIContentImpl*>(uiContent);
1683     CHECK_NULL_RETURN(uiContentImpl, false);
1684     auto viewDataWrap = ViewDataWrap::CreateViewDataWrap();
1685     uiContentImpl->DumpViewData(node, viewDataWrap, false, true);
1686 
1687     auto pipelineContext = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
1688     CHECK_NULL_RETURN(pipelineContext, false);
1689     auto callback = std::make_shared<SaveRequestCallback>(pipelineContext, onFinish);
1690     auto viewDataWrapOhos = AceType::DynamicCast<ViewDataWrapOhos>(viewDataWrap);
1691     CHECK_NULL_RETURN(viewDataWrapOhos, false);
1692     auto viewData = viewDataWrapOhos->GetViewData();
1693     if (!isNative) {
1694         OverwritePageNodeInfo(node, viewData);
1695     }
1696     AbilityRuntime::AutoFill::AutoFillRequest autoFillRequest;
1697     autoFillRequest.viewData = viewData;
1698     autoFillRequest.autoFillCommand = AbilityRuntime::AutoFill::AutoFillCommand::SAVE;
1699     autoFillRequest.autoFillType = ViewDataWrap::ViewDataToType(viewData);
1700     autoFillRequest.doAfterAsyncModalBinding = std::move(onUIExtNodeBindingCompleted);
1701     if (instanceId != -1) {
1702         auto uiWindow = GetUIWindow(instanceId);
1703         CHECK_NULL_RETURN(uiWindow, false);
1704         uiContent = uiWindow->GetUIContent();
1705         CHECK_NULL_RETURN(uiContent, false);
1706     }
1707     AbilityRuntime::AutoFill::AutoFillResult result;
1708     if (AbilityRuntime::AutoFillManager::GetInstance().RequestAutoSave(
1709         uiContent, autoFillRequest, callback, result) != 0) {
1710         return false;
1711     }
1712     return true;
1713 }
1714 
GetNavigationController( const std::string& navigationId)1715 std::shared_ptr<NavigationController> AceContainer::GetNavigationController(
1716     const std::string& navigationId)
1717 {
1718     CHECK_NULL_RETURN(pipelineContext_, nullptr);
1719     return pipelineContext_->GetNavigationController(navigationId);
1720 }
1721 
SetHapPath(const std::string& hapPath)1722 void AceContainer::SetHapPath(const std::string& hapPath)
1723 {
1724     if (hapPath.empty()) {
1725         LOGW("SetHapPath, Use .index to load resource");
1726         return;
1727     }
1728     LOGI("SetHapPath, Use hap path to load resource");
1729     webHapPath_ = hapPath;
1730     resourceInfo_.SetHapPath(hapPath);
1731     SystemProperties::SetUnZipHap(false);
1732 }
1733 
Dispatch( const std::string& group, std::vector<uint8_t>&& data, int32_t id, bool replyToComponent) const1734 void AceContainer::Dispatch(
1735     const std::string& group, std::vector<uint8_t>&& data, int32_t id, bool replyToComponent) const
1736 {
1737     return;
1738 }
1739 
DispatchPluginError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const1740 void AceContainer::DispatchPluginError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const
1741 {
1742     auto front = GetFrontend();
1743     CHECK_NULL_VOID(front);
1744     ContainerScope scope(instanceId_);
1745     taskExecutor_->PostTask(
1746         [front, callbackId, errorCode, errorMessage = std::move(errorMessage)]() mutable {
1747             front->TransferJsPluginGetError(callbackId, errorCode, std::move(errorMessage));
1748         },
1749         TaskExecutor::TaskType::BACKGROUND, "ArkUIDispatchPluginError");
1750 }
1751 
Dump(const std::vector<std::string>& params, std::vector<std::string>& info)1752 bool AceContainer::Dump(const std::vector<std::string>& params, std::vector<std::string>& info)
1753 {
1754     if (isDumping_.test_and_set()) {
1755         LOGW("another dump is still running");
1756         return false;
1757     }
1758     ContainerScope scope(instanceId_);
1759     auto result = false;
1760     paramUie_.assign(params.begin(), params.end());
1761     std::unique_ptr<std::ostream> ostream = std::make_unique<std::ostringstream>();
1762     CHECK_NULL_RETURN(ostream, false);
1763     DumpLog::GetInstance().SetDumpFile(std::move(ostream));
1764     if (IsUIExtensionWindow()) {
1765         DumpLog::GetInstance().SetSeparator(";");
1766     }
1767     auto context = runtimeContext_.lock();
1768     DumpLog::GetInstance().Print("bundleName:" + context->GetHapModuleInfo()->bundleName);
1769     DumpLog::GetInstance().Print("moduleName:" + context->GetHapModuleInfo()->moduleName);
1770     result = DumpInfo(params);
1771     const auto& infoFile = DumpLog::GetInstance().GetDumpFile();
1772     auto* ostringstream = static_cast<std::ostringstream*>(infoFile.get());
1773     info.emplace_back(ostringstream->str());
1774     DumpLog::GetInstance().Reset();
1775     if (!result) {
1776         DumpLog::ShowDumpHelp(info);
1777     }
1778     isDumping_.clear();
1779     return true;
1780 }
1781 
DumpInfo(const std::vector<std::string>& params)1782 bool AceContainer::DumpInfo(const std::vector<std::string>& params)
1783 {
1784     if (aceView_ && aceView_->Dump(params)) {
1785         return true;
1786     }
1787 
1788     if (OnDumpInfo(params)) {
1789         return true;
1790     }
1791     CHECK_NULL_RETURN(pipelineContext_, false);
1792     return pipelineContext_->Dump(params);
1793 }
1794 
OnDumpInfo(const std::vector<std::string>& params)1795 bool AceContainer::OnDumpInfo(const std::vector<std::string>& params)
1796 {
1797     if (!params.empty() && params[0] == "-basicinfo") {
1798         DumpLog::GetInstance().Print("BasicInfo: ");
1799         DumpLog::GetInstance().Print(1, "InstanceId: " + std::to_string(instanceId_));
1800         DumpLog::GetInstance().Print(1,
1801             "FrontendType: " + std::to_string(static_cast<typename std::underlying_type<FrontendType>::type>(type_)));
1802         DumpLog::GetInstance().Print(1, "NewPipeline: " + std::string(IsUseNewPipeline() ? "true" : "false"));
1803         DumpLog::GetInstance().Print(1, "WindowName: " + windowName_);
1804         DumpLog::GetInstance().Print(
1805             1, "WindowState: " +
1806                    (!frontend_ ? "frontend is null"
1807                                : std::to_string(static_cast<typename std::underlying_type<Frontend::State>::type>(
1808                                      frontend_->GetState()))));
1809         DumpLog::GetInstance().Print(1, "Language: " + AceApplicationInfo::GetInstance().GetLocaleTag());
1810         DumpLog::GetInstance().Print(
1811             1, "RTL: " + std::string(AceApplicationInfo::GetInstance().IsRightToLeft() ? "true" : "false"));
1812         DumpLog::GetInstance().Print(
1813             1, "ColorMode: " + std::string(SystemProperties::GetColorMode() == ColorMode::DARK ? "Dark" : "Light"));
1814         DumpLog::GetInstance().Print(1,
1815             "DeviceOrientation: " + std::string(SystemProperties::GetDeviceOrientation() == DeviceOrientation::LANDSCAPE
1816                                                     ? "Landscape"
1817                                                     : "Portrait"));
1818         DumpLog::GetInstance().Print(1, "Resolution: " + std::to_string(SystemProperties::GetDeviceWidth()) + "*" +
1819                                             std::to_string(SystemProperties::GetDeviceHeight()));
1820         if (pipelineContext_) {
1821             DumpLog::GetInstance().Print(1, "AppBgColor: " + pipelineContext_->GetAppBgColor().ColorToString());
1822             DumpLog::GetInstance().Print(1, "Density: " + std::to_string(pipelineContext_->GetDensity()));
1823             DumpLog::GetInstance().Print(1, "ViewScale: " + std::to_string(pipelineContext_->GetViewScale()));
1824             DumpLog::GetInstance().Print(
1825                 1, "DisplayWindowRect: " + pipelineContext_->GetDisplayWindowRectInfo().ToString());
1826             DumpLog::GetInstance().Print(1, "vsyncID: " + std::to_string(pipelineContext_->GetFrameCount()));
1827         }
1828         DumpLog::GetInstance().Print(1, "ApiVersion: " + SystemProperties::GetApiVersion());
1829         DumpLog::GetInstance().Print(1, "ReleaseType: " + SystemProperties::GetReleaseType());
1830         DumpLog::GetInstance().Print(1, "DeviceType: " + SystemProperties::GetParamDeviceType());
1831         return true;
1832     }
1833     return false;
1834 }
1835 
TriggerGarbageCollection()1836 void AceContainer::TriggerGarbageCollection()
1837 {
1838     ContainerScope scope(instanceId_);
1839 #if !defined(OHOS_PLATFORM) || !defined(ENABLE_NATIVE_VIEW)
1840     // GPU and IO thread is standalone while disable native view
1841     taskExecutor_->PostTask([] { PurgeMallocCache(); }, TaskExecutor::TaskType::GPU, "ArkUIPurgeMallocCache");
1842     taskExecutor_->PostTask([] { PurgeMallocCache(); }, TaskExecutor::TaskType::IO, "ArkUIPurgeMallocCache");
1843 #endif
1844     taskExecutor_->PostTask([] { PurgeMallocCache(); }, TaskExecutor::TaskType::UI, "ArkUIPurgeMallocCache");
1845     taskExecutor_->PostTask(
1846         [frontend = WeakPtr<Frontend>(frontend_)] {
1847             auto sp = frontend.Upgrade();
1848             if (sp) {
1849                 sp->TriggerGarbageCollection();
1850             }
1851             PurgeMallocCache();
1852         },
1853         TaskExecutor::TaskType::JS, "ArkUITriggerGarbageCollection");
1854 }
1855 
DumpHeapSnapshot(bool isPrivate)1856 void AceContainer::DumpHeapSnapshot(bool isPrivate)
1857 {
1858     taskExecutor_->PostTask(
1859         [isPrivate, frontend = WeakPtr<Frontend>(frontend_)] {
1860             auto sp = frontend.Upgrade();
1861             CHECK_NULL_VOID(sp);
1862             sp->DumpHeapSnapshot(isPrivate);
1863         },
1864         TaskExecutor::TaskType::JS, "ArkUIDumpHeapSnapshot");
1865 }
1866 
DestroyHeapProfiler()1867 void AceContainer::DestroyHeapProfiler()
1868 {
1869     taskExecutor_->PostTask(
1870         [frontend = WeakPtr<Frontend>(frontend_)] {
1871             auto sp = frontend.Upgrade();
1872             CHECK_NULL_VOID(sp);
1873             sp->DestroyHeapProfiler();
1874         },
1875         TaskExecutor::TaskType::JS, "ArkUIDestroyHeapProfiler");
1876 }
1877 
ForceFullGC()1878 void AceContainer::ForceFullGC()
1879 {
1880     taskExecutor_->PostTask(
1881         [frontend = WeakPtr<Frontend>(frontend_)] {
1882             auto sp = frontend.Upgrade();
1883             CHECK_NULL_VOID(sp);
1884             sp->ForceFullGC();
1885         },
1886         TaskExecutor::TaskType::JS, "ArkUIForceFullGC");
1887 }
1888 
SetLocalStorage( NativeReference* storage, const std::shared_ptr<OHOS::AbilityRuntime::Context>& context)1889 void AceContainer::SetLocalStorage(
1890     NativeReference* storage, const std::shared_ptr<OHOS::AbilityRuntime::Context>& context)
1891 {
1892     ContainerScope scope(instanceId_);
1893     taskExecutor_->PostSyncTask(
1894         [frontend = WeakPtr<Frontend>(frontend_), storage,
1895             contextWeak = std::weak_ptr<OHOS::AbilityRuntime::Context>(context), id = instanceId_,
1896             sharedRuntime = sharedRuntime_] {
1897             auto sp = frontend.Upgrade();
1898             auto contextRef = contextWeak.lock();
1899             if (!sp || !contextRef) {
1900                 ReleaseStorageReference(sharedRuntime, storage);
1901                 return;
1902             }
1903 #ifdef NG_BUILD
1904             auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontendNG>(sp);
1905 #else
1906             auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(sp);
1907 #endif
1908             if (!declarativeFrontend) {
1909                 ReleaseStorageReference(sharedRuntime, storage);
1910                 return;
1911             }
1912             auto jsEngine = declarativeFrontend->GetJsEngine();
1913             if (!jsEngine) {
1914                 ReleaseStorageReference(sharedRuntime, storage);
1915                 return;
1916             }
1917             if (contextRef->GetBindingObject() && contextRef->GetBindingObject()->Get<NativeReference>()) {
1918                 jsEngine->SetContext(id, contextRef->GetBindingObject()->Get<NativeReference>());
1919             }
1920             if (storage) {
1921                 jsEngine->SetLocalStorage(id, storage);
1922             }
1923         },
1924         TaskExecutor::TaskType::JS, "ArkUISetLocalStorage");
1925 }
1926 
AddAssetPath(int32_t instanceId, const std::string& packagePath, const std::string& hapPath, const std::vector<std::string>& paths)1927 void AceContainer::AddAssetPath(int32_t instanceId, const std::string& packagePath, const std::string& hapPath,
1928     const std::vector<std::string>& paths)
1929 {
1930     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1931     CHECK_NULL_VOID(container);
1932     RefPtr<AssetManagerImpl> assetManagerImpl;
1933     if (container->assetManager_) {
1934         assetManagerImpl = AceType::DynamicCast<AssetManagerImpl>(container->assetManager_);
1935     } else {
1936         assetManagerImpl = Referenced::MakeRefPtr<AssetManagerImpl>();
1937         container->assetManager_ = assetManagerImpl;
1938         if (container->type_ != FrontendType::DECLARATIVE_JS && container->type_ != FrontendType::DECLARATIVE_CJ) {
1939             container->frontend_->SetAssetManager(assetManagerImpl);
1940         }
1941     }
1942     CHECK_NULL_VOID(assetManagerImpl);
1943     if (!hapPath.empty()) {
1944         auto assetProvider = AceType::MakeRefPtr<HapAssetProviderImpl>();
1945         if (assetProvider->Initialize(hapPath, paths)) {
1946             LOGI("Push AssetProvider to queue.");
1947             assetManagerImpl->PushBack(std::move(assetProvider));
1948         }
1949     }
1950     if (!packagePath.empty()) {
1951         auto assetProvider = AceType::MakeRefPtr<FileAssetProviderImpl>();
1952         if (assetProvider->Initialize(packagePath, paths)) {
1953             LOGI("Push AssetProvider to queue.");
1954             assetManagerImpl->PushBack(std::move(assetProvider));
1955         }
1956     }
1957 }
1958 
AddLibPath(int32_t instanceId, const std::vector<std::string>& libPath)1959 void AceContainer::AddLibPath(int32_t instanceId, const std::vector<std::string>& libPath)
1960 {
1961     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1962     CHECK_NULL_VOID(container);
1963     RefPtr<AssetManager> assetManagerImpl;
1964     if (container->assetManager_) {
1965         assetManagerImpl = AceType::DynamicCast<AssetManagerImpl>(container->assetManager_);
1966     } else {
1967         assetManagerImpl = Referenced::MakeRefPtr<AssetManagerImpl>();
1968         container->assetManager_ = assetManagerImpl;
1969         if (container->type_ != FrontendType::DECLARATIVE_JS && container->type_ != FrontendType::DECLARATIVE_CJ) {
1970             container->frontend_->SetAssetManager(assetManagerImpl);
1971         }
1972     }
1973     CHECK_NULL_VOID(assetManagerImpl);
1974     assetManagerImpl->SetLibPath("default", libPath);
1975 }
1976 
AttachView(std::shared_ptr<Window> window, const RefPtr<AceView>& view, double density, float width, float height, uint32_t windowId, UIEnvCallback callback)1977 void AceContainer::AttachView(std::shared_ptr<Window> window, const RefPtr<AceView>& view, double density, float width,
1978     float height, uint32_t windowId, UIEnvCallback callback)
1979 {
1980     aceView_ = view;
1981     auto instanceId = aceView_->GetInstanceId();
1982     auto taskExecutorImpl = AceType::DynamicCast<TaskExecutorImpl>(taskExecutor_);
1983     if (!isSubContainer_) {
1984         auto aceView = AceType::DynamicCast<AceViewOhos>(aceView_);
1985         ACE_DCHECK(aceView != nullptr);
1986         taskExecutorImpl->InitOtherThreads(aceView->GetThreadModelImpl());
1987     }
1988     ContainerScope scope(instanceId);
1989     if (type_ == FrontendType::DECLARATIVE_JS || type_ == FrontendType::DECLARATIVE_CJ) {
1990         // For DECLARATIVE_JS frontend display UI in JS thread temporarily.
1991         taskExecutorImpl->InitJsThread(false);
1992         InitializeFrontend();
1993         auto front = GetFrontend();
1994         if (front) {
1995             front->UpdateState(Frontend::State::ON_CREATE);
1996             front->SetJsMessageDispatcher(AceType::Claim(this));
1997             front->SetAssetManager(assetManager_);
1998         }
1999     } else if (type_ != FrontendType::JS_CARD) {
2000         aceView_->SetCreateTime(createTime_);
2001     }
2002     resRegister_ = aceView_->GetPlatformResRegister();
2003 #ifndef NG_BUILD
2004     if (useNewPipeline_) {
2005         pipelineContext_ = AceType::MakeRefPtr<NG::PipelineContext>(
2006             window, taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
2007         pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<NG::TextFieldManagerNG>());
2008     } else {
2009         LOGI("Create old pipeline.");
2010         pipelineContext_ = AceType::MakeRefPtr<PipelineContext>(
2011             window, taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
2012         pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<TextFieldManager>());
2013     }
2014 #else
2015     pipelineContext_ = AceType::MakeRefPtr<NG::PipelineContext>(
2016         window, taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
2017     pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<NG::TextFieldManagerNG>());
2018 #endif
2019 
2020 #ifdef FORM_SUPPORTED
2021     if (isFormRender_) {
2022         pipelineContext_->SetIsFormRender(isFormRender_);
2023         pipelineContext_->SetIsDynamicRender(isDynamicRender_);
2024         auto cardFrontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
2025         if (cardFrontend) {
2026             cardFrontend->SetTaskExecutor(taskExecutor_);
2027             cardFrontend->SetLoadCardCallBack(WeakPtr<PipelineBase>(pipelineContext_));
2028         }
2029     }
2030 #endif
2031 
2032     auto windowDensityCallback = [weak = WeakClaim(this)]() {
2033         auto container = weak.Upgrade();
2034         CHECK_NULL_RETURN(container, 0.0);
2035         return container->GetWindowDensity();
2036     };
2037     pipelineContext_->RegisterWindowDensityCallback(std::move(windowDensityCallback));
2038 
2039     pipelineContext_->SetRootSize(density, width, height);
2040     if (isFormRender_) {
2041         pipelineContext_->OnSurfaceDensityChanged(density);
2042     }
2043     pipelineContext_->SetIsRightToLeft(AceApplicationInfo::GetInstance().IsRightToLeft());
2044     pipelineContext_->SetWindowId(windowId);
2045     pipelineContext_->SetWindowModal(windowModal_);
2046     if (uiWindow_) {
2047         auto windowType = uiWindow_->GetType();
2048         pipelineContext_->SetIsAppWindow(
2049             windowType < Rosen::WindowType::SYSTEM_WINDOW_BASE && windowType >= Rosen::WindowType::APP_WINDOW_BASE);
2050     }
2051     if (installationFree_) {
2052         pipelineContext_->SetInstallationFree(installationFree_);
2053         pipelineContext_->SetSharePanelCallback(std::move(sharePanelCallback_));
2054         std::shared_ptr<AppExecFwk::AbilityInfo> info = abilityInfo_.lock();
2055         if (info != nullptr) {
2056             pipelineContext_->SetAppLabelId(info->labelId);
2057         }
2058     }
2059     if (isSubContainer_) {
2060         pipelineContext_->SetIsSubPipeline(true);
2061     }
2062 
2063     pipelineContext_->SetDrawDelegate(aceView_->GetDrawDelegate());
2064     InitWindowCallback();
2065     InitializeCallback();
2066 
2067     auto&& finishEventHandler = [weak = WeakClaim(this), instanceId] {
2068         auto container = weak.Upgrade();
2069         CHECK_NULL_VOID(container);
2070         ContainerScope scope(instanceId);
2071         auto context = container->GetPipelineContext();
2072         CHECK_NULL_VOID(context);
2073         context->GetTaskExecutor()->PostTask(
2074             [weak = WeakPtr<AceContainer>(container)] {
2075                 auto container = weak.Upgrade();
2076                 CHECK_NULL_VOID(container);
2077                 container->OnFinish();
2078             },
2079             TaskExecutor::TaskType::PLATFORM, "ArkUIHandleFinishEvent");
2080     };
2081     pipelineContext_->SetFinishEventHandler(finishEventHandler);
2082 
2083     auto&& startAbilityHandler = [weak = WeakClaim(this), instanceId](const std::string& address) {
2084         auto container = weak.Upgrade();
2085         CHECK_NULL_VOID(container);
2086         ContainerScope scope(instanceId);
2087         auto context = container->GetPipelineContext();
2088         CHECK_NULL_VOID(context);
2089         context->GetTaskExecutor()->PostTask(
2090             [weak = WeakPtr<AceContainer>(container), address]() {
2091                 auto container = weak.Upgrade();
2092                 CHECK_NULL_VOID(container);
2093                 container->OnStartAbility(address);
2094             },
2095             TaskExecutor::TaskType::PLATFORM, "ArkUIHandleStartAbility");
2096     };
2097     pipelineContext_->SetStartAbilityHandler(startAbilityHandler);
2098 
2099     auto&& setStatusBarEventHandler = [weak = WeakClaim(this), instanceId](const Color& color) {
2100         auto container = weak.Upgrade();
2101         CHECK_NULL_VOID(container);
2102         ContainerScope scope(instanceId);
2103         auto context = container->GetPipelineContext();
2104         CHECK_NULL_VOID(context);
2105         context->GetTaskExecutor()->PostTask(
2106             [weak, color = color.GetValue()]() {
2107                 auto container = weak.Upgrade();
2108                 CHECK_NULL_VOID(container);
2109                 if (container->platformEventCallback_) {
2110                     container->platformEventCallback_->OnStatusBarBgColorChanged(color);
2111                 }
2112             },
2113             TaskExecutor::TaskType::PLATFORM, "ArkUIStatusBarColorChanged");
2114     };
2115     pipelineContext_->SetStatusBarEventHandler(setStatusBarEventHandler);
2116     if (GetSettings().usePlatformAsUIThread) {
2117         FrameReport::GetInstance().Init();
2118     } else {
2119         taskExecutor_->PostTask([] { FrameReport::GetInstance().Init(); },
2120             TaskExecutor::TaskType::UI, "ArkUIFrameReportInit");
2121     }
2122 
2123     // Load custom style at UI thread before frontend attach, for loading style before building tree.
2124     auto initThemeManagerTask = [pipelineContext = pipelineContext_, assetManager = assetManager_,
2125                                     colorScheme = colorScheme_, resourceInfo = resourceInfo_,
2126                                     context = runtimeContext_.lock(), abilityInfo = abilityInfo_.lock()]() {
2127         ACE_SCOPED_TRACE("OHOS::LoadThemes()");
2128 
2129         if (SystemProperties::GetResourceDecoupling()) {
2130             InitResourceAndThemeManager(pipelineContext, assetManager, colorScheme, resourceInfo, context, abilityInfo);
2131         } else {
2132             ThemeConstants::InitDeviceType();
2133             auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>();
2134             pipelineContext->SetThemeManager(themeManager);
2135             themeManager->InitResource(resourceInfo);
2136             themeManager->SetColorScheme(colorScheme);
2137             themeManager->LoadCustomTheme(assetManager);
2138             themeManager->LoadResourceThemes();
2139         }
2140         auto themeManager = pipelineContext->GetThemeManager();
2141         if (themeManager) {
2142             pipelineContext->SetAppBgColor(themeManager->GetBackgroundColor());
2143         }
2144     };
2145 
2146     auto setupRootElementTask = [context = pipelineContext_, callback, isSubContainer = isSubContainer_]() {
2147         if (callback != nullptr) {
2148             callback(AceType::DynamicCast<PipelineContext>(context));
2149         }
2150         if (!isSubContainer) {
2151             context->SetupRootElement();
2152         }
2153     };
2154     if (GetSettings().usePlatformAsUIThread) {
2155         initThemeManagerTask();
2156         setupRootElementTask();
2157     } else {
2158         taskExecutor_->PostTask(initThemeManagerTask, TaskExecutor::TaskType::UI, "ArkUIInitThemeManager");
2159         taskExecutor_->PostTask(setupRootElementTask, TaskExecutor::TaskType::UI, "ArkUISetupRootElement");
2160     }
2161 
2162     aceView_->Launch();
2163 
2164 #ifdef NG_BUILD
2165     auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontendNG>(frontend_);
2166 #else
2167     auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
2168 #endif
2169     if (declarativeFrontend) {
2170         auto jsEngine = AceType::DynamicCast<Framework::JsiDeclarativeEngine>(declarativeFrontend->GetJsEngine());
2171         if (jsEngine && !isFormRender_) {
2172             // register state profiler callback
2173             jsEngine->JsStateProfilerResgiter();
2174         }
2175     }
2176 
2177     if (!isSubContainer_) {
2178         // Only MainWindow instance in FA model will be registered to watch dog.
2179         if (!GetSettings().usingSharedRuntime && !AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint()) {
2180             AceEngine::Get().RegisterToWatchDog(instanceId, taskExecutor_, GetSettings().useUIAsJSThread);
2181         }
2182         frontend_->AttachPipelineContext(pipelineContext_);
2183     } else if (frontend_->GetType() == FrontendType::DECLARATIVE_JS) {
2184         if (declarativeFrontend) {
2185             declarativeFrontend->AttachSubPipelineContext(pipelineContext_);
2186         }
2187         return;
2188     }
2189 
2190     auto dataAbilityHelperImpl = [ability = GetAbilityInner(), runtimeContext = runtimeContext_,
2191                                      useStageModel = useStageModel_]() {
2192         return AceType::MakeRefPtr<DataAbilityHelperStandard>(ability.lock(), runtimeContext.lock(), useStageModel);
2193     };
2194     auto dataProviderManager = MakeRefPtr<DataProviderManagerStandard>(dataAbilityHelperImpl);
2195     pipelineContext_->SetDataProviderManager(dataProviderManager);
2196 
2197 #if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
2198     pipelineContext_->SetPostRTTaskCallBack([](std::function<void()>&& task) {
2199         auto syncTask = std::make_shared<AceRosenSyncTask>(std::move(task));
2200         Rosen::RSTransactionProxy::GetInstance()->ExecuteSynchronousTask(syncTask);
2201     });
2202 #endif
2203 }
2204 
SetUIWindowInner(sptr<OHOS::Rosen::Window> uiWindow)2205 void AceContainer::SetUIWindowInner(sptr<OHOS::Rosen::Window> uiWindow)
2206 {
2207     uiWindow_ = uiWindow;
2208 }
2209 
GetUIWindowInner() const2210 sptr<OHOS::Rosen::Window> AceContainer::GetUIWindowInner() const
2211 {
2212     return uiWindow_;
2213 }
2214 
GetAbilityInner() const2215 std::weak_ptr<OHOS::AppExecFwk::Ability> AceContainer::GetAbilityInner() const
2216 {
2217     return aceAbility_;
2218 }
2219 
GetRuntimeContextInner() const2220 std::weak_ptr<OHOS::AbilityRuntime::Context> AceContainer::GetRuntimeContextInner() const
2221 {
2222     return runtimeContext_;
2223 }
2224 
IsLauncherContainer()2225 bool AceContainer::IsLauncherContainer()
2226 {
2227     auto runtime = runtimeContext_.lock();
2228     if (!runtime) {
2229         return false;
2230     }
2231     auto info = runtime->GetApplicationInfo();
2232     return info ? info->isLauncherApp : false;
2233 }
2234 
IsTransparentBg() const2235 bool AceContainer::IsTransparentBg() const
2236 {
2237     CHECK_NULL_RETURN(pipelineContext_, true);
2238     Color bgColor = pipelineContext_->GetAppBgColor();
2239     std::string bgOpacity = bgColor.ColorToString().substr(0, 3);
2240     std::string transparentOpacity = "#00";
2241     return bgColor == Color::TRANSPARENT || bgOpacity == transparentOpacity;
2242 }
2243 
SetWindowStyle(int32_t instanceId, WindowModal windowModal, ColorScheme colorScheme)2244 void AceContainer::SetWindowStyle(int32_t instanceId, WindowModal windowModal, ColorScheme colorScheme)
2245 {
2246     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
2247     CHECK_NULL_VOID(container);
2248     ContainerScope scope(instanceId);
2249     container->SetWindowModal(windowModal);
2250     container->SetColorScheme(colorScheme);
2251 }
2252 
SetDialogCallback(int32_t instanceId, FrontendDialogCallback callback)2253 void AceContainer::SetDialogCallback(int32_t instanceId, FrontendDialogCallback callback)
2254 {
2255     auto container = AceEngine::Get().GetContainer(instanceId);
2256     CHECK_NULL_VOID(container);
2257     auto front = container->GetFrontend();
2258     if (front && front->GetType() == FrontendType::JS) {
2259         front->SetDialogCallback(callback);
2260     }
2261 }
2262 
RestoreRouterStack( int32_t instanceId, const std::string& contentInfo, ContentInfoType type)2263 std::pair<RouterRecoverRecord, UIContentErrorCode> AceContainer::RestoreRouterStack(
2264     int32_t instanceId, const std::string& contentInfo, ContentInfoType type)
2265 {
2266     auto container = AceEngine::Get().GetContainer(instanceId);
2267     CHECK_NULL_RETURN(container, std::make_pair(RouterRecoverRecord(), UIContentErrorCode::NULL_POINTER));
2268     ContainerScope scope(instanceId);
2269     auto front = container->GetFrontend();
2270     CHECK_NULL_RETURN(front, std::make_pair(RouterRecoverRecord(), UIContentErrorCode::NULL_POINTER));
2271     return front->RestoreRouterStack(contentInfo, type);
2272 }
2273 
GetContentInfo(int32_t instanceId, ContentInfoType type)2274 std::string AceContainer::GetContentInfo(int32_t instanceId, ContentInfoType type)
2275 {
2276     auto container = AceEngine::Get().GetContainer(instanceId);
2277     CHECK_NULL_RETURN(container, "");
2278     ContainerScope scope(instanceId);
2279     auto front = container->GetFrontend();
2280     CHECK_NULL_RETURN(front, "");
2281     return front->GetContentInfo(type);
2282 }
2283 
SetWindowPos(int32_t left, int32_t top)2284 void AceContainer::SetWindowPos(int32_t left, int32_t top)
2285 {
2286     CHECK_NULL_VOID(frontend_);
2287     auto accessibilityManager = frontend_->GetAccessibilityManager();
2288     CHECK_NULL_VOID(accessibilityManager);
2289     accessibilityManager->SetWindowPos(left, top, windowId_);
2290 }
2291 
InitializeSubContainer(int32_t parentContainerId)2292 void AceContainer::InitializeSubContainer(int32_t parentContainerId)
2293 {
2294     auto parentContainer = AceEngine::Get().GetContainer(parentContainerId);
2295     CHECK_NULL_VOID(parentContainer);
2296     auto taskExec = parentContainer->GetTaskExecutor();
2297     taskExecutor_ = AceType::DynamicCast<TaskExecutorImpl>(std::move(taskExec));
2298     auto parentSettings = parentContainer->GetSettings();
2299     GetSettings().useUIAsJSThread = parentSettings.useUIAsJSThread;
2300     GetSettings().usePlatformAsUIThread = parentSettings.usePlatformAsUIThread;
2301     GetSettings().usingSharedRuntime = parentSettings.usingSharedRuntime;
2302 }
2303 
InitWindowCallback()2304 void AceContainer::InitWindowCallback()
2305 {
2306     if (!pipelineContext_ || !uiWindow_) {
2307         return;
2308     }
2309     auto& windowManager = pipelineContext_->GetWindowManager();
2310     std::shared_ptr<AppExecFwk::AbilityInfo> info = abilityInfo_.lock();
2311     if (info != nullptr) {
2312         windowManager->SetAppLabelId(info->labelId);
2313         windowManager->SetAppIconId(info->iconId);
2314     }
2315     windowManager->SetWindowMinimizeCallBack([window = uiWindow_]() { window->Minimize(); });
2316     windowManager->SetWindowMaximizeCallBack([window = uiWindow_]() { window->Maximize(); });
2317     windowManager->SetWindowMaximizeFloatingCallBack([window = uiWindow_]() { window->MaximizeFloating(); });
2318     windowManager->SetWindowRecoverCallBack([window = uiWindow_]() { window->Recover(); });
2319     windowManager->SetWindowCloseCallBack([window = uiWindow_]() { window->Close(); });
2320     windowManager->SetWindowStartMoveCallBack([window = uiWindow_]() { window->StartMove(); });
2321     windowManager->SetGetWindowStartMoveFlagCallBack(
2322         [window = uiWindow_]() -> uint32_t { return static_cast<uint32_t>(window->GetStartMoveFlag()); });
2323     windowManager->SetWindowSplitPrimaryCallBack(
2324         [window = uiWindow_]() { window->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_SPLIT_PRIMARY); });
2325     windowManager->SetWindowSplitSecondaryCallBack(
2326         [window = uiWindow_]() { window->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_SPLIT_SECONDARY); });
2327     windowManager->SetWindowGetModeCallBack(
2328         [window = uiWindow_]() -> WindowMode { return static_cast<WindowMode>(window->GetMode()); });
2329     windowManager->SetWindowGetTypeCallBack(
2330         [window = uiWindow_]() -> WindowType { return static_cast<WindowType>(window->GetType()); });
2331     windowManager->SetWindowSetMaximizeModeCallBack(
2332         [window = uiWindow_](MaximizeMode mode) {
2333         window->SetGlobalMaximizeMode(static_cast<Rosen::MaximizeMode>(mode));
2334     });
2335     windowManager->SetWindowGetMaximizeModeCallBack(
2336         [window = uiWindow_]() -> MaximizeMode {
2337             return static_cast<MaximizeMode>(window->GetGlobalMaximizeMode());
2338         });
2339     windowManager->SetGetSystemBarStyleCallBack(
2340         [window = uiWindow_]() -> RefPtr<SystemBarStyle> {
2341             return SystemBarStyleOhos::GetCurrentSystemBarStyle(window);
2342         });
2343     windowManager->SetSetSystemBarStyleCallBack(
2344         [window = uiWindow_](const RefPtr<SystemBarStyle>& style) {
2345             SystemBarStyleOhos::SetSystemBarStyle(window, style);
2346         });
2347     windowManager->SetGetFreeMultiWindowModeEnabledStateCallback(
2348         [window = uiWindow_]() -> bool {
2349             return window->GetFreeMultiWindowModeEnabledState();
2350         });
2351 
2352     pipelineContext_->SetGetWindowRectImpl([window = uiWindow_]() -> Rect {
2353         Rect rect;
2354         CHECK_NULL_RETURN(window, rect);
2355         auto windowRect = window->GetRect();
2356         rect.SetRect(windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_);
2357         return rect;
2358     });
2359 }
2360 
GetViewSafeAreaByType(OHOS::Rosen::AvoidAreaType type)2361 NG::SafeAreaInsets AceContainer::GetViewSafeAreaByType(OHOS::Rosen::AvoidAreaType type)
2362 {
2363     CHECK_NULL_RETURN(uiWindow_, {});
2364     Rosen::AvoidArea avoidArea;
2365     Rosen::WMError ret = uiWindow_->GetAvoidAreaByType(type, avoidArea);
2366     if (ret == Rosen::WMError::WM_OK) {
2367         auto safeAreaInsets = ConvertAvoidArea(avoidArea);
2368         TAG_LOGI(ACE_LAYOUT, "SafeArea get success, area type is:%{public}d insets area is:%{public}s",
2369             static_cast<int32_t>(type), safeAreaInsets.ToString().c_str());
2370         return safeAreaInsets;
2371     }
2372     return {};
2373 }
2374 
GetSessionAvoidAreaByType(uint32_t safeAreaType)2375 Rect AceContainer::GetSessionAvoidAreaByType(uint32_t safeAreaType)
2376 {
2377     Rosen::WSRect avoidArea;
2378     Rect sessionAvoidArea;
2379     if (safeAreaType == NG::SAFE_AREA_TYPE_SYSTEM) {
2380         auto ret =
2381             Rosen::RootScene::staticRootScene_->GetSessionRectByType(Rosen::AvoidAreaType::TYPE_SYSTEM, avoidArea);
2382         if (ret == Rosen::WMError::WM_OK) {
2383             sessionAvoidArea.SetRect(avoidArea.posX_, avoidArea.posY_, avoidArea.width_, avoidArea.height_);
2384         }
2385     } else if (safeAreaType == NG::SAFE_AREA_TYPE_KEYBOARD) {
2386         auto ret =
2387             Rosen::RootScene::staticRootScene_->GetSessionRectByType(Rosen::AvoidAreaType::TYPE_KEYBOARD, avoidArea);
2388         if (ret == Rosen::WMError::WM_OK) {
2389             sessionAvoidArea.SetRect(avoidArea.posX_, avoidArea.posY_, avoidArea.width_, avoidArea.height_);
2390         }
2391     }
2392     LOGI("GetSessionAvoidAreaByType safeAreaType: %{public}u, sessionAvoidArea; %{public}s", safeAreaType,
2393         sessionAvoidArea.ToString().c_str());
2394     return sessionAvoidArea;
2395 }
2396 
GetKeyboardSafeArea()2397 NG::SafeAreaInsets AceContainer::GetKeyboardSafeArea()
2398 {
2399     CHECK_NULL_RETURN(uiWindow_, {});
2400     Rosen::AvoidArea avoidArea;
2401     Rosen::WMError ret = uiWindow_->GetAvoidAreaByType(Rosen::AvoidAreaType::TYPE_KEYBOARD, avoidArea);
2402     if (ret == Rosen::WMError::WM_OK) {
2403         return ConvertAvoidArea(avoidArea);
2404     }
2405     return {};
2406 }
2407 
GetAvoidAreaByType(Rosen::AvoidAreaType type)2408 Rosen::AvoidArea AceContainer::GetAvoidAreaByType(Rosen::AvoidAreaType type)
2409 {
2410     CHECK_NULL_RETURN(uiWindow_, {});
2411     Rosen::AvoidArea avoidArea;
2412     Rosen::WMError ret = uiWindow_->GetAvoidAreaByType(type, avoidArea);
2413     if (ret == Rosen::WMError::WM_OK) {
2414         return avoidArea;
2415     }
2416     return {};
2417 }
2418 
GetAbilityContextByModule( const std::string& bundle, const std::string& module)2419 std::shared_ptr<OHOS::AbilityRuntime::Context> AceContainer::GetAbilityContextByModule(
2420     const std::string& bundle, const std::string& module)
2421 {
2422     auto context = runtimeContext_.lock();
2423     CHECK_NULL_RETURN(context, nullptr);
2424     if (!isFormRender_ && !bundle.empty() && !module.empty()) {
2425         std::string encode = EncodeBundleAndModule(bundle, module);
2426         if (taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
2427             RecordResAdapter(encode);
2428         } else {
2429             taskExecutor_->PostTask(
2430                 [encode, instanceId = instanceId_]() -> void {
2431                     auto container = AceContainer::GetContainer(instanceId);
2432                     CHECK_NULL_VOID(container);
2433                     container->RecordResAdapter(encode);
2434                 },
2435                 TaskExecutor::TaskType::UI, "ArkUIRecordResAdapter");
2436         }
2437     }
2438     return isFormRender_ ? nullptr : context->CreateModuleContext(bundle, module);
2439 }
2440 
CheckAndSetFontFamily()2441 void AceContainer::CheckAndSetFontFamily()
2442 {
2443     auto fontManager = pipelineContext_->GetFontManager();
2444     CHECK_NULL_VOID(fontManager);
2445     if (fontManager->IsUseAppCustomFont()) {
2446         return;
2447     }
2448     std::string familyName = "";
2449     std::string path = "/data/themes/a/app";
2450     if (!IsFontFileExistInPath(path)) {
2451         path = "/data/themes/b/app";
2452         if (!IsFontFileExistInPath(path)) {
2453             return;
2454         }
2455     }
2456     path = path.append("/fonts/");
2457     familyName = GetFontFamilyName(path);
2458     if (familyName.empty()) {
2459         return;
2460     }
2461     path = path.append(familyName);
2462     if (isFormRender_) {
2463         // Resolve garbled characters caused by FRS multi-thread async
2464         std::lock_guard<std::mutex> lock(g_mutexFormRenderFontFamily);
2465         fontManager->SetFontFamily(familyName.c_str(), path.c_str());
2466     } else {
2467         fontManager->SetFontFamily(familyName.c_str(), path.c_str());
2468     }
2469 }
2470 
SetFontScaleAndWeightScale( const ParsedConfig& parsedConfig, ConfigurationChange& configurationChange)2471 void AceContainer::SetFontScaleAndWeightScale(
2472     const ParsedConfig& parsedConfig, ConfigurationChange& configurationChange)
2473 {
2474     if (!parsedConfig.fontScale.empty()) {
2475         TAG_LOGD(AceLogTag::ACE_AUTO_FILL, "parsedConfig fontScale: %{public}s", parsedConfig.fontScale.c_str());
2476         CHECK_NULL_VOID(pipelineContext_);
2477         float fontSizeScale = StringUtils::StringToFloat(parsedConfig.fontScale);
2478         if (fontSizeScale != pipelineContext_->GetFontScale()) {
2479             SetFontScale(instanceId_, fontSizeScale);
2480             configurationChange.fontScaleUpdate = true;
2481         }
2482     }
2483     if (!parsedConfig.fontWeightScale.empty()) {
2484         TAG_LOGD(AceLogTag::ACE_AUTO_FILL, "parsedConfig fontWeightScale: %{public}s",
2485             parsedConfig.fontWeightScale.c_str());
2486         CHECK_NULL_VOID(pipelineContext_);
2487         float fontWeightScale = StringUtils::StringToFloat(parsedConfig.fontWeightScale);
2488         if (fontWeightScale != pipelineContext_->GetFontWeightScale()) {
2489             SetFontWeightScale(instanceId_, fontWeightScale);
2490             configurationChange.fontWeightScaleUpdate = true;
2491         }
2492     }
2493 }
2494 
ReleaseResourceAdapter()2495 void AceContainer::ReleaseResourceAdapter()
2496 {
2497     for (auto &encode : resAdapterRecord_) {
2498         std::string bundleName;
2499         std::string moduleName;
2500         DecodeBundleAndModule(encode, bundleName, moduleName);
2501         ResourceManager::GetInstance().RemoveResourceAdapter(bundleName, moduleName);
2502     }
2503     resAdapterRecord_.clear();
2504 
2505     if (isFormRender_) {
2506         auto runtimeContext = runtimeContext_.lock();
2507         if (runtimeContext) {
2508             auto defaultBundleName = "";
2509             auto defaultModuleName = "";
2510             ResourceManager::GetInstance().RemoveResourceAdapter(defaultBundleName, defaultModuleName);
2511 
2512             auto bundleName = runtimeContext->GetBundleName();
2513             auto moduleName = runtimeContext->GetHapModuleInfo()->name;
2514             ResourceManager::GetInstance().RemoveResourceAdapter(bundleName, moduleName);
2515         }
2516     }
2517 }
2518 
ProcessDirectionUpdate( const ParsedConfig& parsedConfig, ConfigurationChange& configurationChange)2519 DeviceOrientation AceContainer::ProcessDirectionUpdate(
2520     const ParsedConfig& parsedConfig, ConfigurationChange& configurationChange)
2521 {
2522     if (!parsedConfig.direction.empty()) {
2523         auto resDirection = DeviceOrientation::ORIENTATION_UNDEFINED;
2524         if (parsedConfig.direction == "horizontal") {
2525             resDirection = DeviceOrientation::LANDSCAPE;
2526         } else if (parsedConfig.direction == "vertical") {
2527             resDirection = DeviceOrientation::PORTRAIT;
2528         }
2529         configurationChange.directionUpdate = true;
2530         return resDirection;
2531     }
2532     return DeviceOrientation::ORIENTATION_UNDEFINED;
2533 }
2534 
ProcessThemeUpdate(const ParsedConfig& parsedConfig, ConfigurationChange& configurationChange)2535 void AceContainer::ProcessThemeUpdate(const ParsedConfig& parsedConfig, ConfigurationChange& configurationChange)
2536 {
2537     if (!parsedConfig.themeTag.empty()) {
2538         std::unique_ptr<JsonValue> json = JsonUtil::ParseJsonString(parsedConfig.themeTag);
2539         int fontUpdate = json->GetInt("fonts");
2540         configurationChange.fontUpdate = configurationChange.fontUpdate || fontUpdate;
2541         int iconUpdate = json->GetInt("icons");
2542         configurationChange.iconUpdate = iconUpdate;
2543         int skinUpdate = json->GetInt("skin");
2544         configurationChange.skinUpdate = skinUpdate;
2545         if (fontUpdate) {
2546             CheckAndSetFontFamily();
2547         }
2548     }
2549 }
2550 
UpdateConfiguration(const ParsedConfig& parsedConfig, const std::string& configuration)2551 void AceContainer::UpdateConfiguration(const ParsedConfig& parsedConfig, const std::string& configuration)
2552 {
2553     if (!parsedConfig.IsValid()) {
2554         LOGW("AceContainer::OnConfigurationUpdated param is empty");
2555         return;
2556     }
2557     ConfigurationChange configurationChange;
2558     CHECK_NULL_VOID(pipelineContext_);
2559     auto themeManager = pipelineContext_->GetThemeManager();
2560     CHECK_NULL_VOID(themeManager);
2561     auto resConfig = GetResourceConfiguration();
2562     if (!parsedConfig.colorMode.empty()) {
2563         configurationChange.colorModeUpdate = true;
2564         if (parsedConfig.colorMode == "dark") {
2565             SystemProperties::SetColorMode(ColorMode::DARK);
2566             SetColorScheme(ColorScheme::SCHEME_DARK);
2567             resConfig.SetColorMode(ColorMode::DARK);
2568         } else {
2569             SystemProperties::SetColorMode(ColorMode::LIGHT);
2570             SetColorScheme(ColorScheme::SCHEME_LIGHT);
2571             resConfig.SetColorMode(ColorMode::LIGHT);
2572         }
2573     }
2574     if (!parsedConfig.deviceAccess.empty()) {
2575         // Event of accessing mouse or keyboard
2576         SystemProperties::SetDeviceAccess(parsedConfig.deviceAccess == "true");
2577         resConfig.SetDeviceAccess(parsedConfig.deviceAccess == "true");
2578     }
2579     if (!parsedConfig.languageTag.empty()) {
2580         std::string language;
2581         std::string script;
2582         std::string region;
2583         Localization::ParseLocaleTag(parsedConfig.languageTag, language, script, region, false);
2584         if (!language.empty() || !script.empty() || !region.empty()) {
2585             configurationChange.languageUpdate = true;
2586             AceApplicationInfo::GetInstance().SetLocale(language, region, script, "");
2587         }
2588     }
2589     if (!parsedConfig.fontFamily.empty()) {
2590         auto fontManager = pipelineContext_->GetFontManager();
2591         CHECK_NULL_VOID(fontManager);
2592         configurationChange.fontUpdate = true;
2593         fontManager->SetAppCustomFont(parsedConfig.fontFamily);
2594     }
2595     if (!parsedConfig.direction.empty()) {
2596         resConfig.SetOrientation(ProcessDirectionUpdate(parsedConfig, configurationChange));
2597     }
2598     if (!parsedConfig.densitydpi.empty()) {
2599         configurationChange.dpiUpdate = true;
2600     }
2601     ProcessThemeUpdate(parsedConfig, configurationChange);
2602     if (!parsedConfig.colorModeIsSetByApp.empty()) {
2603         resConfig.SetColorModeIsSetByApp(true);
2604     }
2605     if (!parsedConfig.mcc.empty()) {
2606         resConfig.SetMcc(StringUtils::StringToUint(parsedConfig.mcc));
2607     }
2608     if (!parsedConfig.mnc.empty()) {
2609         resConfig.SetMnc(StringUtils::StringToUint(parsedConfig.mnc));
2610     }
2611     if (!parsedConfig.preferredLanguage.empty()) {
2612         resConfig.SetPreferredLanguage(parsedConfig.preferredLanguage);
2613         configurationChange.languageUpdate = true;
2614     }
2615     SetFontScaleAndWeightScale(parsedConfig, configurationChange);
2616     SetResourceConfiguration(resConfig);
2617     themeManager->UpdateConfig(resConfig);
2618     if (SystemProperties::GetResourceDecoupling()) {
2619         ResourceManager::GetInstance().UpdateResourceConfig(resConfig, !parsedConfig.themeTag.empty());
2620     }
2621     themeManager->LoadResourceThemes();
2622     auto front = GetFrontend();
2623     CHECK_NULL_VOID(front);
2624     if (!configurationChange.directionUpdate && !configurationChange.dpiUpdate) {
2625         front->OnConfigurationUpdated(configuration);
2626     }
2627 #ifdef PLUGIN_COMPONENT_SUPPORTED
2628     OHOS::Ace::PluginManager::GetInstance().UpdateConfigurationInPlugin(resConfig, taskExecutor_);
2629 #endif
2630     NotifyConfigurationChange(!parsedConfig.deviceAccess.empty(), configurationChange);
2631     NotifyConfigToSubContainers(parsedConfig, configuration);
2632     // change color mode and theme to clear image cache
2633     pipelineContext_->ClearImageCache();
2634 }
2635 
NotifyConfigToSubContainers(const ParsedConfig& parsedConfig, const std::string& configuration)2636 void AceContainer::NotifyConfigToSubContainers(const ParsedConfig& parsedConfig, const std::string& configuration)
2637 {
2638     for (auto& item : configurationChangedCallbacks_) {
2639         if (item.second) {
2640             item.second(parsedConfig, configuration);
2641         }
2642     }
2643 }
2644 
NotifyConfigurationChange( bool needReloadTransition, const ConfigurationChange& configurationChange)2645 void AceContainer::NotifyConfigurationChange(
2646     bool needReloadTransition, const ConfigurationChange& configurationChange)
2647 {
2648     auto taskExecutor = GetTaskExecutor();
2649     CHECK_NULL_VOID(taskExecutor);
2650     taskExecutor->PostTask(
2651         [instanceId = instanceId_, weak = WeakClaim(this), needReloadTransition, configurationChange]() {
2652             ContainerScope scope(instanceId);
2653             auto container = weak.Upgrade();
2654             CHECK_NULL_VOID(container);
2655             auto frontend = container->GetFrontend();
2656             if (frontend) {
2657                 LOGI("AceContainer UpdateConfiguration frontend MarkNeedUpdate");
2658                 frontend->FlushReload();
2659             }
2660             auto taskExecutor = container->GetTaskExecutor();
2661             CHECK_NULL_VOID(taskExecutor);
2662             taskExecutor->PostTask(
2663                 [instanceId, weak, needReloadTransition, configurationChange]() {
2664                     ContainerScope scope(instanceId);
2665                     auto container = weak.Upgrade();
2666                     CHECK_NULL_VOID(container);
2667                     auto pipeline = container->GetPipelineContext();
2668                     CHECK_NULL_VOID(pipeline);
2669                     auto themeManager = pipeline->GetThemeManager();
2670                     CHECK_NULL_VOID(themeManager);
2671                     if (configurationChange.directionUpdate &&
2672                         (themeManager->GetResourceLimitKeys() & DIRECTION_KEY) == 0) {
2673                         return;
2674                     }
2675                     if (configurationChange.colorModeUpdate && !container->IsUseCustomBg() &&
2676                         !container->IsTransparentBg()) {
2677                         pipeline->SetAppBgColor(themeManager->GetBackgroundColor());
2678                     }
2679                     pipeline->NotifyConfigurationChange();
2680                     if (configurationChange.IsNeedUpdate()) {
2681                         pipeline->FlushReload(configurationChange);
2682                     }
2683                     if (needReloadTransition) {
2684                         // reload transition animation
2685                         pipeline->FlushReloadTransition();
2686                     }
2687                     pipeline->ChangeDarkModeBrightness();
2688                 },
2689                 TaskExecutor::TaskType::UI, "ArkUIFlushReloadTransition");
2690         },
2691         TaskExecutor::TaskType::JS, "ArkUINotifyConfigurationChange");
2692 }
2693 
HotReload()2694 void AceContainer::HotReload()
2695 {
2696     auto taskExecutor = GetTaskExecutor();
2697     CHECK_NULL_VOID(taskExecutor);
2698     taskExecutor->PostTask(
2699         [instanceId = instanceId_, weak = WeakClaim(this)]() {
2700             ContainerScope scope(instanceId);
2701             auto container = weak.Upgrade();
2702             CHECK_NULL_VOID(container);
2703             auto frontend = container->GetFrontend();
2704             CHECK_NULL_VOID(frontend);
2705             LOGI("AceContainer Flush Frontend for HotReload");
2706             frontend->HotReload();
2707 
2708             auto pipeline = container->GetPipelineContext();
2709             CHECK_NULL_VOID(pipeline);
2710             pipeline->FlushReload(ConfigurationChange());
2711         },
2712         TaskExecutor::TaskType::UI, "ArkUIHotReload");
2713 }
2714 
SetToken(sptr<IRemoteObject>& token)2715 void AceContainer::SetToken(sptr<IRemoteObject>& token)
2716 {
2717     std::lock_guard<std::mutex> lock(cardTokensMutex_);
2718     if (token) {
2719         token_ = token;
2720     }
2721 }
2722 
GetToken()2723 sptr<IRemoteObject> AceContainer::GetToken()
2724 {
2725     std::lock_guard<std::mutex> lock(cardTokensMutex_);
2726     if (token_) {
2727         return token_;
2728     }
2729     LOGE("fail to get Token");
2730     return nullptr;
2731 }
2732 
SetParentToken(sptr<IRemoteObject>& token)2733 void AceContainer::SetParentToken(sptr<IRemoteObject>& token)
2734 {
2735     std::lock_guard<std::mutex> lock(cardTokensMutex_);
2736     if (token) {
2737         parentToken_ = token;
2738     }
2739 }
2740 
GetParentToken()2741 sptr<IRemoteObject> AceContainer::GetParentToken()
2742 {
2743     std::lock_guard<std::mutex> lock(cardTokensMutex_);
2744     return parentToken_;
2745 }
2746 
2747 // ArkTsCard start
GetFormSurfaceNode(int32_t instanceId)2748 std::shared_ptr<Rosen::RSSurfaceNode> AceContainer::GetFormSurfaceNode(int32_t instanceId)
2749 {
2750     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
2751     CHECK_NULL_RETURN(container, nullptr);
2752     auto context = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
2753     CHECK_NULL_RETURN(context, nullptr);
2754     auto window = static_cast<FormRenderWindow*>(context->GetWindow());
2755     CHECK_NULL_RETURN(window, nullptr);
2756     return window->GetRSSurfaceNode();
2757 }
2758 
UpdateFormData(const std::string& data)2759 void AceContainer::UpdateFormData(const std::string& data)
2760 {
2761 #ifdef FORM_SUPPORTED
2762     auto frontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
2763     CHECK_NULL_VOID(frontend);
2764     frontend->UpdateData(data);
2765 #endif
2766 }
2767 
UpdateFormSharedImage(const std::map<std::string, sptr<AppExecFwk::FormAshmem>>& imageDataMap)2768 void AceContainer::UpdateFormSharedImage(const std::map<std::string, sptr<AppExecFwk::FormAshmem>>& imageDataMap)
2769 {
2770     std::vector<std::string> picNameArray;
2771     std::vector<int> fileDescriptorArray;
2772     std::vector<int> byteLenArray;
2773     if (!imageDataMap.empty()) {
2774         for (auto& imageData : imageDataMap) {
2775             picNameArray.push_back(imageData.first);
2776             fileDescriptorArray.push_back(imageData.second->GetAshmemFd());
2777             byteLenArray.push_back(imageData.second->GetAshmemSize());
2778         }
2779         GetNamesOfSharedImage(picNameArray);
2780         UpdateSharedImage(picNameArray, byteLenArray, fileDescriptorArray);
2781     }
2782 }
2783 
UpdateResource()2784 void AceContainer::UpdateResource()
2785 {
2786     // Reload theme and resource
2787     CHECK_NULL_VOID(pipelineContext_);
2788 
2789     if (SystemProperties::GetResourceDecoupling()) {
2790         auto context = runtimeContext_.lock();
2791         auto abilityInfo = abilityInfo_.lock();
2792         if (pipelineContext_->IsFormRender()) {
2793             ReleaseResourceAdapter();
2794         }
2795         InitResourceAndThemeManager(
2796             pipelineContext_, assetManager_, colorScheme_, resourceInfo_, context, abilityInfo, true);
2797     } else {
2798         ThemeConstants::InitDeviceType();
2799         auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>();
2800         pipelineContext_->SetThemeManager(themeManager);
2801         themeManager->InitResource(resourceInfo_);
2802         themeManager->SetColorScheme(colorScheme_);
2803         themeManager->LoadCustomTheme(assetManager_);
2804         themeManager->LoadResourceThemes();
2805     }
2806 
2807     auto cache = pipelineContext_->GetImageCache();
2808     if (cache) {
2809         cache->Clear();
2810     }
2811 }
2812 
GetNamesOfSharedImage(std::vector<std::string>& picNameArray)2813 void AceContainer::GetNamesOfSharedImage(std::vector<std::string>& picNameArray)
2814 {
2815     if (picNameArray.empty()) {
2816         LOGE("picNameArray is null!");
2817         return;
2818     }
2819     auto context = AceType::DynamicCast<NG::PipelineContext>(GetPipelineContext());
2820     CHECK_NULL_VOID(context);
2821     auto sharedImageManager = context->GetOrCreateSharedImageManager();
2822     auto nameSize = picNameArray.size();
2823     for (uint32_t i = 0; i < nameSize; i++) {
2824         // get name of picture
2825         auto name = picNameArray[i];
2826         sharedImageManager->AddPictureNamesToReloadMap(std::move(name));
2827     }
2828 }
2829 
UpdateSharedImage( std::vector<std::string>& picNameArray, std::vector<int32_t>& byteLenArray, std::vector<int>& fileDescriptorArray)2830 void AceContainer::UpdateSharedImage(
2831     std::vector<std::string>& picNameArray, std::vector<int32_t>& byteLenArray, std::vector<int>& fileDescriptorArray)
2832 {
2833     auto context = GetPipelineContext();
2834     CHECK_NULL_VOID(context);
2835     if (picNameArray.empty() || byteLenArray.empty() || fileDescriptorArray.empty()) {
2836         LOGE("array is null! when try UpdateSharedImage");
2837         return;
2838     }
2839     auto nameArraySize = picNameArray.size();
2840     if (nameArraySize != byteLenArray.size()) {
2841         LOGE("nameArraySize does not equal to fileDescriptorArraySize, please check!");
2842         return;
2843     }
2844     if (nameArraySize != fileDescriptorArray.size()) {
2845         LOGE("nameArraySize does not equal to fileDescriptorArraySize, please check!");
2846         return;
2847     }
2848     // now it can be assured that all three arrays are of the same size
2849 
2850     std::string picNameCopy;
2851     for (uint32_t i = 0; i < nameArraySize; i++) {
2852         // get name of picture
2853         auto picName = picNameArray[i];
2854         // save a copy of picName and ReleaseStringUTFChars immediately to avoid memory leak
2855         picNameCopy = picName;
2856 
2857         // get fd ID
2858         auto fd = fileDescriptorArray[i];
2859 
2860         auto newFd = dup(fd);
2861         if (newFd < 0) {
2862             LOGE("dup fd fail, fail reason: %{public}s, fd: %{public}d, picName: %{private}s, length: %{public}d",
2863                 strerror(errno), fd, picNameCopy.c_str(), byteLenArray[i]);
2864             continue;
2865         }
2866 
2867         auto ashmem = Ashmem(newFd, byteLenArray[i]);
2868         GetImageDataFromAshmem(picNameCopy, ashmem, context, byteLenArray[i]);
2869         ashmem.UnmapAshmem();
2870         ashmem.CloseAshmem();
2871     }
2872 }
2873 
GetImageDataFromAshmem( const std::string& picName, Ashmem& ashmem, const RefPtr<PipelineBase>& pipelineContext, int len)2874 void AceContainer::GetImageDataFromAshmem(
2875     const std::string& picName, Ashmem& ashmem, const RefPtr<PipelineBase>& pipelineContext, int len)
2876 {
2877     bool ret = ashmem.MapReadOnlyAshmem();
2878     // if any exception causes a [return] before [AddSharedImage], the memory image will not show because [RenderImage]
2879     // will never be notified to start loading.
2880     if (!ret) {
2881         LOGE("MapReadOnlyAshmem fail, fail reason: %{public}s, picName: %{private}s, length: %{public}d, "
2882              "fd: %{public}d",
2883             strerror(errno), picName.c_str(), len, ashmem.GetAshmemFd());
2884         return;
2885     }
2886     const uint8_t* imageData = reinterpret_cast<const uint8_t*>(ashmem.ReadFromAshmem(len, 0));
2887     if (imageData == nullptr) {
2888         LOGE("imageData is nullptr, errno is: %{public}s, picName: %{private}s, length: %{public}d, fd: %{public}d",
2889             strerror(errno), picName.c_str(), len, ashmem.GetAshmemFd());
2890         return;
2891     }
2892     auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
2893     CHECK_NULL_VOID(context);
2894     RefPtr<SharedImageManager> sharedImageManager = context->GetOrCreateSharedImageManager();
2895     if (sharedImageManager) {
2896         // read image data from shared memory and save a copy to sharedImageManager
2897         sharedImageManager->AddSharedImage(picName, std::vector<uint8_t>(imageData, imageData + len));
2898     }
2899 }
2900 
IsScenceBoardWindow()2901 bool AceContainer::IsScenceBoardWindow()
2902 {
2903     CHECK_NULL_RETURN(uiWindow_, false);
2904     return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_SCENE_BOARD;
2905 }
2906 
IsUIExtensionWindow()2907 bool AceContainer::IsUIExtensionWindow()
2908 {
2909     CHECK_NULL_RETURN(uiWindow_, false);
2910     return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_UI_EXTENSION;
2911 }
2912 
IsSceneBoardEnabled()2913 bool AceContainer::IsSceneBoardEnabled()
2914 {
2915     return Rosen::SceneBoardJudgement::IsSceneBoardEnabled();
2916 }
2917 // ArkTsCard end
2918 
IsMainWindow() const2919 bool AceContainer::IsMainWindow() const
2920 {
2921     CHECK_NULL_RETURN(uiWindow_, false);
2922     return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_APP_MAIN_WINDOW;
2923 }
2924 
IsSubWindow() const2925 bool AceContainer::IsSubWindow() const
2926 {
2927     CHECK_NULL_RETURN(uiWindow_, false);
2928     return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW;
2929 }
2930 
IsDialogWindow() const2931 bool AceContainer::IsDialogWindow() const
2932 {
2933     CHECK_NULL_RETURN(uiWindow_, false);
2934     return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_DIALOG;
2935 }
2936 
IsSystemWindow() const2937 bool AceContainer::IsSystemWindow() const
2938 {
2939     CHECK_NULL_RETURN(uiWindow_, false);
2940     return uiWindow_->GetType() >= Rosen::WindowType::ABOVE_APP_SYSTEM_WINDOW_BASE &&
2941         uiWindow_->GetType() <= Rosen::WindowType::ABOVE_APP_SYSTEM_WINDOW_END;
2942 }
2943 
GetParentWindowType() const2944 uint32_t AceContainer::GetParentWindowType() const
2945 {
2946     CHECK_NULL_RETURN(uiWindow_, DEFAULT_WINDOW_TYPE);
2947     return static_cast<uint32_t>(uiWindow_->GetParentWindowType());
2948 }
2949 
GetWindowType() const2950 uint32_t AceContainer::GetWindowType() const
2951 {
2952     CHECK_NULL_RETURN(uiWindow_, DEFAULT_WINDOW_TYPE);
2953     return static_cast<uint32_t>(uiWindow_->GetType());
2954 }
2955 
IsHostMainWindow() const2956 bool AceContainer::IsHostMainWindow() const
2957 {
2958     CHECK_NULL_RETURN(uiWindow_, false);
2959     return uiWindow_->GetParentWindowType() == Rosen::WindowType::WINDOW_TYPE_APP_MAIN_WINDOW;
2960 }
2961 
IsHostSubWindow() const2962 bool AceContainer::IsHostSubWindow() const
2963 {
2964     CHECK_NULL_RETURN(uiWindow_, false);
2965     return uiWindow_->GetParentWindowType() == Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW;
2966 }
2967 
IsHostDialogWindow() const2968 bool AceContainer::IsHostDialogWindow() const
2969 {
2970     CHECK_NULL_RETURN(uiWindow_, false);
2971     return uiWindow_->GetParentWindowType() == Rosen::WindowType::WINDOW_TYPE_DIALOG;
2972 }
2973 
IsHostSystemWindow() const2974 bool AceContainer::IsHostSystemWindow() const
2975 {
2976     CHECK_NULL_RETURN(uiWindow_, false);
2977     return uiWindow_->GetParentWindowType() >= Rosen::WindowType::ABOVE_APP_SYSTEM_WINDOW_BASE &&
2978         uiWindow_->GetParentWindowType() <= Rosen::WindowType::ABOVE_APP_SYSTEM_WINDOW_END;
2979 }
2980 
IsHostSceneBoardWindow() const2981 bool AceContainer::IsHostSceneBoardWindow() const
2982 {
2983     CHECK_NULL_RETURN(uiWindow_, false);
2984     return uiWindow_->GetParentWindowType() == Rosen::WindowType::WINDOW_TYPE_SCENE_BOARD;
2985 }
2986 
GetParentMainWindowId(uint32_t currentWindowId) const2987 uint32_t AceContainer::GetParentMainWindowId(uint32_t currentWindowId) const
2988 {
2989     uint32_t parentMainWindowId = 0;
2990     if (uiWindow_) {
2991         parentMainWindowId = uiWindow_->GetParentMainWindowId(currentWindowId);
2992         if (parentMainWindowId == 0) {
2993             TAG_LOGE(AceLogTag::ACE_SUB_WINDOW,
2994                 "GetParentMainWindowId, current windowId: %{public}d, main windowId: %{public}d",
2995                 currentWindowId, parentMainWindowId);
2996         }
2997     } else {
2998         TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "Window in container is nullptr when getting main windowId");
2999     }
3000     return parentMainWindowId;
3001 }
3002 
SetCurPointerEvent(const std::shared_ptr<MMI::PointerEvent>& currentEvent)3003 void AceContainer::SetCurPointerEvent(const std::shared_ptr<MMI::PointerEvent>& currentEvent)
3004 {
3005     std::lock_guard<std::mutex> lock(pointerEventMutex_);
3006     CHECK_NULL_VOID(currentEvent);
3007     currentPointerEvent_ = currentEvent;
3008     auto pointerAction = currentEvent->GetPointerAction();
3009     if (pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW ||
3010         pointerAction == MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW) {
3011         return;
3012     }
3013     MMI::PointerEvent::PointerItem pointerItem;
3014     currentEvent->GetPointerItem(currentEvent->GetPointerId(), pointerItem);
3015     int32_t originId = pointerItem.GetOriginPointerId();
3016     currentEvents_[originId] = currentEvent;
3017     auto callbacksIter = stopDragCallbackMap_.begin();
3018     while (callbacksIter != stopDragCallbackMap_.end()) {
3019         auto pointerId = callbacksIter->first;
3020         MMI::PointerEvent::PointerItem pointerItem;
3021         if (!currentEvent->GetPointerItem(pointerId, pointerItem)) {
3022             for (const auto& callback : callbacksIter->second) {
3023                 if (callback) {
3024                     callback();
3025                 }
3026             }
3027             callbacksIter = stopDragCallbackMap_.erase(callbacksIter);
3028         } else {
3029             if (!pointerItem.IsPressed()) {
3030                 for (const auto& callback : callbacksIter->second) {
3031                     if (callback) {
3032                         callback();
3033                     }
3034                 }
3035                 callbacksIter = stopDragCallbackMap_.erase(callbacksIter);
3036             } else {
3037                 ++callbacksIter;
3038             }
3039         }
3040     }
3041 }
3042 
GetCurPointerEventInfo( int32_t& pointerId, int32_t& globalX, int32_t& globalY, int32_t& sourceType, int32_t& sourceTool, StopDragCallback&& stopDragCallback)3043 bool AceContainer::GetCurPointerEventInfo(
3044     int32_t& pointerId, int32_t& globalX, int32_t& globalY, int32_t& sourceType,
3045     int32_t& sourceTool, StopDragCallback&& stopDragCallback)
3046 {
3047     std::lock_guard<std::mutex> lock(pointerEventMutex_);
3048     MMI::PointerEvent::PointerItem pointerItem;
3049     auto iter = currentEvents_.find(pointerId);
3050     if (iter == currentEvents_.end()) {
3051         return false;
3052     }
3053 
3054     auto currentPointerEvent = iter->second;
3055     CHECK_NULL_RETURN(currentPointerEvent, false);
3056     pointerId = currentPointerEvent->GetPointerId();
3057     if (!currentPointerEvent->GetPointerItem(pointerId, pointerItem) || !pointerItem.IsPressed()) {
3058         return false;
3059     }
3060     sourceType = currentPointerEvent->GetSourceType();
3061     globalX = pointerItem.GetDisplayX();
3062     globalY = pointerItem.GetDisplayY();
3063     sourceTool = pointerItem.GetToolType();
3064     RegisterStopDragCallback(pointerId, std::move(stopDragCallback));
3065     return true;
3066 }
3067 
GetCurPointerEventSourceType(int32_t& sourceType)3068 bool AceContainer::GetCurPointerEventSourceType(int32_t& sourceType)
3069 {
3070     std::lock_guard<std::mutex> lock(pointerEventMutex_);
3071     CHECK_NULL_RETURN(currentPointerEvent_, false);
3072     MMI::PointerEvent::PointerItem pointerItem;
3073     sourceType = currentPointerEvent_->GetSourceType();
3074     return true;
3075 }
3076 
RegisterStopDragCallback(int32_t pointerId, StopDragCallback&& stopDragCallback)3077 void AceContainer::RegisterStopDragCallback(int32_t pointerId, StopDragCallback&& stopDragCallback)
3078 {
3079     auto iter = stopDragCallbackMap_.find(pointerId);
3080     if (iter != stopDragCallbackMap_.end()) {
3081         iter->second.emplace_back(std::move(stopDragCallback));
3082     } else {
3083         std::list<StopDragCallback> list;
3084         list.emplace_back(std::move(stopDragCallback));
3085         stopDragCallbackMap_.emplace(pointerId, list);
3086     }
3087 }
3088 
SearchElementInfoByAccessibilityIdNG( int64_t elementId, int32_t mode, int64_t baseParent, std::list<Accessibility::AccessibilityElementInfo>& output)3089 void AceContainer::SearchElementInfoByAccessibilityIdNG(
3090     int64_t elementId, int32_t mode, int64_t baseParent,
3091     std::list<Accessibility::AccessibilityElementInfo>& output)
3092 {
3093     CHECK_NULL_VOID(taskExecutor_);
3094     taskExecutor_->PostSyncTaskTimeout(
3095         [weak = WeakClaim(this), elementId, mode, baseParent, &output]() {
3096             auto container = weak.Upgrade();
3097             CHECK_NULL_VOID(container);
3098             auto pipelineContext = container->GetPipelineContext();
3099             auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3100             CHECK_NULL_VOID(ngPipeline);
3101             auto frontend = container->GetFrontend();
3102             CHECK_NULL_VOID(frontend);
3103             auto accessibilityManager = frontend->GetAccessibilityManager();
3104             CHECK_NULL_VOID(accessibilityManager);
3105             accessibilityManager->SearchElementInfoByAccessibilityIdNG(
3106                 elementId, mode, output, ngPipeline, baseParent);
3107         },
3108         TaskExecutor::TaskType::UI, SEARCH_ELEMENT_TIMEOUT_TIME, "ArkUISearchElementInfoById");
3109 }
3110 
SearchElementInfosByTextNG( int64_t elementId, const std::string& text, int64_t baseParent, std::list<Accessibility::AccessibilityElementInfo>& output)3111 void AceContainer::SearchElementInfosByTextNG(
3112     int64_t elementId, const std::string& text, int64_t baseParent,
3113     std::list<Accessibility::AccessibilityElementInfo>& output)
3114 {
3115     CHECK_NULL_VOID(taskExecutor_);
3116     taskExecutor_->PostSyncTaskTimeout(
3117         [weak = WeakClaim(this), elementId, &text, baseParent, &output]() {
3118             auto container = weak.Upgrade();
3119             CHECK_NULL_VOID(container);
3120             auto pipelineContext = container->GetPipelineContext();
3121             auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3122             CHECK_NULL_VOID(ngPipeline);
3123             auto frontend = container->GetFrontend();
3124             CHECK_NULL_VOID(frontend);
3125             auto accessibilityManager = frontend->GetAccessibilityManager();
3126             CHECK_NULL_VOID(accessibilityManager);
3127             accessibilityManager->SearchElementInfosByTextNG(
3128                 elementId, text, output, ngPipeline, baseParent);
3129         },
3130         TaskExecutor::TaskType::UI, SEARCH_ELEMENT_TIMEOUT_TIME, "ArkUISearchElementInfoByText");
3131 }
3132 
FindFocusedElementInfoNG( int64_t elementId, int32_t focusType, int64_t baseParent, Accessibility::AccessibilityElementInfo& output)3133 void AceContainer::FindFocusedElementInfoNG(
3134     int64_t elementId, int32_t focusType, int64_t baseParent,
3135     Accessibility::AccessibilityElementInfo& output)
3136 {
3137     CHECK_NULL_VOID(taskExecutor_);
3138     taskExecutor_->PostSyncTaskTimeout(
3139         [weak = WeakClaim(this), elementId, focusType, baseParent, &output]() {
3140             auto container = weak.Upgrade();
3141             CHECK_NULL_VOID(container);
3142             auto pipelineContext = container->GetPipelineContext();
3143             auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3144             CHECK_NULL_VOID(ngPipeline);
3145             auto frontend = container->GetFrontend();
3146             CHECK_NULL_VOID(frontend);
3147             auto accessibilityManager = frontend->GetAccessibilityManager();
3148             CHECK_NULL_VOID(accessibilityManager);
3149             accessibilityManager->FindFocusedElementInfoNG(
3150                 elementId, focusType, output, ngPipeline, baseParent);
3151         },
3152         TaskExecutor::TaskType::UI, SEARCH_ELEMENT_TIMEOUT_TIME, "ArkUIFindFocusedElementInfo");
3153 }
3154 
FocusMoveSearchNG( int64_t elementId, int32_t direction, int64_t baseParent, Accessibility::AccessibilityElementInfo& output)3155 void AceContainer::FocusMoveSearchNG(
3156     int64_t elementId, int32_t direction, int64_t baseParent,
3157     Accessibility::AccessibilityElementInfo& output)
3158 {
3159     CHECK_NULL_VOID(taskExecutor_);
3160     taskExecutor_->PostSyncTaskTimeout(
3161         [weak = WeakClaim(this), elementId, direction, baseParent, &output]() {
3162             auto container = weak.Upgrade();
3163             CHECK_NULL_VOID(container);
3164             auto pipelineContext = container->GetPipelineContext();
3165             auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3166             CHECK_NULL_VOID(ngPipeline);
3167             auto frontend = container->GetFrontend();
3168             CHECK_NULL_VOID(frontend);
3169             auto accessibilityManager = frontend->GetAccessibilityManager();
3170             CHECK_NULL_VOID(accessibilityManager);
3171             accessibilityManager->FocusMoveSearchNG(elementId, direction, output, ngPipeline, baseParent);
3172         },
3173         TaskExecutor::TaskType::UI, SEARCH_ELEMENT_TIMEOUT_TIME, "ArkUIFocusMoveSearch");
3174 }
3175 
NotifyExecuteAction( int64_t elementId, const std::map<std::string, std::string>& actionArguments, int32_t action, int64_t offset)3176 bool AceContainer::NotifyExecuteAction(
3177     int64_t elementId, const std::map<std::string, std::string>& actionArguments,
3178     int32_t action, int64_t offset)
3179 {
3180     bool IsExecuted = false;
3181     CHECK_NULL_RETURN(taskExecutor_, IsExecuted);
3182     taskExecutor_->PostSyncTaskTimeout(
3183         [weak = WeakClaim(this), elementId, &actionArguments, action, offset, &IsExecuted]() {
3184             auto container = weak.Upgrade();
3185             CHECK_NULL_VOID(container);
3186             auto pipelineContext = container->GetPipelineContext();
3187             auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3188             CHECK_NULL_VOID(ngPipeline);
3189             auto frontend = container->GetFrontend();
3190             CHECK_NULL_VOID(frontend);
3191             auto accessibilityManager = frontend->GetAccessibilityManager();
3192             CHECK_NULL_VOID(accessibilityManager);
3193             IsExecuted = accessibilityManager->ExecuteExtensionActionNG(
3194                 elementId, actionArguments, action, ngPipeline, offset);
3195         },
3196         TaskExecutor::TaskType::UI, SEARCH_ELEMENT_TIMEOUT_TIME, "ArkUIExecuteExtensionAction");
3197     return IsExecuted;
3198 }
3199 
HandleAccessibilityHoverEvent(float pointX, float pointY, int32_t sourceType, int32_t eventType, int64_t timeMs)3200 void AceContainer::HandleAccessibilityHoverEvent(float pointX, float pointY, int32_t sourceType,
3201     int32_t eventType, int64_t timeMs)
3202 {
3203     CHECK_NULL_VOID(taskExecutor_);
3204     taskExecutor_->PostTask(
3205         [weak = WeakClaim(this), pointX, pointY, sourceType, eventType, timeMs] {
3206             auto container = weak.Upgrade();
3207             CHECK_NULL_VOID(container);
3208             ContainerScope scope(container->GetInstanceId());
3209             auto pipelineContext = container->GetPipelineContext();
3210             auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3211             CHECK_NULL_VOID(ngPipeline);
3212             auto root = ngPipeline->GetRootElement();
3213             CHECK_NULL_VOID(root);
3214             auto accessibilityManagerNG = ngPipeline->GetAccessibilityManagerNG();
3215             CHECK_NULL_VOID(accessibilityManagerNG);
3216             accessibilityManagerNG->HandleAccessibilityHoverEvent(root, pointX, pointY, sourceType, eventType, timeMs);
3217         },
3218         TaskExecutor::TaskType::UI, "ArkUIHandleAccessibilityHoverEvent");
3219 }
3220 
GetOverlayNodePositions()3221 std::vector<Ace::RectF> AceContainer::GetOverlayNodePositions()
3222 {
3223     auto pipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
3224     CHECK_NULL_RETURN(pipeline, {});
3225     return pipeline->GetOverlayNodePositions();
3226 }
3227 
RegisterOverlayNodePositionsUpdateCallback( const std::function<void(std::vector<Ace::RectF>)>&& callback)3228 void AceContainer::RegisterOverlayNodePositionsUpdateCallback(
3229     const std::function<void(std::vector<Ace::RectF>)>&& callback)
3230 {
3231     auto pipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
3232     CHECK_NULL_VOID(pipeline);
3233     pipeline->RegisterOverlayNodePositionsUpdateCallback(std::move(callback));
3234 }
3235 
TerminateUIExtension()3236 void AceContainer::TerminateUIExtension()
3237 {
3238     if (!IsUIExtensionWindow()) {
3239         return;
3240     }
3241     auto sharedContext = runtimeContext_.lock();
3242     auto uiExtensionContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::UIExtensionContext>(sharedContext);
3243     CHECK_NULL_VOID(uiExtensionContext);
3244     uiExtensionContext->TerminateSelf();
3245 }
3246 
RegisterAvoidAreaChangeListener(sptr<Rosen::IAvoidAreaChangedListener>& listener)3247 Rosen::WMError AceContainer::RegisterAvoidAreaChangeListener(sptr<Rosen::IAvoidAreaChangedListener>& listener)
3248 {
3249     if (!uiWindow_) {
3250         return Rosen::WMError::WM_DO_NOTHING;
3251     }
3252     return uiWindow_->RegisterAvoidAreaChangeListener(listener);
3253 }
3254 
UnregisterAvoidAreaChangeListener(sptr<Rosen::IAvoidAreaChangedListener>& listener)3255 Rosen::WMError AceContainer::UnregisterAvoidAreaChangeListener(sptr<Rosen::IAvoidAreaChangedListener>& listener)
3256 {
3257     if (!uiWindow_) {
3258         return Rosen::WMError::WM_DO_NOTHING;
3259     }
3260     return uiWindow_->UnregisterAvoidAreaChangeListener(listener);
3261 }
3262 
OHOS_ACE_HotReloadPage()3263 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_HotReloadPage()
3264 {
3265     AceEngine::Get().NotifyContainers([](const RefPtr<Container>& container) {
3266         LOGI("starting hotReload");
3267 #ifndef NG_BUILD
3268         if (Container::IsCurrentUseNewPipeline()) {
3269             container->HotReload();
3270         } else {
3271             container->NotifyConfigurationChange(true);
3272         }
3273 #else
3274         container->HotReload();
3275 #endif
3276     });
3277 }
3278 
NeedFullUpdate(uint32_t limitKey)3279 bool AceContainer::NeedFullUpdate(uint32_t limitKey)
3280 {
3281     auto themeManager = pipelineContext_->GetThemeManager();
3282     if (!themeManager || (themeManager->GetResourceLimitKeys() & limitKey) == 0) {
3283         return false;
3284     }
3285     return true;
3286 }
3287 
NotifyDensityUpdate()3288 void AceContainer::NotifyDensityUpdate()
3289 {
3290     bool fullUpdate = NeedFullUpdate(DENSITY_KEY);
3291     auto frontend = GetFrontend();
3292     if (frontend) {
3293         frontend->FlushReload();
3294     }
3295     ConfigurationChange configurationChange { .dpiUpdate = true };
3296     pipelineContext_->FlushReload(configurationChange, fullUpdate);
3297 }
3298 
NotifyDirectionUpdate()3299 void AceContainer::NotifyDirectionUpdate()
3300 {
3301     bool fullUpdate = NeedFullUpdate(DIRECTION_KEY);
3302     if (fullUpdate) {
3303         ConfigurationChange configurationChange { .directionUpdate = true };
3304         pipelineContext_->FlushReload(configurationChange, fullUpdate);
3305     }
3306 }
3307 
RenderLayoutBoundary(bool isDebugBoundary)3308 void AceContainer::RenderLayoutBoundary(bool isDebugBoundary)
3309 {
3310     auto container = AceEngine::Get().GetContainer(instanceId_);
3311     CHECK_NULL_VOID(container);
3312     CHECK_NULL_VOID(renderBoundaryManager_);
3313     renderBoundaryManager_->PostTaskRenderBoundary(isDebugBoundary, container);
3314 }
3315 
AddWatchSystemParameter()3316 void AceContainer::AddWatchSystemParameter()
3317 {
3318     auto task = [weak = WeakClaim(this)] {
3319         auto weakPtr = weak.Upgrade();
3320         CHECK_NULL_VOID(weakPtr);
3321         auto container = static_cast<void*>(weakPtr.GetRawPtr());
3322         CHECK_NULL_VOID(container);
3323         SystemProperties::AddWatchSystemParameter(
3324             ENABLE_TRACE_LAYOUT_KEY, container, SystemProperties::EnableSystemParameterTraceLayoutCallback);
3325         SystemProperties::AddWatchSystemParameter(
3326             ENABLE_TRACE_INPUTEVENT_KEY, container, SystemProperties::EnableSystemParameterTraceInputEventCallback);
3327         SystemProperties::AddWatchSystemParameter(ENABLE_SECURITY_DEVELOPERMODE_KEY, container,
3328             SystemProperties::EnableSystemParameterSecurityDevelopermodeCallback);
3329         SystemProperties::AddWatchSystemParameter(
3330             ENABLE_DEBUG_STATEMGR_KEY, container, SystemProperties::EnableSystemParameterDebugStatemgrCallback);
3331         SystemProperties::AddWatchSystemParameter(
3332             ENABLE_DEBUG_BOUNDARY_KEY, container, SystemProperties::EnableSystemParameterDebugBoundaryCallback);
3333         SystemProperties::AddWatchSystemParameter(
3334             ENABLE_PERFORMANCE_MONITOR_KEY, container,
3335             SystemProperties::EnableSystemParameterPerformanceMonitorCallback);
3336     };
3337     BackgroundTaskExecutor::GetInstance().PostTask(task);
3338 }
3339 
RemoveWatchSystemParameter()3340 void AceContainer::RemoveWatchSystemParameter()
3341 {
3342     SystemProperties::RemoveWatchSystemParameter(
3343         ENABLE_TRACE_LAYOUT_KEY, this, SystemProperties::EnableSystemParameterTraceLayoutCallback);
3344     SystemProperties::RemoveWatchSystemParameter(
3345         ENABLE_TRACE_INPUTEVENT_KEY, this, SystemProperties::EnableSystemParameterTraceInputEventCallback);
3346     SystemProperties::RemoveWatchSystemParameter(
3347         ENABLE_SECURITY_DEVELOPERMODE_KEY, this, SystemProperties::EnableSystemParameterSecurityDevelopermodeCallback);
3348     SystemProperties::RemoveWatchSystemParameter(
3349         ENABLE_DEBUG_STATEMGR_KEY, this, SystemProperties::EnableSystemParameterDebugStatemgrCallback);
3350     SystemProperties::RemoveWatchSystemParameter(
3351         ENABLE_DEBUG_BOUNDARY_KEY, this, SystemProperties::EnableSystemParameterDebugBoundaryCallback);
3352     SystemProperties::RemoveWatchSystemParameter(
3353         ENABLE_PERFORMANCE_MONITOR_KEY, this, SystemProperties::EnableSystemParameterPerformanceMonitorCallback);
3354 }
3355 
UpdateResourceOrientation(int32_t orientation)3356 void AceContainer::UpdateResourceOrientation(int32_t orientation)
3357 {
3358     DeviceOrientation newOrientation = WindowUtils::GetDeviceOrientation(orientation);
3359     auto resConfig = GetResourceConfiguration();
3360     resConfig.SetOrientation(newOrientation);
3361     if (SystemProperties::GetResourceDecoupling()) {
3362         ResourceManager::GetInstance().UpdateResourceConfig(resConfig, false);
3363     }
3364     SetResourceConfiguration(resConfig);
3365 }
3366 
UpdateResourceDensity(double density)3367 void AceContainer::UpdateResourceDensity(double density)
3368 {
3369     auto resConfig = GetResourceConfiguration();
3370     resConfig.SetDensity(density);
3371     if (SystemProperties::GetResourceDecoupling()) {
3372         ResourceManager::GetInstance().UpdateResourceConfig(resConfig, false);
3373     }
3374     SetResourceConfiguration(resConfig);
3375 }
3376 } // namespace OHOS::Ace::Platform
3377