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