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 <ui_content.h>
20 #include <viewport_config.h>
21
22 #include "app_mgr_client.h"
23 #include "singleton.h"
24 #include "singleton_container.h"
25
26 #include "dm_common.h"
27 #include "window_manager_hilog.h"
28
29 namespace OHOS {
30 namespace Rosen {
31 namespace {
32 constexpr float MIN_DPI = 1e-6;
33 std::atomic<bool> g_ssIsDestroyed = false;
34 } // namespace
35
ScreenScene(std::string name)36 ScreenScene::ScreenScene(std::string name) : name_(name)
37 {
38 orientation_ = static_cast<int32_t>(DisplayOrientation::PORTRAIT);
39 NodeId nodeId = 0;
40 vsyncStation_ = std::make_shared<VsyncStation>(nodeId);
41 handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
42 g_ssIsDestroyed = false;
43 displayId_ = DISPLAY_ID_INVALID;
44 }
45
~ScreenScene()46 ScreenScene::~ScreenScene()
47 {
48 g_ssIsDestroyed = true;
49 Destroy();
50 }
51
Destroy()52 WMError ScreenScene::Destroy()
53 {
54 std::function<void()> task; //延长task的生命周期
55 {
56 std::lock_guard<std::mutex> lock(mutex_);
57 if (!uiContent_) {
58 TLOGD(WmsLogTag::DMS, "Destroy uiContent_ is nullptr!");
59 return WMError::WM_OK;
60 }
61 std::shared_ptr<Ace::UIContent> uiContent = std::move(uiContent_);
62 uiContent_ = nullptr;
63 vsyncStation_->Destroy();
64 task = [uiContent]() {
65 if (uiContent != nullptr) {
66 uiContent->Destroy();
67 TLOGD(WmsLogTag::DMS, "ScreenScene: uiContent destroy success!");
68 }
69 };
70 }
71 if (handler_) {
72 handler_->PostSyncTask(task, "ScreenScene:Destroy");
73 } else {
74 task();
75 }
76 return WMError::WM_OK;
77 }
78
LoadContent(const std::string & contentUrl,napi_env env,napi_value storage,AbilityRuntime::Context * context)79 void ScreenScene::LoadContent(const std::string& contentUrl, napi_env env, napi_value storage,
80 AbilityRuntime::Context* context)
81 {
82 if (g_ssIsDestroyed) {
83 TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
84 return;
85 }
86 if (context == nullptr) {
87 TLOGE(WmsLogTag::DMS, "context is nullptr!");
88 return;
89 }
90 std::lock_guard<std::mutex> lock(mutex_);
91 uiContent_ = Ace::UIContent::Create(context, reinterpret_cast<NativeEngine*>(env));
92 if (uiContent_ == nullptr) {
93 TLOGE(WmsLogTag::DMS, "uiContent_ is nullptr!");
94 return;
95 }
96
97 uiContent_->Initialize(this, contentUrl, storage);
98 uiContent_->Foreground();
99 uiContent_->SetFrameLayoutFinishCallback(std::move(frameLayoutFinishCb_));
100 }
101
UpdateViewportConfig(const Rect & rect,WindowSizeChangeReason reason)102 void ScreenScene::UpdateViewportConfig(const Rect& rect, WindowSizeChangeReason reason)
103 {
104 if (g_ssIsDestroyed) {
105 TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
106 return;
107 }
108 std::lock_guard<std::mutex> lock(mutex_);
109 if (uiContent_ == nullptr) {
110 TLOGE(WmsLogTag::DMS, "uiContent_ is nullptr!");
111 return;
112 }
113 Ace::ViewportConfig config;
114 config.SetSize(rect.width_, rect.height_);
115 config.SetPosition(rect.posX_, rect.posY_);
116 config.SetDensity(density_);
117 config.SetOrientation(orientation_);
118 config.SetDisplayId(GetDisplayId());
119 uiContent_->UpdateViewportConfig(config, reason);
120 }
121
UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & configuration)122 void ScreenScene::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
123 {
124 if (g_ssIsDestroyed) {
125 TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
126 return;
127 }
128 std::lock_guard<std::mutex> lock(mutex_);
129 if (uiContent_) {
130 TLOGD(WmsLogTag::DMS, "notify root scene ace");
131 uiContent_->UpdateConfiguration(configuration);
132 }
133 }
134
RequestVsync(const std::shared_ptr<VsyncCallback> & vsyncCallback)135 void ScreenScene::RequestVsync(const std::shared_ptr<VsyncCallback>& vsyncCallback)
136 {
137 vsyncStation_->RequestVsync(vsyncCallback);
138 }
139
GetVSyncPeriod()140 int64_t ScreenScene::GetVSyncPeriod()
141 {
142 return vsyncStation_->GetVSyncPeriod();
143 }
144
FlushFrameRate(uint32_t rate,int32_t animatorExpectedFrameRate,uint32_t rateType)145 void ScreenScene::FlushFrameRate(uint32_t rate, int32_t animatorExpectedFrameRate, uint32_t rateType)
146 {
147 vsyncStation_->FlushFrameRate(rate, animatorExpectedFrameRate, rateType);
148 }
149
OnBundleUpdated(const std::string & bundleName)150 void ScreenScene::OnBundleUpdated(const std::string& bundleName)
151 {
152 if (g_ssIsDestroyed) {
153 TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
154 return;
155 }
156 TLOGD(WmsLogTag::DMS, "bundle %{public}s updated", bundleName.c_str());
157 std::lock_guard<std::mutex> lock(mutex_);
158 if (uiContent_) {
159 uiContent_->UpdateResource();
160 }
161 }
162
SetFrameLayoutFinishCallback(std::function<void ()> && callback)163 void ScreenScene::SetFrameLayoutFinishCallback(std::function<void()>&& callback)
164 {
165 if (g_ssIsDestroyed) {
166 TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
167 return;
168 }
169 frameLayoutFinishCb_ = callback;
170 std::lock_guard<std::mutex> lock(mutex_);
171 if (uiContent_) {
172 uiContent_->SetFrameLayoutFinishCallback(std::move(frameLayoutFinishCb_));
173 frameLayoutFinishCb_ = nullptr;
174 }
175 TLOGI(WmsLogTag::WMS_LAYOUT, "SetFrameLayoutFinishCallback end");
176 }
177
SetDisplayDensity(float density)178 void ScreenScene::SetDisplayDensity(float density)
179 {
180 if (density < MIN_DPI) {
181 TLOGE(WmsLogTag::DMS, "invalid density");
182 return;
183 }
184 density_ = density;
185 }
186
GetDisplayId() const187 uint64_t ScreenScene::GetDisplayId() const
188 {
189 return displayId_;
190 }
191
SetDisplayId(DisplayId displayId)192 void ScreenScene::SetDisplayId(DisplayId displayId)
193 {
194 displayId_ = displayId;
195 }
196
SetDisplayOrientation(int32_t orientation)197 void ScreenScene::SetDisplayOrientation(int32_t orientation)
198 {
199 if (orientation < static_cast<int32_t>(DisplayOrientation::PORTRAIT) ||
200 orientation > static_cast<int32_t>(DisplayOrientation::UNKNOWN)) {
201 TLOGE(WmsLogTag::DMS, "invalid orientation");
202 return;
203 }
204 orientation_ = orientation;
205 }
206
GetUIContent() const207 Ace::UIContent* ScreenScene::GetUIContent() const
208 {
209 std::lock_guard<std::mutex> lock(mutex_);
210 if (uiContent_) {
211 return uiContent_.get();
212 } else {
213 TLOGE(WmsLogTag::DMS, "uiContent_ is nullptr!");
214 return nullptr;
215 }
216 }
217 } // namespace Rosen
218 } // namespace OHOS
219