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 }
44 
~ScreenScene()45 ScreenScene::~ScreenScene()
46 {
47     g_ssIsDestroyed = true;
48     Destroy();
49 }
50 
Destroy()51 WMError ScreenScene::Destroy()
52 {
53     if (!uiContent_) {
54         TLOGD(WmsLogTag::DMS, "Destroy uiContent_ is nullptr!");
55         return WMError::WM_OK;
56     }
57     std::shared_ptr<Ace::UIContent> uiContent = std::move(uiContent_);
58     uiContent_ = nullptr;
59     vsyncStation_->Destroy();
60     auto task = [uiContent]() {
61         if (uiContent != nullptr) {
62             uiContent->Destroy();
63             TLOGD(WmsLogTag::DMS, "ScreenScene: uiContent destroy success!");
64         }
65     };
66     if (handler_) {
67         handler_->PostSyncTask(task, "ScreenScene:Destroy");
68     } else {
69         task();
70     }
71     return WMError::WM_OK;
72 }
73 
LoadContent(const std::string& contentUrl, napi_env env, napi_value storage, AbilityRuntime::Context* context)74 void ScreenScene::LoadContent(const std::string& contentUrl, napi_env env, napi_value storage,
75     AbilityRuntime::Context* context)
76 {
77     if (g_ssIsDestroyed) {
78         TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
79         return;
80     }
81     if (context == nullptr) {
82         TLOGE(WmsLogTag::DMS, "context is nullptr!");
83         return;
84     }
85     uiContent_ = Ace::UIContent::Create(context, reinterpret_cast<NativeEngine*>(env));
86     if (uiContent_ == nullptr) {
87         TLOGE(WmsLogTag::DMS, "uiContent_ is nullptr!");
88         return;
89     }
90 
91     uiContent_->Initialize(this, contentUrl, storage);
92     uiContent_->Foreground();
93     uiContent_->SetFrameLayoutFinishCallback(std::move(frameLayoutFinishCb_));
94 }
95 
UpdateViewportConfig(const Rect& rect, WindowSizeChangeReason reason)96 void ScreenScene::UpdateViewportConfig(const Rect& rect, WindowSizeChangeReason reason)
97 {
98     if (g_ssIsDestroyed) {
99         TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
100         return;
101     }
102     if (uiContent_ == nullptr) {
103         TLOGE(WmsLogTag::DMS, "uiContent_ is nullptr!");
104         return;
105     }
106     Ace::ViewportConfig config;
107     config.SetSize(rect.width_, rect.height_);
108     config.SetPosition(rect.posX_, rect.posY_);
109     config.SetDensity(density_);
110     config.SetOrientation(orientation_);
111     uiContent_->UpdateViewportConfig(config, reason);
112 }
113 
UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)114 void ScreenScene::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
115 {
116     if (g_ssIsDestroyed) {
117         TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
118         return;
119     }
120     if (uiContent_) {
121         TLOGD(WmsLogTag::DMS, "notify root scene ace");
122         uiContent_->UpdateConfiguration(configuration);
123     }
124 }
125 
RequestVsync(const std::shared_ptr<VsyncCallback>& vsyncCallback)126 void ScreenScene::RequestVsync(const std::shared_ptr<VsyncCallback>& vsyncCallback)
127 {
128     vsyncStation_->RequestVsync(vsyncCallback);
129 }
130 
GetVSyncPeriod()131 int64_t ScreenScene::GetVSyncPeriod()
132 {
133     return vsyncStation_->GetVSyncPeriod();
134 }
135 
FlushFrameRate(uint32_t rate, int32_t animatorExpectedFrameRate, uint32_t rateType)136 void ScreenScene::FlushFrameRate(uint32_t rate, int32_t animatorExpectedFrameRate, uint32_t rateType)
137 {
138     vsyncStation_->FlushFrameRate(rate, animatorExpectedFrameRate, rateType);
139 }
140 
OnBundleUpdated(const std::string& bundleName)141 void ScreenScene::OnBundleUpdated(const std::string& bundleName)
142 {
143     if (g_ssIsDestroyed) {
144         TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
145         return;
146     }
147     TLOGD(WmsLogTag::DMS, "bundle %{public}s updated", bundleName.c_str());
148     if (uiContent_) {
149         uiContent_->UpdateResource();
150     }
151 }
152 
SetFrameLayoutFinishCallback(std::function<void()>&& callback)153 void ScreenScene::SetFrameLayoutFinishCallback(std::function<void()>&& callback)
154 {
155     if (g_ssIsDestroyed) {
156         TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!");
157         return;
158     }
159     frameLayoutFinishCb_ = callback;
160     if (uiContent_) {
161         uiContent_->SetFrameLayoutFinishCallback(std::move(frameLayoutFinishCb_));
162         frameLayoutFinishCb_ = nullptr;
163     }
164     TLOGI(WmsLogTag::WMS_LAYOUT, "SetFrameLayoutFinishCallback end");
165 }
166 
SetDisplayDensity(float density)167 void ScreenScene::SetDisplayDensity(float density)
168 {
169     if (density < MIN_DPI) {
170         TLOGE(WmsLogTag::DMS, "invalid density");
171         return;
172     }
173     density_ = density;
174 }
175 
SetDisplayOrientation(int32_t orientation)176 void ScreenScene::SetDisplayOrientation(int32_t orientation)
177 {
178     if (orientation < static_cast<int32_t>(DisplayOrientation::PORTRAIT) ||
179         orientation > static_cast<int32_t>(DisplayOrientation::UNKNOWN)) {
180         TLOGE(WmsLogTag::DMS, "invalid orientation");
181         return;
182     }
183     orientation_ = orientation;
184 }
185 } // namespace Rosen
186 } // namespace OHOS
187