• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <fstream>
19 #include <functional>
20 #include <mutex>
21 
22 #include "ability_context.h"
23 #include "ability_info.h"
24 #include "pointer_event.h"
25 #include "scene_board_judgement.h"
26 #include "wm/wm_common.h"
27 
28 #include "adapter/ohos/entrance/ace_application_info.h"
29 #include "adapter/ohos/entrance/ace_view_ohos.h"
30 #include "adapter/ohos/entrance/data_ability_helper_standard.h"
31 #include "adapter/ohos/entrance/file_asset_provider.h"
32 #include "adapter/ohos/entrance/hap_asset_provider.h"
33 #include "adapter/ohos/entrance/utils.h"
34 #include "base/i18n/localization.h"
35 #include "base/log/ace_trace.h"
36 #include "base/log/dump_log.h"
37 #include "base/log/event_report.h"
38 #include "base/log/frame_report.h"
39 #include "base/log/log.h"
40 #include "base/subwindow/subwindow_manager.h"
41 #include "base/utils/system_properties.h"
42 #include "base/utils/utils.h"
43 #include "bridge/card_frontend/card_frontend.h"
44 #include "bridge/card_frontend/form_frontend_declarative.h"
45 #include "bridge/common/utils/engine_helper.h"
46 #include "bridge/declarative_frontend/declarative_frontend.h"
47 #include "bridge/js_frontend/engine/common/js_engine_loader.h"
48 #include "bridge/js_frontend/js_frontend.h"
49 #include "core/common/ace_engine.h"
50 #include "core/common/connect_server_manager.h"
51 #include "core/common/container.h"
52 #include "core/common/container_scope.h"
53 #include "core/common/flutter/flutter_asset_manager.h"
54 #include "core/common/flutter/flutter_task_executor.h"
55 #include "core/common/hdc_register.h"
56 #include "core/common/platform_window.h"
57 #include "core/common/plugin_manager.h"
58 #include "core/common/text_field_manager.h"
59 #include "core/common/window.h"
60 #include "core/components/theme/theme_constants.h"
61 #include "core/components/theme/theme_manager_impl.h"
62 #include "core/components_ng/pattern/text_field/text_field_manager.h"
63 #include "core/components_ng/render/adapter/form_render_window.h"
64 #include "core/components_ng/render/adapter/rosen_window.h"
65 #include "core/pipeline/pipeline_context.h"
66 #include "core/pipeline_ng/pipeline_context.h"
67 
68 #if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
69 #include "adapter/ohos/entrance/ace_rosen_sync_task.h"
70 #endif
71 
72 namespace OHOS::Ace::Platform {
73 namespace {
74 
75 constexpr char ARK_ENGINE_SHARED_LIB[] = "libace_engine_ark.z.so";
76 constexpr char DECLARATIVE_ARK_ENGINE_SHARED_LIB[] = "libace_engine_declarative_ark.z.so";
77 
78 #ifdef _ARM64_
79 const std::string ASSET_LIBARCH_PATH = "/lib/arm64";
80 #else
81 const std::string ASSET_LIBARCH_PATH = "/lib/arm";
82 #endif
83 
GetEngineSharedLibrary()84 const char* GetEngineSharedLibrary()
85 {
86     return ARK_ENGINE_SHARED_LIB;
87 }
88 
GetDeclarativeSharedLibrary()89 const char* GetDeclarativeSharedLibrary()
90 {
91     return DECLARATIVE_ARK_ENGINE_SHARED_LIB;
92 }
93 
94 } // namespace
95 
AceContainer(int32_t instanceId,FrontendType type,std::shared_ptr<OHOS::AppExecFwk::Ability> aceAbility,std::unique_ptr<PlatformEventCallback> callback,bool useCurrentEventRunner,bool useNewPipeline)96 AceContainer::AceContainer(int32_t instanceId, FrontendType type, std::shared_ptr<OHOS::AppExecFwk::Ability> aceAbility,
97     std::unique_ptr<PlatformEventCallback> callback, bool useCurrentEventRunner, bool useNewPipeline)
98     : instanceId_(instanceId), type_(type), aceAbility_(aceAbility), useCurrentEventRunner_(useCurrentEventRunner)
99 {
100     ACE_DCHECK(callback);
101     if (useNewPipeline) {
102         SetUseNewPipeline();
103     }
104     InitializeTask();
105     platformEventCallback_ = std::move(callback);
106     useStageModel_ = false;
107     auto ability = aceAbility_.lock();
108     if (ability) {
109         abilityInfo_ = ability->GetAbilityInfo();
110     }
111 }
112 
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)113 AceContainer::AceContainer(int32_t instanceId, FrontendType type,
114     std::weak_ptr<OHOS::AbilityRuntime::Context> runtimeContext,
115     std::weak_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo, std::unique_ptr<PlatformEventCallback> callback,
116     bool useCurrentEventRunner, bool isSubAceContainer, bool useNewPipeline)
117     : instanceId_(instanceId), type_(type), runtimeContext_(std::move(runtimeContext)),
118       abilityInfo_(std::move(abilityInfo)), useCurrentEventRunner_(useCurrentEventRunner),
119       isSubContainer_(isSubAceContainer)
120 {
121     ACE_DCHECK(callback);
122     if (useNewPipeline) {
123         SetUseNewPipeline();
124     }
125     if (!isSubContainer_) {
126         InitializeTask();
127     }
128     platformEventCallback_ = std::move(callback);
129     useStageModel_ = true;
130 }
131 
~AceContainer()132 AceContainer::~AceContainer()
133 {
134     LOG_DESTROY();
135     if (IsFormRender() && taskExecutor_) {
136         taskExecutor_->Destory();
137         taskExecutor_.Reset();
138     }
139 }
140 
InitializeTask()141 void AceContainer::InitializeTask()
142 {
143     auto flutterTaskExecutor = Referenced::MakeRefPtr<FlutterTaskExecutor>();
144     flutterTaskExecutor->InitPlatformThread(useCurrentEventRunner_);
145     taskExecutor_ = flutterTaskExecutor;
146     // No need to create JS Thread for DECLARATIVE_JS
147     if (type_ == FrontendType::DECLARATIVE_JS) {
148         GetSettings().useUIAsJSThread = true;
149     } else {
150         flutterTaskExecutor->InitJsThread();
151     }
152 }
153 
Initialize()154 void AceContainer::Initialize()
155 {
156     ContainerScope scope(instanceId_);
157     // For DECLARATIVE_JS frontend use UI as JS Thread, so InitializeFrontend after UI thread created.
158     if (type_ != FrontendType::DECLARATIVE_JS) {
159         InitializeFrontend();
160     }
161 }
162 
Destroy()163 void AceContainer::Destroy()
164 {
165     LOGI("AceContainer::Destroy begin");
166     ContainerScope scope(instanceId_);
167     if (pipelineContext_ && taskExecutor_) {
168         // 1. Destroy Pipeline on UI thread.
169         RefPtr<PipelineBase> context;
170         {
171             std::lock_guard<std::mutex> lock(pipelineMutex_);
172             context.Swap(pipelineContext_);
173         }
174         auto uiTask = [context]() { context->Destroy(); };
175         if (GetSettings().usePlatformAsUIThread) {
176             uiTask();
177         } else {
178             taskExecutor_->PostTask(uiTask, TaskExecutor::TaskType::UI);
179         }
180 
181         if (isSubContainer_) {
182             // SubAceContainer just return.
183             return;
184         }
185 
186         // 2. Destroy Frontend on JS thread.
187         RefPtr<Frontend> frontend;
188         {
189             std::lock_guard<std::mutex> lock(frontendMutex_);
190             frontend.Swap(frontend_);
191         }
192         auto jsTask = [frontend]() {
193             auto lock = frontend->GetLock();
194             frontend->Destroy();
195         };
196         frontend->UpdateState(Frontend::State::ON_DESTROY);
197         if (GetSettings().usePlatformAsUIThread && GetSettings().useUIAsJSThread) {
198             jsTask();
199         } else {
200             taskExecutor_->PostTask(jsTask, TaskExecutor::TaskType::JS);
201         }
202     }
203     resRegister_.Reset();
204     assetManager_.Reset();
205     LOGI("AceContainer::Destroy end");
206 }
207 
DestroyView()208 void AceContainer::DestroyView()
209 {
210     ContainerScope scope(instanceId_);
211     CHECK_NULL_VOID_NOLOG(aceView_);
212     auto aceView = static_cast<AceViewOhos*>(aceView_);
213     if (aceView) {
214         aceView->DecRefCount();
215     }
216     aceView_ = nullptr;
217 }
218 
InitializeFrontend()219 void AceContainer::InitializeFrontend()
220 {
221     auto aceAbility = aceAbility_.lock();
222     if (type_ == FrontendType::JS) {
223         frontend_ = Frontend::Create();
224         auto jsFrontend = AceType::DynamicCast<JsFrontend>(frontend_);
225         auto& loader = Framework::JsEngineLoader::Get(GetEngineSharedLibrary());
226         auto jsEngine = loader.CreateJsEngine(instanceId_);
227         jsEngine->AddExtraNativeObject("ability", aceAbility.get());
228         EngineHelper::AddEngine(instanceId_, jsEngine);
229         jsFrontend->SetJsEngine(jsEngine);
230         jsFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
231         jsFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
232     } else if (type_ == FrontendType::JS_CARD) {
233         AceApplicationInfo::GetInstance().SetCardType();
234         frontend_ = AceType::MakeRefPtr<CardFrontend>();
235     } else if (type_ == FrontendType::DECLARATIVE_JS) {
236         if (isFormRender_) {
237             LOGI("Init Form Frontend");
238             frontend_ = AceType::MakeRefPtr<FormFrontendDeclarative>();
239             auto cardFrontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
240             auto& loader = Framework::JsEngineLoader::GetDeclarative(GetDeclarativeSharedLibrary());
241             RefPtr<Framework::JsEngine> jsEngine;
242             if (GetSettings().usingSharedRuntime) {
243                 jsEngine = loader.CreateJsEngineUsingSharedRuntime(instanceId_, sharedRuntime_);
244             } else {
245                 jsEngine = loader.CreateJsEngine(instanceId_);
246             }
247             jsEngine->AddExtraNativeObject("ability", aceAbility.get());
248             EngineHelper::AddEngine(instanceId_, jsEngine);
249             cardFrontend->SetJsEngine(jsEngine);
250             cardFrontend->SetPageProfile(pageProfile_);
251             cardFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
252             cardFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
253             // Card front
254             cardFrontend->SetRunningCardId(0); // ArkTsCard : nodeId, Host->FMS->FRS->innersdk
255             cardFrontend->SetIsFormRender(true);
256         } else if (!isSubContainer_) {
257             frontend_ = AceType::MakeRefPtr<DeclarativeFrontend>();
258             auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
259             auto& loader = Framework::JsEngineLoader::GetDeclarative(GetDeclarativeSharedLibrary());
260             RefPtr<Framework::JsEngine> jsEngine;
261             if (GetSettings().usingSharedRuntime) {
262                 jsEngine = loader.CreateJsEngineUsingSharedRuntime(instanceId_, sharedRuntime_);
263             } else {
264                 jsEngine = loader.CreateJsEngine(instanceId_);
265             }
266             jsEngine->AddExtraNativeObject("ability", aceAbility.get());
267             EngineHelper::AddEngine(instanceId_, jsEngine);
268             declarativeFrontend->SetJsEngine(jsEngine);
269             declarativeFrontend->SetPageProfile(pageProfile_);
270             declarativeFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
271             declarativeFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
272         } else {
273             frontend_ = OHOS::Ace::Platform::AceContainer::GetContainer(parentId_)->GetFrontend();
274             return;
275         }
276     } else {
277         LOGE("Frontend type not supported");
278         EventReport::SendAppStartException(AppStartExcepType::FRONTEND_TYPE_ERR);
279         return;
280     }
281     ACE_DCHECK(frontend_);
282     auto abilityInfo = abilityInfo_.lock();
283     std::shared_ptr<AppExecFwk::AbilityInfo> info = aceAbility ? aceAbility->GetAbilityInfo() : abilityInfo;
284     if (info && info->isLauncherAbility) {
285         frontend_->DisallowPopLastPage();
286     }
287     frontend_->Initialize(type_, taskExecutor_);
288 }
289 
GetContainer(int32_t instanceId)290 RefPtr<AceContainer> AceContainer::GetContainer(int32_t instanceId)
291 {
292     auto container = AceEngine::Get().GetContainer(instanceId);
293     CHECK_NULL_RETURN_NOLOG(container, nullptr);
294     auto aceContainer = AceType::DynamicCast<AceContainer>(container);
295     return aceContainer;
296 }
297 
OnBackPressed(int32_t instanceId)298 bool AceContainer::OnBackPressed(int32_t instanceId)
299 {
300     auto container = AceEngine::Get().GetContainer(instanceId);
301     CHECK_NULL_RETURN_NOLOG(container, false);
302     // When the container is for overlay, it need close the overlay first.
303     if (container->IsSubContainer()) {
304         if (container->IsUseNewPipeline()) {
305             LOGI("back press for remove overlay node");
306             ContainerScope scope(instanceId);
307             auto subPipelineContext = DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
308             CHECK_NULL_RETURN_NOLOG(subPipelineContext, false);
309             auto overlayManager = subPipelineContext->GetOverlayManager();
310             CHECK_NULL_RETURN_NOLOG(overlayManager, false);
311             return overlayManager->RemoveOverlayInSubwindow();
312         }
313         SubwindowManager::GetInstance()->CloseMenu();
314         return true;
315     }
316     ContainerScope scope(instanceId);
317     auto context = container->GetPipelineContext();
318     CHECK_NULL_RETURN_NOLOG(context, false);
319     if (context->PopPageStackOverlay()) {
320         return true;
321     }
322     return context->CallRouterBackToPopPage();
323 }
324 
OnShow(int32_t instanceId)325 void AceContainer::OnShow(int32_t instanceId)
326 {
327     auto container = AceEngine::Get().GetContainer(instanceId);
328     CHECK_NULL_VOID(container);
329     ContainerScope scope(instanceId);
330     auto taskExecutor = container->GetTaskExecutor();
331     CHECK_NULL_VOID(taskExecutor);
332     if (!container->UpdateState(Frontend::State::ON_SHOW)) {
333         return;
334     }
335 
336     auto jsTask = [container, front = container->GetFrontend()]() {
337         if (front && !container->IsSubContainer()) {
338             front->UpdateState(Frontend::State::ON_SHOW);
339             front->OnShow();
340         }
341     };
342 
343     auto uiTask = [container]() {
344         std::unordered_map<int64_t, WeakPtr<Frontend>> cardFrontendMap;
345         container->GetCardFrontendMap(cardFrontendMap);
346         for (const auto& [_, weakCardFront] : cardFrontendMap) {
347             auto cardFront = weakCardFront.Upgrade();
348             if (!cardFront) {
349                 LOGE("cardFront is null");
350                 continue;
351             }
352             cardFront->OnShow();
353         }
354         auto pipelineBase = container->GetPipelineContext();
355         CHECK_NULL_VOID(pipelineBase);
356         pipelineBase->OnShow();
357         pipelineBase->SetForegroundCalled(true);
358     };
359 
360     // stege model needn't post task when already run on UI
361     if (container->GetSettings().useUIAsJSThread && taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
362         jsTask();
363         uiTask();
364     } else {
365         taskExecutor->PostTask(jsTask, TaskExecutor::TaskType::JS);
366         taskExecutor->PostTask(uiTask, TaskExecutor::TaskType::UI);
367     }
368 }
369 
OnHide(int32_t instanceId)370 void AceContainer::OnHide(int32_t instanceId)
371 {
372     auto container = AceEngine::Get().GetContainer(instanceId);
373     CHECK_NULL_VOID(container);
374     ContainerScope scope(instanceId);
375     auto taskExecutor = container->GetTaskExecutor();
376     CHECK_NULL_VOID(taskExecutor);
377     if (!container->UpdateState(Frontend::State::ON_HIDE)) {
378         return;
379     }
380     std::unordered_map<int64_t, WeakPtr<Frontend>> cardFrontendMap;
381     container->GetCardFrontendMap(cardFrontendMap);
382 
383     auto jsTask = [container, front = container->GetFrontend(), cardFrontendMap]() {
384         if (front && !container->IsSubContainer()) {
385             front->UpdateState(Frontend::State::ON_HIDE);
386             front->OnHide();
387             front->TriggerGarbageCollection();
388         }
389         for (const auto& [_, weakCardFront] : cardFrontendMap) {
390             auto cardFront = weakCardFront.Upgrade();
391             if (!cardFront) {
392                 LOGE("cardFront is null");
393                 continue;
394             }
395             cardFront->TriggerGarbageCollection();
396         }
397     };
398 
399     auto uiTask = [container, cardFrontendMap]() {
400         for (const auto& [_, weakCardFront] : cardFrontendMap) {
401             auto cardFront = weakCardFront.Upgrade();
402             if (!cardFront) {
403                 LOGE("cardFront is null");
404                 continue;
405             }
406             cardFront->OnHide();
407         }
408         auto pipelineBase = container->GetPipelineContext();
409         CHECK_NULL_VOID(pipelineBase);
410         pipelineBase->OnHide();
411     };
412 
413     // stege model needn't post task when already run on UI
414     if (container->GetSettings().useUIAsJSThread && taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
415         jsTask();
416         uiTask();
417     } else {
418         taskExecutor->PostTask(jsTask, TaskExecutor::TaskType::JS);
419         taskExecutor->PostTask(uiTask, TaskExecutor::TaskType::UI);
420     }
421 }
422 
OnActive(int32_t instanceId)423 void AceContainer::OnActive(int32_t instanceId)
424 {
425     auto container = AceEngine::Get().GetContainer(instanceId);
426     CHECK_NULL_VOID(container);
427     ContainerScope scope(instanceId);
428     auto taskExecutor = container->GetTaskExecutor();
429     CHECK_NULL_VOID(taskExecutor);
430 
431     auto front = container->GetFrontend();
432     if (front && !container->IsSubContainer()) {
433         WeakPtr<Frontend> weakFrontend = front;
434         taskExecutor->PostTask(
435             [weakFrontend]() {
436                 auto frontend = weakFrontend.Upgrade();
437                 if (frontend) {
438                     frontend->UpdateState(Frontend::State::ON_ACTIVE);
439                     frontend->OnActive();
440                 }
441             },
442             TaskExecutor::TaskType::JS);
443     }
444 
445     taskExecutor->PostTask(
446         [container]() {
447             auto pipelineContext = container->GetPipelineContext();
448             if (!pipelineContext) {
449                 LOGE("pipeline context is null, OnActive failed.");
450                 return;
451             }
452             pipelineContext->WindowFocus(true);
453         },
454         TaskExecutor::TaskType::UI);
455 }
456 
OnInactive(int32_t instanceId)457 void AceContainer::OnInactive(int32_t instanceId)
458 {
459     auto container = AceEngine::Get().GetContainer(instanceId);
460     CHECK_NULL_VOID(container);
461     ContainerScope scope(instanceId);
462     auto taskExecutor = container->GetTaskExecutor();
463     CHECK_NULL_VOID(taskExecutor);
464 
465     auto front = container->GetFrontend();
466     if (front && !container->IsSubContainer()) {
467         WeakPtr<Frontend> weakFrontend = front;
468         taskExecutor->PostTask(
469             [weakFrontend]() {
470                 auto frontend = weakFrontend.Upgrade();
471                 if (frontend) {
472                     frontend->UpdateState(Frontend::State::ON_INACTIVE);
473                     frontend->OnInactive();
474                 }
475             },
476             TaskExecutor::TaskType::JS);
477     }
478 
479     taskExecutor->PostTask(
480         [container]() {
481             auto pipelineContext = container->GetPipelineContext();
482             if (!pipelineContext) {
483                 LOGE("pipeline context is null, OnInactive failed.");
484                 return;
485             }
486             pipelineContext->WindowFocus(false);
487         },
488         TaskExecutor::TaskType::UI);
489 }
490 
OnNewWant(int32_t instanceId,const std::string & data)491 void AceContainer::OnNewWant(int32_t instanceId, const std::string& data)
492 {
493     auto container = AceEngine::Get().GetContainer(instanceId);
494     CHECK_NULL_VOID(container);
495     ContainerScope scope(instanceId);
496     auto front = container->GetFrontend();
497     CHECK_NULL_VOID(front);
498     front->OnNewWant(data);
499 }
500 
OnStartContinuation(int32_t instanceId)501 bool AceContainer::OnStartContinuation(int32_t instanceId)
502 {
503     auto container = AceEngine::Get().GetContainer(instanceId);
504     CHECK_NULL_RETURN(container, false);
505     ContainerScope scope(instanceId);
506     auto front = container->GetFrontend();
507     CHECK_NULL_RETURN(front, false);
508     return front->OnStartContinuation();
509 }
510 
OnSaveData(int32_t instanceId)511 std::string AceContainer::OnSaveData(int32_t instanceId)
512 {
513     std::string result = "false";
514     auto container = AceEngine::Get().GetContainer(instanceId);
515     CHECK_NULL_RETURN(container, result);
516     ContainerScope scope(instanceId);
517     auto front = container->GetFrontend();
518     CHECK_NULL_RETURN(front, result);
519     front->OnSaveData(result);
520     return result;
521 }
522 
OnRestoreData(int32_t instanceId,const std::string & data)523 bool AceContainer::OnRestoreData(int32_t instanceId, const std::string& data)
524 {
525     auto container = AceEngine::Get().GetContainer(instanceId);
526     CHECK_NULL_RETURN(container, false);
527     ContainerScope scope(instanceId);
528     auto front = container->GetFrontend();
529     CHECK_NULL_RETURN(front, false);
530     return front->OnRestoreData(data);
531 }
532 
OnCompleteContinuation(int32_t instanceId,int result)533 void AceContainer::OnCompleteContinuation(int32_t instanceId, int result)
534 {
535     auto container = AceEngine::Get().GetContainer(instanceId);
536     CHECK_NULL_VOID(container);
537     ContainerScope scope(instanceId);
538     auto front = container->GetFrontend();
539     CHECK_NULL_VOID(front);
540     front->OnCompleteContinuation(result);
541 }
542 
OnRemoteTerminated(int32_t instanceId)543 void AceContainer::OnRemoteTerminated(int32_t instanceId)
544 {
545     auto container = AceEngine::Get().GetContainer(instanceId);
546     CHECK_NULL_VOID(container);
547     ContainerScope scope(instanceId);
548     auto front = container->GetFrontend();
549     CHECK_NULL_VOID(front);
550     front->OnRemoteTerminated();
551 }
552 
OnConfigurationUpdated(int32_t instanceId,const std::string & configuration)553 void AceContainer::OnConfigurationUpdated(int32_t instanceId, const std::string& configuration)
554 {
555     auto container = AceEngine::Get().GetContainer(instanceId);
556     CHECK_NULL_VOID(container);
557     ContainerScope scope(instanceId);
558     auto front = container->GetFrontend();
559     CHECK_NULL_VOID(front);
560     front->OnConfigurationUpdated(configuration);
561 }
562 
OnNewRequest(int32_t instanceId,const std::string & data)563 void AceContainer::OnNewRequest(int32_t instanceId, const std::string& data)
564 {
565     auto container = AceEngine::Get().GetContainer(instanceId);
566     CHECK_NULL_VOID_NOLOG(container);
567     ContainerScope scope(instanceId);
568     auto front = container->GetFrontend();
569     CHECK_NULL_VOID_NOLOG(front);
570     front->OnNewRequest(data);
571 }
572 
InitializeCallback()573 void AceContainer::InitializeCallback()
574 {
575     ACE_FUNCTION_TRACE();
576 
577     ACE_DCHECK(aceView_ && taskExecutor_ && pipelineContext_);
578     auto&& touchEventCallback = [context = pipelineContext_, id = instanceId_](
579                                     const TouchEvent& event, const std::function<void()>& markProcess) {
580         ContainerScope scope(id);
581         context->GetTaskExecutor()->PostTask(
582             [context, event, markProcess]() {
583                 context->OnTouchEvent(event);
584                 CHECK_NULL_VOID_NOLOG(markProcess);
585                 markProcess();
586             },
587             TaskExecutor::TaskType::UI);
588     };
589     aceView_->RegisterTouchEventCallback(touchEventCallback);
590 
591     auto&& mouseEventCallback = [context = pipelineContext_, id = instanceId_](
592                                     const MouseEvent& event, const std::function<void()>& markProcess) {
593         ContainerScope scope(id);
594         context->GetTaskExecutor()->PostTask(
595             [context, event, markProcess]() {
596                 context->OnMouseEvent(event);
597                 CHECK_NULL_VOID_NOLOG(markProcess);
598                 markProcess();
599             },
600             TaskExecutor::TaskType::UI);
601     };
602     aceView_->RegisterMouseEventCallback(mouseEventCallback);
603 
604     auto&& axisEventCallback = [context = pipelineContext_, id = instanceId_](
605                                    const AxisEvent& event, const std::function<void()>& markProcess) {
606         ContainerScope scope(id);
607         context->GetTaskExecutor()->PostTask(
608             [context, event, markProcess]() {
609                 context->OnAxisEvent(event);
610                 CHECK_NULL_VOID_NOLOG(markProcess);
611                 markProcess();
612             },
613             TaskExecutor::TaskType::UI);
614     };
615     aceView_->RegisterAxisEventCallback(axisEventCallback);
616 
617     auto&& keyEventCallback = [context = pipelineContext_, id = instanceId_](const KeyEvent& event) {
618         ContainerScope scope(id);
619         bool result = false;
620         context->GetTaskExecutor()->PostSyncTask(
621             [context, event, &result]() { result = context->OnKeyEvent(event); }, TaskExecutor::TaskType::UI);
622         return result;
623     };
624     aceView_->RegisterKeyEventCallback(keyEventCallback);
625 
626     auto&& rotationEventCallback = [context = pipelineContext_, id = instanceId_](const RotationEvent& event) {
627         ContainerScope scope(id);
628         bool result = false;
629         context->GetTaskExecutor()->PostSyncTask(
630             [context, event, &result]() { result = context->OnRotationEvent(event); }, TaskExecutor::TaskType::UI);
631         return result;
632     };
633     aceView_->RegisterRotationEventCallback(rotationEventCallback);
634 
635     auto&& viewChangeCallback = [context = pipelineContext_, id = instanceId_](int32_t width, int32_t height,
636                                     WindowSizeChangeReason type,
637                                     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction) {
638         ContainerScope scope(id);
639         ACE_SCOPED_TRACE("ViewChangeCallback(%d, %d)", width, height);
640         auto callback = [context, width, height, type, rsTransaction, id]() {
641             context->OnSurfaceChanged(width, height, type, rsTransaction);
642             if (type == WindowSizeChangeReason::ROTATION) {
643                 auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(id);
644                 CHECK_NULL_VOID_NOLOG(subwindow);
645                 subwindow->ResizeWindow();
646             }
647         };
648         auto container = Container::Current();
649         CHECK_NULL_VOID(container);
650         auto taskExecutor = container->GetTaskExecutor();
651         CHECK_NULL_VOID(taskExecutor);
652         if ((container->IsUseStageModel() && type == WindowSizeChangeReason::ROTATION) ||
653             taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
654             callback();
655         } else {
656             taskExecutor->PostTask(callback, TaskExecutor::TaskType::UI);
657         }
658     };
659     aceView_->RegisterViewChangeCallback(viewChangeCallback);
660 
661     auto&& viewPositionChangeCallback = [context = pipelineContext_, id = instanceId_](int32_t posX, int32_t posY) {
662         ContainerScope scope(id);
663         ACE_SCOPED_TRACE("ViewPositionChangeCallback(%d, %d)", posX, posY);
664         context->GetTaskExecutor()->PostTask(
665             [context, posX, posY]() { context->OnSurfacePositionChanged(posX, posY); }, TaskExecutor::TaskType::UI);
666     };
667     aceView_->RegisterViewPositionChangeCallback(viewPositionChangeCallback);
668 
669     auto&& densityChangeCallback = [context = pipelineContext_, id = instanceId_](double density) {
670         ContainerScope scope(id);
671         ACE_SCOPED_TRACE("DensityChangeCallback(%lf)", density);
672         context->GetTaskExecutor()->PostTask(
673             [context, density]() { context->OnSurfaceDensityChanged(density); }, TaskExecutor::TaskType::UI);
674     };
675     aceView_->RegisterDensityChangeCallback(densityChangeCallback);
676 
677     auto&& systemBarHeightChangeCallback = [context = pipelineContext_, id = instanceId_](
678                                                double statusBar, double navigationBar) {
679         ContainerScope scope(id);
680         ACE_SCOPED_TRACE("SystemBarHeightChangeCallback(%lf, %lf)", statusBar, navigationBar);
681         context->GetTaskExecutor()->PostTask(
682             [context, statusBar, navigationBar]() { context->OnSystemBarHeightChanged(statusBar, navigationBar); },
683             TaskExecutor::TaskType::UI);
684     };
685     aceView_->RegisterSystemBarHeightChangeCallback(systemBarHeightChangeCallback);
686 
687     auto&& surfaceDestroyCallback = [context = pipelineContext_, id = instanceId_]() {
688         ContainerScope scope(id);
689         context->GetTaskExecutor()->PostTask(
690             [context]() { context->OnSurfaceDestroyed(); }, TaskExecutor::TaskType::UI);
691     };
692     aceView_->RegisterSurfaceDestroyCallback(surfaceDestroyCallback);
693 
694     if (!isFormRender_) {
695         auto&& dragEventCallback = [context = pipelineContext_, id = instanceId_](
696                                        int32_t x, int32_t y, const DragEventAction& action) {
697             ContainerScope scope(id);
698             context->GetTaskExecutor()->PostTask(
699                 [context, x, y, action]() { context->OnDragEvent(x, y, action); }, TaskExecutor::TaskType::UI);
700         };
701         aceView_->RegisterDragEventCallback(dragEventCallback);
702     }
703 }
704 
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)705 void AceContainer::CreateContainer(int32_t instanceId, FrontendType type, const std::string& instanceName,
706     std::shared_ptr<OHOS::AppExecFwk::Ability> aceAbility, std::unique_ptr<PlatformEventCallback> callback,
707     bool useCurrentEventRunner, bool useNewPipeline)
708 {
709     auto aceContainer = AceType::MakeRefPtr<AceContainer>(
710         instanceId, type, aceAbility, std::move(callback), useCurrentEventRunner, useNewPipeline);
711     AceEngine::Get().AddContainer(instanceId, aceContainer);
712     ConnectServerManager::Get().SetDebugMode();
713     HdcRegister::Get().StartHdcRegister(instanceId);
714     aceContainer->Initialize();
715     ContainerScope scope(instanceId);
716     auto front = aceContainer->GetFrontend();
717     if (front) {
718         front->UpdateState(Frontend::State::ON_CREATE);
719         front->SetJsMessageDispatcher(aceContainer);
720     }
721 
722     auto jsFront = AceType::DynamicCast<JsFrontend>(front);
723     CHECK_NULL_VOID_NOLOG(jsFront);
724     jsFront->SetInstanceName(instanceName);
725 }
726 
DestroyContainer(int32_t instanceId,const std::function<void ()> & destroyCallback)727 void AceContainer::DestroyContainer(int32_t instanceId, const std::function<void()>& destroyCallback)
728 {
729     SubwindowManager::GetInstance()->CloseDialog(instanceId);
730     auto container = AceEngine::Get().GetContainer(instanceId);
731     CHECK_NULL_VOID(container);
732     HdcRegister::Get().StopHdcRegister(instanceId);
733     container->Destroy();
734     // unregister watchdog before stop thread to avoid UI_BLOCK report
735     AceEngine::Get().UnRegisterFromWatchDog(instanceId);
736     auto taskExecutor = container->GetTaskExecutor();
737     if (taskExecutor) {
738         taskExecutor->PostSyncTask([] { LOGI("Wait UI thread..."); }, TaskExecutor::TaskType::UI);
739         taskExecutor->PostSyncTask([] { LOGI("Wait JS thread..."); }, TaskExecutor::TaskType::JS);
740     }
741     container->DestroyView(); // Stop all threads(ui,gpu,io) for current ability.
742     auto removeContainerTask = [instanceId, destroyCallback] {
743         LOGI("Remove on Platform thread...");
744         EngineHelper::RemoveEngine(instanceId);
745         AceEngine::Get().RemoveContainer(instanceId);
746         ConnectServerManager::Get().RemoveInstance(instanceId);
747         CHECK_NULL_VOID_NOLOG(destroyCallback);
748         destroyCallback();
749     };
750     if (container->GetSettings().usePlatformAsUIThread) {
751         removeContainerTask();
752     } else {
753         taskExecutor->PostTask(removeContainerTask, TaskExecutor::TaskType::PLATFORM);
754     }
755 }
756 
SetView(AceView * view,double density,int32_t width,int32_t height,sptr<OHOS::Rosen::Window> rsWindow,UIEnvCallback callback)757 void AceContainer::SetView(AceView* view, double density, int32_t width, int32_t height,
758     sptr<OHOS::Rosen::Window> rsWindow, UIEnvCallback callback)
759 {
760     CHECK_NULL_VOID(view);
761     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(view->GetInstanceId()));
762     CHECK_NULL_VOID(container);
763 #ifdef ENABLE_ROSEN_BACKEND
764     auto taskExecutor = container->GetTaskExecutor();
765     CHECK_NULL_VOID(taskExecutor);
766     auto window = std::make_shared<NG::RosenWindow>(rsWindow, taskExecutor, view->GetInstanceId());
767 #else
768     auto platformWindow = PlatformWindow::Create(view);
769     CHECK_NULL_VOID(platformWindow);
770     auto window = std::make_shared<Window>(std::move(platformWindow));
771 #endif
772     AceContainer::SetUIWindow(view->GetInstanceId(), rsWindow);
773     container->AttachView(window, view, density, width, height, rsWindow->GetWindowId(), callback);
774 }
775 
SetViewNew(AceView * view,double density,int32_t width,int32_t height,sptr<OHOS::Rosen::Window> rsWindow)776 void AceContainer::SetViewNew(
777     AceView* view, double density, int32_t width, int32_t height, sptr<OHOS::Rosen::Window> rsWindow)
778 {
779 #ifdef ENABLE_ROSEN_BACKEND
780     CHECK_NULL_VOID(view);
781     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(view->GetInstanceId()));
782     CHECK_NULL_VOID(container);
783     auto taskExecutor = container->GetTaskExecutor();
784     CHECK_NULL_VOID(taskExecutor);
785     AceContainer::SetUIWindow(view->GetInstanceId(), rsWindow);
786 
787     if (container->isFormRender_) {
788         auto window = std::make_shared<FormRenderWindow>(taskExecutor, view->GetInstanceId());
789         container->AttachView(window, view, density, width, height, view->GetInstanceId(), nullptr);
790     } else {
791         auto window = std::make_shared<NG::RosenWindow>(rsWindow, taskExecutor, view->GetInstanceId());
792         container->AttachView(window, view, density, width, height, rsWindow->GetWindowId(), nullptr);
793     }
794 #endif
795 }
796 
SetUIWindow(int32_t instanceId,sptr<OHOS::Rosen::Window> uiWindow)797 void AceContainer::SetUIWindow(int32_t instanceId, sptr<OHOS::Rosen::Window> uiWindow)
798 {
799     CHECK_NULL_VOID_NOLOG(uiWindow);
800     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
801     CHECK_NULL_VOID_NOLOG(container);
802     container->SetUIWindowInner(uiWindow);
803 }
804 
GetUIWindow(int32_t instanceId)805 sptr<OHOS::Rosen::Window> AceContainer::GetUIWindow(int32_t instanceId)
806 {
807     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
808     CHECK_NULL_RETURN_NOLOG(container, nullptr);
809     return container->GetUIWindowInner();
810 }
811 
GetAbility(int32_t instanceId)812 OHOS::AppExecFwk::Ability* AceContainer::GetAbility(int32_t instanceId)
813 {
814     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
815     CHECK_NULL_RETURN_NOLOG(container, nullptr);
816     return container->GetAbilityInner().lock().get();
817 }
818 
RunPage(int32_t instanceId,int32_t pageId,const std::string & content,const std::string & params)819 bool AceContainer::RunPage(int32_t instanceId, int32_t pageId, const std::string& content, const std::string& params)
820 {
821     auto container = AceEngine::Get().GetContainer(instanceId);
822     CHECK_NULL_RETURN_NOLOG(container, false);
823     ContainerScope scope(instanceId);
824     auto front = container->GetFrontend();
825     CHECK_NULL_RETURN_NOLOG(front, false);
826     LOGD("RunPage content=[%{private}s]", content.c_str());
827     front->RunPage(pageId, content, params);
828     return true;
829 }
830 
PushPage(int32_t instanceId,const std::string & content,const std::string & params)831 bool AceContainer::PushPage(int32_t instanceId, const std::string& content, const std::string& params)
832 {
833     auto container = AceEngine::Get().GetContainer(instanceId);
834     CHECK_NULL_RETURN_NOLOG(container, false);
835     ContainerScope scope(instanceId);
836     auto front = container->GetFrontend();
837     CHECK_NULL_RETURN_NOLOG(front, false);
838     front->PushPage(content, params);
839     return true;
840 }
841 
UpdatePage(int32_t instanceId,int32_t pageId,const std::string & content)842 bool AceContainer::UpdatePage(int32_t instanceId, int32_t pageId, const std::string& content)
843 {
844     auto container = AceEngine::Get().GetContainer(instanceId);
845     CHECK_NULL_RETURN_NOLOG(container, false);
846     ContainerScope scope(instanceId);
847     auto context = container->GetPipelineContext();
848     CHECK_NULL_RETURN_NOLOG(context, false);
849     return context->CallRouterBackToPopPage();
850 }
851 
SetHapPath(const std::string & hapPath)852 void AceContainer::SetHapPath(const std::string& hapPath)
853 {
854     if (hapPath.empty()) {
855         LOGI("SetHapPath, Use .index to load resource");
856         return;
857     }
858     LOGI("SetHapPath, Use hap path to load resource");
859     webHapPath_ = hapPath;
860     resourceInfo_.SetHapPath(hapPath);
861     SystemProperties::SetUnZipHap(false);
862 }
863 
Dispatch(const std::string & group,std::vector<uint8_t> && data,int32_t id,bool replyToComponent) const864 void AceContainer::Dispatch(
865     const std::string& group, std::vector<uint8_t>&& data, int32_t id, bool replyToComponent) const
866 {
867     return;
868 }
869 
DispatchPluginError(int32_t callbackId,int32_t errorCode,std::string && errorMessage) const870 void AceContainer::DispatchPluginError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const
871 {
872     auto front = GetFrontend();
873     CHECK_NULL_VOID(front);
874     ContainerScope scope(instanceId_);
875     taskExecutor_->PostTask(
876         [front, callbackId, errorCode, errorMessage = std::move(errorMessage)]() mutable {
877             front->TransferJsPluginGetError(callbackId, errorCode, std::move(errorMessage));
878         },
879         TaskExecutor::TaskType::BACKGROUND);
880 }
881 
Dump(const std::vector<std::string> & params,std::vector<std::string> & info)882 bool AceContainer::Dump(const std::vector<std::string>& params, std::vector<std::string>& info)
883 {
884     if (isDumping_.test_and_set()) {
885         LOGI("another dump is still running");
886         return false;
887     }
888     ContainerScope scope(instanceId_);
889     auto result = false;
890     if (!SystemProperties::GetDebugEnabled()) {
891         std::unique_ptr<std::ostream> ss = std::make_unique<std::ostringstream>();
892         CHECK_NULL_RETURN(ss, false);
893         DumpLog::GetInstance().SetDumpFile(std::move(ss));
894         result = DumpInfo(params);
895         const auto& infoFile = DumpLog::GetInstance().GetDumpFile();
896         auto* ostringstream = static_cast<std::ostringstream*>(infoFile.get());
897         info.emplace_back(ostringstream->str().substr(0, DumpLog::MAX_DUMP_LENGTH));
898         DumpLog::GetInstance().Reset();
899     } else {
900         auto dumpFilePath = AceApplicationInfo::GetInstance().GetDataFileDirPath() + "/arkui.dump";
901         std::unique_ptr<std::ostream> ss = std::make_unique<std::ofstream>(dumpFilePath);
902         CHECK_NULL_RETURN(ss, false);
903         DumpLog::GetInstance().SetDumpFile(std::move(ss));
904         result = DumpInfo(params);
905         info.emplace_back("dumpFilePath: " + dumpFilePath);
906         DumpLog::GetInstance().Reset();
907     }
908     if (!result) {
909         DumpLog::ShowDumpHelp(info);
910     }
911     isDumping_.clear();
912     return true;
913 }
914 
DumpInfo(const std::vector<std::string> & params)915 bool AceContainer::DumpInfo(const std::vector<std::string>& params)
916 {
917     if (aceView_ && aceView_->Dump(params)) {
918         return true;
919     }
920 
921     if (OnDumpInfo(params)) {
922         return true;
923     }
924     CHECK_NULL_RETURN_NOLOG(pipelineContext_, false);
925     return pipelineContext_->Dump(params);
926 }
927 
OnDumpInfo(const std::vector<std::string> & params)928 bool AceContainer::OnDumpInfo(const std::vector<std::string>& params)
929 {
930     if (!params.empty() && params[0] == "-basicinfo") {
931         DumpLog::GetInstance().Print("BasicInfo: ");
932         DumpLog::GetInstance().Print(1, "InstanceId: " + std::to_string(instanceId_));
933         DumpLog::GetInstance().Print(1,
934             "FrontendType: " + std::to_string(static_cast<typename std::underlying_type<FrontendType>::type>(type_)));
935         DumpLog::GetInstance().Print(1, "NewPipeline: " + std::string(IsUseNewPipeline() ? "true" : "false"));
936         DumpLog::GetInstance().Print(1, "WindowName: " + windowName_);
937         DumpLog::GetInstance().Print(
938             1, "WindowState: " +
939                    (!frontend_ ? "frontend is null"
940                                : std::to_string(static_cast<typename std::underlying_type<Frontend::State>::type>(
941                                      frontend_->GetState()))));
942         DumpLog::GetInstance().Print(1, "Language: " + AceApplicationInfo::GetInstance().GetLocaleTag());
943         DumpLog::GetInstance().Print(
944             1, "RTL: " + std::string(AceApplicationInfo::GetInstance().IsRightToLeft() ? "true" : "false"));
945         DumpLog::GetInstance().Print(
946             1, "ColorMode: " + std::string(SystemProperties::GetColorMode() == ColorMode::DARK ? "Dark" : "Light"));
947         DumpLog::GetInstance().Print(1,
948             "DeviceOrientation: " + std::string(SystemProperties::GetDeviceOrientation() == DeviceOrientation::LANDSCAPE
949                                                     ? "Landscape"
950                                                     : "Portrait"));
951         DumpLog::GetInstance().Print(1, "Resolution: " + std::to_string(SystemProperties::GetDeviceWidth()) + "*" +
952                                             std::to_string(SystemProperties::GetDeviceHeight()));
953         if (pipelineContext_) {
954             DumpLog::GetInstance().Print(1, "AppBgColor: " + pipelineContext_->GetAppBgColor().ColorToString());
955             DumpLog::GetInstance().Print(1, "Density: " + std::to_string(pipelineContext_->GetDensity()));
956             DumpLog::GetInstance().Print(1, "ViewScale: " + std::to_string(pipelineContext_->GetViewScale()));
957             DumpLog::GetInstance().Print(
958                 1, "DisplayWindowRect: " + pipelineContext_->GetDisplayWindowRectInfo().ToString());
959         }
960         DumpLog::GetInstance().Print(1, "ApiVersion: " + SystemProperties::GetApiVersion());
961         DumpLog::GetInstance().Print(1, "ReleaseType: " + SystemProperties::GetReleaseType());
962         DumpLog::GetInstance().Print(1, "DeviceType: " + SystemProperties::GetParamDeviceType());
963         return true;
964     }
965     return false;
966 }
967 
TriggerGarbageCollection()968 void AceContainer::TriggerGarbageCollection()
969 {
970     ContainerScope scope(instanceId_);
971 #if !defined(OHOS_PLATFORM) || !defined(ENABLE_NATIVE_VIEW)
972     // GPU and IO thread is standalone while disable native view
973     taskExecutor_->PostTask([] { PurgeMallocCache(); }, TaskExecutor::TaskType::GPU);
974     taskExecutor_->PostTask([] { PurgeMallocCache(); }, TaskExecutor::TaskType::IO);
975 #endif
976     taskExecutor_->PostTask([] { PurgeMallocCache(); }, TaskExecutor::TaskType::UI);
977     taskExecutor_->PostTask(
978         [frontend = WeakPtr<Frontend>(frontend_)] {
979             auto sp = frontend.Upgrade();
980             if (sp) {
981                 sp->TriggerGarbageCollection();
982             }
983             PurgeMallocCache();
984         },
985         TaskExecutor::TaskType::JS);
986 }
987 
DumpHeapSnapshot(bool isPrivate)988 void AceContainer::DumpHeapSnapshot(bool isPrivate)
989 {
990     taskExecutor_->PostTask(
991         [isPrivate, frontend = WeakPtr<Frontend>(frontend_)] {
992             auto sp = frontend.Upgrade();
993             CHECK_NULL_VOID_NOLOG(sp);
994             sp->DumpHeapSnapshot(isPrivate);
995         },
996         TaskExecutor::TaskType::JS);
997 }
998 
SetLocalStorage(NativeReference * storage,NativeReference * context)999 void AceContainer::SetLocalStorage(NativeReference* storage, NativeReference* context)
1000 {
1001     ContainerScope scope(instanceId_);
1002     taskExecutor_->PostTask(
1003         [frontend = WeakPtr<Frontend>(frontend_), storage, context, id = instanceId_] {
1004             auto sp = frontend.Upgrade();
1005             CHECK_NULL_VOID_NOLOG(sp);
1006             auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(sp);
1007             CHECK_NULL_VOID(declarativeFrontend);
1008             auto jsEngine = declarativeFrontend->GetJsEngine();
1009             CHECK_NULL_VOID(jsEngine);
1010             if (context) {
1011                 jsEngine->SetContext(id, context);
1012             }
1013             if (storage) {
1014                 jsEngine->SetLocalStorage(id, storage);
1015             }
1016         },
1017         TaskExecutor::TaskType::JS);
1018 }
1019 
AddAssetPath(int32_t instanceId,const std::string & packagePath,const std::string & hapPath,const std::vector<std::string> & paths)1020 void AceContainer::AddAssetPath(int32_t instanceId, const std::string& packagePath, const std::string& hapPath,
1021     const std::vector<std::string>& paths)
1022 {
1023     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1024     CHECK_NULL_VOID_NOLOG(container);
1025     RefPtr<FlutterAssetManager> flutterAssetManager;
1026     if (container->assetManager_) {
1027         flutterAssetManager = AceType::DynamicCast<FlutterAssetManager>(container->assetManager_);
1028     } else {
1029         flutterAssetManager = Referenced::MakeRefPtr<FlutterAssetManager>();
1030         container->assetManager_ = flutterAssetManager;
1031         if (container->type_ != FrontendType::DECLARATIVE_JS) {
1032             container->frontend_->SetAssetManager(flutterAssetManager);
1033         }
1034     }
1035     CHECK_NULL_VOID_NOLOG(flutterAssetManager);
1036     if (!hapPath.empty()) {
1037         auto assetProvider = AceType::MakeRefPtr<HapAssetProvider>();
1038         if (assetProvider->Initialize(hapPath, paths)) {
1039             LOGI("Push AssetProvider to queue.");
1040             flutterAssetManager->PushBack(std::move(assetProvider));
1041         }
1042     }
1043     if (!packagePath.empty()) {
1044         auto assetProvider = AceType::MakeRefPtr<FileAssetProvider>();
1045         if (assetProvider->Initialize(packagePath, paths)) {
1046             LOGI("Push AssetProvider to queue.");
1047             flutterAssetManager->PushBack(std::move(assetProvider));
1048         }
1049     }
1050 }
1051 
AddLibPath(int32_t instanceId,const std::vector<std::string> & libPath)1052 void AceContainer::AddLibPath(int32_t instanceId, const std::vector<std::string>& libPath)
1053 {
1054     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1055     CHECK_NULL_VOID_NOLOG(container);
1056     RefPtr<FlutterAssetManager> flutterAssetManager;
1057     if (container->assetManager_) {
1058         flutterAssetManager = AceType::DynamicCast<FlutterAssetManager>(container->assetManager_);
1059     } else {
1060         flutterAssetManager = Referenced::MakeRefPtr<FlutterAssetManager>();
1061         container->assetManager_ = flutterAssetManager;
1062         if (container->type_ != FrontendType::DECLARATIVE_JS) {
1063             container->frontend_->SetAssetManager(flutterAssetManager);
1064         }
1065     }
1066     CHECK_NULL_VOID_NOLOG(flutterAssetManager);
1067     flutterAssetManager->SetLibPath("default", libPath);
1068 }
1069 
AttachView(std::shared_ptr<Window> window,AceView * view,double density,int32_t width,int32_t height,uint32_t windowId,UIEnvCallback callback)1070 void AceContainer::AttachView(std::shared_ptr<Window> window, AceView* view, double density, int32_t width,
1071     int32_t height, uint32_t windowId, UIEnvCallback callback)
1072 {
1073     aceView_ = view;
1074     auto instanceId = aceView_->GetInstanceId();
1075     auto flutterTaskExecutor = AceType::DynamicCast<FlutterTaskExecutor>(taskExecutor_);
1076     if (!isSubContainer_) {
1077         auto* aceView = static_cast<AceViewOhos*>(aceView_);
1078         ACE_DCHECK(aceView != nullptr);
1079         flutterTaskExecutor->InitOtherThreads(aceView->GetThreadModel());
1080     }
1081     ContainerScope scope(instanceId);
1082     if (type_ == FrontendType::DECLARATIVE_JS) {
1083         // For DECLARATIVE_JS frontend display UI in JS thread temporarily.
1084         flutterTaskExecutor->InitJsThread(false);
1085         InitializeFrontend();
1086         auto front = GetFrontend();
1087         if (front) {
1088             front->UpdateState(Frontend::State::ON_CREATE);
1089             front->SetJsMessageDispatcher(AceType::Claim(this));
1090             front->SetAssetManager(assetManager_);
1091         }
1092     } else if (type_ != FrontendType::JS_CARD) {
1093         aceView_->SetCreateTime(createTime_);
1094     }
1095     resRegister_ = aceView_->GetPlatformResRegister();
1096     if (useNewPipeline_) {
1097         LOGI("New pipeline version creating...");
1098         pipelineContext_ = AceType::MakeRefPtr<NG::PipelineContext>(
1099             window, taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
1100         pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<NG::TextFieldManagerNG>());
1101     } else {
1102         pipelineContext_ = AceType::MakeRefPtr<PipelineContext>(
1103             window, taskExecutor_, assetManager_, resRegister_, frontend_, instanceId);
1104         pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<TextFieldManager>());
1105     }
1106 
1107     if (isFormRender_) {
1108         pipelineContext_->SetIsFormRender(isFormRender_);
1109         auto cardFrontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
1110         if (cardFrontend) {
1111             cardFrontend->SetTaskExecutor(taskExecutor_);
1112             cardFrontend->SetLoadCardCallBack(WeakPtr<PipelineBase>(pipelineContext_));
1113         }
1114     }
1115 
1116     pipelineContext_->SetRootSize(density, width, height);
1117     if (isFormRender_) {
1118         pipelineContext_->OnSurfaceDensityChanged(density);
1119     }
1120     pipelineContext_->SetIsRightToLeft(AceApplicationInfo::GetInstance().IsRightToLeft());
1121     pipelineContext_->SetWindowId(windowId);
1122     pipelineContext_->SetWindowModal(windowModal_);
1123     if (uiWindow_) {
1124         auto windowType = uiWindow_->GetType();
1125         pipelineContext_->SetIsAppWindow(
1126             windowType < Rosen::WindowType::SYSTEM_WINDOW_BASE && windowType >= Rosen::WindowType::APP_WINDOW_BASE);
1127     }
1128     if (installationFree_) {
1129         pipelineContext_->SetInstallationFree(installationFree_);
1130         pipelineContext_->SetSharePanelCallback(std::move(sharePanelCallback_));
1131         std::shared_ptr<AppExecFwk::AbilityInfo> info = abilityInfo_.lock();
1132         if (info != nullptr) {
1133             pipelineContext_->SetAppLabelId(info->labelId);
1134         }
1135     }
1136     if (isSubContainer_) {
1137         pipelineContext_->SetIsSubPipeline(true);
1138     }
1139 
1140     pipelineContext_->SetDrawDelegate(aceView_->GetDrawDelegate());
1141     InitWindowCallback();
1142     InitializeCallback();
1143 
1144     auto&& finishEventHandler = [weak = WeakClaim(this), instanceId] {
1145         auto container = weak.Upgrade();
1146         CHECK_NULL_VOID(container);
1147         ContainerScope scope(instanceId);
1148         auto context = container->GetPipelineContext();
1149         CHECK_NULL_VOID(context);
1150         context->GetTaskExecutor()->PostTask(
1151             [weak = WeakPtr<AceContainer>(container)] {
1152                 auto container = weak.Upgrade();
1153                 CHECK_NULL_VOID(container);
1154                 container->OnFinish();
1155             },
1156             TaskExecutor::TaskType::PLATFORM);
1157     };
1158     pipelineContext_->SetFinishEventHandler(finishEventHandler);
1159 
1160     auto&& startAbilityHandler = [weak = WeakClaim(this), instanceId](const std::string& address) {
1161         auto container = weak.Upgrade();
1162         CHECK_NULL_VOID(container);
1163         ContainerScope scope(instanceId);
1164         auto context = container->GetPipelineContext();
1165         CHECK_NULL_VOID(context);
1166         context->GetTaskExecutor()->PostTask(
1167             [weak = WeakPtr<AceContainer>(container), address]() {
1168                 auto container = weak.Upgrade();
1169                 CHECK_NULL_VOID(container);
1170                 container->OnStartAbility(address);
1171             },
1172             TaskExecutor::TaskType::PLATFORM);
1173     };
1174     pipelineContext_->SetStartAbilityHandler(startAbilityHandler);
1175 
1176     auto&& setStatusBarEventHandler = [weak = WeakClaim(this), instanceId](const Color& color) {
1177         auto container = weak.Upgrade();
1178         CHECK_NULL_VOID(container);
1179         ContainerScope scope(instanceId);
1180         auto context = container->GetPipelineContext();
1181         CHECK_NULL_VOID(context);
1182         context->GetTaskExecutor()->PostTask(
1183             [weak, color = color.GetValue()]() {
1184                 auto container = weak.Upgrade();
1185                 CHECK_NULL_VOID(container);
1186                 if (container->platformEventCallback_) {
1187                     container->platformEventCallback_->OnStatusBarBgColorChanged(color);
1188                 }
1189             },
1190             TaskExecutor::TaskType::PLATFORM);
1191     };
1192     pipelineContext_->SetStatusBarEventHandler(setStatusBarEventHandler);
1193     if (GetSettings().usePlatformAsUIThread) {
1194         FrameReport::GetInstance().Init();
1195     } else {
1196         taskExecutor_->PostTask([] { FrameReport::GetInstance().Init(); }, TaskExecutor::TaskType::UI);
1197     }
1198 
1199     // Load custom style at UI thread before frontend attach, for loading style before building tree.
1200     auto initThemeManagerTask = [pipelineContext = pipelineContext_, assetManager = assetManager_,
1201                                     colorScheme = colorScheme_, resourceInfo = resourceInfo_]() {
1202         ACE_SCOPED_TRACE("OHOS::LoadThemes()");
1203         LOGD("UIContent load theme");
1204         ThemeConstants::InitDeviceType();
1205         auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>();
1206         pipelineContext->SetThemeManager(themeManager);
1207         themeManager->InitResource(resourceInfo);
1208         themeManager->SetColorScheme(colorScheme);
1209         themeManager->LoadCustomTheme(assetManager);
1210         themeManager->LoadResourceThemes();
1211     };
1212 
1213     auto setupRootElementTask = [context = pipelineContext_, callback, isSubContainer = isSubContainer_]() {
1214         if (callback != nullptr) {
1215             callback(AceType::DynamicCast<PipelineContext>(context));
1216         }
1217         if (!isSubContainer) {
1218             context->SetupRootElement();
1219         }
1220     };
1221     if (GetSettings().usePlatformAsUIThread) {
1222         initThemeManagerTask();
1223         setupRootElementTask();
1224     } else {
1225         taskExecutor_->PostTask(initThemeManagerTask, TaskExecutor::TaskType::UI);
1226         taskExecutor_->PostTask(setupRootElementTask, TaskExecutor::TaskType::UI);
1227     }
1228 
1229     aceView_->Launch();
1230 
1231     if (!isSubContainer_) {
1232         // Only MainWindow instance in FA model will be registered to watch dog.
1233         if (!GetSettings().usingSharedRuntime && !AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint()) {
1234             AceEngine::Get().RegisterToWatchDog(instanceId, taskExecutor_, GetSettings().useUIAsJSThread);
1235         }
1236         frontend_->AttachPipelineContext(pipelineContext_);
1237     } else {
1238         auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
1239         if (declarativeFrontend) {
1240             declarativeFrontend->AttachSubPipelineContext(pipelineContext_);
1241         }
1242         return;
1243     }
1244 
1245     auto dataAbilityHelperImpl = [ability = GetAbilityInner(), runtimeContext = runtimeContext_,
1246                                      useStageModel = useStageModel_]() {
1247         return AceType::MakeRefPtr<DataAbilityHelperStandard>(ability.lock(), runtimeContext.lock(), useStageModel);
1248     };
1249     auto dataProviderManager = MakeRefPtr<DataProviderManagerStandard>(dataAbilityHelperImpl);
1250     pipelineContext_->SetDataProviderManager(dataProviderManager);
1251 
1252 #if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
1253     pipelineContext_->SetPostRTTaskCallBack([](std::function<void()>&& task) {
1254         auto syncTask = std::make_shared<AceRosenSyncTask>(std::move(task));
1255         Rosen::RSTransactionProxy::GetInstance()->ExecuteSynchronousTask(syncTask);
1256     });
1257 #endif
1258 }
1259 
SetUIWindowInner(sptr<OHOS::Rosen::Window> uiWindow)1260 void AceContainer::SetUIWindowInner(sptr<OHOS::Rosen::Window> uiWindow)
1261 {
1262     uiWindow_ = uiWindow;
1263 }
1264 
GetUIWindowInner() const1265 sptr<OHOS::Rosen::Window> AceContainer::GetUIWindowInner() const
1266 {
1267     return uiWindow_;
1268 }
1269 
GetAbilityInner() const1270 std::weak_ptr<OHOS::AppExecFwk::Ability> AceContainer::GetAbilityInner() const
1271 {
1272     return aceAbility_;
1273 }
1274 
IsLauncherContainer()1275 bool AceContainer::IsLauncherContainer()
1276 {
1277     auto runtime = runtimeContext_.lock();
1278     if (!runtime) {
1279         return false;
1280     }
1281     auto info = runtime->GetApplicationInfo();
1282     return info ? info->isLauncherApp : false;
1283 }
1284 
SetFontScale(int32_t instanceId,float fontScale)1285 void AceContainer::SetFontScale(int32_t instanceId, float fontScale)
1286 {
1287     auto container = AceEngine::Get().GetContainer(instanceId);
1288     CHECK_NULL_VOID_NOLOG(container);
1289     ContainerScope scope(instanceId);
1290     auto pipelineContext = container->GetPipelineContext();
1291     CHECK_NULL_VOID(pipelineContext);
1292     pipelineContext->SetFontScale(fontScale);
1293 }
1294 
SetWindowStyle(int32_t instanceId,WindowModal windowModal,ColorScheme colorScheme)1295 void AceContainer::SetWindowStyle(int32_t instanceId, WindowModal windowModal, ColorScheme colorScheme)
1296 {
1297     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1298     CHECK_NULL_VOID_NOLOG(container);
1299     ContainerScope scope(instanceId);
1300     container->SetWindowModal(windowModal);
1301     container->SetColorScheme(colorScheme);
1302 }
1303 
SetDialogCallback(int32_t instanceId,FrontendDialogCallback callback)1304 void AceContainer::SetDialogCallback(int32_t instanceId, FrontendDialogCallback callback)
1305 {
1306     auto container = AceEngine::Get().GetContainer(instanceId);
1307     CHECK_NULL_VOID_NOLOG(container);
1308     auto front = container->GetFrontend();
1309     if (front && front->GetType() == FrontendType::JS) {
1310         front->SetDialogCallback(callback);
1311     }
1312 }
1313 
RestoreRouterStack(int32_t instanceId,const std::string & contentInfo)1314 std::string AceContainer::RestoreRouterStack(int32_t instanceId, const std::string& contentInfo)
1315 {
1316     auto container = AceEngine::Get().GetContainer(instanceId);
1317     CHECK_NULL_RETURN_NOLOG(container, "");
1318     ContainerScope scope(instanceId);
1319     auto front = container->GetFrontend();
1320     CHECK_NULL_RETURN_NOLOG(front, "");
1321     return front->RestoreRouterStack(contentInfo);
1322 }
1323 
GetContentInfo(int32_t instanceId)1324 std::string AceContainer::GetContentInfo(int32_t instanceId)
1325 {
1326     auto container = AceEngine::Get().GetContainer(instanceId);
1327     CHECK_NULL_RETURN_NOLOG(container, "");
1328     ContainerScope scope(instanceId);
1329     auto front = container->GetFrontend();
1330     CHECK_NULL_RETURN_NOLOG(front, "");
1331     return front->GetContentInfo();
1332 }
1333 
SetWindowPos(int32_t left,int32_t top)1334 void AceContainer::SetWindowPos(int32_t left, int32_t top)
1335 {
1336     CHECK_NULL_VOID_NOLOG(frontend_);
1337     auto accessibilityManager = frontend_->GetAccessibilityManager();
1338     CHECK_NULL_VOID_NOLOG(accessibilityManager);
1339     accessibilityManager->SetWindowPos(left, top, windowId_);
1340 }
1341 
InitializeSubContainer(int32_t parentContainerId)1342 void AceContainer::InitializeSubContainer(int32_t parentContainerId)
1343 {
1344     auto parentContainer = AceEngine::Get().GetContainer(parentContainerId);
1345     CHECK_NULL_VOID(parentContainer);
1346     auto taskExec = parentContainer->GetTaskExecutor();
1347     taskExecutor_ = AceType::DynamicCast<FlutterTaskExecutor>(std::move(taskExec));
1348     auto parentSettings = parentContainer->GetSettings();
1349     GetSettings().useUIAsJSThread = parentSettings.useUIAsJSThread;
1350     GetSettings().usePlatformAsUIThread = parentSettings.usePlatformAsUIThread;
1351     GetSettings().usingSharedRuntime = parentSettings.usingSharedRuntime;
1352 }
1353 
InitWindowCallback()1354 void AceContainer::InitWindowCallback()
1355 {
1356     LOGD("AceContainer InitWindowCallback");
1357     if (!pipelineContext_ || !uiWindow_) {
1358         return;
1359     }
1360     auto& windowManager = pipelineContext_->GetWindowManager();
1361     std::shared_ptr<AppExecFwk::AbilityInfo> info = abilityInfo_.lock();
1362     if (info != nullptr) {
1363         windowManager->SetAppLabelId(info->labelId);
1364         windowManager->SetAppIconId(info->iconId);
1365     }
1366     windowManager->SetWindowMinimizeCallBack([window = uiWindow_]() { window->Minimize(); });
1367     windowManager->SetWindowMaximizeCallBack([window = uiWindow_]() { window->Maximize(); });
1368     windowManager->SetWindowMaximizeFloatingCallBack([window = uiWindow_]() { window->MaximizeFloating(); });
1369     windowManager->SetWindowRecoverCallBack([window = uiWindow_]() { window->Recover(); });
1370     windowManager->SetWindowCloseCallBack([window = uiWindow_]() { window->Close(); });
1371     windowManager->SetWindowStartMoveCallBack([window = uiWindow_]() { window->StartMove(); });
1372     windowManager->SetWindowSplitPrimaryCallBack(
1373         [window = uiWindow_]() { window->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_SPLIT_PRIMARY); });
1374     windowManager->SetWindowSplitSecondaryCallBack(
1375         [window = uiWindow_]() { window->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_SPLIT_SECONDARY); });
1376     windowManager->SetWindowGetModeCallBack(
1377         [window = uiWindow_]() -> WindowMode { return static_cast<WindowMode>(window->GetMode()); });
1378     windowManager->SetWindowGetTypeCallBack(
1379         [window = uiWindow_]() -> WindowType { return static_cast<WindowType>(window->GetType()); });
1380     windowManager->SetWindowSetMaximizeModeCallBack(
1381         [window = uiWindow_](MaximizeMode mode) {
1382             window->SetGlobalMaximizeMode(static_cast<Rosen::MaximizeMode>(mode));
1383         });
1384     windowManager->SetWindowGetMaximizeModeCallBack(
1385         [window = uiWindow_]() -> MaximizeMode {
1386             return static_cast<MaximizeMode>(window->GetGlobalMaximizeMode());
1387         });
1388 
1389     pipelineContext_->SetGetWindowRectImpl([window = uiWindow_]() -> Rect {
1390         Rect rect;
1391         CHECK_NULL_RETURN_NOLOG(window, rect);
1392         auto windowRect = window->GetRect();
1393         rect.SetRect(windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_);
1394         return rect;
1395     });
1396 }
1397 
GetViewSafeAreaByType(OHOS::Rosen::AvoidAreaType type)1398 NG::SafeAreaInsets AceContainer::GetViewSafeAreaByType(OHOS::Rosen::AvoidAreaType type)
1399 {
1400     CHECK_NULL_RETURN_NOLOG(uiWindow_, {});
1401     Rosen::AvoidArea avoidArea;
1402     Rosen::WMError ret = uiWindow_->GetAvoidAreaByType(type, avoidArea);
1403     if (ret == Rosen::WMError::WM_OK) {
1404         return ConvertAvoidArea(avoidArea);
1405     }
1406     return {};
1407 }
1408 
GetAbilityContextByModule(const std::string & bundle,const std::string & module)1409 std::shared_ptr<OHOS::AbilityRuntime::Context> AceContainer::GetAbilityContextByModule(
1410     const std::string& bundle, const std::string& module)
1411 {
1412     auto context = runtimeContext_.lock();
1413     CHECK_NULL_RETURN(context, nullptr);
1414     return isFormRender_ ? nullptr : context->CreateModuleContext(bundle, module);
1415 }
1416 
UpdateConfiguration(const std::string & colorMode,const std::string & deviceAccess,const std::string & languageTag,const std::string & configuration)1417 void AceContainer::UpdateConfiguration(const std::string& colorMode, const std::string& deviceAccess,
1418     const std::string& languageTag, const std::string& configuration)
1419 {
1420     if (colorMode.empty() && deviceAccess.empty() && languageTag.empty()) {
1421         LOGW("AceContainer::OnConfigurationUpdated param is empty");
1422         return;
1423     }
1424     OnConfigurationChange configurationChange;
1425     CHECK_NULL_VOID(pipelineContext_);
1426     auto themeManager = pipelineContext_->GetThemeManager();
1427     CHECK_NULL_VOID(themeManager);
1428     auto resConfig = GetResourceConfiguration();
1429     if (!colorMode.empty()) {
1430         configurationChange.colorModeUpdate = true;
1431         if (colorMode == "dark") {
1432             SystemProperties::SetColorMode(ColorMode::DARK);
1433             SetColorScheme(ColorScheme::SCHEME_DARK);
1434             resConfig.SetColorMode(ColorMode::DARK);
1435         } else {
1436             SystemProperties::SetColorMode(ColorMode::LIGHT);
1437             SetColorScheme(ColorScheme::SCHEME_LIGHT);
1438             resConfig.SetColorMode(ColorMode::LIGHT);
1439         }
1440     }
1441     if (!deviceAccess.empty()) {
1442         // Event of accessing mouse or keyboard
1443         SystemProperties::SetDeviceAccess(deviceAccess == "true");
1444         resConfig.SetDeviceAccess(deviceAccess == "true");
1445     }
1446     if (!languageTag.empty()) {
1447         std::string language;
1448         std::string script;
1449         std::string region;
1450         Localization::ParseLocaleTag(languageTag, language, script, region, false);
1451         if (!language.empty() || !script.empty() || !region.empty()) {
1452             configurationChange.languageUpdate = true;
1453             AceApplicationInfo::GetInstance().SetLocale(language, region, script, "");
1454         }
1455     }
1456     SetResourceConfiguration(resConfig);
1457     themeManager->UpdateConfig(resConfig);
1458     themeManager->LoadResourceThemes();
1459     auto front = GetFrontend();
1460     CHECK_NULL_VOID(front);
1461     front->OnConfigurationUpdated(configuration);
1462     OHOS::Ace::PluginManager::GetInstance().UpdateConfigurationInPlugin(resConfig, taskExecutor_);
1463     NotifyConfigurationChange(!deviceAccess.empty(), configurationChange);
1464 }
1465 
NotifyConfigurationChange(bool needReloadTransition,const OnConfigurationChange & configurationChange)1466 void AceContainer::NotifyConfigurationChange(
1467     bool needReloadTransition, const OnConfigurationChange& configurationChange)
1468 {
1469     auto taskExecutor = GetTaskExecutor();
1470     CHECK_NULL_VOID(taskExecutor);
1471     taskExecutor->PostTask(
1472         [instanceId = instanceId_, weak = WeakClaim(this), needReloadTransition, configurationChange]() {
1473             ContainerScope scope(instanceId);
1474             auto container = weak.Upgrade();
1475             CHECK_NULL_VOID(container);
1476             auto frontend = container->GetFrontend();
1477             if (frontend) {
1478                 LOGI("AceContainer::UpdateConfiguration frontend MarkNeedUpdate");
1479                 frontend->FlushReload();
1480             }
1481             auto taskExecutor = container->GetTaskExecutor();
1482             CHECK_NULL_VOID(taskExecutor);
1483             taskExecutor->PostTask(
1484                 [instanceId, weak, needReloadTransition, configurationChange]() {
1485                     ContainerScope scope(instanceId);
1486                     auto container = weak.Upgrade();
1487                     CHECK_NULL_VOID(container);
1488                     auto pipeline = container->GetPipelineContext();
1489                     CHECK_NULL_VOID(pipeline);
1490                     pipeline->NotifyConfigurationChange(configurationChange);
1491                     pipeline->FlushReload();
1492                     if (needReloadTransition) {
1493                         // reload transition animation
1494                         pipeline->FlushReloadTransition();
1495                     }
1496                 },
1497                 TaskExecutor::TaskType::UI);
1498         },
1499         TaskExecutor::TaskType::JS);
1500 }
1501 
HotReload()1502 void AceContainer::HotReload()
1503 {
1504     auto taskExecutor = GetTaskExecutor();
1505     CHECK_NULL_VOID(taskExecutor);
1506     taskExecutor->PostTask(
1507         [instanceId = instanceId_, weak = WeakClaim(this)]() {
1508             ContainerScope scope(instanceId);
1509             auto container = weak.Upgrade();
1510             CHECK_NULL_VOID(container);
1511             auto frontend = container->GetFrontend();
1512             CHECK_NULL_VOID(frontend);
1513             LOGI("AceContainer::Flush Frontend for HotReload");
1514             frontend->HotReload();
1515 
1516             auto pipeline = container->GetPipelineContext();
1517             CHECK_NULL_VOID(pipeline);
1518             pipeline->FlushReload();
1519         },
1520         TaskExecutor::TaskType::UI);
1521 }
1522 
SetToken(sptr<IRemoteObject> & token)1523 void AceContainer::SetToken(sptr<IRemoteObject>& token)
1524 {
1525     std::lock_guard<std::mutex> lock(cardTokensMutex_);
1526     if (token) {
1527         token_ = token;
1528     }
1529 }
1530 
GetToken()1531 sptr<IRemoteObject> AceContainer::GetToken()
1532 {
1533     std::lock_guard<std::mutex> lock(cardTokensMutex_);
1534     if (token_) {
1535         return token_;
1536     }
1537     LOGE("fail to get Token");
1538     return nullptr;
1539 }
1540 
1541 // ArkTsCard start
GetFormSurfaceNode(int32_t instanceId)1542 std::shared_ptr<Rosen::RSSurfaceNode> AceContainer::GetFormSurfaceNode(int32_t instanceId)
1543 {
1544     auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1545     CHECK_NULL_RETURN_NOLOG(container, nullptr);
1546     auto context = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
1547     CHECK_NULL_RETURN(context, nullptr);
1548     auto window = static_cast<FormRenderWindow*>(context->GetWindow());
1549     CHECK_NULL_RETURN(window, nullptr);
1550     return window->GetRSSurfaceNode();
1551 }
1552 
UpdateFormData(const std::string & data)1553 void AceContainer::UpdateFormData(const std::string& data)
1554 {
1555     auto frontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
1556     CHECK_NULL_VOID(frontend);
1557     frontend->UpdateData(data);
1558 }
1559 
UpdateFormSharedImage(const std::map<std::string,sptr<AppExecFwk::FormAshmem>> & imageDataMap)1560 void AceContainer::UpdateFormSharedImage(const std::map<std::string, sptr<AppExecFwk::FormAshmem>>& imageDataMap)
1561 {
1562     std::vector<std::string> picNameArray;
1563     std::vector<int> fileDescriptorArray;
1564     std::vector<int> byteLenArray;
1565     if (!imageDataMap.empty()) {
1566         for (auto& imageData : imageDataMap) {
1567             picNameArray.push_back(imageData.first);
1568             fileDescriptorArray.push_back(imageData.second->GetAshmemFd());
1569             byteLenArray.push_back(imageData.second->GetAshmemSize());
1570         }
1571         GetNamesOfSharedImage(picNameArray);
1572         UpdateSharedImage(picNameArray, byteLenArray, fileDescriptorArray);
1573     }
1574 }
1575 
ReloadForm()1576 void AceContainer::ReloadForm()
1577 {
1578     // Reload theme and resource
1579     CHECK_NULL_VOID(pipelineContext_);
1580     auto themeManager = AceType::MakeRefPtr<ThemeManagerImpl>();
1581     pipelineContext_->SetThemeManager(themeManager);
1582     themeManager->InitResource(resourceInfo_);
1583     themeManager->SetColorScheme(colorScheme_);
1584     themeManager->LoadCustomTheme(assetManager_);
1585     themeManager->LoadResourceThemes();
1586 }
1587 
GetNamesOfSharedImage(std::vector<std::string> & picNameArray)1588 void AceContainer::GetNamesOfSharedImage(std::vector<std::string>& picNameArray)
1589 {
1590     if (picNameArray.empty()) {
1591         LOGE("picNameArray is null!");
1592         return;
1593     }
1594     auto context = AceType::DynamicCast<NG::PipelineContext>(GetPipelineContext());
1595     CHECK_NULL_VOID(context);
1596     auto sharedImageManager = context->GetOrCreateSharedImageManager();
1597     auto nameSize = picNameArray.size();
1598     for (uint32_t i = 0; i < nameSize; i++) {
1599         // get name of picture
1600         auto name = picNameArray[i];
1601         sharedImageManager->AddPictureNamesToReloadMap(std::move(name));
1602     }
1603 }
1604 
UpdateSharedImage(std::vector<std::string> & picNameArray,std::vector<int32_t> & byteLenArray,std::vector<int> & fileDescriptorArray)1605 void AceContainer::UpdateSharedImage(
1606     std::vector<std::string>& picNameArray, std::vector<int32_t>& byteLenArray, std::vector<int>& fileDescriptorArray)
1607 {
1608     auto context = GetPipelineContext();
1609     CHECK_NULL_VOID(context);
1610     if (picNameArray.empty() || byteLenArray.empty() || fileDescriptorArray.empty()) {
1611         LOGE("array is null! when try UpdateSharedImage");
1612         return;
1613     }
1614     auto nameArraySize = picNameArray.size();
1615     if (nameArraySize != byteLenArray.size()) {
1616         LOGE("nameArraySize does not equal to fileDescriptorArraySize, please check!");
1617         return;
1618     }
1619     if (nameArraySize != fileDescriptorArray.size()) {
1620         LOGE("nameArraySize does not equal to fileDescriptorArraySize, please check!");
1621         return;
1622     }
1623     // now it can be assured that all three arrays are of the same size
1624 
1625     std::string picNameCopy;
1626     for (uint32_t i = 0; i < nameArraySize; i++) {
1627         // get name of picture
1628         auto picName = picNameArray[i];
1629         // save a copy of picName and ReleaseStringUTFChars immediately to avoid memory leak
1630         picNameCopy = picName;
1631 
1632         // get fd ID
1633         auto fd = fileDescriptorArray[i];
1634 
1635         auto newFd = dup(fd);
1636         if (newFd < 0) {
1637             LOGE("dup fd fail, fail reason: %{public}s, fd: %{public}d, picName: %{private}s, length: %{public}d",
1638                 strerror(errno), fd, picNameCopy.c_str(), byteLenArray[i]);
1639             continue;
1640         }
1641 
1642         auto ashmem = Ashmem(newFd, byteLenArray[i]);
1643         GetImageDataFromAshmem(picNameCopy, ashmem, context, byteLenArray[i]);
1644         ashmem.UnmapAshmem();
1645         ashmem.CloseAshmem();
1646     }
1647 }
1648 
GetImageDataFromAshmem(const std::string & picName,Ashmem & ashmem,const RefPtr<PipelineBase> & pipelineContext,int len)1649 void AceContainer::GetImageDataFromAshmem(
1650     const std::string& picName, Ashmem& ashmem, const RefPtr<PipelineBase>& pipelineContext, int len)
1651 {
1652     bool ret = ashmem.MapReadOnlyAshmem();
1653     // if any exception causes a [return] before [AddSharedImage], the memory image will not show because [RenderImage]
1654     // will never be notified to start loading.
1655     if (!ret) {
1656         LOGE("MapReadOnlyAshmem fail, fail reason: %{public}s, picName: %{private}s, length: %{public}d, "
1657              "fd: %{public}d",
1658             strerror(errno), picName.c_str(), len, ashmem.GetAshmemFd());
1659         return;
1660     }
1661     const uint8_t* imageData = reinterpret_cast<const uint8_t*>(ashmem.ReadFromAshmem(len, 0));
1662     if (imageData == nullptr) {
1663         LOGE("imageData is nullptr, errno is: %{public}s, picName: %{private}s, length: %{public}d, fd: %{public}d",
1664             strerror(errno), picName.c_str(), len, ashmem.GetAshmemFd());
1665         return;
1666     }
1667     auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
1668     CHECK_NULL_VOID(context);
1669     RefPtr<SharedImageManager> sharedImageManager = context->GetOrCreateSharedImageManager();
1670     if (sharedImageManager) {
1671         // read image data from shared memory and save a copy to sharedImageManager
1672         sharedImageManager->AddSharedImage(picName, std::vector<uint8_t>(imageData, imageData + len));
1673     }
1674 }
1675 
IsScenceBoardWindow()1676 bool AceContainer::IsScenceBoardWindow()
1677 {
1678     CHECK_NULL_RETURN(uiWindow_, false);
1679     return uiWindow_->GetType() == Rosen::WindowType::WINDOW_TYPE_SCENE_BOARD;
1680 }
1681 
IsSceneBoardEnabled()1682 bool AceContainer::IsSceneBoardEnabled()
1683 {
1684     return Rosen::SceneBoardJudgement::IsSceneBoardEnabled();
1685 }
1686 // ArkTsCard end
1687 
SetCurPointerEvent(const std::shared_ptr<MMI::PointerEvent> & currentEvent)1688 void AceContainer::SetCurPointerEvent(const std::shared_ptr<MMI::PointerEvent>& currentEvent)
1689 {
1690     std::lock_guard<std::mutex> lock(pointerEventMutex_);
1691     currentPointerEvent_ = currentEvent;
1692     auto callbacksIter = stopDragCallbackMap_.begin();
1693     while (callbacksIter != stopDragCallbackMap_.end()) {
1694         auto pointerId = callbacksIter->first;
1695         MMI::PointerEvent::PointerItem pointerItem;
1696         if (!currentEvent->GetPointerItem(pointerId, pointerItem)) {
1697             for (const auto& callback : callbacksIter->second) {
1698                 if (callback) {
1699                     callback();
1700                 }
1701             }
1702             callbacksIter = stopDragCallbackMap_.erase(callbacksIter);
1703         } else {
1704             if (!pointerItem.IsPressed()) {
1705                 for (const auto& callback : callbacksIter->second) {
1706                     if (callback) {
1707                         callback();
1708                     }
1709                 }
1710                 callbacksIter = stopDragCallbackMap_.erase(callbacksIter);
1711             } else {
1712                 ++callbacksIter;
1713             }
1714         }
1715     }
1716 }
1717 
GetCurPointerEventInfo(int32_t pointerId,int32_t & globalX,int32_t & globalY,int32_t & sourceType,StopDragCallback && stopDragCallback)1718 bool AceContainer::GetCurPointerEventInfo(
1719     int32_t pointerId, int32_t& globalX, int32_t& globalY, int32_t& sourceType, StopDragCallback&& stopDragCallback)
1720 {
1721     std::lock_guard<std::mutex> lock(pointerEventMutex_);
1722     CHECK_NULL_RETURN(currentPointerEvent_, false);
1723     MMI::PointerEvent::PointerItem pointerItem;
1724     if (!currentPointerEvent_->GetPointerItem(pointerId, pointerItem) || !pointerItem.IsPressed()) {
1725         return false;
1726     }
1727     sourceType = currentPointerEvent_->GetSourceType();
1728     globalX = pointerItem.GetDisplayX();
1729     globalY = pointerItem.GetDisplayY();
1730     RegisterStopDragCallback(pointerId, std::move(stopDragCallback));
1731     return true;
1732 }
1733 
RegisterStopDragCallback(int32_t pointerId,StopDragCallback && stopDragCallback)1734 void AceContainer::RegisterStopDragCallback(int32_t pointerId, StopDragCallback&& stopDragCallback)
1735 {
1736     auto iter = stopDragCallbackMap_.find(pointerId);
1737     if (iter != stopDragCallbackMap_.end()) {
1738         iter->second.emplace_back(std::move(stopDragCallback));
1739     } else {
1740         std::list<StopDragCallback> list;
1741         list.emplace_back(std::move(stopDragCallback));
1742         stopDragCallbackMap_.emplace(pointerId, list);
1743     }
1744 }
1745 
OHOS_ACE_HotReloadPage()1746 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_HotReloadPage()
1747 {
1748     AceEngine::Get().NotifyContainers([](const RefPtr<Container>& container) {
1749         LOGI("starting hotReload");
1750         if (Container::IsCurrentUseNewPipeline()) {
1751             container->HotReload();
1752         } else {
1753             container->NotifyConfigurationChange(true);
1754         }
1755     });
1756 }
1757 
1758 } // namespace OHOS::Ace::Platform
1759