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