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