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/ui_content_impl.h"
17
18 #include <atomic>
19 #include <cinttypes>
20
21 #include "ability_context.h"
22 #include "ability_info.h"
23 #include "configuration.h"
24 #include "dm/display_manager.h"
25 #include "init_data.h"
26 #include "ipc_skeleton.h"
27 #include "js_runtime_utils.h"
28 #include "locale_config.h"
29 #include "native_reference.h"
30 #include "service_extension_context.h"
31 #include "wm_common.h"
32
33 #ifdef ENABLE_ROSEN_BACKEND
34 #include "render_service_client/core/transaction/rs_transaction.h"
35 #include "render_service_client/core/ui/rs_ui_director.h"
36 #endif
37
38 #include "adapter/ohos/entrance/ace_application_info.h"
39 #include "adapter/ohos/entrance/ace_container.h"
40 #include "adapter/ohos/entrance/ace_new_pipe_judgement.h"
41 #include "adapter/ohos/entrance/ace_view_ohos.h"
42 #include "adapter/ohos/entrance/capability_registry.h"
43 #include "adapter/ohos/entrance/dialog_container.h"
44 #include "adapter/ohos/entrance/file_asset_provider.h"
45 #include "adapter/ohos/entrance/form_utils_impl.h"
46 #include "adapter/ohos/entrance/hap_asset_provider.h"
47 #include "adapter/ohos/entrance/plugin_utils_impl.h"
48 #include "adapter/ohos/entrance/utils.h"
49 #include "adapter/ohos/osal/page_url_checker_ohos.h"
50 #include "adapter/ohos/osal/pixel_map_ohos.h"
51 #include "base/geometry/rect.h"
52 #include "base/i18n/localization.h"
53 #include "base/log/ace_checker.h"
54 #include "base/log/ace_performance_check.h"
55 #include "base/log/ace_trace.h"
56 #include "base/log/log.h"
57 #include "base/subwindow/subwindow_manager.h"
58 #include "base/utils/system_properties.h"
59 #include "bridge/card_frontend/form_frontend_declarative.h"
60 #include "core/common/ace_engine.h"
61 #include "core/common/container.h"
62 #include "core/common/container_scope.h"
63 #include "core/common/flutter/flutter_asset_manager.h"
64 #include "core/common/form_manager.h"
65 #include "core/common/layout_inspector.h"
66 #include "core/common/plugin_manager.h"
67 #include "core/pipeline_ng/pipeline_context.h"
68
69 namespace OHOS::Ace {
70 namespace {
71
72 const std::string ABS_BUNDLE_CODE_PATH = "/data/app/el1/bundle/public/";
73 const std::string LOCAL_BUNDLE_CODE_PATH = "/data/storage/el1/bundle/";
74 const std::string FILE_SEPARATOR = "/";
75 const std::string START_PARAMS_KEY = "__startParams";
76 const std::string ACTION_VIEWDATA = "ohos.want.action.viewData";
77
78 } // namespace
79
80 static std::atomic<int32_t> gInstanceId = 0;
81 static std::atomic<int32_t> gSubWindowInstanceId = 100000;
82 static std::atomic<int32_t> gSubInstanceId = 1000000;
83 const std::string SUBWINDOW_PREFIX = "ARK_APP_SUBWINDOW_";
84 const std::string SUBWINDOW_TOAST_DIALOG_PREFIX = "ARK_APP_SUBWINDOW_TOAST_DIALOG_";
85 const int32_t REQUEST_CODE = -1;
86
87 using ContentFinishCallback = std::function<void()>;
88 using ContentStartAbilityCallback = std::function<void(const std::string& address)>;
89 class ContentEventCallback final : public Platform::PlatformEventCallback {
90 public:
ContentEventCallback(ContentFinishCallback onFinish)91 explicit ContentEventCallback(ContentFinishCallback onFinish) : onFinish_(onFinish) {}
ContentEventCallback(ContentFinishCallback onFinish,ContentStartAbilityCallback onStartAbility)92 ContentEventCallback(ContentFinishCallback onFinish, ContentStartAbilityCallback onStartAbility)
93 : onFinish_(onFinish), onStartAbility_(onStartAbility)
94 {}
95 ~ContentEventCallback() override = default;
96
OnFinish() const97 void OnFinish() const override
98 {
99 LOGI("UIContent OnFinish");
100 CHECK_NULL_VOID_NOLOG(onFinish_);
101 onFinish_();
102 }
103
OnStartAbility(const std::string & address)104 void OnStartAbility(const std::string& address) override
105 {
106 LOGI("UIContent OnStartAbility");
107 CHECK_NULL_VOID_NOLOG(onStartAbility_);
108 onStartAbility_(address);
109 }
110
OnStatusBarBgColorChanged(uint32_t color)111 void OnStatusBarBgColorChanged(uint32_t color) override
112 {
113 LOGI("UIContent OnStatusBarBgColorChanged");
114 }
115
116 private:
117 ContentFinishCallback onFinish_;
118 ContentStartAbilityCallback onStartAbility_;
119 };
120
OHOS_ACE_CreateUIContent(void * context,void * runtime)121 extern "C" ACE_FORCE_EXPORT void* OHOS_ACE_CreateUIContent(void* context, void* runtime)
122 {
123 LOGI("Ace lib loaded, CreateUIContent.");
124 return new UIContentImpl(reinterpret_cast<OHOS::AbilityRuntime::Context*>(context), runtime);
125 }
126
OHOS_ACE_CreateFormContent(void * context,void * runtime,bool isCard)127 extern "C" ACE_FORCE_EXPORT void* OHOS_ACE_CreateFormContent(void* context, void* runtime, bool isCard)
128 {
129 LOGI("Ace lib loaded, CreateFormUIContent.");
130 return new UIContentImpl(reinterpret_cast<OHOS::AbilityRuntime::Context*>(context), runtime, isCard);
131 }
132
OHOS_ACE_CreateSubWindowUIContent(void * ability)133 extern "C" ACE_FORCE_EXPORT void* OHOS_ACE_CreateSubWindowUIContent(void* ability)
134 {
135 LOGI("Ace lib loaded, Create SubWindowUIContent.");
136 return new UIContentImpl(reinterpret_cast<OHOS::AppExecFwk::Ability*>(ability));
137 }
138
139 class OccupiedAreaChangeListener : public OHOS::Rosen::IOccupiedAreaChangeListener {
140 public:
OccupiedAreaChangeListener(int32_t instanceId)141 explicit OccupiedAreaChangeListener(int32_t instanceId) : instanceId_(instanceId) {}
142 ~OccupiedAreaChangeListener() = default;
143
OnSizeChange(const sptr<OHOS::Rosen::OccupiedAreaChangeInfo> & info,const std::shared_ptr<OHOS::Rosen::RSTransaction> & rsTransaction)144 void OnSizeChange(const sptr<OHOS::Rosen::OccupiedAreaChangeInfo>& info,
145 const std::shared_ptr<OHOS::Rosen::RSTransaction>& rsTransaction)
146 {
147 auto rect = info->rect_;
148 auto type = info->type_;
149 Rect keyboardRect = Rect(rect.posX_, rect.posY_, rect.width_, rect.height_);
150 LOGI("UIContent::OccupiedAreaChange rect:%{public}s type: %{public}d", keyboardRect.ToString().c_str(), type);
151 if (type == OHOS::Rosen::OccupiedAreaType::TYPE_INPUT) {
152 auto container = Platform::AceContainer::GetContainer(instanceId_);
153 CHECK_NULL_VOID(container);
154 auto taskExecutor = container->GetTaskExecutor();
155 CHECK_NULL_VOID(taskExecutor);
156 ContainerScope scope(instanceId_);
157 taskExecutor->PostTask(
158 [container, keyboardRect, rsTransaction] {
159 auto context = container->GetPipelineContext();
160 CHECK_NULL_VOID_NOLOG(context);
161 context->OnVirtualKeyboardAreaChange(keyboardRect, rsTransaction);
162 },
163 TaskExecutor::TaskType::UI);
164 }
165 }
166
167 private:
168 int32_t instanceId_ = -1;
169 };
170
171 class AvoidAreaChangedListener : public OHOS::Rosen::IAvoidAreaChangedListener {
172 public:
AvoidAreaChangedListener(int32_t instanceId)173 explicit AvoidAreaChangedListener(int32_t instanceId) : instanceId_(instanceId) {}
174 ~AvoidAreaChangedListener() = default;
175
OnAvoidAreaChanged(const OHOS::Rosen::AvoidArea avoidArea,OHOS::Rosen::AvoidAreaType type)176 void OnAvoidAreaChanged(const OHOS::Rosen::AvoidArea avoidArea, OHOS::Rosen::AvoidAreaType type) override
177 {
178 LOGI("UIContent::OnAvoidAreaChanged type:%{public}d, avoidArea:x:%{public}d, y:%{public}d, "
179 "width:%{public}d, height%{public}d",
180 type, avoidArea.topRect_.posX_, avoidArea.topRect_.posY_, (int32_t)avoidArea.topRect_.width_,
181 (int32_t)avoidArea.topRect_.height_);
182 auto container = Platform::AceContainer::GetContainer(instanceId_);
183 CHECK_NULL_VOID_NOLOG(container);
184 auto pipeline = container->GetPipelineContext();
185 CHECK_NULL_VOID_NOLOG(pipeline);
186 auto taskExecutor = container->GetTaskExecutor();
187 CHECK_NULL_VOID_NOLOG(taskExecutor);
188 auto safeArea = ConvertAvoidArea(avoidArea);
189 ContainerScope scope(instanceId_);
190 taskExecutor->PostTask(
191 [pipeline, safeArea, type] {
192 if (type == OHOS::Rosen::AvoidAreaType::TYPE_SYSTEM) {
193 pipeline->UpdateSystemSafeArea(safeArea);
194 } else if (type == OHOS::Rosen::AvoidAreaType::TYPE_CUTOUT) {
195 pipeline->UpdateCutoutSafeArea(safeArea);
196 }
197 },
198 TaskExecutor::TaskType::UI);
199 }
200
201 private:
202 int32_t instanceId_ = -1;
203 };
204
205 class DragWindowListener : public OHOS::Rosen::IWindowDragListener {
206 public:
DragWindowListener(int32_t instanceId)207 explicit DragWindowListener(int32_t instanceId) : instanceId_(instanceId) {}
208 ~DragWindowListener() = default;
OnDrag(int32_t x,int32_t y,OHOS::Rosen::DragEvent event)209 void OnDrag(int32_t x, int32_t y, OHOS::Rosen::DragEvent event)
210 {
211 LOGI("DragWindowListener::OnDrag called.");
212 auto container = Platform::AceContainer::GetContainer(instanceId_);
213 CHECK_NULL_VOID_NOLOG(container);
214 int32_t instanceId = instanceId_;
215 if (container->IsSubContainer()) {
216 instanceId = container->GetParentId();
217 }
218 auto aceView = static_cast<Platform::AceViewOhos*>(Platform::AceContainer::GetContainer(instanceId)->GetView());
219 CHECK_NULL_VOID(aceView);
220 DragEventAction action;
221 switch (event) {
222 case OHOS::Rosen::DragEvent::DRAG_EVENT_END:
223 action = DragEventAction::DRAG_EVENT_END;
224 break;
225 case OHOS::Rosen::DragEvent::DRAG_EVENT_OUT:
226 action = DragEventAction::DRAG_EVENT_OUT;
227 break;
228 case OHOS::Rosen::DragEvent::DRAG_EVENT_MOVE:
229 action = DragEventAction::DRAG_EVENT_MOVE;
230 break;
231 case OHOS::Rosen::DragEvent::DRAG_EVENT_IN:
232 default:
233 action = DragEventAction::DRAG_EVENT_START;
234 break;
235 }
236 #ifndef ENABLE_DRAG_FRAMEWORK
237 aceView->ProcessDragEvent(x, y, action);
238 #endif // ENABLE_DRAG_FRAMEWORK
239 }
240
241 private:
242 int32_t instanceId_ = -1;
243 };
244
245 class TouchOutsideListener : public OHOS::Rosen::ITouchOutsideListener {
246 public:
TouchOutsideListener(int32_t instanceId)247 explicit TouchOutsideListener(int32_t instanceId) : instanceId_(instanceId) {}
248 ~TouchOutsideListener() = default;
249
OnTouchOutside() const250 void OnTouchOutside() const
251 {
252 LOGI("window is touching outside. instance id is %{public}d", instanceId_);
253 auto container = Platform::AceContainer::GetContainer(instanceId_);
254 CHECK_NULL_VOID(container);
255 auto taskExecutor = container->GetTaskExecutor();
256 CHECK_NULL_VOID(taskExecutor);
257 ContainerScope scope(instanceId_);
258 taskExecutor->PostTask(
259 [instanceId = instanceId_] {
260 SubwindowManager::GetInstance()->ClearMenu();
261 SubwindowManager::GetInstance()->ClearMenuNG(instanceId, false);
262 SubwindowManager::GetInstance()->HidePopupNG(-1, instanceId);
263 },
264 TaskExecutor::TaskType::UI);
265 }
266
267 private:
268 int32_t instanceId_ = -1;
269 };
270
UIContentImpl(OHOS::AbilityRuntime::Context * context,void * runtime)271 UIContentImpl::UIContentImpl(OHOS::AbilityRuntime::Context* context, void* runtime) : runtime_(runtime)
272 {
273 CHECK_NULL_VOID(context);
274 context_ = context->weak_from_this();
275 LOGI("Create UIContentImpl successfully.");
276 }
277
UIContentImpl(OHOS::AbilityRuntime::Context * context,void * runtime,bool isCard)278 UIContentImpl::UIContentImpl(OHOS::AbilityRuntime::Context* context, void* runtime, bool isCard)
279 : runtime_(runtime), isFormRender_(isCard)
280 {
281 CHECK_NULL_VOID(context);
282 bundleName_ = context->GetBundleName();
283 auto hapModuleInfo = context->GetHapModuleInfo();
284 CHECK_NULL_VOID(hapModuleInfo);
285 moduleName_ = hapModuleInfo->name;
286 hapPath_ = hapModuleInfo->hapPath;
287 auto applicationInfo = context->GetApplicationInfo();
288 CHECK_NULL_VOID(applicationInfo);
289 minCompatibleVersionCode_ = applicationInfo->minCompatibleVersionCode;
290 isBundle_ = (hapModuleInfo->compileMode == AppExecFwk::CompileMode::JS_BUNDLE);
291 SetConfiguration(context->GetConfiguration());
292 context_ = context->weak_from_this();
293 LOGI("Create form UIContentImpl successfully.");
294 }
295
UIContentImpl(OHOS::AppExecFwk::Ability * ability)296 UIContentImpl::UIContentImpl(OHOS::AppExecFwk::Ability* ability)
297 {
298 CHECK_NULL_VOID(ability);
299 context_ = ability->GetAbilityContext();
300 LOGI("Create UIContentImpl successfully.");
301 }
302
DestroyUIDirector()303 void UIContentImpl::DestroyUIDirector()
304 {
305 auto container = Platform::AceContainer::GetContainer(instanceId_);
306 CHECK_NULL_VOID_NOLOG(container);
307 auto pipelineContext = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext());
308 CHECK_NULL_VOID_NOLOG(pipelineContext);
309 #ifdef ENABLE_ROSEN_BACKEND
310 auto rsUIDirector = pipelineContext->GetRSUIDirector();
311 CHECK_NULL_VOID_NOLOG(rsUIDirector);
312 LOGI("Destroying old rsUIDirectory");
313 rsUIDirector->Destroy();
314 #endif
315 }
316
DestroyCallback() const317 void UIContentImpl::DestroyCallback() const
318 {
319 auto container = Platform::AceContainer::GetContainer(instanceId_);
320 CHECK_NULL_VOID_NOLOG(container);
321 auto pipelineContext = container->GetPipelineContext();
322 CHECK_NULL_VOID_NOLOG(pipelineContext);
323 pipelineContext->SetNextFrameLayoutCallback(nullptr);
324 }
325
Initialize(OHOS::Rosen::Window * window,const std::string & url,NativeValue * storage)326 void UIContentImpl::Initialize(OHOS::Rosen::Window* window, const std::string& url, NativeValue* storage)
327 {
328 if (window && StringUtils::StartWith(window->GetWindowName(), SUBWINDOW_TOAST_DIALOG_PREFIX)) {
329 CommonInitialize(window, url, storage);
330 return;
331 }
332 if (window) {
333 CommonInitialize(window, url, storage);
334 }
335
336 // ArkTSCard need no window : 梳理所有需要window和不需要window的场景
337 if (isFormRender_ && !window) {
338 LOGI("CommonInitializeForm url = %{public}s", url.c_str());
339 CommonInitializeForm(window, url, storage);
340 }
341
342 LOGI("Initialize startUrl = %{public}s", startUrl_.c_str());
343 // run page.
344 Platform::AceContainer::RunPage(
345 instanceId_, Platform::AceContainer::GetContainer(instanceId_)->GeneratePageId(), startUrl_, "");
346 LOGD("Initialize UIContentImpl done.");
347 auto distributedUI = std::make_shared<NG::DistributedUI>();
348 uiManager_ = std::make_unique<DistributedUIManager>(instanceId_, distributedUI);
349 Platform::AceContainer::GetContainer(instanceId_)->SetDistributedUI(distributedUI);
350 }
351
Initialize(OHOS::Rosen::Window * window,const std::string & url,NativeValue * storage,uint32_t focusWindowId)352 void UIContentImpl::Initialize(
353 OHOS::Rosen::Window* window, const std::string& url, NativeValue* storage, uint32_t focusWindowId)
354 {
355 if (window) {
356 CommonInitialize(window, url, storage);
357 }
358 if (focusWindowId != 0) {
359 LOGI("UIExtension host window id:%{public}u", focusWindowId);
360 Platform::AceContainer::GetContainer(instanceId_)->SetFocusWindowId(focusWindowId);
361 }
362
363 LOGI("UIExtension startUrl = %{public}s", startUrl_.c_str());
364 // run page.
365 Platform::AceContainer::RunPage(
366 instanceId_, Platform::AceContainer::GetContainer(instanceId_)->GeneratePageId(), startUrl_, "");
367 auto distributedUI = std::make_shared<NG::DistributedUI>();
368 uiManager_ = std::make_unique<DistributedUIManager>(instanceId_, distributedUI);
369 Platform::AceContainer::GetContainer(instanceId_)->SetDistributedUI(distributedUI);
370 }
371
GetUIContext()372 NativeValue* UIContentImpl::GetUIContext()
373 {
374 auto container = Platform::AceContainer::GetContainer(instanceId_);
375 ContainerScope scope(instanceId_);
376 auto frontend = container->GetFrontend();
377 CHECK_NULL_RETURN(frontend, nullptr);
378 if (frontend->GetType() == FrontendType::DECLARATIVE_JS) {
379 auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend);
380 CHECK_NULL_RETURN(declarativeFrontend, nullptr);
381 return declarativeFrontend->GetContextValue();
382 }
383
384 return nullptr;
385 }
386
Restore(OHOS::Rosen::Window * window,const std::string & contentInfo,NativeValue * storage)387 void UIContentImpl::Restore(OHOS::Rosen::Window* window, const std::string& contentInfo, NativeValue* storage)
388 {
389 CommonInitialize(window, contentInfo, storage);
390 startUrl_ = Platform::AceContainer::RestoreRouterStack(instanceId_, contentInfo);
391 if (startUrl_.empty()) {
392 LOGW("UIContent Restore start url is empty");
393 }
394 LOGI("Restore startUrl = %{public}s", startUrl_.c_str());
395 Platform::AceContainer::RunPage(
396 instanceId_, Platform::AceContainer::GetContainer(instanceId_)->GeneratePageId(), startUrl_, "");
397 LOGI("Restore UIContentImpl done.");
398 }
399
GetContentInfo() const400 std::string UIContentImpl::GetContentInfo() const
401 {
402 LOGI("UIContent GetContentInfo");
403 return Platform::AceContainer::GetContentInfo(instanceId_);
404 }
405
406 // ArkTSCard start
CommonInitializeForm(OHOS::Rosen::Window * window,const std::string & contentInfo,NativeValue * storage)407 void UIContentImpl::CommonInitializeForm(
408 OHOS::Rosen::Window* window, const std::string& contentInfo, NativeValue* storage)
409 {
410 LOGI("Initialize CommonInitializeForm start.");
411 ACE_FUNCTION_TRACE();
412 window_ = window;
413 startUrl_ = contentInfo;
414
415 if (window_) {
416 if (StringUtils::StartWith(window->GetWindowName(), SUBWINDOW_TOAST_DIALOG_PREFIX)) {
417 InitializeSubWindow(window_, true);
418 return;
419 }
420 if (StringUtils::StartWith(window->GetWindowName(), SUBWINDOW_PREFIX)) {
421 InitializeSubWindow(window_);
422 return;
423 }
424 }
425
426 auto context = context_.lock();
427 static std::once_flag onceFlag;
428 if (!isFormRender_) {
429 std::call_once(onceFlag, [&context]() {
430 LOGI("Initialize for current process.");
431 SetHwIcuDirectory();
432 Container::UpdateCurrent(INSTANCE_ID_PLATFORM);
433 AceApplicationInfo::GetInstance().SetProcessName(context->GetBundleName());
434 AceApplicationInfo::GetInstance().SetPackageName(context->GetBundleName());
435 AceApplicationInfo::GetInstance().SetDataFileDirPath(context->GetFilesDir());
436 AceApplicationInfo::GetInstance().SetUid(IPCSkeleton::GetCallingUid());
437 AceApplicationInfo::GetInstance().SetPid(IPCSkeleton::GetCallingPid());
438 CapabilityRegistry::Register();
439 ImageCache::SetImageCacheFilePath(context->GetCacheDir());
440 ImageCache::SetCacheFileInfo();
441 });
442 }
443
444 bool useNewPipe = true;
445 #ifdef ENABLE_ROSEN_BACKEND
446 if (isFormRender_ && !window && !useNewPipe) {
447 useNewPipe = true;
448 }
449
450 std::shared_ptr<OHOS::Rosen::RSUIDirector> rsUiDirector;
451 if (SystemProperties::GetRosenBackendEnabled() && !useNewPipe && isFormRender_) {
452 rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
453 if (rsUiDirector) {
454 rsUiDirector->SetRSSurfaceNode(window->GetSurfaceNode());
455 rsUiDirector->SetCacheDir(context->GetCacheDir());
456 rsUiDirector->Init();
457 }
458 }
459 #endif
460 int32_t deviceWidth = 0;
461 int32_t deviceHeight = 0;
462 float density = 1.0f;
463 auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
464 if (defaultDisplay) {
465 density = defaultDisplay->GetVirtualPixelRatio();
466 deviceWidth = defaultDisplay->GetWidth();
467 deviceHeight = defaultDisplay->GetHeight();
468 LOGI("UIContent: deviceWidth: %{public}d, deviceHeight: %{public}d, default density: %{public}f", deviceWidth,
469 deviceHeight, density);
470 }
471
472 SystemProperties::InitDeviceInfo(deviceWidth, deviceHeight, deviceHeight >= deviceWidth ? 0 : 1, density, false);
473 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
474 if (context) {
475 auto resourceManager = context->GetResourceManager();
476 if (resourceManager != nullptr) {
477 resourceManager->GetResConfig(*resConfig);
478 auto localeInfo = resConfig->GetLocaleInfo();
479 Platform::AceApplicationInfoImpl::GetInstance().SetResourceManager(resourceManager);
480 if (localeInfo != nullptr) {
481 auto language = localeInfo->getLanguage();
482 auto region = localeInfo->getCountry();
483 auto script = localeInfo->getScript();
484 AceApplicationInfo::GetInstance().SetLocale((language == nullptr) ? "" : language,
485 (region == nullptr) ? "" : region, (script == nullptr) ? "" : script, "");
486 }
487 if (resConfig->GetColorMode() == OHOS::Global::Resource::ColorMode::DARK) {
488 SystemProperties::SetColorMode(ColorMode::DARK);
489 LOGI("UIContent set dark mode");
490 } else {
491 SystemProperties::SetColorMode(ColorMode::LIGHT);
492 LOGI("UIContent set light mode");
493 }
494 SystemProperties::SetDeviceAccess(
495 resConfig->GetInputDevice() == Global::Resource::InputDevice::INPUTDEVICE_POINTINGDEVICE);
496 }
497 }
498
499 auto abilityContext = OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(context);
500 std::shared_ptr<OHOS::AppExecFwk::AbilityInfo> info;
501 if (abilityContext) {
502 info = abilityContext->GetAbilityInfo();
503 } else {
504 auto extensionContext =
505 OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::ExtensionContext>(context);
506 if (extensionContext) {
507 info = extensionContext->GetAbilityInfo();
508 } else {
509 LOGE("context is not AbilityContext or ExtensionContext.");
510 }
511 }
512 if (info) {
513 AceApplicationInfo::GetInstance().SetAbilityName(info->name);
514 }
515
516 RefPtr<FlutterAssetManager> flutterAssetManager = Referenced::MakeRefPtr<FlutterAssetManager>();
517 bool isModelJson = info != nullptr ? info->isModuleJson : false;
518 std::string moduleName = info != nullptr ? info->moduleName : "";
519 auto appInfo = context != nullptr ? context->GetApplicationInfo() : nullptr;
520 auto hapModuleInfo = context != nullptr ? context->GetHapModuleInfo() : nullptr;
521 auto bundleName = info != nullptr ? info->bundleName : "";
522 std::string moduleHapPath = info != nullptr ? info->hapPath : "";
523 std::string resPath;
524 std::string pageProfile;
525 LOGI("Initialize UIContent isModelJson:%{public}s", isModelJson ? "true" : "false");
526 if (isFormRender_) {
527 LOGI("Initialize UIContent form assetProvider");
528 std::vector<std::string> basePaths;
529 basePaths.emplace_back("assets/js/" + moduleName_ + "/");
530 basePaths.emplace_back("assets/js/share/");
531 basePaths.emplace_back("");
532 basePaths.emplace_back("js/");
533 basePaths.emplace_back("ets/");
534 auto assetProvider = CreateAssetProvider(hapPath_, basePaths, false);
535 if (assetProvider) {
536 LOGE("push card asset provider to queue.");
537 flutterAssetManager->PushBack(std::move(assetProvider));
538 }
539 } else {
540 if (isModelJson) {
541 std::string hapPath = info != nullptr ? info->hapPath : "";
542 LOGI("hapPath:%{public}s", hapPath.c_str());
543 // first use hap provider
544 if (flutterAssetManager && !hapPath.empty()) {
545 auto assetProvider = AceType::MakeRefPtr<HapAssetProvider>();
546 if (assetProvider->Initialize(hapPath, { "", "ets/", "resources/base/profile/" })) {
547 LOGD("Push HapAssetProvider to queue.");
548 flutterAssetManager->PushBack(std::move(assetProvider));
549 }
550 }
551
552 if (appInfo) {
553 std::vector<OHOS::AppExecFwk::ModuleInfo> moduleList = appInfo->moduleInfos;
554 for (const auto& module : moduleList) {
555 if (module.moduleName == moduleName) {
556 std::regex pattern(ABS_BUNDLE_CODE_PATH + bundleName + FILE_SEPARATOR);
557 auto moduleSourceDir =
558 std::regex_replace(module.moduleSourceDir, pattern, LOCAL_BUNDLE_CODE_PATH);
559 resPath = moduleSourceDir + "/";
560 break;
561 }
562 }
563 }
564
565 // second use file provider, will remove later
566 LOGI("In stage mode, resPath:%{private}s", resPath.c_str());
567 auto assetBasePathStr = { std::string("ets/"), std::string("resources/base/profile/") };
568 if (flutterAssetManager && !resPath.empty()) {
569 auto assetProvider = AceType::MakeRefPtr<FileAssetProvider>();
570 if (assetProvider->Initialize(resPath, assetBasePathStr)) {
571 LOGD("Push AssetProvider to queue.");
572 flutterAssetManager->PushBack(std::move(assetProvider));
573 }
574 }
575
576 if (hapModuleInfo) {
577 pageProfile = hapModuleInfo->pages;
578 const std::string profilePrefix = "$profile:";
579 if (pageProfile.compare(0, profilePrefix.size(), profilePrefix) == 0) {
580 pageProfile = pageProfile.substr(profilePrefix.length()).append(".json");
581 }
582 LOGI("In stage mode, pageProfile:%{public}s", pageProfile.c_str());
583 } else {
584 LOGE("In stage mode, can't get hap info.");
585 }
586 } else {
587 auto packagePathStr = context->GetBundleCodeDir();
588 if (hapModuleInfo != nullptr) {
589 packagePathStr += "/" + hapModuleInfo->package + "/";
590 }
591 std::string srcPath = "";
592 if (info != nullptr && !info->srcPath.empty()) {
593 srcPath = info->srcPath;
594 }
595
596 auto assetBasePathStr = { "assets/js/" + (srcPath.empty() ? "default" : srcPath) + "/",
597 std::string("assets/js/share/") };
598
599 if (flutterAssetManager && !packagePathStr.empty()) {
600 auto assetProvider = AceType::MakeRefPtr<FileAssetProvider>();
601 if (assetProvider->Initialize(packagePathStr, assetBasePathStr)) {
602 LOGD("Push AssetProvider to queue.");
603 flutterAssetManager->PushBack(std::move(assetProvider));
604 }
605 }
606
607 if (appInfo) {
608 std::vector<OHOS::AppExecFwk::ModuleInfo> moduleList = appInfo->moduleInfos;
609 for (const auto& module : moduleList) {
610 if (module.moduleName == moduleName) {
611 std::regex pattern(ABS_BUNDLE_CODE_PATH + bundleName + FILE_SEPARATOR);
612 auto moduleSourceDir =
613 std::regex_replace(module.moduleSourceDir, pattern, LOCAL_BUNDLE_CODE_PATH);
614 resPath = moduleSourceDir + "/assets/" + module.moduleName + "/";
615 break;
616 }
617 }
618 }
619 }
620 }
621
622 std::string hapPath; // hap path in sandbox
623 if (!moduleHapPath.empty()) {
624 if (moduleHapPath.find(ABS_BUNDLE_CODE_PATH) == std::string::npos) {
625 hapPath = moduleHapPath;
626 } else {
627 auto pos = moduleHapPath.find_last_of('/');
628 if (pos != std::string::npos) {
629 hapPath = LOCAL_BUNDLE_CODE_PATH + moduleHapPath.substr(pos + 1);
630 LOGI("In Stage mode, hapPath:%{private}s", hapPath.c_str());
631 }
632 }
633 }
634
635 auto pluginUtils = std::make_shared<PluginUtilsImpl>();
636 PluginManager::GetInstance().SetAceAbility(nullptr, pluginUtils);
637 // create container
638 if (runtime_) {
639 instanceId_ = gInstanceId.fetch_add(1, std::memory_order_relaxed);
640 } else {
641 instanceId_ = gSubWindowInstanceId.fetch_add(1, std::memory_order_relaxed);
642 }
643 auto formUtils = std::make_shared<FormUtilsImpl>();
644 FormManager::GetInstance().SetFormUtils(formUtils);
645 auto container =
646 AceType::MakeRefPtr<Platform::AceContainer>(instanceId_, FrontendType::DECLARATIVE_JS, context_, info,
647 std::make_unique<ContentEventCallback>(
648 [window = window_] {
649 CHECK_NULL_VOID_NOLOG(window);
650 window->PerformBack();
651 },
652 [context = context_](const std::string& address) {
653 auto sharedContext = context.lock();
654 CHECK_NULL_VOID_NOLOG(sharedContext);
655 auto abilityContext =
656 OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(sharedContext);
657 CHECK_NULL_VOID_NOLOG(abilityContext);
658 LOGI("start ability with url = %{private}s", address.c_str());
659 AAFwk::Want want;
660 want.AddEntity(Want::ENTITY_BROWSER);
661 want.SetUri(address);
662 want.SetAction(ACTION_VIEWDATA);
663 abilityContext->StartAbility(want, REQUEST_CODE);
664 }),
665 false, false, useNewPipe);
666
667 CHECK_NULL_VOID(container);
668 container->SetIsFormRender(isFormRender_);
669 container->SetIsFRSCardContainer(isFormRender_);
670 if (window_) {
671 container->SetWindowName(window_->GetWindowName());
672 container->SetWindowId(window_->GetWindowId());
673 }
674
675 if (context) {
676 auto token = context->GetToken();
677 container->SetToken(token);
678 }
679
680 // Mark the relationship between windowId and containerId, it is 1:1
681 if (window) {
682 SubwindowManager::GetInstance()->AddContainerId(window->GetWindowId(), instanceId_);
683 }
684 AceEngine::Get().AddContainer(instanceId_, container);
685 if (runtime_) {
686 container->GetSettings().SetUsingSharedRuntime(true);
687 container->SetSharedRuntime(runtime_);
688 } else {
689 container->GetSettings().SetUsingSharedRuntime(false);
690 }
691 container->SetPageProfile(pageProfile);
692 container->Initialize();
693 ContainerScope scope(instanceId_);
694 auto front = container->GetFrontend();
695 if (front) {
696 front->UpdateState(Frontend::State::ON_CREATE);
697 front->SetJsMessageDispatcher(container);
698 }
699 auto aceResCfg = container->GetResourceConfiguration();
700 aceResCfg.SetOrientation(SystemProperties::GetDeviceOrientation());
701 aceResCfg.SetDensity(SystemProperties::GetResolution());
702 aceResCfg.SetDeviceType(SystemProperties::GetDeviceType());
703 aceResCfg.SetColorMode(SystemProperties::GetColorMode());
704 aceResCfg.SetDeviceAccess(SystemProperties::GetDeviceAccess());
705 if (isFormRender_) {
706 resPath = "/data/bundles/" + bundleName_ + "/" + moduleName_ + "/";
707 hapPath = hapPath_;
708 }
709 LOGI("CommonInitializeForm resPath = %{public}s hapPath = %{public}s", resPath.c_str(), hapPath.c_str());
710 container->SetResourceConfiguration(aceResCfg);
711 container->SetPackagePathStr(resPath);
712 container->SetHapPath(hapPath);
713 container->SetAssetManager(flutterAssetManager);
714 if (!isFormRender_) {
715 container->SetBundlePath(context->GetBundleCodeDir());
716 container->SetFilesDataPath(context->GetFilesDir());
717 }
718
719 if (window_) {
720 if (window_->IsDecorEnable()) {
721 LOGI("Container modal is enabled.");
722 container->SetWindowModal(WindowModal::CONTAINER_MODAL);
723 }
724
725 dragWindowListener_ = new DragWindowListener(instanceId_);
726 window_->RegisterDragListener(dragWindowListener_);
727 occupiedAreaChangeListener_ = new OccupiedAreaChangeListener(instanceId_);
728 window_->RegisterOccupiedAreaChangeListener(occupiedAreaChangeListener_);
729 }
730
731 // create ace_view
732 Platform::AceViewOhos* aceView = nullptr;
733 if (isFormRender_) {
734 aceView = Platform::AceViewOhos::CreateView(instanceId_, true, container->GetSettings().usePlatformAsUIThread);
735 Platform::AceViewOhos::SurfaceCreated(aceView, window_);
736 } else {
737 aceView = Platform::AceViewOhos::CreateView(instanceId_, false, container->GetSettings().usePlatformAsUIThread);
738 Platform::AceViewOhos::SurfaceCreated(aceView, window_);
739 }
740
741 if (!useNewPipe) {
742 Ace::Platform::UIEnvCallback callback = nullptr;
743 #ifdef ENABLE_ROSEN_BACKEND
744 callback = [window, id = instanceId_, container, aceView, rsUiDirector](
745 const OHOS::Ace::RefPtr<OHOS::Ace::PipelineContext>& context) {
746 if (rsUiDirector) {
747 ACE_SCOPED_TRACE("OHOS::Rosen::RSUIDirector::Create()");
748 rsUiDirector->SetUITaskRunner(
749 [taskExecutor = container->GetTaskExecutor(), id](const std::function<void()>& task) {
750 ContainerScope scope(id);
751 taskExecutor->PostTask(task, TaskExecutor::TaskType::UI);
752 });
753 auto context = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext());
754 if (context != nullptr) {
755 context->SetRSUIDirector(rsUiDirector);
756 }
757 LOGD("UIContent Init Rosen Backend");
758 }
759 };
760 #endif
761 // set view
762 Platform::AceContainer::SetView(aceView, density, 0, 0, window_, callback);
763 } else {
764 if (isFormRender_) {
765 LOGI("Platform::AceContainer::SetViewNew is card formWidth=%{public}f, formHeight=%{public}f", formWidth_,
766 formHeight_);
767 Platform::AceContainer::SetViewNew(aceView, density, formWidth_, formHeight_, window_);
768 auto frontend = AceType::DynamicCast<FormFrontendDeclarative>(container->GetFrontend());
769 CHECK_NULL_VOID(frontend);
770 frontend->SetBundleName(bundleName_);
771 frontend->SetModuleName(moduleName_);
772 // arkTSCard only support "esModule" compile mode
773 frontend->SetIsBundle(false);
774 } else {
775 Platform::AceContainer::SetViewNew(aceView, density, 0, 0, window_);
776 }
777 }
778
779 // after frontend initialize
780 if (window_ && window_->IsFocused()) {
781 LOGI("UIContentImpl: focus again");
782 Focus();
783 }
784
785 if (isFormRender_ && !isFormRenderInit_) {
786 container->UpdateFormSharedImage(formImageDataMap_);
787 container->UpdateFormData(formData_);
788 isFormRenderInit_ = true;
789 }
790
791 if (isFormRender_) {
792 Platform::AceViewOhos::SurfaceChanged(aceView, formWidth_, formHeight_, deviceHeight >= deviceWidth ? 0 : 1);
793 // Set sdk version in module json mode for form
794 auto pipeline = container->GetPipelineContext();
795 if (pipeline) {
796 pipeline->SetMinPlatformVersion(minCompatibleVersionCode_);
797 }
798 } else {
799 Platform::AceViewOhos::SurfaceChanged(aceView, 0, 0, deviceHeight >= deviceWidth ? 0 : 1);
800 }
801 // Set sdk version in module json mode
802 if (isModelJson) {
803 auto pipeline = container->GetPipelineContext();
804 if (pipeline && appInfo) {
805 LOGI("SetMinPlatformVersion code is %{public}d", appInfo->minCompatibleVersionCode);
806 pipeline->SetMinPlatformVersion(appInfo->minCompatibleVersionCode);
807 }
808 }
809 if (runtime_ && !isFormRender_) { // ArkTSCard not support inherit local strorage from context
810 auto nativeEngine = reinterpret_cast<NativeEngine*>(runtime_);
811 if (!storage) {
812 container->SetLocalStorage(nullptr, context->GetBindingObject()->Get<NativeReference>());
813 } else {
814 LOGI("SetLocalStorage %{public}d", storage->TypeOf());
815 container->SetLocalStorage(
816 nativeEngine->CreateReference(storage, 1), context->GetBindingObject()->Get<NativeReference>());
817 }
818 }
819 }
820
SetConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration> & config)821 void UIContentImpl::SetConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config)
822 {
823 if (config == nullptr) {
824 LOGI("config is nullptr, set localeInfo to default");
825 UErrorCode status = U_ZERO_ERROR;
826 icu::Locale locale = icu::Locale::forLanguageTag(Global::I18n::LocaleConfig::GetSystemLanguage(), status);
827 AceApplicationInfo::GetInstance().SetLocale(locale.getLanguage(), locale.getCountry(), locale.getScript(), "");
828 SystemProperties::SetColorMode(ColorMode::LIGHT);
829 return;
830 }
831
832 LOGI("SetConfiguration");
833 auto colorMode = config->GetItem(OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
834 auto deviceAccess = config->GetItem(OHOS::AAFwk::GlobalConfigurationKey::INPUT_POINTER_DEVICE);
835 auto languageTag = config->GetItem(OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE);
836 if (!colorMode.empty()) {
837 LOGI("SetConfiguration colorMode: %{public}s", colorMode.c_str());
838 if (colorMode == "dark") {
839 SystemProperties::SetColorMode(ColorMode::DARK);
840 } else {
841 SystemProperties::SetColorMode(ColorMode::LIGHT);
842 }
843 }
844
845 if (!deviceAccess.empty()) {
846 // Event of accessing mouse or keyboard
847 LOGI("SetConfiguration deviceAccess: %{public}s", deviceAccess.c_str());
848 SystemProperties::SetDeviceAccess(deviceAccess == "true");
849 }
850
851 if (!languageTag.empty()) {
852 LOGI("SetConfiguration languageTag: %{public}s", languageTag.c_str());
853 std::string language;
854 std::string script;
855 std::string region;
856 Localization::ParseLocaleTag(languageTag, language, script, region, false);
857 if (!language.empty() || !script.empty() || !region.empty()) {
858 AceApplicationInfo::GetInstance().SetLocale(language, region, script, "");
859 }
860 }
861 }
862
GetFormRootNode()863 std::shared_ptr<Rosen::RSSurfaceNode> UIContentImpl::GetFormRootNode()
864 {
865 return Platform::AceContainer::GetFormSurfaceNode(instanceId_);
866 }
867 // ArkTSCard end
868
CommonInitialize(OHOS::Rosen::Window * window,const std::string & contentInfo,NativeValue * storage)869 void UIContentImpl::CommonInitialize(OHOS::Rosen::Window* window, const std::string& contentInfo, NativeValue* storage)
870 {
871 ACE_FUNCTION_TRACE();
872 window_ = window;
873 CHECK_NULL_VOID(window_);
874 startUrl_ = contentInfo;
875 if (StringUtils::StartWith(window->GetWindowName(), SUBWINDOW_TOAST_DIALOG_PREFIX)) {
876 InitializeSubWindow(window_, true);
877 return;
878 }
879 if (StringUtils::StartWith(window->GetWindowName(), SUBWINDOW_PREFIX)) {
880 InitializeSubWindow(window_);
881 return;
882 }
883 auto context = context_.lock();
884 CHECK_NULL_VOID(context);
885 LOGI("Initialize UIContentImpl start.");
886 static std::once_flag onceFlag;
887 std::call_once(onceFlag, [&context]() {
888 LOGI("Initialize for current process.");
889 SetHwIcuDirectory();
890 Container::UpdateCurrent(INSTANCE_ID_PLATFORM);
891 auto abilityContext = OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(context);
892 if (abilityContext) {
893 int32_t missionId = -1;
894 abilityContext->GetMissionId(missionId);
895 AceApplicationInfo::GetInstance().SetMissionId(missionId);
896 }
897 AceApplicationInfo::GetInstance().SetProcessName(context->GetBundleName());
898 AceApplicationInfo::GetInstance().SetPackageName(context->GetBundleName());
899 AceApplicationInfo::GetInstance().SetDataFileDirPath(context->GetFilesDir());
900 AceApplicationInfo::GetInstance().SetApiTargetVersion(context->GetApplicationInfo()->apiTargetVersion);
901 AceApplicationInfo::GetInstance().SetAppVersionName(context->GetApplicationInfo()->versionName);
902 AceApplicationInfo::GetInstance().SetAppVersionCode(context->GetApplicationInfo()->versionCode);
903 AceApplicationInfo::GetInstance().SetUid(IPCSkeleton::GetCallingUid());
904 AceApplicationInfo::GetInstance().SetPid(IPCSkeleton::GetCallingPid());
905 CapabilityRegistry::Register();
906 ImageCache::SetImageCacheFilePath(context->GetCacheDir());
907 ImageCache::SetCacheFileInfo();
908 });
909 AceNewPipeJudgement::InitAceNewPipeConfig();
910 auto apiCompatibleVersion = context->GetApplicationInfo()->apiCompatibleVersion;
911 auto apiReleaseType = context->GetApplicationInfo()->apiReleaseType;
912 auto apiTargetVersion = context->GetApplicationInfo()->apiTargetVersion;
913 const auto& hapModuleInfo = context->GetHapModuleInfo();
914 std::vector<OHOS::AppExecFwk::Metadata> metaData;
915 if (hapModuleInfo) {
916 metaData = hapModuleInfo->metadata;
917 }
918 bool closeArkTSPartialUpdate = std::any_of(metaData.begin(), metaData.end(), [](const auto& metaDataItem) {
919 return metaDataItem.name == "ArkTSPartialUpdate" && metaDataItem.value == "false";
920 });
921
922 bool isDelayedUpdateOnInactive = std::any_of(metaData.begin(), metaData.end(), [](const auto& metaDataItem) {
923 return metaDataItem.name == "delayedUpdateOnInactive" && metaDataItem.value == "true";
924 });
925 AceApplicationInfo::GetInstance().SetDelayedUpdateOnInactive(isDelayedUpdateOnInactive);
926
927 auto useNewPipe =
928 AceNewPipeJudgement::QueryAceNewPipeEnabledStage(AceApplicationInfo::GetInstance().GetPackageName(),
929 apiCompatibleVersion, apiTargetVersion, apiReleaseType, closeArkTSPartialUpdate);
930 LOGI("UIContent: apiCompatibleVersion: %{public}d, apiTargetVersion: %{public}d, and apiReleaseType: %{public}s, "
931 "useNewPipe: %{public}d, isDelayedUpdateOnInactive: %{public}d",
932 apiCompatibleVersion, apiTargetVersion, apiReleaseType.c_str(), useNewPipe, isDelayedUpdateOnInactive);
933 #ifdef ENABLE_ROSEN_BACKEND
934 std::shared_ptr<OHOS::Rosen::RSUIDirector> rsUiDirector;
935 if (SystemProperties::GetRosenBackendEnabled() && !useNewPipe) {
936 rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
937 if (rsUiDirector) {
938 rsUiDirector->SetRSSurfaceNode(window->GetSurfaceNode());
939 rsUiDirector->SetCacheDir(context->GetCacheDir());
940 rsUiDirector->Init();
941 }
942 }
943 #endif
944 int32_t deviceWidth = 0;
945 int32_t deviceHeight = 0;
946 float density = 1.0f;
947 auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
948 if (defaultDisplay) {
949 density = defaultDisplay->GetVirtualPixelRatio();
950 deviceWidth = defaultDisplay->GetWidth();
951 deviceHeight = defaultDisplay->GetHeight();
952 LOGI("UIContent: deviceWidth: %{public}d, deviceHeight: %{public}d, default density: %{public}f", deviceWidth,
953 deviceHeight, density);
954 }
955 SystemProperties::InitDeviceInfo(deviceWidth, deviceHeight, deviceHeight >= deviceWidth ? 0 : 1, density, false);
956 // Initialize performance check parameters
957 AceChecker::InitPerformanceParameters();
958 AcePerformanceCheck::Start();
959 SystemProperties::SetColorMode(ColorMode::LIGHT);
960
961 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
962 auto resourceManager = context->GetResourceManager();
963 if (resourceManager != nullptr) {
964 resourceManager->GetResConfig(*resConfig);
965 auto localeInfo = resConfig->GetLocaleInfo();
966 Platform::AceApplicationInfoImpl::GetInstance().SetResourceManager(resourceManager);
967 if (localeInfo != nullptr) {
968 auto language = localeInfo->getLanguage();
969 auto region = localeInfo->getCountry();
970 auto script = localeInfo->getScript();
971 AceApplicationInfo::GetInstance().SetLocale((language == nullptr) ? "" : language,
972 (region == nullptr) ? "" : region, (script == nullptr) ? "" : script, "");
973 }
974 if (resConfig->GetColorMode() == OHOS::Global::Resource::ColorMode::DARK) {
975 SystemProperties::SetColorMode(ColorMode::DARK);
976 LOGI("UIContent set dark mode");
977 } else {
978 SystemProperties::SetColorMode(ColorMode::LIGHT);
979 LOGI("UIContent set light mode");
980 }
981 SystemProperties::SetDeviceAccess(
982 resConfig->GetInputDevice() == Global::Resource::InputDevice::INPUTDEVICE_POINTINGDEVICE);
983 }
984
985 auto abilityContext = OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(context);
986 std::shared_ptr<OHOS::AppExecFwk::AbilityInfo> info;
987 if (abilityContext) {
988 info = abilityContext->GetAbilityInfo();
989 } else {
990 auto extensionContext =
991 OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::ExtensionContext>(context);
992 if (!extensionContext) {
993 LOGE("context is not AbilityContext or ExtensionContext.");
994 return;
995 }
996 info = extensionContext->GetAbilityInfo();
997 }
998 if (info) {
999 AceApplicationInfo::GetInstance().SetAbilityName(info->name);
1000 }
1001
1002 RefPtr<FlutterAssetManager> flutterAssetManager = Referenced::MakeRefPtr<FlutterAssetManager>();
1003 bool isModelJson = info != nullptr ? info->isModuleJson : false;
1004 std::string moduleName = info != nullptr ? info->moduleName : "";
1005 auto appInfo = context->GetApplicationInfo();
1006 auto bundleName = info != nullptr ? info->bundleName : "";
1007 std::string moduleHapPath = info != nullptr ? info->hapPath : "";
1008 std::string resPath;
1009 std::string pageProfile;
1010 LOGI("Initialize UIContent isModelJson:%{public}s", isModelJson ? "true" : "false");
1011 if (isModelJson) {
1012 std::string hapPath = info != nullptr ? info->hapPath : "";
1013 LOGI("hapPath:%{public}s", hapPath.c_str());
1014 // first use hap provider
1015 if (flutterAssetManager && !hapPath.empty()) {
1016 auto assetProvider = AceType::MakeRefPtr<HapAssetProvider>();
1017 if (assetProvider->Initialize(hapPath, { "", "ets/", "resources/base/profile/" })) {
1018 LOGD("Push HapAssetProvider to queue.");
1019 flutterAssetManager->PushBack(std::move(assetProvider));
1020 }
1021 }
1022
1023 if (appInfo) {
1024 std::vector<OHOS::AppExecFwk::ModuleInfo> moduleList = appInfo->moduleInfos;
1025 for (const auto& module : moduleList) {
1026 if (module.moduleName == moduleName) {
1027 std::regex pattern(ABS_BUNDLE_CODE_PATH + bundleName + FILE_SEPARATOR);
1028 auto moduleSourceDir = std::regex_replace(module.moduleSourceDir, pattern, LOCAL_BUNDLE_CODE_PATH);
1029 resPath = moduleSourceDir + "/";
1030 break;
1031 }
1032 }
1033 }
1034
1035 // second use file provider, will remove later
1036 LOGI("In stage mode, resPath:%{private}s", resPath.c_str());
1037 auto assetBasePathStr = { std::string("ets/"), std::string("resources/base/profile/") };
1038 if (flutterAssetManager && !resPath.empty()) {
1039 auto assetProvider = AceType::MakeRefPtr<FileAssetProvider>();
1040 if (assetProvider->Initialize(resPath, assetBasePathStr)) {
1041 LOGD("Push AssetProvider to queue.");
1042 flutterAssetManager->PushBack(std::move(assetProvider));
1043 }
1044 }
1045
1046 if (hapModuleInfo) {
1047 pageProfile = hapModuleInfo->pages;
1048 const std::string profilePrefix = "$profile:";
1049 if (pageProfile.compare(0, profilePrefix.size(), profilePrefix) == 0) {
1050 pageProfile = pageProfile.substr(profilePrefix.length()).append(".json");
1051 }
1052 LOGI("In stage mode, pageProfile:%{public}s", pageProfile.c_str());
1053 } else {
1054 LOGE("In stage mode, can't get hap info.");
1055 }
1056 } else {
1057 auto packagePathStr = context->GetBundleCodeDir();
1058 if (hapModuleInfo != nullptr) {
1059 packagePathStr += "/" + hapModuleInfo->package + "/";
1060 }
1061 std::string srcPath = "";
1062 if (info != nullptr && !info->srcPath.empty()) {
1063 srcPath = info->srcPath;
1064 }
1065
1066 auto assetBasePathStr = { "assets/js/" + (srcPath.empty() ? "default" : srcPath) + "/",
1067 std::string("assets/js/share/") };
1068
1069 if (flutterAssetManager && !packagePathStr.empty()) {
1070 auto assetProvider = AceType::MakeRefPtr<FileAssetProvider>();
1071 if (assetProvider->Initialize(packagePathStr, assetBasePathStr)) {
1072 LOGD("Push AssetProvider to queue.");
1073 flutterAssetManager->PushBack(std::move(assetProvider));
1074 }
1075 }
1076
1077 if (appInfo) {
1078 std::vector<OHOS::AppExecFwk::ModuleInfo> moduleList = appInfo->moduleInfos;
1079 for (const auto& module : moduleList) {
1080 if (module.moduleName == moduleName) {
1081 std::regex pattern(ABS_BUNDLE_CODE_PATH + bundleName + FILE_SEPARATOR);
1082 auto moduleSourceDir = std::regex_replace(module.moduleSourceDir, pattern, LOCAL_BUNDLE_CODE_PATH);
1083 resPath = moduleSourceDir + "/assets/" + module.moduleName + "/";
1084 break;
1085 }
1086 }
1087 }
1088 }
1089
1090 std::string hapPath; // hap path in sandbox
1091 if (!moduleHapPath.empty()) {
1092 if (moduleHapPath.find(ABS_BUNDLE_CODE_PATH) == std::string::npos) {
1093 hapPath = moduleHapPath;
1094 } else {
1095 auto pos = moduleHapPath.find_last_of('/');
1096 if (pos != std::string::npos) {
1097 hapPath = LOCAL_BUNDLE_CODE_PATH + moduleHapPath.substr(pos + 1);
1098 LOGI("In Stage mode, hapPath:%{private}s", hapPath.c_str());
1099 }
1100 }
1101 }
1102
1103 auto pluginUtils = std::make_shared<PluginUtilsImpl>();
1104 PluginManager::GetInstance().SetAceAbility(nullptr, pluginUtils);
1105 // create container
1106 if (runtime_) {
1107 instanceId_ = gInstanceId.fetch_add(1, std::memory_order_relaxed);
1108 } else {
1109 instanceId_ = gSubWindowInstanceId.fetch_add(1, std::memory_order_relaxed);
1110 }
1111 auto formUtils = std::make_shared<FormUtilsImpl>();
1112 FormManager::GetInstance().SetFormUtils(formUtils);
1113 auto container =
1114 AceType::MakeRefPtr<Platform::AceContainer>(instanceId_, FrontendType::DECLARATIVE_JS, context_, info,
1115 std::make_unique<ContentEventCallback>(
1116 [window = window_] {
1117 CHECK_NULL_VOID_NOLOG(window);
1118 window->PerformBack();
1119 },
1120 [context = context_](const std::string& address) {
1121 auto sharedContext = context.lock();
1122 CHECK_NULL_VOID_NOLOG(sharedContext);
1123 auto abilityContext =
1124 OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(sharedContext);
1125 CHECK_NULL_VOID_NOLOG(abilityContext);
1126 LOGI("start ability with url = %{private}s", address.c_str());
1127 AAFwk::Want want;
1128 want.AddEntity(Want::ENTITY_BROWSER);
1129 want.SetUri(address);
1130 want.SetAction(ACTION_VIEWDATA);
1131 abilityContext->StartAbility(want, REQUEST_CODE);
1132 }),
1133 false, false, useNewPipe);
1134 CHECK_NULL_VOID(container);
1135 container->SetWindowName(window_->GetWindowName());
1136 container->SetWindowId(window_->GetWindowId());
1137 auto token = context->GetToken();
1138 container->SetToken(token);
1139 container->SetPageUrlChecker(AceType::MakeRefPtr<PageUrlCheckerOhos>(context));
1140 // Mark the relationship between windowId and containerId, it is 1:1
1141 SubwindowManager::GetInstance()->AddContainerId(window->GetWindowId(), instanceId_);
1142 AceEngine::Get().AddContainer(instanceId_, container);
1143 if (runtime_) {
1144 container->GetSettings().SetUsingSharedRuntime(true);
1145 container->SetSharedRuntime(runtime_);
1146 } else {
1147 container->GetSettings().SetUsingSharedRuntime(false);
1148 }
1149 container->SetPageProfile(pageProfile);
1150 container->Initialize();
1151 ContainerScope scope(instanceId_);
1152 auto front = container->GetFrontend();
1153 if (front) {
1154 front->UpdateState(Frontend::State::ON_CREATE);
1155 front->SetJsMessageDispatcher(container);
1156 }
1157 auto aceResCfg = container->GetResourceConfiguration();
1158 aceResCfg.SetOrientation(SystemProperties::GetDeviceOrientation());
1159 aceResCfg.SetDensity(SystemProperties::GetResolution());
1160 aceResCfg.SetDeviceType(SystemProperties::GetDeviceType());
1161 aceResCfg.SetColorMode(SystemProperties::GetColorMode());
1162 aceResCfg.SetDeviceAccess(SystemProperties::GetDeviceAccess());
1163 container->SetResourceConfiguration(aceResCfg);
1164 container->SetPackagePathStr(resPath);
1165 container->SetHapPath(hapPath);
1166 container->SetAssetManager(flutterAssetManager);
1167 container->SetBundlePath(context->GetBundleCodeDir());
1168 container->SetFilesDataPath(context->GetFilesDir());
1169 container->SetModuleName(hapModuleInfo->moduleName);
1170 container->SetIsModule(hapModuleInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE);
1171 // for atomic service
1172 container->SetInstallationFree(hapModuleInfo && hapModuleInfo->installationFree);
1173 if (hapModuleInfo->installationFree) {
1174 container->SetSharePanelCallback(
1175 [context = context_](const std::string& bundleName, const std::string& abilityName) {
1176 auto sharedContext = context.lock();
1177 CHECK_NULL_VOID_NOLOG(sharedContext);
1178 auto abilityContext =
1179 OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(sharedContext);
1180 CHECK_NULL_VOID_NOLOG(abilityContext);
1181 auto abilityInfo = abilityContext->GetAbilityInfo();
1182 AAFwk::Want want;
1183 want.SetParam("abilityName", abilityInfo->name);
1184 want.SetParam("bundleName", abilityInfo->bundleName);
1185 want.SetParam("moduleName", abilityInfo->moduleName);
1186 want.SetParam("hostPkgName", abilityInfo->bundleName);
1187 want.SetElementName(bundleName, abilityName);
1188 abilityContext->StartAbility(want, REQUEST_CODE);
1189 });
1190 }
1191
1192 if (window_->IsDecorEnable()) {
1193 LOGI("Container modal is enabled.");
1194 container->SetWindowModal(WindowModal::CONTAINER_MODAL);
1195 }
1196 dragWindowListener_ = new DragWindowListener(instanceId_);
1197 window_->RegisterDragListener(dragWindowListener_);
1198 occupiedAreaChangeListener_ = new OccupiedAreaChangeListener(instanceId_);
1199 window_->RegisterOccupiedAreaChangeListener(occupiedAreaChangeListener_);
1200
1201 // create ace_view
1202 auto aceView =
1203 Platform::AceViewOhos::CreateView(instanceId_, false, container->GetSettings().usePlatformAsUIThread);
1204 Platform::AceViewOhos::SurfaceCreated(aceView, window_);
1205 if (!useNewPipe) {
1206 Ace::Platform::UIEnvCallback callback = nullptr;
1207 #ifdef ENABLE_ROSEN_BACKEND
1208 callback = [window, id = instanceId_, container, aceView, rsUiDirector](
1209 const OHOS::Ace::RefPtr<OHOS::Ace::PipelineContext>& context) {
1210 if (rsUiDirector) {
1211 ACE_SCOPED_TRACE("OHOS::Rosen::RSUIDirector::Create()");
1212 rsUiDirector->SetUITaskRunner(
1213 [taskExecutor = container->GetTaskExecutor(), id](const std::function<void()>& task) {
1214 ContainerScope scope(id);
1215 taskExecutor->PostTask(task, TaskExecutor::TaskType::UI);
1216 });
1217 auto context = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext());
1218 if (context != nullptr) {
1219 context->SetRSUIDirector(rsUiDirector);
1220 }
1221 LOGD("UIContent Init Rosen Backend");
1222 }
1223 };
1224 #endif
1225 // set view
1226 Platform::AceContainer::SetView(aceView, density, 0, 0, window_, callback);
1227 } else {
1228 Platform::AceContainer::SetViewNew(aceView, density, 0, 0, window_);
1229 }
1230
1231 // after frontend initialize
1232 if (window_->IsFocused()) {
1233 LOGI("UIContentImpl: focus again");
1234 Focus();
1235 }
1236
1237 Platform::AceViewOhos::SurfaceChanged(aceView, 0, 0, deviceHeight >= deviceWidth ? 0 : 1);
1238 auto pipeline = container->GetPipelineContext();
1239 if (pipeline) {
1240 auto rsConfig = window_->GetKeyboardAnimationConfig();
1241 KeyboardAnimationConfig config = { rsConfig.curveType_, rsConfig.curveParams_, rsConfig.durationIn_,
1242 rsConfig.durationOut_ };
1243 pipeline->SetKeyboardAnimationConfig(config);
1244 }
1245 // Set sdk version in module json mode
1246 if (isModelJson) {
1247 if (pipeline && appInfo) {
1248 LOGI("SetMinPlatformVersion code is %{public}d", appInfo->apiCompatibleVersion);
1249 pipeline->SetMinPlatformVersion(appInfo->apiCompatibleVersion);
1250 }
1251 }
1252 if (runtime_) {
1253 auto nativeEngine = reinterpret_cast<NativeEngine*>(runtime_);
1254 if (!storage) {
1255 container->SetLocalStorage(nullptr, context->GetBindingObject()->Get<NativeReference>());
1256 } else {
1257 LOGI("SetLocalStorage %{public}d", storage->TypeOf());
1258 container->SetLocalStorage(
1259 nativeEngine->CreateReference(storage, 1), context->GetBindingObject()->Get<NativeReference>());
1260 }
1261 }
1262
1263 InitializeSafeArea(container);
1264
1265 LayoutInspector::SetCallback(instanceId_);
1266
1267 LOGI("Initialize UIContentImpl end.");
1268 }
1269
InitializeSafeArea(const RefPtr<Platform::AceContainer> & container)1270 void UIContentImpl::InitializeSafeArea(const RefPtr<Platform::AceContainer>& container)
1271 {
1272 constexpr static int32_t PLATFORM_VERSION_TEN = 10;
1273 auto pipeline = container->GetPipelineContext();
1274 if (pipeline && pipeline->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN && pipeline->GetIsAppWindow()) {
1275 avoidAreaChangedListener_ = new AvoidAreaChangedListener(instanceId_);
1276 window_->RegisterAvoidAreaChangeListener(avoidAreaChangedListener_);
1277 pipeline->UpdateSystemSafeArea(container->GetViewSafeAreaByType(Rosen::AvoidAreaType::TYPE_SYSTEM));
1278 pipeline->UpdateCutoutSafeArea(container->GetViewSafeAreaByType(Rosen::AvoidAreaType::TYPE_CUTOUT));
1279 }
1280 }
1281
Foreground()1282 void UIContentImpl::Foreground()
1283 {
1284 LOGI("UIContentImpl: window foreground");
1285 Platform::AceContainer::OnShow(instanceId_);
1286 // set the flag isForegroundCalled to be true
1287 auto container = Platform::AceContainer::GetContainer(instanceId_);
1288 CHECK_NULL_VOID(container);
1289 auto pipelineContext = container->GetPipelineContext();
1290 CHECK_NULL_VOID(pipelineContext);
1291 pipelineContext->SetForegroundCalled(true);
1292 }
1293
Background()1294 void UIContentImpl::Background()
1295 {
1296 LOGI("UIContentImpl: window background");
1297 Platform::AceContainer::OnHide(instanceId_);
1298 }
1299
ReloadForm(const std::string & url)1300 void UIContentImpl::ReloadForm(const std::string& url)
1301 {
1302 startUrl_ = url;
1303 LOGI("ReloadForm startUrl = %{public}s", startUrl_.c_str());
1304 auto container = Platform::AceContainer::GetContainer(instanceId_);
1305 CHECK_NULL_VOID(container);
1306 auto flutterAssetManager = AceType::DynamicCast<FlutterAssetManager>(container->GetAssetManager());
1307 flutterAssetManager->ReloadProvider();
1308 container->ReloadForm();
1309 Platform::AceContainer::RunPage(
1310 instanceId_, Platform::AceContainer::GetContainer(instanceId_)->GeneratePageId(), startUrl_, "");
1311 }
1312
Focus()1313 void UIContentImpl::Focus()
1314 {
1315 LOGI("UIContentImpl: window focus");
1316 Platform::AceContainer::OnActive(instanceId_);
1317 }
1318
UnFocus()1319 void UIContentImpl::UnFocus()
1320 {
1321 LOGI("UIContentImpl: window unFocus");
1322 Platform::AceContainer::OnInactive(instanceId_);
1323 }
1324
Destroy()1325 void UIContentImpl::Destroy()
1326 {
1327 LOGI("UIContentImpl: window destroy");
1328 auto container = AceEngine::Get().GetContainer(instanceId_);
1329 CHECK_NULL_VOID_NOLOG(container);
1330 // stop performance check and output json file
1331 AcePerformanceCheck::Stop();
1332 if (AceType::InstanceOf<Platform::DialogContainer>(container)) {
1333 Platform::DialogContainer::DestroyContainer(instanceId_);
1334 } else {
1335 Platform::AceContainer::DestroyContainer(instanceId_);
1336 }
1337 }
1338
OnNewWant(const OHOS::AAFwk::Want & want)1339 void UIContentImpl::OnNewWant(const OHOS::AAFwk::Want& want)
1340 {
1341 LOGI("UIContent OnNewWant");
1342 std::string params = want.GetStringParam(START_PARAMS_KEY);
1343 Platform::AceContainer::OnNewRequest(instanceId_, params);
1344 }
1345
GetBackgroundColor()1346 uint32_t UIContentImpl::GetBackgroundColor()
1347 {
1348 auto container = Platform::AceContainer::GetContainer(instanceId_);
1349 CHECK_NULL_RETURN(container, 0x000000);
1350 auto taskExecutor = container->GetTaskExecutor();
1351 CHECK_NULL_RETURN(taskExecutor, 0x000000);
1352 ContainerScope scope(instanceId_);
1353 uint32_t bgColor = 0x000000;
1354 taskExecutor->PostSyncTask(
1355 [&bgColor, container]() {
1356 CHECK_NULL_VOID(container);
1357 auto pipelineContext = container->GetPipelineContext();
1358 CHECK_NULL_VOID(pipelineContext);
1359 bgColor = pipelineContext->GetAppBgColor().GetValue();
1360 },
1361 TaskExecutor::TaskType::UI);
1362
1363 LOGI("UIContentImpl::GetBackgroundColor, value is %{public}u", bgColor);
1364 return bgColor;
1365 }
1366
SetBackgroundColor(uint32_t color)1367 void UIContentImpl::SetBackgroundColor(uint32_t color)
1368 {
1369 LOGI("UIContentImpl: SetBackgroundColor color is %{public}u", color);
1370 auto container = AceEngine::Get().GetContainer(instanceId_);
1371 CHECK_NULL_VOID(container);
1372 ContainerScope scope(instanceId_);
1373 auto taskExecutor = container->GetTaskExecutor();
1374 CHECK_NULL_VOID(taskExecutor);
1375 taskExecutor->PostSyncTask(
1376 [container, bgColor = color]() {
1377 auto pipelineContext = container->GetPipelineContext();
1378 CHECK_NULL_VOID(pipelineContext);
1379 pipelineContext->SetAppBgColor(Color(bgColor));
1380 },
1381 TaskExecutor::TaskType::UI);
1382 }
1383
ProcessBackPressed()1384 bool UIContentImpl::ProcessBackPressed()
1385 {
1386 LOGI("UIContentImpl: ProcessBackPressed: Platform::AceContainer::OnBackPressed called");
1387 auto container = AceEngine::Get().GetContainer(instanceId_);
1388 CHECK_NULL_RETURN_NOLOG(container, false);
1389 auto taskExecutor = container->GetTaskExecutor();
1390 CHECK_NULL_RETURN_NOLOG(taskExecutor, false);
1391 bool ret = false;
1392 taskExecutor->PostSyncTask(
1393 [container, this, &ret]() {
1394 if (AceType::InstanceOf<Platform::DialogContainer>(container)) {
1395 if (Platform::DialogContainer::OnBackPressed(instanceId_)) {
1396 LOGI("UIContentImpl::ProcessBackPressed DialogContainer return true");
1397 ret = true;
1398 }
1399 } else {
1400 LOGI("UIContentImpl::ProcessBackPressed AceContainer");
1401 if (Platform::AceContainer::OnBackPressed(instanceId_)) {
1402 LOGI("UIContentImpl::ProcessBackPressed AceContainer return true");
1403 ret = true;
1404 }
1405 }
1406 },
1407 TaskExecutor::TaskType::UI);
1408 LOGI("ProcessBackPressed: Platform::AceContainer::OnBackPressed return false");
1409 return ret;
1410 }
1411
ProcessPointerEvent(const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)1412 bool UIContentImpl::ProcessPointerEvent(const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
1413 {
1414 LOGD("UIContentImpl::ProcessPointerEvent begin");
1415 auto container = AceType::DynamicCast<Platform::AceContainer>(AceEngine::Get().GetContainer(instanceId_));
1416 CHECK_NULL_RETURN(container, false);
1417 container->SetCurPointerEvent(pointerEvent);
1418 auto aceView = static_cast<Platform::AceViewOhos*>(container->GetView());
1419 Platform::AceViewOhos::DispatchTouchEvent(aceView, pointerEvent);
1420 LOGD("UIContentImpl::ProcessPointerEvent end");
1421 return true;
1422 }
1423
ProcessKeyEvent(const std::shared_ptr<OHOS::MMI::KeyEvent> & touchEvent)1424 bool UIContentImpl::ProcessKeyEvent(const std::shared_ptr<OHOS::MMI::KeyEvent>& touchEvent)
1425 {
1426 LOGD("UIContentImpl: OnKeyUp called, keyEvent info: keyCode is %{public}d,"
1427 "keyAction is %{public}d, keyActionTime is %{public}" PRId64,
1428 touchEvent->GetKeyCode(), touchEvent->GetKeyAction(), touchEvent->GetActionTime());
1429 auto container = AceEngine::Get().GetContainer(instanceId_);
1430 CHECK_NULL_RETURN(container, false);
1431 auto aceView = static_cast<Platform::AceViewOhos*>(container->GetView());
1432 return Platform::AceViewOhos::DispatchKeyEvent(aceView, touchEvent);
1433 }
1434
ProcessAxisEvent(const std::shared_ptr<OHOS::MMI::AxisEvent> & axisEvent)1435 bool UIContentImpl::ProcessAxisEvent(const std::shared_ptr<OHOS::MMI::AxisEvent>& axisEvent)
1436 {
1437 LOGD("UIContentImpl ProcessAxisEvent");
1438 return false;
1439 }
1440
ProcessVsyncEvent(uint64_t timeStampNanos)1441 bool UIContentImpl::ProcessVsyncEvent(uint64_t timeStampNanos)
1442 {
1443 LOGD("UIContentImpl ProcessVsyncEvent");
1444 return false;
1445 }
1446
UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration> & config)1447 void UIContentImpl::UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config)
1448 {
1449 LOGI("UIContentImpl: UpdateConfiguration called");
1450 CHECK_NULL_VOID(config);
1451 auto container = Platform::AceContainer::GetContainer(instanceId_);
1452 CHECK_NULL_VOID(container);
1453 auto taskExecutor = container->GetTaskExecutor();
1454 CHECK_NULL_VOID(taskExecutor);
1455 taskExecutor->PostTask(
1456 [weakContainer = WeakPtr<Platform::AceContainer>(container), config]() {
1457 auto container = weakContainer.Upgrade();
1458 CHECK_NULL_VOID_NOLOG(container);
1459 auto colorMode = config->GetItem(OHOS::AppExecFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
1460 auto deviceAccess = config->GetItem(OHOS::AppExecFwk::GlobalConfigurationKey::INPUT_POINTER_DEVICE);
1461 auto languageTag = config->GetItem(OHOS::AppExecFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE);
1462 container->UpdateConfiguration(colorMode, deviceAccess, languageTag, (*config).GetName());
1463 LOGI("UIContentImpl: UpdateConfiguration called End, name:%{public}s", config->GetName().c_str());
1464 },
1465 TaskExecutor::TaskType::UI);
1466 }
1467
UpdateViewportConfig(const ViewportConfig & config,OHOS::Rosen::WindowSizeChangeReason reason,const std::shared_ptr<OHOS::Rosen::RSTransaction> & rsTransaction)1468 void UIContentImpl::UpdateViewportConfig(const ViewportConfig& config, OHOS::Rosen::WindowSizeChangeReason reason,
1469 const std::shared_ptr<OHOS::Rosen::RSTransaction>& rsTransaction)
1470 {
1471 LOGI("UIContentImpl: UpdateViewportConfig %{public}s", config.ToString().c_str());
1472 SystemProperties::SetResolution(config.Density());
1473 SystemProperties::SetDeviceOrientation(config.Orientation());
1474 auto container = Platform::AceContainer::GetContainer(instanceId_);
1475 CHECK_NULL_VOID(container);
1476 auto taskExecutor = container->GetTaskExecutor();
1477 CHECK_NULL_VOID(taskExecutor);
1478 auto task = [config, container, reason, rsTransaction, rsWindow = window_]() {
1479 container->SetWindowPos(config.Left(), config.Top());
1480 auto pipelineContext = container->GetPipelineContext();
1481 if (pipelineContext) {
1482 pipelineContext->SetDisplayWindowRectInfo(
1483 Rect(Offset(config.Left(), config.Top()), Size(config.Width(), config.Height())));
1484 if (rsWindow) {
1485 pipelineContext->SetIsLayoutFullScreen(
1486 rsWindow->GetMode() == Rosen::WindowMode::WINDOW_MODE_FULLSCREEN);
1487 }
1488 if (reason == OHOS::Rosen::WindowSizeChangeReason::ROTATION) {
1489 pipelineContext->FlushBuild();
1490 }
1491 }
1492 auto aceView = static_cast<Platform::AceViewOhos*>(container->GetAceView());
1493 CHECK_NULL_VOID(aceView);
1494 Platform::AceViewOhos::SetViewportMetrics(aceView, config);
1495 Platform::AceViewOhos::SurfaceChanged(aceView, config.Width(), config.Height(), config.Orientation(),
1496 static_cast<WindowSizeChangeReason>(reason), rsTransaction);
1497 Platform::AceViewOhos::SurfacePositionChanged(aceView, config.Left(), config.Top());
1498 };
1499 if (container->IsUseStageModel() && reason == OHOS::Rosen::WindowSizeChangeReason::ROTATION) {
1500 task();
1501 } else {
1502 taskExecutor->PostTask(task, TaskExecutor::TaskType::PLATFORM);
1503 }
1504 }
1505
SetIgnoreViewSafeArea(bool ignoreViewSafeArea)1506 void UIContentImpl::SetIgnoreViewSafeArea(bool ignoreViewSafeArea)
1507 {
1508 LOGI("UIContentImpl: SetIgnoreViewSafeArea:%{public}u", ignoreViewSafeArea);
1509 auto container = AceEngine::Get().GetContainer(instanceId_);
1510 CHECK_NULL_VOID(container);
1511 ContainerScope scope(instanceId_);
1512 auto pipeline = container->GetPipelineContext();
1513 const static int32_t PLATFORM_VERSION_TEN = 10;
1514 CHECK_NULL_VOID_NOLOG(
1515 pipeline && pipeline->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN && pipeline->GetIsAppWindow());
1516 auto taskExecutor = container->GetTaskExecutor();
1517 CHECK_NULL_VOID(taskExecutor);
1518 taskExecutor->PostSyncTask(
1519 [container, ignoreSafeArea = ignoreViewSafeArea]() {
1520 auto pipelineContext = container->GetPipelineContext();
1521 CHECK_NULL_VOID(pipelineContext);
1522 pipelineContext->SetIgnoreViewSafeArea(ignoreSafeArea);
1523 },
1524 TaskExecutor::TaskType::UI);
1525 }
1526
UpdateWindowMode(OHOS::Rosen::WindowMode mode,bool hasDeco)1527 void UIContentImpl::UpdateWindowMode(OHOS::Rosen::WindowMode mode, bool hasDeco)
1528 {
1529 LOGI("UIContentImpl: UpdateWindowMode, window mode is %{public}d, hasDeco is %{public}d", mode, hasDeco);
1530 auto container = Platform::AceContainer::GetContainer(instanceId_);
1531 CHECK_NULL_VOID(container);
1532 ContainerScope scope(instanceId_);
1533 auto taskExecutor = Container::CurrentTaskExecutor();
1534 CHECK_NULL_VOID(taskExecutor);
1535 taskExecutor->PostTask(
1536 [container, mode, hasDeco]() {
1537 auto pipelineContext = container->GetPipelineContext();
1538 CHECK_NULL_VOID(pipelineContext);
1539 pipelineContext->ShowContainerTitle(mode == OHOS::Rosen::WindowMode::WINDOW_MODE_FLOATING, hasDeco);
1540 },
1541 TaskExecutor::TaskType::UI);
1542 }
1543
HideWindowTitleButton(bool hideSplit,bool hideMaximize,bool hideMinimize)1544 void UIContentImpl::HideWindowTitleButton(bool hideSplit, bool hideMaximize, bool hideMinimize)
1545 {
1546 LOGI("HideWindowTitleButton hideSplit: %{public}d, hideMaximize: %{public}d, hideMinimize: %{public}d", hideSplit,
1547 hideMaximize, hideMinimize);
1548 auto container = Platform::AceContainer::GetContainer(instanceId_);
1549 CHECK_NULL_VOID(container);
1550 ContainerScope scope(instanceId_);
1551 auto taskExecutor = Container::CurrentTaskExecutor();
1552 CHECK_NULL_VOID(taskExecutor);
1553 taskExecutor->PostTask(
1554 [container, hideSplit, hideMaximize, hideMinimize]() {
1555 auto pipelineContext = container->GetPipelineContext();
1556 CHECK_NULL_VOID(pipelineContext);
1557 pipelineContext->SetContainerButtonHide(hideSplit, hideMaximize, hideMinimize);
1558 },
1559 TaskExecutor::TaskType::UI);
1560 }
1561
DumpInfo(const std::vector<std::string> & params,std::vector<std::string> & info)1562 void UIContentImpl::DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info)
1563 {
1564 auto container = Platform::AceContainer::GetContainer(instanceId_);
1565 CHECK_NULL_VOID(container);
1566 auto taskExecutor = container->GetTaskExecutor();
1567 CHECK_NULL_VOID(taskExecutor);
1568 auto ret = taskExecutor->PostSyncTaskTimeout(
1569 [&]() { container->Dump(params, info); }, TaskExecutor::TaskType::UI, 1500); // timeout 1.5s
1570 if (!ret) {
1571 LOGE("DumpInfo failed");
1572 }
1573 }
1574
InitializeSubWindow(OHOS::Rosen::Window * window,bool isDialog)1575 void UIContentImpl::InitializeSubWindow(OHOS::Rosen::Window* window, bool isDialog)
1576 {
1577 window_ = window;
1578 LOGI("The window name is %{public}s", window->GetWindowName().c_str());
1579 CHECK_NULL_VOID(window_);
1580 RefPtr<Container> container;
1581 instanceId_ = gSubInstanceId.fetch_add(1, std::memory_order_relaxed);
1582
1583 std::weak_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo;
1584 std::weak_ptr<OHOS::AbilityRuntime::Context> runtimeContext;
1585 if (isDialog) {
1586 container = AceType::MakeRefPtr<Platform::DialogContainer>(instanceId_, FrontendType::DECLARATIVE_JS);
1587 } else {
1588 if (Container::IsCurrentUseNewPipeline()) {
1589 container = AceType::MakeRefPtr<Platform::AceContainer>(instanceId_, FrontendType::DECLARATIVE_JS,
1590 runtimeContext, abilityInfo, std::make_unique<ContentEventCallback>([] {
1591 // Sub-window ,just return.
1592 LOGI("Content event callback");
1593 }),
1594 false, true, true);
1595 } else {
1596 container = AceType::MakeRefPtr<Platform::AceContainer>(instanceId_, FrontendType::DECLARATIVE_JS,
1597 runtimeContext, abilityInfo, std::make_unique<ContentEventCallback>([] {
1598 // Sub-window ,just return.
1599 LOGI("Content event callback");
1600 }),
1601 false, true);
1602 }
1603 }
1604 SubwindowManager::GetInstance()->AddContainerId(window->GetWindowId(), instanceId_);
1605 AceEngine::Get().AddContainer(instanceId_, container);
1606 touchOutsideListener_ = new TouchOutsideListener(instanceId_);
1607 window_->RegisterTouchOutsideListener(touchOutsideListener_);
1608 dragWindowListener_ = new DragWindowListener(instanceId_);
1609 window_->RegisterDragListener(dragWindowListener_);
1610 occupiedAreaChangeListener_ = new OccupiedAreaChangeListener(instanceId_);
1611 window_->RegisterOccupiedAreaChangeListener(occupiedAreaChangeListener_);
1612 }
1613
SetNextFrameLayoutCallback(std::function<void ()> && callback)1614 void UIContentImpl::SetNextFrameLayoutCallback(std::function<void()>&& callback)
1615 {
1616 CHECK_NULL_VOID(callback);
1617 auto container = Platform::AceContainer::GetContainer(instanceId_);
1618 CHECK_NULL_VOID(container);
1619 auto pipelineContext = container->GetPipelineContext();
1620 CHECK_NULL_VOID(pipelineContext);
1621 pipelineContext->SetNextFrameLayoutCallback(std::move(callback));
1622 }
1623
NotifyMemoryLevel(int32_t level)1624 void UIContentImpl::NotifyMemoryLevel(int32_t level)
1625 {
1626 LOGI("Receive Memory level notification, level: %{public}d", level);
1627 auto container = Platform::AceContainer::GetContainer(instanceId_);
1628 CHECK_NULL_VOID(container);
1629 auto pipelineContext = container->GetPipelineContext();
1630 CHECK_NULL_VOID(pipelineContext);
1631 ContainerScope scope(instanceId_);
1632 pipelineContext->NotifyMemoryLevel(level);
1633 }
1634
SetAppWindowTitle(const std::string & title)1635 void UIContentImpl::SetAppWindowTitle(const std::string& title)
1636 {
1637 auto container = Platform::AceContainer::GetContainer(instanceId_);
1638 CHECK_NULL_VOID(container);
1639 auto pipelineContext = container->GetPipelineContext();
1640 CHECK_NULL_VOID(pipelineContext);
1641 ContainerScope scope(instanceId_);
1642 LOGI("set app title");
1643 pipelineContext->SetAppTitle(title);
1644 }
1645
SetAppWindowIcon(const std::shared_ptr<Media::PixelMap> & pixelMap)1646 void UIContentImpl::SetAppWindowIcon(const std::shared_ptr<Media::PixelMap>& pixelMap)
1647 {
1648 auto container = Platform::AceContainer::GetContainer(instanceId_);
1649 CHECK_NULL_VOID(container);
1650 auto pipelineContext = container->GetPipelineContext();
1651 CHECK_NULL_VOID(pipelineContext);
1652 ContainerScope scope(instanceId_);
1653 LOGI("set app icon");
1654 pipelineContext->SetAppIcon(AceType::MakeRefPtr<PixelMapOhos>(pixelMap));
1655 }
1656
UpdateFormData(const std::string & data)1657 void UIContentImpl::UpdateFormData(const std::string& data)
1658 {
1659 if (isFormRenderInit_) {
1660 auto container = Platform::AceContainer::GetContainer(instanceId_);
1661 CHECK_NULL_VOID(container);
1662 container->UpdateFormData(data);
1663 } else {
1664 formData_ = data;
1665 }
1666 }
1667
UpdateFormSharedImage(const std::map<std::string,sptr<OHOS::AppExecFwk::FormAshmem>> & imageDataMap)1668 void UIContentImpl::UpdateFormSharedImage(const std::map<std::string, sptr<OHOS::AppExecFwk::FormAshmem>>& imageDataMap)
1669 {
1670 if (isFormRenderInit_) {
1671 auto container = Platform::AceContainer::GetContainer(instanceId_);
1672 CHECK_NULL_VOID(container);
1673 container->UpdateFormSharedImage(imageDataMap);
1674 } else {
1675 formImageDataMap_ = imageDataMap;
1676 }
1677 }
1678
SetActionEventHandler(std::function<void (const std::string & action)> && actionCallback)1679 void UIContentImpl::SetActionEventHandler(std::function<void(const std::string& action)>&& actionCallback)
1680 {
1681 CHECK_NULL_VOID(actionCallback);
1682 auto container = Platform::AceContainer::GetContainer(instanceId_);
1683 CHECK_NULL_VOID(container);
1684 auto pipelineContext = container->GetPipelineContext();
1685 CHECK_NULL_VOID(pipelineContext);
1686 pipelineContext->SetActionEventHandler(std::move(actionCallback));
1687 }
1688
SetFormLinkInfoUpdateHandler(std::function<void (const std::vector<std::string> &)> && callback)1689 void UIContentImpl::SetFormLinkInfoUpdateHandler(std::function<void(const std::vector<std::string>&)>&& callback)
1690 {
1691 CHECK_NULL_VOID(callback);
1692 auto container = Platform::AceContainer::GetContainer(instanceId_);
1693 CHECK_NULL_VOID(container);
1694 auto pipelineContext = container->GetPipelineContext();
1695 CHECK_NULL_VOID(pipelineContext);
1696 pipelineContext->SetFormLinkInfoUpdateHandler(std::move(callback));
1697 }
1698
SetErrorEventHandler(std::function<void (const std::string &,const std::string &)> && errorCallback)1699 void UIContentImpl::SetErrorEventHandler(std::function<void(const std::string&, const std::string&)>&& errorCallback)
1700 {
1701 CHECK_NULL_VOID(errorCallback);
1702 auto container = Platform::AceContainer::GetContainer(instanceId_);
1703 CHECK_NULL_VOID(container);
1704 auto front = container->GetFrontend();
1705 CHECK_NULL_VOID(front);
1706 return front->SetErrorEventHandler(std::move(errorCallback));
1707 }
1708
OnFormSurfaceChange(float width,float height)1709 void UIContentImpl::OnFormSurfaceChange(float width, float height)
1710 {
1711 auto container = Platform::AceContainer::GetContainer(instanceId_);
1712 CHECK_NULL_VOID(container);
1713 auto pipelineContext = container->GetPipelineContext();
1714 CHECK_NULL_VOID(pipelineContext);
1715 ContainerScope scope(instanceId_);
1716 auto density = pipelineContext->GetDensity();
1717 pipelineContext->SetRootSize(density, width, height);
1718 pipelineContext->OnSurfaceChanged(width, height);
1719 }
1720
GetResourcePaths(std::vector<std::string> & resourcesPaths,std::string & assetRootPath,std::vector<std::string> & assetBasePaths,std::string & resFolderName)1721 void UIContentImpl::GetResourcePaths(std::vector<std::string>& resourcesPaths, std::string& assetRootPath,
1722 std::vector<std::string>& assetBasePaths, std::string& resFolderName)
1723 {
1724 auto container = Platform::AceContainer::GetContainer(instanceId_);
1725 CHECK_NULL_VOID(container);
1726 ContainerScope scope(instanceId_);
1727 auto taskExecutor = Container::CurrentTaskExecutor();
1728 CHECK_NULL_VOID(taskExecutor);
1729 taskExecutor->PostTask(
1730 [container]() {
1731 auto pipelineContext = container->GetPipelineContext();
1732 CHECK_NULL_VOID(pipelineContext);
1733 },
1734 TaskExecutor::TaskType::PLATFORM);
1735 }
1736
SetResourcePaths(const std::vector<std::string> & resourcesPaths,const std::string & assetRootPath,const std::vector<std::string> & assetBasePaths)1737 void UIContentImpl::SetResourcePaths(const std::vector<std::string>& resourcesPaths, const std::string& assetRootPath,
1738 const std::vector<std::string>& assetBasePaths)
1739 {
1740 auto container = Platform::AceContainer::GetContainer(instanceId_);
1741 CHECK_NULL_VOID(container);
1742 ContainerScope scope(instanceId_);
1743 auto taskExecutor = Container::CurrentTaskExecutor();
1744 CHECK_NULL_VOID(taskExecutor);
1745 taskExecutor->PostTask(
1746 [container, resourcesPaths, assetRootPath, assetBasePaths]() {
1747 auto pipelineContext = container->GetPipelineContext();
1748 CHECK_NULL_VOID(pipelineContext);
1749 auto flutterAssetManager = pipelineContext->GetAssetManager();
1750 CHECK_NULL_VOID(flutterAssetManager);
1751 auto themeManager = pipelineContext->GetThemeManager();
1752 CHECK_NULL_VOID(themeManager);
1753
1754 if (resourcesPaths.empty() && assetRootPath.empty()) {
1755 LOGE("Reload old resource");
1756 return;
1757 }
1758
1759 if (!assetRootPath.empty()) {
1760 LOGD("new FileAssetProvider, assetRootPath: %{private}s", assetRootPath.c_str());
1761 auto assetProvider = AceType::MakeRefPtr<FileAssetProvider>();
1762 if (assetProvider->Initialize(assetRootPath, assetBasePaths)) {
1763 LOGD("Push file AssetProvider to queue.");
1764 flutterAssetManager->PushBack(std::move(assetProvider));
1765 }
1766 return;
1767 }
1768
1769 for (auto iter = resourcesPaths.begin(); iter != resourcesPaths.end(); iter++) {
1770 LOGD("new HapAssetProvider, iter: %{private}s", iter->c_str());
1771 auto assetProvider = AceType::MakeRefPtr<HapAssetProvider>();
1772 if (assetProvider->Initialize(*iter, assetBasePaths)) {
1773 LOGD("Push hap AssetProvider to queue.");
1774 flutterAssetManager->PushBack(std::move(assetProvider));
1775 }
1776 }
1777 },
1778 TaskExecutor::TaskType::PLATFORM);
1779 }
1780
SetIsFocusActive(bool isFocusActive)1781 void UIContentImpl::SetIsFocusActive(bool isFocusActive)
1782 {
1783 auto container = Platform::AceContainer::GetContainer(instanceId_);
1784 CHECK_NULL_VOID(container);
1785 ContainerScope scope(instanceId_);
1786 auto taskExecutor = Container::CurrentTaskExecutor();
1787 CHECK_NULL_VOID(taskExecutor);
1788 taskExecutor->PostTask(
1789 [container, isFocusActive]() {
1790 auto pipelineContext = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
1791 CHECK_NULL_VOID(pipelineContext);
1792 pipelineContext->SetIsFocusActive(isFocusActive);
1793 },
1794 TaskExecutor::TaskType::UI);
1795 }
1796
CreateModalUIExtension(const AAFwk::Want & want,const ModalUIExtensionCallbacks & callbacks)1797 int32_t UIContentImpl::CreateModalUIExtension(const AAFwk::Want& want, const ModalUIExtensionCallbacks& callbacks)
1798 {
1799 LOGI("create ui extension modal page start");
1800 auto container = Platform::AceContainer::GetContainer(instanceId_);
1801 CHECK_NULL_RETURN_NOLOG(container, 0);
1802 ContainerScope scope(instanceId_);
1803 auto taskExecutor = Container::CurrentTaskExecutor();
1804 CHECK_NULL_RETURN_NOLOG(taskExecutor, 0);
1805 int32_t sessionId = 0;
1806 taskExecutor->PostSyncTask(
1807 [container, &sessionId, want, callbacks = callbacks]() {
1808 auto pipeline = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
1809 CHECK_NULL_VOID_NOLOG(pipeline);
1810 auto overlay = pipeline->GetOverlayManager();
1811 CHECK_NULL_VOID_NOLOG(overlay);
1812 sessionId = overlay->CreateModalUIExtension(want, callbacks);
1813 },
1814 TaskExecutor::TaskType::UI);
1815 LOGI("create ui extension modal page end, sessionId=%{public}d", sessionId);
1816 return sessionId;
1817 }
1818
CloseModalUIExtension(int32_t sessionId)1819 void UIContentImpl::CloseModalUIExtension(int32_t sessionId)
1820 {
1821 LOGI("close ui extension modal page, sessionId=%{public}d", sessionId);
1822 if (sessionId == 0) {
1823 LOGW("refuse to close ui extension modal page");
1824 return;
1825 }
1826 auto container = Platform::AceContainer::GetContainer(instanceId_);
1827 CHECK_NULL_VOID_NOLOG(container);
1828 ContainerScope scope(instanceId_);
1829 auto taskExecutor = Container::CurrentTaskExecutor();
1830 CHECK_NULL_VOID_NOLOG(taskExecutor);
1831 taskExecutor->PostTask(
1832 [container, sessionId]() {
1833 auto pipeline = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
1834 CHECK_NULL_VOID_NOLOG(pipeline);
1835 auto overlay = pipeline->GetOverlayManager();
1836 CHECK_NULL_VOID_NOLOG(overlay);
1837 overlay->CloseModalUIExtension(sessionId);
1838 },
1839 TaskExecutor::TaskType::UI);
1840 }
1841 } // namespace OHOS::Ace
1842