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