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