• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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