• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "core/components_ng/pattern/window_scene/screen/screen_pattern.h"
17 
18 #include <mutex>
19 
20 #include "ipc_skeleton.h"
21 #include "root_scene.h"
22 #include "screen_scene.h"
23 #include "screen_manager.h"
24 #include "transaction/rs_transaction_proxy.h"
25 
26 #include "core/common/container.h"
27 #include "core/components_ng/pattern/window_scene/helper/window_scene_helper.h"
28 #include "core/components_ng/pattern/window_scene/scene/window_scene_layout_manager.h"
29 #include "core/components_ng/render/adapter/rosen_render_context.h"
30 #include "core/components_ng/render/adapter/rosen_window.h"
31 #include "core/pipeline_ng/pipeline_context.h"
32 
33 namespace OHOS::Ace::NG {
34 namespace {
35 constexpr float DIRECTION0 = 0;
36 constexpr float DIRECTION90 = 90;
37 constexpr float DIRECTION180 = 180;
38 constexpr float DIRECTION270 = 270;
39 constexpr uint32_t DOT_PER_INCH = 160;
40 
41 std::vector<MMI::DisplayInfo> g_displayInfoVector;
42 
43 std::mutex g_vecLock;
44 
ConvertDegreeToMMIRotation(float degree)45 MMI::Direction ConvertDegreeToMMIRotation(float degree)
46 {
47     if (NearEqual(degree, DIRECTION0)) {
48         return MMI::DIRECTION0;
49     }
50     if (NearEqual(degree, DIRECTION90)) {
51         return MMI::DIRECTION90;
52     }
53     if (NearEqual(degree, DIRECTION180)) {
54         return MMI::DIRECTION180;
55     }
56     if (NearEqual(degree, DIRECTION270)) {
57         return MMI::DIRECTION270;
58     }
59     return MMI::DIRECTION0;
60 }
61 } // namespace
62 
63 float ScreenPattern::screenMaxWidth_;
64 float ScreenPattern::screenMaxHeight_;
65 
ScreenPattern(const sptr<Rosen::ScreenSession> & screenSession)66 ScreenPattern::ScreenPattern(const sptr<Rosen::ScreenSession>& screenSession)
67 {
68     screenSession_ = screenSession;
69     if (screenSession_ != nullptr) {
70         screenSession_->SetUpdateToInputManagerCallback(std::bind(&ScreenPattern::UpdateToInputManager,
71             this, std::placeholders::_1));
72         screenSession_->SetUpdateScreenPivotCallback(std::bind(
73             &ScreenPattern::UpdateRenderPivot, this, std::placeholders::_1, std::placeholders::_2));
74     }
75 }
76 
OnAttachToFrameNode()77 void ScreenPattern::OnAttachToFrameNode()
78 {
79     CHECK_NULL_VOID(screenSession_);
80     auto displayNode = screenSession_->GetDisplayNode();
81     CHECK_NULL_VOID(displayNode);
82 
83     auto host = GetHost();
84     CHECK_NULL_VOID(host);
85 
86     auto pipeline = PipelineContext::GetCurrentContext();
87     CHECK_NULL_VOID(pipeline);
88     pipeline->SetScreenNode(host);
89 
90     auto context = AceType::DynamicCast<NG::RosenRenderContext>(host->GetRenderContext());
91     CHECK_NULL_VOID(context);
92     context->SetRSNode(displayNode);
93     auto instance = WindowSceneLayoutManager::GetInstance();
94     if (instance) {
95         instance->RegisterScreenNode(screenSession_->GetScreenId(), host);
96     }
97 }
98 
OnDetachFromFrameNode(FrameNode * frameNode)99 void ScreenPattern::OnDetachFromFrameNode(FrameNode* frameNode)
100 {
101     CHECK_NULL_VOID(screenSession_);
102     auto instance = WindowSceneLayoutManager::GetInstance();
103     if (instance) {
104         instance->UnregisterScreenNode(screenSession_->GetScreenId());
105     }
106 }
107 
UpdateDisplayInfo()108 void ScreenPattern::UpdateDisplayInfo()
109 {
110     CHECK_NULL_VOID(screenSession_);
111     auto displayNode = screenSession_->GetDisplayNode();
112     CHECK_NULL_VOID(displayNode);
113     auto displayNodeRotation = displayNode->GetStagingProperties().GetRotation();
114     if (displayNodeRotation < DIRECTION0) {
115         displayNodeRotation = -displayNodeRotation;
116     }
117 
118     UpdateToInputManager(displayNodeRotation);
119 }
120 
UpdateRenderPivot(float pivotX,float pivotY)121 void ScreenPattern::UpdateRenderPivot(float pivotX, float pivotY)
122 {
123     auto host = GetHost();
124     CHECK_NULL_VOID(host);
125     auto context = host->GetRenderContext();
126     CHECK_NULL_VOID(context);
127     context->SetRenderPivot(pivotX, pivotY);
128     auto transactionProxy = Rosen::RSTransactionProxy::GetInstance();
129     if (transactionProxy != nullptr) {
130         transactionProxy->FlushImplicitTransaction();
131     } else {
132         LOGE("RSTransactionProxy transactionProxy is nullptr");
133     }
134 }
135 
UpdateToInputManager(float rotation)136 void ScreenPattern::UpdateToInputManager(float rotation)
137 {
138     CHECK_NULL_VOID(screenSession_);
139     auto pid = IPCSkeleton::GetCallingRealPid();
140     auto uid = IPCSkeleton::GetCallingUid();
141     auto screenId = screenSession_->GetScreenId();
142     auto dpi = GetDensityInCurrentResolution() * DOT_PER_INCH;
143 
144     auto host = GetHost();
145     CHECK_NULL_VOID(host);
146     auto renderContext = host->GetRenderContext();
147     CHECK_NULL_VOID(renderContext);
148     auto paintRect = renderContext->GetPaintRectWithTransform();
149     auto tempHeight = paintRect.Height();
150     auto tempWidth = paintRect.Width();
151     if (rotation != DIRECTION0 && rotation != DIRECTION180) {
152         auto temp = tempWidth;
153         tempWidth = tempHeight;
154         tempHeight = temp;
155     }
156     screenMaxWidth_ = std::max(screenMaxWidth_, tempWidth);
157     screenMaxHeight_ = std::max(screenMaxHeight_, tempHeight);
158 
159     MMI::Rect screenRect = {
160         paintRect.Left(),
161         paintRect.Top(),
162         screenMaxWidth_,
163         screenMaxHeight_,
164     };
165     MMI::WindowInfo windowInfo = {
166         .id = 0,    // root scene id 0
167         .pid = pid,
168         .uid = uid,
169         .area = screenRect,
170         .defaultHotAreas = { screenRect },
171         .pointerHotAreas = { screenRect },
172         .agentWindowId = 0, // root scene id 0
173         .flags = 0  // touchable
174     };
175     MMI::DisplayInfo displayInfo = {
176         .id = screenId,
177         .x = paintRect.Left(),
178         .y = paintRect.Top(),
179         .width = paintRect.Width(),
180         .height = paintRect.Height(),
181         .dpi = dpi,
182         .name = "display" + std::to_string(screenId),
183         .uniq = "default" + std::to_string(screenId),
184         .direction = ConvertDegreeToMMIRotation(rotation)
185     };
186     InputManagerUpdateDisplayInfo(paintRect, displayInfo, windowInfo);
187 }
188 
InputManagerUpdateDisplayInfo(RectF paintRect,MMI::DisplayInfo displayInfo,MMI::WindowInfo windowInfo)189 void ScreenPattern::InputManagerUpdateDisplayInfo(RectF paintRect,
190     MMI::DisplayInfo displayInfo, MMI::WindowInfo windowInfo)
191 {
192     std::lock_guard<std::mutex> lock(g_vecLock);
193     DeduplicateDisplayInfo();
194     g_displayInfoVector.insert(g_displayInfoVector.begin(), displayInfo);
195 
196     MMI::DisplayGroupInfo displayGroupInfo = {
197         .width = paintRect.Width(),
198         .height = paintRect.Height(),
199         .focusWindowId = 0, // root scene id 0
200         .windowsInfo = { windowInfo },
201         .displaysInfo = g_displayInfoVector
202     };
203 }
204 
DeduplicateDisplayInfo()205 void ScreenPattern::DeduplicateDisplayInfo()
206 {
207     auto screenId = screenSession_->GetScreenId();
208     auto it = std::remove_if(g_displayInfoVector.begin(), g_displayInfoVector.end(),
209         [screenId](MMI::DisplayInfo displayInfo) {
210             return displayInfo.id == static_cast<int32_t>(screenId);
211         });
212     g_displayInfoVector.erase(it, g_displayInfoVector.end());
213 }
214 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & changeConfig)215 bool ScreenPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& changeConfig)
216 {
217     UpdateDisplayInfo();
218     if (screenSession_->GetScreenProperty().GetScreenType() == Rosen::ScreenType::VIRTUAL) {
219         return false;
220     }
221     auto container = Container::Current();
222     CHECK_NULL_RETURN(container, false);
223     auto window = static_cast<RosenWindow*>(container->GetWindow());
224     CHECK_NULL_RETURN(window, false);
225     auto rsWindow = window->GetRSWindow();
226     CHECK_NULL_RETURN(rsWindow, false);
227     auto screenBounds = screenSession_->GetScreenProperty().GetBounds();
228     Rosen::Rect rect = { screenBounds.rect_.left_, screenBounds.rect_.top_,
229         screenBounds.rect_.width_, screenBounds.rect_.height_ };
230     float density = GetDensityInCurrentResolution();
231     if (rsWindow->GetClassType() == "RootScene") {
232         auto rootScene = static_cast<Rosen::RootScene*>(rsWindow.GetRefPtr());
233         CHECK_NULL_RETURN(rootScene, false);
234         rootScene->SetDisplayDensity(density);
235         int32_t orientation = static_cast<int32_t>(screenSession_->GetScreenProperty().GetDisplayOrientation());
236         rootScene->SetDisplayOrientation(orientation);
237         rootScene->UpdateViewportConfig(rect, Rosen::WindowSizeChangeReason::UNDEFINED);
238     } else if (rsWindow->GetClassType() == "ScreenScene") {
239         auto screenScene = static_cast<Rosen::ScreenScene*>(rsWindow.GetRefPtr());
240         CHECK_NULL_RETURN(screenScene, false);
241         screenScene->SetDisplayDensity(density);
242         int32_t orientation = static_cast<int32_t>(screenSession_->GetScreenProperty().GetDisplayOrientation());
243         screenScene->SetDisplayOrientation(orientation);
244         screenScene->UpdateViewportConfig(rect, Rosen::WindowSizeChangeReason::UNDEFINED);
245     } else {
246         LOGE("others type");
247     }
248     return true;
249 }
250 
GetDensityInCurrentResolution()251 float ScreenPattern::GetDensityInCurrentResolution()
252 {
253     sptr<Rosen::Screen> screen = Rosen::ScreenManager::GetInstance().GetScreenById(screenSession_->GetScreenId());
254     float density = screenSession_->GetScreenProperty().GetDefaultDensity();
255     if (screen != nullptr) {
256         screen->GetDensityInCurResolution(density);
257     }
258     return density;
259 }
260 
GetWindowPatternType() const261 uint32_t ScreenPattern::GetWindowPatternType() const
262 {
263     return static_cast<uint32_t>(WindowPatternType::SCREEN_SCENE);
264 }
265 } // namespace OHOS::Ace::NG
266