1 /*
2 * Copyright (c) 2021-2023 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 "base/json/json_util.h"
29 #include "pointer_event.h"
30 #include "scene_board_judgement.h"
31 #include "window_manager.h"
32 #include "wm/wm_common.h"
33
34 #include "adapter/ohos/entrance/ace_application_info.h"
35 #include "adapter/ohos/entrance/ace_view_ohos.h"
36 #include "adapter/ohos/entrance/data_ability_helper_standard.h"
37 #include "adapter/ohos/entrance/file_asset_provider_impl.h"
38 #include "adapter/ohos/entrance/hap_asset_provider_impl.h"
39 #include "adapter/ohos/entrance/ui_content_impl.h"
40 #include "adapter/ohos/entrance/utils.h"
41 #include "adapter/ohos/osal/resource_adapter_impl_v2.h"
42 #include "adapter/ohos/osal/view_data_wrap_ohos.h"
43 #include "base/i18n/localization.h"
44 #include "base/log/ace_trace.h"
45 #include "base/log/dump_log.h"
46 #include "base/log/event_report.h"
47 #include "base/log/frame_report.h"
48 #include "base/log/jank_frame_report.h"
49 #include "base/log/log.h"
50 #include "base/log/log_wrapper.h"
51 #include "base/subwindow/subwindow_manager.h"
52 #include "base/thread/task_executor.h"
53 #include "base/utils/device_config.h"
54 #include "base/utils/system_properties.h"
55 #include "base/utils/utils.h"
56 #include "bridge/card_frontend/card_frontend.h"
57 #include "bridge/card_frontend/form_frontend_declarative.h"
58 #include "bridge/common/utils/engine_helper.h"
59 #include "bridge/declarative_frontend/declarative_frontend.h"
60 #include "bridge/js_frontend/engine/common/js_engine_loader.h"
61 #include "bridge/js_frontend/js_frontend.h"
62 #include "core/common/ace_application_info.h"
63 #include "core/common/ace_engine.h"
64 #include "core/common/asset_manager_impl.h"
65 #include "core/common/container.h"
66 #include "core/common/container_scope.h"
67 #include "core/common/platform_window.h"
68 #include "core/common/plugin_manager.h"
69 #include "core/common/resource/resource_manager.h"
70 #include "core/common/task_executor_impl.h"
71 #include "core/common/text_field_manager.h"
72 #include "core/common/window.h"
73 #include "core/components/theme/theme_constants.h"
74 #include "core/components/theme/theme_manager_impl.h"
75 #include "core/components_ng/pattern/text_field/text_field_manager.h"
76 #include "core/components_ng/render/adapter/form_render_window.h"
77 #include "core/components_ng/render/adapter/rosen_window.h"
78 #include "core/pipeline/pipeline_base.h"
79 #include "core/pipeline/pipeline_context.h"
80 #include "core/pipeline_ng/pipeline_context.h"
81
82 #if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
83 #include "adapter/ohos/entrance/ace_rosen_sync_task.h"
84 #endif
85
86 namespace OHOS::Ace::Platform {
87 namespace {
88 constexpr uint32_t DIRECTION_KEY = 0b1000;
89
90 #ifdef _ARM64_
91 const std::string ASSET_LIBARCH_PATH = "/lib/arm64";
92 #else
93 const std::string ASSET_LIBARCH_PATH = "/lib/arm";
94 #endif
95
96 #ifndef NG_BUILD
97 constexpr char ARK_ENGINE_SHARED_LIB[] = "libace_engine_ark.z.so";
GetEngineSharedLibrary()98 const char* GetEngineSharedLibrary()
99 {
100 return ARK_ENGINE_SHARED_LIB;
101 }
102 #endif
103
104 constexpr char DECLARATIVE_ARK_ENGINE_SHARED_LIB[] = "libace_engine_declarative_ark.z.so";
GetDeclarativeSharedLibrary()105 const char* GetDeclarativeSharedLibrary()
106 {
107 return DECLARATIVE_ARK_ENGINE_SHARED_LIB;
108 }
109
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)110 void InitResourceAndThemeManager(const RefPtr<PipelineBase>& pipelineContext, const RefPtr<AssetManager>& assetManager,
111 const ColorScheme& colorScheme, const ResourceInfo& resourceInfo,
112 const std::shared_ptr<OHOS::AbilityRuntime::Context>& context,
113 const std::shared_ptr<OHOS::AppExecFwk::AbilityInfo>& abilityInfo, bool clearCache = false)
114 {
115 RefPtr<ResourceAdapter> resourceAdapter = nullptr;
116 if (context && context->GetResourceManager()) {
117 resourceAdapter = AceType::MakeRefPtr<ResourceAdapterImplV2>(context->GetResourceManager(), resourceInfo);
118 } else {
119 resourceAdapter = ResourceAdapter::CreateV2();
120 resourceAdapter->Init(resourceInfo);
121 }
122
123 ThemeConstants::InitDeviceType();
124 auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>(resourceAdapter);
125 pipelineContext->SetThemeManager(themeManager);
126 themeManager->SetColorScheme(colorScheme);
127 themeManager->LoadCustomTheme(assetManager);
128 themeManager->LoadResourceThemes();
129
130 if (clearCache) {
131 ResourceManager::GetInstance().Reset();
132 }
133
134 auto defaultBundleName = "";
135 auto defaultModuleName = "";
136 ResourceManager::GetInstance().AddResourceAdapter(defaultBundleName, defaultModuleName, resourceAdapter, true);
137 if (context) {
138 auto bundleName = context->GetBundleName();
139 auto moduleName = context->GetHapModuleInfo()->name;
140 if (!bundleName.empty() && !moduleName.empty()) {
141 ResourceManager::GetInstance().AddResourceAdapter(bundleName, moduleName, resourceAdapter, true);
142 }
143 } else if (abilityInfo) {
144 auto bundleName = abilityInfo->bundleName;
145 auto moduleName = abilityInfo->moduleName;
146 if (!bundleName.empty() && !moduleName.empty()) {
147 ResourceManager::GetInstance().AddResourceAdapter(bundleName, moduleName, resourceAdapter, true);
148 }
149 }
150 }
151
EncodeBundleAndModule(const std::string & bundleName,const std::string & moduleName)152 std::string EncodeBundleAndModule(const std::string& bundleName, const std::string& moduleName)
153 {
154 return bundleName + " " + moduleName;
155 }
156
DecodeBundleAndModule(const std::string & encode,std::string & bundleName,std::string & moduleName)157 void DecodeBundleAndModule(const std::string& encode, std::string& bundleName, std::string& moduleName)
158 {
159 std::vector<std::string> tokens;
160 StringUtils::StringSplitter(encode, ' ', tokens);
161 bundleName = tokens[0];
162 moduleName = tokens[1];
163 }
164 } // namespace
165
AceContainer(int32_t instanceId,FrontendType type,std::shared_ptr<OHOS::AppExecFwk::Ability> aceAbility,std::unique_ptr<PlatformEventCallback> callback,bool useCurrentEventRunner,bool useNewPipeline)166 AceContainer::AceContainer(int32_t instanceId, FrontendType type, std::shared_ptr<OHOS::AppExecFwk::Ability> aceAbility,
167 std::unique_ptr<PlatformEventCallback> callback, bool useCurrentEventRunner, bool useNewPipeline)
168 : instanceId_(instanceId), type_(type), aceAbility_(aceAbility), useCurrentEventRunner_(useCurrentEventRunner)
169 {
170 ACE_DCHECK(callback);
171 if (useNewPipeline) {
172 SetUseNewPipeline();
173 }
174 InitializeTask();
175 platformEventCallback_ = std::move(callback);
176 useStageModel_ = false;
177 auto ability = aceAbility_.lock();
178 if (ability) {
179 abilityInfo_ = ability->GetAbilityInfo();
180 }
181 }
182
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)183 AceContainer::AceContainer(int32_t instanceId, FrontendType type,
184 std::weak_ptr<OHOS::AbilityRuntime::Context> runtimeContext,
185 std::weak_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo, std::unique_ptr<PlatformEventCallback> callback,
186 bool useCurrentEventRunner, bool isSubAceContainer, bool useNewPipeline)
187 : instanceId_(instanceId), type_(type), runtimeContext_(std::move(runtimeContext)),
188 abilityInfo_(std::move(abilityInfo)), useCurrentEventRunner_(useCurrentEventRunner),
189 isSubContainer_(isSubAceContainer)
190 {
191 ACE_DCHECK(callback);
192 if (useNewPipeline) {
193 SetUseNewPipeline();
194 }
195 if (!isSubContainer_) {
196 InitializeTask();
197 }
198 platformEventCallback_ = std::move(callback);
199 useStageModel_ = true;
200 }
201
202 // 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)203 AceContainer::AceContainer(int32_t instanceId, FrontendType type,
204 std::weak_ptr<OHOS::AbilityRuntime::Context> runtimeContext,
205 std::weak_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo, std::unique_ptr<PlatformEventCallback> callback,
206 std::shared_ptr<TaskWrapper> taskWrapper,
207 bool useCurrentEventRunner, bool isSubAceContainer, bool useNewPipeline)
208 : instanceId_(instanceId), type_(type), runtimeContext_(std::move(runtimeContext)),
209 abilityInfo_(std::move(abilityInfo)), useCurrentEventRunner_(useCurrentEventRunner),
210 isSubContainer_(isSubAceContainer)
211 {
212 ACE_DCHECK(callback);
213 if (useNewPipeline) {
214 SetUseNewPipeline();
215 }
216 if (!isSubContainer_) {
217 InitializeTask(taskWrapper);
218 }
219 platformEventCallback_ = std::move(callback);
220 useStageModel_ = true;
221 }
222
~AceContainer()223 AceContainer::~AceContainer()
224 {
225 std::lock_guard lock(destructMutex_);
226 LOG_DESTROY();
227 }
228
InitializeTask(std::shared_ptr<TaskWrapper> taskWrapper)229 void AceContainer::InitializeTask(std::shared_ptr<TaskWrapper> taskWrapper)
230 {
231 RefPtr<TaskExecutorImpl> taskExecutorImpl;
232 if (taskWrapper != nullptr) {
233 taskExecutorImpl = Referenced::MakeRefPtr<TaskExecutorImpl>(taskWrapper);
234 } else {
235 taskExecutorImpl = Referenced::MakeRefPtr<TaskExecutorImpl>();
236 }
237 taskExecutorImpl->InitPlatformThread(useCurrentEventRunner_);
238 taskExecutor_ = taskExecutorImpl;
239 // No need to create JS Thread for DECLARATIVE_JS
240 if (type_ == FrontendType::DECLARATIVE_JS) {
241 GetSettings().useUIAsJSThread = true;
242 } else {
243 taskExecutorImpl->InitJsThread();
244 }
245 }
246
IsKeyboard()247 bool AceContainer::IsKeyboard()
248 {
249 if (uiWindow_ == nullptr) {
250 return false;
251 }
252 return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT;
253 }
254
Initialize()255 void AceContainer::Initialize()
256 {
257 ContainerScope scope(instanceId_);
258 // For DECLARATIVE_JS frontend use UI as JS Thread, so InitializeFrontend after UI thread created.
259 if (type_ != FrontendType::DECLARATIVE_JS) {
260 InitializeFrontend();
261 }
262 }
263
MaybeRelease()264 bool AceContainer::MaybeRelease()
265 {
266 CHECK_NULL_RETURN(taskExecutor_, true);
267 if (taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::PLATFORM)) {
268 LOGI("Destroy AceContainer on PLATFORM thread.");
269 return true;
270 } else {
271 std::lock_guard lock(destructMutex_);
272 LOGI("Post Destroy AceContainer Task to PLATFORM thread.");
273 return !taskExecutor_->PostTask([this] { delete this; }, TaskExecutor::TaskType::PLATFORM);
274 }
275 }
276
Destroy()277 void AceContainer::Destroy()
278 {
279 LOGI("AceContainer Destroy begin");
280 ContainerScope scope(instanceId_);
281
282 for (auto& encode : resAdapterRecord_) {
283 std::string bundleName;
284 std::string moduleName;
285 DecodeBundleAndModule(encode, bundleName, moduleName);
286 ResourceManager::GetInstance().RemoveResourceAdapter(bundleName, moduleName);
287 }
288 resAdapterRecord_.clear();
289
290 if (pipelineContext_ && taskExecutor_) {
291 // 1. Destroy Pipeline on UI thread.
292 RefPtr<PipelineBase> context;
293 {
294 std::lock_guard<std::mutex> lock(pipelineMutex_);
295 context.Swap(pipelineContext_);
296 }
297 auto uiTask = [context]() { context->Destroy(); };
298 if (GetSettings().usePlatformAsUIThread) {
299 uiTask();
300 } else {
301 taskExecutor_->PostTask(uiTask, TaskExecutor::TaskType::UI);
302 }
303
304 if (isSubContainer_) {
305 // SubAceContainer just return.
306 return;
307 }
308
309 // 2. Destroy Frontend on JS thread.
310 RefPtr<Frontend> frontend;
311 {
312 std::lock_guard<std::mutex> lock(frontendMutex_);
313 frontend.Swap(frontend_);
314 }
315 auto jsTask = [frontend]() {
316 auto lock = frontend->GetLock();
317 frontend->Destroy();
318 };
319 frontend->UpdateState(Frontend::State::ON_DESTROY);
320 if (GetSettings().usePlatformAsUIThread && GetSettings().useUIAsJSThread) {
321 jsTask();
322 } else {
323 taskExecutor_->PostTask(jsTask, TaskExecutor::TaskType::JS);
324 }
325 }
326 resRegister_.Reset();
327 assetManager_.Reset();
328 }
329
DestroyView()330 void AceContainer::DestroyView()
331 {
332 ContainerScope scope(instanceId_);
333 CHECK_NULL_VOID(aceView_);
334 auto aceView = static_cast<AceViewOhos*>(aceView_);
335 if (aceView) {
336 aceView->DecRefCount();
337 }
338 aceView_ = nullptr;
339 }
340
InitializeFrontend()341 void AceContainer::InitializeFrontend()
342 {
343 auto aceAbility = aceAbility_.lock();
344 if (type_ == FrontendType::JS) {
345 #ifndef NG_BUILD
346 frontend_ = Frontend::Create();
347 auto jsFrontend = AceType::DynamicCast<JsFrontend>(frontend_);
348 auto& loader = Framework::JsEngineLoader::Get(GetEngineSharedLibrary());
349 auto jsEngine = loader.CreateJsEngine(instanceId_);
350 jsEngine->AddExtraNativeObject("ability", aceAbility.get());
351 EngineHelper::AddEngine(instanceId_, jsEngine);
352 jsFrontend->SetJsEngine(jsEngine);
353 jsFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
354 jsFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
355 #endif
356 } else if (type_ == FrontendType::JS_CARD) {
357 #ifndef NG_BUILD
358 AceApplicationInfo::GetInstance().SetCardType();
359 frontend_ = AceType::MakeRefPtr<CardFrontend>();
360 #endif
361 } else if (type_ == FrontendType::DECLARATIVE_JS) {
362 if (isFormRender_) {
363 #ifdef FORM_SUPPORTED
364 LOGI("Init Form Frontend");
365 frontend_ = AceType::MakeRefPtr<FormFrontendDeclarative>();
366 auto cardFrontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
367 auto& loader = Framework::JsEngineLoader::GetDeclarative(GetDeclarativeSharedLibrary());
368 RefPtr<Framework::JsEngine> jsEngine;
369 if (GetSettings().usingSharedRuntime) {
370 jsEngine = loader.CreateJsEngineUsingSharedRuntime(instanceId_, sharedRuntime_);
371 } else {
372 jsEngine = loader.CreateJsEngine(instanceId_);
373 }
374 jsEngine->AddExtraNativeObject("ability", aceAbility.get());
375 EngineHelper::AddEngine(instanceId_, jsEngine);
376 cardFrontend->SetJsEngine(jsEngine);
377 cardFrontend->SetPageProfile(pageProfile_);
378 cardFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
379 cardFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
380 // Card front
381 cardFrontend->SetRunningCardId(0); // ArkTsCard : nodeId, Host->FMS->FRS->innersdk
382 cardFrontend->SetIsFormRender(true);
383 #endif
384 } else if (!isSubContainer_) {
385 #ifdef NG_BUILD
386 frontend_ = AceType::MakeRefPtr<DeclarativeFrontendNG>();
387 auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontendNG>(frontend_);
388 #else
389 frontend_ = AceType::MakeRefPtr<DeclarativeFrontend>();
390 auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
391 #endif
392 auto& loader = Framework::JsEngineLoader::GetDeclarative(GetDeclarativeSharedLibrary());
393 RefPtr<Framework::JsEngine> jsEngine;
394 if (GetSettings().usingSharedRuntime) {
395 jsEngine = loader.CreateJsEngineUsingSharedRuntime(instanceId_, sharedRuntime_);
396 } else {
397 jsEngine = loader.CreateJsEngine(instanceId_);
398 }
399 jsEngine->AddExtraNativeObject("ability", aceAbility.get());
400 EngineHelper::AddEngine(instanceId_, jsEngine);
401 declarativeFrontend->SetJsEngine(jsEngine);
402 declarativeFrontend->SetPageProfile(pageProfile_);
403 declarativeFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
404 declarativeFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
405 } else {
406 frontend_ = OHOS::Ace::Platform::AceContainer::GetContainer(parentId_)->GetFrontend();
407 return;
408 }
409 } else {
410 LOGE("Frontend type not supported");
411 EventReport::SendAppStartException(AppStartExcepType::FRONTEND_TYPE_ERR);
412 return;
413 }
414 ACE_DCHECK(frontend_);
415 auto abilityInfo = abilityInfo_.lock();
416 std::shared_ptr<AppExecFwk::AbilityInfo> info = aceAbility ? aceAbility->GetAbilityInfo() : abilityInfo;
417 if (info && info->isLauncherAbility) {
418 frontend_->DisallowPopLastPage();
419 }
420 frontend_->Initialize(type_, taskExecutor_);
421 }
422
GetContainer(int32_t instanceId)423 RefPtr<AceContainer> AceContainer::GetContainer(int32_t instanceId)
424 {
425 auto container = AceEngine::Get().GetContainer(instanceId);
426 CHECK_NULL_RETURN(container, nullptr);
427 auto aceContainer = AceType::DynamicCast<AceContainer>(container);
428 return aceContainer;
429 }
430
OnBackPressed(int32_t instanceId)431 bool AceContainer::OnBackPressed(int32_t instanceId)
432 {
433 auto container = AceEngine::Get().GetContainer(instanceId);
434 CHECK_NULL_RETURN(container, false);
435 // When the container is for overlay, it need close the overlay first.
436 if (container->IsSubContainer()) {
437 #ifdef NG_BUILD
438 LOGI("back press for remove overlay node");
439 ContainerScope scope(instanceId);
440 auto subPipelineContext = DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
441 CHECK_NULL_RETURN(subPipelineContext, false);
442 auto overlayManager = subPipelineContext->GetOverlayManager();
443 CHECK_NULL_RETURN(overlayManager, false);
444 return overlayManager->RemoveOverlayInSubwindow();
445 #else
446 if (container->IsUseNewPipeline()) {
447 LOGI("back press for remove overlay node");
448 ContainerScope scope(instanceId);
449 auto subPipelineContext = DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
450 CHECK_NULL_RETURN(subPipelineContext, false);
451 auto overlayManager = subPipelineContext->GetOverlayManager();
452 CHECK_NULL_RETURN(overlayManager, false);
453 return overlayManager->RemoveOverlayInSubwindow();
454 }
455 SubwindowManager::GetInstance()->CloseMenu();
456 return true;
457 #endif
458 }
459 // remove overlay through SubwindowManager if subwindow unfocused.
460 auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(instanceId);
461 if (subwindow) {
462 if (subwindow->GetShown()) {
463 auto overlayManager = subwindow->GetOverlayManager();
464 CHECK_NULL_RETURN(overlayManager, false);
465 return overlayManager->RemoveOverlayInSubwindow();
466 }
467 }
468 ContainerScope scope(instanceId);
469 auto context = container->GetPipelineContext();
470 CHECK_NULL_RETURN(context, false);
471 if (context->PopPageStackOverlay()) {
472 return true;
473 }
474 return context->CallRouterBackToPopPage();
475 }
476
OnShow(int32_t instanceId)477 void AceContainer::OnShow(int32_t instanceId)
478 {
479 auto container = AceEngine::Get().GetContainer(instanceId);
480 CHECK_NULL_VOID(container);
481 ContainerScope scope(instanceId);
482 auto taskExecutor = container->GetTaskExecutor();
483 CHECK_NULL_VOID(taskExecutor);
484 if (!container->UpdateState(Frontend::State::ON_SHOW)) {
485 return;
486 }
487
488 auto jsTask = [container, front = container->GetFrontend()]() {
489 if (front && !container->IsSubContainer()) {
490 front->UpdateState(Frontend::State::ON_SHOW);
491 front->OnShow();
492 }
493 };
494
495 auto uiTask = [container]() {
496 std::unordered_map<int64_t, WeakPtr<Frontend>> cardFrontendMap;
497 container->GetCardFrontendMap(cardFrontendMap);
498 for (const auto& [_, weakCardFront] : cardFrontendMap) {
499 auto cardFront = weakCardFront.Upgrade();
500 if (!cardFront) {
501 LOGE("cardFront is null");
502 continue;
503 }
504 cardFront->OnShow();
505 }
506 auto pipelineBase = container->GetPipelineContext();
507 CHECK_NULL_VOID(pipelineBase);
508 pipelineBase->OnShow();
509 pipelineBase->SetForegroundCalled(true);
510 };
511
512 // stege model needn't post task when already run on UI
513 if (container->GetSettings().useUIAsJSThread && taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
514 jsTask();
515 uiTask();
516 } else {
517 taskExecutor->PostTask(jsTask, TaskExecutor::TaskType::JS);
518 taskExecutor->PostTask(uiTask, TaskExecutor::TaskType::UI);
519 }
520 }
521
OnHide(int32_t instanceId)522 void AceContainer::OnHide(int32_t instanceId)
523 {
524 auto container = AceEngine::Get().GetContainer(instanceId);
525 CHECK_NULL_VOID(container);
526 ContainerScope scope(instanceId);
527 auto taskExecutor = container->GetTaskExecutor();
528 CHECK_NULL_VOID(taskExecutor);
529 if (!container->UpdateState(Frontend::State::ON_HIDE)) {
530 return;
531 }
532 std::unordered_map<int64_t, WeakPtr<Frontend>> cardFrontendMap;
533 container->GetCardFrontendMap(cardFrontendMap);
534
535 auto jsTask = [container, front = container->GetFrontend(), cardFrontendMap]() {
536 if (front && !container->IsSubContainer()) {
537 front->UpdateState(Frontend::State::ON_HIDE);
538 front->OnHide();
539 front->TriggerGarbageCollection();
540 }
541 for (const auto& [_, weakCardFront] : cardFrontendMap) {
542 auto cardFront = weakCardFront.Upgrade();
543 if (!cardFront) {
544 LOGE("cardFront is null");
545 continue;
546 }
547 cardFront->TriggerGarbageCollection();
548 }
549 };
550
551 auto uiTask = [container, cardFrontendMap]() {
552 for (const auto& [_, weakCardFront] : cardFrontendMap) {
553 auto cardFront = weakCardFront.Upgrade();
554 if (!cardFront) {
555 LOGE("cardFront is null");
556 continue;
557 }
558 cardFront->OnHide();
559 }
560 auto pipelineBase = container->GetPipelineContext();
561 CHECK_NULL_VOID(pipelineBase);
562 pipelineBase->OnHide();
563 };
564
565 // stege model needn't post task when already run on UI
566 if (container->GetSettings().useUIAsJSThread && taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
567 jsTask();
568 uiTask();
569 } else {
570 taskExecutor->PostTask(jsTask, TaskExecutor::TaskType::JS);
571 taskExecutor->PostTask(uiTask, TaskExecutor::TaskType::UI);
572 }
573 }
574
OnActive(int32_t instanceId)575 void AceContainer::OnActive(int32_t instanceId)
576 {
577 auto container = AceEngine::Get().GetContainer(instanceId);
578 CHECK_NULL_VOID(container);
579 ContainerScope scope(instanceId);
580 auto taskExecutor = container->GetTaskExecutor();
581 CHECK_NULL_VOID(taskExecutor);
582
583 auto front = container->GetFrontend();
584 if (front && !container->IsSubContainer()) {
585 WeakPtr<Frontend> weakFrontend = front;
586 taskExecutor->PostTask(
587 [weakFrontend]() {
588 auto frontend = weakFrontend.Upgrade();
589 if (frontend) {
590 frontend->UpdateState(Frontend::State::ON_ACTIVE);
591 frontend->OnActive();
592 }
593 },
594 TaskExecutor::TaskType::JS);
595 }
596
597 taskExecutor->PostTask(
598 [container]() {
599 auto pipelineContext = container->GetPipelineContext();
600 if (!pipelineContext) {
601 LOGE("pipeline context is null, OnActive failed.");
602 return;
603 }
604 pipelineContext->WindowFocus(true);
605 },
606 TaskExecutor::TaskType::UI);
607 }
608
OnInactive(int32_t instanceId)609 void AceContainer::OnInactive(int32_t instanceId)
610 {
611 auto container = AceEngine::Get().GetContainer(instanceId);
612 CHECK_NULL_VOID(container);
613 ContainerScope scope(instanceId);
614 auto taskExecutor = container->GetTaskExecutor();
615 CHECK_NULL_VOID(taskExecutor);
616
617 auto front = container->GetFrontend();
618 if (front && !container->IsSubContainer()) {
619 WeakPtr<Frontend> weakFrontend = front;
620 taskExecutor->PostTask(
621 [weakFrontend]() {
622 auto frontend = weakFrontend.Upgrade();
623 if (frontend) {
624 frontend->UpdateState(Frontend::State::ON_INACTIVE);
625 frontend->OnInactive();
626 }
627 },
628 TaskExecutor::TaskType::JS);
629 }
630
631 taskExecutor->PostTask(
632 [container]() {
633 auto pipelineContext = container->GetPipelineContext();
634 if (!pipelineContext) {
635 LOGE("pipeline context is null, OnInactive failed.");
636 return;
637 }
638 pipelineContext->WindowFocus(false);
639 if (container->IsScenceBoardWindow()) {
640 JankFrameReport::GetInstance().FlushRecord();
641 }
642 },
643 TaskExecutor::TaskType::UI);
644 }
645
OnNewWant(int32_t instanceId,const std::string & data)646 void AceContainer::OnNewWant(int32_t instanceId, const std::string& data)
647 {
648 auto container = AceEngine::Get().GetContainer(instanceId);
649 CHECK_NULL_VOID(container);
650 ContainerScope scope(instanceId);
651 auto front = container->GetFrontend();
652 CHECK_NULL_VOID(front);
653 front->OnNewWant(data);
654 }
655
OnStartContinuation(int32_t instanceId)656 bool AceContainer::OnStartContinuation(int32_t instanceId)
657 {
658 auto container = AceEngine::Get().GetContainer(instanceId);
659 CHECK_NULL_RETURN(container, false);
660 ContainerScope scope(instanceId);
661 auto front = container->GetFrontend();
662 CHECK_NULL_RETURN(front, false);
663 return front->OnStartContinuation();
664 }
665
OnSaveData(int32_t instanceId)666 std::string AceContainer::OnSaveData(int32_t instanceId)
667 {
668 std::string result = "false";
669 auto container = AceEngine::Get().GetContainer(instanceId);
670 CHECK_NULL_RETURN(container, result);
671 ContainerScope scope(instanceId);
672 auto front = container->GetFrontend();
673 CHECK_NULL_RETURN(front, result);
674 front->OnSaveData(result);
675 return result;
676 }
677
OnRestoreData(int32_t instanceId,const std::string & data)678 bool AceContainer::OnRestoreData(int32_t instanceId, const std::string& data)
679 {
680 auto container = AceEngine::Get().GetContainer(instanceId);
681 CHECK_NULL_RETURN(container, false);
682 ContainerScope scope(instanceId);
683 auto front = container->GetFrontend();
684 CHECK_NULL_RETURN(front, false);
685 return front->OnRestoreData(data);
686 }
687
OnCompleteContinuation(int32_t instanceId,int result)688 void AceContainer::OnCompleteContinuation(int32_t instanceId, int result)
689 {
690 auto container = AceEngine::Get().GetContainer(instanceId);
691 CHECK_NULL_VOID(container);
692 ContainerScope scope(instanceId);
693 auto front = container->GetFrontend();
694 CHECK_NULL_VOID(front);
695 front->OnCompleteContinuation(result);
696 }
697
OnRemoteTerminated(int32_t instanceId)698 void AceContainer::OnRemoteTerminated(int32_t instanceId)
699 {
700 auto container = AceEngine::Get().GetContainer(instanceId);
701 CHECK_NULL_VOID(container);
702 ContainerScope scope(instanceId);
703 auto front = container->GetFrontend();
704 CHECK_NULL_VOID(front);
705 front->OnRemoteTerminated();
706 }
707
OnConfigurationUpdated(int32_t instanceId,const std::string & configuration)708 void AceContainer::OnConfigurationUpdated(int32_t instanceId, const std::string& configuration)
709 {
710 auto container = AceEngine::Get().GetContainer(instanceId);
711 CHECK_NULL_VOID(container);
712 ContainerScope scope(instanceId);
713 auto front = container->GetFrontend();
714 CHECK_NULL_VOID(front);
715 front->OnConfigurationUpdated(configuration);
716 }
717
OnNewRequest(int32_t instanceId,const std::string & data)718 void AceContainer::OnNewRequest(int32_t instanceId, const std::string& data)
719 {
720 auto container = AceEngine::Get().GetContainer(instanceId);
721 CHECK_NULL_VOID(container);
722 ContainerScope scope(instanceId);
723 auto front = container->GetFrontend();
724 CHECK_NULL_VOID(front);
725 front->OnNewRequest(data);
726 }
727
InitializeCallback()728 void AceContainer::InitializeCallback()
729 {
730 ACE_FUNCTION_TRACE();
731
732 ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
733 auto&& touchEventCallback = [context = pipelineContext_, id = instanceId_](
734 const TouchEvent& event, const std::function<void()>& markProcess,
735 const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
736 ContainerScope scope(id);
737 context->GetTaskExecutor()->PostTask(
738 [context, event, markProcess, node]() {
739 if (node) {
740 context->OnTouchEvent(event, node);
741 } else {
742 context->OnTouchEvent(event);
743 }
744 CHECK_NULL_VOID(markProcess);
745 markProcess();
746 },
747 TaskExecutor::TaskType::UI);
748 };
749 aceView_->RegisterTouchEventCallback(touchEventCallback);
750
751 auto&& mouseEventCallback = [context = pipelineContext_, id = instanceId_](
752 const MouseEvent& event, const std::function<void()>& markProcess,
753 const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
754 ContainerScope scope(id);
755 context->GetTaskExecutor()->PostTask(
756 [context, event, markProcess, node]() {
757 if (node) {
758 context->OnMouseEvent(event, node);
759 } else {
760 context->OnMouseEvent(event);
761 }
762 CHECK_NULL_VOID(markProcess);
763 markProcess();
764 },
765 TaskExecutor::TaskType::UI);
766 };
767 aceView_->RegisterMouseEventCallback(mouseEventCallback);
768
769 auto&& axisEventCallback = [context = pipelineContext_, id = instanceId_](
770 const AxisEvent& event, const std::function<void()>& markProcess,
771 const RefPtr<OHOS::Ace::NG::FrameNode>& node) {
772 ContainerScope scope(id);
773 context->GetTaskExecutor()->PostTask(
774 [context, event, markProcess, node]() {
775 if (node) {
776 context->OnAxisEvent(event, node);
777 } else {
778 context->OnAxisEvent(event);
779 }
780 CHECK_NULL_VOID(markProcess);
781 markProcess();
782 },
783 TaskExecutor::TaskType::UI);
784 };
785 aceView_->RegisterAxisEventCallback(axisEventCallback);
786
787 auto&& keyEventCallback = [context = pipelineContext_, id = instanceId_](const KeyEvent& event) {
788 ContainerScope scope(id);
789 bool result = false;
790 context->GetTaskExecutor()->PostSyncTask(
791 [context, event, &result]() {
792 result = context->OnKeyEvent(event);
793 },
794 TaskExecutor::TaskType::UI);
795 return result;
796 };
797 aceView_->RegisterKeyEventCallback(keyEventCallback);
798
799 auto&& rotationEventCallback = [context = pipelineContext_, id = instanceId_](const RotationEvent& event) {
800 ContainerScope scope(id);
801 bool result = false;
802 context->GetTaskExecutor()->PostSyncTask(
803 [context, event, &result]() { result = context->OnRotationEvent(event); }, TaskExecutor::TaskType::UI);
804 return result;
805 };
806 aceView_->RegisterRotationEventCallback(rotationEventCallback);
807
808 auto&& viewChangeCallback = [context = pipelineContext_, id = instanceId_](int32_t width, int32_t height,
809 WindowSizeChangeReason type,
810 const std::shared_ptr<Rosen::RSTransaction>& rsTransaction) {
811 ContainerScope scope(id);
812 ACE_SCOPED_TRACE("ViewChangeCallback(%d, %d)", width, height);
813
814 if (type != WindowSizeChangeReason::ROTATION) {
815 context->SetSurfaceChangeMsg(width, height, type, rsTransaction);
816 context->RequestFrame();
817 return;
818 }
819 context->ResetSurfaceChangeMsg();
820
821 auto callback = [context, width, height, type, rsTransaction, id]() {
822 context->OnSurfaceChanged(width, height, type, rsTransaction);
823 if (type == WindowSizeChangeReason::ROTATION) {
824 auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(id);
825 CHECK_NULL_VOID(subwindow);
826 subwindow->ResizeWindow();
827 }
828 };
829 auto container = Container::Current();
830 CHECK_NULL_VOID(container);
831 auto taskExecutor = container->GetTaskExecutor();
832 CHECK_NULL_VOID(taskExecutor);
833 if ((container->IsUseStageModel() && type == WindowSizeChangeReason::ROTATION) ||
834 taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
835 callback();
836 } else {
837 taskExecutor->PostTask(callback, TaskExecutor::TaskType::UI);
838 }
839 };
840 aceView_->RegisterViewChangeCallback(viewChangeCallback);
841
842 auto&& viewPositionChangeCallback = [context = pipelineContext_, id = instanceId_](int32_t posX, int32_t posY) {
843 ContainerScope scope(id);
844 ACE_SCOPED_TRACE("ViewPositionChangeCallback(%d, %d)", posX, posY);
845 context->GetTaskExecutor()->PostTask(
846 [context, posX, posY]() { context->OnSurfacePositionChanged(posX, posY); }, TaskExecutor::TaskType::UI);
847 };
848 aceView_->RegisterViewPositionChangeCallback(viewPositionChangeCallback);
849
850 auto&& densityChangeCallback = [context = pipelineContext_, id = instanceId_](double density) {
851 ContainerScope scope(id);
852 ACE_SCOPED_TRACE("DensityChangeCallback(%lf)", density);
853 auto callback = [context, density]() { context->OnSurfaceDensityChanged(density); };
854 auto taskExecutor = context->GetTaskExecutor();
855 CHECK_NULL_VOID(taskExecutor);
856 if (taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
857 callback();
858 } else {
859 taskExecutor->PostTask(callback, TaskExecutor::TaskType::UI);
860 }
861 };
862 aceView_->RegisterDensityChangeCallback(densityChangeCallback);
863
864 auto&& systemBarHeightChangeCallback = [context = pipelineContext_, id = instanceId_](
865 double statusBar, double navigationBar) {
866 ContainerScope scope(id);
867 ACE_SCOPED_TRACE("SystemBarHeightChangeCallback(%lf, %lf)", statusBar, navigationBar);
868 context->GetTaskExecutor()->PostTask(
869 [context, statusBar, navigationBar]() { context->OnSystemBarHeightChanged(statusBar, navigationBar); },
870 TaskExecutor::TaskType::UI);
871 };
872 aceView_->RegisterSystemBarHeightChangeCallback(systemBarHeightChangeCallback);
873
874 auto&& surfaceDestroyCallback = [context = pipelineContext_, id = instanceId_]() {
875 ContainerScope scope(id);
876 context->GetTaskExecutor()->PostTask(
877 [context]() { context->OnSurfaceDestroyed(); }, TaskExecutor::TaskType::UI);
878 };
879 aceView_->RegisterSurfaceDestroyCallback(surfaceDestroyCallback);
880
881 if (!isFormRender_) {
882 auto&& dragEventCallback = [context = pipelineContext_, id = instanceId_](
883 const PointerEvent& pointerEvent, const DragEventAction& action) {
884 ContainerScope scope(id);
885 context->GetTaskExecutor()->PostTask(
886 [context, pointerEvent, action]() { context->OnDragEvent(pointerEvent, action); },
887 TaskExecutor::TaskType::UI);
888 };
889 aceView_->RegisterDragEventCallback(dragEventCallback);
890 }
891 }
892
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)893 void AceContainer::CreateContainer(int32_t instanceId, FrontendType type, const std::string& instanceName,
894 std::shared_ptr<OHOS::AppExecFwk::Ability> aceAbility, std::unique_ptr<PlatformEventCallback> callback,
895 bool useCurrentEventRunner, bool useNewPipeline)
896 {
897 auto aceContainer = AceType::MakeRefPtr<AceContainer>(
898 instanceId, type, aceAbility, std::move(callback), useCurrentEventRunner, useNewPipeline);
899 AceEngine::Get().AddContainer(instanceId, aceContainer);
900 aceContainer->Initialize();
901 ContainerScope scope(instanceId);
902 auto front = aceContainer->GetFrontend();
903 if (front) {
904 front->UpdateState(Frontend::State::ON_CREATE);
905 front->SetJsMessageDispatcher(aceContainer);
906 }
907
908 auto jsFront = AceType::DynamicCast<JsFrontend>(front);
909 CHECK_NULL_VOID(jsFront);
910 jsFront->SetInstanceName(instanceName);
911 }
912
DestroyContainer(int32_t instanceId,const std::function<void ()> & destroyCallback)913 void AceContainer::DestroyContainer(int32_t instanceId, const std::function<void()>& destroyCallback)
914 {
915 SubwindowManager::GetInstance()->CloseDialog(instanceId);
916 auto container = AceEngine::Get().GetContainer(instanceId);
917 CHECK_NULL_VOID(container);
918 container->Destroy();
919 // unregister watchdog before stop thread to avoid UI_BLOCK report
920 AceEngine::Get().UnRegisterFromWatchDog(instanceId);
921 auto taskExecutor = container->GetTaskExecutor();
922 CHECK_NULL_VOID(taskExecutor);
923
924 taskExecutor->PostSyncTask([] { LOGI("Wait UI thread..."); }, TaskExecutor::TaskType::UI);
925 taskExecutor->PostSyncTask([] { LOGI("Wait JS thread..."); }, TaskExecutor::TaskType::JS);
926
927 container->DestroyView(); // Stop all threads(ui,gpu,io) for current ability.
928 auto removeContainerTask = [instanceId, destroyCallback] {
929 LOGI("Remove on Platform thread...");
930 EngineHelper::RemoveEngine(instanceId);
931 AceEngine::Get().RemoveContainer(instanceId);
932 CHECK_NULL_VOID(destroyCallback);
933 destroyCallback();
934 };
935 if (container->GetSettings().usePlatformAsUIThread) {
936 removeContainerTask();
937 } else {
938 taskExecutor->PostTask(removeContainerTask, TaskExecutor::TaskType::PLATFORM);
939 }
940 }
941
SetView(AceView * view,double density,int32_t width,int32_t height,sptr<OHOS::Rosen::Window> rsWindow,UIEnvCallback callback)942 void AceContainer::SetView(AceView* view, double density, int32_t width, int32_t height,
943 sptr<OHOS::Rosen::Window> rsWindow, UIEnvCallback callback)
944 {
945 CHECK_NULL_VOID(view);
946 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(view->GetInstanceId()));
947 CHECK_NULL_VOID(container);
948 #ifdef ENABLE_ROSEN_BACKEND
949 auto taskExecutor = container->GetTaskExecutor();
950 CHECK_NULL_VOID(taskExecutor);
951 auto window = std::make_shared<NG::RosenWindow>(rsWindow, taskExecutor, view->GetInstanceId());
952 #else
953 auto platformWindow = PlatformWindow::Create(view);
954 CHECK_NULL_VOID(platformWindow);
955 auto window = std::make_shared<Window>(std::move(platformWindow));
956 #endif
957 AceContainer::SetUIWindow(view->GetInstanceId(), rsWindow);
958 container->AttachView(window, view, density, width, height, rsWindow->GetWindowId(), callback);
959 }
960
SetViewNew(AceView * view,double density,float width,float height,sptr<OHOS::Rosen::Window> rsWindow)961 UIContentErrorCode AceContainer::SetViewNew(
962 AceView* view, double density, float width, float height, sptr<OHOS::Rosen::Window> rsWindow)
963 {
964 #ifdef ENABLE_ROSEN_BACKEND
965 CHECK_NULL_RETURN(view, UIContentErrorCode::NULL_POINTER);
966 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(view->GetInstanceId()));
967 CHECK_NULL_RETURN(container, UIContentErrorCode::NULL_POINTER);
968 auto taskExecutor = container->GetTaskExecutor();
969 CHECK_NULL_RETURN(taskExecutor, UIContentErrorCode::NULL_POINTER);
970 AceContainer::SetUIWindow(view->GetInstanceId(), rsWindow);
971
972 if (container->isFormRender_) {
973 auto window = std::make_shared<FormRenderWindow>(taskExecutor, view->GetInstanceId());
974 container->AttachView(window, view, density, width, height, view->GetInstanceId(), nullptr);
975 } else {
976 auto window = std::make_shared<NG::RosenWindow>(rsWindow, taskExecutor, view->GetInstanceId());
977 container->AttachView(window, view, density, width, height, rsWindow->GetWindowId(), nullptr);
978 }
979
980 return UIContentErrorCode::NO_ERRORS;
981 #endif
982 }
983
SetUIWindow(int32_t instanceId,sptr<OHOS::Rosen::Window> uiWindow)984 void AceContainer::SetUIWindow(int32_t instanceId, sptr<OHOS::Rosen::Window> uiWindow)
985 {
986 CHECK_NULL_VOID(uiWindow);
987 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
988 CHECK_NULL_VOID(container);
989 container->SetUIWindowInner(uiWindow);
990 }
991
GetUIWindow(int32_t instanceId)992 sptr<OHOS::Rosen::Window> AceContainer::GetUIWindow(int32_t instanceId)
993 {
994 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
995 CHECK_NULL_RETURN(container, nullptr);
996 return container->GetUIWindowInner();
997 }
998
GetAbility(int32_t instanceId)999 OHOS::AppExecFwk::Ability* AceContainer::GetAbility(int32_t instanceId)
1000 {
1001 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1002 CHECK_NULL_RETURN(container, nullptr);
1003 return container->GetAbilityInner().lock().get();
1004 }
1005
RunPage(int32_t instanceId,const std::string & content,const std::string & params,bool isNamedRouter)1006 UIContentErrorCode AceContainer::RunPage(
1007 int32_t instanceId, const std::string& content, const std::string& params, bool isNamedRouter)
1008 {
1009 auto container = AceEngine::Get().GetContainer(instanceId);
1010 CHECK_NULL_RETURN(container, UIContentErrorCode::NULL_POINTER);
1011
1012 auto aceContainer = DynamicCast<AceContainer>(container);
1013 CHECK_NULL_RETURN(aceContainer, UIContentErrorCode::NULL_POINTER);
1014 bool isStageModel = aceContainer->IsUseStageModel();
1015 bool isFormRender = aceContainer->IsFormRender();
1016 if (isStageModel && content.size() == 0) {
1017 return UIContentErrorCode::NULL_URL;
1018 }
1019
1020 if (!isFormRender && !isNamedRouter && isStageModel && !CheckUrlValid(content, container->GetHapPath())) {
1021 return UIContentErrorCode::INVALID_URL;
1022 }
1023
1024 ContainerScope scope(instanceId);
1025 auto front = container->GetFrontend();
1026 CHECK_NULL_RETURN(front, UIContentErrorCode::NULL_POINTER);
1027 if (isNamedRouter) {
1028 return front->RunPageByNamedRouter(content);
1029 }
1030
1031 return front->RunPage(content, params);
1032 }
1033
RunPage(int32_t instanceId,const std::shared_ptr<std::vector<uint8_t>> & content,const std::string & params)1034 UIContentErrorCode AceContainer::RunPage(
1035 int32_t instanceId, const std::shared_ptr<std::vector<uint8_t>>& content, const std::string& params)
1036 {
1037 auto container = AceEngine::Get().GetContainer(instanceId);
1038 CHECK_NULL_RETURN(container, UIContentErrorCode::NULL_POINTER);
1039 ContainerScope scope(instanceId);
1040 auto front = container->GetFrontend();
1041 CHECK_NULL_RETURN(front, UIContentErrorCode::NULL_POINTER);
1042 return front->RunPage(content, params);
1043 }
1044
RunDynamicPage(int32_t instanceId,const std::string & content,const std::string & params,const std::string & entryPoint)1045 bool AceContainer::RunDynamicPage(
1046 int32_t instanceId, const std::string& content, const std::string& params, const std::string& entryPoint)
1047 {
1048 auto container = AceEngine::Get().GetContainer(instanceId);
1049 CHECK_NULL_RETURN(container, false);
1050 ContainerScope scope(instanceId);
1051 auto front = container->GetFrontend();
1052 CHECK_NULL_RETURN(front, false);
1053 front->RunDynamicPage(content, params, entryPoint);
1054 return true;
1055 }
1056
PushPage(int32_t instanceId,const std::string & content,const std::string & params)1057 bool AceContainer::PushPage(int32_t instanceId, const std::string& content, const std::string& params)
1058 {
1059 auto container = AceEngine::Get().GetContainer(instanceId);
1060 CHECK_NULL_RETURN(container, false);
1061 ContainerScope scope(instanceId);
1062 auto front = container->GetFrontend();
1063 CHECK_NULL_RETURN(front, false);
1064 front->PushPage(content, params);
1065 return true;
1066 }
1067
UpdatePage(int32_t instanceId,int32_t pageId,const std::string & content)1068 bool AceContainer::UpdatePage(int32_t instanceId, int32_t pageId, const std::string& content)
1069 {
1070 auto container = AceEngine::Get().GetContainer(instanceId);
1071 CHECK_NULL_RETURN(container, false);
1072 ContainerScope scope(instanceId);
1073 auto context = container->GetPipelineContext();
1074 CHECK_NULL_RETURN(context, false);
1075 return context->CallRouterBackToPopPage();
1076 }
1077
1078 class FillRequestCallback : public AbilityRuntime::IFillRequestCallback {
1079 public:
FillRequestCallback(WeakPtr<NG::PipelineContext> pipelineContext,const RefPtr<NG::FrameNode> & node,AceAutoFillType autoFillType)1080 FillRequestCallback(WeakPtr<NG::PipelineContext> pipelineContext, const RefPtr<NG::FrameNode>& node,
1081 AceAutoFillType autoFillType)
1082 : pipelineContext_(pipelineContext), node_(node), autoFillType_(autoFillType) {}
1083 virtual ~FillRequestCallback() = default;
OnFillRequestSuccess(const AbilityBase::ViewData & viewData)1084 void OnFillRequestSuccess(const AbilityBase::ViewData& viewData) override
1085 {
1086 TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called, pageUrl=[%{private}s]", viewData.pageUrl.c_str());
1087 auto pipelineContext = pipelineContext_.Upgrade();
1088 CHECK_NULL_VOID(pipelineContext);
1089 auto taskExecutor = pipelineContext->GetTaskExecutor();
1090 CHECK_NULL_VOID(taskExecutor);
1091 auto viewDataWrap = ViewDataWrap::CreateViewDataWrap(viewData);
1092 CHECK_NULL_VOID(viewDataWrap);
1093 taskExecutor->PostTask(
1094 [viewDataWrap, pipelineContext, autoFillType = autoFillType_]() {
1095 if (pipelineContext) {
1096 pipelineContext->NotifyFillRequestSuccess(autoFillType, viewDataWrap);
1097 }
1098 },
1099 TaskExecutor::TaskType::UI);
1100 }
1101
OnFillRequestFailed(int32_t errCode)1102 void OnFillRequestFailed(int32_t errCode) override
1103 {
1104 TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called, errCode: %{public}d", errCode);
1105 auto pipelineContext = pipelineContext_.Upgrade();
1106 CHECK_NULL_VOID(pipelineContext);
1107 auto node = node_.Upgrade();
1108 CHECK_NULL_VOID(node);
1109 auto taskExecutor = pipelineContext->GetTaskExecutor();
1110 CHECK_NULL_VOID(taskExecutor);
1111 taskExecutor->PostTask(
1112 [errCode, pipelineContext, node]() {
1113 if (pipelineContext) {
1114 pipelineContext->NotifyFillRequestFailed(node, errCode);
1115 }
1116 },
1117 TaskExecutor::TaskType::UI);
1118 }
1119 private:
1120 WeakPtr<NG::PipelineContext> pipelineContext_ = nullptr;
1121 WeakPtr<NG::FrameNode> node_ = nullptr;
1122 AceAutoFillType autoFillType_ = AceAutoFillType::ACE_UNSPECIFIED;
1123 };
1124
RequestAutoFill(const RefPtr<NG::FrameNode> & node,AceAutoFillType autoFillType)1125 bool AceContainer::RequestAutoFill(const RefPtr<NG::FrameNode>& node, AceAutoFillType autoFillType)
1126 {
1127 TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called, autoFillType: %{public}d", static_cast<int32_t>(autoFillType));
1128 auto pipelineContext = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);
1129 CHECK_NULL_RETURN(pipelineContext, false);
1130 CHECK_NULL_RETURN(uiWindow_, false);
1131 auto uiContent = uiWindow_->GetUIContent();
1132 auto uiContentImpl = reinterpret_cast<UIContentImpl*>(uiContent);
1133 CHECK_NULL_RETURN(uiContentImpl, false);
1134 auto viewDataWrap = ViewDataWrap::CreateViewDataWrap();
1135 uiContentImpl->DumpViewData(node, viewDataWrap);
1136
1137 auto callback = std::make_shared<FillRequestCallback>(pipelineContext, node, autoFillType);
1138 auto viewDataWrapOhos = AceType::DynamicCast<ViewDataWrapOhos>(viewDataWrap);
1139 CHECK_NULL_RETURN(viewDataWrapOhos, false);
1140 auto viewData = viewDataWrapOhos->GetViewData();
1141 if (AbilityRuntime::AutoFillManager::GetInstance().RequestAutoFill(
1142 static_cast<AbilityBase::AutoFillType>(autoFillType), uiContent, viewData, callback) != 0) {
1143 return false;
1144 }
1145 return true;
1146 }
1147
1148 class SaveRequestCallback : public AbilityRuntime::ISaveRequestCallback {
1149 public:
1150 SaveRequestCallback() = default;
1151 virtual ~SaveRequestCallback() = default;
OnSaveRequestSuccess()1152 void OnSaveRequestSuccess() override
1153 {
1154 TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called");
1155 }
1156
OnSaveRequestFailed()1157 void OnSaveRequestFailed() override
1158 {
1159 TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called");
1160 }
1161 };
1162
RequestAutoSave(const RefPtr<NG::FrameNode> & node)1163 bool AceContainer::RequestAutoSave(const RefPtr<NG::FrameNode>& node)
1164 {
1165 TAG_LOGI(AceLogTag::ACE_AUTO_FILL, "called");
1166 CHECK_NULL_RETURN(uiWindow_, false);
1167 auto uiContent = uiWindow_->GetUIContent();
1168 auto uiContentImpl = reinterpret_cast<UIContentImpl*>(uiContent);
1169 CHECK_NULL_RETURN(uiContentImpl, false);
1170 auto viewDataWrap = ViewDataWrap::CreateViewDataWrap();
1171 uiContentImpl->DumpViewData(node, viewDataWrap);
1172
1173 auto callback = std::make_shared<SaveRequestCallback>();
1174 auto viewDataWrapOhos = AceType::DynamicCast<ViewDataWrapOhos>(viewDataWrap);
1175 CHECK_NULL_RETURN(viewDataWrapOhos, false);
1176 auto viewData = viewDataWrapOhos->GetViewData();
1177 if (AbilityRuntime::AutoFillManager::GetInstance().RequestAutoSave(uiContent, viewData, callback) != 0) {
1178 return false;
1179 }
1180 return true;
1181 }
1182
GetNavigationController(const std::string & navigationId)1183 std::shared_ptr<NavigationController> AceContainer::GetNavigationController(
1184 const std::string& navigationId)
1185 {
1186 CHECK_NULL_RETURN(pipelineContext_, nullptr);
1187 return pipelineContext_->GetNavigationController(navigationId);
1188 }
1189
SetHapPath(const std::string & hapPath)1190 void AceContainer::SetHapPath(const std::string& hapPath)
1191 {
1192 if (hapPath.empty()) {
1193 LOGW("SetHapPath, Use .index to load resource");
1194 return;
1195 }
1196 LOGI("SetHapPath, Use hap path to load resource");
1197 webHapPath_ = hapPath;
1198 resourceInfo_.SetHapPath(hapPath);
1199 SystemProperties::SetUnZipHap(false);
1200 }
1201
Dispatch(const std::string & group,std::vector<uint8_t> && data,int32_t id,bool replyToComponent) const1202 void AceContainer::Dispatch(
1203 const std::string& group, std::vector<uint8_t>&& data, int32_t id, bool replyToComponent) const
1204 {
1205 return;
1206 }
1207
DispatchPluginError(int32_t callbackId,int32_t errorCode,std::string && errorMessage) const1208 void AceContainer::DispatchPluginError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const
1209 {
1210 auto front = GetFrontend();
1211 CHECK_NULL_VOID(front);
1212 ContainerScope scope(instanceId_);
1213 taskExecutor_->PostTask(
1214 [front, callbackId, errorCode, errorMessage = std::move(errorMessage)]() mutable {
1215 front->TransferJsPluginGetError(callbackId, errorCode, std::move(errorMessage));
1216 },
1217 TaskExecutor::TaskType::BACKGROUND);
1218 }
1219
Dump(const std::vector<std::string> & params,std::vector<std::string> & info)1220 bool AceContainer::Dump(const std::vector<std::string>& params, std::vector<std::string>& info)
1221 {
1222 if (isDumping_.test_and_set()) {
1223 LOGW("another dump is still running");
1224 return false;
1225 }
1226 ContainerScope scope(instanceId_);
1227 auto result = false;
1228 std::unique_ptr<std::ostream> ostream = std::make_unique<std::ostringstream>();
1229 CHECK_NULL_RETURN(ostream, false);
1230 DumpLog::GetInstance().SetDumpFile(std::move(ostream));
1231 result = DumpInfo(params);
1232 const auto& infoFile = DumpLog::GetInstance().GetDumpFile();
1233 auto* ostringstream = static_cast<std::ostringstream*>(infoFile.get());
1234 info.emplace_back(ostringstream->str());
1235 DumpLog::GetInstance().Reset();
1236 if (!result) {
1237 DumpLog::ShowDumpHelp(info);
1238 }
1239 isDumping_.clear();
1240 return true;
1241 }
1242
DumpInfo(const std::vector<std::string> & params)1243 bool AceContainer::DumpInfo(const std::vector<std::string>& params)
1244 {
1245 if (aceView_ && aceView_->Dump(params)) {
1246 return true;
1247 }
1248
1249 if (OnDumpInfo(params)) {
1250 return true;
1251 }
1252 CHECK_NULL_RETURN(pipelineContext_, false);
1253 return pipelineContext_->Dump(params);
1254 }
1255
OnDumpInfo(const std::vector<std::string> & params)1256 bool AceContainer::OnDumpInfo(const std::vector<std::string>& params)
1257 {
1258 if (!params.empty() && params[0] == "-basicinfo") {
1259 DumpLog::GetInstance().Print("BasicInfo: ");
1260 DumpLog::GetInstance().Print(1, "InstanceId: " + std::to_string(instanceId_));
1261 DumpLog::GetInstance().Print(1,
1262 "FrontendType: " + std::to_string(static_cast<typename std::underlying_type<FrontendType>::type>(type_)));
1263 DumpLog::GetInstance().Print(1, "NewPipeline: " + std::string(IsUseNewPipeline() ? "true" : "false"));
1264 DumpLog::GetInstance().Print(1, "WindowName: " + windowName_);
1265 DumpLog::GetInstance().Print(
1266 1, "WindowState: " +
1267 (!frontend_ ? "frontend is null"
1268 : std::to_string(static_cast<typename std::underlying_type<Frontend::State>::type>(
1269 frontend_->GetState()))));
1270 DumpLog::GetInstance().Print(1, "Language: " + AceApplicationInfo::GetInstance().GetLocaleTag());
1271 DumpLog::GetInstance().Print(
1272 1, "RTL: " + std::string(AceApplicationInfo::GetInstance().IsRightToLeft() ? "true" : "false"));
1273 DumpLog::GetInstance().Print(
1274 1, "ColorMode: " + std::string(SystemProperties::GetColorMode() == ColorMode::DARK ? "Dark" : "Light"));
1275 DumpLog::GetInstance().Print(1,
1276 "DeviceOrientation: " + std::string(SystemProperties::GetDeviceOrientation() == DeviceOrientation::LANDSCAPE
1277 ? "Landscape"
1278 : "Portrait"));
1279 DumpLog::GetInstance().Print(1, "Resolution: " + std::to_string(SystemProperties::GetDeviceWidth()) + "*" +
1280 std::to_string(SystemProperties::GetDeviceHeight()));
1281 if (pipelineContext_) {
1282 DumpLog::GetInstance().Print(1, "AppBgColor: " + pipelineContext_->GetAppBgColor().ColorToString());
1283 DumpLog::GetInstance().Print(1, "Density: " + std::to_string(pipelineContext_->GetDensity()));
1284 DumpLog::GetInstance().Print(1, "ViewScale: " + std::to_string(pipelineContext_->GetViewScale()));
1285 DumpLog::GetInstance().Print(
1286 1, "DisplayWindowRect: " + pipelineContext_->GetDisplayWindowRectInfo().ToString());
1287 }
1288 DumpLog::GetInstance().Print(1, "ApiVersion: " + SystemProperties::GetApiVersion());
1289 DumpLog::GetInstance().Print(1, "ReleaseType: " + SystemProperties::GetReleaseType());
1290 DumpLog::GetInstance().Print(1, "DeviceType: " + SystemProperties::GetParamDeviceType());
1291 return true;
1292 }
1293 return false;
1294 }
1295
TriggerGarbageCollection()1296 void AceContainer::TriggerGarbageCollection()
1297 {
1298 ContainerScope scope(instanceId_);
1299 #if !defined(OHOS_PLATFORM) || !defined(ENABLE_NATIVE_VIEW)
1300 // GPU and IO thread is standalone while disable native view
1301 taskExecutor_->PostTask([] { PurgeMallocCache(); }, TaskExecutor::TaskType::GPU);
1302 taskExecutor_->PostTask([] { PurgeMallocCache(); }, TaskExecutor::TaskType::IO);
1303 #endif
1304 taskExecutor_->PostTask([] { PurgeMallocCache(); }, TaskExecutor::TaskType::UI);
1305 taskExecutor_->PostTask(
1306 [frontend = WeakPtr<Frontend>(frontend_)] {
1307 auto sp = frontend.Upgrade();
1308 if (sp) {
1309 sp->TriggerGarbageCollection();
1310 }
1311 PurgeMallocCache();
1312 },
1313 TaskExecutor::TaskType::JS);
1314 }
1315
DumpHeapSnapshot(bool isPrivate)1316 void AceContainer::DumpHeapSnapshot(bool isPrivate)
1317 {
1318 taskExecutor_->PostTask(
1319 [isPrivate, frontend = WeakPtr<Frontend>(frontend_)] {
1320 auto sp = frontend.Upgrade();
1321 CHECK_NULL_VOID(sp);
1322 sp->DumpHeapSnapshot(isPrivate);
1323 },
1324 TaskExecutor::TaskType::JS);
1325 }
1326
DestroyHeapProfiler()1327 void AceContainer::DestroyHeapProfiler()
1328 {
1329 taskExecutor_->PostTask(
1330 [frontend = WeakPtr<Frontend>(frontend_)] {
1331 auto sp = frontend.Upgrade();
1332 CHECK_NULL_VOID(sp);
1333 sp->DestroyHeapProfiler();
1334 },
1335 TaskExecutor::TaskType::JS);
1336 }
1337
ForceFullGC()1338 void AceContainer::ForceFullGC()
1339 {
1340 taskExecutor_->PostTask(
1341 [frontend = WeakPtr<Frontend>(frontend_)] {
1342 auto sp = frontend.Upgrade();
1343 CHECK_NULL_VOID(sp);
1344 sp->ForceFullGC();
1345 },
1346 TaskExecutor::TaskType::JS);
1347 }
1348
SetLocalStorage(NativeReference * storage,NativeReference * context)1349 void AceContainer::SetLocalStorage(NativeReference* storage, NativeReference* context)
1350 {
1351 ContainerScope scope(instanceId_);
1352 taskExecutor_->PostTask(
1353 [frontend = WeakPtr<Frontend>(frontend_), storage, context, id = instanceId_] {
1354 auto sp = frontend.Upgrade();
1355 CHECK_NULL_VOID(sp);
1356 #ifdef NG_BUILD
1357 auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontendNG>(sp);
1358 #else
1359 auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(sp);
1360 #endif
1361 CHECK_NULL_VOID(declarativeFrontend);
1362 auto jsEngine = declarativeFrontend->GetJsEngine();
1363 CHECK_NULL_VOID(jsEngine);
1364 if (context) {
1365 jsEngine->SetContext(id, context);
1366 }
1367 if (storage) {
1368 jsEngine->SetLocalStorage(id, storage);
1369 }
1370 },
1371 TaskExecutor::TaskType::JS);
1372 }
1373
AddAssetPath(int32_t instanceId,const std::string & packagePath,const std::string & hapPath,const std::vector<std::string> & paths)1374 void AceContainer::AddAssetPath(int32_t instanceId, const std::string& packagePath, const std::string& hapPath,
1375 const std::vector<std::string>& paths)
1376 {
1377 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1378 CHECK_NULL_VOID(container);
1379 RefPtr<AssetManagerImpl> assetManagerImpl;
1380 if (container->assetManager_) {
1381 assetManagerImpl = AceType::DynamicCast<AssetManagerImpl>(container->assetManager_);
1382 } else {
1383 assetManagerImpl = Referenced::MakeRefPtr<AssetManagerImpl>();
1384 container->assetManager_ = assetManagerImpl;
1385 if (container->type_ != FrontendType::DECLARATIVE_JS) {
1386 container->frontend_->SetAssetManager(assetManagerImpl);
1387 }
1388 }
1389 CHECK_NULL_VOID(assetManagerImpl);
1390 if (!hapPath.empty()) {
1391 auto assetProvider = AceType::MakeRefPtr<HapAssetProviderImpl>();
1392 if (assetProvider->Initialize(hapPath, paths)) {
1393 LOGI("Push AssetProvider to queue.");
1394 assetManagerImpl->PushBack(std::move(assetProvider));
1395 }
1396 }
1397 if (!packagePath.empty()) {
1398 auto assetProvider = AceType::MakeRefPtr<FileAssetProviderImpl>();
1399 if (assetProvider->Initialize(packagePath, paths)) {
1400 LOGI("Push AssetProvider to queue.");
1401 assetManagerImpl->PushBack(std::move(assetProvider));
1402 }
1403 }
1404 }
1405
AddLibPath(int32_t instanceId,const std::vector<std::string> & libPath)1406 void AceContainer::AddLibPath(int32_t instanceId, const std::vector<std::string>& libPath)
1407 {
1408 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1409 CHECK_NULL_VOID(container);
1410 RefPtr<AssetManager> assetManagerImpl;
1411 if (container->assetManager_) {
1412 assetManagerImpl = AceType::DynamicCast<AssetManagerImpl>(container->assetManager_);
1413 } else {
1414 assetManagerImpl = Referenced::MakeRefPtr<AssetManagerImpl>();
1415 container->assetManager_ = assetManagerImpl;
1416 if (container->type_ != FrontendType::DECLARATIVE_JS) {
1417 container->frontend_->SetAssetManager(assetManagerImpl);
1418 }
1419 }
1420 CHECK_NULL_VOID(assetManagerImpl);
1421 assetManagerImpl->SetLibPath("default", libPath);
1422 }
1423
AttachView(std::shared_ptr<Window> window,AceView * view,double density,float width,float height,uint32_t windowId,UIEnvCallback callback)1424 void AceContainer::AttachView(std::shared_ptr<Window> window, AceView* view, double density, float width,
1425 float height, uint32_t windowId, UIEnvCallback callback)
1426 {
1427 aceView_ = view;
1428 auto instanceId = aceView_->GetInstanceId();
1429 auto taskExecutorImpl = AceType::DynamicCast<TaskExecutorImpl>(taskExecutor_);
1430 if (!isSubContainer_) {
1431 auto* aceView = static_cast<AceViewOhos*>(aceView_);
1432 ACE_DCHECK(aceView != nullptr);
1433 taskExecutorImpl->InitOtherThreads(aceView->GetThreadModelImpl());
1434 }
1435 ContainerScope scope(instanceId);
1436 if (type_ == FrontendType::DECLARATIVE_JS) {
1437 // For DECLARATIVE_JS frontend display UI in JS thread temporarily.
1438 taskExecutorImpl->InitJsThread(false);
1439 InitializeFrontend();
1440 auto front = GetFrontend();
1441 if (front) {
1442 front->UpdateState(Frontend::State::ON_CREATE);
1443 front->SetJsMessageDispatcher(AceType::Claim(this));
1444 front->SetAssetManager(assetManager_);
1445 }
1446 } else if (type_ != FrontendType::JS_CARD) {
1447 aceView_->SetCreateTime(createTime_);
1448 }
1449 resRegister_ = aceView_->GetPlatformResRegister();
1450 #ifndef NG_BUILD
1451 if (useNewPipeline_) {
1452 LOGI("New pipeline version creating...");
1453 pipelineContext_ = AceType::MakeRefPtr<NG::PipelineContext>(
1454 window, taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
1455 pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<NG::TextFieldManagerNG>());
1456 } else {
1457 pipelineContext_ = AceType::MakeRefPtr<PipelineContext>(
1458 window, taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
1459 pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<TextFieldManager>());
1460 }
1461 #else
1462 LOGI("New pipeline version creating...");
1463 pipelineContext_ = AceType::MakeRefPtr<NG::PipelineContext>(
1464 window, taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
1465 pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<NG::TextFieldManagerNG>());
1466 #endif
1467
1468 #ifdef FORM_SUPPORTED
1469 if (isFormRender_) {
1470 pipelineContext_->SetIsFormRender(isFormRender_);
1471 auto cardFrontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
1472 if (cardFrontend) {
1473 cardFrontend->SetTaskExecutor(taskExecutor_);
1474 cardFrontend->SetLoadCardCallBack(WeakPtr<PipelineBase>(pipelineContext_));
1475 }
1476 }
1477 #endif
1478
1479 pipelineContext_->SetRootSize(density, width, height);
1480 if (isFormRender_) {
1481 pipelineContext_->OnSurfaceDensityChanged(density);
1482 }
1483 pipelineContext_->SetIsRightToLeft(AceApplicationInfo::GetInstance().IsRightToLeft());
1484 pipelineContext_->SetWindowId(windowId);
1485 pipelineContext_->SetWindowModal(windowModal_);
1486 if (uiWindow_) {
1487 auto windowType = uiWindow_->GetType();
1488 pipelineContext_->SetIsAppWindow(
1489 windowType < Rosen::WindowType::SYSTEM_WINDOW_BASE && windowType >= Rosen::WindowType::APP_WINDOW_BASE);
1490 }
1491 if (installationFree_) {
1492 pipelineContext_->SetInstallationFree(installationFree_);
1493 pipelineContext_->SetSharePanelCallback(std::move(sharePanelCallback_));
1494 std::shared_ptr<AppExecFwk::AbilityInfo> info = abilityInfo_.lock();
1495 if (info != nullptr) {
1496 pipelineContext_->SetAppLabelId(info->labelId);
1497 }
1498 }
1499 if (isSubContainer_) {
1500 pipelineContext_->SetIsSubPipeline(true);
1501 }
1502
1503 pipelineContext_->SetDrawDelegate(aceView_->GetDrawDelegate());
1504 InitWindowCallback();
1505 InitializeCallback();
1506
1507 auto&& finishEventHandler = [weak = WeakClaim(this), instanceId] {
1508 auto container = weak.Upgrade();
1509 CHECK_NULL_VOID(container);
1510 ContainerScope scope(instanceId);
1511 auto context = container->GetPipelineContext();
1512 CHECK_NULL_VOID(context);
1513 context->GetTaskExecutor()->PostTask(
1514 [weak = WeakPtr<AceContainer>(container)] {
1515 auto container = weak.Upgrade();
1516 CHECK_NULL_VOID(container);
1517 container->OnFinish();
1518 },
1519 TaskExecutor::TaskType::PLATFORM);
1520 };
1521 pipelineContext_->SetFinishEventHandler(finishEventHandler);
1522
1523 auto&& startAbilityHandler = [weak = WeakClaim(this), instanceId](const std::string& address) {
1524 auto container = weak.Upgrade();
1525 CHECK_NULL_VOID(container);
1526 ContainerScope scope(instanceId);
1527 auto context = container->GetPipelineContext();
1528 CHECK_NULL_VOID(context);
1529 context->GetTaskExecutor()->PostTask(
1530 [weak = WeakPtr<AceContainer>(container), address]() {
1531 auto container = weak.Upgrade();
1532 CHECK_NULL_VOID(container);
1533 container->OnStartAbility(address);
1534 },
1535 TaskExecutor::TaskType::PLATFORM);
1536 };
1537 pipelineContext_->SetStartAbilityHandler(startAbilityHandler);
1538
1539 auto&& setStatusBarEventHandler = [weak = WeakClaim(this), instanceId](const Color& color) {
1540 auto container = weak.Upgrade();
1541 CHECK_NULL_VOID(container);
1542 ContainerScope scope(instanceId);
1543 auto context = container->GetPipelineContext();
1544 CHECK_NULL_VOID(context);
1545 context->GetTaskExecutor()->PostTask(
1546 [weak, color = color.GetValue()]() {
1547 auto container = weak.Upgrade();
1548 CHECK_NULL_VOID(container);
1549 if (container->platformEventCallback_) {
1550 container->platformEventCallback_->OnStatusBarBgColorChanged(color);
1551 }
1552 },
1553 TaskExecutor::TaskType::PLATFORM);
1554 };
1555 pipelineContext_->SetStatusBarEventHandler(setStatusBarEventHandler);
1556 if (GetSettings().usePlatformAsUIThread) {
1557 FrameReport::GetInstance().Init();
1558 } else {
1559 taskExecutor_->PostTask([] { FrameReport::GetInstance().Init(); }, TaskExecutor::TaskType::UI);
1560 }
1561
1562 // Load custom style at UI thread before frontend attach, for loading style before building tree.
1563 auto initThemeManagerTask = [pipelineContext = pipelineContext_, assetManager = assetManager_,
1564 colorScheme = colorScheme_, resourceInfo = resourceInfo_,
1565 context = runtimeContext_.lock(), abilityInfo = abilityInfo_.lock()]() {
1566 ACE_SCOPED_TRACE("OHOS::LoadThemes()");
1567
1568 if (SystemProperties::GetResourceDecoupling()) {
1569 InitResourceAndThemeManager(pipelineContext, assetManager, colorScheme, resourceInfo, context, abilityInfo);
1570 } else {
1571 ThemeConstants::InitDeviceType();
1572 auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>();
1573 pipelineContext->SetThemeManager(themeManager);
1574 themeManager->InitResource(resourceInfo);
1575 themeManager->SetColorScheme(colorScheme);
1576 themeManager->LoadCustomTheme(assetManager);
1577 themeManager->LoadResourceThemes();
1578 }
1579 auto themeManager = pipelineContext->GetThemeManager();
1580 if (themeManager) {
1581 pipelineContext->SetAppBgColor(themeManager->GetBackgroundColor());
1582 }
1583 };
1584
1585 auto setupRootElementTask = [context = pipelineContext_, callback, isSubContainer = isSubContainer_]() {
1586 if (callback != nullptr) {
1587 callback(AceType::DynamicCast<PipelineContext>(context));
1588 }
1589 if (!isSubContainer) {
1590 context->SetupRootElement();
1591 }
1592 };
1593 if (GetSettings().usePlatformAsUIThread) {
1594 initThemeManagerTask();
1595 setupRootElementTask();
1596 } else {
1597 taskExecutor_->PostTask(initThemeManagerTask, TaskExecutor::TaskType::UI);
1598 taskExecutor_->PostTask(setupRootElementTask, TaskExecutor::TaskType::UI);
1599 }
1600
1601 aceView_->Launch();
1602
1603 if (!isSubContainer_) {
1604 // Only MainWindow instance in FA model will be registered to watch dog.
1605 if (!GetSettings().usingSharedRuntime && !AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint()) {
1606 AceEngine::Get().RegisterToWatchDog(instanceId, taskExecutor_, GetSettings().useUIAsJSThread);
1607 }
1608 frontend_->AttachPipelineContext(pipelineContext_);
1609 } else {
1610 #ifdef NG_BUILD
1611 auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontendNG>(frontend_);
1612 #else
1613 auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
1614 #endif
1615 if (declarativeFrontend) {
1616 declarativeFrontend->AttachSubPipelineContext(pipelineContext_);
1617 }
1618 return;
1619 }
1620
1621 auto dataAbilityHelperImpl = [ability = GetAbilityInner(), runtimeContext = runtimeContext_,
1622 useStageModel = useStageModel_]() {
1623 return AceType::MakeRefPtr<DataAbilityHelperStandard>(ability.lock(), runtimeContext.lock(), useStageModel);
1624 };
1625 auto dataProviderManager = MakeRefPtr<DataProviderManagerStandard>(dataAbilityHelperImpl);
1626 pipelineContext_->SetDataProviderManager(dataProviderManager);
1627
1628 #if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
1629 pipelineContext_->SetPostRTTaskCallBack([](std::function<void()>&& task) {
1630 auto syncTask = std::make_shared<AceRosenSyncTask>(std::move(task));
1631 Rosen::RSTransactionProxy::GetInstance()->ExecuteSynchronousTask(syncTask);
1632 });
1633 #endif
1634 }
1635
SetUIWindowInner(sptr<OHOS::Rosen::Window> uiWindow)1636 void AceContainer::SetUIWindowInner(sptr<OHOS::Rosen::Window> uiWindow)
1637 {
1638 uiWindow_ = uiWindow;
1639 }
1640
GetUIWindowInner() const1641 sptr<OHOS::Rosen::Window> AceContainer::GetUIWindowInner() const
1642 {
1643 return uiWindow_;
1644 }
1645
GetAbilityInner() const1646 std::weak_ptr<OHOS::AppExecFwk::Ability> AceContainer::GetAbilityInner() const
1647 {
1648 return aceAbility_;
1649 }
1650
IsLauncherContainer()1651 bool AceContainer::IsLauncherContainer()
1652 {
1653 auto runtime = runtimeContext_.lock();
1654 if (!runtime) {
1655 return false;
1656 }
1657 auto info = runtime->GetApplicationInfo();
1658 return info ? info->isLauncherApp : false;
1659 }
1660
IsTransparentBg() const1661 bool AceContainer::IsTransparentBg() const
1662 {
1663 CHECK_NULL_RETURN(pipelineContext_, true);
1664 Color bgColor = pipelineContext_->GetAppBgColor();
1665 std::string bgOpacity = bgColor.ColorToString().substr(0, 3);
1666 std::string transparentOpacity = "#00";
1667 return bgColor == Color::TRANSPARENT || bgOpacity == transparentOpacity;
1668 }
1669
SetFontScale(int32_t instanceId,float fontScale)1670 void AceContainer::SetFontScale(int32_t instanceId, float fontScale)
1671 {
1672 auto container = AceEngine::Get().GetContainer(instanceId);
1673 CHECK_NULL_VOID(container);
1674 ContainerScope scope(instanceId);
1675 auto pipelineContext = container->GetPipelineContext();
1676 CHECK_NULL_VOID(pipelineContext);
1677 pipelineContext->SetFontScale(fontScale);
1678 }
1679
ParseThemeConfig(const std::string & themeConfig)1680 bool AceContainer::ParseThemeConfig(const std::string& themeConfig)
1681 {
1682 std::regex pattern("\"font\":(\\d+)");
1683 std::smatch match;
1684 if (std::regex_search(themeConfig, match, pattern)) {
1685 std::string fontValue = match[1].str();
1686 if (fontValue.length() > 1) {
1687 LOGE("ParseThemeConfig error value");
1688 return false;
1689 }
1690 int font = std::stoi(fontValue);
1691 return font == 1;
1692 }
1693 return false;
1694 }
1695
SetWindowStyle(int32_t instanceId,WindowModal windowModal,ColorScheme colorScheme)1696 void AceContainer::SetWindowStyle(int32_t instanceId, WindowModal windowModal, ColorScheme colorScheme)
1697 {
1698 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1699 CHECK_NULL_VOID(container);
1700 ContainerScope scope(instanceId);
1701 container->SetWindowModal(windowModal);
1702 container->SetColorScheme(colorScheme);
1703 }
1704
SetDialogCallback(int32_t instanceId,FrontendDialogCallback callback)1705 void AceContainer::SetDialogCallback(int32_t instanceId, FrontendDialogCallback callback)
1706 {
1707 auto container = AceEngine::Get().GetContainer(instanceId);
1708 CHECK_NULL_VOID(container);
1709 auto front = container->GetFrontend();
1710 if (front && front->GetType() == FrontendType::JS) {
1711 front->SetDialogCallback(callback);
1712 }
1713 }
1714
RestoreRouterStack(int32_t instanceId,const std::string & contentInfo)1715 std::pair<std::string, UIContentErrorCode> AceContainer::RestoreRouterStack(
1716 int32_t instanceId, const std::string& contentInfo)
1717 {
1718 auto container = AceEngine::Get().GetContainer(instanceId);
1719 CHECK_NULL_RETURN(container, std::make_pair("", UIContentErrorCode::NULL_POINTER));
1720 ContainerScope scope(instanceId);
1721 auto front = container->GetFrontend();
1722 CHECK_NULL_RETURN(front, std::make_pair("", UIContentErrorCode::NULL_POINTER));
1723 return front->RestoreRouterStack(contentInfo);
1724 }
1725
GetContentInfo(int32_t instanceId)1726 std::string AceContainer::GetContentInfo(int32_t instanceId)
1727 {
1728 auto container = AceEngine::Get().GetContainer(instanceId);
1729 CHECK_NULL_RETURN(container, "");
1730 ContainerScope scope(instanceId);
1731 auto front = container->GetFrontend();
1732 CHECK_NULL_RETURN(front, "");
1733 return front->GetContentInfo();
1734 }
1735
SetWindowPos(int32_t left,int32_t top)1736 void AceContainer::SetWindowPos(int32_t left, int32_t top)
1737 {
1738 CHECK_NULL_VOID(frontend_);
1739 auto accessibilityManager = frontend_->GetAccessibilityManager();
1740 CHECK_NULL_VOID(accessibilityManager);
1741 accessibilityManager->SetWindowPos(left, top, windowId_);
1742 }
1743
InitializeSubContainer(int32_t parentContainerId)1744 void AceContainer::InitializeSubContainer(int32_t parentContainerId)
1745 {
1746 auto parentContainer = AceEngine::Get().GetContainer(parentContainerId);
1747 CHECK_NULL_VOID(parentContainer);
1748 auto taskExec = parentContainer->GetTaskExecutor();
1749 taskExecutor_ = AceType::DynamicCast<TaskExecutorImpl>(std::move(taskExec));
1750 auto parentSettings = parentContainer->GetSettings();
1751 GetSettings().useUIAsJSThread = parentSettings.useUIAsJSThread;
1752 GetSettings().usePlatformAsUIThread = parentSettings.usePlatformAsUIThread;
1753 GetSettings().usingSharedRuntime = parentSettings.usingSharedRuntime;
1754 }
1755
InitWindowCallback()1756 void AceContainer::InitWindowCallback()
1757 {
1758 if (!pipelineContext_ || !uiWindow_) {
1759 return;
1760 }
1761 auto& windowManager = pipelineContext_->GetWindowManager();
1762 std::shared_ptr<AppExecFwk::AbilityInfo> info = abilityInfo_.lock();
1763 if (info != nullptr) {
1764 windowManager->SetAppLabelId(info->labelId);
1765 windowManager->SetAppIconId(info->iconId);
1766 }
1767 windowManager->SetWindowMinimizeCallBack([window = uiWindow_]() { window->Minimize(); });
1768 windowManager->SetWindowMaximizeCallBack([window = uiWindow_]() { window->Maximize(); });
1769 windowManager->SetWindowMaximizeFloatingCallBack([window = uiWindow_]() { window->MaximizeFloating(); });
1770 windowManager->SetWindowRecoverCallBack([window = uiWindow_]() { window->Recover(); });
1771 windowManager->SetWindowCloseCallBack([window = uiWindow_]() { window->Close(); });
1772 windowManager->SetWindowStartMoveCallBack([window = uiWindow_]() { window->StartMove(); });
1773 windowManager->SetWindowSplitPrimaryCallBack(
1774 [window = uiWindow_]() { window->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_SPLIT_PRIMARY); });
1775 windowManager->SetWindowSplitSecondaryCallBack(
1776 [window = uiWindow_]() { window->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_SPLIT_SECONDARY); });
1777 windowManager->SetWindowGetModeCallBack(
1778 [window = uiWindow_]() -> WindowMode { return static_cast<WindowMode>(window->GetMode()); });
1779 windowManager->SetWindowGetTypeCallBack(
1780 [window = uiWindow_]() -> WindowType { return static_cast<WindowType>(window->GetType()); });
1781 windowManager->SetWindowSetMaximizeModeCallBack(
1782 [window = uiWindow_](MaximizeMode mode) {
1783 window->SetGlobalMaximizeMode(static_cast<Rosen::MaximizeMode>(mode));
1784 });
1785 windowManager->SetWindowGetMaximizeModeCallBack(
1786 [window = uiWindow_]() -> MaximizeMode {
1787 return static_cast<MaximizeMode>(window->GetGlobalMaximizeMode());
1788 });
1789
1790 pipelineContext_->SetGetWindowRectImpl([window = uiWindow_]() -> Rect {
1791 Rect rect;
1792 CHECK_NULL_RETURN(window, rect);
1793 auto windowRect = window->GetRect();
1794 rect.SetRect(windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_);
1795 return rect;
1796 });
1797 }
1798
GetViewSafeAreaByType(OHOS::Rosen::AvoidAreaType type)1799 NG::SafeAreaInsets AceContainer::GetViewSafeAreaByType(OHOS::Rosen::AvoidAreaType type)
1800 {
1801 CHECK_NULL_RETURN(uiWindow_, {});
1802 Rosen::AvoidArea avoidArea;
1803 Rosen::WMError ret = uiWindow_->GetAvoidAreaByType(type, avoidArea);
1804 if (ret == Rosen::WMError::WM_OK) {
1805 return ConvertAvoidArea(avoidArea);
1806 }
1807 return {};
1808 }
1809
GetKeyboardSafeArea()1810 NG::SafeAreaInsets AceContainer::GetKeyboardSafeArea()
1811 {
1812 CHECK_NULL_RETURN(uiWindow_, {});
1813 Rosen::AvoidArea avoidArea;
1814 Rosen::WMError ret = uiWindow_->GetAvoidAreaByType(Rosen::AvoidAreaType::TYPE_KEYBOARD, avoidArea);
1815 if (ret == Rosen::WMError::WM_OK) {
1816 return ConvertAvoidArea(avoidArea);
1817 }
1818 return {};
1819 }
1820
GetAvoidAreaByType(Rosen::AvoidAreaType type)1821 Rosen::AvoidArea AceContainer::GetAvoidAreaByType(Rosen::AvoidAreaType type)
1822 {
1823 CHECK_NULL_RETURN(uiWindow_, {});
1824 Rosen::AvoidArea avoidArea;
1825 Rosen::WMError ret = uiWindow_->GetAvoidAreaByType(type, avoidArea);
1826 if (ret == Rosen::WMError::WM_OK) {
1827 return avoidArea;
1828 }
1829 return {};
1830 }
1831
GetAbilityContextByModule(const std::string & bundle,const std::string & module)1832 std::shared_ptr<OHOS::AbilityRuntime::Context> AceContainer::GetAbilityContextByModule(
1833 const std::string& bundle, const std::string& module)
1834 {
1835 auto context = runtimeContext_.lock();
1836 CHECK_NULL_RETURN(context, nullptr);
1837 if (!isFormRender_ && !bundle.empty() && !module.empty()) {
1838 std::string encode = EncodeBundleAndModule(bundle, module);
1839 resAdapterRecord_.emplace(encode);
1840 }
1841 return isFormRender_ ? nullptr : context->CreateModuleContext(bundle, module);
1842 }
1843
CheckAndSetFontFamily()1844 void AceContainer::CheckAndSetFontFamily()
1845 {
1846 std::string familyName = "";
1847 std::string path = "/data/themes/a/app";
1848 if (!IsFontFileExistInPath(path)) {
1849 path = "/data/themes/b/app";
1850 if (!IsFontFileExistInPath(path)) {
1851 return;
1852 }
1853 }
1854 path = path.append("/font/");
1855 familyName = GetFontFamilyName(path);
1856 if (familyName.empty()) {
1857 return;
1858 }
1859 path = path.append(familyName);
1860 auto fontManager = pipelineContext_->GetFontManager();
1861 fontManager->SetFontFamily(familyName.c_str(), path.c_str());
1862 }
1863
IsFontFileExistInPath(std::string path)1864 bool AceContainer::IsFontFileExistInPath(std::string path)
1865 {
1866 DIR* dir;
1867 struct dirent* ent;
1868 bool isFlagFileExist = false;
1869 bool isFontDirExist = false;
1870 if ((dir = opendir(path.c_str())) == nullptr) {
1871 if (errno == ENOENT) {
1872 LOGE("ERROR ENOENT");
1873 } else if (errno == EACCES) {
1874 LOGE("ERROR EACCES");
1875 } else {
1876 LOGE("ERROR Other");
1877 }
1878 return false;
1879 }
1880 while ((ent = readdir(dir)) != nullptr) {
1881 if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
1882 continue;
1883 }
1884 if (strcmp(ent->d_name, "flag") == 0) {
1885 isFlagFileExist = true;
1886 } else if (strcmp(ent->d_name, "font") == 0) {
1887 isFontDirExist = true;
1888 }
1889 }
1890 closedir(dir);
1891 if (isFlagFileExist && isFontDirExist) {
1892 LOGI("font path exist");
1893 return true;
1894 }
1895 return false;
1896 }
1897
GetFontFamilyName(std::string path)1898 std::string AceContainer::GetFontFamilyName(std::string path)
1899 {
1900 std::string fontFamilyName = "";
1901 DIR* dir;
1902 struct dirent* ent;
1903 if ((dir = opendir(path.c_str())) == nullptr) {
1904 return fontFamilyName;
1905 }
1906 while ((ent = readdir(dir)) != nullptr) {
1907 if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
1908 continue;
1909 }
1910 if (endsWith(ent->d_name, ".ttf")) {
1911 fontFamilyName = ent->d_name;
1912 break;
1913 }
1914 }
1915 closedir(dir);
1916 return fontFamilyName;
1917 }
1918
endsWith(std::string str,std::string suffix)1919 bool AceContainer::endsWith(std::string str, std::string suffix)
1920 {
1921 if (str.length() < suffix.length()) {
1922 return false;
1923 }
1924 return str.substr(str.length() - suffix.length()) == suffix;
1925 }
1926
UpdateConfiguration(const ParsedConfig & parsedConfig,const std::string & configuration)1927 void AceContainer::UpdateConfiguration(const ParsedConfig& parsedConfig, const std::string& configuration)
1928 {
1929 if (!parsedConfig.IsValid()) {
1930 LOGW("AceContainer::OnConfigurationUpdated param is empty");
1931 return;
1932 }
1933 ConfigurationChange configurationChange;
1934 CHECK_NULL_VOID(pipelineContext_);
1935 auto themeManager = pipelineContext_->GetThemeManager();
1936 CHECK_NULL_VOID(themeManager);
1937 auto resConfig = GetResourceConfiguration();
1938 if (!parsedConfig.colorMode.empty()) {
1939 configurationChange.colorModeUpdate = true;
1940 if (parsedConfig.colorMode == "dark") {
1941 SystemProperties::SetColorMode(ColorMode::DARK);
1942 SetColorScheme(ColorScheme::SCHEME_DARK);
1943 resConfig.SetColorMode(ColorMode::DARK);
1944 } else {
1945 SystemProperties::SetColorMode(ColorMode::LIGHT);
1946 SetColorScheme(ColorScheme::SCHEME_LIGHT);
1947 resConfig.SetColorMode(ColorMode::LIGHT);
1948 }
1949 }
1950 if (!parsedConfig.deviceAccess.empty()) {
1951 // Event of accessing mouse or keyboard
1952 SystemProperties::SetDeviceAccess(parsedConfig.deviceAccess == "true");
1953 resConfig.SetDeviceAccess(parsedConfig.deviceAccess == "true");
1954 }
1955 if (!parsedConfig.languageTag.empty()) {
1956 std::string language;
1957 std::string script;
1958 std::string region;
1959 Localization::ParseLocaleTag(parsedConfig.languageTag, language, script, region, false);
1960 if (!language.empty() || !script.empty() || !region.empty()) {
1961 configurationChange.languageUpdate = true;
1962 AceApplicationInfo::GetInstance().SetLocale(language, region, script, "");
1963 }
1964 }
1965 if (!parsedConfig.direction.empty()) {
1966 auto resDirection = DeviceOrientation::ORIENTATION_UNDEFINED;
1967 if (parsedConfig.direction == "horizontal") {
1968 resDirection = DeviceOrientation::LANDSCAPE;
1969 } else if (parsedConfig.direction == "vertical") {
1970 resDirection = DeviceOrientation::PORTRAIT;
1971 }
1972 configurationChange.directionUpdate = true;
1973 resConfig.SetOrientation(resDirection);
1974 }
1975 if (!parsedConfig.densitydpi.empty()) {
1976 configurationChange.dpiUpdate = true;
1977 }
1978 if (!parsedConfig.themeTag.empty()) {
1979 std::unique_ptr<JsonValue> json = JsonUtil::ParseJsonString(parsedConfig.themeTag);
1980 int fontUpdate = json->GetInt("font");
1981 configurationChange.fontUpdate = fontUpdate;
1982 int iconUpdate = json->GetInt("icons");
1983 configurationChange.iconUpdate = iconUpdate;
1984 int skinUpdate = json->GetInt("skin");
1985 configurationChange.skinUpdate = skinUpdate;
1986 if (fontUpdate) {
1987 CheckAndSetFontFamily();
1988 }
1989 }
1990 SetResourceConfiguration(resConfig);
1991 themeManager->UpdateConfig(resConfig);
1992 if (SystemProperties::GetResourceDecoupling()) {
1993 ResourceManager::GetInstance().UpdateResourceConfig(resConfig, !parsedConfig.themeTag.empty());
1994 }
1995 themeManager->LoadResourceThemes();
1996 auto front = GetFrontend();
1997 CHECK_NULL_VOID(front);
1998 if (!configurationChange.directionUpdate && !configurationChange.dpiUpdate) {
1999 front->OnConfigurationUpdated(configuration);
2000 }
2001 #ifdef PLUGIN_COMPONENT_SUPPORTED
2002 OHOS::Ace::PluginManager::GetInstance().UpdateConfigurationInPlugin(resConfig, taskExecutor_);
2003 #endif
2004 NotifyConfigurationChange(!parsedConfig.deviceAccess.empty(), configurationChange);
2005 }
2006
NotifyConfigurationChange(bool needReloadTransition,const ConfigurationChange & configurationChange)2007 void AceContainer::NotifyConfigurationChange(
2008 bool needReloadTransition, const ConfigurationChange& configurationChange)
2009 {
2010 auto taskExecutor = GetTaskExecutor();
2011 CHECK_NULL_VOID(taskExecutor);
2012 taskExecutor->PostTask(
2013 [instanceId = instanceId_, weak = WeakClaim(this), needReloadTransition, configurationChange]() {
2014 ContainerScope scope(instanceId);
2015 auto container = weak.Upgrade();
2016 CHECK_NULL_VOID(container);
2017 auto frontend = container->GetFrontend();
2018 if (frontend) {
2019 LOGI("AceContainer UpdateConfiguration frontend MarkNeedUpdate");
2020 frontend->FlushReload();
2021 }
2022 auto taskExecutor = container->GetTaskExecutor();
2023 CHECK_NULL_VOID(taskExecutor);
2024 taskExecutor->PostTask(
2025 [instanceId, weak, needReloadTransition, configurationChange]() {
2026 ContainerScope scope(instanceId);
2027 auto container = weak.Upgrade();
2028 CHECK_NULL_VOID(container);
2029 auto pipeline = container->GetPipelineContext();
2030 CHECK_NULL_VOID(pipeline);
2031 auto themeManager = pipeline->GetThemeManager();
2032 CHECK_NULL_VOID(themeManager);
2033 if (configurationChange.directionUpdate &&
2034 (themeManager->GetResourceLimitKeys() & DIRECTION_KEY) == 0) {
2035 return;
2036 }
2037 if (configurationChange.colorModeUpdate && !container->IsTransparentBg()) {
2038 pipeline->SetAppBgColor(themeManager->GetBackgroundColor());
2039 }
2040 pipeline->NotifyConfigurationChange();
2041 pipeline->FlushReload(configurationChange);
2042 if (needReloadTransition) {
2043 // reload transition animation
2044 pipeline->FlushReloadTransition();
2045 }
2046 },
2047 TaskExecutor::TaskType::UI);
2048 },
2049 TaskExecutor::TaskType::JS);
2050 }
2051
HotReload()2052 void AceContainer::HotReload()
2053 {
2054 auto taskExecutor = GetTaskExecutor();
2055 CHECK_NULL_VOID(taskExecutor);
2056 taskExecutor->PostTask(
2057 [instanceId = instanceId_, weak = WeakClaim(this)]() {
2058 ContainerScope scope(instanceId);
2059 auto container = weak.Upgrade();
2060 CHECK_NULL_VOID(container);
2061 auto frontend = container->GetFrontend();
2062 CHECK_NULL_VOID(frontend);
2063 LOGI("AceContainer Flush Frontend for HotReload");
2064 frontend->HotReload();
2065
2066 auto pipeline = container->GetPipelineContext();
2067 CHECK_NULL_VOID(pipeline);
2068 pipeline->FlushReload(ConfigurationChange());
2069 },
2070 TaskExecutor::TaskType::UI);
2071 }
2072
SetToken(sptr<IRemoteObject> & token)2073 void AceContainer::SetToken(sptr<IRemoteObject>& token)
2074 {
2075 std::lock_guard<std::mutex> lock(cardTokensMutex_);
2076 if (token) {
2077 token_ = token;
2078 }
2079 }
2080
GetToken()2081 sptr<IRemoteObject> AceContainer::GetToken()
2082 {
2083 std::lock_guard<std::mutex> lock(cardTokensMutex_);
2084 if (token_) {
2085 return token_;
2086 }
2087 LOGE("fail to get Token");
2088 return nullptr;
2089 }
2090
SetParentToken(sptr<IRemoteObject> & token)2091 void AceContainer::SetParentToken(sptr<IRemoteObject>& token)
2092 {
2093 std::lock_guard<std::mutex> lock(cardTokensMutex_);
2094 if (token) {
2095 parentToken_ = token;
2096 }
2097 }
2098
GetParentToken()2099 sptr<IRemoteObject> AceContainer::GetParentToken()
2100 {
2101 std::lock_guard<std::mutex> lock(cardTokensMutex_);
2102 return parentToken_;
2103 }
2104
2105 // ArkTsCard start
GetFormSurfaceNode(int32_t instanceId)2106 std::shared_ptr<Rosen::RSSurfaceNode> AceContainer::GetFormSurfaceNode(int32_t instanceId)
2107 {
2108 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
2109 CHECK_NULL_RETURN(container, nullptr);
2110 auto context = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
2111 CHECK_NULL_RETURN(context, nullptr);
2112 auto window = static_cast<FormRenderWindow*>(context->GetWindow());
2113 CHECK_NULL_RETURN(window, nullptr);
2114 return window->GetRSSurfaceNode();
2115 }
2116
UpdateFormData(const std::string & data)2117 void AceContainer::UpdateFormData(const std::string& data)
2118 {
2119 #ifdef FORM_SUPPORTED
2120 auto frontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
2121 CHECK_NULL_VOID(frontend);
2122 frontend->UpdateData(data);
2123 #endif
2124 }
2125
UpdateFormSharedImage(const std::map<std::string,sptr<AppExecFwk::FormAshmem>> & imageDataMap)2126 void AceContainer::UpdateFormSharedImage(const std::map<std::string, sptr<AppExecFwk::FormAshmem>>& imageDataMap)
2127 {
2128 std::vector<std::string> picNameArray;
2129 std::vector<int> fileDescriptorArray;
2130 std::vector<int> byteLenArray;
2131 if (!imageDataMap.empty()) {
2132 for (auto& imageData : imageDataMap) {
2133 picNameArray.push_back(imageData.first);
2134 fileDescriptorArray.push_back(imageData.second->GetAshmemFd());
2135 byteLenArray.push_back(imageData.second->GetAshmemSize());
2136 }
2137 GetNamesOfSharedImage(picNameArray);
2138 UpdateSharedImage(picNameArray, byteLenArray, fileDescriptorArray);
2139 }
2140 }
2141
UpdateResource()2142 void AceContainer::UpdateResource()
2143 {
2144 // Reload theme and resource
2145 CHECK_NULL_VOID(pipelineContext_);
2146
2147 if (SystemProperties::GetResourceDecoupling()) {
2148 auto context = runtimeContext_.lock();
2149 auto abilityInfo = abilityInfo_.lock();
2150 InitResourceAndThemeManager(
2151 pipelineContext_, assetManager_, colorScheme_, resourceInfo_, context, abilityInfo, true);
2152 } else {
2153 ThemeConstants::InitDeviceType();
2154 auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>();
2155 pipelineContext_->SetThemeManager(themeManager);
2156 themeManager->InitResource(resourceInfo_);
2157 themeManager->SetColorScheme(colorScheme_);
2158 themeManager->LoadCustomTheme(assetManager_);
2159 themeManager->LoadResourceThemes();
2160 }
2161
2162 auto cache = pipelineContext_->GetImageCache();
2163 if (cache) {
2164 cache->Clear();
2165 }
2166 }
2167
GetNamesOfSharedImage(std::vector<std::string> & picNameArray)2168 void AceContainer::GetNamesOfSharedImage(std::vector<std::string>& picNameArray)
2169 {
2170 if (picNameArray.empty()) {
2171 LOGE("picNameArray is null!");
2172 return;
2173 }
2174 auto context = AceType::DynamicCast<NG::PipelineContext>(GetPipelineContext());
2175 CHECK_NULL_VOID(context);
2176 auto sharedImageManager = context->GetOrCreateSharedImageManager();
2177 auto nameSize = picNameArray.size();
2178 for (uint32_t i = 0; i < nameSize; i++) {
2179 // get name of picture
2180 auto name = picNameArray[i];
2181 sharedImageManager->AddPictureNamesToReloadMap(std::move(name));
2182 }
2183 }
2184
GetDisplayInfo()2185 RefPtr<DisplayInfo> AceContainer::GetDisplayInfo()
2186 {
2187 auto displayManager = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
2188 CHECK_NULL_RETURN(displayManager, nullptr);
2189 auto dmRotation = displayManager->GetRotation();
2190 auto isFoldable = Rosen::DisplayManager::GetInstance().IsFoldable();
2191 auto dmFoldStatus = Rosen::DisplayManager::GetInstance().GetFoldStatus();
2192 std::vector<Rect> rects;
2193 auto foldCreaseRegion = Rosen::DisplayManager::GetInstance().GetCurrentFoldCreaseRegion();
2194 if (foldCreaseRegion) {
2195 auto creaseRects = foldCreaseRegion->GetCreaseRects();
2196 if (!creaseRects.empty()) {
2197 for (const auto& item : creaseRects) {
2198 Rect rect;
2199 rect.SetRect(item.posX_, item.posY_, item.width_, item.height_);
2200 rects.insert(rects.end(), rect);
2201 }
2202 }
2203 }
2204 displayInfo_->SetDisplayId(displayManager->GetId());
2205 displayInfo_->SetIsFoldable(isFoldable);
2206 displayInfo_->SetFoldStatus(static_cast<FoldStatus>(static_cast<uint32_t>(dmFoldStatus)));
2207 displayInfo_->SetRotation(static_cast<Rotation>(static_cast<uint32_t>(dmRotation)));
2208 displayInfo_->SetCurrentFoldCreaseRegion(rects);
2209 return displayInfo_;
2210 }
2211
UpdateSharedImage(std::vector<std::string> & picNameArray,std::vector<int32_t> & byteLenArray,std::vector<int> & fileDescriptorArray)2212 void AceContainer::UpdateSharedImage(
2213 std::vector<std::string>& picNameArray, std::vector<int32_t>& byteLenArray, std::vector<int>& fileDescriptorArray)
2214 {
2215 auto context = GetPipelineContext();
2216 CHECK_NULL_VOID(context);
2217 if (picNameArray.empty() || byteLenArray.empty() || fileDescriptorArray.empty()) {
2218 LOGE("array is null! when try UpdateSharedImage");
2219 return;
2220 }
2221 auto nameArraySize = picNameArray.size();
2222 if (nameArraySize != byteLenArray.size()) {
2223 LOGE("nameArraySize does not equal to fileDescriptorArraySize, please check!");
2224 return;
2225 }
2226 if (nameArraySize != fileDescriptorArray.size()) {
2227 LOGE("nameArraySize does not equal to fileDescriptorArraySize, please check!");
2228 return;
2229 }
2230 // now it can be assured that all three arrays are of the same size
2231
2232 std::string picNameCopy;
2233 for (uint32_t i = 0; i < nameArraySize; i++) {
2234 // get name of picture
2235 auto picName = picNameArray[i];
2236 // save a copy of picName and ReleaseStringUTFChars immediately to avoid memory leak
2237 picNameCopy = picName;
2238
2239 // get fd ID
2240 auto fd = fileDescriptorArray[i];
2241
2242 auto newFd = dup(fd);
2243 if (newFd < 0) {
2244 LOGE("dup fd fail, fail reason: %{public}s, fd: %{public}d, picName: %{private}s, length: %{public}d",
2245 strerror(errno), fd, picNameCopy.c_str(), byteLenArray[i]);
2246 continue;
2247 }
2248
2249 auto ashmem = Ashmem(newFd, byteLenArray[i]);
2250 GetImageDataFromAshmem(picNameCopy, ashmem, context, byteLenArray[i]);
2251 ashmem.UnmapAshmem();
2252 ashmem.CloseAshmem();
2253 }
2254 }
2255
GetImageDataFromAshmem(const std::string & picName,Ashmem & ashmem,const RefPtr<PipelineBase> & pipelineContext,int len)2256 void AceContainer::GetImageDataFromAshmem(
2257 const std::string& picName, Ashmem& ashmem, const RefPtr<PipelineBase>& pipelineContext, int len)
2258 {
2259 bool ret = ashmem.MapReadOnlyAshmem();
2260 // if any exception causes a [return] before [AddSharedImage], the memory image will not show because [RenderImage]
2261 // will never be notified to start loading.
2262 if (!ret) {
2263 LOGE("MapReadOnlyAshmem fail, fail reason: %{public}s, picName: %{private}s, length: %{public}d, "
2264 "fd: %{public}d",
2265 strerror(errno), picName.c_str(), len, ashmem.GetAshmemFd());
2266 return;
2267 }
2268 const uint8_t* imageData = reinterpret_cast<const uint8_t*>(ashmem.ReadFromAshmem(len, 0));
2269 if (imageData == nullptr) {
2270 LOGE("imageData is nullptr, errno is: %{public}s, picName: %{private}s, length: %{public}d, fd: %{public}d",
2271 strerror(errno), picName.c_str(), len, ashmem.GetAshmemFd());
2272 return;
2273 }
2274 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
2275 CHECK_NULL_VOID(context);
2276 RefPtr<SharedImageManager> sharedImageManager = context->GetOrCreateSharedImageManager();
2277 if (sharedImageManager) {
2278 // read image data from shared memory and save a copy to sharedImageManager
2279 sharedImageManager->AddSharedImage(picName, std::vector<uint8_t>(imageData, imageData + len));
2280 }
2281 }
2282
IsScenceBoardWindow()2283 bool AceContainer::IsScenceBoardWindow()
2284 {
2285 CHECK_NULL_RETURN(uiWindow_, false);
2286 return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_SCENE_BOARD;
2287 }
2288
IsUIExtensionWindow()2289 bool AceContainer::IsUIExtensionWindow()
2290 {
2291 CHECK_NULL_RETURN(uiWindow_, false);
2292 return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_UI_EXTENSION;
2293 }
2294
IsSceneBoardEnabled()2295 bool AceContainer::IsSceneBoardEnabled()
2296 {
2297 return Rosen::SceneBoardJudgement::IsSceneBoardEnabled();
2298 }
2299 // ArkTsCard end
2300
SetCurPointerEvent(const std::shared_ptr<MMI::PointerEvent> & currentEvent)2301 void AceContainer::SetCurPointerEvent(const std::shared_ptr<MMI::PointerEvent>& currentEvent)
2302 {
2303 std::lock_guard<std::mutex> lock(pointerEventMutex_);
2304 currentPointerEvent_ = currentEvent;
2305 auto callbacksIter = stopDragCallbackMap_.begin();
2306 while (callbacksIter != stopDragCallbackMap_.end()) {
2307 auto pointerId = callbacksIter->first;
2308 MMI::PointerEvent::PointerItem pointerItem;
2309 if (!currentEvent->GetPointerItem(pointerId, pointerItem)) {
2310 for (const auto& callback : callbacksIter->second) {
2311 if (callback) {
2312 callback();
2313 }
2314 }
2315 callbacksIter = stopDragCallbackMap_.erase(callbacksIter);
2316 } else {
2317 if (!pointerItem.IsPressed()) {
2318 for (const auto& callback : callbacksIter->second) {
2319 if (callback) {
2320 callback();
2321 }
2322 }
2323 callbacksIter = stopDragCallbackMap_.erase(callbacksIter);
2324 } else {
2325 ++callbacksIter;
2326 }
2327 }
2328 }
2329 }
2330
GetCurPointerEventInfo(int32_t pointerId,int32_t & globalX,int32_t & globalY,int32_t & sourceType,StopDragCallback && stopDragCallback)2331 bool AceContainer::GetCurPointerEventInfo(
2332 int32_t pointerId, int32_t& globalX, int32_t& globalY, int32_t& sourceType, StopDragCallback&& stopDragCallback)
2333 {
2334 std::lock_guard<std::mutex> lock(pointerEventMutex_);
2335 CHECK_NULL_RETURN(currentPointerEvent_, false);
2336 MMI::PointerEvent::PointerItem pointerItem;
2337 if (!currentPointerEvent_->GetPointerItem(pointerId, pointerItem) || !pointerItem.IsPressed()) {
2338 return false;
2339 }
2340 sourceType = currentPointerEvent_->GetSourceType();
2341 globalX = pointerItem.GetDisplayX();
2342 globalY = pointerItem.GetDisplayY();
2343 RegisterStopDragCallback(pointerId, std::move(stopDragCallback));
2344 return true;
2345 }
2346
RegisterStopDragCallback(int32_t pointerId,StopDragCallback && stopDragCallback)2347 void AceContainer::RegisterStopDragCallback(int32_t pointerId, StopDragCallback&& stopDragCallback)
2348 {
2349 auto iter = stopDragCallbackMap_.find(pointerId);
2350 if (iter != stopDragCallbackMap_.end()) {
2351 iter->second.emplace_back(std::move(stopDragCallback));
2352 } else {
2353 std::list<StopDragCallback> list;
2354 list.emplace_back(std::move(stopDragCallback));
2355 stopDragCallbackMap_.emplace(pointerId, list);
2356 }
2357 }
2358
SearchElementInfoByAccessibilityIdNG(int64_t elementId,int32_t mode,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & output)2359 void AceContainer::SearchElementInfoByAccessibilityIdNG(
2360 int64_t elementId, int32_t mode, int64_t baseParent,
2361 std::list<Accessibility::AccessibilityElementInfo>& output)
2362 {
2363 CHECK_NULL_VOID(taskExecutor_);
2364 taskExecutor_->PostSyncTaskTimeout(
2365 [weak = WeakClaim(this), elementId, mode, baseParent, &output]() {
2366 auto container = weak.Upgrade();
2367 CHECK_NULL_VOID(container);
2368 auto pipelineContext = container->GetPipelineContext();
2369 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
2370 CHECK_NULL_VOID(ngPipeline);
2371 auto frontend = container->GetFrontend();
2372 CHECK_NULL_VOID(frontend);
2373 auto accessibilityManager = frontend->GetAccessibilityManager();
2374 CHECK_NULL_VOID(accessibilityManager);
2375 accessibilityManager->SearchElementInfoByAccessibilityIdNG(
2376 elementId, mode, output, ngPipeline, baseParent);
2377 },
2378 TaskExecutor::TaskType::UI, 1500);
2379 }
2380
SearchElementInfosByTextNG(int64_t elementId,const std::string & text,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & output)2381 void AceContainer::SearchElementInfosByTextNG(
2382 int64_t elementId, const std::string& text, int64_t baseParent,
2383 std::list<Accessibility::AccessibilityElementInfo>& output)
2384 {
2385 CHECK_NULL_VOID(taskExecutor_);
2386 taskExecutor_->PostSyncTaskTimeout(
2387 [weak = WeakClaim(this), elementId, &text, baseParent, &output]() {
2388 auto container = weak.Upgrade();
2389 CHECK_NULL_VOID(container);
2390 auto pipelineContext = container->GetPipelineContext();
2391 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
2392 CHECK_NULL_VOID(ngPipeline);
2393 auto frontend = container->GetFrontend();
2394 CHECK_NULL_VOID(frontend);
2395 auto accessibilityManager = frontend->GetAccessibilityManager();
2396 CHECK_NULL_VOID(accessibilityManager);
2397 accessibilityManager->SearchElementInfosByTextNG(
2398 elementId, text, output, ngPipeline, baseParent);
2399 },
2400 TaskExecutor::TaskType::UI, 1500);
2401 }
2402
FindFocusedElementInfoNG(int64_t elementId,int32_t focusType,int64_t baseParent,Accessibility::AccessibilityElementInfo & output)2403 void AceContainer::FindFocusedElementInfoNG(
2404 int64_t elementId, int32_t focusType, int64_t baseParent,
2405 Accessibility::AccessibilityElementInfo& output)
2406 {
2407 CHECK_NULL_VOID(taskExecutor_);
2408 taskExecutor_->PostSyncTaskTimeout(
2409 [weak = WeakClaim(this), elementId, focusType, baseParent, &output]() {
2410 auto container = weak.Upgrade();
2411 CHECK_NULL_VOID(container);
2412 auto pipelineContext = container->GetPipelineContext();
2413 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
2414 CHECK_NULL_VOID(ngPipeline);
2415 auto frontend = container->GetFrontend();
2416 CHECK_NULL_VOID(frontend);
2417 auto accessibilityManager = frontend->GetAccessibilityManager();
2418 CHECK_NULL_VOID(accessibilityManager);
2419 accessibilityManager->FindFocusedElementInfoNG(
2420 elementId, focusType, output, ngPipeline, baseParent);
2421 },
2422 TaskExecutor::TaskType::UI, 1500);
2423 }
2424
FocusMoveSearchNG(int64_t elementId,int32_t direction,int64_t baseParent,Accessibility::AccessibilityElementInfo & output)2425 void AceContainer::FocusMoveSearchNG(
2426 int64_t elementId, int32_t direction, int64_t baseParent,
2427 Accessibility::AccessibilityElementInfo& output)
2428 {
2429 CHECK_NULL_VOID(taskExecutor_);
2430 taskExecutor_->PostSyncTaskTimeout(
2431 [weak = WeakClaim(this), elementId, direction, baseParent, &output]() {
2432 auto container = weak.Upgrade();
2433 CHECK_NULL_VOID(container);
2434 auto pipelineContext = container->GetPipelineContext();
2435 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
2436 CHECK_NULL_VOID(ngPipeline);
2437 auto frontend = container->GetFrontend();
2438 CHECK_NULL_VOID(frontend);
2439 auto accessibilityManager = frontend->GetAccessibilityManager();
2440 CHECK_NULL_VOID(accessibilityManager);
2441 accessibilityManager->FocusMoveSearchNG(elementId, direction, output, ngPipeline, baseParent);
2442 },
2443 TaskExecutor::TaskType::UI, 1500);
2444 }
2445
NotifyExecuteAction(int64_t elementId,const std::map<std::string,std::string> & actionArguments,int32_t action,int64_t offset)2446 bool AceContainer::NotifyExecuteAction(
2447 int64_t elementId, const std::map<std::string, std::string>& actionArguments,
2448 int32_t action, int64_t offset)
2449 {
2450 bool IsExecuted = false;
2451 CHECK_NULL_RETURN(taskExecutor_, IsExecuted);
2452 taskExecutor_->PostSyncTaskTimeout(
2453 [weak = WeakClaim(this), elementId, &actionArguments, action, offset, &IsExecuted]() {
2454 auto container = weak.Upgrade();
2455 CHECK_NULL_VOID(container);
2456 auto pipelineContext = container->GetPipelineContext();
2457 auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
2458 CHECK_NULL_VOID(ngPipeline);
2459 auto frontend = container->GetFrontend();
2460 CHECK_NULL_VOID(frontend);
2461 auto accessibilityManager = frontend->GetAccessibilityManager();
2462 CHECK_NULL_VOID(accessibilityManager);
2463 IsExecuted = accessibilityManager->ExecuteExtensionActionNG(
2464 elementId, actionArguments, action, ngPipeline, offset);
2465 },
2466 TaskExecutor::TaskType::UI, 1500);
2467 return IsExecuted;
2468 }
2469
OHOS_ACE_HotReloadPage()2470 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_HotReloadPage()
2471 {
2472 AceEngine::Get().NotifyContainers([](const RefPtr<Container>& container) {
2473 LOGI("starting hotReload");
2474 #ifndef NG_BUILD
2475 if (Container::IsCurrentUseNewPipeline()) {
2476 container->HotReload();
2477 } else {
2478 container->NotifyConfigurationChange(true);
2479 }
2480 #else
2481 container->HotReload();
2482 #endif
2483 });
2484 }
2485 } // namespace OHOS::Ace::Platform
2486