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