• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "auto_fill_manager.h"
19 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
20 #include "scene_board_judgement.h"
21 #include "ui/rs_surface_node.h"
22 #include "ui_extension_context.h"
23 
24 #include "adapter/ohos/entrance/ace_view_ohos.h"
25 #include "adapter/ohos/entrance/cj_utils/cj_utils.h"
26 #include "adapter/ohos/entrance/data_ability_helper_standard.h"
27 #include "adapter/ohos/entrance/file_asset_provider_impl.h"
28 #include "adapter/ohos/entrance/hap_asset_provider_impl.h"
29 #include "adapter/ohos/entrance/mmi_event_convertor.h"
30 #include "adapter/ohos/entrance/ui_content_impl.h"
31 #include "adapter/ohos/entrance/utils.h"
32 #include "adapter/ohos/osal/resource_adapter_impl_v2.h"
33 #include "adapter/ohos/osal/system_bar_style_ohos.h"
34 #include "adapter/ohos/osal/view_data_wrap_ohos.h"
35 #include "adapter/ohos/osal/window_utils.h"
36 #include "base/i18n/localization.h"
37 #include "base/log/jank_frame_report.h"
38 #include "base/thread/background_task_executor.h"
39 #include "base/thread/task_dependency_manager.h"
40 #include "bridge/card_frontend/card_frontend.h"
41 #include "bridge/card_frontend/form_frontend_declarative.h"
42 #include "bridge/common/utils/engine_helper.h"
43 #include "bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h"
44 #include "bridge/js_frontend/js_frontend.h"
45 #include "core/common/ace_engine.h"
46 #include "core/common/plugin_manager.h"
47 #include "core/common/resource/resource_manager.h"
48 #include "core/common/task_executor_impl.h"
49 #include "core/common/text_field_manager.h"
50 #include "core/components_ng/base/inspector.h"
51 #include "core/components_ng/pattern/text_field/text_field_manager.h"
52 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
53 #include "core/components_ng/render/adapter/form_render_window.h"
54 #include "core/components_ng/render/adapter/rosen_render_context.h"
55 #include "core/components_ng/render/adapter/rosen_window.h"
56 #include "core/components_ng/token_theme/token_theme_storage.h"
57 
58 #if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
59 #include "adapter/ohos/entrance/ace_rosen_sync_task.h"
60 #endif
61 
62 #include "base/ressched/ressched_report.h"
63 
64 namespace OHOS::Ace::Platform {
65 namespace {
66 constexpr uint32_t DIRECTION_KEY = 0b1000;
67 constexpr uint32_t DENSITY_KEY = 0b0100;
68 constexpr uint32_t POPUPSIZE_HEIGHT = 0;
69 constexpr uint32_t POPUPSIZE_WIDTH = 0;
70 constexpr int32_t SEARCH_ELEMENT_TIMEOUT_TIME = 1500;
71 constexpr int32_t POPUP_CALCULATE_RATIO = 2;
72 constexpr int32_t POPUP_EDGE_INTERVAL = 8;
73 constexpr int32_t POPUP_MIN_EDGE = 1;
74 constexpr uint32_t DEFAULT_WINDOW_TYPE = 1;
75 const char ENABLE_DEBUG_BOUNDARY_KEY[] = "persist.ace.debug.boundary.enabled";
76 const char ENABLE_TRACE_LAYOUT_KEY[] = "persist.ace.trace.layout.enabled";
77 const char ENABLE_TRACE_INPUTEVENT_KEY[] = "persist.ace.trace.inputevent.enabled";
78 const char ENABLE_SECURITY_DEVELOPERMODE_KEY[] = "const.security.developermode.state";
79 const char ENABLE_DEBUG_STATEMGR_KEY[] = "persist.ace.debug.statemgr.enabled";
80 const char ENABLE_PERFORMANCE_MONITOR_KEY[] = "persist.ace.performance.monitor.enabled";
81 const char IS_FOCUS_ACTIVE_KEY[] = "persist.gesture.smart_gesture_enable";
82 std::mutex g_mutexFormRenderFontFamily;
83 constexpr uint32_t RES_TYPE_CROWN_ROTATION_STATUS = 129;
84 constexpr int32_t EXTENSION_HALF_SCREEN_MODE = 2;
85 constexpr size_t RESOURCE_CACHE_DEFAULT_SIZE = 5;
86 #ifdef _ARM64_
87 const std::string ASSET_LIBARCH_PATH = "/lib/arm64";
88 #else
89 const std::string ASSET_LIBARCH_PATH = "/lib/arm";
90 #endif
91 const std::string THEME_JSON = "theme_config.json";
92 
93 #ifndef NG_BUILD
94 constexpr char ARK_ENGINE_SHARED_LIB[] = "libace_engine_ark.z.so";
GetEngineSharedLibrary()95 const char* GetEngineSharedLibrary()
96 {
97     return ARK_ENGINE_SHARED_LIB;
98 }
99 #endif
100 
101 constexpr char DECLARATIVE_ARK_ENGINE_SHARED_LIB[] = "libace_engine_declarative_ark.z.so";
GetDeclarativeSharedLibrary()102 const char* GetDeclarativeSharedLibrary()
103 {
104     return DECLARATIVE_ARK_ENGINE_SHARED_LIB;
105 }
106 
LoadSystemThemeFromJson(const RefPtr<AssetManager> & assetManager,const RefPtr<PipelineBase> & pipelineContext)107 void LoadSystemThemeFromJson(const RefPtr<AssetManager>& assetManager, const RefPtr<PipelineBase>& pipelineContext)
108 {
109     std::string themeJsonContent;
110     bool loadThemeJsonFlag = OHOS::Ace::Framework::GetAssetContentImpl(assetManager, THEME_JSON, themeJsonContent);
111     if (loadThemeJsonFlag) {
112         auto themeRootJson = JsonUtil::ParseJsonString(themeJsonContent);
113         if (themeRootJson) {
114             auto systemThemeId = themeRootJson->GetInt("systemTheme", -1);
115             if (systemThemeId != -1) {
116                 auto themeManager = pipelineContext->GetThemeManager();
117                 themeManager->LoadSystemTheme(systemThemeId);
118                 auto checkTheme = themeManager->GetSystemTheme();
119                 LOGI("get systemTheme id from json success, systemTheme id = %{public}d", checkTheme);
120             } else {
121                 LOGW("get systemTheme id from json failed, not a number");
122             }
123         } else {
124             LOGW("get systemTheme id from json failed, parse theme json file failed");
125         }
126     } else {
127         LOGW("get systemTheme id from json failed, %{public}s not found", THEME_JSON.c_str());
128     }
129 }
130 
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)131 void InitResourceAndThemeManager(const RefPtr<PipelineBase>& pipelineContext, const RefPtr<AssetManager>& assetManager,
132     const ColorScheme& colorScheme, const ResourceInfo& resourceInfo,
133     const std::shared_ptr<OHOS::AbilityRuntime::Context>& context,
134     const std::shared_ptr<OHOS::AppExecFwk::AbilityInfo>& abilityInfo, bool clearCache = false)
135 {
136     std::string bundleName = "";
137     std::string moduleName = "";
138     if (context) {
139         bundleName = context->GetBundleName();
140         moduleName = context->GetHapModuleInfo()->name;
141     } else if (abilityInfo) {
142         bundleName = abilityInfo->bundleName;
143         moduleName = abilityInfo->moduleName;
144     }
145     int32_t instanceId = pipelineContext->GetInstanceId();
146     RefPtr<ResourceAdapter> resourceAdapter = nullptr;
147     if (context && context->GetResourceManager()) {
148         resourceAdapter = AceType::MakeRefPtr<ResourceAdapterImplV2>(context->GetResourceManager(), resourceInfo);
149     } else if (ResourceManager::GetInstance().IsResourceAdapterRecord(bundleName, moduleName, instanceId)) {
150         resourceAdapter = ResourceManager::GetInstance().GetResourceAdapter(bundleName, moduleName, instanceId);
151     }
152 
153     if (resourceAdapter == nullptr) {
154         resourceAdapter = ResourceAdapter::CreateV2();
155         resourceAdapter->Init(resourceInfo);
156     }
157 
158     ThemeConstants::InitDeviceType();
159     auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>(resourceAdapter);
160     pipelineContext->SetThemeManager(themeManager);
161     LoadSystemThemeFromJson(assetManager, pipelineContext);
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(
173         defaultBundleName, defaultModuleName, instanceId, resourceAdapter, true);
174     if (!bundleName.empty() && !moduleName.empty()) {
175         ResourceManager::GetInstance().RegisterMainResourceAdapter(bundleName, moduleName, instanceId, resourceAdapter);
176         ResourceManager::GetInstance().RegisterMainResourceAdapter(
177             bundleName, moduleName, INSTANCE_ID_UNDEFINED, resourceAdapter);
178     }
179 }
180 
EncodeBundleAndModule(const std::string & bundleName,const std::string & moduleName)181 std::string EncodeBundleAndModule(const std::string& bundleName, const std::string& moduleName)
182 {
183     return bundleName + " " + moduleName;
184 }
185 
DecodeBundleAndModule(const std::string & encode,std::string & bundleName,std::string & moduleName)186 void DecodeBundleAndModule(const std::string& encode, std::string& bundleName, std::string& moduleName)
187 {
188     std::vector<std::string> tokens;
189     StringUtils::StringSplitter(encode, ' ', tokens);
190     bundleName = tokens[0];
191     moduleName = tokens[1];
192 }
193 
ReleaseStorageReference(void * sharedRuntime,NativeReference * storage)194 void ReleaseStorageReference(void* sharedRuntime, NativeReference* storage)
195 {
196     if (sharedRuntime && storage) {
197         auto nativeEngine = reinterpret_cast<NativeEngine*>(sharedRuntime);
198         auto env = reinterpret_cast<napi_env>(nativeEngine);
199         napi_delete_reference(env, reinterpret_cast<napi_ref>(storage));
200     }
201 }
202 
ParseLanguage(ConfigurationChange & configurationChange,const std::string & languageTag)203 void ParseLanguage(ConfigurationChange& configurationChange, const std::string& languageTag)
204 {
205     std::string language;
206     std::string script;
207     std::string region;
208     Localization::ParseLocaleTag(languageTag, language, script, region, false);
209     if (!language.empty() || !script.empty() || !region.empty()) {
210         configurationChange.languageUpdate = true;
211         AceApplicationInfo::GetInstance().SetLocale(language, region, script, "");
212     }
213 }
214 } // namespace
215 
AceContainer(int32_t instanceId,FrontendType type,std::shared_ptr<OHOS::AppExecFwk::Ability> aceAbility,std::unique_ptr<PlatformEventCallback> callback,bool useCurrentEventRunner,bool useNewPipeline)216 AceContainer::AceContainer(int32_t instanceId, FrontendType type, std::shared_ptr<OHOS::AppExecFwk::Ability> aceAbility,
217     std::unique_ptr<PlatformEventCallback> callback, bool useCurrentEventRunner, bool useNewPipeline)
218     : instanceId_(instanceId), type_(type), aceAbility_(aceAbility), useCurrentEventRunner_(useCurrentEventRunner)
219 {
220     ACE_DCHECK(callback);
221     if (useNewPipeline) {
222         SetUseNewPipeline();
223         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
224             SetUsePartialUpdate();
225         }
226     }
227     InitializeTask();
228     platformEventCallback_ = std::move(callback);
229     useStageModel_ = false;
230     auto ability = aceAbility_.lock();
231     if (ability) {
232         abilityInfo_ = ability->GetAbilityInfo();
233     }
234 }
235 
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)236 AceContainer::AceContainer(int32_t instanceId, FrontendType type,
237     std::weak_ptr<OHOS::AbilityRuntime::Context> runtimeContext,
238     std::weak_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo, std::unique_ptr<PlatformEventCallback> callback,
239     bool useCurrentEventRunner, bool isSubAceContainer, bool useNewPipeline)
240     : instanceId_(instanceId), type_(type), runtimeContext_(std::move(runtimeContext)),
241       abilityInfo_(std::move(abilityInfo)), useCurrentEventRunner_(useCurrentEventRunner),
242       isSubContainer_(isSubAceContainer)
243 {
244     ACE_DCHECK(callback);
245     if (useNewPipeline) {
246         SetUseNewPipeline();
247         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
248             SetUsePartialUpdate();
249         }
250     }
251     if (!isSubContainer_) {
252         InitializeTask();
253     }
254     platformEventCallback_ = std::move(callback);
255     useStageModel_ = true;
256 }
257 
258 // 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)259 AceContainer::AceContainer(int32_t instanceId, FrontendType type,
260     std::weak_ptr<OHOS::AbilityRuntime::Context> runtimeContext,
261     std::weak_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo, std::unique_ptr<PlatformEventCallback> callback,
262     std::shared_ptr<TaskWrapper> taskWrapper, bool useCurrentEventRunner, bool isSubAceContainer, bool useNewPipeline)
263     : instanceId_(instanceId), type_(type), runtimeContext_(std::move(runtimeContext)),
264       abilityInfo_(std::move(abilityInfo)), useCurrentEventRunner_(useCurrentEventRunner),
265       isSubContainer_(isSubAceContainer)
266 {
267     ACE_DCHECK(callback);
268     if (useNewPipeline) {
269         SetUseNewPipeline();
270         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
271             SetUsePartialUpdate();
272         }
273     }
274     if (!isSubContainer_) {
275         InitializeTask(taskWrapper);
276     }
277     platformEventCallback_ = std::move(callback);
278     useStageModel_ = true;
279 }
280 
AceContainer(int32_t instanceId,FrontendType type)281 AceContainer::AceContainer(int32_t instanceId, FrontendType type) : instanceId_(instanceId), type_(type)
282 {
283     auto taskExecutorImpl = Referenced::MakeRefPtr<TaskExecutorImpl>();
284     taskExecutorImpl->InitPlatformThread(true);
285     taskExecutor_ = taskExecutorImpl;
286     GetSettings().useUIAsJSThread = true;
287     GetSettings().usePlatformAsUIThread = true;
288     GetSettings().usingSharedRuntime = true;
289 }
290 
~AceContainer()291 AceContainer::~AceContainer()
292 {
293     std::lock_guard lock(destructMutex_);
294     LOGI("Container Destroyed");
295 }
296 
InitializeTask(std::shared_ptr<TaskWrapper> taskWrapper)297 void AceContainer::InitializeTask(std::shared_ptr<TaskWrapper> taskWrapper)
298 {
299     RefPtr<TaskExecutorImpl> taskExecutorImpl;
300     if (taskWrapper != nullptr) {
301         taskExecutorImpl = Referenced::MakeRefPtr<TaskExecutorImpl>(taskWrapper);
302     } else {
303         taskExecutorImpl = Referenced::MakeRefPtr<TaskExecutorImpl>();
304     }
305     taskExecutorImpl->InitPlatformThread(useCurrentEventRunner_);
306     taskExecutor_ = taskExecutorImpl;
307     // No need to create JS Thread for DECLARATIVE_JS
308     if (type_ == FrontendType::DECLARATIVE_JS || type_ == FrontendType::DECLARATIVE_CJ) {
309         GetSettings().useUIAsJSThread = true;
310     } else {
311         taskExecutorImpl->InitJsThread();
312     }
313 }
314 
IsKeyboard()315 bool AceContainer::IsKeyboard()
316 {
317     if (uiWindow_ == nullptr) {
318         return false;
319     }
320     return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT;
321 }
322 
Initialize()323 void AceContainer::Initialize()
324 {
325     ContainerScope scope(instanceId_);
326     // For DECLARATIVE_JS frontend use UI as JS Thread, so InitializeFrontend after UI thread created.
327     if (type_ != FrontendType::DECLARATIVE_JS && type_ != FrontendType::DECLARATIVE_CJ) {
328         InitializeFrontend();
329     }
330 }
331 
MaybeRelease()332 bool AceContainer::MaybeRelease()
333 {
334     CHECK_NULL_RETURN(taskExecutor_, true);
335     if (taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::PLATFORM)) {
336         LOGI("Destroy AceContainer on PLATFORM thread.");
337         return true;
338     } else {
339         std::lock_guard lock(destructMutex_);
340         LOGI("Post Destroy AceContainer Task to PLATFORM thread.");
341         return !taskExecutor_->PostTask(
342             [this] { delete this; }, TaskExecutor::TaskType::PLATFORM, "ArkUIAceContainerDestroy");
343     }
344 }
345 
Destroy()346 void AceContainer::Destroy()
347 {
348     LOGI("AceContainer Destroy begin");
349     ContainerScope scope(instanceId_);
350     RemoveWatchSystemParameter();
351 
352     ReleaseResourceAdapter();
353     if (pipelineContext_ && taskExecutor_) {
354         // 1. Destroy Pipeline on UI thread.
355         RefPtr<PipelineBase> context;
356         {
357             std::lock_guard<std::mutex> lock(pipelineMutex_);
358             context.Swap(pipelineContext_);
359         }
360         auto uiTask = [context]() { context->Destroy(); };
361         if (GetSettings().usePlatformAsUIThread) {
362             uiTask();
363         } else {
364             taskExecutor_->PostTask(uiTask, TaskExecutor::TaskType::UI, "ArkUIPipelineDestroy");
365         }
366 
367         if (isSubContainer_) {
368             // SubAceContainer just return.
369             return;
370         }
371 
372         // 2. Destroy Frontend on JS thread.
373         RefPtr<Frontend> frontend;
374         {
375             std::lock_guard<std::mutex> lock(frontendMutex_);
376             frontend.Swap(frontend_);
377         }
378         auto jsTask = [frontend]() {
379             auto lock = frontend->GetLock();
380             frontend->Destroy();
381         };
382         frontend->UpdateState(Frontend::State::ON_DESTROY);
383         if (GetSettings().usePlatformAsUIThread && GetSettings().useUIAsJSThread) {
384             jsTask();
385         } else {
386             taskExecutor_->PostTask(jsTask, TaskExecutor::TaskType::JS, "ArkUIFrontendDestroy");
387         }
388     }
389     DestroyToastSubwindow(instanceId_);
390     DestroySelectOverlaySubwindow(instanceId_);
391     resRegister_.Reset();
392     assetManager_.Reset();
393 }
394 
DestroyView()395 void AceContainer::DestroyView()
396 {
397     ContainerScope scope(instanceId_);
398     std::lock_guard<std::mutex> lock(viewMutex_);
399     aceView_ = nullptr;
400 }
401 
InitializeFrontend()402 void AceContainer::InitializeFrontend()
403 {
404     auto aceAbility = aceAbility_.lock();
405     if (type_ == FrontendType::JS) {
406 #ifndef NG_BUILD
407         frontend_ = Frontend::Create();
408         auto jsFrontend = AceType::DynamicCast<JsFrontend>(frontend_);
409         auto& loader = Framework::JsEngineLoader::Get(GetEngineSharedLibrary());
410         auto jsEngine = loader.CreateJsEngine(instanceId_);
411         jsEngine->AddExtraNativeObject("ability", aceAbility.get());
412         EngineHelper::AddEngine(instanceId_, jsEngine);
413         jsFrontend->SetJsEngine(jsEngine);
414         jsFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
415         jsFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
416 #endif
417     } else if (type_ == FrontendType::JS_CARD) {
418 #ifndef NG_BUILD
419         AceApplicationInfo::GetInstance().SetCardType();
420         frontend_ = AceType::MakeRefPtr<CardFrontend>();
421 #endif
422     } else if (type_ == FrontendType::DECLARATIVE_JS) {
423         if (isFormRender_) {
424 #ifdef FORM_SUPPORTED
425             LOGI("Init Form Frontend");
426             frontend_ = AceType::MakeRefPtr<FormFrontendDeclarative>();
427             auto cardFrontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
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             EngineHelper::AddEngine(instanceId_, jsEngine);
437             cardFrontend->SetJsEngine(jsEngine);
438             cardFrontend->SetPageProfile(pageProfile_);
439             cardFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
440             cardFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
441             // Card front
442             cardFrontend->SetRunningCardId(0); // ArkTsCard : nodeId, Host->FMS->FRS->innersdk
443             cardFrontend->SetIsFormRender(true);
444 #endif
445         } else if (!isSubContainer_) {
446 #ifdef NG_BUILD
447             frontend_ = AceType::MakeRefPtr<DeclarativeFrontendNG>();
448             auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontendNG>(frontend_);
449 #else
450             frontend_ = AceType::MakeRefPtr<DeclarativeFrontend>();
451             auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
452 #endif
453             auto& loader = Framework::JsEngineLoader::GetDeclarative(GetDeclarativeSharedLibrary());
454             RefPtr<Framework::JsEngine> jsEngine;
455             if (GetSettings().usingSharedRuntime) {
456                 jsEngine = loader.CreateJsEngineUsingSharedRuntime(instanceId_, sharedRuntime_);
457             } else {
458                 jsEngine = loader.CreateJsEngine(instanceId_);
459             }
460             jsEngine->AddExtraNativeObject("ability", aceAbility.get());
461             auto pageUrlCheckFunc =
462                 [id = instanceId_](const std::string& url, const std::function<void()>& callback,
463                     const std::function<void(int32_t, const std::string&)>& silentInstallErrorCallBack) {
464                     ContainerScope scope(id);
465                     auto container = Container::Current();
466                     CHECK_NULL_VOID(container);
467                     auto pageUrlChecker = container->GetPageUrlChecker();
468                     CHECK_NULL_VOID(pageUrlChecker);
469                     pageUrlChecker->LoadPageUrl(url, callback, silentInstallErrorCallBack);
470                 };
471             jsEngine->SetPageUrlCheckFunc(std::move(pageUrlCheckFunc));
472             EngineHelper::AddEngine(instanceId_, jsEngine);
473             declarativeFrontend->SetJsEngine(jsEngine);
474             declarativeFrontend->SetPageProfile(pageProfile_);
475             declarativeFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
476             declarativeFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
477         } else {
478             frontend_ = OHOS::Ace::Platform::AceContainer::GetContainer(parentId_)->GetFrontend();
479             return;
480         }
481     } else if (type_ == FrontendType::DECLARATIVE_CJ) {
482         LOGD("cj Frontend");
483         if (!isSubContainer_) {
484             auto cjFrontend = CJUtils::LoadCjFrontend(useNewPipeline_, useStageModel_);
485             if (cjFrontend == nullptr) {
486                 LOGE("Create cj frontend failed.");
487                 return;
488             }
489             frontend_ = AceType::Claim(reinterpret_cast<Frontend*>(cjFrontend));
490         } else {
491             frontend_ = OHOS::Ace::Platform::AceContainer::GetContainer(parentId_)->GetFrontend();
492             return;
493         }
494     } else {
495         LOGE("Frontend type not supported");
496         EventReport::SendAppStartException(AppStartExcepType::FRONTEND_TYPE_ERR);
497         return;
498     }
499     ACE_DCHECK(frontend_);
500     auto abilityInfo = abilityInfo_.lock();
501     std::shared_ptr<AppExecFwk::AbilityInfo> info = aceAbility ? aceAbility->GetAbilityInfo() : abilityInfo;
502     if (info && info->isLauncherAbility) {
503         frontend_->DisallowPopLastPage();
504     }
505     frontend_->Initialize(type_, taskExecutor_);
506 }
507 
GetContainer(int32_t instanceId)508 RefPtr<AceContainer> AceContainer::GetContainer(int32_t instanceId)
509 {
510     auto container = AceEngine::Get().GetContainer(instanceId);
511     CHECK_NULL_RETURN(container, nullptr);
512     auto aceContainer = AceType::DynamicCast<AceContainer>(container);
513     return aceContainer;
514 }
515 
MarkRemoveOverlayInSubwindow(const RefPtr<Subwindow> subwindow,int32_t instanceId)516 bool MarkRemoveOverlayInSubwindow(const RefPtr<Subwindow> subwindow, int32_t instanceId)
517 {
518     if (subwindow && subwindow->GetShown()) {
519         auto subContainerId = SubwindowManager::GetInstance()->GetSubContainerId(instanceId);
520         if (subContainerId < 0) {
521             return false;
522         }
523         ContainerScope scope(subContainerId);
524         auto overlayManager = subwindow->GetOverlayManager();
525         CHECK_NULL_RETURN(overlayManager, false);
526         return overlayManager->RemoveOverlayInSubwindow();
527     }
528     return false;
529 }
530 
RemoveOverlayBySubwindowManager(int32_t instanceId)531 bool AceContainer::RemoveOverlayBySubwindowManager(int32_t instanceId)
532 {
533     auto sortSubwindow = SubwindowManager::GetInstance()->GetSortSubwindow(instanceId);
534     for (const auto& subwindow : sortSubwindow) {
535         if (!MarkRemoveOverlayInSubwindow(subwindow, instanceId)) {
536             continue;
537         }
538         return true;
539     }
540     return false;
541 }
542 
GetAbilityContext()543 std::shared_ptr<OHOS::AbilityRuntime::Context> AceContainer::GetAbilityContext()
544 {
545     auto context = runtimeContext_.lock();
546     if (context == nullptr) {
547         LOGW("runtimeContext_ is null.");
548     }
549 
550     return context;
551 }
552 
SetJsContext(const std::shared_ptr<Framework::JsValue> & jsContext)553 void AceContainer::SetJsContext(const std::shared_ptr<Framework::JsValue>& jsContext)
554 {
555     ContainerScope scope(instanceId_);
556 #ifdef NG_BUILD
557     auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontendNG>(frontend_);
558 #else
559     auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
560 #endif
561     CHECK_NULL_VOID(declarativeFrontend);
562     auto jsEngine = AceType::DynamicCast<Framework::JsiDeclarativeEngine>(declarativeFrontend->GetJsEngine());
563     CHECK_NULL_VOID(jsEngine);
564     jsEngine->SetJsContext(jsContext);
565 }
566 
GetJsContext()567 std::shared_ptr<Framework::JsValue> AceContainer::GetJsContext()
568 {
569     ContainerScope scope(instanceId_);
570 #ifdef NG_BUILD
571     auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontendNG>(frontend_);
572 #else
573     auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
574 #endif
575     CHECK_NULL_RETURN(declarativeFrontend, nullptr);
576     auto jsEngine = AceType::DynamicCast<Framework::JsiDeclarativeEngine>(declarativeFrontend->GetJsEngine());
577     CHECK_NULL_RETURN(jsEngine, nullptr);
578     return jsEngine->GetJsContext();
579 }
580 
OnBackPressed(int32_t instanceId)581 bool AceContainer::OnBackPressed(int32_t instanceId)
582 {
583     auto container = AceEngine::Get().GetContainer(instanceId);
584     CHECK_NULL_RETURN(container, false);
585     // When the container is for overlay, it need close the overlay first.
586     if (container->IsSubContainer()) {
587 #ifdef NG_BUILD
588         TAG_LOGI(AceLogTag::ACE_UIEVENT, "back press for remove overlay node");
589         ContainerScope scope(instanceId);
590         auto subPipelineContext = DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
591         CHECK_NULL_RETURN(subPipelineContext, false);
592         auto overlayManager = subPipelineContext->GetOverlayManager();
593         CHECK_NULL_RETURN(overlayManager, false);
594         return overlayManager->RemoveOverlayInSubwindow();
595 #else
596         if (container->IsUseNewPipeline()) {
597             TAG_LOGI(AceLogTag::ACE_UIEVENT, "back press for remove overlay node");
598             ContainerScope scope(instanceId);
599             auto subPipelineContext = DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
600             CHECK_NULL_RETURN(subPipelineContext, false);
601             auto textfieldMgr = DynamicCast<NG::TextFieldManagerNG>(subPipelineContext->GetTextFieldManager());
602             if (textfieldMgr) {
603                 auto lastRequestKeyboardNodeId = textfieldMgr->GetLastRequestKeyboardId();
604                 auto lastRequestKeyboardNode = DynamicCast<NG::FrameNode>(
605                     ElementRegister::GetInstance()->GetUINodeById(lastRequestKeyboardNodeId));
606                 if (lastRequestKeyboardNode && lastRequestKeyboardNode->GetPageId() == -1 &&
607                     textfieldMgr->OnBackPressed()) {
608                     LOGI("textfield consumed backpressed event");
609                     return true;
610                 }
611             }
612             auto overlayManager = subPipelineContext->GetOverlayManager();
613             CHECK_NULL_RETURN(overlayManager, false);
614             if (overlayManager->RemoveOverlayInSubwindow()) {
615                 TAG_LOGI(AceLogTag::ACE_UIEVENT, "subwindow consumed backpressed event");
616                 return true;
617             }
618             instanceId = SubwindowManager::GetInstance()->GetParentContainerId(instanceId);
619         } else {
620             SubwindowManager::GetInstance()->CloseMenu();
621             TAG_LOGI(AceLogTag::ACE_UIEVENT, "Menu consumed backpressed event");
622             return true;
623         }
624 #endif
625     }
626     // remove overlay through SubwindowManager if subwindow unfocused.
627     if (RemoveOverlayBySubwindowManager(instanceId)) {
628         TAG_LOGI(AceLogTag::ACE_UIEVENT, "subwindow consumed backpressed event");
629         return true;
630     }
631     ContainerScope scope(instanceId);
632     auto context = container->GetPipelineContext();
633     CHECK_NULL_RETURN(context, false);
634     if (context->PopPageStackOverlay()) {
635         return true;
636     }
637     return context->CallRouterBackToPopPage();
638 }
639 
OnShow(int32_t instanceId)640 void AceContainer::OnShow(int32_t instanceId)
641 {
642     auto container = AceEngine::Get().GetContainer(instanceId);
643     CHECK_NULL_VOID(container);
644     ContainerScope scope(instanceId);
645     auto taskExecutor = container->GetTaskExecutor();
646     CHECK_NULL_VOID(taskExecutor);
647     if (!container->UpdateState(Frontend::State::ON_SHOW)) {
648         return;
649     }
650 
651     auto jsTask = [container, front = container->GetFrontend()]() {
652         if (front && !container->IsSubContainer()) {
653             front->UpdateState(Frontend::State::ON_SHOW);
654             front->OnShow();
655         }
656     };
657 
658     auto uiTask = [container]() {
659         std::unordered_map<int64_t, WeakPtr<Frontend>> cardFrontendMap;
660         container->GetCardFrontendMap(cardFrontendMap);
661         for (const auto& [_, weakCardFront] : cardFrontendMap) {
662             auto cardFront = weakCardFront.Upgrade();
663             if (!cardFront) {
664                 LOGE("cardFront is null");
665                 continue;
666             }
667             cardFront->OnShow();
668         }
669         auto pipelineBase = container->GetPipelineContext();
670         CHECK_NULL_VOID(pipelineBase);
671         pipelineBase->OnShow();
672         pipelineBase->SetForegroundCalled(true);
673     };
674 
675     // stege model needn't post task when already run on UI
676     if (container->GetSettings().useUIAsJSThread && taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
677         jsTask();
678         uiTask();
679     } else {
680         taskExecutor->PostTask(jsTask, TaskExecutor::TaskType::JS, "ArkUIFrontendShow");
681         taskExecutor->PostTask(uiTask, TaskExecutor::TaskType::UI, "ArkUICardFrontendShow");
682     }
683 }
684 
OnHide(int32_t instanceId)685 void AceContainer::OnHide(int32_t instanceId)
686 {
687     auto container = AceEngine::Get().GetContainer(instanceId);
688     CHECK_NULL_VOID(container);
689     ContainerScope scope(instanceId);
690     auto taskExecutor = container->GetTaskExecutor();
691     CHECK_NULL_VOID(taskExecutor);
692     if (!container->UpdateState(Frontend::State::ON_HIDE)) {
693         return;
694     }
695     std::unordered_map<int64_t, WeakPtr<Frontend>> cardFrontendMap;
696     container->GetCardFrontendMap(cardFrontendMap);
697 
698     auto jsTask = [container, front = container->GetFrontend(), cardFrontendMap]() {
699         if (front && !container->IsSubContainer()) {
700             front->UpdateState(Frontend::State::ON_HIDE);
701             front->OnHide();
702             front->TriggerGarbageCollection();
703         }
704         for (const auto& [_, weakCardFront] : cardFrontendMap) {
705             auto cardFront = weakCardFront.Upgrade();
706             if (!cardFront) {
707                 LOGE("cardFront is null");
708                 continue;
709             }
710             cardFront->TriggerGarbageCollection();
711         }
712     };
713 
714     auto uiTask = [container, cardFrontendMap]() {
715         for (const auto& [_, weakCardFront] : cardFrontendMap) {
716             auto cardFront = weakCardFront.Upgrade();
717             if (!cardFront) {
718                 LOGE("cardFront is null");
719                 continue;
720             }
721             cardFront->OnHide();
722         }
723         auto pipelineBase = container->GetPipelineContext();
724         CHECK_NULL_VOID(pipelineBase);
725         pipelineBase->OnHide();
726     };
727 
728     // stege model needn't post task when already run on UI
729     if (container->GetSettings().useUIAsJSThread && taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
730         jsTask();
731         uiTask();
732     } else {
733         taskExecutor->PostTask(jsTask, TaskExecutor::TaskType::JS, "ArkUIFrontendHide");
734         taskExecutor->PostTask(uiTask, TaskExecutor::TaskType::UI, "ArkUICardFrontendHide");
735     }
736 }
737 
OnActive(int32_t instanceId)738 void AceContainer::OnActive(int32_t instanceId)
739 {
740     auto container = AceEngine::Get().GetContainer(instanceId);
741     CHECK_NULL_VOID(container);
742     ContainerScope scope(instanceId);
743     auto taskExecutor = container->GetTaskExecutor();
744     CHECK_NULL_VOID(taskExecutor);
745 
746     auto front = container->GetFrontend();
747     if (front && !container->IsSubContainer() && front->GetState() != Frontend::State::ON_ACTIVE) {
748         WeakPtr<Frontend> weakFrontend = front;
749         taskExecutor->PostTask(
750             [weakFrontend, instanceId]() {
751                 auto frontend = weakFrontend.Upgrade();
752                 if (frontend) {
753                     ContainerScope scope(instanceId);
754                     frontend->UpdateState(Frontend::State::ON_ACTIVE);
755                     frontend->OnActive();
756                 }
757             },
758             TaskExecutor::TaskType::JS, "ArkUIFrontendActive");
759     }
760 
761     taskExecutor->PostTask(
762         [container]() {
763             auto pipelineContext = container->GetPipelineContext();
764             if (!pipelineContext) {
765                 LOGE("pipeline context is null, OnActive failed.");
766                 return;
767             }
768             ContainerScope scope(container->GetInstanceId());
769             pipelineContext->WindowFocus(true);
770             pipelineContext->ChangeDarkModeBrightness();
771         },
772         TaskExecutor::TaskType::UI, "ArkUIWindowFocus");
773 }
774 
OnInactive(int32_t instanceId)775 void AceContainer::OnInactive(int32_t instanceId)
776 {
777     auto container = AceEngine::Get().GetContainer(instanceId);
778     CHECK_NULL_VOID(container);
779     ContainerScope scope(instanceId);
780     auto taskExecutor = container->GetTaskExecutor();
781     CHECK_NULL_VOID(taskExecutor);
782 
783     auto front = container->GetFrontend();
784     if (front && !container->IsSubContainer() && front->GetState() != Frontend::State::ON_INACTIVE) {
785         WeakPtr<Frontend> weakFrontend = front;
786         taskExecutor->PostTask(
787             [weakFrontend, instanceId]() {
788                 auto frontend = weakFrontend.Upgrade();
789                 if (frontend) {
790                     ContainerScope scope(instanceId);
791                     frontend->UpdateState(Frontend::State::ON_INACTIVE);
792                     frontend->OnInactive();
793                 }
794             },
795             TaskExecutor::TaskType::JS, "ArkUIFrontendInactive");
796     }
797 
798     taskExecutor->PostTask(
799         [container]() {
800             auto pipelineContext = container->GetPipelineContext();
801             if (!pipelineContext) {
802                 LOGE("pipeline context is null, OnInactive failed.");
803                 return;
804             }
805             ContainerScope scope(container->GetInstanceId());
806             pipelineContext->WindowFocus(false);
807             pipelineContext->ChangeDarkModeBrightness();
808             if (container->IsScenceBoardWindow()) {
809                 JankFrameReport::GetInstance().FlushRecord();
810             }
811         },
812         TaskExecutor::TaskType::UI, "ArkUIWindowUnfocus");
813 }
814 
ActiveWindow(int32_t instanceId)815 void AceContainer::ActiveWindow(int32_t instanceId)
816 {
817     auto container = AceEngine::Get().GetContainer(instanceId);
818     CHECK_NULL_VOID(container);
819     ContainerScope scope(instanceId);
820     auto taskExecutor = container->GetTaskExecutor();
821     CHECK_NULL_VOID(taskExecutor);
822 
823     auto front = container->GetFrontend();
824     if (front && !container->IsSubContainer()) {
825         WeakPtr<Frontend> weakFrontend = front;
826         taskExecutor->PostTask(
827             [weakFrontend, instanceId]() {
828                 auto frontend = weakFrontend.Upgrade();
829                 if (frontend) {
830                     ContainerScope scope(instanceId);
831                     frontend->UpdateState(Frontend::State::ON_ACTIVE);
832                     frontend->OnActive();
833                 }
834             },
835             TaskExecutor::TaskType::JS, "ArkUIFrontendActive",
836             TaskExecutor::GetPriorityTypeWithCheck(PriorityType::VIP));
837     }
838 
839     taskExecutor->PostTask(
840         [container]() {
841             auto pipelineContext = container->GetPipelineContext();
842             if (!pipelineContext) {
843                 LOGE("pipeline context is null, ActiveWindow failed.");
844                 return;
845             }
846             ContainerScope scope(container->GetInstanceId());
847             pipelineContext->WindowActivate(true);
848             pipelineContext->ChangeDarkModeBrightness();
849         },
850         TaskExecutor::TaskType::UI, "ArkUIWindowActivate", TaskExecutor::GetPriorityTypeWithCheck(PriorityType::VIP));
851 }
852 
UnActiveWindow(int32_t instanceId)853 void AceContainer::UnActiveWindow(int32_t instanceId)
854 {
855     auto container = AceEngine::Get().GetContainer(instanceId);
856     CHECK_NULL_VOID(container);
857     ContainerScope scope(instanceId);
858     auto taskExecutor = container->GetTaskExecutor();
859     CHECK_NULL_VOID(taskExecutor);
860 
861     auto front = container->GetFrontend();
862     if (front && !container->IsSubContainer()) {
863         WeakPtr<Frontend> weakFrontend = front;
864         taskExecutor->PostTask(
865             [weakFrontend, instanceId]() {
866                 auto frontend = weakFrontend.Upgrade();
867                 if (frontend) {
868                     ContainerScope scope(instanceId);
869                     frontend->UpdateState(Frontend::State::ON_INACTIVE);
870                     frontend->OnInactive();
871                 }
872             },
873             TaskExecutor::TaskType::JS, "ArkUIFrontendInactive",
874             TaskExecutor::GetPriorityTypeWithCheck(PriorityType::VIP));
875     }
876 
877     taskExecutor->PostTask(
878         [container]() {
879             auto pipelineContext = container->GetPipelineContext();
880             if (!pipelineContext) {
881                 LOGE("pipeline context is null, OnInactive failed.");
882                 return;
883             }
884             ContainerScope scope(container->GetInstanceId());
885             pipelineContext->WindowActivate(false);
886             pipelineContext->ChangeDarkModeBrightness();
887             if (container->IsScenceBoardWindow()) {
888                 JankFrameReport::GetInstance().FlushRecord();
889             }
890         },
891         TaskExecutor::TaskType::UI, "ArkUIWindowUnActivate", TaskExecutor::GetPriorityTypeWithCheck(PriorityType::VIP));
892 }
893 
OnNewWant(int32_t instanceId,const std::string & data)894 void AceContainer::OnNewWant(int32_t instanceId, const std::string& data)
895 {
896     auto container = AceEngine::Get().GetContainer(instanceId);
897     CHECK_NULL_VOID(container);
898     ContainerScope scope(instanceId);
899     auto front = container->GetFrontend();
900     CHECK_NULL_VOID(front);
901     front->OnNewWant(data);
902 }
903 
OnStartContinuation(int32_t instanceId)904 bool AceContainer::OnStartContinuation(int32_t instanceId)
905 {
906     auto container = AceEngine::Get().GetContainer(instanceId);
907     CHECK_NULL_RETURN(container, false);
908     ContainerScope scope(instanceId);
909     auto front = container->GetFrontend();
910     CHECK_NULL_RETURN(front, false);
911     return front->OnStartContinuation();
912 }
913 
OnSaveData(int32_t instanceId)914 std::string AceContainer::OnSaveData(int32_t instanceId)
915 {
916     std::string result = "false";
917     auto container = AceEngine::Get().GetContainer(instanceId);
918     CHECK_NULL_RETURN(container, result);
919     ContainerScope scope(instanceId);
920     auto front = container->GetFrontend();
921     CHECK_NULL_RETURN(front, result);
922     front->OnSaveData(result);
923     return result;
924 }
925 
OnRestoreData(int32_t instanceId,const std::string & data)926 bool AceContainer::OnRestoreData(int32_t instanceId, const std::string& data)
927 {
928     auto container = AceEngine::Get().GetContainer(instanceId);
929     CHECK_NULL_RETURN(container, false);
930     ContainerScope scope(instanceId);
931     auto front = container->GetFrontend();
932     CHECK_NULL_RETURN(front, false);
933     return front->OnRestoreData(data);
934 }
935 
OnCompleteContinuation(int32_t instanceId,int result)936 void AceContainer::OnCompleteContinuation(int32_t instanceId, int result)
937 {
938     auto container = AceEngine::Get().GetContainer(instanceId);
939     CHECK_NULL_VOID(container);
940     ContainerScope scope(instanceId);
941     auto front = container->GetFrontend();
942     CHECK_NULL_VOID(front);
943     front->OnCompleteContinuation(result);
944 }
945 
OnRemoteTerminated(int32_t instanceId)946 void AceContainer::OnRemoteTerminated(int32_t instanceId)
947 {
948     auto container = AceEngine::Get().GetContainer(instanceId);
949     CHECK_NULL_VOID(container);
950     ContainerScope scope(instanceId);
951     auto front = container->GetFrontend();
952     CHECK_NULL_VOID(front);
953     front->OnRemoteTerminated();
954 }
955 
OnConfigurationUpdated(int32_t instanceId,const std::string & configuration)956 void AceContainer::OnConfigurationUpdated(int32_t instanceId, const std::string& configuration)
957 {
958     auto container = AceEngine::Get().GetContainer(instanceId);
959     CHECK_NULL_VOID(container);
960     ContainerScope scope(instanceId);
961     auto front = container->GetFrontend();
962     CHECK_NULL_VOID(front);
963     front->OnConfigurationUpdated(configuration);
964 }
965 
OnNewRequest(int32_t instanceId,const std::string & data)966 void AceContainer::OnNewRequest(int32_t instanceId, const std::string& data)
967 {
968     auto container = AceEngine::Get().GetContainer(instanceId);
969     CHECK_NULL_VOID(container);
970     ContainerScope scope(instanceId);
971     auto front = container->GetFrontend();
972     CHECK_NULL_VOID(front);
973     front->OnNewRequest(data);
974 }
975 
InitializeCallback()976 void AceContainer::InitializeCallback()
977 {
978     ACE_FUNCTION_TRACE();
979     ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
980     auto touchPassMode = AceApplicationInfo::GetInstance().GetTouchEventPassMode();
981     bool isDebugAcc = (SystemProperties::GetTouchAccelarate() == static_cast<int32_t>(TouchPassMode::ACCELERATE));
982     pipelineContext_->SetTouchAccelarate((touchPassMode == TouchPassMode::ACCELERATE) || isDebugAcc);
983     pipelineContext_->SetTouchPassThrough(touchPassMode == TouchPassMode::PASS_THROUGH);
984     auto&& touchEventCallback = [context = pipelineContext_, id = instanceId_](const TouchEvent& event,
985                                     const std::function<void()>& markProcess,
986                                     const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
987         ContainerScope scope(id);
988         context->CheckAndLogLastReceivedTouchEventInfo(event.touchEventId, event.type);
989         auto touchTask = [context, event, markProcess, node]() {
990             if (event.type == TouchType::HOVER_ENTER || event.type == TouchType::HOVER_MOVE ||
991                 event.type == TouchType::HOVER_EXIT || event.type == TouchType::HOVER_CANCEL) {
992                 context->OnAccessibilityHoverEvent(event, node);
993             } else if (event.IsPenHoverEvent()) {
994                 context->OnPenHoverEvent(event, node);
995             } else {
996                 if (node) {
997                     context->OnTouchEvent(event, node, false);
998                 } else {
999                     context->OnTouchEvent(event, false);
1000                 }
1001             }
1002             CHECK_NULL_VOID(markProcess);
1003             markProcess();
1004             context->CheckAndLogLastConsumedTouchEventInfo(event.touchEventId, event.type);
1005         };
1006         auto uiTaskRunner = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1007         if (uiTaskRunner.IsRunOnCurrentThread()) {
1008             touchTask();
1009             return;
1010         }
1011         context->GetTaskExecutor()->PostTask(
1012             touchTask, TaskExecutor::TaskType::UI, "ArkUIAceContainerTouchEvent", PriorityType::VIP);
1013     };
1014     aceView_->RegisterTouchEventCallback(touchEventCallback);
1015 
1016     auto&& mouseEventCallback = [context = pipelineContext_, id = instanceId_](const MouseEvent& event,
1017                                     const std::function<void()>& markProcess,
1018                                     const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
1019         ContainerScope scope(id);
1020         context->CheckAndLogLastReceivedMouseEventInfo(event.touchEventId, event.action);
1021         auto mouseTask = [context, event, markProcess, node]() {
1022             if (node) {
1023                 context->OnMouseEvent(event, node);
1024             } else {
1025                 context->OnMouseEvent(event);
1026             }
1027             CHECK_NULL_VOID(markProcess);
1028             markProcess();
1029             context->CheckAndLogLastConsumedMouseEventInfo(event.touchEventId, event.action);
1030         };
1031         auto uiTaskRunner = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1032         if (uiTaskRunner.IsRunOnCurrentThread()) {
1033             mouseTask();
1034             return;
1035         }
1036         context->GetTaskExecutor()->PostTask(
1037             mouseTask, TaskExecutor::TaskType::UI, "ArkUIAceContainerMouseEvent", PriorityType::VIP);
1038     };
1039     aceView_->RegisterMouseEventCallback(mouseEventCallback);
1040 
1041     auto&& axisEventCallback = [context = pipelineContext_, id = instanceId_](const AxisEvent& event,
1042                                    const std::function<void()>& markProcess,
1043                                    const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
1044         ContainerScope scope(id);
1045         context->CheckAndLogLastReceivedAxisEventInfo(event.touchEventId, event.action);
1046         auto axisTask = [context, event, markProcess, node]() {
1047             if (node) {
1048                 context->OnAxisEvent(event, node);
1049             } else {
1050                 context->OnAxisEvent(event);
1051             }
1052             CHECK_NULL_VOID(markProcess);
1053             markProcess();
1054             context->CheckAndLogLastConsumedAxisEventInfo(event.touchEventId, event.action);
1055         };
1056         auto uiTaskRunner = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1057         if (uiTaskRunner.IsRunOnCurrentThread()) {
1058             axisTask();
1059             return;
1060         }
1061         context->GetTaskExecutor()->PostTask(
1062             axisTask, TaskExecutor::TaskType::UI, "ArkUIAceContainerAxisEvent", PriorityType::VIP);
1063     };
1064     aceView_->RegisterAxisEventCallback(axisEventCallback);
1065 
1066     auto&& nonPointerEventCallback = [context = pipelineContext_, id = instanceId_](
1067                                          const NonPointerEvent& event, const std::function<void()>& markProcess) {
1068         ContainerScope scope(id);
1069         bool result = false;
1070         context->GetTaskExecutor()->PostSyncTask(
1071             [context, &event, &result, id, markProcess]() {
1072                 ContainerScope scope(id);
1073                 result = context->OnNonPointerEvent(event);
1074                 CHECK_NULL_VOID(markProcess);
1075                 markProcess();
1076             },
1077             TaskExecutor::TaskType::UI, "ArkUIAceContainerNonPointerEvent", PriorityType::VIP);
1078         return result;
1079     };
1080     aceView_->RegisterNonPointerEventCallback(nonPointerEventCallback);
1081 
1082     auto&& crownEventCallback = [context = pipelineContext_, id = instanceId_](
1083                                     const CrownEvent& event, const std::function<void()>& markProcess) {
1084         if (event.action == CrownAction::BEGIN || event.action == CrownAction::END) {
1085             std::unordered_map<std::string, std::string> mapPayload;
1086             ResSchedReport::GetInstance().ResSchedDataReport(
1087                 RES_TYPE_CROWN_ROTATION_STATUS, static_cast<int32_t>(event.action), mapPayload);
1088         }
1089         ContainerScope scope(id);
1090         bool result = false;
1091         auto crownTask = [context, event, &result, markProcess, id]() {
1092             ContainerScope scope(id);
1093             result = context->OnNonPointerEvent(event);
1094             CHECK_NULL_VOID(markProcess);
1095             markProcess();
1096         };
1097         auto uiTaskRunner = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
1098         if (uiTaskRunner.IsRunOnCurrentThread()) {
1099             crownTask();
1100             return result;
1101         }
1102         context->GetTaskExecutor()->PostTask(
1103             crownTask, TaskExecutor::TaskType::UI, "ArkUIAceContainerCrownEvent", PriorityType::VIP);
1104         return result;
1105     };
1106     aceView_->RegisterCrownEventCallback(crownEventCallback);
1107 
1108     auto&& rotationEventCallback = [context = pipelineContext_, id = instanceId_](const RotationEvent& event) {
1109         ContainerScope scope(id);
1110         bool result = false;
1111         context->GetTaskExecutor()->PostSyncTask(
1112             [context, event, &result]() { result = context->OnRotationEvent(event); }, TaskExecutor::TaskType::UI,
1113             "ArkUIAceContainerRotationEvent");
1114         return result;
1115     };
1116     aceView_->RegisterRotationEventCallback(rotationEventCallback);
1117 
1118     auto&& viewChangeCallback = [context = pipelineContext_, id = instanceId_](int32_t width, int32_t height,
1119                                     WindowSizeChangeReason type,
1120                                     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction) {
1121         ContainerScope scope(id);
1122         ACE_SCOPED_TRACE_COMMERCIAL("ViewChangeCallback(%d, %d)", width, height);
1123         auto callback = [context, width, height, type, rsTransaction]() {
1124             context->OnSurfaceChanged(width, height, type, rsTransaction);
1125         };
1126         auto container = Container::Current();
1127         CHECK_NULL_VOID(container);
1128         auto taskExecutor = container->GetTaskExecutor();
1129         CHECK_NULL_VOID(taskExecutor);
1130         if ((container->IsUseStageModel() && type == WindowSizeChangeReason::ROTATION) ||
1131             taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
1132             callback();
1133         } else {
1134             taskExecutor->PostTask(callback, TaskExecutor::TaskType::UI, "ArkUISubwindowResizeWindow");
1135         }
1136     };
1137     aceView_->RegisterViewChangeCallback(viewChangeCallback);
1138 
1139     auto&& viewPositionChangeCallback = [context = pipelineContext_, id = instanceId_](int32_t posX, int32_t posY) {
1140         ContainerScope scope(id);
1141         ACE_SCOPED_TRACE("ViewPositionChangeCallback(%d, %d)", posX, posY);
1142         context->GetTaskExecutor()->PostTask(
1143             [context, posX, posY]() { context->OnSurfacePositionChanged(posX, posY); },
1144             TaskExecutor::TaskType::UI, "ArkUISurfacePositionChanged");
1145     };
1146     aceView_->RegisterViewPositionChangeCallback(viewPositionChangeCallback);
1147 
1148     auto&& densityChangeCallback = [context = pipelineContext_, id = instanceId_](double density) {
1149         ContainerScope scope(id);
1150         ACE_SCOPED_TRACE("DensityChangeCallback(%lf)", density);
1151         auto callback = [context, density, id]() {
1152             context->OnSurfaceDensityChanged(density);
1153             if (context->IsNeedReloadDensity()) {
1154                 auto container = Container::GetContainer(id);
1155                 CHECK_NULL_VOID(container);
1156                 auto aceContainer = DynamicCast<AceContainer>(container);
1157                 CHECK_NULL_VOID(aceContainer);
1158                 aceContainer->NotifyDensityUpdate(density);
1159                 context->SetIsNeedReloadDensity(false);
1160             }
1161         };
1162         auto taskExecutor = context->GetTaskExecutor();
1163         CHECK_NULL_VOID(taskExecutor);
1164         if (taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
1165             callback();
1166         } else {
1167             taskExecutor->PostTask(callback, TaskExecutor::TaskType::UI, "ArkUISurfaceDensityChanged");
1168         }
1169     };
1170     aceView_->RegisterDensityChangeCallback(densityChangeCallback);
1171 
1172     auto&& transformHintChangeCallback = [context = pipelineContext_, id = instanceId_](uint32_t transform) {
1173         ContainerScope scope(id);
1174         ACE_SCOPED_TRACE("TransformHintChangeCallback(%d)", transform);
1175         auto callback = [context, transform]() { context->OnTransformHintChanged(transform); };
1176         auto taskExecutor = context->GetTaskExecutor();
1177         CHECK_NULL_VOID(taskExecutor);
1178         if (taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
1179             callback();
1180         } else {
1181             taskExecutor->PostTask(callback, TaskExecutor::TaskType::UI, "ArkUITransformHintChanged");
1182         }
1183     };
1184     aceView_->RegisterTransformHintChangeCallback(transformHintChangeCallback);
1185 
1186     auto&& systemBarHeightChangeCallback = [context = pipelineContext_, id = instanceId_](
1187                                                double statusBar, double navigationBar) {
1188         ContainerScope scope(id);
1189         ACE_SCOPED_TRACE("SystemBarHeightChangeCallback(%lf, %lf)", statusBar, navigationBar);
1190         context->GetTaskExecutor()->PostTask(
1191             [context, statusBar, navigationBar]() { context->OnSystemBarHeightChanged(statusBar, navigationBar); },
1192             TaskExecutor::TaskType::UI, "ArkUISystemBarHeightChanged");
1193     };
1194     aceView_->RegisterSystemBarHeightChangeCallback(systemBarHeightChangeCallback);
1195 
1196     auto&& surfaceDestroyCallback = [context = pipelineContext_, id = instanceId_]() {
1197         ContainerScope scope(id);
1198         context->GetTaskExecutor()->PostTask(
1199             [context]() { context->OnSurfaceDestroyed(); }, TaskExecutor::TaskType::UI, "ArkUISurfaceDestroyed");
1200     };
1201     aceView_->RegisterSurfaceDestroyCallback(surfaceDestroyCallback);
1202     InitDragEventCallback();
1203 }
1204 
InitDragEventCallback()1205 void AceContainer::InitDragEventCallback()
1206 {
1207     if (!isFormRender_) {
1208         auto&& dragEventCallback = [context = pipelineContext_, id = instanceId_](const DragPointerEvent& pointerEvent,
1209                                        const DragEventAction& action, const RefPtr<NG::FrameNode>& node) {
1210             ContainerScope scope(id);
1211             CHECK_NULL_VOID(context);
1212             auto callback = [context, pointerEvent, action, node]() {
1213                 context->OnDragEvent(pointerEvent, action, node);
1214             };
1215             auto taskExecutor = context->GetTaskExecutor();
1216             CHECK_NULL_VOID(taskExecutor);
1217             auto uiTaskRunner = SingleTaskExecutor::Make(taskExecutor, TaskExecutor::TaskType::UI);
1218             if (uiTaskRunner.IsRunOnCurrentThread()) {
1219                 callback();
1220                 return;
1221             }
1222             taskExecutor->PostTask(
1223                 callback, TaskExecutor::TaskType::UI, "ArkUIAceContainerDragEvent", PriorityType::VIP);
1224         };
1225         aceView_->RegisterDragEventCallback(dragEventCallback);
1226     }
1227 }
1228 
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)1229 void AceContainer::CreateContainer(int32_t instanceId, FrontendType type, const std::string& instanceName,
1230     std::shared_ptr<OHOS::AppExecFwk::Ability> aceAbility, std::unique_ptr<PlatformEventCallback> callback,
1231     bool useCurrentEventRunner, bool useNewPipeline)
1232 {
1233     auto aceContainer = AceType::MakeRefPtr<AceContainer>(
1234         instanceId, type, aceAbility, std::move(callback), useCurrentEventRunner, useNewPipeline);
1235     AceEngine::Get().AddContainer(instanceId, aceContainer);
1236     aceContainer->Initialize();
1237     ContainerScope scope(instanceId);
1238     auto front = aceContainer->GetFrontend();
1239     if (front) {
1240         front->UpdateState(Frontend::State::ON_CREATE);
1241         front->SetJsMessageDispatcher(aceContainer);
1242     }
1243 
1244     auto jsFront = AceType::DynamicCast<JsFrontend>(front);
1245     CHECK_NULL_VOID(jsFront);
1246     jsFront->SetInstanceName(instanceName);
1247 }
1248 
DestroyContainer(int32_t instanceId,const std::function<void ()> & destroyCallback)1249 void AceContainer::DestroyContainer(int32_t instanceId, const std::function<void()>& destroyCallback)
1250 {
1251     SubwindowManager::GetInstance()->CloseDialog(instanceId);
1252     auto container = AceEngine::Get().GetContainer(instanceId);
1253     CHECK_NULL_VOID(container);
1254     container->Destroy();
1255     // unregister watchdog before stop thread to avoid UI_BLOCK report
1256     AceEngine::Get().UnRegisterFromWatchDog(instanceId);
1257     auto taskExecutor = container->GetTaskExecutor();
1258     CHECK_NULL_VOID(taskExecutor);
1259 
1260     taskExecutor->PostSyncTask([] { LOGI("Wait UI thread..."); }, TaskExecutor::TaskType::UI, "ArkUIWaitLog");
1261     taskExecutor->PostSyncTask([] { LOGI("Wait JS thread..."); }, TaskExecutor::TaskType::JS, "ArkUIWaitLog");
1262 
1263     container->DestroyView(); // Stop all threads(ui,gpu,io) for current ability.
1264     auto removeContainerTask = [instanceId, destroyCallback] {
1265         LOGI("Remove on Platform thread...");
1266         EngineHelper::RemoveEngine(instanceId);
1267         AceEngine::Get().RemoveContainer(instanceId);
1268         CHECK_NULL_VOID(destroyCallback);
1269         destroyCallback();
1270     };
1271     if (container->GetSettings().usePlatformAsUIThread) {
1272         removeContainerTask();
1273     } else {
1274         taskExecutor->PostTask(removeContainerTask, TaskExecutor::TaskType::PLATFORM, "ArkUIAceContainerRemove");
1275     }
1276 }
1277 
SetView(const RefPtr<AceView> & view,double density,int32_t width,int32_t height,sptr<OHOS::Rosen::Window> rsWindow,UIEnvCallback callback)1278 void AceContainer::SetView(const RefPtr<AceView>& view, double density, int32_t width, int32_t height,
1279     sptr<OHOS::Rosen::Window> rsWindow, UIEnvCallback callback)
1280 {
1281     CHECK_NULL_VOID(view);
1282     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(view->GetInstanceId()));
1283     CHECK_NULL_VOID(container);
1284 #ifdef ENABLE_ROSEN_BACKEND
1285     auto taskExecutor = container->GetTaskExecutor();
1286     CHECK_NULL_VOID(taskExecutor);
1287     auto window = std::make_shared<NG::RosenWindow>(rsWindow, taskExecutor, view->GetInstanceId());
1288     window->Init();
1289 #else
1290     auto platformWindow = PlatformWindow::Create(view);
1291     CHECK_NULL_VOID(platformWindow);
1292     auto window = std::make_shared<Window>(std::move(platformWindow));
1293 #endif
1294     AceContainer::SetUIWindow(view->GetInstanceId(), rsWindow);
1295     container->AttachView(window, view, density, width, height, rsWindow->GetWindowId(), callback);
1296 }
1297 
SetViewNew(const RefPtr<AceView> & view,double density,float width,float height,sptr<OHOS::Rosen::Window> rsWindow)1298 UIContentErrorCode AceContainer::SetViewNew(
1299     const RefPtr<AceView>& view, double density, float width, float height, sptr<OHOS::Rosen::Window> rsWindow)
1300 {
1301 #ifdef ENABLE_ROSEN_BACKEND
1302     CHECK_NULL_RETURN(view, UIContentErrorCode::NULL_POINTER);
1303     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(view->GetInstanceId()));
1304     CHECK_NULL_RETURN(container, UIContentErrorCode::NULL_POINTER);
1305     auto taskExecutor = container->GetTaskExecutor();
1306     CHECK_NULL_RETURN(taskExecutor, UIContentErrorCode::NULL_POINTER);
1307     AceContainer::SetUIWindow(view->GetInstanceId(), rsWindow);
1308 
1309     if (container->isFormRender_) {
1310         auto window = std::make_shared<FormRenderWindow>(taskExecutor, view->GetInstanceId());
1311         container->AttachView(window, view, density, width, height, view->GetInstanceId(), nullptr);
1312     } else {
1313         auto window = std::make_shared<NG::RosenWindow>(rsWindow, taskExecutor, view->GetInstanceId());
1314         window->Init();
1315         container->AttachView(window, view, density, width, height, rsWindow->GetWindowId(), nullptr);
1316     }
1317 
1318     return UIContentErrorCode::NO_ERRORS;
1319 #endif
1320 }
1321 
SetUIWindow(int32_t instanceId,sptr<OHOS::Rosen::Window> uiWindow)1322 void AceContainer::SetUIWindow(int32_t instanceId, sptr<OHOS::Rosen::Window> uiWindow)
1323 {
1324     CHECK_NULL_VOID(uiWindow);
1325     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1326     CHECK_NULL_VOID(container);
1327     container->SetUIWindowInner(uiWindow);
1328     if (!container->IsScenceBoardWindow()) {
1329         ResourceManager::GetInstance().SetResourceCacheSize(RESOURCE_CACHE_DEFAULT_SIZE);
1330     }
1331 }
1332 
GetUIWindow(int32_t instanceId)1333 sptr<OHOS::Rosen::Window> AceContainer::GetUIWindow(int32_t instanceId)
1334 {
1335     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1336     CHECK_NULL_RETURN(container, nullptr);
1337     return container->GetUIWindowInner();
1338 }
1339 
GetAbility(int32_t instanceId)1340 OHOS::AppExecFwk::Ability* AceContainer::GetAbility(int32_t instanceId)
1341 {
1342     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1343     CHECK_NULL_RETURN(container, nullptr);
1344     return container->GetAbilityInner().lock().get();
1345 }
1346 
GetRuntimeContext(int32_t instanceId)1347 OHOS::AbilityRuntime::Context* AceContainer::GetRuntimeContext(int32_t instanceId)
1348 {
1349     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1350     CHECK_NULL_RETURN(container, nullptr);
1351     return container->GetRuntimeContextInner().lock().get();
1352 }
1353 
RunPage(int32_t instanceId,const std::string & content,const std::string & params,bool isNamedRouter)1354 UIContentErrorCode AceContainer::RunPage(
1355     int32_t instanceId, const std::string& content, const std::string& params, bool isNamedRouter)
1356 {
1357     auto container = AceEngine::Get().GetContainer(instanceId);
1358     CHECK_NULL_RETURN(container, UIContentErrorCode::NULL_POINTER);
1359 
1360     auto aceContainer = DynamicCast<AceContainer>(container);
1361     CHECK_NULL_RETURN(aceContainer, UIContentErrorCode::NULL_POINTER);
1362     bool isStageModel = aceContainer->IsUseStageModel();
1363     bool isFormRender = aceContainer->IsFormRender();
1364     if (isStageModel && content.size() == 0) {
1365         return UIContentErrorCode::NULL_URL;
1366     }
1367 
1368     ContainerScope scope(instanceId);
1369     auto front = container->GetFrontend();
1370     CHECK_NULL_RETURN(front, UIContentErrorCode::NULL_POINTER);
1371 
1372     if (front->GetType() != FrontendType::DECLARATIVE_CJ && !isFormRender && !isNamedRouter && isStageModel &&
1373         !CheckUrlValid(content, container->GetHapPath())) {
1374         return UIContentErrorCode::INVALID_URL;
1375     }
1376 
1377     if (isNamedRouter) {
1378         return front->RunPageByNamedRouter(content, params);
1379     }
1380 
1381     return front->RunPage(content, params);
1382 }
1383 
RunPage(int32_t instanceId,const std::shared_ptr<std::vector<uint8_t>> & content,const std::string & params)1384 UIContentErrorCode AceContainer::RunPage(
1385     int32_t instanceId, const std::shared_ptr<std::vector<uint8_t>>& content, const std::string& params)
1386 {
1387     auto container = AceEngine::Get().GetContainer(instanceId);
1388     CHECK_NULL_RETURN(container, UIContentErrorCode::NULL_POINTER);
1389     ContainerScope scope(instanceId);
1390     auto front = container->GetFrontend();
1391     CHECK_NULL_RETURN(front, UIContentErrorCode::NULL_POINTER);
1392     return front->RunPage(content, params);
1393 }
1394 
RunDynamicPage(int32_t instanceId,const std::string & content,const std::string & params,const std::string & entryPoint)1395 bool AceContainer::RunDynamicPage(
1396     int32_t instanceId, const std::string& content, const std::string& params, const std::string& entryPoint)
1397 {
1398     auto container = AceEngine::Get().GetContainer(instanceId);
1399     CHECK_NULL_RETURN(container, false);
1400     ContainerScope scope(instanceId);
1401     auto front = container->GetFrontend();
1402     CHECK_NULL_RETURN(front, false);
1403     front->RunDynamicPage(content, params, entryPoint);
1404     return true;
1405 }
1406 
PushPage(int32_t instanceId,const std::string & content,const std::string & params)1407 bool AceContainer::PushPage(int32_t instanceId, const std::string& content, const std::string& params)
1408 {
1409     auto container = AceEngine::Get().GetContainer(instanceId);
1410     CHECK_NULL_RETURN(container, false);
1411     ContainerScope scope(instanceId);
1412     auto front = container->GetFrontend();
1413     CHECK_NULL_RETURN(front, false);
1414     front->PushPage(content, params);
1415     return true;
1416 }
1417 
UpdatePage(int32_t instanceId,int32_t pageId,const std::string & content)1418 bool AceContainer::UpdatePage(int32_t instanceId, int32_t pageId, const std::string& content)
1419 {
1420     auto container = AceEngine::Get().GetContainer(instanceId);
1421     CHECK_NULL_RETURN(container, false);
1422     ContainerScope scope(instanceId);
1423     auto context = container->GetPipelineContext();
1424     CHECK_NULL_RETURN(context, false);
1425     return context->CallRouterBackToPopPage();
1426 }
1427 
1428 class FillRequestCallback : public AbilityRuntime::IFillRequestCallback {
1429 public:
FillRequestCallback(WeakPtr<NG::PipelineContext> pipelineContext,const RefPtr<NG::FrameNode> & node,AceAutoFillType autoFillType,bool isNative=true,const std::function<void ()> & onFinish=nullptr)1430     FillRequestCallback(WeakPtr<NG::PipelineContext> pipelineContext, const RefPtr<NG::FrameNode>& node,
1431         AceAutoFillType autoFillType, bool isNative = true, const std::function<void()>& onFinish = nullptr)
1432         : pipelineContext_(pipelineContext), node_(node), autoFillType_(autoFillType), isNative_(isNative),
1433           onFinish_(onFinish)
1434     {}
1435     virtual ~FillRequestCallback() = default;
OnFillRequestSuccess(const AbilityBase::ViewData & viewData)1436     void OnFillRequestSuccess(const AbilityBase::ViewData& viewData) override
1437     {
1438         TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called OnFillRequestSuccess, pageUrl=[%{private}zu]",
1439             viewData.pageUrl.size());
1440         ProcessOnFinish();
1441         auto pipelineContext = pipelineContext_.Upgrade();
1442         CHECK_NULL_VOID(pipelineContext);
1443         auto taskExecutor = pipelineContext->GetTaskExecutor();
1444         CHECK_NULL_VOID(taskExecutor);
1445         auto viewDataWrap = ViewDataWrap::CreateViewDataWrap(viewData);
1446         CHECK_NULL_VOID(viewDataWrap);
1447         if (!isNative_) {
1448             auto node = node_.Upgrade();
1449             CHECK_NULL_VOID(node);
1450             taskExecutor->PostTask(
1451                 [viewDataWrap, node, autoFillType = autoFillType_]() {
1452                     if (node) {
1453                         node->NotifyFillRequestSuccess(viewDataWrap, nullptr, autoFillType);
1454                     }
1455                 },
1456                 TaskExecutor::TaskType::UI, "ArkUINotifyWebFillRequestSuccess");
1457             return;
1458         }
1459 
1460         taskExecutor->PostTask(
1461             [viewDataWrap, pipelineContext, autoFillType = autoFillType_]() {
1462                 if (pipelineContext) {
1463                     pipelineContext->NotifyFillRequestSuccess(autoFillType, viewDataWrap);
1464                 }
1465             },
1466             TaskExecutor::TaskType::UI, "ArkUINotifyFillRequestSuccess");
1467     }
1468 
OnFillRequestFailed(int32_t errCode,const std::string & fillContent,bool isPopup)1469     void OnFillRequestFailed(int32_t errCode, const std::string& fillContent, bool isPopup) override
1470     {
1471         TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called, errCode: %{public}d", errCode);
1472         ProcessOnFinish();
1473         auto pipelineContext = pipelineContext_.Upgrade();
1474         CHECK_NULL_VOID(pipelineContext);
1475         auto node = node_.Upgrade();
1476         CHECK_NULL_VOID(node);
1477         auto taskExecutor = pipelineContext->GetTaskExecutor();
1478         CHECK_NULL_VOID(taskExecutor);
1479         taskExecutor->PostTask(
1480             [errCode, pipelineContext, node, fillContent, isPopup]() {
1481                 if (pipelineContext) {
1482                     pipelineContext->NotifyFillRequestFailed(node, errCode, fillContent, isPopup);
1483                 }
1484             },
1485             TaskExecutor::TaskType::UI, "ArkUINotifyFillRequestFailed");
1486     }
1487 
onPopupConfigWillUpdate(AbilityRuntime::AutoFill::AutoFillCustomConfig & config)1488     void onPopupConfigWillUpdate(AbilityRuntime::AutoFill::AutoFillCustomConfig& config) override
1489     {
1490         // Non-native component like web/xcomponent
1491         // The offset needs to be calculated based on the placement
1492         if (isNative_ || !config.targetSize.has_value() || !config.placement.has_value()) {
1493             return;
1494         }
1495         AbilityRuntime::AutoFill::PopupOffset offset;
1496         offset.deltaX = GetPopupConfigWillUpdateX(config);
1497         offset.deltaY = GetPopupConfigWillUpdateY(config);
1498         TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "PopupOffset x:%{public}f,y:%{public}f", offset.deltaX, offset.deltaY);
1499         config.targetOffset = offset;
1500         config.placement = AbilityRuntime::AutoFill::PopupPlacement::BOTTOM;
1501     }
1502 
SetFocusedRect(AbilityBase::Rect rect)1503     void SetFocusedRect(AbilityBase::Rect rect)
1504     {
1505         rect_ = rect;
1506     }
1507 
SetWindowRect(Rosen::Rect rect)1508     void SetWindowRect(Rosen::Rect rect)
1509     {
1510         windowRect_ = rect;
1511     }
1512 
1513 private:
GetPopupConfigWillUpdateY(AbilityRuntime::AutoFill::AutoFillCustomConfig & config)1514     double GetPopupConfigWillUpdateY(AbilityRuntime::AutoFill::AutoFillCustomConfig& config)
1515     {
1516         auto node = node_.Upgrade();
1517         CHECK_NULL_RETURN(node, 0);
1518         auto rectf = node->GetRectWithRender();
1519         double deltaY = 0;
1520         AbilityRuntime::AutoFill::PopupPlacement placement = config.placement.value();
1521         AbilityRuntime::AutoFill::PopupSize size = config.targetSize.value();
1522 
1523         auto trans = node->GetTransformRelativeOffset();
1524         auto bottomAvoidHeight = GetBottomAvoidHeight();
1525         auto edge = PipelineBase::Vp2PxWithCurrentDensity(POPUP_EDGE_INTERVAL);
1526         auto minEdge = PipelineBase::Vp2PxWithCurrentDensity(POPUP_MIN_EDGE);
1527 
1528         bool isBottom = placement == AbilityRuntime::AutoFill::PopupPlacement::BOTTOM ||
1529                         placement == AbilityRuntime::AutoFill::PopupPlacement::BOTTOM_LEFT ||
1530                         placement == AbilityRuntime::AutoFill::PopupPlacement::BOTTOM_RIGHT;
1531         if (rectf.GetY() > size.height + edge + minEdge) {
1532             if (isBottom) {
1533                 deltaY = rect_.top - trans.GetY() + rect_.height + size.height + edge * POPUP_CALCULATE_RATIO;
1534             } else {
1535                 deltaY = rect_.top - trans.GetY();
1536             }
1537         } else if ((windowRect_.height_ - rectf.Height() - trans.GetY()) >
1538                    (size.height + edge * POPUP_CALCULATE_RATIO + bottomAvoidHeight)) {
1539             // popup will display at the bottom of the container
1540             if (isBottom) {
1541                 deltaY = rect_.top + rect_.height - rectf.Height() - trans.GetY() + edge;
1542             } else {
1543                 deltaY = rect_.top - rectf.Height() - size.height - trans.GetY() - edge;
1544             }
1545         } else {
1546             // popup will display in the middle of the container
1547             if (isBottom) {
1548                 deltaY = rect_.top + rect_.height - ((rectf.Height() - size.height) / POPUP_CALCULATE_RATIO) -
1549                          trans.GetY() + edge;
1550             } else {
1551                 deltaY = rect_.top - ((rectf.Height() + size.height) / POPUP_CALCULATE_RATIO) - trans.GetY() - edge;
1552             }
1553         }
1554         return deltaY;
1555     }
1556 
GetPopupConfigWillUpdateX(AbilityRuntime::AutoFill::AutoFillCustomConfig & config)1557     double GetPopupConfigWillUpdateX(AbilityRuntime::AutoFill::AutoFillCustomConfig& config)
1558     {
1559         auto node = node_.Upgrade();
1560         CHECK_NULL_RETURN(node, 0);
1561         auto rectf = node->GetRectWithRender();
1562         double deltaX = 0;
1563         AbilityRuntime::AutoFill::PopupPlacement placement = config.placement.value();
1564         AbilityRuntime::AutoFill::PopupSize size = config.targetSize.value();
1565 
1566         if (placement == AbilityRuntime::AutoFill::PopupPlacement::TOP_LEFT ||
1567             placement == AbilityRuntime::AutoFill::PopupPlacement::BOTTOM_LEFT) {
1568             double edgeDist = (rectf.Width() - size.width) / POPUP_CALCULATE_RATIO;
1569             deltaX = rect_.left - edgeDist;
1570             if (deltaX > edgeDist) {
1571                 deltaX = edgeDist;
1572             }
1573             if (rect_.left + size.width > windowRect_.width_) {
1574                 deltaX = windowRect_.width_ - size.width - edgeDist;
1575             }
1576             if (edgeDist + size.width > windowRect_.width_) {
1577                 deltaX = 0;
1578             }
1579         }
1580 
1581         if (placement == AbilityRuntime::AutoFill::PopupPlacement::TOP_RIGHT ||
1582             placement == AbilityRuntime::AutoFill::PopupPlacement::BOTTOM_RIGHT) {
1583             double edgeDist = (rectf.Width() - size.width) / POPUP_CALCULATE_RATIO;
1584             deltaX = edgeDist + rect_.left + rect_.width - rectf.Width();
1585             if ((deltaX < -DBL_EPSILON) && (std::fabs(deltaX) > edgeDist)) {
1586                 deltaX = -edgeDist;
1587             }
1588         }
1589         return deltaX;
1590     }
1591 
GetBottomAvoidHeight()1592     uint32_t GetBottomAvoidHeight()
1593     {
1594         auto containerId = Container::CurrentId();
1595         RefPtr<NG::PipelineContext> pipelineContext;
1596         if (containerId >= MIN_SUBCONTAINER_ID) {
1597             auto parentContainerId = SubwindowManager::GetInstance()->GetParentContainerId(containerId);
1598             auto parentContainer = AceEngine::Get().GetContainer(parentContainerId);
1599             CHECK_NULL_RETURN(parentContainer, 0);
1600             pipelineContext = AceType::DynamicCast<NG::PipelineContext>(parentContainer->GetPipelineContext());
1601         } else {
1602             pipelineContext = NG::PipelineContext::GetCurrentContext();
1603         }
1604         CHECK_NULL_RETURN(pipelineContext, 0);
1605         auto safeAreaManager = pipelineContext->GetSafeAreaManager();
1606         CHECK_NULL_RETURN(safeAreaManager, 0);
1607         return safeAreaManager->GetSystemSafeArea().bottom_.Length();
1608     }
1609 
ProcessOnFinish()1610     void ProcessOnFinish()
1611     {
1612         if (!onFinish_) {
1613             return;
1614         }
1615         auto pipelineContext = pipelineContext_.Upgrade();
1616         CHECK_NULL_VOID(pipelineContext);
1617         auto taskExecutor = pipelineContext->GetTaskExecutor();
1618         CHECK_NULL_VOID(taskExecutor);
1619         taskExecutor->PostTask(
1620             [onFinish = std::move(onFinish_)]() mutable {
1621                 if (onFinish) {
1622                     onFinish();
1623                     onFinish = nullptr;
1624                 }
1625             },
1626             TaskExecutor::TaskType::UI, "FillRequestCallbackProcessOnFinish");
1627     }
1628 
1629     WeakPtr<NG::PipelineContext> pipelineContext_ = nullptr;
1630     WeakPtr<NG::FrameNode> node_ = nullptr;
1631     AceAutoFillType autoFillType_ = AceAutoFillType::ACE_UNSPECIFIED;
1632     bool isNative_ = true;
1633     AbilityBase::Rect rect_;
1634     Rosen::Rect windowRect_ { 0, 0, 0, 0 };
1635     std::function<void()> onFinish_;
1636 };
1637 
UpdatePopupUIExtension(const RefPtr<NG::FrameNode> & node,uint32_t autoFillSessionId,bool isNative)1638 bool AceContainer::UpdatePopupUIExtension(const RefPtr<NG::FrameNode>& node, uint32_t autoFillSessionId, bool isNative)
1639 {
1640     TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "UpdatePopupUIExtension called");
1641     CHECK_NULL_RETURN(node, false);
1642     CHECK_NULL_RETURN(uiWindow_, false);
1643     auto uiContent = uiWindow_->GetUIContent();
1644     auto uiContentImpl = reinterpret_cast<UIContentImpl*>(uiContent);
1645     CHECK_NULL_RETURN(uiContentImpl, false);
1646     auto viewDataWrap = ViewDataWrap::CreateViewDataWrap();
1647     auto autoFillContainerNode = node->GetFirstAutoFillContainerNode();
1648     uiContentImpl->DumpViewData(autoFillContainerNode, viewDataWrap, true);
1649     auto viewDataWrapOhos = AceType::DynamicCast<ViewDataWrapOhos>(viewDataWrap);
1650     CHECK_NULL_RETURN(viewDataWrapOhos, false);
1651     auto viewData = viewDataWrapOhos->GetViewData();
1652     if (!isNative) {
1653         OverwritePageNodeInfo(node, viewData);
1654     }
1655     AbilityRuntime::AutoFillManager::GetInstance().UpdateCustomPopupUIExtension(autoFillSessionId, viewData);
1656     return true;
1657 }
1658 
ClosePopupUIExtension(uint32_t autoFillSessionId)1659 bool AceContainer::ClosePopupUIExtension(uint32_t autoFillSessionId)
1660 {
1661     AbilityRuntime::AutoFillManager::GetInstance().CloseUIExtension(autoFillSessionId);
1662     return true;
1663 }
1664 
PlaceHolderToType(const std::string & onePlaceHolder)1665 HintToTypeWrap AceContainer::PlaceHolderToType(const std::string& onePlaceHolder)
1666 {
1667     HintToTypeWrap hintToTypeWrap;
1668     auto viewDataWrap = ViewDataWrap::CreateViewDataWrap();
1669     CHECK_NULL_RETURN(viewDataWrap, hintToTypeWrap);
1670     auto viewDataWrapOhos = AceType::DynamicCast<ViewDataWrapOhos>(viewDataWrap);
1671     CHECK_NULL_RETURN(viewDataWrapOhos, hintToTypeWrap);
1672     std::vector<std::string> placeHolder;
1673     std::vector<int> intType;
1674     std::vector<std::string> metadata;
1675     placeHolder.push_back(onePlaceHolder);
1676     auto isSuccess = viewDataWrapOhos->LoadHint2Type(placeHolder, intType, metadata);
1677     if (!isSuccess) {
1678         TAG_LOGE(AceLogTag::ACE_AUTO_FILL, "Load Hint2Type Failed !");
1679         return hintToTypeWrap;
1680     }
1681     if (intType.empty()) {
1682         return hintToTypeWrap;
1683     }
1684     hintToTypeWrap.autoFillType = static_cast<AceAutoFillType>(viewDataWrapOhos->HintToAutoFillType(intType[0]));
1685     if (!metadata.empty()) {
1686         hintToTypeWrap.metadata = metadata[0];
1687     }
1688     return hintToTypeWrap;
1689 }
1690 
FillAutoFillViewData(const RefPtr<NG::FrameNode> & node,RefPtr<ViewDataWrap> & viewDataWrap)1691 void AceContainer::FillAutoFillViewData(const RefPtr<NG::FrameNode>& node, RefPtr<ViewDataWrap>& viewDataWrap)
1692 {
1693     CHECK_NULL_VOID(node);
1694     CHECK_NULL_VOID(viewDataWrap);
1695     auto nodeInfoWraps = viewDataWrap->GetPageNodeInfoWraps();
1696     auto pattern = node->GetPattern<NG::TextFieldPattern>();
1697     CHECK_NULL_VOID(pattern);
1698     auto autoFillUserName = pattern->GetAutoFillUserName();
1699     auto autoFillNewPassword = pattern->GetAutoFillNewPassword();
1700     if (!autoFillUserName.empty()) {
1701         for (auto nodeInfoWrap : nodeInfoWraps) {
1702             if (!nodeInfoWrap) {
1703                 continue;
1704             }
1705             auto metadataObject = JsonUtil::ParseJsonString(nodeInfoWrap->GetMetadata());
1706             if (nodeInfoWrap->GetAutoFillType() == AceAutoFillType::ACE_USER_NAME) {
1707                 nodeInfoWrap->SetValue(autoFillUserName);
1708                 viewDataWrap->SetUserSelected(true);
1709                 break;
1710             } else if (nodeInfoWrap->GetAutoFillType() == AceAutoFillType::ACE_UNSPECIFIED && metadataObject &&
1711                        metadataObject->Contains("type")) {
1712                 metadataObject->Put("username", autoFillUserName.c_str());
1713                 nodeInfoWrap->SetMetadata(metadataObject->ToString());
1714                 viewDataWrap->SetUserSelected(true);
1715             }
1716         }
1717         pattern->SetAutoFillUserName("");
1718     }
1719     if (!autoFillNewPassword.empty()) {
1720         for (auto nodeInfoWrap : nodeInfoWraps) {
1721             if (nodeInfoWrap && nodeInfoWrap->GetAutoFillType() == AceAutoFillType::ACE_NEW_PASSWORD) {
1722                 nodeInfoWrap->SetValue(autoFillNewPassword);
1723                 pattern->SetAutoFillNewPassword("");
1724                 break;
1725             }
1726         }
1727     }
1728 }
1729 
OverwritePageNodeInfo(const RefPtr<NG::FrameNode> & frameNode,AbilityBase::ViewData & viewData)1730 void AceContainer::OverwritePageNodeInfo(const RefPtr<NG::FrameNode>& frameNode, AbilityBase::ViewData& viewData)
1731 {
1732     // Non-native component like web/xcomponent, does not have PageNodeInfo
1733     CHECK_NULL_VOID(frameNode);
1734     auto pattern = frameNode->GetPattern();
1735     CHECK_NULL_VOID(pattern);
1736     std::vector<AbilityBase::PageNodeInfo> nodeInfos;
1737     auto viewDataWrap = ViewDataWrap::CreateViewDataWrap();
1738     pattern->DumpViewDataPageNode(viewDataWrap);
1739     auto infos = viewDataWrap->GetPageNodeInfoWraps();
1740     for (const auto& info : infos) {
1741         if (!info) {
1742             continue;
1743         }
1744         AbilityBase::PageNodeInfo node;
1745         node.id = info->GetId();
1746         node.depth = -1;
1747         node.autoFillType = static_cast<AbilityBase::AutoFillType>(info->GetAutoFillType());
1748         node.isFocus = info->GetIsFocus();
1749         node.value = info->GetValue();
1750         node.placeholder = info->GetPlaceholder();
1751         node.metadata = info->GetMetadata();
1752         NG::RectF rectF = info->GetPageNodeRect();
1753         node.rect.left = rectF.GetX();
1754         node.rect.top = rectF.GetY();
1755         node.rect.width = rectF.Width();
1756         node.rect.height = rectF.Height();
1757         nodeInfos.emplace_back(node);
1758     }
1759     viewData.nodes = nodeInfos;
1760     viewData.pageUrl = viewDataWrap->GetPageUrl();
1761 }
1762 
FillAutoFillCustomConfig(const RefPtr<NG::FrameNode> & node,AbilityRuntime::AutoFill::AutoFillCustomConfig & customConfig,bool isNative)1763 void FillAutoFillCustomConfig(
1764     const RefPtr<NG::FrameNode>& node, AbilityRuntime::AutoFill::AutoFillCustomConfig& customConfig, bool isNative)
1765 {
1766     CHECK_NULL_VOID(node);
1767     AbilityRuntime::AutoFill::PopupSize popupSize;
1768     popupSize.height = POPUPSIZE_HEIGHT;
1769     popupSize.width = POPUPSIZE_WIDTH;
1770     customConfig.targetSize = popupSize;
1771     customConfig.isShowInSubWindow = false;
1772     customConfig.nodeId = node->GetId();
1773     customConfig.isEnableArrow = false;
1774     if (!isNative) {
1775         // web component will manually destroy the popup
1776         customConfig.isAutoCancel = true;
1777     }
1778 }
1779 
GetFocusedElementRect(const AbilityBase::ViewData & viewData,AbilityBase::Rect & rect)1780 void GetFocusedElementRect(const AbilityBase::ViewData& viewData, AbilityBase::Rect& rect)
1781 {
1782     for (const auto& info : viewData.nodes) {
1783         if (info.isFocus) {
1784             rect = info.rect;
1785         }
1786     }
1787 }
1788 
RequestAutoFill(const RefPtr<NG::FrameNode> & node,AceAutoFillType autoFillType,bool isNewPassWord,bool & isPopup,uint32_t & autoFillSessionId,bool isNative,const std::function<void ()> & onFinish,const std::function<void ()> & onUIExtNodeBindingCompleted)1789 int32_t AceContainer::RequestAutoFill(const RefPtr<NG::FrameNode>& node, AceAutoFillType autoFillType,
1790     bool isNewPassWord, bool& isPopup, uint32_t& autoFillSessionId, bool isNative,
1791     const std::function<void()>& onFinish, const std::function<void()>& onUIExtNodeBindingCompleted)
1792 {
1793     TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called, autoFillType: %{public}d", static_cast<int32_t>(autoFillType));
1794     auto pipelineContext = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
1795     CHECK_NULL_RETURN(node, AceAutoFillError::ACE_AUTO_FILL_DEFAULT);
1796     CHECK_NULL_RETURN(pipelineContext, AceAutoFillError::ACE_AUTO_FILL_DEFAULT);
1797     CHECK_NULL_RETURN(uiWindow_, AceAutoFillError::ACE_AUTO_FILL_DEFAULT);
1798     auto uiContent = uiWindow_->GetUIContent();
1799     CHECK_NULL_RETURN(uiContent, AceAutoFillError::ACE_AUTO_FILL_DEFAULT);
1800     auto uiContentImpl = reinterpret_cast<UIContentImpl*>(uiContent);
1801     CHECK_NULL_RETURN(uiContentImpl, AceAutoFillError::ACE_AUTO_FILL_DEFAULT);
1802     auto viewDataWrap = ViewDataWrap::CreateViewDataWrap();
1803     CHECK_NULL_RETURN(viewDataWrap, AceAutoFillError::ACE_AUTO_FILL_DEFAULT);
1804     auto autoFillContainerNode = node->GetFirstAutoFillContainerNode();
1805     uiContentImpl->DumpViewData(autoFillContainerNode, viewDataWrap, true);
1806     FillAutoFillViewData(node, viewDataWrap);
1807     auto callback = std::make_shared<FillRequestCallback>(pipelineContext, node, autoFillType, isNative, onFinish);
1808     auto viewDataWrapOhos = AceType::DynamicCast<ViewDataWrapOhos>(viewDataWrap);
1809     CHECK_NULL_RETURN(viewDataWrapOhos, AceAutoFillError::ACE_AUTO_FILL_DEFAULT);
1810     auto viewData = viewDataWrapOhos->GetViewData();
1811     TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "isNewPassWord is: %{public}d", isNewPassWord);
1812     if (isNewPassWord) {
1813         callback->OnFillRequestSuccess(viewData);
1814         return AceAutoFillError::ACE_AUTO_FILL_SUCCESS;
1815     }
1816     if (!isNative) {
1817         OverwritePageNodeInfo(node, viewData);
1818         AbilityBase::Rect rect;
1819         GetFocusedElementRect(viewData, rect);
1820         callback->SetFocusedRect(rect);
1821         callback->SetWindowRect(uiWindow_->GetRect());
1822     }
1823     AbilityRuntime::AutoFill::AutoFillCustomConfig customConfig;
1824     FillAutoFillCustomConfig(node, customConfig, isNative);
1825     AbilityRuntime::AutoFill::AutoFillRequest autoFillRequest;
1826     autoFillRequest.config = customConfig;
1827     autoFillRequest.autoFillType = static_cast<AbilityBase::AutoFillType>(autoFillType);
1828     autoFillRequest.autoFillCommand = AbilityRuntime::AutoFill::AutoFillCommand::FILL;
1829     autoFillRequest.viewData = viewData;
1830     autoFillRequest.doAfterAsyncModalBinding = std::move(onUIExtNodeBindingCompleted);
1831     AbilityRuntime::AutoFill::AutoFillResult result;
1832     auto resultCode =
1833         AbilityRuntime::AutoFillManager::GetInstance().RequestAutoFill(uiContent, autoFillRequest, callback, result);
1834     if (resultCode == AceAutoFillError::ACE_AUTO_FILL_SUCCESS) {
1835         isPopup = result.isPopup;
1836         autoFillSessionId = result.autoFillSessionId;
1837     }
1838     return resultCode;
1839 }
1840 
IsNeedToCreatePopupWindow(const AceAutoFillType & autoFillType)1841 bool AceContainer::IsNeedToCreatePopupWindow(const AceAutoFillType& autoFillType)
1842 {
1843     return AbilityRuntime::AutoFillManager::GetInstance().IsNeedToCreatePopupWindow(
1844         static_cast<AbilityBase::AutoFillType>(autoFillType));
1845 }
1846 
1847 class SaveRequestCallback : public AbilityRuntime::ISaveRequestCallback {
1848 public:
SaveRequestCallback(WeakPtr<NG::PipelineContext> pipelineContext,const std::function<void ()> & onFinish)1849     SaveRequestCallback(WeakPtr<NG::PipelineContext> pipelineContext, const std::function<void()>& onFinish)
1850         : pipelineContext_(pipelineContext), onFinish_(onFinish)
1851     {}
1852     virtual ~SaveRequestCallback() = default;
OnSaveRequestSuccess()1853     void OnSaveRequestSuccess() override
1854     {
1855         TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "OnSaveRequestSuccess called");
1856         ProcessOnFinish();
1857     }
1858 
OnSaveRequestFailed()1859     void OnSaveRequestFailed() override
1860     {
1861         TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "OnSaveRequestFailed called");
1862         ProcessOnFinish();
1863     }
1864 
ProcessOnFinish()1865     void ProcessOnFinish()
1866     {
1867         if (!onFinish_) {
1868             return;
1869         }
1870         auto pipelineContext = pipelineContext_.Upgrade();
1871         CHECK_NULL_VOID(pipelineContext);
1872         auto taskExecutor = pipelineContext->GetTaskExecutor();
1873         CHECK_NULL_VOID(taskExecutor);
1874         taskExecutor->PostTask(
1875             [onFinish = std::move(onFinish_)]() mutable {
1876                 if (onFinish) {
1877                     onFinish();
1878                     onFinish = nullptr;
1879                 }
1880             },
1881             TaskExecutor::TaskType::UI, "ProcessOnFinish");
1882     }
1883 
1884 private:
1885     WeakPtr<NG::PipelineContext> pipelineContext_ = nullptr;
1886     std::function<void()> onFinish_;
1887 };
1888 
RequestAutoSave(const RefPtr<NG::FrameNode> & node,const std::function<void ()> & onFinish,const std::function<void ()> & onUIExtNodeBindingCompleted,bool isNative,int32_t instanceId)1889 bool AceContainer::RequestAutoSave(const RefPtr<NG::FrameNode>& node, const std::function<void()>& onFinish,
1890     const std::function<void()>& onUIExtNodeBindingCompleted, bool isNative, int32_t instanceId)
1891 {
1892     TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "RequestAutoSave called");
1893     CHECK_NULL_RETURN(uiWindow_, false);
1894     auto uiContent = uiWindow_->GetUIContent();
1895     auto uiContentImpl = reinterpret_cast<UIContentImpl*>(uiContent);
1896     CHECK_NULL_RETURN(uiContentImpl, false);
1897     auto viewDataWrap = ViewDataWrap::CreateViewDataWrap();
1898     uiContentImpl->DumpViewData(node, viewDataWrap, false, true);
1899 
1900     auto pipelineContext = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
1901     CHECK_NULL_RETURN(pipelineContext, false);
1902     auto callback = std::make_shared<SaveRequestCallback>(pipelineContext, onFinish);
1903     auto viewDataWrapOhos = AceType::DynamicCast<ViewDataWrapOhos>(viewDataWrap);
1904     CHECK_NULL_RETURN(viewDataWrapOhos, false);
1905     auto viewData = viewDataWrapOhos->GetViewData();
1906     if (!isNative) {
1907         OverwritePageNodeInfo(node, viewData);
1908     }
1909     AbilityRuntime::AutoFill::AutoFillRequest autoFillRequest;
1910     autoFillRequest.viewData = viewData;
1911     autoFillRequest.autoFillCommand = AbilityRuntime::AutoFill::AutoFillCommand::SAVE;
1912     autoFillRequest.autoFillType = ViewDataWrap::ViewDataToType(viewData);
1913     autoFillRequest.doAfterAsyncModalBinding = std::move(onUIExtNodeBindingCompleted);
1914     if (instanceId != -1) {
1915         auto uiWindow = GetUIWindow(instanceId);
1916         CHECK_NULL_RETURN(uiWindow, false);
1917         uiContent = uiWindow->GetUIContent();
1918         CHECK_NULL_RETURN(uiContent, false);
1919     }
1920     AbilityRuntime::AutoFill::AutoFillResult result;
1921     if (AbilityRuntime::AutoFillManager::GetInstance().RequestAutoSave(uiContent, autoFillRequest, callback, result) !=
1922         0) {
1923         return false;
1924     }
1925     return true;
1926 }
1927 
GetNavigationController(const std::string & navigationId)1928 std::shared_ptr<NavigationController> AceContainer::GetNavigationController(const std::string& navigationId)
1929 {
1930     CHECK_NULL_RETURN(pipelineContext_, nullptr);
1931     return pipelineContext_->GetNavigationController(navigationId);
1932 }
1933 
SetHapPath(const std::string & hapPath)1934 void AceContainer::SetHapPath(const std::string& hapPath)
1935 {
1936     if (hapPath.empty()) {
1937         LOGW("SetHapPath, Use .index to load resource");
1938         return;
1939     }
1940     LOGI("SetHapPath, Use hap path to load resource");
1941     webHapPath_ = hapPath;
1942     resourceInfo_.SetHapPath(hapPath);
1943     SystemProperties::SetUnZipHap(false);
1944 }
1945 
Dispatch(const std::string & group,std::vector<uint8_t> && data,int32_t id,bool replyToComponent) const1946 void AceContainer::Dispatch(
1947     const std::string& group, std::vector<uint8_t>&& data, int32_t id, bool replyToComponent) const
1948 {
1949     return;
1950 }
1951 
DispatchPluginError(int32_t callbackId,int32_t errorCode,std::string && errorMessage) const1952 void AceContainer::DispatchPluginError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const
1953 {
1954     auto front = GetFrontend();
1955     CHECK_NULL_VOID(front);
1956     ContainerScope scope(instanceId_);
1957     taskExecutor_->PostTask(
1958         [front, callbackId, errorCode, errorMessage = std::move(errorMessage)]() mutable {
1959             front->TransferJsPluginGetError(callbackId, errorCode, std::move(errorMessage));
1960         },
1961         TaskExecutor::TaskType::BACKGROUND, "ArkUIDispatchPluginError");
1962 }
1963 
Dump(const std::vector<std::string> & params,std::vector<std::string> & info)1964 bool AceContainer::Dump(const std::vector<std::string>& params, std::vector<std::string>& info)
1965 {
1966     bool isDynamicUiContent = GetUIContentType() == UIContentType::DYNAMIC_COMPONENT;
1967     if (isDynamicUiContent) {
1968         return DumpDynamicUiContent(params, info);
1969     }
1970 
1971     return DumpCommon(params, info);
1972 }
1973 
DumpCommon(const std::vector<std::string> & params,std::vector<std::string> & info)1974 bool AceContainer::DumpCommon(const std::vector<std::string>& params, std::vector<std::string>& info)
1975 {
1976     if (isDumping_.test_and_set()) {
1977         LOGW("another dump is still running");
1978         return false;
1979     }
1980     ContainerScope scope(instanceId_);
1981     auto result = false;
1982     paramUie_.assign(params.begin(), params.end());
1983     if (std::find(params.begin(), params.end(), "-simplify") != params.end()) {
1984         paramUie_.push_back("-nouie");
1985     }
1986     std::unique_ptr<std::ostream> ostream = std::make_unique<std::ostringstream>();
1987     CHECK_NULL_RETURN(ostream, false);
1988     DumpLog::GetInstance().SetDumpFile(std::move(ostream));
1989     if (IsUIExtensionWindow()) {
1990         DumpLog::GetInstance().SetSeparator(";");
1991     }
1992     auto context = runtimeContext_.lock();
1993     DumpLog::GetInstance().Print("bundleName:" + context->GetHapModuleInfo()->bundleName);
1994     DumpLog::GetInstance().Print("moduleName:" + context->GetHapModuleInfo()->moduleName);
1995     result = DumpInfo(params);
1996     const auto& infoFile = DumpLog::GetInstance().GetDumpFile();
1997     auto* ostringstream = static_cast<std::ostringstream*>(infoFile.get());
1998     info.emplace_back(ostringstream->str());
1999     DumpLog::GetInstance().Reset();
2000     if (!result) {
2001         DumpLog::ShowDumpHelp(info);
2002     }
2003     isDumping_.clear();
2004     return true;
2005 }
2006 
DumpDynamicUiContent(const std::vector<std::string> & params,std::vector<std::string> & info)2007 bool AceContainer::DumpDynamicUiContent(const std::vector<std::string>& params, std::vector<std::string>& info)
2008 {
2009     LOGI("DumpDynamicUiContent");
2010     ContainerScope scope(instanceId_);
2011     return DumpInfo(params);
2012 }
2013 
DumpInfo(const std::vector<std::string> & params)2014 bool AceContainer::DumpInfo(const std::vector<std::string>& params)
2015 {
2016     if (aceView_ && aceView_->Dump(params)) {
2017         return true;
2018     }
2019 
2020     if (OnDumpInfo(params)) {
2021         return true;
2022     }
2023 
2024     if (DumpRSNodeByStringID(params)) {
2025         return true;
2026     }
2027     CHECK_NULL_RETURN(pipelineContext_, false);
2028     return pipelineContext_->Dump(params);
2029 }
2030 
DumpRSNodeByStringID(const std::vector<std::string> & params)2031 bool AceContainer::DumpRSNodeByStringID(const std::vector<std::string>& params)
2032 {
2033     if (!params.empty() && params[0] == "-rsnodebyid" && (params.size() > 1)) {
2034         DumpLog::GetInstance().Print("------------DumpRSNodeByStringID------------");
2035         DumpLog::GetInstance().Print(1, "Query by stringid: " + params[1]);
2036         auto frameNode = NG::Inspector::GetFrameNodeByKey(params[1], true, true);
2037         if (!frameNode) {
2038             DumpLog::GetInstance().Print(1, "RSNode Not Found.");
2039             return true;
2040         }
2041         auto renderContext = AceType::DynamicCast<NG::RosenRenderContext>(frameNode->GetRenderContext());
2042         CHECK_NULL_RETURN(renderContext, true);
2043         auto rsNode = renderContext->GetRSNode();
2044         DumpLog::GetInstance().Print(
2045             1, "RSNode " + (rsNode ? ("name: " + rsNode->GetNodeName() + ", nodeId: " + std::to_string(rsNode->GetId()))
2046                                    : "Not Found."));
2047         return true;
2048     }
2049     return false;
2050 }
2051 
OnDumpInfo(const std::vector<std::string> & params)2052 bool AceContainer::OnDumpInfo(const std::vector<std::string>& params)
2053 {
2054     if (!params.empty() && params[0] == "-basicinfo") {
2055         DumpLog::GetInstance().Print("BasicInfo: ");
2056         DumpLog::GetInstance().Print(1, "InstanceId: " + std::to_string(instanceId_));
2057         DumpLog::GetInstance().Print(1,
2058             "FrontendType: " + std::to_string(static_cast<typename std::underlying_type<FrontendType>::type>(type_)));
2059         DumpLog::GetInstance().Print(1, "NewPipeline: " + std::string(IsUseNewPipeline() ? "true" : "false"));
2060         DumpLog::GetInstance().Print(1, "WindowName: " + windowName_);
2061         DumpLog::GetInstance().Print(
2062             1, "WindowState: " +
2063                    (!frontend_ ? "frontend is null"
2064                                : std::to_string(static_cast<typename std::underlying_type<Frontend::State>::type>(
2065                                      frontend_->GetState()))));
2066         DumpLog::GetInstance().Print(1, "Language: " + AceApplicationInfo::GetInstance().GetLocaleTag());
2067         DumpLog::GetInstance().Print(
2068             1, "RTL: " + std::string(AceApplicationInfo::GetInstance().IsRightToLeft() ? "true" : "false"));
2069         DumpLog::GetInstance().Print(
2070             1, "ColorMode: " + std::string(GetColorMode() == ColorMode::DARK ? "Dark" : "Light"));
2071         DumpLog::GetInstance().Print(1,
2072             "DeviceOrientation: " + std::string(SystemProperties::GetDeviceOrientation() == DeviceOrientation::LANDSCAPE
2073                                                     ? "Landscape"
2074                                                     : "Portrait"));
2075         DumpLog::GetInstance().Print(1, "Resolution: " + std::to_string(SystemProperties::GetDeviceWidth()) + "*" +
2076                                             std::to_string(SystemProperties::GetDeviceHeight()));
2077         if (pipelineContext_) {
2078             DumpLog::GetInstance().Print(1, "AppBgColor: " + pipelineContext_->GetAppBgColor().ColorToString());
2079             DumpLog::GetInstance().Print(1, "Density: " + std::to_string(pipelineContext_->GetDensity()));
2080             DumpLog::GetInstance().Print(1, "ViewScale: " + std::to_string(pipelineContext_->GetViewScale()));
2081             DumpLog::GetInstance().Print(
2082                 1, "DisplayWindowRect: " + pipelineContext_->GetDisplayWindowRectInfo().ToString());
2083             DumpLog::GetInstance().Print(1, "vsyncID: " + std::to_string(pipelineContext_->GetFrameCount()));
2084         }
2085         DumpLog::GetInstance().Print(1, "ApiVersion: " + SystemProperties::GetApiVersion());
2086         DumpLog::GetInstance().Print(1, "ReleaseType: " + SystemProperties::GetReleaseType());
2087         DumpLog::GetInstance().Print(1, "DeviceType: " + SystemProperties::GetParamDeviceType());
2088         return true;
2089     }
2090     return false;
2091 }
2092 
TriggerGarbageCollection()2093 void AceContainer::TriggerGarbageCollection()
2094 {
2095     ContainerScope scope(instanceId_);
2096 #if !defined(OHOS_PLATFORM) || !defined(ENABLE_NATIVE_VIEW)
2097     // GPU and IO thread is standalone while disable native view
2098     taskExecutor_->PostTask([] { PurgeMallocCache(); }, TaskExecutor::TaskType::GPU, "ArkUIPurgeMallocCache");
2099     taskExecutor_->PostTask([] { PurgeMallocCache(); }, TaskExecutor::TaskType::IO, "ArkUIPurgeMallocCache");
2100 #endif
2101     taskExecutor_->PostTask([] { PurgeMallocCache(); }, TaskExecutor::TaskType::UI, "ArkUIPurgeMallocCache");
2102     taskExecutor_->PostTask(
2103         [frontend = WeakPtr<Frontend>(frontend_)] {
2104             auto sp = frontend.Upgrade();
2105             if (sp) {
2106                 sp->TriggerGarbageCollection();
2107             }
2108             PurgeMallocCache();
2109         },
2110         TaskExecutor::TaskType::JS, "ArkUITriggerGarbageCollection");
2111 }
2112 
DumpHeapSnapshot(bool isPrivate)2113 void AceContainer::DumpHeapSnapshot(bool isPrivate)
2114 {
2115     taskExecutor_->PostTask(
2116         [isPrivate, frontend = WeakPtr<Frontend>(frontend_)] {
2117             auto sp = frontend.Upgrade();
2118             CHECK_NULL_VOID(sp);
2119             sp->DumpHeapSnapshot(isPrivate);
2120         },
2121         TaskExecutor::TaskType::JS, "ArkUIDumpHeapSnapshot");
2122 }
2123 
DestroyHeapProfiler()2124 void AceContainer::DestroyHeapProfiler()
2125 {
2126     taskExecutor_->PostTask(
2127         [frontend = WeakPtr<Frontend>(frontend_)] {
2128             auto sp = frontend.Upgrade();
2129             CHECK_NULL_VOID(sp);
2130             sp->DestroyHeapProfiler();
2131         },
2132         TaskExecutor::TaskType::JS, "ArkUIDestroyHeapProfiler");
2133 }
2134 
ForceFullGC()2135 void AceContainer::ForceFullGC()
2136 {
2137     taskExecutor_->PostTask(
2138         [frontend = WeakPtr<Frontend>(frontend_)] {
2139             auto sp = frontend.Upgrade();
2140             CHECK_NULL_VOID(sp);
2141             sp->ForceFullGC();
2142         },
2143         TaskExecutor::TaskType::JS, "ArkUIForceFullGC");
2144 }
2145 
SetLocalStorage(NativeReference * storage,const std::shared_ptr<OHOS::AbilityRuntime::Context> & context)2146 void AceContainer::SetLocalStorage(
2147     NativeReference* storage, const std::shared_ptr<OHOS::AbilityRuntime::Context>& context)
2148 {
2149     ContainerScope scope(instanceId_);
2150     taskExecutor_->PostSyncTask(
2151         [frontend = WeakPtr<Frontend>(frontend_), storage,
2152             contextWeak = std::weak_ptr<OHOS::AbilityRuntime::Context>(context), id = instanceId_,
2153             sharedRuntime = sharedRuntime_] {
2154             auto sp = frontend.Upgrade();
2155             auto contextRef = contextWeak.lock();
2156             if (!sp || !contextRef) {
2157                 ReleaseStorageReference(sharedRuntime, storage);
2158                 return;
2159             }
2160 #ifdef NG_BUILD
2161             auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontendNG>(sp);
2162 #else
2163             auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(sp);
2164 #endif
2165             if (!declarativeFrontend) {
2166                 ReleaseStorageReference(sharedRuntime, storage);
2167                 return;
2168             }
2169             auto jsEngine = declarativeFrontend->GetJsEngine();
2170             if (!jsEngine) {
2171                 ReleaseStorageReference(sharedRuntime, storage);
2172                 return;
2173             }
2174             if (contextRef->GetBindingObject() && contextRef->GetBindingObject()->Get<NativeReference>()) {
2175                 jsEngine->SetContext(id, contextRef->GetBindingObject()->Get<NativeReference>());
2176             }
2177             if (storage) {
2178                 jsEngine->SetLocalStorage(id, storage);
2179             }
2180         },
2181         TaskExecutor::TaskType::JS, "ArkUISetLocalStorage");
2182 }
2183 
AddAssetPath(int32_t instanceId,const std::string & packagePath,const std::string & hapPath,const std::vector<std::string> & paths)2184 void AceContainer::AddAssetPath(int32_t instanceId, const std::string& packagePath, const std::string& hapPath,
2185     const std::vector<std::string>& paths)
2186 {
2187     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
2188     CHECK_NULL_VOID(container);
2189     RefPtr<AssetManagerImpl> assetManagerImpl;
2190     if (container->assetManager_) {
2191         assetManagerImpl = AceType::DynamicCast<AssetManagerImpl>(container->assetManager_);
2192     } else {
2193         assetManagerImpl = Referenced::MakeRefPtr<AssetManagerImpl>();
2194         container->assetManager_ = assetManagerImpl;
2195         if (container->type_ != FrontendType::DECLARATIVE_JS && container->type_ != FrontendType::DECLARATIVE_CJ) {
2196             container->frontend_->SetAssetManager(assetManagerImpl);
2197         }
2198     }
2199     CHECK_NULL_VOID(assetManagerImpl);
2200     if (!hapPath.empty()) {
2201         auto assetProvider = AceType::MakeRefPtr<HapAssetProviderImpl>();
2202         if (assetProvider->Initialize(hapPath, paths)) {
2203             LOGI("Push AssetProvider to queue.");
2204             assetManagerImpl->PushBack(std::move(assetProvider));
2205         }
2206     }
2207     if (!packagePath.empty()) {
2208         auto assetProvider = AceType::MakeRefPtr<FileAssetProviderImpl>();
2209         if (assetProvider->Initialize(packagePath, paths)) {
2210             LOGI("Push AssetProvider to queue.");
2211             assetManagerImpl->PushBack(std::move(assetProvider));
2212         }
2213     }
2214 }
2215 
AddLibPath(int32_t instanceId,const std::vector<std::string> & libPath)2216 void AceContainer::AddLibPath(int32_t instanceId, const std::vector<std::string>& libPath)
2217 {
2218     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
2219     CHECK_NULL_VOID(container);
2220     RefPtr<AssetManager> assetManagerImpl;
2221     if (container->assetManager_) {
2222         assetManagerImpl = AceType::DynamicCast<AssetManagerImpl>(container->assetManager_);
2223     } else {
2224         assetManagerImpl = Referenced::MakeRefPtr<AssetManagerImpl>();
2225         container->assetManager_ = assetManagerImpl;
2226         if (container->type_ != FrontendType::DECLARATIVE_JS && container->type_ != FrontendType::DECLARATIVE_CJ) {
2227             container->frontend_->SetAssetManager(assetManagerImpl);
2228         }
2229     }
2230     CHECK_NULL_VOID(assetManagerImpl);
2231     assetManagerImpl->SetLibPath("default", libPath);
2232 }
2233 
AttachView(std::shared_ptr<Window> window,const RefPtr<AceView> & view,double density,float width,float height,uint32_t windowId,UIEnvCallback callback)2234 void AceContainer::AttachView(std::shared_ptr<Window> window, const RefPtr<AceView>& view, double density, float width,
2235     float height, uint32_t windowId, UIEnvCallback callback)
2236 {
2237     aceView_ = view;
2238     auto instanceId = aceView_->GetInstanceId();
2239     auto taskExecutorImpl = AceType::DynamicCast<TaskExecutorImpl>(taskExecutor_);
2240     if (!isSubContainer_) {
2241         auto aceView = AceType::DynamicCast<AceViewOhos>(aceView_);
2242         ACE_DCHECK(aceView != nullptr);
2243         taskExecutorImpl->InitOtherThreads(aceView->GetThreadModelImpl());
2244     }
2245     ContainerScope scope(instanceId);
2246     if (type_ == FrontendType::DECLARATIVE_JS || type_ == FrontendType::DECLARATIVE_CJ) {
2247         // For DECLARATIVE_JS frontend display UI in JS thread temporarily.
2248         taskExecutorImpl->InitJsThread(false);
2249         InitializeFrontend();
2250         auto front = GetFrontend();
2251         if (front) {
2252             front->UpdateState(Frontend::State::ON_CREATE);
2253             front->SetJsMessageDispatcher(AceType::Claim(this));
2254             front->SetAssetManager(assetManager_);
2255         }
2256     } else if (type_ != FrontendType::JS_CARD) {
2257         aceView_->SetCreateTime(createTime_);
2258     }
2259     resRegister_ = aceView_->GetPlatformResRegister();
2260     auto uiTranslateManager = std::make_shared<UiTranslateManagerImpl>();
2261 #ifndef NG_BUILD
2262     if (useNewPipeline_) {
2263         pipelineContext_ = AceType::MakeRefPtr<NG::PipelineContext>(
2264             window, taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
2265         pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<NG::TextFieldManagerNG>());
2266         auto pipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
2267         UiSessionManager::GetInstance()->SaveTranslateManager(uiTranslateManager);
2268         if (pipeline) {
2269             pipeline->SaveTranslateManager(uiTranslateManager);
2270         } else {
2271             LOGE("pipeline invalid,only new ArkUI pipeline support UIsession");
2272         }
2273     } else {
2274         LOGI("Create old pipeline.");
2275         pipelineContext_ = AceType::MakeRefPtr<PipelineContext>(
2276             window, taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
2277         pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<TextFieldManager>());
2278     }
2279 #else
2280     pipelineContext_ = AceType::MakeRefPtr<NG::PipelineContext>(
2281         window, taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
2282     pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<NG::TextFieldManagerNG>());
2283     auto pipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
2284     UiSessionManager::GetInstance()->SaveTranslateManager(uiTranslateManager);
2285     if (pipeline) {
2286         pipeline->SaveTranslateManager(uiTranslateManager);
2287     } else {
2288         LOGE("pipeline invalid,only new ArkUI pipeline support UIsession");
2289     }
2290 #endif
2291     RegisterUIExtDataConsumer();
2292     RegisterUIExtDataSendToHost();
2293     RegisterAvoidInfoCallback();
2294 
2295 #ifdef FORM_SUPPORTED
2296     if (isFormRender_) {
2297         pipelineContext_->SetIsFormRender(isFormRender_);
2298         pipelineContext_->SetIsDynamicRender(isDynamicRender_);
2299         auto cardFrontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
2300         if (cardFrontend) {
2301             cardFrontend->SetTaskExecutor(taskExecutor_);
2302             cardFrontend->SetLoadCardCallBack(WeakPtr<PipelineBase>(pipelineContext_));
2303         }
2304     }
2305 #endif
2306 
2307     if (isDynamicRender_) {
2308         pipelineContext_->SetIsDynamicRender(isDynamicRender_);
2309     }
2310 
2311     auto windowDensityCallback = [weak = WeakClaim(this)]() {
2312         auto container = weak.Upgrade();
2313         CHECK_NULL_RETURN(container, 0.0);
2314         return container->GetWindowDensity();
2315     };
2316     pipelineContext_->RegisterWindowDensityCallback(std::move(windowDensityCallback));
2317 
2318     pipelineContext_->SetRootSize(density, width, height);
2319     if (isFormRender_) {
2320         pipelineContext_->OnSurfaceDensityChanged(density);
2321     }
2322     pipelineContext_->SetIsRightToLeft(AceApplicationInfo::GetInstance().IsRightToLeft());
2323     pipelineContext_->SetWindowId(windowId);
2324     pipelineContext_->SetWindowModal(windowModal_);
2325     if (uiWindow_) {
2326         bool isAppWindow = uiWindow_->IsAppWindow();
2327         bool isSystemWindow = uiWindow_->IsSystemWindow();
2328         bool isSceneBoardWindow = uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_SCENE_BOARD;
2329         pipelineContext_->SetIsAppWindow(isAppWindow);
2330         auto pipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
2331         if (pipeline) {
2332             auto safeAreaManager = pipeline->GetSafeAreaManager();
2333             if (safeAreaManager) {
2334                 safeAreaManager->SetWindowTypeConfig(isAppWindow, isSystemWindow, isSceneBoardWindow);
2335             }
2336         }
2337     }
2338     if (installationFree_) {
2339         pipelineContext_->SetInstallationFree(installationFree_);
2340         pipelineContext_->SetSharePanelCallback(std::move(sharePanelCallback_));
2341         std::shared_ptr<AppExecFwk::AbilityInfo> info = abilityInfo_.lock();
2342         if (info != nullptr) {
2343             pipelineContext_->SetAppLabelId(info->labelId);
2344         }
2345     }
2346     if (isSubContainer_) {
2347         pipelineContext_->SetIsSubPipeline(true);
2348     }
2349 
2350     pipelineContext_->SetDrawDelegate(aceView_->GetDrawDelegate());
2351     InitWindowCallback();
2352     InitializeCallback();
2353 
2354     auto&& finishEventHandler = [weak = WeakClaim(this), instanceId] {
2355         auto container = weak.Upgrade();
2356         CHECK_NULL_VOID(container);
2357         ContainerScope scope(instanceId);
2358         auto context = container->GetPipelineContext();
2359         CHECK_NULL_VOID(context);
2360         context->GetTaskExecutor()->PostTask(
2361             [weak = WeakPtr<AceContainer>(container)] {
2362                 auto container = weak.Upgrade();
2363                 CHECK_NULL_VOID(container);
2364                 container->OnFinish();
2365             },
2366             TaskExecutor::TaskType::PLATFORM, "ArkUIHandleFinishEvent");
2367     };
2368     pipelineContext_->SetFinishEventHandler(finishEventHandler);
2369 
2370     auto&& startAbilityHandler = [weak = WeakClaim(this), instanceId](const std::string& address) {
2371         auto container = weak.Upgrade();
2372         CHECK_NULL_VOID(container);
2373         ContainerScope scope(instanceId);
2374         auto context = container->GetPipelineContext();
2375         CHECK_NULL_VOID(context);
2376         context->GetTaskExecutor()->PostTask(
2377             [weak = WeakPtr<AceContainer>(container), address]() {
2378                 auto container = weak.Upgrade();
2379                 CHECK_NULL_VOID(container);
2380                 container->OnStartAbility(address);
2381             },
2382             TaskExecutor::TaskType::PLATFORM, "ArkUIHandleStartAbility");
2383     };
2384     pipelineContext_->SetStartAbilityHandler(startAbilityHandler);
2385 
2386     auto&& startAbilityOnQueryHandler = [weak = WeakClaim(this), instanceId](const std::string& queryWord) {
2387         auto container = weak.Upgrade();
2388         CHECK_NULL_VOID(container);
2389         ContainerScope scope(instanceId);
2390         auto context = container->GetPipelineContext();
2391         CHECK_NULL_VOID(context);
2392         context->GetTaskExecutor()->PostTask(
2393             [weak = WeakPtr<AceContainer>(container), queryWord]() {
2394                 auto container = weak.Upgrade();
2395                 CHECK_NULL_VOID(container);
2396                 container->OnStartAbilityOnQuery(queryWord);
2397             },
2398             TaskExecutor::TaskType::PLATFORM, "ArkUIHandleStartAbilityOnQuery");
2399     };
2400     pipelineContext_->SetStartAbilityOnQueryHandler(startAbilityOnQueryHandler);
2401 
2402     auto&& setStatusBarEventHandler = [weak = WeakClaim(this), instanceId](const Color& color) {
2403         auto container = weak.Upgrade();
2404         CHECK_NULL_VOID(container);
2405         ContainerScope scope(instanceId);
2406         auto context = container->GetPipelineContext();
2407         CHECK_NULL_VOID(context);
2408         context->GetTaskExecutor()->PostTask(
2409             [weak, color = color.GetValue()]() {
2410                 auto container = weak.Upgrade();
2411                 CHECK_NULL_VOID(container);
2412                 if (container->platformEventCallback_) {
2413                     container->platformEventCallback_->OnStatusBarBgColorChanged(color);
2414                 }
2415             },
2416             TaskExecutor::TaskType::PLATFORM, "ArkUIStatusBarColorChanged");
2417     };
2418     pipelineContext_->SetStatusBarEventHandler(setStatusBarEventHandler);
2419 
2420     auto uiExtensionEventCallback = [weak = WeakClaim(this)](uint32_t eventId) {
2421         auto container = weak.Upgrade();
2422         CHECK_NULL_VOID(container);
2423         container->FireUIExtensionEventCallback(eventId);
2424     };
2425     pipelineContext_->SetUIExtensionEventCallback(uiExtensionEventCallback);
2426 
2427     auto accessibilityEventCallback = [weak = WeakClaim(this)](uint32_t eventId, int64_t parameter) {
2428         auto container = weak.Upgrade();
2429         CHECK_NULL_VOID(container);
2430         container->FireAccessibilityEventCallback(eventId, parameter);
2431     };
2432     pipelineContext_->SetAccessibilityEventCallback(accessibilityEventCallback);
2433 
2434     if (GetSettings().usePlatformAsUIThread) {
2435         std::string frameReportInitTaskKey = "FrameReportInit";
2436         TaskDependencyManager::GetInstance()->PostTaskToBg([] {
2437                 ACE_SCOPED_TRACE("FrameReport INIT");
2438                 FrameReport::GetInstance().Init();
2439             }, frameReportInitTaskKey);
2440     } else {
2441         taskExecutor_->PostTask([] { FrameReport::GetInstance().Init(); },
2442             TaskExecutor::TaskType::UI, "ArkUIFrameReportInit");
2443     }
2444 
2445     // Load custom style at UI thread before frontend attach, for loading style before building tree.
2446     auto initThemeManagerTask = [pipelineContext = pipelineContext_, assetManager = assetManager_,
2447                                     colorScheme = colorScheme_, resourceInfo = resourceInfo_,
2448                                     context = runtimeContext_.lock(), abilityInfo = abilityInfo_.lock()]() {
2449         ACE_SCOPED_TRACE("OHOS::LoadThemes()");
2450 
2451         if (SystemProperties::GetResourceDecoupling()) {
2452             InitResourceAndThemeManager(pipelineContext, assetManager, colorScheme, resourceInfo, context, abilityInfo);
2453         } else {
2454             ThemeConstants::InitDeviceType();
2455             auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>();
2456             pipelineContext->SetThemeManager(themeManager);
2457             themeManager->InitResource(resourceInfo);
2458             themeManager->SetColorScheme(colorScheme);
2459             themeManager->LoadCustomTheme(assetManager);
2460             themeManager->LoadResourceThemes();
2461         }
2462         auto themeManager = pipelineContext->GetThemeManager();
2463         if (themeManager) {
2464             pipelineContext->SetAppBgColor(themeManager->GetBackgroundColor());
2465         }
2466     };
2467 
2468     auto setupRootElementTask = [context = pipelineContext_, callback, isSubContainer = isSubContainer_,
2469         isDialogContainer = IsDialogContainer()]() {
2470         if (callback != nullptr) {
2471             callback(AceType::DynamicCast<PipelineContext>(context));
2472         }
2473         if (!isSubContainer && !isDialogContainer) {
2474             context->SetupRootElement();
2475         }
2476     };
2477     if (GetSettings().usePlatformAsUIThread) {
2478         initThemeManagerTask();
2479         setupRootElementTask();
2480     } else {
2481         taskExecutor_->PostTask(initThemeManagerTask, TaskExecutor::TaskType::UI, "ArkUIInitThemeManager");
2482         taskExecutor_->PostTask(setupRootElementTask, TaskExecutor::TaskType::UI, "ArkUISetupRootElement");
2483     }
2484 
2485     aceView_->Launch();
2486 
2487 #ifdef NG_BUILD
2488     auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontendNG>(frontend_);
2489 #else
2490     auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
2491 #endif
2492     if (declarativeFrontend) {
2493         auto jsEngine = AceType::DynamicCast<Framework::JsiDeclarativeEngine>(declarativeFrontend->GetJsEngine());
2494         if (jsEngine && !isFormRender_) {
2495             // register state profiler callback
2496             jsEngine->JsStateProfilerResgiter();
2497             jsEngine->JsSetAceDebugMode();
2498         }
2499     }
2500 
2501     if (!isSubContainer_) {
2502         // Only MainWindow instance in FA model will be registered to watch dog.
2503         if (!GetSettings().usingSharedRuntime && !AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint()) {
2504             AceEngine::Get().RegisterToWatchDog(instanceId, taskExecutor_, GetSettings().useUIAsJSThread);
2505         }
2506         frontend_->AttachPipelineContext(pipelineContext_);
2507     } else if (frontend_->GetType() == FrontendType::DECLARATIVE_JS) {
2508         if (declarativeFrontend) {
2509             declarativeFrontend->AttachSubPipelineContext(pipelineContext_);
2510         }
2511         return;
2512     }
2513 
2514     auto dataAbilityHelperImpl = [ability = GetAbilityInner(), runtimeContext = runtimeContext_,
2515                                      useStageModel = useStageModel_]() {
2516         return AceType::MakeRefPtr<DataAbilityHelperStandard>(ability.lock(), runtimeContext.lock(), useStageModel);
2517     };
2518     auto dataProviderManager = MakeRefPtr<DataProviderManagerStandard>(dataAbilityHelperImpl);
2519     pipelineContext_->SetDataProviderManager(dataProviderManager);
2520 
2521 #if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
2522     pipelineContext_->SetPostRTTaskCallBack([](std::function<void()>&& task) {
2523         auto syncTask = std::make_shared<AceRosenSyncTask>(std::move(task));
2524         Rosen::RSTransactionProxy::GetInstance()->ExecuteSynchronousTask(syncTask);
2525     });
2526 #endif
2527     if (IsUIExtensionWindow()) {
2528         auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
2529         CHECK_NULL_VOID(ngPipeline);
2530         auto uiExtManager = ngPipeline->GetUIExtensionManager();
2531         CHECK_NULL_VOID(uiExtManager);
2532         uiExtManager->SendPageModeRequestToHost(ngPipeline);
2533         auto accessibilityManager = ngPipeline->GetAccessibilityManager();
2534         CHECK_NULL_VOID(accessibilityManager);
2535         accessibilityManager->RegisterUIExtGetPageModeCallback(uiExtManager);
2536     }
2537 }
2538 
SetUIWindowInner(sptr<OHOS::Rosen::Window> uiWindow)2539 void AceContainer::SetUIWindowInner(sptr<OHOS::Rosen::Window> uiWindow)
2540 {
2541     uiWindow_ = uiWindow;
2542 }
2543 
GetUIWindowInner() const2544 sptr<OHOS::Rosen::Window> AceContainer::GetUIWindowInner() const
2545 {
2546     return uiWindow_;
2547 }
2548 
GetAbilityInner() const2549 std::weak_ptr<OHOS::AppExecFwk::Ability> AceContainer::GetAbilityInner() const
2550 {
2551     return aceAbility_;
2552 }
2553 
GetRuntimeContextInner() const2554 std::weak_ptr<OHOS::AbilityRuntime::Context> AceContainer::GetRuntimeContextInner() const
2555 {
2556     return runtimeContext_;
2557 }
2558 
IsLauncherContainer()2559 bool AceContainer::IsLauncherContainer()
2560 {
2561     auto runtime = runtimeContext_.lock();
2562     if (!runtime) {
2563         return false;
2564     }
2565     auto info = runtime->GetApplicationInfo();
2566     return info ? info->isLauncherApp : false;
2567 }
2568 
IsTransparentBg() const2569 bool AceContainer::IsTransparentBg() const
2570 {
2571     CHECK_NULL_RETURN(pipelineContext_, true);
2572     Color bgColor = pipelineContext_->GetAppBgColor();
2573     std::string bgOpacity = bgColor.ColorToString().substr(0, 3);
2574     std::string transparentOpacity = "#00";
2575     return bgColor == Color::TRANSPARENT || bgOpacity == transparentOpacity;
2576 }
2577 
SetWindowStyle(int32_t instanceId,WindowModal windowModal,ColorScheme colorScheme)2578 void AceContainer::SetWindowStyle(int32_t instanceId, WindowModal windowModal, ColorScheme colorScheme)
2579 {
2580     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
2581     CHECK_NULL_VOID(container);
2582     ContainerScope scope(instanceId);
2583     container->SetWindowModal(windowModal);
2584     container->SetColorScheme(colorScheme);
2585 }
2586 
SetDialogCallback(int32_t instanceId,FrontendDialogCallback callback)2587 void AceContainer::SetDialogCallback(int32_t instanceId, FrontendDialogCallback callback)
2588 {
2589     auto container = AceEngine::Get().GetContainer(instanceId);
2590     CHECK_NULL_VOID(container);
2591     auto front = container->GetFrontend();
2592     if (front && front->GetType() == FrontendType::JS) {
2593         front->SetDialogCallback(callback);
2594     }
2595 }
2596 
RestoreRouterStack(int32_t instanceId,const std::string & contentInfo,ContentInfoType type)2597 std::pair<RouterRecoverRecord, UIContentErrorCode> AceContainer::RestoreRouterStack(
2598     int32_t instanceId, const std::string& contentInfo, ContentInfoType type)
2599 {
2600     auto container = AceEngine::Get().GetContainer(instanceId);
2601     CHECK_NULL_RETURN(container, std::make_pair(RouterRecoverRecord(), UIContentErrorCode::NULL_POINTER));
2602     ContainerScope scope(instanceId);
2603     auto front = container->GetFrontend();
2604     CHECK_NULL_RETURN(front, std::make_pair(RouterRecoverRecord(), UIContentErrorCode::NULL_POINTER));
2605     return front->RestoreRouterStack(contentInfo, type);
2606 }
2607 
GetContentInfo(int32_t instanceId,ContentInfoType type)2608 std::string AceContainer::GetContentInfo(int32_t instanceId, ContentInfoType type)
2609 {
2610     auto container = AceEngine::Get().GetContainer(instanceId);
2611     CHECK_NULL_RETURN(container, "");
2612     ContainerScope scope(instanceId);
2613     auto front = container->GetFrontend();
2614     CHECK_NULL_RETURN(front, "");
2615     return front->GetContentInfo(type);
2616 }
2617 
SetWindowPos(int32_t left,int32_t top)2618 void AceContainer::SetWindowPos(int32_t left, int32_t top)
2619 {
2620     CHECK_NULL_VOID(frontend_);
2621     auto accessibilityManager = frontend_->GetAccessibilityManager();
2622     CHECK_NULL_VOID(accessibilityManager);
2623     accessibilityManager->SetWindowPos(left, top, windowId_);
2624 }
2625 
InitializeSubContainer(int32_t parentContainerId)2626 void AceContainer::InitializeSubContainer(int32_t parentContainerId)
2627 {
2628     auto parentContainer = AceEngine::Get().GetContainer(parentContainerId);
2629     CHECK_NULL_VOID(parentContainer);
2630     auto taskExec = parentContainer->GetTaskExecutor();
2631     taskExecutor_ = AceType::DynamicCast<TaskExecutorImpl>(std::move(taskExec));
2632     auto parentSettings = parentContainer->GetSettings();
2633     GetSettings().useUIAsJSThread = parentSettings.useUIAsJSThread;
2634     GetSettings().usePlatformAsUIThread = parentSettings.usePlatformAsUIThread;
2635     GetSettings().usingSharedRuntime = parentSettings.usingSharedRuntime;
2636 }
2637 
InitWindowCallback()2638 void AceContainer::InitWindowCallback()
2639 {
2640     if (!pipelineContext_ || !uiWindow_) {
2641         return;
2642     }
2643     auto& windowManager = pipelineContext_->GetWindowManager();
2644     std::shared_ptr<AppExecFwk::AbilityInfo> info = abilityInfo_.lock();
2645     if (info != nullptr) {
2646         windowManager->SetAppLabelId(info->labelId);
2647         windowManager->SetAppIconId(info->iconId);
2648     }
2649     windowManager->SetWindowMinimizeCallBack([window = uiWindow_]() { window->Minimize(); });
2650     windowManager->SetWindowMaximizeCallBack([window = uiWindow_]() { window->Maximize(); });
2651     windowManager->SetWindowMaximizeFloatingCallBack([window = uiWindow_]() { window->MaximizeFloating(); });
2652     windowManager->SetWindowRecoverCallBack([window = uiWindow_]() { window->Recover(); });
2653     windowManager->SetWindowCloseCallBack([window = uiWindow_]() { window->Close(); });
2654     windowManager->SetWindowStartMoveCallBack([window = uiWindow_]() { window->StartMove(); });
2655     windowManager->SetPerformBackCallback([window = uiWindow_]() { window->PerformBack(); });
2656     windowManager->SetWindowIsStartMovingCallBack(
2657         [window = uiWindow_]() -> bool { return static_cast<bool>(window->IsStartMoving()); });
2658     windowManager->SetWindowSplitPrimaryCallBack(
2659         [window = uiWindow_]() { window->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_SPLIT_PRIMARY); });
2660     windowManager->SetWindowSplitSecondaryCallBack(
2661         [window = uiWindow_]() { window->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_SPLIT_SECONDARY); });
2662     windowManager->SetWindowGetModeCallBack(
2663         [window = uiWindow_]() -> WindowMode { return static_cast<WindowMode>(window->GetWindowMode()); });
2664     windowManager->SetWindowGetIsMidSceneCallBack([window = uiWindow_](bool& isMidScene) -> int32_t {
2665         return static_cast<int32_t>(window->GetIsMidScene(isMidScene));
2666     });
2667     windowManager->SetWindowGetTypeCallBack(
2668         [window = uiWindow_]() -> WindowType { return static_cast<WindowType>(window->GetType()); });
2669     windowManager->SetWindowSetMaximizeModeCallBack([window = uiWindow_](MaximizeMode mode) {
2670         window->SetGlobalMaximizeMode(static_cast<Rosen::MaximizeMode>(mode));
2671     });
2672     windowManager->SetWindowGetMaximizeModeCallBack(
2673         [window = uiWindow_]() -> MaximizeMode { return static_cast<MaximizeMode>(window->GetGlobalMaximizeMode()); });
2674     windowManager->SetGetSystemBarStyleCallBack([window = uiWindow_]() -> RefPtr<SystemBarStyle> {
2675         return SystemBarStyleOhos::GetCurrentSystemBarStyle(window);
2676     });
2677     windowManager->SetSetSystemBarStyleCallBack([window = uiWindow_](const RefPtr<SystemBarStyle>& style) {
2678         SystemBarStyleOhos::SetSystemBarStyle(window, style);
2679     });
2680     windowManager->SetGetFreeMultiWindowModeEnabledStateCallback(
2681         [window = uiWindow_]() -> bool { return window->GetFreeMultiWindowModeEnabledState(); });
2682     windowManager->SetWindowCallNativeCallback([window = uiWindow_](const std::string& name, const std::string& value) {
2683         window->OnContainerModalEvent(name, value);
2684     });
2685     pipelineContext_->SetGetWindowRectImpl([window = uiWindow_]() -> Rect {
2686         Rect rect;
2687         CHECK_NULL_RETURN(window, rect);
2688         auto windowRect = window->GetRect();
2689         rect.SetRect(windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_);
2690         return rect;
2691     });
2692 }
2693 
GetViewSafeAreaByType(OHOS::Rosen::AvoidAreaType type,std::optional<NG::RectF> windowRect)2694 NG::SafeAreaInsets AceContainer::GetViewSafeAreaByType(
2695     OHOS::Rosen::AvoidAreaType type, std::optional<NG::RectF> windowRect)
2696 {
2697     CHECK_NULL_RETURN(uiWindow_, {});
2698     Rosen::AvoidArea avoidArea;
2699     Rosen::WMError ret;
2700     if (windowRect.has_value()) {
2701         auto rect = windowRect.value();
2702         Rosen::Rect rosenRect = { static_cast<int32_t>(rect.GetX()), static_cast<int32_t>(rect.GetY()),
2703             static_cast<uint32_t>(rect.Width()), static_cast<uint32_t>(rect.Height()) };
2704         ret = uiWindow_->GetAvoidAreaByType(type, avoidArea, rosenRect);
2705     } else {
2706         ret = uiWindow_->GetAvoidAreaByType(type, avoidArea);
2707     }
2708     if (ret == Rosen::WMError::WM_OK) {
2709         auto safeAreaInsets = ConvertAvoidArea(avoidArea);
2710         TAG_LOGI(ACE_LAYOUT, "SafeArea get success, area type is:%{public}d insets area is:%{public}s",
2711             static_cast<int32_t>(type), safeAreaInsets.ToString().c_str());
2712         return safeAreaInsets;
2713     }
2714     return {};
2715 }
2716 
GetKeyboardSafeArea()2717 NG::SafeAreaInsets AceContainer::GetKeyboardSafeArea()
2718 {
2719     CHECK_NULL_RETURN(uiWindow_, {});
2720     Rosen::AvoidArea avoidArea;
2721     Rosen::WMError ret = uiWindow_->GetAvoidAreaByType(Rosen::AvoidAreaType::TYPE_KEYBOARD, avoidArea);
2722     if (ret == Rosen::WMError::WM_OK) {
2723         return ConvertAvoidArea(avoidArea);
2724     }
2725     return {};
2726 }
2727 
GetAvoidAreaByType(Rosen::AvoidAreaType type,int32_t apiVersion)2728 Rosen::AvoidArea AceContainer::GetAvoidAreaByType(Rosen::AvoidAreaType type, int32_t apiVersion)
2729 {
2730     CHECK_NULL_RETURN(uiWindow_, {});
2731     Rosen::AvoidArea avoidArea;
2732     Rosen::Rect rect;
2733     Rosen::WMError ret = uiWindow_->GetAvoidAreaByType(type, avoidArea, rect, apiVersion);
2734     if (ret == Rosen::WMError::WM_OK) {
2735         return avoidArea;
2736     }
2737     return {};
2738 }
2739 
GetStatusBarHeight()2740 uint32_t AceContainer::GetStatusBarHeight()
2741 {
2742     CHECK_NULL_RETURN(uiWindow_, 0);
2743     return static_cast<uint32_t>(uiWindow_->GetStatusBarHeight());
2744 }
2745 
GetAbilityContextByModule(const std::string & bundle,const std::string & module)2746 std::shared_ptr<OHOS::AbilityRuntime::Context> AceContainer::GetAbilityContextByModule(
2747     const std::string& bundle, const std::string& module)
2748 {
2749     auto context = runtimeContext_.lock();
2750     CHECK_NULL_RETURN(context, nullptr);
2751     if (!isFormRender_ && !bundle.empty() && !module.empty()) {
2752         std::string encode = EncodeBundleAndModule(bundle, module);
2753         if (taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
2754             RecordResAdapter(encode);
2755         } else {
2756             taskExecutor_->PostTask(
2757                 [encode, instanceId = instanceId_]() -> void {
2758                     auto container = AceContainer::GetContainer(instanceId);
2759                     CHECK_NULL_VOID(container);
2760                     container->RecordResAdapter(encode);
2761                 },
2762                 TaskExecutor::TaskType::UI, "ArkUIRecordResAdapter");
2763         }
2764     }
2765     return isFormRender_ ? nullptr : context->CreateModuleContext(bundle, module);
2766 }
2767 
CheckAndSetFontFamily()2768 void AceContainer::CheckAndSetFontFamily()
2769 {
2770     CHECK_NULL_VOID(pipelineContext_);
2771     auto fontManager = pipelineContext_->GetFontManager();
2772     CHECK_NULL_VOID(fontManager);
2773     if (fontManager->IsUseAppCustomFont()) {
2774         return;
2775     }
2776     std::string familyName = "";
2777     std::string path = "/data/themes/a/app";
2778     if (!IsFontFileExistInPath(path)) {
2779         path = "/data/themes/b/app";
2780         if (!IsFontFileExistInPath(path)) {
2781             return;
2782         }
2783     }
2784     path = path.append("/fonts/");
2785     auto fontFamilyNames = GetFontFamilyName(path);
2786     if (fontFamilyNames.empty()) {
2787         return;
2788     }
2789     familyName = fontFamilyNames[0];
2790     std::vector<std::string> fullPath;
2791     for (const auto& fontFamilyName : fontFamilyNames) {
2792         fullPath.push_back(path + fontFamilyName);
2793     }
2794     if (isFormRender_) {
2795         // Resolve garbled characters caused by FRS multi-thread async
2796         std::lock_guard<std::mutex> lock(g_mutexFormRenderFontFamily);
2797         fontManager->SetFontFamily(familyName.c_str(), fullPath);
2798     } else {
2799         fontManager->SetFontFamily(familyName.c_str(), fullPath);
2800     }
2801 }
2802 
SetFontScaleAndWeightScale(int32_t instanceId)2803 void AceContainer::SetFontScaleAndWeightScale(int32_t instanceId)
2804 {
2805     float fontScale = SystemProperties::GetFontScale();
2806     float fontWeightScale = SystemProperties::GetFontWeightScale();
2807     Container::SetFontScale(instanceId, fontScale);
2808     Container::SetFontWeightScale(instanceId, fontWeightScale);
2809 }
2810 
SetFontScaleAndWeightScale(const ParsedConfig & parsedConfig,ConfigurationChange & configurationChange)2811 void AceContainer::SetFontScaleAndWeightScale(
2812     const ParsedConfig& parsedConfig, ConfigurationChange& configurationChange)
2813 {
2814     if (!parsedConfig.fontScale.empty()) {
2815         TAG_LOGD(AceLogTag::ACE_FONT, "parsedConfig fontScale: %{public}s", parsedConfig.fontScale.c_str());
2816         CHECK_NULL_VOID(pipelineContext_);
2817         float fontSizeScale = StringUtils::StringToFloat(parsedConfig.fontScale);
2818         if (fontSizeScale != pipelineContext_->GetFontScale()) {
2819             SetFontScale(instanceId_, fontSizeScale);
2820             configurationChange.fontScaleUpdate = true;
2821         }
2822     }
2823     if (!parsedConfig.fontWeightScale.empty()) {
2824         TAG_LOGD(AceLogTag::ACE_FONT, "parsedConfig fontWeightScale: %{public}s", parsedConfig.fontWeightScale.c_str());
2825         CHECK_NULL_VOID(pipelineContext_);
2826         float fontWeightScale = StringUtils::StringToFloat(parsedConfig.fontWeightScale);
2827         if (fontWeightScale != pipelineContext_->GetFontWeightScale()) {
2828             SetFontWeightScale(instanceId_, fontWeightScale);
2829             configurationChange.fontWeightScaleUpdate = true;
2830         }
2831     }
2832 }
2833 
ReleaseResourceAdapter()2834 void AceContainer::ReleaseResourceAdapter()
2835 {
2836     for (auto& encode : resAdapterRecord_) {
2837         std::string bundleName;
2838         std::string moduleName;
2839         DecodeBundleAndModule(encode, bundleName, moduleName);
2840         ResourceManager::GetInstance().RemoveResourceAdapter(bundleName, moduleName, instanceId_);
2841     }
2842     resAdapterRecord_.clear();
2843 
2844     if (isFormRender_) {
2845         auto runtimeContext = runtimeContext_.lock();
2846         if (runtimeContext) {
2847             auto bundleName = runtimeContext->GetBundleName();
2848             auto moduleName = runtimeContext->GetHapModuleInfo()->name;
2849             ResourceManager::GetInstance().RemoveResourceAdapter(bundleName, moduleName, instanceId_);
2850         }
2851     }
2852 }
2853 
ProcessDirectionUpdate(const ParsedConfig & parsedConfig,ConfigurationChange & configurationChange)2854 DeviceOrientation AceContainer::ProcessDirectionUpdate(
2855     const ParsedConfig& parsedConfig, ConfigurationChange& configurationChange)
2856 {
2857     if (!parsedConfig.direction.empty()) {
2858         auto resDirection = DeviceOrientation::ORIENTATION_UNDEFINED;
2859         if (parsedConfig.direction == "horizontal") {
2860             resDirection = DeviceOrientation::LANDSCAPE;
2861         } else if (parsedConfig.direction == "vertical") {
2862             resDirection = DeviceOrientation::PORTRAIT;
2863         }
2864         configurationChange.directionUpdate = true;
2865         return resDirection;
2866     }
2867     return DeviceOrientation::ORIENTATION_UNDEFINED;
2868 }
2869 
ProcessThemeUpdate(const ParsedConfig & parsedConfig,ConfigurationChange & configurationChange)2870 void AceContainer::ProcessThemeUpdate(const ParsedConfig& parsedConfig, ConfigurationChange& configurationChange)
2871 {
2872     if (!parsedConfig.themeTag.empty()) {
2873         std::unique_ptr<JsonValue> json = JsonUtil::ParseJsonString(parsedConfig.themeTag);
2874         int fontUpdate = json->GetInt("fonts");
2875         configurationChange.fontUpdate = configurationChange.fontUpdate || fontUpdate;
2876         int iconUpdate = json->GetInt("icons");
2877         configurationChange.iconUpdate = iconUpdate;
2878         int skinUpdate = json->GetInt("skin");
2879         configurationChange.skinUpdate = skinUpdate;
2880         if ((isDynamicRender_ || isFormRender_) && fontUpdate) {
2881             CheckAndSetFontFamily();
2882         }
2883     }
2884 }
2885 
BuildResConfig(ResourceConfiguration & resConfig,ConfigurationChange & configurationChange,const ParsedConfig & parsedConfig)2886 void AceContainer::BuildResConfig(
2887     ResourceConfiguration& resConfig, ConfigurationChange& configurationChange, const ParsedConfig& parsedConfig)
2888 {
2889     if (!parsedConfig.colorMode.empty()) {
2890         ProcessColorModeUpdate(resConfig, configurationChange, parsedConfig);
2891     }
2892     if (!parsedConfig.deviceAccess.empty()) {
2893         // Event of accessing mouse or keyboard
2894         SystemProperties::SetDeviceAccess(parsedConfig.deviceAccess == "true");
2895         resConfig.SetDeviceAccess(parsedConfig.deviceAccess == "true");
2896     }
2897     if (!parsedConfig.languageTag.empty()) {
2898         ParseLanguage(configurationChange, parsedConfig.languageTag);
2899         resConfig.SetLanguage(parsedConfig.languageTag);
2900     }
2901     if (!parsedConfig.fontFamily.empty()) {
2902         auto fontManager = pipelineContext_->GetFontManager();
2903         CHECK_NULL_VOID(fontManager);
2904         configurationChange.fontUpdate = true;
2905         fontManager->SetAppCustomFont(parsedConfig.fontFamily);
2906     }
2907     if (!parsedConfig.direction.empty()) {
2908         resConfig.SetOrientation(ProcessDirectionUpdate(parsedConfig, configurationChange));
2909     }
2910     if (!parsedConfig.densitydpi.empty()) {
2911         configurationChange.dpiUpdate = true;
2912     }
2913     ProcessThemeUpdate(parsedConfig, configurationChange);
2914     if (!parsedConfig.colorModeIsSetByApp.empty()) {
2915         resConfig.SetColorModeIsSetByApp(true);
2916     }
2917     if (!parsedConfig.mcc.empty()) {
2918         resConfig.SetMcc(StringUtils::StringToUint(parsedConfig.mcc));
2919     }
2920     if (!parsedConfig.mnc.empty()) {
2921         resConfig.SetMnc(StringUtils::StringToUint(parsedConfig.mnc));
2922     }
2923 }
2924 
ProcessColorModeUpdate(ResourceConfiguration & resConfig,ConfigurationChange & configurationChange,const ParsedConfig & parsedConfig)2925 void AceContainer::ProcessColorModeUpdate(
2926     ResourceConfiguration& resConfig, ConfigurationChange& configurationChange, const ParsedConfig& parsedConfig)
2927 {
2928     configurationChange.colorModeUpdate = true;
2929     // clear cache of ark theme instances when configuration updates
2930     NG::TokenThemeStorage::GetInstance()->CacheClear();
2931     if (parsedConfig.colorMode == "dark") {
2932         SetColorMode(ColorMode::DARK);
2933         SetColorScheme(ColorScheme::SCHEME_DARK);
2934         resConfig.SetColorMode(ColorMode::DARK);
2935     } else {
2936         SetColorMode(ColorMode::LIGHT);
2937         SetColorScheme(ColorScheme::SCHEME_LIGHT);
2938         resConfig.SetColorMode(ColorMode::LIGHT);
2939     }
2940 }
2941 
UpdateConfiguration(const ParsedConfig & parsedConfig,const std::string & configuration,bool abilityLevel)2942 void AceContainer::UpdateConfiguration(
2943     const ParsedConfig& parsedConfig, const std::string& configuration, bool abilityLevel)
2944 {
2945     if (!parsedConfig.IsValid()) {
2946         LOGW("AceContainer::OnConfigurationUpdated param is empty");
2947         return;
2948     }
2949     ConfigurationChange configurationChange;
2950     CHECK_NULL_VOID(pipelineContext_);
2951     auto themeManager = pipelineContext_->GetThemeManager();
2952     CHECK_NULL_VOID(themeManager);
2953     auto resConfig = GetResourceConfiguration();
2954     BuildResConfig(resConfig, configurationChange, parsedConfig);
2955     if (!parsedConfig.preferredLanguage.empty()) {
2956         ParseLanguage(configurationChange, parsedConfig.preferredLanguage);
2957         resConfig.SetPreferredLanguage(parsedConfig.preferredLanguage);
2958     }
2959     // The density of sub windows neds to be consistent with the main window.
2960     if (instanceId_ >= MIN_SUBCONTAINER_ID) {
2961         auto parentContainer = Platform::AceContainer::GetContainer(GetParentId());
2962         CHECK_NULL_VOID(parentContainer);
2963         auto parentPipeline = parentContainer->GetPipelineContext();
2964         CHECK_NULL_VOID(parentPipeline);
2965         resConfig.SetDensity(parentPipeline->GetDensity());
2966     }
2967     SetFontScaleAndWeightScale(parsedConfig, configurationChange);
2968     SetResourceConfiguration(resConfig);
2969     if (!abilityLevel) {
2970         themeManager->UpdateConfig(resConfig);
2971         if (SystemProperties::GetResourceDecoupling()) {
2972             ResourceManager::GetInstance().UpdateResourceConfig(resConfig, !parsedConfig.themeTag.empty());
2973         }
2974     }
2975     themeManager->LoadResourceThemes();
2976     auto front = GetFrontend();
2977     CHECK_NULL_VOID(front);
2978     if (!configurationChange.directionUpdate && !configurationChange.dpiUpdate) {
2979         front->OnConfigurationUpdated(configuration);
2980     }
2981 #ifdef PLUGIN_COMPONENT_SUPPORTED
2982     if (configurationChange.IsNeedUpdate()) {
2983         OHOS::Ace::PluginManager::GetInstance().UpdateConfigurationInPlugin(resConfig, taskExecutor_);
2984     }
2985 #endif
2986     NotifyConfigurationChange(!parsedConfig.deviceAccess.empty(), configurationChange);
2987     NotifyConfigToSubContainers(parsedConfig, configuration);
2988     // change color mode and theme to clear image cache
2989     pipelineContext_->ClearImageCache();
2990 }
2991 
UpdateConfigurationSyncForAll(const ParsedConfig & parsedConfig,const std::string & configuration)2992 void AceContainer::UpdateConfigurationSyncForAll(const ParsedConfig& parsedConfig, const std::string& configuration)
2993 {
2994     if (!parsedConfig.IsValid()) {
2995         LOGW("AceContainer::OnConfigurationUpdated param is empty");
2996         return;
2997     }
2998 
2999     if (!parsedConfig.fontId.empty()) {
3000         CheckAndSetFontFamily();
3001     }
3002 }
3003 
NotifyConfigToSubContainers(const ParsedConfig & parsedConfig,const std::string & configuration)3004 void AceContainer::NotifyConfigToSubContainers(const ParsedConfig& parsedConfig, const std::string& configuration)
3005 {
3006     for (auto& item : configurationChangedCallbacks_) {
3007         if (item.second) {
3008             item.second(parsedConfig, configuration);
3009         }
3010     }
3011 }
3012 
NotifyConfigurationChange(bool needReloadTransition,const ConfigurationChange & configurationChange)3013 void AceContainer::NotifyConfigurationChange(bool needReloadTransition, const ConfigurationChange& configurationChange)
3014 {
3015     auto taskExecutor = GetTaskExecutor();
3016     CHECK_NULL_VOID(taskExecutor);
3017     taskExecutor->PostTask(
3018         [instanceId = instanceId_, weak = WeakClaim(this), needReloadTransition, configurationChange]() {
3019             ContainerScope scope(instanceId);
3020             auto container = weak.Upgrade();
3021             CHECK_NULL_VOID(container);
3022             auto frontend = container->GetFrontend();
3023             if (frontend) {
3024                 LOGI("AceContainer UpdateConfiguration frontend MarkNeedUpdate");
3025                 frontend->FlushReload();
3026             }
3027             auto taskExecutor = container->GetTaskExecutor();
3028             CHECK_NULL_VOID(taskExecutor);
3029             taskExecutor->PostTask(
3030                 [instanceId, weak, needReloadTransition, configurationChange]() {
3031                     ContainerScope scope(instanceId);
3032                     auto container = weak.Upgrade();
3033                     CHECK_NULL_VOID(container);
3034                     auto pipeline = container->GetPipelineContext();
3035                     CHECK_NULL_VOID(pipeline);
3036                     auto themeManager = pipeline->GetThemeManager();
3037                     CHECK_NULL_VOID(themeManager);
3038                     if (configurationChange.directionUpdate &&
3039                         (themeManager->GetResourceLimitKeys() & DIRECTION_KEY) == 0) {
3040                         return;
3041                     }
3042                     if (configurationChange.colorModeUpdate && !container->IsUseCustomBg() &&
3043                         !container->IsTransparentBg()) {
3044                         pipeline->SetAppBgColor(themeManager->GetBackgroundColor());
3045                     }
3046                     pipeline->NotifyConfigurationChange();
3047                     pipeline->FlushReload(configurationChange);
3048                     if (needReloadTransition) {
3049                         // reload transition animation
3050                         pipeline->FlushReloadTransition();
3051                     }
3052                     pipeline->ChangeDarkModeBrightness();
3053                 },
3054                 TaskExecutor::TaskType::UI, "ArkUIFlushReloadTransition");
3055         },
3056         TaskExecutor::TaskType::JS, "ArkUINotifyConfigurationChange");
3057 }
3058 
HotReload()3059 void AceContainer::HotReload()
3060 {
3061     auto taskExecutor = GetTaskExecutor();
3062     CHECK_NULL_VOID(taskExecutor);
3063     taskExecutor->PostTask(
3064         [instanceId = instanceId_, weak = WeakClaim(this)]() {
3065             ContainerScope scope(instanceId);
3066             auto container = weak.Upgrade();
3067             CHECK_NULL_VOID(container);
3068             auto frontend = container->GetFrontend();
3069             CHECK_NULL_VOID(frontend);
3070             LOGI("AceContainer Flush Frontend for HotReload");
3071             frontend->HotReload();
3072 
3073             auto pipeline = container->GetPipelineContext();
3074             CHECK_NULL_VOID(pipeline);
3075             ConfigurationChange configurationChange { .hotReloadUpdate = true };
3076             pipeline->FlushReload(configurationChange);
3077         },
3078         TaskExecutor::TaskType::UI, "ArkUIHotReload");
3079 }
3080 
SetToken(sptr<IRemoteObject> & token)3081 void AceContainer::SetToken(sptr<IRemoteObject>& token)
3082 {
3083     std::lock_guard<std::mutex> lock(cardTokensMutex_);
3084     if (token) {
3085         token_ = token;
3086     }
3087 }
3088 
GetToken()3089 sptr<IRemoteObject> AceContainer::GetToken()
3090 {
3091     std::lock_guard<std::mutex> lock(cardTokensMutex_);
3092     if (token_) {
3093         return token_;
3094     }
3095     LOGE("fail to get Token");
3096     return nullptr;
3097 }
3098 
SetParentToken(sptr<IRemoteObject> & token)3099 void AceContainer::SetParentToken(sptr<IRemoteObject>& token)
3100 {
3101     std::lock_guard<std::mutex> lock(cardTokensMutex_);
3102     if (token) {
3103         parentToken_ = token;
3104     }
3105 }
3106 
GetParentToken()3107 sptr<IRemoteObject> AceContainer::GetParentToken()
3108 {
3109     std::lock_guard<std::mutex> lock(cardTokensMutex_);
3110     return parentToken_;
3111 }
3112 
3113 // ArkTsCard start
GetFormSurfaceNode(int32_t instanceId)3114 std::shared_ptr<Rosen::RSSurfaceNode> AceContainer::GetFormSurfaceNode(int32_t instanceId)
3115 {
3116     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
3117     CHECK_NULL_RETURN(container, nullptr);
3118     auto context = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
3119     CHECK_NULL_RETURN(context, nullptr);
3120     auto window = static_cast<FormRenderWindow*>(context->GetWindow());
3121     CHECK_NULL_RETURN(window, nullptr);
3122     return window->GetRSSurfaceNode();
3123 }
3124 
UpdateFormData(const std::string & data)3125 void AceContainer::UpdateFormData(const std::string& data)
3126 {
3127 #ifdef FORM_SUPPORTED
3128     auto frontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
3129     CHECK_NULL_VOID(frontend);
3130     frontend->UpdateData(data);
3131 #endif
3132 }
3133 
UpdateFormSharedImage(const std::map<std::string,sptr<AppExecFwk::FormAshmem>> & imageDataMap)3134 void AceContainer::UpdateFormSharedImage(const std::map<std::string, sptr<AppExecFwk::FormAshmem>>& imageDataMap)
3135 {
3136     std::vector<std::string> picNameArray;
3137     std::vector<int> fileDescriptorArray;
3138     std::vector<int> byteLenArray;
3139     if (!imageDataMap.empty()) {
3140         for (auto& imageData : imageDataMap) {
3141             picNameArray.push_back(imageData.first);
3142             fileDescriptorArray.push_back(imageData.second->GetAshmemFd());
3143             byteLenArray.push_back(imageData.second->GetAshmemSize());
3144         }
3145         GetNamesOfSharedImage(picNameArray);
3146         UpdateSharedImage(picNameArray, byteLenArray, fileDescriptorArray);
3147     }
3148 }
3149 
UpdateResource()3150 void AceContainer::UpdateResource()
3151 {
3152     // Reload theme and resource
3153     CHECK_NULL_VOID(pipelineContext_);
3154 
3155     if (SystemProperties::GetResourceDecoupling()) {
3156         auto context = runtimeContext_.lock();
3157         auto abilityInfo = abilityInfo_.lock();
3158         if (pipelineContext_->IsFormRender()) {
3159             ReleaseResourceAdapter();
3160         }
3161         InitResourceAndThemeManager(
3162             pipelineContext_, assetManager_, colorScheme_, resourceInfo_, context, abilityInfo, true);
3163     } else {
3164         ThemeConstants::InitDeviceType();
3165         auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>();
3166         pipelineContext_->SetThemeManager(themeManager);
3167         themeManager->InitResource(resourceInfo_);
3168         themeManager->SetColorScheme(colorScheme_);
3169         themeManager->LoadCustomTheme(assetManager_);
3170         themeManager->LoadResourceThemes();
3171     }
3172 
3173     auto cache = pipelineContext_->GetImageCache();
3174     if (cache) {
3175         cache->Clear();
3176     }
3177 }
3178 
GetNamesOfSharedImage(std::vector<std::string> & picNameArray)3179 void AceContainer::GetNamesOfSharedImage(std::vector<std::string>& picNameArray)
3180 {
3181     if (picNameArray.empty()) {
3182         LOGE("picNameArray is null!");
3183         return;
3184     }
3185     auto context = AceType::DynamicCast<NG::PipelineContext>(GetPipelineContext());
3186     CHECK_NULL_VOID(context);
3187     auto sharedImageManager = context->GetOrCreateSharedImageManager();
3188     auto nameSize = picNameArray.size();
3189     for (uint32_t i = 0; i < nameSize; i++) {
3190         // get name of picture
3191         auto name = picNameArray[i];
3192         sharedImageManager->AddPictureNamesToReloadMap(std::move(name));
3193     }
3194 }
3195 
UpdateSharedImage(std::vector<std::string> & picNameArray,std::vector<int32_t> & byteLenArray,std::vector<int> & fileDescriptorArray)3196 void AceContainer::UpdateSharedImage(
3197     std::vector<std::string>& picNameArray, std::vector<int32_t>& byteLenArray, std::vector<int>& fileDescriptorArray)
3198 {
3199     auto context = GetPipelineContext();
3200     CHECK_NULL_VOID(context);
3201     if (picNameArray.empty() || byteLenArray.empty() || fileDescriptorArray.empty()) {
3202         LOGE("array is null! when try UpdateSharedImage");
3203         return;
3204     }
3205     auto nameArraySize = picNameArray.size();
3206     if (nameArraySize != byteLenArray.size()) {
3207         LOGE("nameArraySize does not equal to fileDescriptorArraySize, please check!");
3208         return;
3209     }
3210     if (nameArraySize != fileDescriptorArray.size()) {
3211         LOGE("nameArraySize does not equal to fileDescriptorArraySize, please check!");
3212         return;
3213     }
3214     // now it can be assured that all three arrays are of the same size
3215 
3216     std::string picNameCopy;
3217     for (uint32_t i = 0; i < nameArraySize; i++) {
3218         // get name of picture
3219         auto picName = picNameArray[i];
3220         // save a copy of picName and ReleaseStringUTFChars immediately to avoid memory leak
3221         picNameCopy = picName;
3222 
3223         // get fd ID
3224         auto fd = fileDescriptorArray[i];
3225 
3226         auto newFd = dup(fd);
3227         if (newFd < 0) {
3228             LOGE("dup fd fail, fail reason: %{public}s, fd: %{public}d, picName: %{private}s, length: %{public}d",
3229                 strerror(errno), fd, picNameCopy.c_str(), byteLenArray[i]);
3230             continue;
3231         }
3232 
3233         auto ashmem = Ashmem(newFd, byteLenArray[i]);
3234         GetImageDataFromAshmem(picNameCopy, ashmem, context, byteLenArray[i]);
3235         ashmem.UnmapAshmem();
3236         ashmem.CloseAshmem();
3237     }
3238 }
3239 
GetImageDataFromAshmem(const std::string & picName,Ashmem & ashmem,const RefPtr<PipelineBase> & pipelineContext,int len)3240 void AceContainer::GetImageDataFromAshmem(
3241     const std::string& picName, Ashmem& ashmem, const RefPtr<PipelineBase>& pipelineContext, int len)
3242 {
3243     bool ret = ashmem.MapReadOnlyAshmem();
3244     // if any exception causes a [return] before [AddSharedImage], the memory image will not show because [RenderImage]
3245     // will never be notified to start loading.
3246     if (!ret) {
3247         LOGE("MapReadOnlyAshmem fail, fail reason: %{public}s, picName: %{private}s, length: %{public}d, "
3248              "fd: %{public}d",
3249             strerror(errno), picName.c_str(), len, ashmem.GetAshmemFd());
3250         return;
3251     }
3252     const uint8_t* imageData = reinterpret_cast<const uint8_t*>(ashmem.ReadFromAshmem(len, 0));
3253     if (imageData == nullptr) {
3254         LOGE("imageData is nullptr, errno is: %{public}s, picName: %{private}s, length: %{public}d, fd: %{public}d",
3255             strerror(errno), picName.c_str(), len, ashmem.GetAshmemFd());
3256         return;
3257     }
3258     auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3259     CHECK_NULL_VOID(context);
3260     RefPtr<SharedImageManager> sharedImageManager = context->GetOrCreateSharedImageManager();
3261     if (sharedImageManager) {
3262         // read image data from shared memory and save a copy to sharedImageManager
3263         sharedImageManager->AddSharedImage(picName, std::vector<uint8_t>(imageData, imageData + len));
3264     }
3265 }
3266 
IsScenceBoardWindow()3267 bool AceContainer::IsScenceBoardWindow()
3268 {
3269     CHECK_NULL_RETURN(uiWindow_, false);
3270     return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_SCENE_BOARD;
3271 }
3272 
IsCrossAxisWindow()3273 bool AceContainer::IsCrossAxisWindow()
3274 {
3275     CHECK_NULL_RETURN(uiWindow_, false);
3276     return uiWindow_->GetCrossAxisState() == Rosen::CrossAxisState::STATE_CROSS;
3277 }
3278 
IsUIExtensionWindow()3279 bool AceContainer::IsUIExtensionWindow()
3280 {
3281     CHECK_NULL_RETURN(uiWindow_, false);
3282     return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_UI_EXTENSION;
3283 }
3284 
FireUIExtensionEventCallback(uint32_t eventId)3285 void AceContainer::FireUIExtensionEventCallback(uint32_t eventId)
3286 {
3287     if (!IsUIExtensionWindow()) {
3288         return;
3289     }
3290     ACE_SCOPED_TRACE("FireUIExtensionEventCallback event[%u]", eventId);
3291     uiWindow_->NotifyExtensionEventAsync(eventId);
3292 }
3293 
IsSceneBoardEnabled()3294 bool AceContainer::IsSceneBoardEnabled()
3295 {
3296     return Rosen::SceneBoardJudgement::IsSceneBoardEnabled();
3297 }
3298 // ArkTsCard end
3299 
IsMainWindow() const3300 bool AceContainer::IsMainWindow() const
3301 {
3302     CHECK_NULL_RETURN(uiWindow_, false);
3303     return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_APP_MAIN_WINDOW;
3304 }
3305 
IsSubWindow() const3306 bool AceContainer::IsSubWindow() const
3307 {
3308     CHECK_NULL_RETURN(uiWindow_, false);
3309     return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW;
3310 }
3311 
IsDialogWindow() const3312 bool AceContainer::IsDialogWindow() const
3313 {
3314     CHECK_NULL_RETURN(uiWindow_, false);
3315     return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_DIALOG;
3316 }
3317 
IsSystemWindow() const3318 bool AceContainer::IsSystemWindow() const
3319 {
3320     CHECK_NULL_RETURN(uiWindow_, false);
3321     return uiWindow_->GetType() >= Rosen::WindowType::ABOVE_APP_SYSTEM_WINDOW_BASE &&
3322            uiWindow_->GetType() <= Rosen::WindowType::ABOVE_APP_SYSTEM_WINDOW_END;
3323 }
3324 
GetParentWindowType() const3325 uint32_t AceContainer::GetParentWindowType() const
3326 {
3327     CHECK_NULL_RETURN(uiWindow_, DEFAULT_WINDOW_TYPE);
3328     return static_cast<uint32_t>(uiWindow_->GetParentWindowType());
3329 }
3330 
GetWindowType() const3331 uint32_t AceContainer::GetWindowType() const
3332 {
3333     CHECK_NULL_RETURN(uiWindow_, DEFAULT_WINDOW_TYPE);
3334     return static_cast<uint32_t>(uiWindow_->GetType());
3335 }
3336 
IsHostMainWindow() const3337 bool AceContainer::IsHostMainWindow() const
3338 {
3339     CHECK_NULL_RETURN(uiWindow_, false);
3340     return uiWindow_->GetParentWindowType() == Rosen::WindowType::WINDOW_TYPE_APP_MAIN_WINDOW;
3341 }
3342 
IsHostSubWindow() const3343 bool AceContainer::IsHostSubWindow() const
3344 {
3345     CHECK_NULL_RETURN(uiWindow_, false);
3346     return uiWindow_->GetParentWindowType() == Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW;
3347 }
3348 
IsHostDialogWindow() const3349 bool AceContainer::IsHostDialogWindow() const
3350 {
3351     CHECK_NULL_RETURN(uiWindow_, false);
3352     return uiWindow_->GetParentWindowType() == Rosen::WindowType::WINDOW_TYPE_DIALOG;
3353 }
3354 
IsHostSystemWindow() const3355 bool AceContainer::IsHostSystemWindow() const
3356 {
3357     CHECK_NULL_RETURN(uiWindow_, false);
3358     return uiWindow_->GetParentWindowType() >= Rosen::WindowType::ABOVE_APP_SYSTEM_WINDOW_BASE &&
3359            uiWindow_->GetParentWindowType() <= Rosen::WindowType::ABOVE_APP_SYSTEM_WINDOW_END;
3360 }
3361 
IsHostSceneBoardWindow() const3362 bool AceContainer::IsHostSceneBoardWindow() const
3363 {
3364     CHECK_NULL_RETURN(uiWindow_, false);
3365     return uiWindow_->GetParentWindowType() == Rosen::WindowType::WINDOW_TYPE_SCENE_BOARD;
3366 }
3367 
GetParentMainWindowId(uint32_t currentWindowId) const3368 uint32_t AceContainer::GetParentMainWindowId(uint32_t currentWindowId) const
3369 {
3370     uint32_t parentMainWindowId = 0;
3371     if (uiWindow_) {
3372         parentMainWindowId = uiWindow_->GetParentMainWindowId(currentWindowId);
3373         if (parentMainWindowId == 0) {
3374             TAG_LOGE(AceLogTag::ACE_SUB_WINDOW,
3375                 "GetParentMainWindowId, current windowId: %{public}d, main windowId: %{public}d", currentWindowId,
3376                 parentMainWindowId);
3377         }
3378     } else {
3379         TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "Window in container is nullptr when getting main windowId");
3380     }
3381     return parentMainWindowId;
3382 }
3383 
SetCurPointerEvent(const std::shared_ptr<MMI::PointerEvent> & currentEvent)3384 void AceContainer::SetCurPointerEvent(const std::shared_ptr<MMI::PointerEvent>& currentEvent)
3385 {
3386     std::lock_guard<std::mutex> lock(pointerEventMutex_);
3387     CHECK_NULL_VOID(currentEvent);
3388     currentPointerEvent_ = currentEvent;
3389     auto pointerAction = currentEvent->GetPointerAction();
3390     if (pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW ||
3391         pointerAction == MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW) {
3392         return;
3393     }
3394     MMI::PointerEvent::PointerItem pointerItem;
3395     currentEvent->GetPointerItem(currentEvent->GetPointerId(), pointerItem);
3396     int32_t originId = pointerItem.GetOriginPointerId();
3397     currentEvents_[originId] = currentEvent;
3398     auto callbacksIter = stopDragCallbackMap_.begin();
3399     while (callbacksIter != stopDragCallbackMap_.end()) {
3400         auto pointerId = callbacksIter->first;
3401         MMI::PointerEvent::PointerItem pointerItem;
3402         if (!currentEvent->GetPointerItem(pointerId, pointerItem) || !pointerItem.IsPressed() ||
3403             pointerAction == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
3404             for (const auto& callback : callbacksIter->second) {
3405                 if (callback) {
3406                     callback();
3407                 }
3408             }
3409             callbacksIter = stopDragCallbackMap_.erase(callbacksIter);
3410         } else {
3411             ++callbacksIter;
3412         }
3413     }
3414 }
3415 
GetCurPointerEventInfo(DragPointerEvent & dragPointerEvent,StopDragCallback && stopDragCallback)3416 bool AceContainer::GetCurPointerEventInfo(DragPointerEvent& dragPointerEvent, StopDragCallback&& stopDragCallback)
3417 {
3418     std::lock_guard<std::mutex> lock(pointerEventMutex_);
3419     MMI::PointerEvent::PointerItem pointerItem;
3420     auto iter = currentEvents_.find(dragPointerEvent.pointerId);
3421     if (iter == currentEvents_.end()) {
3422         TAG_LOGW(AceLogTag::ACE_DRAG, "Can not find PointerEvent, pointerId: %{public}d.", dragPointerEvent.pointerId);
3423         return false;
3424     }
3425 
3426     auto currentPointerEvent = iter->second;
3427     CHECK_NULL_RETURN(currentPointerEvent, false);
3428     dragPointerEvent.pointerId = currentPointerEvent->GetPointerId();
3429     if (!currentPointerEvent->GetPointerItem(dragPointerEvent.pointerId, pointerItem)) {
3430         TAG_LOGW(AceLogTag::ACE_DRAG, "Can not find pointerItem, pointerId: %{public}d.", dragPointerEvent.pointerId);
3431         return false;
3432     }
3433     if (!pointerItem.IsPressed()) {
3434         TAG_LOGW(AceLogTag::ACE_DRAG, "Current pointer is not pressed, pointerId: %{public}d.",
3435             dragPointerEvent.pointerId);
3436         return false;
3437     }
3438     dragPointerEvent.sourceType = currentPointerEvent->GetSourceType();
3439     dragPointerEvent.displayX = pointerItem.GetDisplayX();
3440     dragPointerEvent.displayY = pointerItem.GetDisplayY();
3441     dragPointerEvent.windowX = pointerItem.GetWindowX();
3442     dragPointerEvent.windowY = pointerItem.GetWindowY();
3443     dragPointerEvent.deviceId = pointerItem.GetDeviceId();
3444     dragPointerEvent.sourceTool = static_cast<SourceTool>(GetSourceTool(pointerItem.GetToolType()));
3445     dragPointerEvent.displayId = currentPointerEvent->GetTargetDisplayId();
3446     dragPointerEvent.pointerEventId = currentPointerEvent->GetId();
3447     dragPointerEvent.originId = pointerItem.GetOriginPointerId();
3448     RegisterStopDragCallback(dragPointerEvent.pointerId, std::move(stopDragCallback));
3449     return true;
3450 }
3451 
GetCurPointerEventSourceType(int32_t & sourceType)3452 bool AceContainer::GetCurPointerEventSourceType(int32_t& sourceType)
3453 {
3454     std::lock_guard<std::mutex> lock(pointerEventMutex_);
3455     CHECK_NULL_RETURN(currentPointerEvent_, false);
3456     MMI::PointerEvent::PointerItem pointerItem;
3457     sourceType = currentPointerEvent_->GetSourceType();
3458     return true;
3459 }
3460 
RegisterStopDragCallback(int32_t pointerId,StopDragCallback && stopDragCallback)3461 void AceContainer::RegisterStopDragCallback(int32_t pointerId, StopDragCallback&& stopDragCallback)
3462 {
3463     auto iter = stopDragCallbackMap_.find(pointerId);
3464     if (iter != stopDragCallbackMap_.end()) {
3465         iter->second.emplace_back(std::move(stopDragCallback));
3466     } else {
3467         std::list<StopDragCallback> list;
3468         list.emplace_back(std::move(stopDragCallback));
3469         stopDragCallbackMap_.emplace(pointerId, list);
3470     }
3471 }
3472 
GetLastMovingPointerPosition(DragPointerEvent & dragPointerEvent)3473 bool AceContainer::GetLastMovingPointerPosition(DragPointerEvent& dragPointerEvent)
3474 {
3475     std::lock_guard<std::mutex> lock(pointerEventMutex_);
3476     auto iter = currentEvents_.find(dragPointerEvent.originId);
3477     if (iter == currentEvents_.end()) {
3478         return false;
3479     }
3480     MMI::PointerEvent::PointerItem pointerItem;
3481     auto currentPointerEvent = iter->second;
3482     CHECK_NULL_RETURN(currentPointerEvent, false);
3483     if (!currentPointerEvent->GetPointerItem(currentPointerEvent->GetPointerId(), pointerItem) ||
3484         !pointerItem.IsPressed()) {
3485         return false;
3486     }
3487     dragPointerEvent.displayX = pointerItem.GetDisplayX();
3488     dragPointerEvent.displayY = pointerItem.GetDisplayY();
3489     dragPointerEvent.windowX = pointerItem.GetWindowX();
3490     dragPointerEvent.windowY = pointerItem.GetWindowY();
3491     return true;
3492 }
3493 
SearchElementInfoByAccessibilityIdNG(int64_t elementId,int32_t mode,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & output)3494 void AceContainer::SearchElementInfoByAccessibilityIdNG(
3495     int64_t elementId, int32_t mode, int64_t baseParent, std::list<Accessibility::AccessibilityElementInfo>& output)
3496 {
3497     CHECK_NULL_VOID(taskExecutor_);
3498     taskExecutor_->PostSyncTaskTimeout(
3499         [weak = WeakClaim(this), elementId, mode, baseParent, &output]() {
3500             auto container = weak.Upgrade();
3501             CHECK_NULL_VOID(container);
3502             auto pipelineContext = container->GetPipelineContext();
3503             auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3504             CHECK_NULL_VOID(ngPipeline);
3505             auto frontend = container->GetFrontend();
3506             CHECK_NULL_VOID(frontend);
3507             auto accessibilityManager = frontend->GetAccessibilityManager();
3508             CHECK_NULL_VOID(accessibilityManager);
3509             accessibilityManager->SearchElementInfoByAccessibilityIdNG(elementId, mode, output, ngPipeline, baseParent);
3510         },
3511         TaskExecutor::TaskType::UI, SEARCH_ELEMENT_TIMEOUT_TIME, "ArkUISearchElementInfoById");
3512 }
3513 
SearchElementInfosByTextNG(int64_t elementId,const std::string & text,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & output)3514 void AceContainer::SearchElementInfosByTextNG(int64_t elementId, const std::string& text, int64_t baseParent,
3515     std::list<Accessibility::AccessibilityElementInfo>& output)
3516 {
3517     CHECK_NULL_VOID(taskExecutor_);
3518     taskExecutor_->PostSyncTaskTimeout(
3519         [weak = WeakClaim(this), elementId, &text, baseParent, &output]() {
3520             auto container = weak.Upgrade();
3521             CHECK_NULL_VOID(container);
3522             auto pipelineContext = container->GetPipelineContext();
3523             auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3524             CHECK_NULL_VOID(ngPipeline);
3525             auto frontend = container->GetFrontend();
3526             CHECK_NULL_VOID(frontend);
3527             auto accessibilityManager = frontend->GetAccessibilityManager();
3528             CHECK_NULL_VOID(accessibilityManager);
3529             accessibilityManager->SearchElementInfosByTextNG(elementId, text, output, ngPipeline, baseParent);
3530         },
3531         TaskExecutor::TaskType::UI, SEARCH_ELEMENT_TIMEOUT_TIME, "ArkUISearchElementInfoByText");
3532 }
3533 
FindFocusedElementInfoNG(int64_t elementId,int32_t focusType,int64_t baseParent,Accessibility::AccessibilityElementInfo & output)3534 void AceContainer::FindFocusedElementInfoNG(
3535     int64_t elementId, int32_t focusType, int64_t baseParent, Accessibility::AccessibilityElementInfo& output)
3536 {
3537     CHECK_NULL_VOID(taskExecutor_);
3538     taskExecutor_->PostSyncTaskTimeout(
3539         [weak = WeakClaim(this), elementId, focusType, baseParent, &output]() {
3540             auto container = weak.Upgrade();
3541             CHECK_NULL_VOID(container);
3542             auto pipelineContext = container->GetPipelineContext();
3543             auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3544             CHECK_NULL_VOID(ngPipeline);
3545             auto frontend = container->GetFrontend();
3546             CHECK_NULL_VOID(frontend);
3547             auto accessibilityManager = frontend->GetAccessibilityManager();
3548             CHECK_NULL_VOID(accessibilityManager);
3549             accessibilityManager->FindFocusedElementInfoNG(elementId, focusType, output, ngPipeline, baseParent);
3550         },
3551         TaskExecutor::TaskType::UI, SEARCH_ELEMENT_TIMEOUT_TIME, "ArkUIFindFocusedElementInfo");
3552 }
3553 
FocusMoveSearchNG(int64_t elementId,int32_t direction,int64_t baseParent,Accessibility::AccessibilityElementInfo & output)3554 void AceContainer::FocusMoveSearchNG(
3555     int64_t elementId, int32_t direction, int64_t baseParent, Accessibility::AccessibilityElementInfo& output)
3556 {
3557     CHECK_NULL_VOID(taskExecutor_);
3558     taskExecutor_->PostSyncTaskTimeout(
3559         [weak = WeakClaim(this), elementId, direction, baseParent, &output]() {
3560             auto container = weak.Upgrade();
3561             CHECK_NULL_VOID(container);
3562             auto pipelineContext = container->GetPipelineContext();
3563             auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3564             CHECK_NULL_VOID(ngPipeline);
3565             auto frontend = container->GetFrontend();
3566             CHECK_NULL_VOID(frontend);
3567             auto accessibilityManager = frontend->GetAccessibilityManager();
3568             CHECK_NULL_VOID(accessibilityManager);
3569             accessibilityManager->FocusMoveSearchNG(elementId, direction, output, ngPipeline, baseParent);
3570         },
3571         TaskExecutor::TaskType::UI, SEARCH_ELEMENT_TIMEOUT_TIME, "ArkUIFocusMoveSearch");
3572 }
3573 
NotifyExecuteAction(int64_t elementId,const std::map<std::string,std::string> & actionArguments,int32_t action,int64_t offset)3574 bool AceContainer::NotifyExecuteAction(
3575     int64_t elementId, const std::map<std::string, std::string>& actionArguments, int32_t action, int64_t offset)
3576 {
3577     bool IsExecuted = false;
3578     CHECK_NULL_RETURN(taskExecutor_, IsExecuted);
3579     taskExecutor_->PostSyncTaskTimeout(
3580         [weak = WeakClaim(this), elementId, &actionArguments, action, offset, &IsExecuted]() {
3581             auto container = weak.Upgrade();
3582             CHECK_NULL_VOID(container);
3583             auto pipelineContext = container->GetPipelineContext();
3584             auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3585             CHECK_NULL_VOID(ngPipeline);
3586             auto frontend = container->GetFrontend();
3587             CHECK_NULL_VOID(frontend);
3588             auto accessibilityManager = frontend->GetAccessibilityManager();
3589             CHECK_NULL_VOID(accessibilityManager);
3590             IsExecuted =
3591                 accessibilityManager->ExecuteExtensionActionNG(elementId, actionArguments, action, ngPipeline, offset);
3592         },
3593         TaskExecutor::TaskType::UI, SEARCH_ELEMENT_TIMEOUT_TIME, "ArkUIExecuteExtensionAction");
3594     return IsExecuted;
3595 }
3596 
HandleAccessibilityHoverEvent(float pointX,float pointY,int32_t sourceType,int32_t eventType,int64_t timeMs)3597 void AceContainer::HandleAccessibilityHoverEvent(
3598     float pointX, float pointY, int32_t sourceType, int32_t eventType, int64_t timeMs)
3599 {
3600     CHECK_NULL_VOID(taskExecutor_);
3601     taskExecutor_->PostTask(
3602         [weak = WeakClaim(this), pointX, pointY, sourceType, eventType, timeMs] {
3603             auto container = weak.Upgrade();
3604             CHECK_NULL_VOID(container);
3605             ContainerScope scope(container->GetInstanceId());
3606             auto pipelineContext = container->GetPipelineContext();
3607             auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3608             CHECK_NULL_VOID(ngPipeline);
3609             auto root = ngPipeline->GetRootElement();
3610             CHECK_NULL_VOID(root);
3611             auto accessibilityManagerNG = ngPipeline->GetAccessibilityManagerNG();
3612             CHECK_NULL_VOID(accessibilityManagerNG);
3613             accessibilityManagerNG->HandleAccessibilityHoverEvent(root, pointX, pointY, sourceType, eventType, timeMs);
3614         },
3615         TaskExecutor::TaskType::UI, "ArkUIHandleAccessibilityHoverEvent");
3616 }
3617 
FireAccessibilityEventCallback(uint32_t eventId,int64_t parameter)3618 void AceContainer::FireAccessibilityEventCallback(uint32_t eventId, int64_t parameter)
3619 {
3620     CHECK_NULL_VOID(taskExecutor_);
3621     taskExecutor_->PostTask(
3622         [weak = WeakClaim(this), eventId, parameter] {
3623             auto container = weak.Upgrade();
3624             CHECK_NULL_VOID(container);
3625             ContainerScope scope(container->GetInstanceId());
3626             auto pipelineContext = container->GetPipelineContext();
3627             auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3628             CHECK_NULL_VOID(ngPipeline);
3629             auto accessibilityManager = ngPipeline->GetAccessibilityManager();
3630             CHECK_NULL_VOID(accessibilityManager);
3631             accessibilityManager->FireAccessibilityEventCallback(eventId, parameter);
3632         },
3633         TaskExecutor::TaskType::UI, "ArkUIHandleAccessibilityEventCallback");
3634 }
3635 
GetOverlayNodePositions()3636 std::vector<Ace::RectF> AceContainer::GetOverlayNodePositions()
3637 {
3638     auto pipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
3639     CHECK_NULL_RETURN(pipeline, {});
3640     return pipeline->GetOverlayNodePositions();
3641 }
3642 
RegisterOverlayNodePositionsUpdateCallback(const std::function<void (std::vector<Ace::RectF>)> && callback)3643 void AceContainer::RegisterOverlayNodePositionsUpdateCallback(
3644     const std::function<void(std::vector<Ace::RectF>)>&& callback)
3645 {
3646     auto pipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
3647     CHECK_NULL_VOID(pipeline);
3648     pipeline->RegisterOverlayNodePositionsUpdateCallback(std::move(callback));
3649 }
3650 
TerminateUIExtension()3651 void AceContainer::TerminateUIExtension()
3652 {
3653     if (!IsUIExtensionWindow()) {
3654         return;
3655     }
3656     auto sharedContext = runtimeContext_.lock();
3657     auto uiExtensionContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::UIExtensionContext>(sharedContext);
3658     CHECK_NULL_VOID(uiExtensionContext);
3659     uiExtensionContext->TerminateSelf();
3660 }
3661 
UIExtensionIsHalfScreen()3662 bool AceContainer::UIExtensionIsHalfScreen()
3663 {
3664     if (!IsUIExtensionWindow()) {
3665         return false;
3666     }
3667     auto sharedContext = runtimeContext_.lock();
3668     auto uiExtensionContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::UIExtensionContext>(sharedContext);
3669     CHECK_NULL_RETURN(uiExtensionContext, false);
3670     return uiExtensionContext->GetScreenMode() == EXTENSION_HALF_SCREEN_MODE;
3671 }
3672 
SetAppRunningUniqueId(const std::string & uniqueId)3673 void AceContainer::SetAppRunningUniqueId(const std::string& uniqueId)
3674 {
3675     uniqueId_ = uniqueId;
3676 }
3677 
GetAppRunningUniqueId() const3678 const std::string& AceContainer::GetAppRunningUniqueId() const
3679 {
3680     return uniqueId_;
3681 }
3682 
RegisterAvoidAreaChangeListener(sptr<Rosen::IAvoidAreaChangedListener> & listener)3683 Rosen::WMError AceContainer::RegisterAvoidAreaChangeListener(sptr<Rosen::IAvoidAreaChangedListener>& listener)
3684 {
3685     if (!uiWindow_) {
3686         return Rosen::WMError::WM_DO_NOTHING;
3687     }
3688     return uiWindow_->RegisterAvoidAreaChangeListener(listener);
3689 }
3690 
UnregisterAvoidAreaChangeListener(sptr<Rosen::IAvoidAreaChangedListener> & listener)3691 Rosen::WMError AceContainer::UnregisterAvoidAreaChangeListener(sptr<Rosen::IAvoidAreaChangedListener>& listener)
3692 {
3693     if (!uiWindow_) {
3694         return Rosen::WMError::WM_DO_NOTHING;
3695     }
3696     return uiWindow_->UnregisterAvoidAreaChangeListener(listener);
3697 }
3698 
OHOS_ACE_HotReloadPage()3699 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_HotReloadPage()
3700 {
3701     AceEngine::Get().NotifyContainers([](const RefPtr<Container>& container) {
3702         LOGI("starting hotReload");
3703 #ifndef NG_BUILD
3704         if (Container::IsCurrentUseNewPipeline()) {
3705             container->HotReload();
3706         } else {
3707             container->NotifyConfigurationChange(true);
3708         }
3709 #else
3710         container->HotReload();
3711 #endif
3712     });
3713 }
3714 
NeedFullUpdate(uint32_t limitKey)3715 bool AceContainer::NeedFullUpdate(uint32_t limitKey)
3716 {
3717     auto themeManager = pipelineContext_->GetThemeManager();
3718     if (!themeManager || (themeManager->GetResourceLimitKeys() & limitKey) == 0) {
3719         return false;
3720     }
3721     return true;
3722 }
3723 
NotifyDensityUpdate(double density)3724 void AceContainer::NotifyDensityUpdate(double density)
3725 {
3726     bool fullUpdate = NeedFullUpdate(DENSITY_KEY);
3727     auto frontend = GetFrontend();
3728     if (frontend) {
3729         frontend->FlushReload();
3730     }
3731     UpdateResourceDensity(density, fullUpdate);
3732     ConfigurationChange configurationChange { .dpiUpdate = true };
3733     pipelineContext_->FlushReload(configurationChange, fullUpdate);
3734 }
3735 
NotifyDirectionUpdate()3736 void AceContainer::NotifyDirectionUpdate()
3737 {
3738     bool fullUpdate = NeedFullUpdate(DIRECTION_KEY);
3739     if (fullUpdate) {
3740         ConfigurationChange configurationChange { .directionUpdate = true };
3741         pipelineContext_->FlushReload(configurationChange, fullUpdate);
3742     }
3743 }
3744 
RenderLayoutBoundary(bool isDebugBoundary)3745 void AceContainer::RenderLayoutBoundary(bool isDebugBoundary)
3746 {
3747     auto container = AceEngine::Get().GetContainer(instanceId_);
3748     CHECK_NULL_VOID(container);
3749     CHECK_NULL_VOID(renderBoundaryManager_);
3750     renderBoundaryManager_->PostTaskRenderBoundary(isDebugBoundary, container);
3751 }
3752 
AddWatchSystemParameter()3753 void AceContainer::AddWatchSystemParameter()
3754 {
3755     auto task = [weak = WeakClaim(this)] {
3756         auto container = weak.Upgrade();
3757         CHECK_NULL_VOID(container);
3758         auto rawPtr = static_cast<void*>(Referenced::RawPtr(container));
3759         CHECK_NULL_VOID(rawPtr);
3760         SystemProperties::AddWatchSystemParameter(
3761             ENABLE_TRACE_LAYOUT_KEY, rawPtr, SystemProperties::EnableSystemParameterTraceLayoutCallback);
3762         SystemProperties::AddWatchSystemParameter(
3763             ENABLE_TRACE_INPUTEVENT_KEY, rawPtr, SystemProperties::EnableSystemParameterTraceInputEventCallback);
3764         SystemProperties::AddWatchSystemParameter(ENABLE_SECURITY_DEVELOPERMODE_KEY, rawPtr,
3765             SystemProperties::EnableSystemParameterSecurityDevelopermodeCallback);
3766         SystemProperties::AddWatchSystemParameter(
3767             ENABLE_DEBUG_STATEMGR_KEY, rawPtr, SystemProperties::EnableSystemParameterDebugStatemgrCallback);
3768         SystemProperties::AddWatchSystemParameter(
3769             ENABLE_DEBUG_BOUNDARY_KEY, rawPtr, SystemProperties::EnableSystemParameterDebugBoundaryCallback);
3770         SystemProperties::AddWatchSystemParameter(ENABLE_PERFORMANCE_MONITOR_KEY, rawPtr,
3771             SystemProperties::EnableSystemParameterPerformanceMonitorCallback);
3772         SystemProperties::AddWatchSystemParameter(
3773             IS_FOCUS_ACTIVE_KEY, rawPtr, SystemProperties::OnFocusActiveChanged);
3774     };
3775     BackgroundTaskExecutor::GetInstance().PostTask(task);
3776 }
3777 
RemoveWatchSystemParameter()3778 void AceContainer::RemoveWatchSystemParameter()
3779 {
3780     SystemProperties::RemoveWatchSystemParameter(
3781         ENABLE_TRACE_LAYOUT_KEY, this, SystemProperties::EnableSystemParameterTraceLayoutCallback);
3782     SystemProperties::RemoveWatchSystemParameter(
3783         ENABLE_TRACE_INPUTEVENT_KEY, this, SystemProperties::EnableSystemParameterTraceInputEventCallback);
3784     SystemProperties::RemoveWatchSystemParameter(
3785         ENABLE_SECURITY_DEVELOPERMODE_KEY, this, SystemProperties::EnableSystemParameterSecurityDevelopermodeCallback);
3786     SystemProperties::RemoveWatchSystemParameter(
3787         ENABLE_DEBUG_STATEMGR_KEY, this, SystemProperties::EnableSystemParameterDebugStatemgrCallback);
3788     SystemProperties::RemoveWatchSystemParameter(
3789         ENABLE_DEBUG_BOUNDARY_KEY, this, SystemProperties::EnableSystemParameterDebugBoundaryCallback);
3790     SystemProperties::RemoveWatchSystemParameter(
3791         ENABLE_PERFORMANCE_MONITOR_KEY, this, SystemProperties::EnableSystemParameterPerformanceMonitorCallback);
3792     SystemProperties::RemoveWatchSystemParameter(IS_FOCUS_ACTIVE_KEY, this, SystemProperties::OnFocusActiveChanged);
3793 }
3794 
UpdateResourceOrientation(int32_t orientation)3795 void AceContainer::UpdateResourceOrientation(int32_t orientation)
3796 {
3797     DeviceOrientation newOrientation = WindowUtils::GetDeviceOrientation(orientation);
3798     auto resConfig = GetResourceConfiguration();
3799     resConfig.SetOrientation(newOrientation);
3800     if (SystemProperties::GetResourceDecoupling()) {
3801         ResourceManager::GetInstance().UpdateResourceConfig(resConfig, false);
3802     }
3803     SetResourceConfiguration(resConfig);
3804 }
3805 
UpdateResourceDensity(double density,bool isUpdateResConfig)3806 void AceContainer::UpdateResourceDensity(double density, bool isUpdateResConfig)
3807 {
3808     auto resConfig = GetResourceConfiguration();
3809     resConfig.SetDensity(density);
3810     SetResourceConfiguration(resConfig);
3811     if (SystemProperties::GetResourceDecoupling() && isUpdateResConfig) {
3812         ResourceManager::GetInstance().UpdateResourceConfig(resConfig, false);
3813     }
3814 }
3815 
RegisterUIExtDataConsumer()3816 void AceContainer::RegisterUIExtDataConsumer()
3817 {
3818     ACE_FUNCTION_TRACE();
3819     if (!IsUIExtensionWindow()) {
3820         return;
3821     }
3822     CHECK_NULL_VOID(uiWindow_);
3823     auto dataHandler = uiWindow_->GetExtensionDataHandler();
3824     CHECK_NULL_VOID(dataHandler);
3825     auto uiExtDataConsumeCallback = [weak = WeakClaim(this)](SubSystemId id, uint32_t customId, AAFwk::Want&& data,
3826                                         std::optional<AAFwk::Want>& reply) -> int32_t {
3827         auto container = weak.Upgrade();
3828         CHECK_NULL_RETURN(container, 0);
3829         container->DispatchUIExtDataConsume(static_cast<NG::UIContentBusinessCode>(customId), data, reply);
3830         return 0;
3831     };
3832     auto result = dataHandler->RegisterDataConsumer(SubSystemId::ARKUI_UIEXT, std::move(uiExtDataConsumeCallback));
3833     if (result != Rosen::DataHandlerErr::OK) {
3834         TAG_LOGW(
3835             AceLogTag::ACE_UIEXTENSIONCOMPONENT, "RegisterUIExtDataConsumer fail, same subSystemId repeate registe.");
3836     }
3837 }
3838 
UnRegisterUIExtDataConsumer()3839 void AceContainer::UnRegisterUIExtDataConsumer()
3840 {
3841     ACE_FUNCTION_TRACE();
3842     if (!IsUIExtensionWindow()) {
3843         return;
3844     }
3845     CHECK_NULL_VOID(uiWindow_);
3846     auto dataHandler = uiWindow_->GetExtensionDataHandler();
3847     CHECK_NULL_VOID(dataHandler);
3848     dataHandler->UnregisterDataConsumer(SubSystemId::ARKUI_UIEXT);
3849 }
3850 
DispatchUIExtDataConsume(NG::UIContentBusinessCode code,const AAFwk::Want & data,std::optional<AAFwk::Want> & reply)3851 void AceContainer::DispatchUIExtDataConsume(
3852     NG::UIContentBusinessCode code, const AAFwk::Want& data, std::optional<AAFwk::Want>& reply)
3853 {
3854     ACE_FUNCTION_TRACE();
3855     CHECK_NULL_VOID(taskExecutor_);
3856     if (reply.has_value()) {
3857         taskExecutor_->PostSyncTask(
3858             [weak = WeakClaim(this), code, data, &reply] {
3859                 auto container = weak.Upgrade();
3860                 CHECK_NULL_VOID(container);
3861                 ContainerScope scop(container->GetInstanceId());
3862                 auto pipelineContext = container->GetPipelineContext();
3863                 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3864                 CHECK_NULL_VOID(ngPipeline);
3865                 auto uiExtManager = ngPipeline->GetUIExtensionManager();
3866                 CHECK_NULL_VOID(uiExtManager);
3867                 uiExtManager->DispatchBusinessDataConsumeReply(code, data, reply);
3868             },
3869             TaskExecutor::TaskType::UI, "ArkUIUIxtDispatchDataConsumeReplyCallback");
3870     } else {
3871         taskExecutor_->PostTask(
3872             [weak = WeakClaim(this), code, data] {
3873                 auto container = weak.Upgrade();
3874                 CHECK_NULL_VOID(container);
3875                 ContainerScope scop(container->GetInstanceId());
3876                 auto pipelineContext = container->GetPipelineContext();
3877                 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
3878                 CHECK_NULL_VOID(ngPipeline);
3879                 auto uiExtManager = ngPipeline->GetUIExtensionManager();
3880                 CHECK_NULL_VOID(uiExtManager);
3881                 uiExtManager->DispatchBusinessDataConsume(code, data);
3882             },
3883             TaskExecutor::TaskType::UI, "ArkUIUIxtDispatchDataConsumeCallback");
3884     }
3885 }
3886 
FireUIExtDataSendToHost(NG::UIContentBusinessCode code,const AAFwk::Want & data,NG::BusinessDataSendType type)3887 bool AceContainer::FireUIExtDataSendToHost(
3888     NG::UIContentBusinessCode code, const AAFwk::Want& data, NG::BusinessDataSendType type)
3889 {
3890     if (code == NG::UIContentBusinessCode::UNDEFINED) {
3891         TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "UIExt send data to host fail, businessCode is invalid.");
3892         return false;
3893     }
3894     if (!IsUIExtensionWindow()) {
3895         return false;
3896     }
3897     CHECK_NULL_RETURN(uiWindow_, false);
3898     auto dataHandler = uiWindow_->GetExtensionDataHandler();
3899     CHECK_NULL_RETURN(dataHandler, false);
3900     if (type == NG::BusinessDataSendType::ASYNC) {
3901         dataHandler->SendDataAsync(SubSystemId::ARKUI_UIEXT, static_cast<uint32_t>(code), data);
3902         TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "UIExt sent data to host async success, businessCode=%{public}d.",
3903             code);
3904         return true;
3905     }
3906     auto result = dataHandler->SendDataSync(SubSystemId::ARKUI_UIEXT, static_cast<uint32_t>(code), data);
3907     if (result != DataHandlerErr::OK) {
3908         TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
3909             "UIExt sent data to host sync fail, businessCode=%{public}d, result=%{public}d.", code,
3910             static_cast<uint32_t>(result));
3911         return false;
3912     }
3913     TAG_LOGI(
3914         AceLogTag::ACE_UIEXTENSIONCOMPONENT, "UIExt sent data to host async success, businessCode=%{public}d.", code);
3915     return true;
3916 }
3917 
FireUIExtDataSendToHostReply(NG::UIContentBusinessCode code,const AAFwk::Want & data,AAFwk::Want & reply)3918 bool AceContainer::FireUIExtDataSendToHostReply(
3919     NG::UIContentBusinessCode code, const AAFwk::Want& data, AAFwk::Want& reply)
3920 {
3921     if (code == NG::UIContentBusinessCode::UNDEFINED) {
3922         TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "UIExt send data to host fail, businessCode is invalid.");
3923         return false;
3924     }
3925     if (!IsUIExtensionWindow()) {
3926         return false;
3927     }
3928     CHECK_NULL_RETURN(uiWindow_, false);
3929     auto dataHandler = uiWindow_->GetExtensionDataHandler();
3930     CHECK_NULL_RETURN(dataHandler, false);
3931     auto result = dataHandler->SendDataSync(SubSystemId::ARKUI_UIEXT, static_cast<uint32_t>(code), data, reply);
3932     if (result != DataHandlerErr::OK) {
3933         TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
3934             "UIExt sent data to host sync reply fail, businessCode=%{public}d, result=%{public}d.", code,
3935             static_cast<uint32_t>(result));
3936         return false;
3937     }
3938     TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
3939         "UIExt sent data to host sync reply success, businessCode=%{public}d.", code);
3940     return true;
3941 }
3942 
RegisterUIExtDataSendToHost()3943 void AceContainer::RegisterUIExtDataSendToHost()
3944 {
3945     auto uiExtDataSendSyncReply = [weak = WeakClaim(this)](
3946         uint32_t customId, const AAFwk::Want& data, AAFwk::Want& reply) -> bool {
3947         auto container = weak.Upgrade();
3948         CHECK_NULL_RETURN(container, false);
3949         return container->FireUIExtDataSendToHostReply(
3950             static_cast<NG::UIContentBusinessCode>(customId), data, reply);
3951     };
3952     auto uiExtDataSend = [weak = WeakClaim(this)](
3953         uint32_t customId, const AAFwk::Want& data, NG::BusinessDataSendType type) -> bool {
3954         auto container = weak.Upgrade();
3955         CHECK_NULL_RETURN(container, false);
3956         return container->FireUIExtDataSendToHost(
3957             static_cast<NG::UIContentBusinessCode>(customId), data, type);
3958     };
3959     auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
3960     CHECK_NULL_VOID(ngPipeline);
3961     auto uiExtManager = ngPipeline->GetUIExtensionManager();
3962     CHECK_NULL_VOID(uiExtManager);
3963     uiExtManager->RegisterBusinessSendToHostReply(uiExtDataSendSyncReply);
3964     uiExtManager->RegisterBusinessSendToHost(uiExtDataSend);
3965 }
3966 
SetDrawReadyEventCallback()3967 void AceContainer::SetDrawReadyEventCallback()
3968 {
3969     CHECK_NULL_VOID(uiWindow_);
3970     auto surfaceNode = uiWindow_->GetSurfaceNode();
3971     CHECK_NULL_VOID(surfaceNode);
3972     auto callback = [weak = WeakClaim(this)]() {
3973         auto container = weak.Upgrade();
3974         CHECK_NULL_VOID(container);
3975         container->FireUIExtensionEventCallback(static_cast<int>(NG::UIExtCallbackEventId::ON_DRAW_FIRST));
3976     };
3977     surfaceNode->SetBufferAvailableCallback(callback);
3978 }
3979 
GetDisplayAvailableRect() const3980 Rect AceContainer::GetDisplayAvailableRect() const
3981 {
3982     if (!uiWindow_) {
3983         TAG_LOGW(AceLogTag::ACE_WINDOW, "uiwindow is null, can't get displayId");
3984         return Rect();
3985     }
3986 
3987     return displayManager_->GetDisplayAvailableRect(uiWindow_->GetDisplayId());
3988 }
3989 
GetExtensionConfig(AAFwk::WantParams & want)3990 void AceContainer::GetExtensionConfig(AAFwk::WantParams& want)
3991 {
3992     CHECK_NULL_VOID(uiWindow_);
3993     uiWindow_->GetExtensionConfig(want);
3994 }
3995 
SetIsFocusActive(bool isFocusActive)3996 void AceContainer::SetIsFocusActive(bool isFocusActive)
3997 {
3998     auto pipelineContext = DynamicCast<NG::PipelineContext>(GetPipelineContext());
3999     CHECK_NULL_VOID(pipelineContext);
4000     pipelineContext->SetIsFocusActive(isFocusActive);
4001 }
4002 
CloseWindow(int32_t instanceId)4003 bool AceContainer::CloseWindow(int32_t instanceId)
4004 {
4005     TAG_LOGI(AceLogTag::ACE_DIALOG, "AceContainer CloseWindow begin");
4006     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
4007     CHECK_NULL_RETURN(container, false);
4008     auto window = container->GetUIWindowInner();
4009     CHECK_NULL_RETURN(window, false);
4010     OHOS::Rosen::WMError ret = window->Close();
4011     if (ret != OHOS::Rosen::WMError::WM_OK) {
4012         TAG_LOGE(AceLogTag::ACE_DIALOG, "AceContainer CloseWindow Failed to close the window.");
4013         return false;
4014     }
4015     sptr<OHOS::Rosen::Window> uiWindow = nullptr;
4016     AceContainer::SetUIWindow(instanceId, uiWindow);
4017     return true;
4018 }
4019 
HideWindow(int32_t instanceId)4020 bool AceContainer::HideWindow(int32_t instanceId)
4021 {
4022     TAG_LOGI(AceLogTag::ACE_DIALOG, "AceContainer HideWindow begin");
4023     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
4024     CHECK_NULL_RETURN(container, false);
4025     auto window = container->GetUIWindowInner();
4026     CHECK_NULL_RETURN(window, false);
4027     OHOS::Rosen::WMError ret = window->Hide();
4028     if (ret != OHOS::Rosen::WMError::WM_OK) {
4029         TAG_LOGE(AceLogTag::ACE_DIALOG, "AceContainer HideWindow Failed to hide the window.");
4030         return false;
4031     }
4032     sptr<OHOS::Rosen::Window> uiWindow = nullptr;
4033     AceContainer::SetUIWindow(instanceId, uiWindow);
4034     return true;
4035 }
4036 
RegisterAvoidInfoCallback()4037 void AceContainer::RegisterAvoidInfoCallback()
4038 {
4039     RegisterAvoidInfoDataProcessCallback();
4040 
4041 #ifdef WINDOW_SCENE_SUPPORTED
4042     auto pipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
4043     CHECK_NULL_VOID(pipeline);
4044     auto avoidInfoMgr = pipeline->GetAvoidInfoManager();
4045     CHECK_NULL_VOID(avoidInfoMgr);
4046     auto uiExtMgr = pipeline->GetUIExtensionManager();
4047     CHECK_NULL_VOID(uiExtMgr);
4048     auto checkTask = [weakMgr = WeakPtr(uiExtMgr)]() {
4049         auto mgr = weakMgr.Upgrade();
4050         CHECK_NULL_VOID(mgr);
4051         mgr->NotifyUECProviderIfNeedded();
4052     };
4053     auto registerCallback = [weakMgr = WeakPtr(uiExtMgr)](NG::UECAvoidInfoConsumer&& consumer) {
4054         auto mgr = weakMgr.Upgrade();
4055         CHECK_NULL_VOID(mgr);
4056         mgr->RegisterBusinessDataConsumeCallback(NG::UIContentBusinessCode::NOTIFY_AVOID_INFO_CHANGE, consumer);
4057     };
4058     auto requestCallback = [weakMgr = WeakPtr(uiExtMgr)]() {
4059         auto mgr = weakMgr.Upgrade();
4060         CHECK_NULL_VOID(mgr);
4061         AAFwk::Want want;
4062         mgr->SendBusinessToHost(
4063             NG::UIContentBusinessCode::GET_AVOID_INFO, std::move(want), NG::BusinessDataSendType::ASYNC);
4064     };
4065     pipeline->AddPersistAfterLayoutTask(std::move(checkTask));
4066     avoidInfoMgr->SetRegisterUECAvoidInfoConsumerCallback(std::move(registerCallback));
4067     avoidInfoMgr->SetRequestAvoidInfoCallback(std::move(requestCallback));
4068 #endif
4069 }
4070 
RegisterAvoidInfoDataProcessCallback()4071 void AceContainer::RegisterAvoidInfoDataProcessCallback()
4072 {
4073     auto pipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
4074     CHECK_NULL_VOID(pipeline);
4075     auto avoidInfoMgr = pipeline->GetAvoidInfoManager();
4076     CHECK_NULL_VOID(avoidInfoMgr);
4077     auto parseCallback = [](const AAFwk::Want& want, NG::ContainerModalAvoidInfo& info) {
4078         if (!want.HasParameter("needAvoid")) {
4079             TAG_LOGW(AceLogTag::ACE_LAYOUT, "Invalid want for ContainerModalAvoidInfo");
4080             return false;
4081         }
4082         bool needAvoid = want.GetBoolParam("needAvoid", false);
4083         int32_t titleHeight = want.GetIntParam("titleHeight", 0);
4084         float x = want.GetFloatParam("controlBottonsRectX", 0);
4085         float y = want.GetFloatParam("controlBottonsRectY", 0);
4086         float w = want.GetFloatParam("controlBottonsRectW", 0);
4087         float h = want.GetFloatParam("controlBottonsRectH", 0);
4088         info.needAvoid = needAvoid;
4089         info.titleHeight = titleHeight;
4090         info.controlBottonsRect.SetRect(x, y, w, h);
4091         return true;
4092     };
4093     auto buildCallback = [](const NG::ContainerModalAvoidInfo& info, AAFwk::Want& want) {
4094         want.SetParam("needAvoid", info.needAvoid);
4095         want.SetParam("titleHeight", info.titleHeight);
4096         want.SetParam("controlBottonsRectX", info.controlBottonsRect.GetX());
4097         want.SetParam("controlBottonsRectY", info.controlBottonsRect.GetY());
4098         want.SetParam("controlBottonsRectW", info.controlBottonsRect.Width());
4099         want.SetParam("controlBottonsRectH", info.controlBottonsRect.Height());
4100     };
4101     avoidInfoMgr->SetParseAvoidInfoCallback(std::move(parseCallback));
4102     avoidInfoMgr->SetBuildAvoidInfoCallback(std::move(buildCallback));
4103 }
4104 } // namespace OHOS::Ace::Platform
4105