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