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