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