• 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 "session/screen/include/screen_session.h"
17 #include <hisysevent.h>
18 
19 #include <hitrace_meter.h>
20 #include <surface_capture_future.h>
21 #include <transaction/rs_interfaces.h>
22 #include <transaction/rs_transaction.h>
23 #include "window_manager_hilog.h"
24 #include "dm_common.h"
25 #include "dms_xcollie.h"
26 #include "fold_screen_state_internel.h"
27 #include <parameters.h>
28 
29 namespace OHOS::Rosen {
30 namespace {
31 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "ScreenSession" };
32 static const int32_t g_screenRotationOffSet = system::GetIntParameter<int32_t>("const.fold.screen_rotation.offset", 0);
33 static const int32_t ROTATION_90 = 1;
34 static const int32_t ROTATION_270 = 3;
35 const unsigned int XCOLLIE_TIMEOUT_5S = 5;
36 }
37 
ScreenSession(const ScreenSessionConfig & config,ScreenSessionReason reason)38 ScreenSession::ScreenSession(const ScreenSessionConfig& config, ScreenSessionReason reason)
39     : name_(config.name), screenId_(config.screenId), rsId_(config.rsId), defaultScreenId_(config.defaultScreenId),
40     property_(config.property), displayNode_(config.displayNode)
41 {
42     TLOGI(WmsLogTag::DMS,
43         "[DPNODE]Create Session, reason: %{public}d, screenId: %{public}" PRIu64", rsId: %{public}" PRIu64"",
44         reason, screenId_, rsId_);
45     TLOGI(WmsLogTag::DMS,
46         "[DPNODE]Config name: %{public}s, defaultId: %{public}" PRIu64", mirrorNodeId: %{public}" PRIu64"",
47         name_.c_str(), defaultScreenId_, config.mirrorNodeId);
48     Rosen::RSDisplayNodeConfig rsConfig;
49     bool isNeedCreateDisplayNode = true;
50     switch (reason) {
51         case ScreenSessionReason::CREATE_SESSION_FOR_CLIENT: {
52             TLOGI(WmsLogTag::DMS, "create screen session for client. noting to do.");
53             return;
54         }
55         case ScreenSessionReason::CREATE_SESSION_FOR_VIRTUAL: {
56             // create virtual screen should use rsid
57             rsConfig.screenId = rsId_;
58             break;
59         }
60         case ScreenSessionReason::CREATE_SESSION_FOR_MIRROR: {
61             rsConfig.screenId = screenId_;
62             rsConfig.isMirrored = true;
63             rsConfig.mirrorNodeId = config.mirrorNodeId;
64             rsConfig.isSync = true;
65             break;
66         }
67         case ScreenSessionReason::CREATE_SESSION_FOR_REAL: {
68             rsConfig.screenId = screenId_;
69             break;
70         }
71         case ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE: {
72             TLOGI(WmsLogTag::DMS, "screen session no need create displayNode.");
73             isNeedCreateDisplayNode = false;
74             break;
75         }
76         default : {
77             TLOGE(WmsLogTag::DMS, "INVALID invalid screen session config.");
78             break;
79         }
80     }
81     if (isNeedCreateDisplayNode) {
82         CreateDisplayNode(rsConfig);
83     }
84 }
85 
CreateDisplayNode(const Rosen::RSDisplayNodeConfig & config)86 void ScreenSession::CreateDisplayNode(const Rosen::RSDisplayNodeConfig& config)
87 {
88     TLOGI(WmsLogTag::DMS,
89         "[DPNODE]config screenId: %{public}" PRIu64", mirrorNodeId: %{public}" PRIu64", isMirrored: %{public}d",
90         config.screenId, config.mirrorNodeId, static_cast<int32_t>(config.isMirrored));
91     {
92         std::unique_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
93         displayNode_ = Rosen::RSDisplayNode::Create(config);
94         if (displayNode_) {
95             displayNode_->SetFrame(property_.GetBounds().rect_.left_, property_.GetBounds().rect_.top_,
96                 property_.GetBounds().rect_.width_, property_.GetBounds().rect_.height_);
97             displayNode_->SetBounds(property_.GetBounds().rect_.left_, property_.GetBounds().rect_.top_,
98                 property_.GetBounds().rect_.width_, property_.GetBounds().rect_.height_);
99         } else {
100             TLOGE(WmsLogTag::DMS, "Failed to create displayNode, displayNode is null!");
101         }
102     }
103     RSTransaction::FlushImplicitTransaction();
104 }
105 
ScreenSession(ScreenId screenId,ScreenId rsId,const std::string & name,const ScreenProperty & property,const std::shared_ptr<RSDisplayNode> & displayNode)106 ScreenSession::ScreenSession(ScreenId screenId, ScreenId rsId, const std::string& name,
107     const ScreenProperty& property, const std::shared_ptr<RSDisplayNode>& displayNode)
108     : name_(name), screenId_(screenId), rsId_(rsId), property_(property), displayNode_(displayNode)
109 {
110     WLOGFI("Success to create screenSession in constructor_0, screenid is %{public}" PRIu64"", screenId_);
111 }
112 
ScreenSession(ScreenId screenId,const ScreenProperty & property,ScreenId defaultScreenId)113 ScreenSession::ScreenSession(ScreenId screenId, const ScreenProperty& property, ScreenId defaultScreenId)
114     : screenId_(screenId), defaultScreenId_(defaultScreenId), property_(property)
115 {
116     Rosen::RSDisplayNodeConfig config = { .screenId = screenId_ };
117     displayNode_ = Rosen::RSDisplayNode::Create(config);
118     if (displayNode_) {
119         WLOGI("Success to create displayNode in constructor_1, screenid is %{public}" PRIu64"", screenId_);
120         displayNode_->SetFrame(property_.GetBounds().rect_.left_, property_.GetBounds().rect_.top_,
121             property_.GetBounds().rect_.width_, property_.GetBounds().rect_.height_);
122         displayNode_->SetBounds(property_.GetBounds().rect_.left_, property_.GetBounds().rect_.top_,
123             property_.GetBounds().rect_.width_, property_.GetBounds().rect_.height_);
124     } else {
125         WLOGFE("Failed to create displayNode, displayNode is null!");
126     }
127     RSTransaction::FlushImplicitTransaction();
128 }
129 
ScreenSession(ScreenId screenId,const ScreenProperty & property,NodeId nodeId,ScreenId defaultScreenId)130 ScreenSession::ScreenSession(ScreenId screenId, const ScreenProperty& property,
131     NodeId nodeId, ScreenId defaultScreenId)
132     : screenId_(screenId), defaultScreenId_(defaultScreenId), property_(property)
133 {
134     rsId_ = screenId;
135     Rosen::RSDisplayNodeConfig config = { .screenId = screenId_, .isMirrored = true, .mirrorNodeId = nodeId,
136         .isSync = true};
137     displayNode_ = Rosen::RSDisplayNode::Create(config);
138     if (displayNode_) {
139         WLOGI("Success to create displayNode in constructor_2, screenid is %{public}" PRIu64"", screenId_);
140         displayNode_->SetFrame(property_.GetBounds().rect_.left_, property_.GetBounds().rect_.top_,
141             property_.GetBounds().rect_.width_, property_.GetBounds().rect_.height_);
142         displayNode_->SetBounds(property_.GetBounds().rect_.left_, property_.GetBounds().rect_.top_,
143             property_.GetBounds().rect_.width_, property_.GetBounds().rect_.height_);
144     } else {
145         WLOGFE("Failed to create displayNode, displayNode is null!");
146     }
147     RSTransaction::FlushImplicitTransaction();
148 }
149 
ScreenSession(const std::string & name,ScreenId smsId,ScreenId rsId,ScreenId defaultScreenId)150 ScreenSession::ScreenSession(const std::string& name, ScreenId smsId, ScreenId rsId, ScreenId defaultScreenId)
151     : name_(name), screenId_(smsId), rsId_(rsId), defaultScreenId_(defaultScreenId)
152 {
153     (void)rsId_;
154     // 虚拟屏的screen id和rs id不一致,displayNode的创建应使用rs id
155     Rosen::RSDisplayNodeConfig config = { .screenId = rsId_ };
156     displayNode_ = Rosen::RSDisplayNode::Create(config);
157     if (displayNode_) {
158         WLOGI("Success to create displayNode in constructor_3, rs id is %{public}" PRIu64"", rsId_);
159         displayNode_->SetFrame(property_.GetBounds().rect_.left_, property_.GetBounds().rect_.top_,
160             property_.GetBounds().rect_.width_, property_.GetBounds().rect_.height_);
161         displayNode_->SetBounds(property_.GetBounds().rect_.left_, property_.GetBounds().rect_.top_,
162             property_.GetBounds().rect_.width_, property_.GetBounds().rect_.height_);
163     } else {
164         WLOGFE("Failed to create displayNode, displayNode is null!");
165     }
166     RSTransaction::FlushImplicitTransaction();
167 }
168 
SetMirrorScreenType(MirrorScreenType mirrorType)169 void ScreenSession::SetMirrorScreenType(MirrorScreenType mirrorType)
170 {
171     mirrorScreenType_ = mirrorType;
172 }
173 
GetMirrorScreenType()174 MirrorScreenType ScreenSession::GetMirrorScreenType()
175 {
176     return mirrorScreenType_;
177 }
178 
SetDisplayNodeScreenId(ScreenId screenId)179 void ScreenSession::SetDisplayNodeScreenId(ScreenId screenId)
180 {
181     std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
182     if (displayNode_ != nullptr) {
183         WLOGFI("SetDisplayNodeScreenId %{public}" PRIu64"", screenId);
184         displayNode_->SetScreenId(screenId);
185     }
186 }
187 
RegisterScreenChangeListener(IScreenChangeListener * screenChangeListener)188 void ScreenSession::RegisterScreenChangeListener(IScreenChangeListener* screenChangeListener)
189 {
190     if (screenChangeListener == nullptr) {
191         WLOGFE("Failed to register screen change listener, listener is null!");
192         return;
193     }
194 
195     if (std::find(screenChangeListenerList_.begin(), screenChangeListenerList_.end(), screenChangeListener) !=
196         screenChangeListenerList_.end()) {
197         WLOGFI("Repeat to register screen change listener!");
198         return;
199     }
200 
201     screenChangeListenerList_.emplace_back(screenChangeListener);
202     if (screenState_ == ScreenState::CONNECTION) {
203         screenChangeListener->OnConnect(screenId_);
204         WLOGFI("Success to call onconnect callback.");
205     }
206     WLOGFI("Success to register screen change listener.");
207 }
208 
UnregisterScreenChangeListener(IScreenChangeListener * screenChangeListener)209 void ScreenSession::UnregisterScreenChangeListener(IScreenChangeListener* screenChangeListener)
210 {
211     if (screenChangeListener == nullptr) {
212         WLOGFE("Failed to unregister screen change listener, listener is null!");
213         return;
214     }
215 
216     screenChangeListenerList_.erase(
217         std::remove_if(screenChangeListenerList_.begin(), screenChangeListenerList_.end(),
218             [screenChangeListener](IScreenChangeListener* listener) { return screenChangeListener == listener; }),
219         screenChangeListenerList_.end());
220 }
221 
ConvertToDisplayInfo()222 sptr<DisplayInfo> ScreenSession::ConvertToDisplayInfo()
223 {
224     sptr<DisplayInfo> displayInfo = new(std::nothrow) DisplayInfo();
225     if (displayInfo == nullptr) {
226         return displayInfo;
227     }
228     displayInfo->name_ = name_;
229     displayInfo->SetWidth(property_.GetBounds().rect_.GetWidth());
230     displayInfo->SetHeight(property_.GetBounds().rect_.GetHeight());
231     displayInfo->SetPhysicalWidth(property_.GetPhyBounds().rect_.GetWidth());
232     displayInfo->SetPhysicalHeight(property_.GetPhyBounds().rect_.GetHeight());
233     displayInfo->SetScreenId(screenId_);
234     displayInfo->SetDisplayId(screenId_);
235     displayInfo->SetRefreshRate(property_.GetRefreshRate());
236     displayInfo->SetVirtualPixelRatio(property_.GetVirtualPixelRatio());
237     displayInfo->SetDensityInCurResolution(property_.GetDensityInCurResolution());
238     displayInfo->SetDefaultVirtualPixelRatio(property_.GetDefaultDensity());
239     displayInfo->SetXDpi(property_.GetXDpi());
240     displayInfo->SetYDpi(property_.GetYDpi());
241     displayInfo->SetDpi(property_.GetVirtualPixelRatio() * DOT_PER_INCH);
242     displayInfo->SetRotation(property_.GetScreenRotation());
243     displayInfo->SetOrientation(property_.GetOrientation());
244     displayInfo->SetOffsetX(property_.GetOffsetX());
245     displayInfo->SetOffsetY(property_.GetOffsetY());
246     displayInfo->SetDisplayOrientation(property_.GetDisplayOrientation());
247     displayInfo->SetHdrFormats(hdrFormats_);
248     displayInfo->SetColorSpaces(colorSpaces_);
249     displayInfo->SetDisplayState(property_.GetDisplayState());
250     displayInfo->SetDefaultDeviceRotationOffset(property_.GetDefaultDeviceRotationOffset());
251     displayInfo->SetAvailableWidth(property_.GetAvailableArea().width_);
252     displayInfo->SetAvailableHeight(property_.GetAvailableArea().height_);
253     displayInfo->SetScaleX(property_.GetScaleX());
254     displayInfo->SetScaleY(property_.GetScaleY());
255     displayInfo->SetPivotX(property_.GetPivotX());
256     displayInfo->SetPivotY(property_.GetPivotY());
257     displayInfo->SetTranslateX(property_.GetTranslateX());
258     displayInfo->SetTranslateY(property_.GetTranslateY());
259     return displayInfo;
260 }
261 
GetScreenSupportedColorGamuts(std::vector<ScreenColorGamut> & colorGamuts)262 DMError ScreenSession::GetScreenSupportedColorGamuts(std::vector<ScreenColorGamut>& colorGamuts)
263 {
264     auto ret = RSInterfaces::GetInstance().GetScreenSupportedColorGamuts(rsId_, colorGamuts);
265     if (ret != StatusCode::SUCCESS) {
266         WLOGE("SCB: ScreenSession::GetScreenSupportedColorGamuts fail! rsId %{public}" PRIu64", ret:%{public}d",
267             rsId_, ret);
268         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
269     }
270     WLOGI("SCB: ScreenSession::GetScreenSupportedColorGamuts ok! rsId %{public}" PRIu64", size %{public}u",
271         rsId_, static_cast<uint32_t>(colorGamuts.size()));
272 
273     return DMError::DM_OK;
274 }
275 
GetName()276 std::string ScreenSession::GetName()
277 {
278     return name_;
279 }
280 
SetName(std::string name)281 void ScreenSession::SetName(std::string name)
282 {
283     name_ = name;
284 }
285 
GetScreenId()286 ScreenId ScreenSession::GetScreenId()
287 {
288     return screenId_;
289 }
290 
GetRSScreenId()291 ScreenId ScreenSession::GetRSScreenId()
292 {
293     return rsId_;
294 }
295 
GetScreenProperty() const296 ScreenProperty ScreenSession::GetScreenProperty() const
297 {
298     return property_;
299 }
300 
SetScreenScale(float scaleX,float scaleY,float pivotX,float pivotY,float translateX,float translateY)301 void ScreenSession::SetScreenScale(float scaleX, float scaleY, float pivotX, float pivotY, float translateX,
302                                    float translateY)
303 {
304     property_.SetScaleX(scaleX);
305     property_.SetScaleY(scaleY);
306     property_.SetPivotX(pivotX);
307     property_.SetPivotY(pivotY);
308     property_.SetTranslateX(translateX);
309     property_.SetTranslateY(translateY);
310 }
311 
SetDefaultDeviceRotationOffset(uint32_t defaultRotationOffset)312 void ScreenSession::SetDefaultDeviceRotationOffset(uint32_t defaultRotationOffset)
313 {
314     WLOGFI("set device default rotation offset: %{public}u", defaultRotationOffset);
315     property_.SetDefaultDeviceRotationOffset(defaultRotationOffset);
316 }
317 
UpdatePropertyByActiveMode()318 void ScreenSession::UpdatePropertyByActiveMode()
319 {
320     sptr<SupportedScreenModes> mode = GetActiveScreenMode();
321     if (mode != nullptr) {
322         auto screeBounds = property_.GetBounds();
323         screeBounds.rect_.width_ = mode->width_;
324         screeBounds.rect_.height_ = mode->height_;
325         property_.SetBounds(screeBounds);
326     }
327 }
328 
UpdatePropertyByFoldControl(const ScreenProperty & updatedProperty)329 void ScreenSession::UpdatePropertyByFoldControl(const ScreenProperty& updatedProperty)
330 {
331     property_.SetDpiPhyBounds(updatedProperty.GetPhyWidth(), updatedProperty.GetPhyHeight());
332     property_.SetBounds(updatedProperty.GetBounds());
333     property_.SetPhyBounds(updatedProperty.GetPhyBounds());
334 }
335 
UpdateDisplayState(DisplayState displayState)336 void ScreenSession::UpdateDisplayState(DisplayState displayState)
337 {
338     property_.SetDisplayState(displayState);
339 }
340 
UpdateRefreshRate(uint32_t refreshRate)341 void ScreenSession::UpdateRefreshRate(uint32_t refreshRate)
342 {
343     property_.SetRefreshRate(refreshRate);
344 }
345 
GetRefreshRate()346 uint32_t ScreenSession::GetRefreshRate()
347 {
348     return property_.GetRefreshRate();
349 }
350 
UpdatePropertyByResolution(uint32_t width,uint32_t height)351 void ScreenSession::UpdatePropertyByResolution(uint32_t width, uint32_t height)
352 {
353     auto screenBounds = property_.GetBounds();
354     screenBounds.rect_.width_ = width;
355     screenBounds.rect_.height_ = height;
356     property_.SetBounds(screenBounds);
357 }
358 
GetDisplayNode() const359 std::shared_ptr<RSDisplayNode> ScreenSession::GetDisplayNode() const
360 {
361     std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
362     return displayNode_;
363 }
364 
ReleaseDisplayNode()365 void ScreenSession::ReleaseDisplayNode()
366 {
367     std::unique_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
368     displayNode_ = nullptr;
369     WLOGFI("displayNode_ is released.");
370 }
371 
Connect()372 void ScreenSession::Connect()
373 {
374     screenState_ = ScreenState::CONNECTION;
375     if (screenChangeListenerList_.empty()) {
376         WLOGFE("screenChangeListenerList is empty.");
377         return;
378     }
379     for (auto& listener : screenChangeListenerList_) {
380         listener->OnConnect(screenId_);
381     }
382 }
383 
Disconnect()384 void ScreenSession::Disconnect()
385 {
386     screenState_ = ScreenState::DISCONNECTION;
387     for (auto& listener : screenChangeListenerList_) {
388         if (!listener) {
389             continue;
390         }
391         listener->OnDisconnect(screenId_);
392     }
393 }
394 
PropertyChange(const ScreenProperty & newProperty,ScreenPropertyChangeReason reason)395 void ScreenSession::PropertyChange(const ScreenProperty& newProperty, ScreenPropertyChangeReason reason)
396 {
397     property_ = newProperty;
398     for (auto& listener : screenChangeListenerList_) {
399         if (!listener) {
400             continue;
401         }
402         listener->OnPropertyChange(newProperty, reason, screenId_);
403     }
404 }
405 
PowerStatusChange(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)406 void ScreenSession::PowerStatusChange(DisplayPowerEvent event, EventStatus status, PowerStateChangeReason reason)
407 {
408     for (auto& listener : screenChangeListenerList_) {
409         if (!listener) {
410             continue;
411         }
412         listener->OnPowerStatusChange(event, status, reason);
413     }
414 }
415 
ConvertRotationToFloat(Rotation sensorRotation)416 float ScreenSession::ConvertRotationToFloat(Rotation sensorRotation)
417 {
418     float rotation = 0.f;
419     switch (sensorRotation) {
420         case Rotation::ROTATION_90:
421             rotation = 90.f; // degree 90
422             break;
423         case Rotation::ROTATION_180:
424             rotation = 180.f; // degree 180
425             break;
426         case Rotation::ROTATION_270:
427             rotation = 270.f; // degree 270
428             break;
429         default:
430             rotation = 0.f;
431             break;
432     }
433     return rotation;
434 }
435 
HandleSensorRotation(float sensorRotation)436 void ScreenSession::HandleSensorRotation(float sensorRotation)
437 {
438     SensorRotationChange(sensorRotation);
439 }
440 
SensorRotationChange(Rotation sensorRotation)441 void ScreenSession::SensorRotationChange(Rotation sensorRotation)
442 {
443     float rotation = ConvertRotationToFloat(sensorRotation);
444     SensorRotationChange(rotation);
445 }
446 
SensorRotationChange(float sensorRotation)447 void ScreenSession::SensorRotationChange(float sensorRotation)
448 {
449     if (sensorRotation >= 0.0f) {
450         currentSensorRotation_ = sensorRotation;
451     }
452     for (auto& listener : screenChangeListenerList_) {
453         listener->OnSensorRotationChange(sensorRotation, screenId_);
454     }
455 }
456 
ScreenOrientationChange(Orientation orientation,FoldDisplayMode foldDisplayMode)457 void ScreenSession::ScreenOrientationChange(Orientation orientation, FoldDisplayMode foldDisplayMode)
458 {
459     Rotation rotationAfter = CalcRotation(orientation, foldDisplayMode);
460     float screenRotation = ConvertRotationToFloat(rotationAfter);
461     ScreenOrientationChange(screenRotation);
462 }
463 
ScreenOrientationChange(float orientation)464 void ScreenSession::ScreenOrientationChange(float orientation)
465 {
466     for (auto& listener : screenChangeListenerList_) {
467         listener->OnScreenOrientationChange(orientation, screenId_);
468     }
469 }
470 
ConvertIntToRotation(int rotation)471 Rotation ScreenSession::ConvertIntToRotation(int rotation)
472 {
473     Rotation targetRotation = Rotation::ROTATION_0;
474     switch (rotation) {
475         case 90: // Rotation 90 degree
476             targetRotation = Rotation::ROTATION_90;
477             break;
478         case 180: // Rotation 180 degree
479             targetRotation = Rotation::ROTATION_180;
480             break;
481         case 270: // Rotation 270 degree
482             targetRotation = Rotation::ROTATION_270;
483             break;
484         default:
485             targetRotation = Rotation::ROTATION_0;
486             break;
487     }
488     return targetRotation;
489 }
490 
SetUpdateToInputManagerCallback(std::function<void (float)> updateToInputManagerCallback)491 void ScreenSession::SetUpdateToInputManagerCallback(std::function<void(float)> updateToInputManagerCallback)
492 {
493     updateToInputManagerCallback_ = updateToInputManagerCallback;
494 }
495 
SetUpdateScreenPivotCallback(std::function<void (float,float)> && updateScreenPivotCallback)496 void ScreenSession::SetUpdateScreenPivotCallback(std::function<void(float, float)>&& updateScreenPivotCallback)
497 {
498     updateScreenPivotCallback_ = std::move(updateScreenPivotCallback);
499 }
500 
GetVirtualScreenFlag()501 VirtualScreenFlag ScreenSession::GetVirtualScreenFlag()
502 {
503     return screenFlag_;
504 }
505 
SetVirtualScreenFlag(VirtualScreenFlag screenFlag)506 void ScreenSession::SetVirtualScreenFlag(VirtualScreenFlag screenFlag)
507 {
508     screenFlag_ = screenFlag;
509 }
510 
UpdateToInputManager(RRect bounds,int rotation,FoldDisplayMode foldDisplayMode)511 void ScreenSession::UpdateToInputManager(RRect bounds, int rotation, FoldDisplayMode foldDisplayMode)
512 {
513     bool needUpdateToInputManager = false;
514     if (foldDisplayMode == FoldDisplayMode::FULL && g_screenRotationOffSet == ROTATION_270 &&
515         property_.GetBounds() == bounds && property_.GetRotation() != static_cast<float>(rotation)) {
516         needUpdateToInputManager = true;
517     }
518     Rotation targetRotation = ConvertIntToRotation(rotation);
519     DisplayOrientation displayOrientation = CalcDisplayOrientation(targetRotation, foldDisplayMode);
520     property_.SetBounds(bounds);
521     property_.SetRotation(static_cast<float>(rotation));
522     property_.UpdateScreenRotation(targetRotation);
523     property_.SetDisplayOrientation(displayOrientation);
524     if (needUpdateToInputManager && updateToInputManagerCallback_ != nullptr) {
525         // fold phone need fix 90 degree by remainder 360 degree
526         int foldRotation = (rotation + 90) % 360;
527         updateToInputManagerCallback_(static_cast<float>(foldRotation));
528         WLOGFI("updateToInputManagerCallback_:%{public}d", foldRotation);
529     }
530 }
531 
UpdatePropertyAfterRotation(RRect bounds,int rotation,FoldDisplayMode foldDisplayMode)532 void ScreenSession::UpdatePropertyAfterRotation(RRect bounds, int rotation, FoldDisplayMode foldDisplayMode)
533 {
534     Rotation targetRotation = ConvertIntToRotation(rotation);
535     DisplayOrientation displayOrientation = CalcDisplayOrientation(targetRotation, foldDisplayMode);
536     property_.SetBounds(bounds);
537     property_.SetRotation(static_cast<float>(rotation));
538     property_.UpdateScreenRotation(targetRotation);
539     property_.SetDisplayOrientation(displayOrientation);
540     {
541         std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
542         if (!displayNode_) {
543             WLOGFI("update failed since null display node with rotation:%{public}d displayOrientation:%{public}u",
544                 rotation, displayOrientation);
545             return;
546         }
547     }
548     auto transactionProxy = RSTransactionProxy::GetInstance();
549     if (transactionProxy != nullptr) {
550         transactionProxy->Begin();
551         {
552             std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
553             displayNode_->SetScreenRotation(static_cast<uint32_t>(targetRotation));
554         }
555         transactionProxy->Commit();
556     } else {
557         {
558             std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
559             displayNode_->SetScreenRotation(static_cast<uint32_t>(targetRotation));
560         }
561     }
562     WLOGFI("bounds:[%{public}f %{public}f %{public}f %{public}f],rotation:%{public}d,displayOrientation:%{public}u",
563         property_.GetBounds().rect_.GetLeft(), property_.GetBounds().rect_.GetTop(),
564         property_.GetBounds().rect_.GetWidth(), property_.GetBounds().rect_.GetHeight(),
565         rotation, displayOrientation);
566     ReportNotifyModeChange(displayOrientation);
567 }
568 
UpdatePropertyOnly(RRect bounds,int rotation,FoldDisplayMode foldDisplayMode)569 void ScreenSession::UpdatePropertyOnly(RRect bounds, int rotation, FoldDisplayMode foldDisplayMode)
570 {
571     Rotation targetRotation = ConvertIntToRotation(rotation);
572     DisplayOrientation displayOrientation = CalcDisplayOrientation(targetRotation, foldDisplayMode);
573     property_.SetBounds(bounds);
574     property_.SetRotation(static_cast<float>(rotation));
575     property_.UpdateScreenRotation(targetRotation);
576     property_.SetDisplayOrientation(displayOrientation);
577     WLOGFI("bounds:[%{public}f %{public}f %{public}f %{public}f],rotation:%{public}d,displayOrientation:%{public}u",
578         property_.GetBounds().rect_.GetLeft(), property_.GetBounds().rect_.GetTop(),
579         property_.GetBounds().rect_.GetWidth(), property_.GetBounds().rect_.GetHeight(),
580         rotation, displayOrientation);
581 }
582 
ReportNotifyModeChange(DisplayOrientation displayOrientation)583 void ScreenSession::ReportNotifyModeChange(DisplayOrientation displayOrientation)
584 {
585     int32_t vhMode = 1;
586     if (displayOrientation == DisplayOrientation::PORTRAIT_INVERTED ||
587         displayOrientation == DisplayOrientation::PORTRAIT) {
588         vhMode = 0;
589     }
590     int32_t ret = HiSysEventWrite(
591         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
592         "VH_MODE",
593         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
594         "MODE", vhMode);
595     if (ret != 0) {
596         TLOGE(WmsLogTag::DMS, "ReportNotifyModeChange Write HiSysEvent error, ret: %{public}d", ret);
597     }
598 }
599 
UpdateRotationAfterBoot(bool foldToExpand)600 void ScreenSession::UpdateRotationAfterBoot(bool foldToExpand)
601 {
602     TLOGI(WmsLogTag::DMS, "foldToExpand: %{public}d, Rotation: %{public}f",
603         static_cast<int32_t>(foldToExpand), currentSensorRotation_);
604     if (foldToExpand) {
605         SensorRotationChange(currentSensorRotation_);
606     }
607 }
608 
GetActiveScreenMode() const609 sptr<SupportedScreenModes> ScreenSession::GetActiveScreenMode() const
610 {
611     if (activeIdx_ < 0 || activeIdx_ >= static_cast<int32_t>(modes_.size())) {
612         WLOGW("SCB: ScreenSession::GetActiveScreenMode active mode index is wrong: %{public}d", activeIdx_);
613         return nullptr;
614     }
615     return modes_[activeIdx_];
616 }
617 
GetOrientation() const618 Orientation ScreenSession::GetOrientation() const
619 {
620     return property_.GetOrientation();
621 }
622 
SetOrientation(Orientation orientation)623 void ScreenSession::SetOrientation(Orientation orientation)
624 {
625     property_.SetOrientation(orientation);
626 }
627 
GetRotation() const628 Rotation ScreenSession::GetRotation() const
629 {
630     return property_.GetScreenRotation();
631 }
632 
SetRotation(Rotation rotation)633 void ScreenSession::SetRotation(Rotation rotation)
634 {
635     property_.SetScreenRotation(rotation);
636 }
637 
SetRotationAndScreenRotationOnly(Rotation rotation)638 void ScreenSession::SetRotationAndScreenRotationOnly(Rotation rotation)
639 {
640     property_.SetRotationAndScreenRotationOnly(rotation);
641 }
642 
SetScreenRequestedOrientation(Orientation orientation)643 void ScreenSession::SetScreenRequestedOrientation(Orientation orientation)
644 {
645     property_.SetScreenRequestedOrientation(orientation);
646 }
647 
SetScreenRotationLocked(bool isLocked)648 void ScreenSession::SetScreenRotationLocked(bool isLocked)
649 {
650     isScreenLocked_ = isLocked;
651     for (auto& listener : screenChangeListenerList_) {
652         if (!listener) {
653             continue;
654         }
655         listener->OnScreenRotationLockedChange(isLocked, screenId_);
656     }
657 }
658 
SetScreenRotationLockedFromJs(bool isLocked)659 void ScreenSession::SetScreenRotationLockedFromJs(bool isLocked)
660 {
661     isScreenLocked_ = isLocked;
662 }
663 
IsScreenRotationLocked()664 bool ScreenSession::IsScreenRotationLocked()
665 {
666     return isScreenLocked_;
667 }
668 
SetTouchEnabledFromJs(bool isTouchEnabled)669 void ScreenSession::SetTouchEnabledFromJs(bool isTouchEnabled)
670 {
671     TLOGI(WmsLogTag::WMS_EVENT, "isTouchEnabled:%{public}u", static_cast<uint32_t>(isTouchEnabled));
672     touchEnabled_.store(isTouchEnabled);
673 }
674 
IsTouchEnabled()675 bool ScreenSession::IsTouchEnabled()
676 {
677     return touchEnabled_.load();
678 }
679 
GetScreenRequestedOrientation() const680 Orientation ScreenSession::GetScreenRequestedOrientation() const
681 {
682     return property_.GetScreenRequestedOrientation();
683 }
684 
SetVirtualPixelRatio(float virtualPixelRatio)685 void ScreenSession::SetVirtualPixelRatio(float virtualPixelRatio)
686 {
687     property_.SetVirtualPixelRatio(virtualPixelRatio);
688 }
689 
SetScreenSceneDpiChangeListener(const SetScreenSceneDpiFunc & func)690 void ScreenSession::SetScreenSceneDpiChangeListener(const SetScreenSceneDpiFunc& func)
691 {
692     SetScreenSceneDpiCallback_ = func;
693     TLOGI(WmsLogTag::DMS, "SetScreenSceneDpiChangeListener");
694 }
695 
SetScreenSceneDpi(float density)696 void ScreenSession::SetScreenSceneDpi(float density)
697 {
698     if (SetScreenSceneDpiCallback_ == nullptr) {
699         TLOGI(WmsLogTag::DMS, "SetScreenSceneDpiCallback_ is nullptr");
700         return;
701     }
702     SetScreenSceneDpiCallback_(density);
703 }
704 
SetScreenSceneDestroyListener(const DestroyScreenSceneFunc & func)705 void ScreenSession::SetScreenSceneDestroyListener(const DestroyScreenSceneFunc& func)
706 {
707     destroyScreenSceneCallback_ = func;
708     TLOGI(WmsLogTag::DMS, "SetScreenSceneDestroyListener");
709 }
710 
DestroyScreenScene()711 void ScreenSession::DestroyScreenScene()
712 {
713     if (destroyScreenSceneCallback_ == nullptr) {
714         TLOGI(WmsLogTag::DMS, "destroyScreenSceneCallback_ is nullptr");
715         return;
716     }
717     destroyScreenSceneCallback_();
718 }
719 
SetDensityInCurResolution(float densityInCurResolution)720 void ScreenSession::SetDensityInCurResolution(float densityInCurResolution)
721 {
722     property_.SetDensityInCurResolution(densityInCurResolution);
723 }
724 
SetScreenType(ScreenType type)725 void ScreenSession::SetScreenType(ScreenType type)
726 {
727     property_.SetScreenType(type);
728 }
729 
CalcRotation(Orientation orientation,FoldDisplayMode foldDisplayMode) const730 Rotation ScreenSession::CalcRotation(Orientation orientation, FoldDisplayMode foldDisplayMode) const
731 {
732     sptr<SupportedScreenModes> info = GetActiveScreenMode();
733     if (info == nullptr) {
734         return Rotation::ROTATION_0;
735     }
736     // vertical: phone(Plugin screen); horizontal: pad & external screen
737     bool isVerticalScreen = info->width_ < info->height_;
738     if (foldDisplayMode != FoldDisplayMode::UNKNOWN &&
739         (g_screenRotationOffSet == ROTATION_90 || g_screenRotationOffSet == ROTATION_270)) {
740         isVerticalScreen = info->width_ > info->height_;
741     }
742     switch (orientation) {
743         case Orientation::UNSPECIFIED: {
744             return Rotation::ROTATION_0;
745         }
746         case Orientation::VERTICAL: {
747             return isVerticalScreen ? Rotation::ROTATION_0 : Rotation::ROTATION_90;
748         }
749         case Orientation::HORIZONTAL: {
750             return isVerticalScreen ? Rotation::ROTATION_90 : Rotation::ROTATION_0;
751         }
752         case Orientation::REVERSE_VERTICAL: {
753             return isVerticalScreen ? Rotation::ROTATION_180 : Rotation::ROTATION_270;
754         }
755         case Orientation::REVERSE_HORIZONTAL: {
756             return isVerticalScreen ? Rotation::ROTATION_270 : Rotation::ROTATION_180;
757         }
758         default: {
759             WLOGE("unknown orientation %{public}u", orientation);
760             return Rotation::ROTATION_0;
761         }
762     }
763 }
764 
CalcDisplayOrientation(Rotation rotation,FoldDisplayMode foldDisplayMode) const765 DisplayOrientation ScreenSession::CalcDisplayOrientation(Rotation rotation, FoldDisplayMode foldDisplayMode) const
766 {
767     // vertical: phone(Plugin screen); horizontal: pad & external screen
768     bool isVerticalScreen = property_.GetPhyWidth() < property_.GetPhyHeight();
769     if (foldDisplayMode != FoldDisplayMode::UNKNOWN
770         && (g_screenRotationOffSet == ROTATION_90 || g_screenRotationOffSet == ROTATION_270)) {
771         WLOGD("foldDisplay is verticalScreen when width is greater than height");
772         isVerticalScreen = property_.GetPhyWidth() > property_.GetPhyHeight();
773     }
774     switch (rotation) {
775         case Rotation::ROTATION_0: {
776             return isVerticalScreen ? DisplayOrientation::PORTRAIT : DisplayOrientation::LANDSCAPE;
777         }
778         case Rotation::ROTATION_90: {
779             return isVerticalScreen ? DisplayOrientation::LANDSCAPE : DisplayOrientation::PORTRAIT;
780         }
781         case Rotation::ROTATION_180: {
782             return isVerticalScreen ? DisplayOrientation::PORTRAIT_INVERTED : DisplayOrientation::LANDSCAPE_INVERTED;
783         }
784         case Rotation::ROTATION_270: {
785             return isVerticalScreen ? DisplayOrientation::LANDSCAPE_INVERTED : DisplayOrientation::PORTRAIT_INVERTED;
786         }
787         default: {
788             WLOGE("unknown rotation %{public}u", rotation);
789             return DisplayOrientation::UNKNOWN;
790         }
791     }
792 }
793 
GetSourceMode() const794 ScreenSourceMode ScreenSession::GetSourceMode() const
795 {
796     if (screenId_ == defaultScreenId_) {
797         return ScreenSourceMode::SCREEN_MAIN;
798     }
799     ScreenCombination combination = GetScreenCombination();
800     switch (combination) {
801         case ScreenCombination::SCREEN_MIRROR: {
802             return ScreenSourceMode::SCREEN_MIRROR;
803         }
804         case ScreenCombination::SCREEN_EXPAND: {
805             return ScreenSourceMode::SCREEN_EXTEND;
806         }
807         case ScreenCombination::SCREEN_ALONE: {
808             return ScreenSourceMode::SCREEN_ALONE;
809         }
810         case ScreenCombination::SCREEN_UNIQUE: {
811             return ScreenSourceMode::SCREEN_UNIQUE;
812         }
813         default: {
814             return ScreenSourceMode::SCREEN_ALONE;
815         }
816     }
817 }
818 
SetScreenCombination(ScreenCombination combination)819 void ScreenSession::SetScreenCombination(ScreenCombination combination)
820 {
821     combination_ = combination;
822 }
823 
GetScreenCombination() const824 ScreenCombination ScreenSession::GetScreenCombination() const
825 {
826     return combination_;
827 }
828 
FillScreenInfo(sptr<ScreenInfo> info) const829 void ScreenSession::FillScreenInfo(sptr<ScreenInfo> info) const
830 {
831     if (info == nullptr) {
832         WLOGE("FillScreenInfo failed! info is nullptr");
833         return;
834     }
835     info->SetScreenId(screenId_);
836     info->SetName(name_);
837     uint32_t width = 0;
838     uint32_t height = 0;
839     sptr<SupportedScreenModes> screenSessionModes = GetActiveScreenMode();
840     if (screenSessionModes != nullptr) {
841         height = screenSessionModes->height_;
842         width = screenSessionModes->width_;
843     }
844     float virtualPixelRatio = property_.GetVirtualPixelRatio();
845     // "< 1e-set6" means virtualPixelRatio is 0.
846     if (fabsf(virtualPixelRatio) < 1e-6) {
847         virtualPixelRatio = 1.0f;
848     }
849     ScreenSourceMode sourceMode = GetSourceMode();
850     info->SetVirtualPixelRatio(property_.GetVirtualPixelRatio());
851     info->SetVirtualHeight(height / virtualPixelRatio);
852     info->SetVirtualWidth(width / virtualPixelRatio);
853     info->SetRotation(property_.GetScreenRotation());
854     info->SetOrientation(static_cast<Orientation>(property_.GetDisplayOrientation()));
855     info->SetSourceMode(sourceMode);
856     info->SetType(property_.GetScreenType());
857     info->SetModeId(activeIdx_);
858 
859     info->lastParent_ = lastGroupSmsId_;
860     info->parent_ = groupSmsId_;
861     info->isScreenGroup_ = isScreenGroup_;
862     info->modes_ = modes_;
863 }
864 
ConvertToScreenInfo() const865 sptr<ScreenInfo> ScreenSession::ConvertToScreenInfo() const
866 {
867     sptr<ScreenInfo> info = new(std::nothrow) ScreenInfo();
868     if (info == nullptr) {
869         return nullptr;
870     }
871     FillScreenInfo(info);
872     return info;
873 }
874 
GetScreenColorGamut(ScreenColorGamut & colorGamut)875 DMError ScreenSession::GetScreenColorGamut(ScreenColorGamut& colorGamut)
876 {
877     auto ret = RSInterfaces::GetInstance().GetScreenColorGamut(rsId_, colorGamut);
878     if (ret != StatusCode::SUCCESS) {
879         WLOGE("GetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_);
880         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
881     }
882     WLOGI("GetScreenColorGamut ok! rsId %{public}" PRIu64", colorGamut %{public}u",
883         rsId_, static_cast<uint32_t>(colorGamut));
884     return DMError::DM_OK;
885 }
886 
SetScreenColorGamut(int32_t colorGamutIdx)887 DMError ScreenSession::SetScreenColorGamut(int32_t colorGamutIdx)
888 {
889     std::vector<ScreenColorGamut> colorGamuts;
890     DMError res = GetScreenSupportedColorGamuts(colorGamuts);
891     if (res != DMError::DM_OK) {
892         WLOGE("SetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_);
893         return res;
894     }
895     if (colorGamutIdx < 0 || colorGamutIdx >= static_cast<int32_t>(colorGamuts.size())) {
896         WLOGE("SetScreenColorGamut fail! rsId %{public}" PRIu64" colorGamutIdx %{public}d invalid.",
897             rsId_, colorGamutIdx);
898         return DMError::DM_ERROR_INVALID_PARAM;
899     }
900     auto ret = RSInterfaces::GetInstance().SetScreenColorGamut(rsId_, colorGamutIdx);
901     if (ret != StatusCode::SUCCESS) {
902         WLOGE("SetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_);
903         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
904     }
905     WLOGI("SetScreenColorGamut ok! rsId %{public}" PRIu64", colorGamutIdx %{public}u",
906         rsId_, colorGamutIdx);
907     return DMError::DM_OK;
908 }
909 
GetScreenGamutMap(ScreenGamutMap & gamutMap)910 DMError ScreenSession::GetScreenGamutMap(ScreenGamutMap& gamutMap)
911 {
912     auto ret = RSInterfaces::GetInstance().GetScreenGamutMap(rsId_, gamutMap);
913     if (ret != StatusCode::SUCCESS) {
914         WLOGE("GetScreenGamutMap fail! rsId %{public}" PRIu64"", rsId_);
915         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
916     }
917     WLOGI("GetScreenGamutMap ok! rsId %{public}" PRIu64", gamutMap %{public}u",
918         rsId_, static_cast<uint32_t>(gamutMap));
919     return DMError::DM_OK;
920 }
921 
SetScreenGamutMap(ScreenGamutMap gamutMap)922 DMError ScreenSession::SetScreenGamutMap(ScreenGamutMap gamutMap)
923 {
924     if (gamutMap > GAMUT_MAP_HDR_EXTENSION) {
925         return DMError::DM_ERROR_INVALID_PARAM;
926     }
927     auto ret = RSInterfaces::GetInstance().SetScreenGamutMap(rsId_, gamutMap);
928     if (ret != StatusCode::SUCCESS) {
929         WLOGE("SetScreenGamutMap fail! rsId %{public}" PRIu64"", rsId_);
930         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
931     }
932     WLOGI("SetScreenGamutMap ok! rsId %{public}" PRIu64", gamutMap %{public}u",
933         rsId_, static_cast<uint32_t>(gamutMap));
934     return DMError::DM_OK;
935 }
936 
SetScreenColorTransform()937 DMError ScreenSession::SetScreenColorTransform()
938 {
939     WLOGI("SetScreenColorTransform ok! rsId %{public}" PRIu64"", rsId_);
940     return DMError::DM_OK;
941 }
942 
GetPixelFormat(GraphicPixelFormat & pixelFormat)943 DMError ScreenSession::GetPixelFormat(GraphicPixelFormat& pixelFormat)
944 {
945     auto ret = RSInterfaces::GetInstance().GetPixelFormat(rsId_, pixelFormat);
946     if (ret != StatusCode::SUCCESS) {
947         WLOGE("GetPixelFormat fail! rsId %{public}" PRIu64, rsId_);
948         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
949     }
950     WLOGI("GetPixelFormat ok! rsId %{public}" PRIu64 ", pixelFormat %{public}u",
951         rsId_, static_cast<uint32_t>(pixelFormat));
952     return DMError::DM_OK;
953 }
954 
SetPixelFormat(GraphicPixelFormat pixelFormat)955 DMError ScreenSession::SetPixelFormat(GraphicPixelFormat pixelFormat)
956 {
957     if (pixelFormat > GRAPHIC_PIXEL_FMT_VENDER_MASK) {
958         return DMError::DM_ERROR_INVALID_PARAM;
959     }
960     auto ret = RSInterfaces::GetInstance().SetPixelFormat(rsId_, pixelFormat);
961     if (ret != StatusCode::SUCCESS) {
962         WLOGE("SetPixelFormat fail! rsId %{public}" PRIu64, rsId_);
963         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
964     }
965     WLOGI("SetPixelFormat ok! rsId %{public}" PRIu64 ", gamutMap %{public}u",
966         rsId_, static_cast<uint32_t>(pixelFormat));
967     return DMError::DM_OK;
968 }
969 
GetSupportedHDRFormats(std::vector<ScreenHDRFormat> & hdrFormats)970 DMError ScreenSession::GetSupportedHDRFormats(std::vector<ScreenHDRFormat>& hdrFormats)
971 {
972     auto ret = RSInterfaces::GetInstance().GetScreenSupportedHDRFormats(rsId_, hdrFormats);
973     if (ret != StatusCode::SUCCESS) {
974         WLOGE("SCB: ScreenSession::GetSupportedHDRFormats fail! rsId %{public}" PRIu64 ", ret:%{public}d",
975             rsId_, ret);
976         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
977     }
978     WLOGI("SCB: ScreenSession::GetSupportedHDRFormats ok! rsId %{public}" PRIu64 ", size %{public}u",
979         rsId_, static_cast<uint32_t>(hdrFormats.size()));
980 
981     return DMError::DM_OK;
982 }
983 
GetScreenHDRFormat(ScreenHDRFormat & hdrFormat)984 DMError ScreenSession::GetScreenHDRFormat(ScreenHDRFormat& hdrFormat)
985 {
986     auto ret = RSInterfaces::GetInstance().GetScreenHDRFormat(rsId_, hdrFormat);
987     if (ret != StatusCode::SUCCESS) {
988         WLOGE("GetScreenHDRFormat fail! rsId %{public}" PRIu64, rsId_);
989         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
990     }
991     WLOGI("GetScreenHDRFormat ok! rsId %{public}" PRIu64 ", colorSpace %{public}u",
992         rsId_, static_cast<uint32_t>(hdrFormat));
993     return DMError::DM_OK;
994 }
995 
SetScreenHDRFormat(int32_t modeIdx)996 DMError ScreenSession::SetScreenHDRFormat(int32_t modeIdx)
997 {
998     std::vector<ScreenHDRFormat> hdrFormats;
999     DMError res = GetSupportedHDRFormats(hdrFormats);
1000     if (res != DMError::DM_OK) {
1001         WLOGE("SetScreenHDRFormat fail! rsId %{public}" PRIu64, rsId_);
1002         return res;
1003     }
1004     if (modeIdx < 0 || modeIdx >= static_cast<int32_t>(hdrFormats.size())) {
1005         WLOGE("SetScreenHDRFormat fail! rsId %{public}" PRIu64 " modeIdx %{public}d invalid.",
1006             rsId_, modeIdx);
1007         return DMError::DM_ERROR_INVALID_PARAM;
1008     }
1009     auto ret = RSInterfaces::GetInstance().SetScreenHDRFormat(rsId_, modeIdx);
1010     if (ret != StatusCode::SUCCESS) {
1011         WLOGE("SetScreenHDRFormat fail! rsId %{public}" PRIu64, rsId_);
1012         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1013     }
1014     WLOGI("SetScreenHDRFormat ok! rsId %{public}" PRIu64 ", modeIdx %{public}u",
1015         rsId_, modeIdx);
1016     return DMError::DM_OK;
1017 }
1018 
GetSupportedColorSpaces(std::vector<GraphicCM_ColorSpaceType> & colorSpaces)1019 DMError ScreenSession::GetSupportedColorSpaces(std::vector<GraphicCM_ColorSpaceType>& colorSpaces)
1020 {
1021     auto ret = RSInterfaces::GetInstance().GetScreenSupportedColorSpaces(rsId_, colorSpaces);
1022     if (ret != StatusCode::SUCCESS) {
1023         WLOGE("SCB: ScreenSession::GetSupportedColorSpaces fail! rsId %{public}" PRIu64 ", ret:%{public}d",
1024             rsId_, ret);
1025         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1026     }
1027     WLOGI("SCB: ScreenSession::GetSupportedColorSpaces ok! rsId %{public}" PRIu64 ", size %{public}u",
1028         rsId_, static_cast<uint32_t>(colorSpaces.size()));
1029     return DMError::DM_OK;
1030 }
1031 
GetScreenColorSpace(GraphicCM_ColorSpaceType & colorSpace)1032 DMError ScreenSession::GetScreenColorSpace(GraphicCM_ColorSpaceType& colorSpace)
1033 {
1034     auto ret = RSInterfaces::GetInstance().GetScreenColorSpace(rsId_, colorSpace);
1035     if (ret != StatusCode::SUCCESS) {
1036         WLOGE("GetScreenColorSpace fail! rsId %{public}" PRIu64, rsId_);
1037         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1038     }
1039     WLOGI("GetScreenColorSpace ok! rsId %{public}" PRIu64 ", colorSpace %{public}u",
1040         rsId_, static_cast<uint32_t>(colorSpace));
1041     return DMError::DM_OK;
1042 }
1043 
SetScreenColorSpace(GraphicCM_ColorSpaceType colorSpace)1044 DMError ScreenSession::SetScreenColorSpace(GraphicCM_ColorSpaceType colorSpace)
1045 {
1046     std::vector<GraphicCM_ColorSpaceType> colorSpaces;
1047     DMError res = GetSupportedColorSpaces(colorSpaces);
1048     if (res != DMError::DM_OK) {
1049         WLOGE("SetScreenColorSpace fail! rsId %{public}" PRIu64, rsId_);
1050         return res;
1051     }
1052     if (colorSpace < 0 || static_cast<int32_t>(colorSpace) >= static_cast<int32_t>(colorSpaces.size())) {
1053         WLOGE("SetScreenColorSpace fail! rsId %{public}" PRIu64 " colorSpace %{public}d invalid.",
1054             rsId_, colorSpace);
1055         return DMError::DM_ERROR_INVALID_PARAM;
1056     }
1057     auto ret = RSInterfaces::GetInstance().SetScreenColorSpace(rsId_, colorSpace);
1058     if (ret != StatusCode::SUCCESS) {
1059         WLOGE("SetScreenColorSpace fail! rsId %{public}" PRIu64, rsId_);
1060         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1061     }
1062     WLOGI("SetScreenColorSpace ok! rsId %{public}" PRIu64 ", colorSpace %{public}u",
1063         rsId_, colorSpace);
1064     return DMError::DM_OK;
1065 }
1066 
HasPrivateSessionForeground() const1067 bool ScreenSession::HasPrivateSessionForeground() const
1068 {
1069     return hasPrivateWindowForeground_;
1070 }
1071 
SetPrivateSessionForeground(bool hasPrivate)1072 void ScreenSession::SetPrivateSessionForeground(bool hasPrivate)
1073 {
1074     hasPrivateWindowForeground_ = hasPrivate;
1075 }
1076 
InitRSDisplayNode(RSDisplayNodeConfig & config,Point & startPoint)1077 void ScreenSession::InitRSDisplayNode(RSDisplayNodeConfig& config, Point& startPoint)
1078 {
1079     std::unique_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
1080     if (displayNode_ != nullptr) {
1081         displayNode_->SetDisplayNodeMirrorConfig(config);
1082         if (screenId_ == 0 && isFold_) {
1083             WLOGFI("Return InitRSDisplayNode foldScreen0");
1084             return;
1085         }
1086     } else {
1087         std::shared_ptr<RSDisplayNode> rsDisplayNode = RSDisplayNode::Create(config);
1088         if (rsDisplayNode == nullptr) {
1089             WLOGE("fail to add child. create rsDisplayNode fail!");
1090             return;
1091         }
1092         displayNode_ = rsDisplayNode;
1093     }
1094     WLOGFI("SetDisplayOffset: posX:%{public}d, posY:%{public}d", startPoint.posX_, startPoint.posY_);
1095     displayNode_->SetDisplayOffset(startPoint.posX_, startPoint.posY_);
1096     uint32_t width = 0;
1097     uint32_t height = 0;
1098     sptr<SupportedScreenModes> abstractScreenModes = GetActiveScreenMode();
1099     if (abstractScreenModes != nullptr) {
1100         height = abstractScreenModes->height_;
1101         width = abstractScreenModes->width_;
1102     }
1103     RSScreenType screenType;
1104     DmsXcollie dmsXcollie("DMS:InitRSDisplayNode:GetScreenType", XCOLLIE_TIMEOUT_5S);
1105     auto ret = RSInterfaces::GetInstance().GetScreenType(rsId_, screenType);
1106     if (ret == StatusCode::SUCCESS && screenType == RSScreenType::VIRTUAL_TYPE_SCREEN) {
1107         displayNode_->SetSecurityDisplay(true);
1108         WLOGFI("virtualScreen SetSecurityDisplay success");
1109     }
1110     // If setDisplayOffset is not valid for SetFrame/SetBounds
1111     WLOGFI("InitRSDisplayNode screenId:%{public}" PRIu64" width:%{public}u height:%{public}u",
1112         screenId_, width, height);
1113     displayNode_->SetFrame(0, 0, width, height);
1114     displayNode_->SetBounds(0, 0, width, height);
1115     auto transactionProxy = RSTransactionProxy::GetInstance();
1116     if (transactionProxy != nullptr) {
1117         transactionProxy->FlushImplicitTransaction();
1118     }
1119 }
1120 
ScreenSessionGroup(ScreenId screenId,ScreenId rsId,std::string name,ScreenCombination combination)1121 ScreenSessionGroup::ScreenSessionGroup(ScreenId screenId, ScreenId rsId,
1122     std::string name, ScreenCombination combination) : combination_(combination)
1123 {
1124     name_ = name;
1125     screenId_ = screenId;
1126     rsId_ = rsId;
1127     SetScreenType(ScreenType::UNDEFINED);
1128     isScreenGroup_ = true;
1129 }
1130 
~ScreenSessionGroup()1131 ScreenSessionGroup::~ScreenSessionGroup()
1132 {
1133     ReleaseDisplayNode();
1134     screenSessionMap_.clear();
1135 }
1136 
GetRSDisplayNodeConfig(sptr<ScreenSession> & screenSession,struct RSDisplayNodeConfig & config,sptr<ScreenSession> defaultScreenSession)1137 bool ScreenSessionGroup::GetRSDisplayNodeConfig(sptr<ScreenSession>& screenSession, struct RSDisplayNodeConfig& config,
1138                                                 sptr<ScreenSession> defaultScreenSession)
1139 {
1140     if (screenSession == nullptr) {
1141         WLOGE("screenSession is nullptr.");
1142         return false;
1143     }
1144     config = { screenSession->rsId_ };
1145     switch (combination_) {
1146         case ScreenCombination::SCREEN_ALONE:
1147             [[fallthrough]];
1148         case ScreenCombination::SCREEN_EXPAND:
1149             break;
1150         case ScreenCombination::SCREEN_UNIQUE:
1151             break;
1152         case ScreenCombination::SCREEN_MIRROR: {
1153             if (GetChildCount() == 0 || mirrorScreenId_ == screenSession->screenId_) {
1154                 WLOGI("SCREEN_MIRROR, config is not mirror");
1155                 break;
1156             }
1157             if (defaultScreenSession == nullptr) {
1158                 WLOGFE("defaultScreenSession is nullptr");
1159                 break;
1160             }
1161             std::shared_ptr<RSDisplayNode> displayNode = defaultScreenSession->GetDisplayNode();
1162             if (displayNode == nullptr) {
1163                 WLOGFE("displayNode is nullptr, cannot get DisplayNode");
1164                 break;
1165             }
1166             NodeId nodeId = displayNode->GetId();
1167             WLOGI("mirrorScreenId_:%{public}" PRIu64", rsId_:%{public}" PRIu64", nodeId:%{public}" PRIu64"",
1168                 mirrorScreenId_, screenSession->rsId_, nodeId);
1169             config = {screenSession->rsId_, true, nodeId, true};
1170             break;
1171         }
1172         default:
1173             WLOGE("fail to add child. invalid group combination:%{public}u", combination_);
1174             return false;
1175     }
1176     return true;
1177 }
1178 
AddChild(sptr<ScreenSession> & smsScreen,Point & startPoint,sptr<ScreenSession> defaultScreenSession)1179 bool ScreenSessionGroup::AddChild(sptr<ScreenSession>& smsScreen, Point& startPoint,
1180                                   sptr<ScreenSession> defaultScreenSession)
1181 {
1182     if (smsScreen == nullptr) {
1183         WLOGE("AddChild, smsScreen is nullptr.");
1184         return false;
1185     }
1186     ScreenId screenId = smsScreen->screenId_;
1187     auto iter = screenSessionMap_.find(screenId);
1188     if (iter != screenSessionMap_.end()) {
1189         WLOGE("AddChild, screenSessionMap_ has smsScreen:%{public}" PRIu64"", screenId);
1190         return false;
1191     }
1192     struct RSDisplayNodeConfig config;
1193     if (!GetRSDisplayNodeConfig(smsScreen, config, defaultScreenSession)) {
1194         return false;
1195     }
1196     smsScreen->InitRSDisplayNode(config, startPoint);
1197     smsScreen->lastGroupSmsId_ = smsScreen->groupSmsId_;
1198     smsScreen->groupSmsId_ = screenId_;
1199     screenSessionMap_.insert(std::make_pair(screenId, std::make_pair(smsScreen, startPoint)));
1200     return true;
1201 }
1202 
AddChildren(std::vector<sptr<ScreenSession>> & smsScreens,std::vector<Point> & startPoints)1203 bool ScreenSessionGroup::AddChildren(std::vector<sptr<ScreenSession>>& smsScreens, std::vector<Point>& startPoints)
1204 {
1205     size_t size = smsScreens.size();
1206     if (size != startPoints.size()) {
1207         WLOGE("AddChildren, unequal size.");
1208         return false;
1209     }
1210     bool res = true;
1211     for (size_t i = 0; i < size; i++) {
1212         res = AddChild(smsScreens[i], startPoints[i], nullptr) && res;
1213     }
1214     return res;
1215 }
1216 
RemoveChild(sptr<ScreenSession> & smsScreen)1217 bool ScreenSessionGroup::RemoveChild(sptr<ScreenSession>& smsScreen)
1218 {
1219     if (smsScreen == nullptr) {
1220         WLOGE("RemoveChild, smsScreen is nullptr.");
1221         return false;
1222     }
1223     ScreenId screenId = smsScreen->screenId_;
1224     smsScreen->lastGroupSmsId_ = smsScreen->groupSmsId_;
1225     smsScreen->groupSmsId_ = SCREEN_ID_INVALID;
1226     std::shared_ptr<RSDisplayNode> displayNode = smsScreen->GetDisplayNode();
1227     if (displayNode != nullptr) {
1228         displayNode->SetDisplayOffset(0, 0);
1229         displayNode->RemoveFromTree();
1230         smsScreen->ReleaseDisplayNode();
1231     }
1232     displayNode = nullptr;
1233     // attention: make sure reference count 0
1234     RSTransaction::FlushImplicitTransaction();
1235     return screenSessionMap_.erase(screenId);
1236 }
1237 
HasChild(ScreenId childScreen) const1238 bool ScreenSessionGroup::HasChild(ScreenId childScreen) const
1239 {
1240     return screenSessionMap_.find(childScreen) != screenSessionMap_.end();
1241 }
1242 
GetChildren() const1243 std::vector<sptr<ScreenSession>> ScreenSessionGroup::GetChildren() const
1244 {
1245     std::vector<sptr<ScreenSession>> res;
1246     for (auto iter = screenSessionMap_.begin(); iter != screenSessionMap_.end(); iter++) {
1247         res.push_back(iter->second.first);
1248     }
1249     return res;
1250 }
1251 
GetChildrenPosition() const1252 std::vector<Point> ScreenSessionGroup::GetChildrenPosition() const
1253 {
1254     std::vector<Point> res;
1255     for (auto iter = screenSessionMap_.begin(); iter != screenSessionMap_.end(); iter++) {
1256         res.push_back(iter->second.second);
1257     }
1258     return res;
1259 }
1260 
GetChildPosition(ScreenId screenId) const1261 Point ScreenSessionGroup::GetChildPosition(ScreenId screenId) const
1262 {
1263     Point point;
1264     auto iter = screenSessionMap_.find(screenId);
1265     if (iter != screenSessionMap_.end()) {
1266         point = iter->second.second;
1267     }
1268     return point;
1269 }
1270 
GetChildCount() const1271 size_t ScreenSessionGroup::GetChildCount() const
1272 {
1273     return screenSessionMap_.size();
1274 }
1275 
GetScreenCombination() const1276 ScreenCombination ScreenSessionGroup::GetScreenCombination() const
1277 {
1278     return combination_;
1279 }
1280 
ConvertToScreenGroupInfo() const1281 sptr<ScreenGroupInfo> ScreenSessionGroup::ConvertToScreenGroupInfo() const
1282 {
1283     sptr<ScreenGroupInfo> screenGroupInfo = new(std::nothrow) ScreenGroupInfo();
1284     if (screenGroupInfo == nullptr) {
1285         return nullptr;
1286     }
1287     FillScreenInfo(screenGroupInfo);
1288     screenGroupInfo->combination_ = combination_;
1289     for (auto iter = screenSessionMap_.begin(); iter != screenSessionMap_.end(); iter++) {
1290         screenGroupInfo->children_.push_back(iter->first);
1291     }
1292     auto positions = GetChildrenPosition();
1293     screenGroupInfo->position_.insert(screenGroupInfo->position_.end(), positions.begin(), positions.end());
1294     return screenGroupInfo;
1295 }
1296 
SetDisplayBoundary(const RectF & rect,const uint32_t & offsetY)1297 void ScreenSession::SetDisplayBoundary(const RectF& rect, const uint32_t& offsetY)
1298 {
1299     property_.SetOffsetY(offsetY);
1300     property_.SetBounds(RRect(rect, 0.0f, 0.0f));
1301 }
1302 
Resize(uint32_t width,uint32_t height)1303 void ScreenSession::Resize(uint32_t width, uint32_t height)
1304 {
1305     sptr<SupportedScreenModes> screenMode = GetActiveScreenMode();
1306     if (screenMode != nullptr) {
1307         screenMode->width_ = width;
1308         screenMode->height_ = height;
1309         UpdatePropertyByActiveMode();
1310         {
1311             std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
1312             if (displayNode_ == nullptr) {
1313                 WLOGFE("displayNode_ is null, resize failed");
1314                 return;
1315             }
1316             displayNode_->SetFrame(0, 0, static_cast<float>(width), static_cast<float>(height));
1317             displayNode_->SetBounds(0, 0, static_cast<float>(width), static_cast<float>(height));
1318         }
1319         RSTransaction::FlushImplicitTransaction();
1320     }
1321 }
1322 
UpdateAvailableArea(DMRect area)1323 bool ScreenSession::UpdateAvailableArea(DMRect area)
1324 {
1325     if (property_.GetAvailableArea() == area) {
1326         return false;
1327     }
1328     property_.SetAvailableArea(area);
1329     return true;
1330 }
1331 
SetAvailableArea(DMRect area)1332 void ScreenSession::SetAvailableArea(DMRect area)
1333 {
1334     property_.SetAvailableArea(area);
1335 }
1336 
GetAvailableArea()1337 DMRect ScreenSession::GetAvailableArea()
1338 {
1339     return property_.GetAvailableArea();
1340 }
1341 
SetFoldScreen(bool isFold)1342 void ScreenSession::SetFoldScreen(bool isFold)
1343 {
1344     WLOGFI("SetFoldScreen %{public}u", isFold);
1345     isFold_ = isFold;
1346 }
1347 
SetHdrFormats(std::vector<uint32_t> && hdrFormats)1348 void ScreenSession::SetHdrFormats(std::vector<uint32_t>&& hdrFormats)
1349 {
1350     hdrFormats_ = std::move(hdrFormats);
1351 }
1352 
SetColorSpaces(std::vector<uint32_t> && colorSpaces)1353 void ScreenSession::SetColorSpaces(std::vector<uint32_t>&& colorSpaces)
1354 {
1355     colorSpaces_ = std::move(colorSpaces);
1356 }
1357 
GetScreenSnapshot(float scaleX,float scaleY)1358 std::shared_ptr<Media::PixelMap> ScreenSession::GetScreenSnapshot(float scaleX, float scaleY)
1359 {
1360     {
1361         std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
1362         if (displayNode_ == nullptr) {
1363             WLOGFE("get screen snapshot displayNode_ is null");
1364             return nullptr;
1365         }
1366     }
1367 
1368     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ss:GetScreenSnapshot");
1369     auto callback = std::make_shared<SurfaceCaptureFuture>();
1370     RSSurfaceCaptureConfig config = {
1371         .scaleX = scaleX,
1372         .scaleY = scaleY,
1373     };
1374     {
1375         DmsXcollie dmsXcollie("DMS:GetScreenSnapshot:TakeSurfaceCapture", XCOLLIE_TIMEOUT_5S);
1376         std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
1377         bool ret = RSInterfaces::GetInstance().TakeSurfaceCapture(displayNode_, callback, config);
1378         if (!ret) {
1379             WLOGFE("get screen snapshot TakeSurfaceCapture failed");
1380             return nullptr;
1381         }
1382     }
1383 
1384     auto pixelMap = callback->GetResult(2000);
1385     if (pixelMap != nullptr) {
1386         WLOGFD("save pixelMap WxH = %{public}dx%{public}d", pixelMap->GetWidth(), pixelMap->GetHeight());
1387     } else {
1388         WLOGFE("failed to get pixelMap, return nullptr");
1389     }
1390     return pixelMap;
1391 }
1392 } // namespace OHOS::Rosen
1393