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