• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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/subwindow/subwindow_ohos.h"
17 
18 #include "dm/display_manager.h"
19 #include "interfaces/innerkits/ace/viewport_config.h"
20 #include "render_service_client/core/ui/rs_ui_director.h"
21 
22 #include "adapter/ohos/entrance/ace_application_info.h"
23 #include "adapter/ohos/entrance/ace_container.h"
24 #include "adapter/ohos/entrance/flutter_ace_view.h"
25 #include "adapter/ohos/entrance/utils.h"
26 #include "base/utils/system_properties.h"
27 #include "core/common/container_scope.h"
28 #include "core/common/frontend.h"
29 #include "core/components/popup/popup_component.h"
30 
31 namespace OHOS::Ace {
32 
33 int32_t SubwindowOhos::id_ = 0;
34 
CreateSubwindow(int32_t instanceId)35 RefPtr<Subwindow> Subwindow::CreateSubwindow(int32_t instanceId)
36 {
37     LOGI("Create Subwindow, parent container id is %{public}d", instanceId);
38     return AceType::MakeRefPtr<SubwindowOhos>(instanceId);
39 }
40 
SubwindowOhos(int32_t instanceId)41 SubwindowOhos::SubwindowOhos(int32_t instanceId)
42 {
43     parentContainerId_ = instanceId;
44     windowId_ = id_;
45     SetSubwindowId(windowId_);
46     id_++;
47 }
48 
InitContainer()49 void SubwindowOhos::InitContainer()
50 {
51     LOGI("Subwindow start initialize container");
52     if (!window_) {
53         LOGI("Window is null, need create a new window");
54         OHOS::sptr<OHOS::Rosen::WindowOption> windowOption = new OHOS::Rosen::WindowOption();
55         auto parentWindowName = Platform::AceContainer::GetContainer(parentContainerId_)->GetWindowName();
56         auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
57         sptr<OHOS::Rosen::Window> parentWindow = OHOS::Rosen::Window::Find(parentWindowName);
58         if (parentWindow == nullptr) {
59             return;
60         }
61         auto windowType = parentWindow->GetType();
62         if (windowType == Rosen::WindowType::WINDOW_TYPE_DESKTOP) {
63             windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_FLOAT);
64         } else {
65             windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
66             windowOption->SetParentName(parentWindowName);
67         }
68         windowOption->SetWindowRect({ 0, 0, defaultDisplay->GetWidth(), defaultDisplay->GetHeight() });
69         windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
70         window_ = OHOS::Rosen::Window::Create(
71             "ARK_APP_SUBWINDOW_" + parentWindowName + std::to_string(windowId_), windowOption);
72         if (window_ == nullptr) {
73             LOGI("create window error return");
74             return;
75         }
76     }
77     std::string url = "";
78     window_->SetUIContent(url, nullptr, nullptr, false);
79     childContainerId_ = SubwindowManager::GetInstance()->GetContainerId(window_->GetWindowId());
80     SubwindowManager::GetInstance()->AddParentContainerId(childContainerId_, parentContainerId_);
81     auto parentContainer = Platform::AceContainer::GetContainer(parentContainerId_);
82     if (!parentContainer) {
83         LOGE("Get container failed, container is null");
84         return;
85     }
86 
87     auto container = Platform::AceContainer::GetContainer(childContainerId_);
88     if (!container) {
89         LOGE("Get container failed, container is null");
90         return;
91     }
92 
93     container->SetParentId(parentContainerId_);
94     container->GetSettings().SetUsingSharedRuntime(true);
95     container->SetSharedRuntime(parentContainer->GetSharedRuntime());
96     container->Initialize();
97     container->SetAssetManager(parentContainer->GetAssetManager());
98     container->SetResourceConfiguration(parentContainer->GetResourceConfiguration());
99     container->SetPackagePathStr(parentContainer->GetPackagePathStr());
100     container->SetIsSubContainer(true);
101     container->InitializeSubContainer(parentContainerId_);
102     ViewportConfig config;
103     // create ace_view
104     auto flutterAceView =
105         Platform::FlutterAceView::CreateView(childContainerId_, true, container->GetSettings().usePlatformAsUIThread);
106     Platform::FlutterAceView::SurfaceCreated(flutterAceView, window_);
107 
108     int32_t width = static_cast<int32_t>(window_->GetRect().width_);
109     int32_t height = static_cast<int32_t>(window_->GetRect().height_);
110     LOGI("UIContent Initialize: width: %{public}d, height: %{public}d", width, height);
111 
112     Ace::Platform::UIEnvCallback callback = nullptr;
113     // set view
114     Platform::AceContainer::SetView(flutterAceView, config.Density(), width, height, window_->GetWindowId(), callback);
115     Platform::FlutterAceView::SurfaceChanged(flutterAceView, width, height, config.Orientation());
116 
117 #ifdef ENABLE_ROSEN_BACKEND
118     if (SystemProperties::GetRosenBackendEnabled()) {
119         rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
120         if (rsUiDirector != nullptr) {
121             rsUiDirector->SetRSSurfaceNode(window_->GetSurfaceNode());
122             rsUiDirector->SetUITaskRunner(
123                 [taskExecutor = container->GetTaskExecutor()](
124                     const std::function<void()>& task) { taskExecutor->PostTask(task, TaskExecutor::TaskType::UI); });
125             auto context = container->GetPipelineContext();
126             if (context != nullptr) {
127                 LOGI("Init RSUIDirector");
128                 context->SetRSUIDirector(rsUiDirector);
129             }
130             rsUiDirector->Init();
131             LOGI("UIContent Init Rosen Backend");
132         }
133     }
134 #endif
135     auto subPipelineContext = Platform::AceContainer::GetContainer(childContainerId_)->GetPipelineContext();
136     if (!subPipelineContext) {
137         LOGE("Get SubPipelineContext failed, pipelineContext is null");
138     }
139     subPipelineContext->SetupSubRootElement();
140 }
141 
ShowWindow()142 void SubwindowOhos::ShowWindow()
143 {
144     LOGI("Show the subwindow");
145     if (!window_) {
146         LOGE("Show window failed, window is null");
147         return;
148     }
149 
150     OHOS::Rosen::WMError ret = window_->Show();
151 
152     if (ret != OHOS::Rosen::WMError::WM_OK) {
153         LOGE("Show window failed with errCode: %{public}d", static_cast<int32_t>(ret));
154         return;
155     }
156     LOGI("Show the subwindow successfully.");
157     SubwindowManager::GetInstance()->SetCurrentSubwindow(AceType::Claim(this));
158 }
159 
HideWindow()160 void SubwindowOhos::HideWindow()
161 {
162     LOGI("Hide the subwindow");
163     if (!window_) {
164         LOGE("Hide window failed, window is null");
165         return;
166     }
167 
168     OHOS::Rosen::WMError ret = window_->Hide();
169 
170     if (ret != OHOS::Rosen::WMError::WM_OK) {
171         LOGE("Hide window failed with errCode: %{public}d", static_cast<int32_t>(ret));
172         return;
173     }
174     LOGI("Hide the subwindow successfully.");
175 }
176 
AddMenu(const RefPtr<Component> & newComponent)177 void SubwindowOhos::AddMenu(const RefPtr<Component>& newComponent)
178 {
179     LOGI("Subwindow push new component start.");
180     auto stack = GetStack();
181     if (!stack) {
182         LOGE("Get stack failed, it is null");
183         return;
184     }
185     // Push the component
186     stack->PopMenu();
187     stack->PushComponent(newComponent);
188     popup_ = AceType::DynamicCast<SelectPopupComponent>(newComponent);
189     if (!popup_) {
190         LOGE("Add menu failed, this is not a popup component.");
191     }
192     LOGI("Subwindow push new component end.");
193 }
194 
ClearMenu()195 void SubwindowOhos::ClearMenu()
196 {
197     LOGI("Subwindow Clear menu start.");
198     auto stack = GetStack();
199     if (!stack) {
200         LOGE("Get stack failed, it is null");
201         return;
202     }
203     // Pop the component
204     stack->PopMenu();
205     auto context = stack->GetContext().Upgrade();
206     if (!context) {
207         LOGE("Get context failed, it is null");
208     }
209     context->FlushPipelineImmediately();
210     HideWindow();
211     LOGI("Subwindow clear menu end.");
212 }
213 
ShowMenu(const RefPtr<Component> & newComponent)214 void SubwindowOhos::ShowMenu(const RefPtr<Component>& newComponent)
215 {
216     LOGI("Show the menu");
217     ShowWindow();
218     AddMenu(newComponent);
219 }
220 
CloseMenu()221 void SubwindowOhos::CloseMenu()
222 {
223     LOGI("Close the menu");
224     if (popup_) {
225         popup_->CloseContextMenu();
226     }
227 }
228 
GetStack()229 RefPtr<StackElement> SubwindowOhos::GetStack()
230 {
231     auto aceContainer = Platform::AceContainer::GetContainer(childContainerId_);
232     if (!aceContainer) {
233         LOGE("Get container failed, it is null");
234         return nullptr;
235     }
236 
237     auto context = aceContainer->GetPipelineContext();
238     if (!context) {
239         LOGE("Get context failed, it is null");
240         return nullptr;
241     }
242     return context->GetLastStack();
243 }
244 
245 } // namespace OHOS::Ace