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
SetToken(sptr<IRemoteObject> & token)1368 void AceContainer::SetToken(sptr<IRemoteObject>& token)
1369 {
1370 std::lock_guard<std::mutex> lock(cardTokensMutex_);
1371 if (token) {
1372 token_ = token;
1373 }
1374 }
1375
GetToken()1376 sptr<IRemoteObject> AceContainer::GetToken()
1377 {
1378 std::lock_guard<std::mutex> lock(cardTokensMutex_);
1379 if (token_) {
1380 return token_;
1381 }
1382 LOGE("fail to get Token");
1383 return nullptr;
1384 }
1385
1386 // ArkTsCard start
GetFormSurfaceNode(int32_t instanceId)1387 std::shared_ptr<Rosen::RSSurfaceNode> AceContainer::GetFormSurfaceNode(int32_t instanceId)
1388 {
1389 auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
1390 CHECK_NULL_RETURN_NOLOG(container, nullptr);
1391 auto context = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
1392 CHECK_NULL_RETURN(context, nullptr);
1393 auto window = static_cast<FormRenderWindow*>(context->GetWindow());
1394 CHECK_NULL_RETURN(window, nullptr);
1395 return window->GetRSSurfaceNode();
1396 }
1397
UpdateFormData(const std::string & data)1398 void AceContainer::UpdateFormData(const std::string& data)
1399 {
1400 auto frontend = AceType::DynamicCast<FormFrontendDeclarative>(frontend_);
1401 CHECK_NULL_VOID(frontend);
1402 frontend->UpdateData(data);
1403 }
1404
UpdateFormSharedImage(const std::map<std::string,sptr<AppExecFwk::FormAshmem>> & imageDataMap)1405 void AceContainer::UpdateFormSharedImage(const std::map<std::string, sptr<AppExecFwk::FormAshmem>>& imageDataMap)
1406 {
1407 std::vector<std::string> picNameArray;
1408 std::vector<int> fileDescriptorArray;
1409 std::vector<int> byteLenArray;
1410 if (!imageDataMap.empty()) {
1411 for (auto& imageData : imageDataMap) {
1412 picNameArray.push_back(imageData.first);
1413 fileDescriptorArray.push_back(imageData.second->GetAshmemFd());
1414 byteLenArray.push_back(imageData.second->GetAshmemSize());
1415 }
1416 GetNamesOfSharedImage(picNameArray);
1417 UpdateSharedImage(picNameArray, byteLenArray, fileDescriptorArray);
1418 }
1419 }
1420
GetNamesOfSharedImage(std::vector<std::string> & picNameArray)1421 void AceContainer::GetNamesOfSharedImage(std::vector<std::string>& picNameArray)
1422 {
1423 if (picNameArray.empty()) {
1424 LOGE("picNameArray is null!");
1425 return;
1426 }
1427 auto context = AceType::DynamicCast<NG::PipelineContext>(GetPipelineContext());
1428 CHECK_NULL_VOID(context);
1429 RefPtr<SharedImageManager> sharedImageManager = context->GetSharedImageManager();
1430 if (!sharedImageManager) {
1431 sharedImageManager = AceType::MakeRefPtr<SharedImageManager>(context->GetTaskExecutor());
1432 context->SetSharedImageManager(sharedImageManager);
1433 }
1434 auto nameSize = picNameArray.size();
1435 for (uint32_t i = 0; i < nameSize; i++) {
1436 // get name of picture
1437 auto name = picNameArray[i];
1438 sharedImageManager->AddPictureNamesToReloadMap(std::move(name));
1439 }
1440 }
1441
UpdateSharedImage(std::vector<std::string> & picNameArray,std::vector<int32_t> & byteLenArray,std::vector<int> & fileDescriptorArray)1442 void AceContainer::UpdateSharedImage(
1443 std::vector<std::string>& picNameArray, std::vector<int32_t>& byteLenArray, std::vector<int>& fileDescriptorArray)
1444 {
1445 auto context = GetPipelineContext();
1446 CHECK_NULL_VOID(context);
1447 if (picNameArray.empty() || byteLenArray.empty() || fileDescriptorArray.empty()) {
1448 LOGE("array is null! when try UpdateSharedImage");
1449 return;
1450 }
1451 auto nameArraySize = picNameArray.size();
1452 if (nameArraySize != byteLenArray.size()) {
1453 LOGE("nameArraySize does not equal to fileDescriptorArraySize, please check!");
1454 return;
1455 }
1456 if (nameArraySize != fileDescriptorArray.size()) {
1457 LOGE("nameArraySize does not equal to fileDescriptorArraySize, please check!");
1458 return;
1459 }
1460 // now it can be assured that all three arrays are of the same size
1461
1462 std::string picNameCopy;
1463 for (uint32_t i = 0; i < nameArraySize; i++) {
1464 // get name of picture
1465 auto picName = picNameArray[i];
1466 // save a copy of picName and ReleaseStringUTFChars immediately to avoid memory leak
1467 picNameCopy = picName;
1468
1469 // get fd ID
1470 auto fd = fileDescriptorArray[i];
1471
1472 auto newFd = dup(fd);
1473 if (newFd < 0) {
1474 LOGE("dup fd fail, fail reason: %{public}s, fd: %{public}d, picName: %{private}s, length: %{public}d",
1475 strerror(errno), fd, picNameCopy.c_str(), byteLenArray[i]);
1476 continue;
1477 }
1478
1479 auto ashmem = Ashmem(newFd, byteLenArray[i]);
1480 GetImageDataFromAshmem(picNameCopy, ashmem, context, byteLenArray[i]);
1481 ashmem.UnmapAshmem();
1482 ashmem.CloseAshmem();
1483 }
1484 }
1485
GetImageDataFromAshmem(const std::string & picName,Ashmem & ashmem,const RefPtr<PipelineBase> & pipelineContext,int len)1486 void AceContainer::GetImageDataFromAshmem(
1487 const std::string& picName, Ashmem& ashmem, const RefPtr<PipelineBase>& pipelineContext, int len)
1488 {
1489 bool ret = ashmem.MapReadOnlyAshmem();
1490 // if any exception causes a [return] before [AddSharedImage], the memory image will not show because [RenderImage]
1491 // will never be notified to start loading.
1492 if (!ret) {
1493 LOGE("MapReadOnlyAshmem fail, fail reason: %{public}s, picName: %{private}s, length: %{public}d, "
1494 "fd: %{public}d",
1495 strerror(errno), picName.c_str(), len, ashmem.GetAshmemFd());
1496 return;
1497 }
1498 const uint8_t* imageData = reinterpret_cast<const uint8_t*>(ashmem.ReadFromAshmem(len, 0));
1499 if (imageData == nullptr) {
1500 LOGE("imageData is nullptr, errno is: %{public}s, picName: %{private}s, length: %{public}d, fd: %{public}d",
1501 strerror(errno), picName.c_str(), len, ashmem.GetAshmemFd());
1502 return;
1503 }
1504 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
1505 CHECK_NULL_VOID(context);
1506 RefPtr<SharedImageManager> sharedImageManager = context->GetSharedImageManager();
1507 if (sharedImageManager) {
1508 // read image data from shared memory and save a copy to sharedImageManager
1509 sharedImageManager->AddSharedImage(picName, std::vector<uint8_t>(imageData, imageData + len));
1510 }
1511 }
1512
1513 // ArkTsCard end
1514
OHOS_ACE_HotReloadPage()1515 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_HotReloadPage()
1516 {
1517 AceEngine::Get().NotifyContainers([](const RefPtr<Container>& container) {
1518 auto ace = AceType::DynamicCast<AceContainer>(container);
1519 CHECK_NULL_VOID(ace);
1520 if (ace->IsUseNewPipeline()) {
1521 auto frontend = ace->GetFrontend();
1522 CHECK_NULL_VOID(frontend);
1523 frontend->RebuildAllPages();
1524 } else {
1525 ace->NotifyConfigurationChange(true);
1526 }
1527 LOGI("frontend rebuild finished");
1528 });
1529 }
1530
1531 } // namespace OHOS::Ace::Platform
1532