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