1 /*
2  * Copyright (c) 2021-2024 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 "window_scene.h"
17 
18 #include <ability_context.h>
19 #include <configuration.h>
20 
21 #include "perform_reporter.h"
22 #include "singleton_container.h"
23 #include "static_call.h"
24 #include "window_manager_hilog.h"
25 
26 namespace OHOS {
27 namespace Rosen {
28 namespace {
29 const std::string MAIN_WINDOW_ID = "main window";
30 std::atomic<uint32_t> g_count { 0 };
31 
GenerateMainWindowName(const std::shared_ptr<AbilityRuntime::Context> & context)32 std::string GenerateMainWindowName(const std::shared_ptr<AbilityRuntime::Context>& context)
33 {
34     if (context == nullptr) {
35         return MAIN_WINDOW_ID + std::to_string(g_count++);
36     } else {
37         std::string windowName = context->GetBundleName() + std::to_string(g_count++);
38         std::size_t pos = windowName.find_last_of('.');
39         return (pos == std::string::npos) ? windowName : windowName.substr(pos + 1); // skip '.'
40     }
41 }
42 }
43 
~WindowScene()44 WindowScene::~WindowScene()
45 {
46     TLOGI(WmsLogTag::WMS_MAIN, "winId %{public}u destructor!", mainWindowId_);
47 }
48 
OnLastStrongRef(const void *)49 void WindowScene::OnLastStrongRef(const void *)
50 {
51     if (auto mainWindow = GetMainWindow()) {
52         mainWindow->Destroy();
53     }
54 }
55 
Init(DisplayId displayId,const std::shared_ptr<AbilityRuntime::Context> & context,sptr<IWindowLifeCycle> & listener,sptr<WindowOption> option)56 WMError WindowScene::Init(DisplayId displayId, const std::shared_ptr<AbilityRuntime::Context>& context,
57     sptr<IWindowLifeCycle>& listener, sptr<WindowOption> option)
58 {
59     TLOGI(WmsLogTag::WMS_MAIN, "WindowScene init with normal option!");
60     if (option == nullptr) {
61         option = sptr<WindowOption>::MakeSptr();
62     }
63     option->SetDisplayId(displayId);
64     option->SetWindowTag(WindowTag::MAIN_WINDOW);
65     if (context != nullptr) {
66         option->SetBundleName(context->GetBundleName());
67     }
68     auto mainWindow = SingletonContainer::Get<StaticCall>().CreateWindow(
69         GenerateMainWindowName(context), option, context);
70     if (mainWindow == nullptr) {
71         TLOGE(WmsLogTag::WMS_MAIN, "mainWindow is null after create Window!");
72         return WMError::WM_ERROR_NULLPTR;
73     }
74     {
75         std::lock_guard<std::mutex> lock(mainWindowMutex_);
76         mainWindow_ = mainWindow;
77     }
78     mainWindowId_ = mainWindow->GetWindowId();
79     mainWindow->RegisterLifeCycleListener(listener);
80 
81     // report when application startup request window
82     SingletonContainer::Get<WindowInfoReporter>()
83         .ReportStartWindow(option->GetBundleName(), mainWindow->GetWindowName());
84     return WMError::WM_OK;
85 }
86 
Init(DisplayId displayId,const std::shared_ptr<AbilityRuntime::Context> & context,sptr<IWindowLifeCycle> & listener,sptr<WindowOption> option,const sptr<IRemoteObject> & iSession,const std::string & identityToken)87 WMError WindowScene::Init(DisplayId displayId, const std::shared_ptr<AbilityRuntime::Context>& context,
88     sptr<IWindowLifeCycle>& listener, sptr<WindowOption> option, const sptr<IRemoteObject>& iSession,
89     const std::string& identityToken)
90 {
91     TLOGI(WmsLogTag::WMS_MAIN, "WindowScene with window session!");
92     if (option == nullptr || iSession == nullptr) {
93         TLOGE(WmsLogTag::WMS_MAIN, "failed with option or iSession null!");
94         return WMError::WM_ERROR_NULLPTR;
95     }
96     option->SetDisplayId(displayId);
97     option->SetWindowName(GenerateMainWindowName(context));
98     if (context != nullptr) {
99         option->SetBundleName(context->GetBundleName());
100     }
101     auto mainWindow = SingletonContainer::Get<StaticCall>()
102         .CreateWindow(option, context, iSession, identityToken);
103     if (mainWindow == nullptr) {
104         TLOGE(WmsLogTag::WMS_MAIN, "mainWindow is null after create Window!");
105         return WMError::WM_ERROR_NULLPTR;
106     }
107     {
108         std::lock_guard<std::mutex> lock(mainWindowMutex_);
109         mainWindow_ = mainWindow;
110     }
111     mainWindowId_ = mainWindow->GetWindowId();
112     mainWindow->RegisterLifeCycleListener(listener);
113 
114     // report when application startup request window
115     SingletonContainer::Get<WindowInfoReporter>()
116         .ReportStartWindow(option->GetBundleName(), mainWindow->GetWindowName());
117     return WMError::WM_OK;
118 }
119 
CreateWindow(const std::string & windowName,sptr<WindowOption> & option) const120 sptr<Window> WindowScene::CreateWindow(const std::string& windowName, sptr<WindowOption>& option) const
121 {
122     auto mainWindow = GetMainWindow();
123     if (windowName.empty() || mainWindow == nullptr || option == nullptr) {
124         TLOGE(WmsLogTag::WMS_MAIN, "new windowName: %{public}s", windowName.c_str());
125         return nullptr;
126     }
127     option->SetParentId(mainWindow->GetWindowId());
128     option->SetWindowTag(WindowTag::SUB_WINDOW);
129     TLOGD(WmsLogTag::WMS_SUB, "windowName: %{public}s, parentId: %{public}u",
130         windowName.c_str(), mainWindow->GetWindowId());
131     return SingletonContainer::Get<StaticCall>().CreateWindow(windowName, option, mainWindow->GetContext());
132 }
133 
GetMainWindow() const134 sptr<Window> WindowScene::GetMainWindow() const
135 {
136     std::lock_guard<std::mutex> lock(mainWindowMutex_);
137     return mainWindow_;
138 }
139 
GetSubWindow()140 std::vector<sptr<Window>> WindowScene::GetSubWindow()
141 {
142     auto mainWindow = GetMainWindow();
143     if (mainWindow == nullptr) {
144         TLOGE(WmsLogTag::WMS_MAIN, "failed, because main window is null");
145         return {};
146     }
147     uint32_t parentId = mainWindow->GetWindowId();
148     return SingletonContainer::Get<StaticCall>().GetSubWindow(parentId);
149 }
150 
GoForeground(uint32_t reason)151 WMError WindowScene::GoForeground(uint32_t reason)
152 {
153     TLOGI(WmsLogTag::WMS_MAIN, "reason: %{public}u", reason);
154     auto mainWindow = GetMainWindow();
155     if (mainWindow == nullptr) {
156         TLOGE(WmsLogTag::WMS_MAIN, "failed, because main window is null");
157         return WMError::WM_ERROR_NULLPTR;
158     }
159     return mainWindow->Show(reason);
160 }
161 
GoBackground(uint32_t reason)162 WMError WindowScene::GoBackground(uint32_t reason)
163 {
164     TLOGI(WmsLogTag::WMS_MAIN, "reason: %{public}u", reason);
165     auto mainWindow = GetMainWindow();
166     if (mainWindow == nullptr) {
167         TLOGE(WmsLogTag::WMS_MAIN, "failed, because main window is null");
168         return WMError::WM_ERROR_NULLPTR;
169     }
170     return mainWindow->Hide(reason);
171 }
172 
GoDestroy()173 WMError WindowScene::GoDestroy()
174 {
175     auto mainWindow = GetMainWindow();
176     if (mainWindow == nullptr) {
177         TLOGE(WmsLogTag::WMS_MAIN, "main window is null");
178         return WMError::WM_ERROR_NULLPTR;
179     }
180     WMError ret = mainWindow->Destroy();
181     if (ret != WMError::WM_OK) {
182         TLOGE(WmsLogTag::WMS_MAIN, "failed, name: %{public}s", mainWindow->GetWindowName().c_str());
183         return ret;
184     }
185 
186     std::lock_guard<std::mutex> lock(mainWindowMutex_);
187     mainWindow_ = nullptr;
188     return WMError::WM_OK;
189 }
190 
OnNewWant(const AAFwk::Want & want)191 WMError WindowScene::OnNewWant(const AAFwk::Want& want)
192 {
193     auto mainWindow = GetMainWindow();
194     if (mainWindow == nullptr) {
195         TLOGE(WmsLogTag::WMS_MAIN, "failed, because main window is null");
196         return WMError::WM_ERROR_NULLPTR;
197     }
198     mainWindow->OnNewWant(want);
199     return WMError::WM_OK;
200 }
201 
SetSystemBarProperty(WindowType type,const SystemBarProperty & property) const202 WMError WindowScene::SetSystemBarProperty(WindowType type, const SystemBarProperty& property) const
203 {
204     auto mainWindow = GetMainWindow();
205     if (mainWindow == nullptr) {
206         TLOGE(WmsLogTag::WMS_MAIN, "failed, because main window is null");
207         return WMError::WM_ERROR_NULLPTR;
208     }
209     return mainWindow->SetSystemBarProperty(type, property);
210 }
211 
RequestFocus() const212 WMError WindowScene::RequestFocus() const
213 {
214     auto mainWindow = GetMainWindow();
215     if (mainWindow == nullptr) {
216         TLOGE(WmsLogTag::WMS_MAIN, "failed, because main window is null");
217         return WMError::WM_ERROR_NULLPTR;
218     }
219     return mainWindow->RequestFocus();
220 }
221 
UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & configuration)222 void WindowScene::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
223 {
224     if (auto mainWindow = GetMainWindow()) {
225         TLOGI(WmsLogTag::WMS_MAIN, "winId: %{public}u", mainWindow->GetWindowId());
226         mainWindow->UpdateConfiguration(configuration);
227     } else {
228         TLOGE(WmsLogTag::WMS_MAIN, "failed, because main window is null");
229     }
230 }
231 
GetContentInfo(BackupAndRestoreType type) const232 std::string WindowScene::GetContentInfo(BackupAndRestoreType type) const
233 {
234     auto mainWindow = GetMainWindow();
235     if (mainWindow == nullptr) {
236         TLOGE(WmsLogTag::WMS_MAIN, "failed, because main window is null");
237         return "";
238     }
239     return mainWindow->GetContentInfo(type);
240 }
241 
NotifyMemoryLevel(int32_t level)242 WMError WindowScene::NotifyMemoryLevel(int32_t level)
243 {
244     auto mainWindow = GetMainWindow();
245     if (mainWindow == nullptr) {
246         TLOGE(WmsLogTag::WMS_MAIN, "failed, because main window is null");
247         return WMError::WM_ERROR_NULLPTR;
248     }
249     TLOGI(WmsLogTag::WMS_MAIN, "level: %{public}d", level);
250     return mainWindow->NotifyMemoryLevel(level);
251 }
252 
253 } // namespace Rosen
254 } // namespace OHOS
255