• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "adapter/ohos/entrance/ui_content_impl.h"
17 
18 #include <atomic>
19 #include <cinttypes>
20 #include <regex>
21 
22 #include "ability_context.h"
23 #include "ability_info.h"
24 #include "configuration.h"
25 #include "dm/display_manager.h"
26 #include "init_data.h"
27 #include "js_runtime_utils.h"
28 #include "native_reference.h"
29 #include "service_extension_context.h"
30 
31 #ifdef ENABLE_ROSEN_BACKEND
32 #include "render_service_client/core/ui/rs_ui_director.h"
33 #endif
34 
35 #include "adapter/ohos/entrance/ace_application_info.h"
36 #include "adapter/ohos/entrance/ace_container.h"
37 #include "adapter/ohos/entrance/capability_registry.h"
38 #include "adapter/ohos/entrance/file_asset_provider.h"
39 #include "adapter/ohos/entrance/flutter_ace_view.h"
40 #include "adapter/ohos/entrance/plugin_utils_impl.h"
41 #include "base/geometry/rect.h"
42 #include "base/log/log.h"
43 #include "base/subwindow/subwindow_manager.h"
44 #include "base/utils/string_utils.h"
45 #include "base/utils/system_properties.h"
46 #include "core/common/ace_engine.h"
47 #include "core/common/container_scope.h"
48 #include "core/common/flutter/flutter_asset_manager.h"
49 #include "core/common/plugin_manager.h"
50 
51 namespace OHOS::Ace {
52 namespace {
53 
54 const std::string ABS_BUNDLE_CODE_PATH = "/data/app/el1/bundle/public/";
55 const std::string LOCAL_BUNDLE_CODE_PATH = "/data/storage/el1/bundle/";
56 const std::string FILE_SEPARATOR = "/";
57 
GetWindowMode(OHOS::Rosen::Window * window)58 WindowMode GetWindowMode(OHOS::Rosen::Window* window)
59 {
60     if (!window) {
61         LOGE("Get window mode failed, window is null!");
62         return WindowMode::WINDOW_MODE_UNDEFINED;
63     }
64     switch (window->GetMode()) {
65         case OHOS::Rosen::WindowMode::WINDOW_MODE_FULLSCREEN:
66             return WindowMode::WINDOW_MODE_FULLSCREEN;
67         case OHOS::Rosen::WindowMode::WINDOW_MODE_SPLIT_PRIMARY:
68             return WindowMode::WINDOW_MODE_SPLIT_PRIMARY;
69         case OHOS::Rosen::WindowMode::WINDOW_MODE_SPLIT_SECONDARY:
70             return WindowMode::WINDOW_MODE_SPLIT_SECONDARY;
71         case OHOS::Rosen::WindowMode::WINDOW_MODE_FLOATING:
72             return WindowMode::WINDOW_MODE_FLOATING;
73         case OHOS::Rosen::WindowMode::WINDOW_MODE_PIP:
74             return WindowMode::WINDOW_MODE_PIP;
75         default:
76             return WindowMode::WINDOW_MODE_UNDEFINED;
77     }
78 }
79 
80 } // namespace
81 
82 static std::atomic<int32_t> gInstanceId = 0;
83 static std::atomic<int32_t> gSubWindowInstanceId = 100000;
84 static std::atomic<int32_t> gSubInstanceId = 1000000;
85 const std::string SUBWINDOW_PREFIX = "ARK_APP_SUBWINDOW_";
86 
87 using ContentFinishCallback = std::function<void()>;
88 class ContentEventCallback final : public Platform::PlatformEventCallback {
89 public:
ContentEventCallback(ContentFinishCallback onFinish)90     explicit ContentEventCallback(ContentFinishCallback onFinish) : onFinish_(onFinish) {}
91     ~ContentEventCallback() = default;
92 
OnFinish() const93     virtual void OnFinish() const
94     {
95         LOGI("UIContent OnFinish");
96         if (onFinish_) {
97             onFinish_();
98         }
99     }
100 
OnStatusBarBgColorChanged(uint32_t color)101     virtual void OnStatusBarBgColorChanged(uint32_t color)
102     {
103         LOGI("UIContent OnStatusBarBgColorChanged");
104     }
105 
106 private:
107     ContentFinishCallback onFinish_;
108 };
109 
OHOS_ACE_CreateUIContent(void * context,void * runtime)110 extern "C" ACE_EXPORT void* OHOS_ACE_CreateUIContent(void* context, void* runtime)
111 {
112     LOGI("Ace lib loaded, CreateUIContent.");
113     return new UIContentImpl(reinterpret_cast<OHOS::AbilityRuntime::Context*>(context), runtime);
114 }
115 
OHOS_ACE_CreateSubWindowUIContent(void * ability)116 extern "C" ACE_EXPORT void* OHOS_ACE_CreateSubWindowUIContent(void* ability)
117 {
118     LOGI("Ace lib loaded, Create SubWindowUIContent.");
119     return new UIContentImpl(reinterpret_cast<OHOS::AppExecFwk::Ability*>(ability));
120 }
121 
122 class OccupiedAreaChangeListener : public OHOS::Rosen::IOccupiedAreaChangeListener {
123 public:
OccupiedAreaChangeListener(int32_t instanceId)124     explicit OccupiedAreaChangeListener(int32_t instanceId) : instanceId_(instanceId) {}
125     ~OccupiedAreaChangeListener() = default;
126 
OnSizeChange(const sptr<OHOS::Rosen::OccupiedAreaChangeInfo> & info)127     void OnSizeChange(const sptr<OHOS::Rosen::OccupiedAreaChangeInfo>& info)
128     {
129         auto rect = info->rect_;
130         auto type = info->type_;
131         Rect keyboardRect = Rect(rect.posX_, rect.posY_, rect.width_, rect.height_);
132         LOGI("UIContent::OccupiedAreaChange rect:%{public}s type: %{public}d", keyboardRect.ToString().c_str(), type);
133         if (type == OHOS::Rosen::OccupiedAreaType::TYPE_INPUT) {
134             auto container = Platform::AceContainer::GetContainer(instanceId_);
135             if (!container) {
136                 LOGE("container may be destroyed.");
137                 return;
138             }
139             auto taskExecutor = container->GetTaskExecutor();
140             if (!taskExecutor) {
141                 LOGE("OnSizeChange: taskExecutor is null.");
142                 return;
143             }
144 
145             ContainerScope scope(instanceId_);
146             taskExecutor->PostTask([container, keyboardRect] {
147                 auto context = container->GetPipelineContext();
148                 if (context != nullptr) {
149                     context->OnVirtualKeyboardAreaChange(keyboardRect);
150                 }
151             }, TaskExecutor::TaskType::UI);
152         }
153     }
154 
155 private:
156     int32_t instanceId_ = -1;
157 };
158 
159 class DragWindowListener : public OHOS::Rosen::IWindowDragListener {
160 public:
DragWindowListener(int32_t instanceId)161     explicit DragWindowListener(int32_t instanceId) : instanceId_(instanceId) {}
162     ~DragWindowListener() = default;
OnDrag(int32_t x,int32_t y,OHOS::Rosen::DragEvent event)163     void OnDrag(int32_t x, int32_t y, OHOS::Rosen::DragEvent event)
164     {
165         LOGI("DragWindowListener::OnDrag called.");
166         auto flutterAceView =
167             static_cast<Platform::FlutterAceView*>(Platform::AceContainer::GetContainer(instanceId_)->GetView());
168         if (!flutterAceView) {
169             LOGE("DragWindowListener::OnDrag flutterAceView is null");
170             return;
171         }
172 
173         DragEventAction action;
174         switch (event) {
175             case OHOS::Rosen::DragEvent::DRAG_EVENT_END:
176                 action = DragEventAction::DRAG_EVENT_END;
177                 break;
178             case OHOS::Rosen::DragEvent::DRAG_EVENT_MOVE:
179             case OHOS::Rosen::DragEvent::DRAG_EVENT_OUT:
180                 action = DragEventAction::DRAG_EVENT_MOVE;
181                 break;
182             case OHOS::Rosen::DragEvent::DRAG_EVENT_IN:
183             default:
184                 action = DragEventAction::DRAG_EVENT_START;
185                 break;
186         }
187 
188         flutterAceView->ProcessDragEvent(x, y, action);
189     }
190 
191 private:
192     int32_t instanceId_ = -1;
193 };
194 
UIContentImpl(OHOS::AbilityRuntime::Context * context,void * runtime)195 UIContentImpl::UIContentImpl(OHOS::AbilityRuntime::Context* context, void* runtime) : runtime_(runtime)
196 {
197     if (context == nullptr) {
198         LOGE("context is nullptr");
199         return;
200     }
201     const auto& obj = context->GetBindingObject();
202     auto ref = obj->Get<NativeReference>();
203     auto object = AbilityRuntime::ConvertNativeValueTo<NativeObject>(ref->Get());
204     auto weak = static_cast<std::weak_ptr<AbilityRuntime::Context>*>(object->GetNativePointer());
205     context_ = *weak;
206     LOGI("Create UIContentImpl successfully.");
207 }
208 
UIContentImpl(OHOS::AppExecFwk::Ability * ability)209 UIContentImpl::UIContentImpl(OHOS::AppExecFwk::Ability* ability)
210 {
211     if (ability == nullptr) {
212         LOGE("ability is nullptr");
213         return;
214     }
215     auto weak = static_cast<std::weak_ptr<AbilityRuntime::Context>>(ability->GetAbilityContext());
216     context_ = weak;
217     LOGI("Create UIContentImpl successfully.");
218 }
219 
Initialize(OHOS::Rosen::Window * window,const std::string & url,NativeValue * storage)220 void UIContentImpl::Initialize(OHOS::Rosen::Window* window, const std::string& url, NativeValue* storage)
221 {
222     CommonInitialize(window, url, storage);
223     LOGI("Initialize startUrl = %{public}s", startUrl_.c_str());
224     // run page.
225     Platform::AceContainer::RunPage(
226         instanceId_, Platform::AceContainer::GetContainer(instanceId_)->GeneratePageId(), startUrl_, "");
227     LOGI("Initialize UIContentImpl done.");
228 }
229 
Restore(OHOS::Rosen::Window * window,const std::string & contentInfo,NativeValue * storage)230 void UIContentImpl::Restore(OHOS::Rosen::Window* window, const std::string& contentInfo, NativeValue* storage)
231 {
232     CommonInitialize(window, contentInfo, storage);
233     startUrl_ = Platform::AceContainer::RestoreRouterStack(instanceId_, contentInfo);
234     if (startUrl_.empty()) {
235         LOGW("UIContent Restore start url is empty");
236     }
237     LOGI("Restore startUrl = %{public}s", startUrl_.c_str());
238     Platform::AceContainer::RunPage(
239         instanceId_, Platform::AceContainer::GetContainer(instanceId_)->GeneratePageId(), startUrl_, "");
240     LOGI("Restore UIContentImpl done.");
241 }
242 
GetContentInfo() const243 std::string UIContentImpl::GetContentInfo() const
244 {
245     LOGI("UIContent GetContentInfo");
246     return Platform::AceContainer::GetContentInfo(instanceId_);
247 }
248 
CommonInitialize(OHOS::Rosen::Window * window,const std::string & contentInfo,NativeValue * storage)249 void UIContentImpl::CommonInitialize(OHOS::Rosen::Window* window, const std::string& contentInfo, NativeValue* storage)
250 {
251     window_ = window;
252     startUrl_ = contentInfo;
253     if (!window_) {
254         LOGE("Null window, can't initialize UI content");
255         return;
256     }
257     if (StringUtils::StartWith(window->GetWindowName(), SUBWINDOW_PREFIX)) {
258         InitializeSubWindow(window_);
259         return;
260     }
261     auto context = context_.lock();
262     if (!context) {
263         LOGE("context is null");
264         return;
265     }
266     LOGI("Initialize UIContentImpl start.");
267     static std::once_flag onceFlag;
268     std::call_once(onceFlag, [&context]() {
269         LOGI("Initialize for current process.");
270         SetHwIcuDirectory();
271         Container::UpdateCurrent(INSTANCE_ID_PLATFORM);
272         AceApplicationInfo::GetInstance().SetProcessName(context->GetBundleName());
273         AceApplicationInfo::GetInstance().SetDataFileDirPath(context->GetFilesDir());
274         CapabilityRegistry::Register();
275         ImageCache::SetImageCacheFilePath(context->GetCacheDir());
276         ImageCache::SetCacheFileInfo();
277     });
278 
279     int32_t deviceWidth = 0;
280     int32_t deviceHeight = 0;
281     float density = 1.0f;
282     auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
283     if (defaultDisplay) {
284         density = defaultDisplay->GetVirtualPixelRatio();
285         deviceWidth = defaultDisplay->GetWidth();
286         deviceHeight = defaultDisplay->GetHeight();
287         LOGI("UIContent: deviceWidth: %{public}d, deviceHeight: %{public}d, default density: %{public}f", deviceWidth,
288             deviceHeight, density);
289     }
290     SystemProperties::InitDeviceInfo(deviceWidth, deviceHeight, deviceHeight >= deviceWidth ? 0 : 1, density, false);
291     SystemProperties::SetColorMode(ColorMode::LIGHT);
292 
293     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
294     auto resourceManager = context->GetResourceManager();
295     if (resourceManager != nullptr) {
296         resourceManager->GetResConfig(*resConfig);
297         auto localeInfo = resConfig->GetLocaleInfo();
298         Platform::AceApplicationInfoImpl::GetInstance().SetResourceManager(resourceManager);
299         if (localeInfo != nullptr) {
300             auto language = localeInfo->getLanguage();
301             auto region = localeInfo->getCountry();
302             auto script = localeInfo->getScript();
303             AceApplicationInfo::GetInstance().SetLocale((language == nullptr) ? "" : language,
304                 (region == nullptr) ? "" : region, (script == nullptr) ? "" : script, "");
305         }
306     }
307 
308     auto abilityContext = OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(context);
309     std::shared_ptr<OHOS::AppExecFwk::AbilityInfo> info;
310 
311     if (abilityContext) {
312         info = abilityContext->GetAbilityInfo();
313     } else {
314         auto extensionContext =
315             OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::ExtensionContext>(context);
316         if (!extensionContext) {
317             LOGE("context is not AbilityContext or ExtensionContext.");
318             return;
319         }
320         info = extensionContext->GetAbilityInfo();
321     }
322 
323     RefPtr<FlutterAssetManager> flutterAssetManager = Referenced::MakeRefPtr<FlutterAssetManager>();
324     bool isModelJson = info != nullptr ? info->isModuleJson : false;
325     std::string moduleName = info != nullptr ? info->moduleName : "";
326     auto appInfo = context->GetApplicationInfo();
327     auto bundleName = info != nullptr ? info->bundleName : "";
328     std::string resPath;
329     std::string pageProfile;
330     LOGI("Initialize UIContent isModelJson:%{public}s", isModelJson ? "true" : "false");
331     if (isModelJson) {
332         if (appInfo) {
333             std::vector<OHOS::AppExecFwk::ModuleInfo> moduleList = appInfo->moduleInfos;
334             for (const auto& module : moduleList) {
335                 if (module.moduleName == moduleName) {
336                     std::regex pattern(ABS_BUNDLE_CODE_PATH + bundleName + FILE_SEPARATOR);
337                     auto moduleSourceDir = std::regex_replace(module.moduleSourceDir, pattern, LOCAL_BUNDLE_CODE_PATH);
338                     resPath = moduleSourceDir + "/";
339                     break;
340                 }
341             }
342         }
343         LOGI("In stage mode, resPath:%{private}s", resPath.c_str());
344         auto assetBasePathStr = { std::string("ets/"), std::string("resources/base/profile/") };
345         if (flutterAssetManager && !resPath.empty()) {
346             auto assetProvider = AceType::MakeRefPtr<FileAssetProvider>();
347             if (assetProvider->Initialize(resPath, assetBasePathStr)) {
348                 LOGI("Push AssetProvider to queue.");
349                 flutterAssetManager->PushBack(std::move(assetProvider));
350             }
351         }
352         auto hapInfo = context->GetHapModuleInfo();
353         if (hapInfo) {
354             pageProfile = hapInfo->pages;
355             const std::string profilePrefix = "@profile:";
356             if (pageProfile.compare(0, profilePrefix.size(), profilePrefix) == 0) {
357                 pageProfile = pageProfile.substr(profilePrefix.length()).append(".json");
358             }
359             LOGI("In stage mode, pageProfile:%{public}s", pageProfile.c_str());
360         } else {
361             LOGE("In stage mode, can't get hap info.");
362         }
363     } else {
364         auto packagePathStr = context->GetBundleCodeDir();
365         auto moduleInfo = context->GetHapModuleInfo();
366         if (moduleInfo != nullptr) {
367             packagePathStr += "/" + moduleInfo->package + "/";
368         }
369         std::string srcPath = "";
370         if (info != nullptr && !info->srcPath.empty()) {
371             srcPath = info->srcPath;
372         }
373 
374         auto assetBasePathStr = { "assets/js/" + (srcPath.empty() ? "default" : srcPath) + "/",
375             std::string("assets/js/share/") };
376 
377         if (flutterAssetManager && !packagePathStr.empty()) {
378             auto assetProvider = AceType::MakeRefPtr<FileAssetProvider>();
379             if (assetProvider->Initialize(packagePathStr, assetBasePathStr)) {
380                 LOGI("Push AssetProvider to queue.");
381                 flutterAssetManager->PushBack(std::move(assetProvider));
382             }
383         }
384 
385         if (appInfo) {
386             std::vector<OHOS::AppExecFwk::ModuleInfo> moduleList = appInfo->moduleInfos;
387             for (const auto& module : moduleList) {
388                 if (module.moduleName == moduleName) {
389                     std::regex pattern(ABS_BUNDLE_CODE_PATH + bundleName + FILE_SEPARATOR);
390                     auto moduleSourceDir = std::regex_replace(module.moduleSourceDir, pattern, LOCAL_BUNDLE_CODE_PATH);
391                     resPath = moduleSourceDir + "/assets/" + module.moduleName + "/";
392                     break;
393                 }
394             }
395         }
396     }
397     if (appInfo && flutterAssetManager) {
398         std::string nativeLibraryPath = appInfo->nativeLibraryPath;
399         if (!nativeLibraryPath.empty()) {
400             if (nativeLibraryPath.back() == '/') {
401                 nativeLibraryPath.pop_back();
402             }
403             std::string libPath = context->GetBundleCodeDir();
404             libPath += (libPath.back() == '/') ? nativeLibraryPath : "/" + nativeLibraryPath;
405             LOGI("napi lib path = %{private}s", libPath.c_str());
406             flutterAssetManager->SetLibPath(libPath);
407         }
408     }
409 
410     auto pluginUtils = std::make_shared<PluginUtilsImpl>();
411     PluginManager::GetInstance().SetAceAbility(nullptr, pluginUtils);
412     // create container
413     if (runtime_) {
414         instanceId_ = gInstanceId.fetch_add(1, std::memory_order_relaxed);
415     } else {
416         instanceId_ = gSubWindowInstanceId.fetch_add(1, std::memory_order_relaxed);
417     }
418     auto container = AceType::MakeRefPtr<Platform::AceContainer>(instanceId_, FrontendType::DECLARATIVE_JS, true,
419         context_, info, std::make_unique<ContentEventCallback>([context = context_] {
420             auto sharedContext = context.lock();
421             if (!sharedContext) {
422                 return;
423             }
424             auto abilityContext =
425                 OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(sharedContext);
426             if (abilityContext) {
427                 abilityContext->CloseAbility();
428             }
429         }));
430     container->SetWindowName(window_->GetWindowName());
431 
432     // Mark the relationship between windowId and containerId, it is 1:1
433     SubwindowManager::GetInstance()->AddContainerId(window->GetWindowId(), instanceId_);
434     AceEngine::Get().AddContainer(instanceId_, container);
435     if (runtime_) {
436         container->GetSettings().SetUsingSharedRuntime(true);
437         container->SetSharedRuntime(runtime_);
438     } else {
439         container->GetSettings().SetUsingSharedRuntime(false);
440     }
441     container->SetPageProfile(pageProfile);
442     container->Initialize();
443     ContainerScope scope(instanceId_);
444     auto front = container->GetFrontend();
445     if (front) {
446         front->UpdateState(Frontend::State::ON_CREATE);
447         front->SetJsMessageDispatcher(container);
448     }
449     auto aceResCfg = container->GetResourceConfiguration();
450     aceResCfg.SetOrientation(SystemProperties::GetDevcieOrientation());
451     aceResCfg.SetDensity(SystemProperties::GetResolution());
452     aceResCfg.SetDeviceType(SystemProperties::GetDeviceType());
453     container->SetResourceConfiguration(aceResCfg);
454     container->SetPackagePathStr(resPath);
455     container->SetAssetManager(flutterAssetManager);
456     container->SetBundlePath(context->GetBundleCodeDir());
457     container->SetFilesDataPath(context->GetFilesDir());
458 
459     if (window_->IsDecorEnable()) {
460         LOGI("Container modal is enabled.");
461         container->SetWindowModal(WindowModal::CONTAINER_MODAL);
462     }
463 
464     // create ace_view
465     auto flutterAceView =
466         Platform::FlutterAceView::CreateView(instanceId_, false, container->GetSettings().usePlatformAsUIThread);
467     Platform::FlutterAceView::SurfaceCreated(flutterAceView, window_);
468 
469     Ace::Platform::UIEnvCallback callback = nullptr;
470 #ifdef ENABLE_ROSEN_BACKEND
471     callback = [window, id = instanceId_, container](const OHOS::Ace::RefPtr<OHOS::Ace::PipelineContext>& context) {
472         if (SystemProperties::GetRosenBackendEnabled()) {
473             auto rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
474             if (rsUiDirector != nullptr) {
475                 rsUiDirector->SetRSSurfaceNode(window->GetSurfaceNode());
476                 rsUiDirector->SetUITaskRunner(
477                     [taskExecutor = container->GetTaskExecutor(), id](const std::function<void()>& task) {
478                         ContainerScope scope(id);
479                         taskExecutor->PostTask(task, TaskExecutor::TaskType::UI);
480                     });
481                 auto context = container->GetPipelineContext();
482                 if (context != nullptr) {
483                     context->SetRSUIDirector(rsUiDirector);
484                 }
485                 rsUiDirector->Init();
486                 LOGI("UIContent Init Rosen Backend");
487             }
488         }
489     };
490 #endif
491     // set view
492     Platform::AceContainer::SetView(flutterAceView, density, 0, 0, window_->GetWindowId(), callback);
493     Platform::FlutterAceView::SurfaceChanged(flutterAceView, 0, 0, config_.Orientation());
494     if (isModelJson) {
495         auto pipeline = container->GetPipelineContext();
496         if (pipeline && appInfo) {
497             LOGI("SetMinPlatformVersion code is %{public}d", appInfo->minCompatibleVersionCode);
498             pipeline->SetMinPlatformVersion(appInfo->minCompatibleVersionCode);
499         }
500     }
501     if (runtime_) {
502         auto nativeEngine = reinterpret_cast<NativeEngine*>(runtime_);
503         if (!storage) {
504             container->SetContentStorage(nullptr, context->GetBindingObject()->Get<NativeReference>());
505         } else {
506             LOGI("SetContentStorage %{public}d", storage->TypeOf());
507             container->SetContentStorage(
508                 nativeEngine->CreateReference(storage, 1), context->GetBindingObject()->Get<NativeReference>());
509         }
510     }
511     InitWindowCallback(info);
512 }
513 
Foreground()514 void UIContentImpl::Foreground()
515 {
516     LOGI("Show UIContent");
517     Platform::AceContainer::OnShow(instanceId_);
518 }
519 
Background()520 void UIContentImpl::Background()
521 {
522     LOGI("Hide UIContent");
523     Platform::AceContainer::OnHide(instanceId_);
524 }
525 
Focus()526 void UIContentImpl::Focus()
527 {
528     LOGI("Active UIContent");
529     Platform::AceContainer::OnActive(instanceId_);
530 }
531 
UnFocus()532 void UIContentImpl::UnFocus()
533 {
534     LOGI("Inactive UIContent");
535     Platform::AceContainer::OnInactive(instanceId_);
536 }
537 
Destroy()538 void UIContentImpl::Destroy()
539 {
540     LOGI("Destroy UIContent");
541     Platform::AceContainer::DestroyContainer(instanceId_);
542 }
543 
GetBackgroundColor()544 uint32_t UIContentImpl::GetBackgroundColor()
545 {
546     auto container = Platform::AceContainer::GetContainer(instanceId_);
547     if (!container) {
548         LOGE("GetBackgroundColor failed: container is null. return 0x000000");
549         return 0x000000;
550     }
551     auto taskExecutor = container->GetTaskExecutor();
552     if (!taskExecutor) {
553         LOGE("GetBackgroundColor failed: taskExecutor is null.");
554         return 0x000000;
555     }
556     ContainerScope scope(instanceId_);
557     uint32_t bgColor = 0x000000;
558     taskExecutor->PostSyncTask([&bgColor, container]() {
559             if (!container) {
560                 LOGE("Post sync task GetBackgroundColor failed: container is null. return 0x000000");
561                 return;
562             }
563             auto pipelineContext = container->GetPipelineContext();
564             if (!pipelineContext) {
565                 LOGE("Post sync task GetBackgroundColor failed: pipeline is null. return 0x000000");
566                 return;
567             }
568             bgColor = pipelineContext->GetAppBgColor().GetValue();
569         }, TaskExecutor::TaskType::UI);
570 
571     LOGI("UIContentImpl::GetBackgroundColor, value is %{public}u", bgColor);
572     return bgColor;
573 }
574 
SetBackgroundColor(uint32_t color)575 void UIContentImpl::SetBackgroundColor(uint32_t color)
576 {
577     LOGI("UIContentImpl::SetBackgroundColor color is %{public}u", color);
578     auto container = Platform::AceContainer::GetContainer(instanceId_);
579     if (!container) {
580         LOGE("SetBackgroundColor failed: container is null.");
581         return;
582     }
583     ContainerScope scope(instanceId_);
584     auto taskExecutor = container->GetTaskExecutor();
585     if (!taskExecutor) {
586         LOGE("SetBackgroundColor failed: taskExecutor is null.");
587         return;
588     }
589     taskExecutor->PostSyncTask([container, bgColor = color]() {
590         auto pipelineContext = container->GetPipelineContext();
591         if (!pipelineContext) {
592             LOGE("SetBackgroundColor failed, pipeline context is null.");
593             return;
594         }
595         pipelineContext->SetAppBgColor(Color(bgColor));
596     }, TaskExecutor::TaskType::UI);
597 }
598 
ProcessBackPressed()599 bool UIContentImpl::ProcessBackPressed()
600 {
601     LOGI("UIContent ProcessBackPressed");
602     return Platform::AceContainer::OnBackPressed(instanceId_);
603 }
604 
ProcessPointerEvent(const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)605 bool UIContentImpl::ProcessPointerEvent(const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
606 {
607     LOGI("UIContent ProcessPointerEvent");
608     auto container = Platform::AceContainer::GetContainer(instanceId_);
609     if (container) {
610         auto aceView = static_cast<Platform::FlutterAceView*>(container->GetAceView());
611         Platform::FlutterAceView::DispatchTouchEvent(aceView, pointerEvent);
612         return true;
613     }
614     return false;
615 }
616 
ProcessKeyEvent(const std::shared_ptr<OHOS::MMI::KeyEvent> & touchEvent)617 bool UIContentImpl::ProcessKeyEvent(const std::shared_ptr<OHOS::MMI::KeyEvent>& touchEvent)
618 {
619     LOGI("AceAbility::OnKeyUp called,touchEvent info: keyCode is %{private}d,"
620          "keyAction is %{public}d, keyActionTime is %{public}" PRId64,
621         touchEvent->GetKeyCode(), touchEvent->GetKeyAction(), touchEvent->GetActionTime());
622     auto container = Platform::AceContainer::GetContainer(instanceId_);
623     if (container) {
624         auto aceView = static_cast<Platform::FlutterAceView*>(container->GetAceView());
625         return Platform::FlutterAceView::DispatchKeyEvent(aceView, touchEvent);
626     }
627     return false;
628 }
629 
ProcessAxisEvent(const std::shared_ptr<OHOS::MMI::AxisEvent> & axisEvent)630 bool UIContentImpl::ProcessAxisEvent(const std::shared_ptr<OHOS::MMI::AxisEvent>& axisEvent)
631 {
632     LOGI("UIContent ProcessAxisEvent");
633     return false;
634 }
635 
ProcessVsyncEvent(uint64_t timeStampNanos)636 bool UIContentImpl::ProcessVsyncEvent(uint64_t timeStampNanos)
637 {
638     LOGI("UIContent ProcessVsyncEvent");
639     return false;
640 }
641 
UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration> & config)642 void UIContentImpl::UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config)
643 {
644     if (!config) {
645         LOGE("UIContent null config");
646         return;
647     }
648     LOGI("UIContent UpdateConfiguration %{public}s", config->GetName().c_str());
649 }
650 
UpdateViewportConfig(const ViewportConfig & config,OHOS::Rosen::WindowSizeChangeReason reason)651 void UIContentImpl::UpdateViewportConfig(const ViewportConfig& config, OHOS::Rosen::WindowSizeChangeReason reason)
652 {
653     LOGI("UIContent UpdateViewportConfig %{public}s", config.ToString().c_str());
654     SystemProperties::SetResolution(config.Density());
655     SystemProperties::SetDeviceOrientation(config.Height() >= config.Width() ? 0 : 1);
656     SystemProperties::SetWindowPos(config.Left(), config.Top());
657     auto container = Platform::AceContainer::GetContainer(instanceId_);
658     if (!container) {
659         LOGE("UpdateViewportConfig: container is null.");
660         return;
661     }
662     auto taskExecutor = container->GetTaskExecutor();
663     if (!taskExecutor) {
664         LOGE("UpdateViewportConfig: taskExecutor is null.");
665         return;
666     }
667     taskExecutor->PostTask([config, container, reason]() {
668             auto aceView = static_cast<Platform::FlutterAceView*>(container->GetAceView());
669             if (!aceView) {
670                 LOGE("UpdateViewportConfig: aceView is null.");
671                 return;
672             }
673             flutter::ViewportMetrics metrics;
674             metrics.physical_width = config.Width();
675             metrics.physical_height = config.Height();
676             metrics.device_pixel_ratio = config.Density();
677             Platform::FlutterAceView::SetViewportMetrics(aceView, metrics);
678             Platform::FlutterAceView::SurfaceChanged(aceView, config.Width(), config.Height(), config.Orientation(),
679                 static_cast<WindowSizeChangeReason>(reason));
680         }, TaskExecutor::TaskType::PLATFORM);
681     config_ = config;
682     updateConfig_ = true;
683 }
684 
UpdateWindowMode(OHOS::Rosen::WindowMode mode)685 void UIContentImpl::UpdateWindowMode(OHOS::Rosen::WindowMode mode)
686 {
687     LOGI("UpdateWindowMode, window mode is %{public}d", mode);
688     auto container = Platform::AceContainer::GetContainer(instanceId_);
689     if (!container) {
690         LOGE("UpdateWindowMode failed, get container(id=%{public}d) failed", instanceId_);
691         return;
692     }
693     auto pipelineContext = container->GetPipelineContext();
694     if (!pipelineContext) {
695         LOGE("UpdateWindowMode failed, pipeline context is null.");
696         return;
697     }
698     if (mode == OHOS::Rosen::WindowMode::WINDOW_MODE_FULLSCREEN ||
699         mode == OHOS::Rosen::WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
700         mode == OHOS::Rosen::WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
701         pipelineContext->ShowContainerTitle(false);
702     } else {
703         pipelineContext->ShowContainerTitle(true);
704     }
705 }
706 
DumpInfo(const std::vector<std::string> & params,std::vector<std::string> & info)707 void UIContentImpl::DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info)
708 {
709     auto container = Platform::AceContainer::GetContainer(instanceId_);
710     if (!container) {
711         LOGE("get container(id=%{public}d) failed", instanceId_);
712         return;
713     }
714     auto pipelineContext = container->GetPipelineContext();
715     if (!pipelineContext) {
716         LOGE("get pipeline context failed");
717         return;
718     }
719     pipelineContext->DumpInfo(params, info);
720 }
721 
InitWindowCallback(const std::shared_ptr<OHOS::AppExecFwk::AbilityInfo> & info)722 void UIContentImpl::InitWindowCallback(const std::shared_ptr<OHOS::AppExecFwk::AbilityInfo>& info)
723 {
724     LOGE("UIContent InitWindowCallback");
725     auto container = Platform::AceContainer::GetContainer(instanceId_);
726     if (!container) {
727         LOGE("get container(id=%{public}d) failed", instanceId_);
728         return;
729     }
730     auto pipelineContext = container->GetPipelineContext();
731     if (!pipelineContext) {
732         LOGE("get pipeline context failed");
733         return;
734     }
735     if (info != nullptr) {
736         pipelineContext->SetAppLabelId(info->labelId);
737         pipelineContext->SetAppIconId(info->iconId);
738     }
739 
740     auto& window = window_;
741     pipelineContext->SetWindowMinimizeCallBack([&window]() -> bool {
742         if (!window) {
743             return false;
744         }
745         return (OHOS::Rosen::WMError::WM_OK == window->Minimize());
746     });
747 
748     pipelineContext->SetWindowMaximizeCallBack([&window]() -> bool {
749         if (!window) {
750             return false;
751         }
752         return (OHOS::Rosen::WMError::WM_OK == window->Maximize());
753     });
754 
755     pipelineContext->SetWindowRecoverCallBack([&window]() -> bool {
756         if (!window) {
757             return false;
758         }
759         return (OHOS::Rosen::WMError::WM_OK == window->Recover());
760     });
761 
762     pipelineContext->SetWindowCloseCallBack([&window]() -> bool {
763         if (!window) {
764             return false;
765         }
766         return (OHOS::Rosen::WMError::WM_OK == window->Close());
767     });
768 
769     pipelineContext->SetWindowStartMoveCallBack([&window]() {
770         if (!window) {
771             return;
772         }
773         window->StartMove();
774     });
775 
776     pipelineContext->SetWindowSplitCallBack([&window]() -> bool {
777         if (!window) {
778             return false;
779         }
780         return (
781             OHOS::Rosen::WMError::WM_OK == window->SetWindowMode(OHOS::Rosen::WindowMode::WINDOW_MODE_SPLIT_PRIMARY));
782     });
783 
784     pipelineContext->SetWindowGetModeCallBack([&window]() -> WindowMode { return GetWindowMode(window); });
785 
786     pipelineContext->SetGetWindowRectImpl([&window]() -> Rect {
787         Rect rect;
788         if (!window) {
789             return rect;
790         }
791         auto windowRect = window->GetRect();
792         rect.SetRect(windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_);
793         return rect;
794     });
795 
796     dragWindowListener_ = new DragWindowListener(instanceId_);
797     window->RegisterDragListener(dragWindowListener_);
798     occupiedAreaChangeListener_ = new OccupiedAreaChangeListener(instanceId_);
799     window->RegisterOccupiedAreaChangeListener(occupiedAreaChangeListener_);
800 }
801 
InitializeSubWindow(OHOS::Rosen::Window * window)802 void UIContentImpl::InitializeSubWindow(OHOS::Rosen::Window* window)
803 {
804     window_ = window;
805     LOGI("The window name is %{public}s", window->GetWindowName().c_str());
806     if (!window_) {
807         LOGE("Null window, can't initialize UI content");
808         return;
809     }
810 
811     RefPtr<Platform::AceContainer> container;
812     instanceId_ = gSubInstanceId.fetch_add(1, std::memory_order_relaxed);
813 
814     std::weak_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo;
815     std::weak_ptr<OHOS::AbilityRuntime::Context> runtimeContext;
816     container = AceType::MakeRefPtr<Platform::AceContainer>(instanceId_, FrontendType::DECLARATIVE_JS, true,
817         runtimeContext, abilityInfo, std::make_unique<ContentEventCallback>([] {
818             // Subwindow ,just return.
819             LOGI("Content event callback");
820         }),
821         false, true);
822     SubwindowManager::GetInstance()->AddContainerId(window->GetWindowId(), instanceId_);
823     AceEngine::Get().AddContainer(instanceId_, container);
824 }
825 
826 } // namespace OHOS::Ace
827