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