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