1 /*
2 * Copyright (c) 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 "screen_scene.h"
17
18 #include <event_handler.h>
19 #include <transaction/rs_interfaces.h>
20 #include <ui_content.h>
21 #include <viewport_config.h>
22
23 #include "app_mgr_client.h"
24 #include "singleton.h"
25 #include "singleton_container.h"
26
27 #include "dm_common.h"
28 #include "display_manager.h"
29 #include "rs_adapter.h"
30 #include "screen_session_manager_client.h"
31 #include "intention_event_manager.h"
32 #include "input_transfer_station.h"
33 #include "window_manager_hilog.h"
34 #include "root_scene.h"
35
36 namespace OHOS {
37 namespace Rosen {
38 namespace {
39 constexpr float MIN_DPI = 1e-6;
40 std::atomic<bool> g_ssIsDestroyed = false;
41 const std::string INPUT_AND_VSYNC_THREAD = "InputAndVsyncThread";
42 } // namespace
43
ScreenScene(std::string name)44 ScreenScene::ScreenScene(std::string name) : name_(name)
45 {
46 orientation_ = static_cast<int32_t>(DisplayOrientation::PORTRAIT);
47 NodeId nodeId = 0;
48 vsyncStation_ = std::make_shared<VsyncStation>(nodeId);
49 handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
50 g_ssIsDestroyed = false;
51 displayId_ = DISPLAY_ID_INVALID;
52 }
53
~ScreenScene()54 ScreenScene::~ScreenScene()
55 {
56 g_ssIsDestroyed = true;
57 Destroy();
58 }
59
Destroy(uint32_t reason)60 WMError ScreenScene::Destroy(uint32_t reason)
61 {
62 std::function<void()> task; //延长task的生命周期
63 {
64 std::lock_guard<std::mutex> lock(mutex_);
65 if (!uiContent_) {
66 TLOGD(WmsLogTag::DMS, "Destroy uiContent_ is nullptr!");
67 return WMError::WM_OK;
68 }
69 std::shared_ptr<Ace::UIContent> uiContent = std::move(uiContent_);
70 uiContent_ = nullptr;
71 RootScene::staticRootScene_->RemoveRootScene(displayId_);
72 vsyncStation_->Destroy();
73 task = [uiContent]() {
74 if (uiContent != nullptr) {
75 uiContent->Destroy();
76 TLOGD(WmsLogTag::DMS, "ScreenScene: uiContent destroy success!");
77 }
78 };
79 }
80 if (handler_) {
81 handler_->PostSyncTask(task, "ScreenScene:Destroy");
82 } else {
83 task();
84 }
85 return WMError::WM_OK;
86 }
87
LoadContent(const std::string & contentUrl,napi_env env,napi_value storage,AbilityRuntime::Context * context)88 void ScreenScene::LoadContent(const std::string& contentUrl, napi_env env, napi_value storage,
89 AbilityRuntime::Context* context)
90 {
91 if (g_ssIsDestroyed) {
92 TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
93 return;
94 }
95 if (context == nullptr) {
96 TLOGE(WmsLogTag::DMS, "context is nullptr!");
97 return;
98 }
99 std::lock_guard<std::mutex> lock(mutex_);
100 uiContent_ = Ace::UIContent::Create(context, reinterpret_cast<NativeEngine*>(env));
101 if (uiContent_ == nullptr) {
102 TLOGE(WmsLogTag::DMS, "uiContent_ is nullptr!");
103 return;
104 }
105
106 uiContent_->Initialize(this, contentUrl, storage);
107 uiContent_->Foreground();
108 uiContent_->SetFrameLayoutFinishCallback(std::move(frameLayoutFinishCb_));
109 wptr<Window> weakWindow(this);
110 RootScene::staticRootScene_->AddRootScene(DEFAULT_DISPLAY_ID, weakWindow);
111 RegisterInputEventListener();
112 }
113
RegisterInputEventListener()114 void ScreenScene::RegisterInputEventListener()
115 {
116 auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
117 if (mainEventRunner) {
118 TLOGI(WmsLogTag::DMS, "MainEventRunner is available");
119 handler_ = std::make_shared<AppExecFwk::EventHandler>(mainEventRunner);
120 } else {
121 TLOGI(WmsLogTag::DMS, "MainEventRunner is not available");
122 handler_ = AppExecFwk::EventHandler::Current();
123 if (!handler_) {
124 handler_ =
125 std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::Create(INPUT_AND_VSYNC_THREAD));
126 }
127 }
128 if (!(DelayedSingleton<IntentionEventManager>::GetInstance()->EnableInputEventListener(uiContent_.get(),
129 handler_, this))) {
130 TLOGI(WmsLogTag::DMS, "EnableInputEventListener fail");
131 }
132 InputTransferStation::GetInstance().MarkRegisterToMMI();
133 }
134
UpdateViewportConfig(const Rect & rect,WindowSizeChangeReason reason)135 void ScreenScene::UpdateViewportConfig(const Rect& rect, WindowSizeChangeReason reason)
136 {
137 if (g_ssIsDestroyed) {
138 TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
139 return;
140 }
141 std::lock_guard<std::mutex> lock(mutex_);
142 if (uiContent_ == nullptr) {
143 TLOGE(WmsLogTag::DMS, "uiContent_ is nullptr!");
144 return;
145 }
146 Ace::ViewportConfig config;
147 config.SetSize(rect.width_, rect.height_);
148 config.SetPosition(rect.posX_, rect.posY_);
149 config.SetDensity(density_);
150 config.SetOrientation(orientation_);
151 config.SetDisplayId(GetDisplayId());
152 uiContent_->UpdateViewportConfig(config, reason);
153 }
154
UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & configuration)155 void ScreenScene::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
156 {
157 if (g_ssIsDestroyed) {
158 TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
159 return;
160 }
161 std::lock_guard<std::mutex> lock(mutex_);
162 if (uiContent_) {
163 TLOGD(WmsLogTag::DMS, "notify root scene ace");
164 uiContent_->UpdateConfiguration(configuration);
165 if (configuration == nullptr) {
166 return;
167 }
168 std::string colorMode = configuration->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
169 bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
170 bool ret = RSInterfaces::GetInstance().SetGlobalDarkColorMode(isDark);
171 if (!ret) {
172 TLOGI(WmsLogTag::DMS, "SetGlobalDarkColorMode fail with colorMode : %{public}s", colorMode.c_str());
173 }
174 }
175 }
176
UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration)177 void ScreenScene::UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
178 {
179 TLOGI(WmsLogTag::DMS, "update configuration.");
180 UpdateConfiguration(configuration);
181 if (configurationUpdateCallback_) {
182 configurationUpdateCallback_(configuration);
183 }
184 }
185
SetOnConfigurationUpdatedCallback(const std::function<void (const std::shared_ptr<AppExecFwk::Configuration> &)> & callback)186 void ScreenScene::SetOnConfigurationUpdatedCallback(
187 const std::function<void(const std::shared_ptr<AppExecFwk::Configuration>&)>& callback)
188 {
189 configurationUpdateCallback_ = callback;
190 }
191
RequestVsync(const std::shared_ptr<VsyncCallback> & vsyncCallback)192 void ScreenScene::RequestVsync(const std::shared_ptr<VsyncCallback>& vsyncCallback)
193 {
194 vsyncStation_->RequestVsync(vsyncCallback);
195 }
196
GetVSyncPeriod()197 int64_t ScreenScene::GetVSyncPeriod()
198 {
199 return vsyncStation_->GetVSyncPeriod();
200 }
201
FlushFrameRate(uint32_t rate,int32_t animatorExpectedFrameRate,uint32_t rateType)202 void ScreenScene::FlushFrameRate(uint32_t rate, int32_t animatorExpectedFrameRate, uint32_t rateType)
203 {
204 vsyncStation_->FlushFrameRate(GetRSUIContext(), rate, animatorExpectedFrameRate, rateType);
205 }
206
OnBundleUpdated(const std::string & bundleName)207 void ScreenScene::OnBundleUpdated(const std::string& bundleName)
208 {
209 if (g_ssIsDestroyed) {
210 TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
211 return;
212 }
213 TLOGD(WmsLogTag::DMS, "bundle %{public}s updated", bundleName.c_str());
214 std::lock_guard<std::mutex> lock(mutex_);
215 if (uiContent_) {
216 uiContent_->UpdateResource();
217 }
218 }
219
SetFrameLayoutFinishCallback(std::function<void ()> && callback)220 void ScreenScene::SetFrameLayoutFinishCallback(std::function<void()>&& callback)
221 {
222 if (g_ssIsDestroyed) {
223 TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
224 return;
225 }
226 frameLayoutFinishCb_ = callback;
227 std::lock_guard<std::mutex> lock(mutex_);
228 if (uiContent_) {
229 uiContent_->SetFrameLayoutFinishCallback(std::move(frameLayoutFinishCb_));
230 frameLayoutFinishCb_ = nullptr;
231 }
232 TLOGI(WmsLogTag::WMS_LAYOUT, "SetFrameLayoutFinishCallback end");
233 }
234
SetDisplayDensity(float density)235 void ScreenScene::SetDisplayDensity(float density)
236 {
237 if (density < MIN_DPI) {
238 TLOGE(WmsLogTag::DMS, "invalid density");
239 return;
240 }
241 density_ = density;
242 }
243
GetDisplayId() const244 uint64_t ScreenScene::GetDisplayId() const
245 {
246 return displayId_;
247 }
248
SetDisplayId(DisplayId displayId)249 void ScreenScene::SetDisplayId(DisplayId displayId)
250 {
251 displayId_ = displayId;
252 }
253
SetDisplayOrientation(int32_t orientation)254 void ScreenScene::SetDisplayOrientation(int32_t orientation)
255 {
256 if (orientation < static_cast<int32_t>(DisplayOrientation::PORTRAIT) ||
257 orientation > static_cast<int32_t>(DisplayOrientation::UNKNOWN)) {
258 TLOGE(WmsLogTag::DMS, "invalid orientation");
259 return;
260 }
261 orientation_ = orientation;
262 }
263
GetUIContent() const264 Ace::UIContent* ScreenScene::GetUIContent() const
265 {
266 std::lock_guard<std::mutex> lock(mutex_);
267 if (uiContent_) {
268 return uiContent_.get();
269 } else {
270 TLOGE(WmsLogTag::DMS, "uiContent_ is nullptr!");
271 return nullptr;
272 }
273 }
274
GetRSUIDirector() const275 std::shared_ptr<RSUIDirector> ScreenScene::GetRSUIDirector() const
276 {
277 RETURN_IF_RS_CLIENT_MULTI_INSTANCE_DISABLED(nullptr);
278 sptr<Display> display;
279 if (displayId_ == DISPLAY_ID_INVALID) {
280 display = DisplayManager::GetInstance().GetDefaultDisplay();
281 TLOGE(WmsLogTag::WMS_SCB, "displayId is invalid, use default display");
282 } else {
283 display = DisplayManager::GetInstance().GetDisplayById(displayId_);
284 }
285 if (!display) {
286 TLOGE(WmsLogTag::WMS_SCB, "display is null, displayId: %{public}" PRIu64, displayId_);
287 return nullptr;
288 }
289 auto screenId = display->GetScreenId();
290 auto rsUIDirector = ScreenSessionManagerClient::GetInstance().GetRSUIDirector(screenId);
291 TLOGD(WmsLogTag::WMS_SCB, "%{public}s, screenId: %{public}" PRIu64 ", windowId: %{public}d",
292 RSAdapterUtil::RSUIDirectorToStr(rsUIDirector).c_str(), screenId, GetWindowId());
293 return rsUIDirector;
294 }
295
GetRSUIContext() const296 std::shared_ptr<RSUIContext> ScreenScene::GetRSUIContext() const
297 {
298 RETURN_IF_RS_CLIENT_MULTI_INSTANCE_DISABLED(nullptr);
299 auto rsUIDirector = GetRSUIDirector();
300 auto rsUIContext = rsUIDirector ? rsUIDirector->GetRSUIContext() : nullptr;
301 TLOGD(WmsLogTag::WMS_SCB, "%{public}s, windowId: %{public}d",
302 RSAdapterUtil::RSUIContextToStr(rsUIContext).c_str(), GetWindowId());
303 return rsUIContext;
304 }
305 } // namespace Rosen
306 } // namespace OHOS
307