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_DISPLAY, "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 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 
SetDisplayNodeScreenId(ScreenId screenId)169 void ScreenSession::SetDisplayNodeScreenId(ScreenId screenId)
170 {
171     std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
172     if (displayNode_ != nullptr) {
173         WLOGFI("SetDisplayNodeScreenId %{public}" PRIu64"", screenId);
174         displayNode_->SetScreenId(screenId);
175     }
176 }
177 
RegisterScreenChangeListener(IScreenChangeListener* screenChangeListener)178 void ScreenSession::RegisterScreenChangeListener(IScreenChangeListener* screenChangeListener)
179 {
180     if (screenChangeListener == nullptr) {
181         WLOGFE("Failed to register screen change listener, listener is null!");
182         return;
183     }
184 
185     if (std::find(screenChangeListenerList_.begin(), screenChangeListenerList_.end(), screenChangeListener) !=
186         screenChangeListenerList_.end()) {
187         WLOGFI("Repeat to register screen change listener!");
188         return;
189     }
190 
191     screenChangeListenerList_.emplace_back(screenChangeListener);
192     if (screenState_ == ScreenState::CONNECTION) {
193         screenChangeListener->OnConnect(screenId_);
194         WLOGFI("Success to call onconnect callback.");
195     }
196     WLOGFI("Success to register screen change listener.");
197 }
198 
UnregisterScreenChangeListener(IScreenChangeListener* screenChangeListener)199 void ScreenSession::UnregisterScreenChangeListener(IScreenChangeListener* screenChangeListener)
200 {
201     if (screenChangeListener == nullptr) {
202         WLOGFE("Failed to unregister screen change listener, listener is null!");
203         return;
204     }
205 
206     screenChangeListenerList_.erase(
207         std::remove_if(screenChangeListenerList_.begin(), screenChangeListenerList_.end(),
208             [screenChangeListener](IScreenChangeListener* listener) { return screenChangeListener == listener; }),
209         screenChangeListenerList_.end());
210 }
211 
ConvertToDisplayInfo()212 sptr<DisplayInfo> ScreenSession::ConvertToDisplayInfo()
213 {
214     sptr<DisplayInfo> displayInfo = new(std::nothrow) DisplayInfo();
215     if (displayInfo == nullptr) {
216         return displayInfo;
217     }
218     RRect bounds = property_.GetBounds();
219     RRect phyBounds = property_.GetPhyBounds();
220     displayInfo->name_ = name_;
221     displayInfo->SetWidth(bounds.rect_.GetWidth());
222     displayInfo->SetHeight(bounds.rect_.GetHeight());
223     displayInfo->SetPhysicalWidth(phyBounds.rect_.GetWidth());
224     displayInfo->SetPhysicalHeight(phyBounds.rect_.GetHeight());
225     displayInfo->SetScreenId(screenId_);
226     displayInfo->SetDisplayId(screenId_);
227     displayInfo->SetRefreshRate(property_.GetRefreshRate());
228     displayInfo->SetVirtualPixelRatio(property_.GetVirtualPixelRatio());
229     displayInfo->SetDensityInCurResolution(property_.GetDensityInCurResolution());
230     displayInfo->SetDefaultVirtualPixelRatio(property_.GetDefaultDensity());
231     displayInfo->SetXDpi(property_.GetXDpi());
232     displayInfo->SetYDpi(property_.GetYDpi());
233     displayInfo->SetDpi(property_.GetVirtualPixelRatio() * DOT_PER_INCH);
234     displayInfo->SetRotation(property_.GetScreenRotation());
235     displayInfo->SetOrientation(property_.GetOrientation());
236     displayInfo->SetOffsetX(property_.GetOffsetX());
237     displayInfo->SetOffsetY(property_.GetOffsetY());
238     displayInfo->SetDisplayOrientation(property_.GetDisplayOrientation());
239     displayInfo->SetHdrFormats(hdrFormats_);
240     displayInfo->SetColorSpaces(colorSpaces_);
241     displayInfo->SetDisplayState(property_.GetDisplayState());
242     displayInfo->SetDefaultDeviceRotationOffset(property_.GetDefaultDeviceRotationOffset());
243     displayInfo->SetAvailableWidth(property_.GetAvailableArea().width_);
244     displayInfo->SetAvailableHeight(property_.GetAvailableArea().height_);
245     displayInfo->SetScaleX(property_.GetScaleX());
246     displayInfo->SetScaleY(property_.GetScaleY());
247     displayInfo->SetPivotX(property_.GetPivotX());
248     displayInfo->SetPivotY(property_.GetPivotY());
249     displayInfo->SetTranslateX(property_.GetTranslateX());
250     displayInfo->SetTranslateY(property_.GetTranslateY());
251     return displayInfo;
252 }
253 
GetScreenSupportedColorGamuts(std::vector<ScreenColorGamut>& colorGamuts)254 DMError ScreenSession::GetScreenSupportedColorGamuts(std::vector<ScreenColorGamut>& colorGamuts)
255 {
256     auto ret = RSInterfaces::GetInstance().GetScreenSupportedColorGamuts(rsId_, colorGamuts);
257     if (ret != StatusCode::SUCCESS) {
258         WLOGE("SCB: ScreenSession::GetScreenSupportedColorGamuts fail! rsId %{public}" PRIu64", ret:%{public}d",
259             rsId_, ret);
260         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
261     }
262     WLOGI("SCB: ScreenSession::GetScreenSupportedColorGamuts ok! rsId %{public}" PRIu64", size %{public}u",
263         rsId_, static_cast<uint32_t>(colorGamuts.size()));
264 
265     return DMError::DM_OK;
266 }
267 
SetIsExtend(bool isExtend)268 void ScreenSession::SetIsExtend(bool isExtend)
269 {
270     isExtended_ = isExtend;
271 }
272 
GetIsExtend() const273 bool ScreenSession::GetIsExtend() const
274 {
275     return isExtended_;
276 }
277 
SetIsInternal(bool isInternal)278 void ScreenSession::SetIsInternal(bool isInternal)
279 {
280     isInternal_ = isInternal;
281 }
282 
GetIsInternal() const283 bool ScreenSession::GetIsInternal() const
284 {
285     return isInternal_;
286 }
287 
SetIsCurrentInUse(bool isInUse)288 void ScreenSession::SetIsCurrentInUse(bool isInUse)
289 {
290     isInUse_ = isInUse;
291 }
292 
GetIsCurrentInUse() const293 bool ScreenSession::GetIsCurrentInUse() const
294 {
295     return isInUse_;
296 }
297 
GetName()298 std::string ScreenSession::GetName()
299 {
300     return name_;
301 }
302 
SetName(std::string name)303 void ScreenSession::SetName(std::string name)
304 {
305     name_ = name;
306 }
307 
SetMirrorScreenType(MirrorScreenType mirrorType)308 void ScreenSession::SetMirrorScreenType(MirrorScreenType mirrorType)
309 {
310     mirrorScreenType_ = mirrorType;
311 }
312 
GetMirrorScreenType()313 MirrorScreenType ScreenSession::GetMirrorScreenType()
314 {
315     return mirrorScreenType_;
316 }
317 
GetScreenId()318 ScreenId ScreenSession::GetScreenId()
319 {
320     return screenId_;
321 }
322 
GetRSScreenId()323 ScreenId ScreenSession::GetRSScreenId()
324 {
325     return rsId_;
326 }
327 
GetScreenProperty() const328 ScreenProperty ScreenSession::GetScreenProperty() const
329 {
330     return property_;
331 }
332 
SetScreenScale(float scaleX, float scaleY, float pivotX, float pivotY, float translateX, float translateY)333 void ScreenSession::SetScreenScale(float scaleX, float scaleY, float pivotX, float pivotY, float translateX,
334                                    float translateY)
335 {
336     property_.SetScaleX(scaleX);
337     property_.SetScaleY(scaleY);
338     property_.SetPivotX(pivotX);
339     property_.SetPivotY(pivotY);
340     property_.SetTranslateX(translateX);
341     property_.SetTranslateY(translateY);
342 }
343 
SetDefaultDeviceRotationOffset(uint32_t defaultRotationOffset)344 void ScreenSession::SetDefaultDeviceRotationOffset(uint32_t defaultRotationOffset)
345 {
346     WLOGFI("set device default rotation offset: %{public}d", defaultRotationOffset);
347     property_.SetDefaultDeviceRotationOffset(defaultRotationOffset);
348 }
349 
UpdatePropertyByActiveMode()350 void ScreenSession::UpdatePropertyByActiveMode()
351 {
352     sptr<SupportedScreenModes> mode = GetActiveScreenMode();
353     if (mode != nullptr) {
354         auto screeBounds = property_.GetBounds();
355         screeBounds.rect_.width_ = mode->width_;
356         screeBounds.rect_.height_ = mode->height_;
357         property_.SetBounds(screeBounds);
358     }
359 }
360 
UpdatePropertyByFoldControl(const ScreenProperty& updatedProperty)361 ScreenProperty ScreenSession::UpdatePropertyByFoldControl(const ScreenProperty& updatedProperty)
362 {
363     property_.SetDpiPhyBounds(updatedProperty.GetPhyWidth(), updatedProperty.GetPhyHeight());
364     property_.SetBounds(updatedProperty.GetBounds());
365     property_.SetPhyBounds(updatedProperty.GetPhyBounds());
366     return property_;
367 }
368 
UpdateDisplayState(DisplayState displayState)369 void ScreenSession::UpdateDisplayState(DisplayState displayState)
370 {
371     property_.SetDisplayState(displayState);
372 }
373 
UpdateRefreshRate(uint32_t refreshRate)374 void ScreenSession::UpdateRefreshRate(uint32_t refreshRate)
375 {
376     property_.SetRefreshRate(refreshRate);
377 }
378 
GetRefreshRate()379 uint32_t ScreenSession::GetRefreshRate()
380 {
381     return property_.GetRefreshRate();
382 }
383 
UpdatePropertyByResolution(uint32_t width, uint32_t height)384 void ScreenSession::UpdatePropertyByResolution(uint32_t width, uint32_t height)
385 {
386     auto screenBounds = property_.GetBounds();
387     screenBounds.rect_.width_ = width;
388     screenBounds.rect_.height_ = height;
389     property_.SetBounds(screenBounds);
390 }
391 
GetDisplayNode() const392 std::shared_ptr<RSDisplayNode> ScreenSession::GetDisplayNode() const
393 {
394     std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
395     return displayNode_;
396 }
397 
ReleaseDisplayNode()398 void ScreenSession::ReleaseDisplayNode()
399 {
400     std::unique_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
401     displayNode_ = nullptr;
402     WLOGFI("displayNode_ is released.");
403 }
404 
Connect()405 void ScreenSession::Connect()
406 {
407     screenState_ = ScreenState::CONNECTION;
408     if (screenChangeListenerList_.empty()) {
409         WLOGFE("screenChangeListenerList is empty.");
410         return;
411     }
412     for (auto& listener : screenChangeListenerList_) {
413         listener->OnConnect(screenId_);
414     }
415 }
416 
Disconnect()417 void ScreenSession::Disconnect()
418 {
419     screenState_ = ScreenState::DISCONNECTION;
420     for (auto& listener : screenChangeListenerList_) {
421         if (!listener) {
422             continue;
423         }
424         listener->OnDisconnect(screenId_);
425     }
426 }
427 
PropertyChange(const ScreenProperty& newProperty, ScreenPropertyChangeReason reason)428 void ScreenSession::PropertyChange(const ScreenProperty& newProperty, ScreenPropertyChangeReason reason)
429 {
430     property_ = newProperty;
431     for (auto& listener : screenChangeListenerList_) {
432         if (!listener) {
433             continue;
434         }
435         listener->OnPropertyChange(newProperty, reason, screenId_);
436     }
437 }
438 
PowerStatusChange(DisplayPowerEvent event, EventStatus status, PowerStateChangeReason reason)439 void ScreenSession::PowerStatusChange(DisplayPowerEvent event, EventStatus status, PowerStateChangeReason reason)
440 {
441     for (auto& listener : screenChangeListenerList_) {
442         if (!listener) {
443             continue;
444         }
445         listener->OnPowerStatusChange(event, status, reason);
446     }
447 }
448 
ConvertRotationToFloat(Rotation sensorRotation)449 float ScreenSession::ConvertRotationToFloat(Rotation sensorRotation)
450 {
451     float rotation = 0.f;
452     switch (sensorRotation) {
453         case Rotation::ROTATION_90:
454             rotation = 90.f; // degree 90
455             break;
456         case Rotation::ROTATION_180:
457             rotation = 180.f; // degree 180
458             break;
459         case Rotation::ROTATION_270:
460             rotation = 270.f; // degree 270
461             break;
462         default:
463             rotation = 0.f;
464             break;
465     }
466     return rotation;
467 }
468 
HandleSensorRotation(float sensorRotation)469 void ScreenSession::HandleSensorRotation(float sensorRotation)
470 {
471     SensorRotationChange(sensorRotation);
472 }
473 
SensorRotationChange(Rotation sensorRotation)474 void ScreenSession::SensorRotationChange(Rotation sensorRotation)
475 {
476     float rotation = ConvertRotationToFloat(sensorRotation);
477     SensorRotationChange(rotation);
478 }
479 
SensorRotationChange(float sensorRotation)480 void ScreenSession::SensorRotationChange(float sensorRotation)
481 {
482     if (sensorRotation >= 0.0f) {
483         currentSensorRotation_ = sensorRotation;
484     }
485     for (auto& listener : screenChangeListenerList_) {
486         listener->OnSensorRotationChange(sensorRotation, screenId_);
487     }
488 }
489 
HandleHoverStatusChange(int32_t hoverStatus)490 void ScreenSession::HandleHoverStatusChange(int32_t hoverStatus)
491 {
492     HoverStatusChange(hoverStatus);
493 }
494 
HoverStatusChange(int32_t hoverStatus)495 void ScreenSession::HoverStatusChange(int32_t hoverStatus)
496 {
497     for (auto& listener : screenChangeListenerList_) {
498         listener->OnHoverStatusChange(hoverStatus, screenId_);
499     }
500 }
501 
ScreenExtendChange(ScreenId mainScreenId, ScreenId extendScreenId)502 void ScreenSession::ScreenExtendChange(ScreenId mainScreenId, ScreenId extendScreenId)
503 {
504     for (auto& listener : screenChangeListenerList_) {
505         listener->OnScreenExtendChange(mainScreenId, extendScreenId);
506     }
507 }
508 
ScreenOrientationChange(Orientation orientation, FoldDisplayMode foldDisplayMode)509 void ScreenSession::ScreenOrientationChange(Orientation orientation, FoldDisplayMode foldDisplayMode)
510 {
511     Rotation rotationAfter = CalcRotation(orientation, foldDisplayMode);
512     float screenRotation = ConvertRotationToFloat(rotationAfter);
513     ScreenOrientationChange(screenRotation);
514 }
515 
ScreenOrientationChange(float orientation)516 void ScreenSession::ScreenOrientationChange(float orientation)
517 {
518     for (auto& listener : screenChangeListenerList_) {
519         listener->OnScreenOrientationChange(orientation, screenId_);
520     }
521 }
522 
ConvertIntToRotation(int rotation)523 Rotation ScreenSession::ConvertIntToRotation(int rotation)
524 {
525     Rotation targetRotation = Rotation::ROTATION_0;
526     switch (rotation) {
527         case 90: // Rotation 90 degree
528             targetRotation = Rotation::ROTATION_90;
529             break;
530         case 180: // Rotation 180 degree
531             targetRotation = Rotation::ROTATION_180;
532             break;
533         case 270: // Rotation 270 degree
534             targetRotation = Rotation::ROTATION_270;
535             break;
536         default:
537             targetRotation = Rotation::ROTATION_0;
538             break;
539     }
540     return targetRotation;
541 }
542 
SetUpdateToInputManagerCallback(std::function<void(float)> updateToInputManagerCallback)543 void ScreenSession::SetUpdateToInputManagerCallback(std::function<void(float)> updateToInputManagerCallback)
544 {
545     updateToInputManagerCallback_ = updateToInputManagerCallback;
546 }
547 
SetUpdateScreenPivotCallback(std::function<void(float, float)>&& updateScreenPivotCallback)548 void ScreenSession::SetUpdateScreenPivotCallback(std::function<void(float, float)>&& updateScreenPivotCallback)
549 {
550     updateScreenPivotCallback_ = std::move(updateScreenPivotCallback);
551 }
552 
GetVirtualScreenFlag()553 VirtualScreenFlag ScreenSession::GetVirtualScreenFlag()
554 {
555     return screenFlag_;
556 }
557 
SetVirtualScreenFlag(VirtualScreenFlag screenFlag)558 void ScreenSession::SetVirtualScreenFlag(VirtualScreenFlag screenFlag)
559 {
560     screenFlag_ = screenFlag;
561 }
562 
UpdateToInputManager(RRect bounds, int rotation, FoldDisplayMode foldDisplayMode)563 void ScreenSession::UpdateToInputManager(RRect bounds, int rotation, FoldDisplayMode foldDisplayMode)
564 {
565     bool needUpdateToInputManager = false;
566     if (foldDisplayMode == FoldDisplayMode::FULL &&
567         property_.GetBounds() == bounds && property_.GetRotation() != static_cast<float>(rotation)) {
568         needUpdateToInputManager = true;
569     }
570     Rotation targetRotation = ConvertIntToRotation(rotation);
571     DisplayOrientation displayOrientation = CalcDisplayOrientation(targetRotation, foldDisplayMode);
572     property_.SetBounds(bounds);
573     property_.SetRotation(static_cast<float>(rotation));
574     property_.UpdateScreenRotation(targetRotation);
575     property_.SetDisplayOrientation(displayOrientation);
576     if (needUpdateToInputManager && updateToInputManagerCallback_ != nullptr
577         && g_screenRotationOffSet == ROTATION_270) {
578         // fold phone need fix 90 degree by remainder 360 degree
579         int foldRotation = (rotation + 90) % 360;
580         updateToInputManagerCallback_(static_cast<float>(foldRotation));
581         WLOGFI("updateToInputManagerCallback_:%{public}d", foldRotation);
582     }
583 }
584 
SetPhysicalRotation(int rotation, FoldStatus foldStatus)585 void ScreenSession::SetPhysicalRotation(int rotation, FoldStatus foldStatus)
586 {
587     int32_t realRotation = static_cast<int32_t>(rotation);
588     std::vector<std::string> phyOffsets = FoldScreenStateInternel::GetPhyRotationOffset();
589     int32_t offsetRotation = 0;
590     if (phyOffsets.size() == 1 || foldStatus == FoldStatus::FOLDED) {
591         offsetRotation = static_cast<int32_t>(std::stoi(phyOffsets[0]));
592     }
593     if ((foldStatus == FoldStatus::EXPAND || foldStatus == FoldStatus::HALF_FOLD) &&
594         phyOffsets.size() == 2) { // 2 is arg number
595         offsetRotation = static_cast<int32_t>(std::stoi(phyOffsets[1]));
596     }
597     realRotation = (rotation + offsetRotation) % 360; // 360 is 360 degree
598     property_.SetPhysicalRotation(static_cast<float>(realRotation));
599     WLOGFI("physicalrotation :%{public}f , rotation: %{public}d , phyOffset: %{public}d",
600         property_.GetPhysicalRotation(), rotation, offsetRotation);
601 }
602 
UpdatePropertyAfterRotation(RRect bounds, int rotation, FoldDisplayMode foldDisplayMode)603 void ScreenSession::UpdatePropertyAfterRotation(RRect bounds, int rotation, FoldDisplayMode foldDisplayMode)
604 {
605     Rotation targetRotation = ConvertIntToRotation(rotation);
606     DisplayOrientation displayOrientation = CalcDisplayOrientation(targetRotation, foldDisplayMode);
607     property_.SetBounds(bounds);
608     property_.SetRotation(static_cast<float>(rotation));
609     property_.UpdateScreenRotation(targetRotation);
610     property_.SetDisplayOrientation(displayOrientation);
611     {
612         std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
613         if (!displayNode_) {
614             WLOGFI("update failed since null display node with rotation:%{public}d displayOrientation:%{public}u",
615                 rotation, displayOrientation);
616             return;
617         }
618     }
619     auto transactionProxy = RSTransactionProxy::GetInstance();
620     if (transactionProxy != nullptr) {
621         transactionProxy->Begin();
622         {
623             std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
624             displayNode_->SetScreenRotation(static_cast<uint32_t>(targetRotation));
625         }
626         transactionProxy->Commit();
627     } else {
628         {
629             std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
630             displayNode_->SetScreenRotation(static_cast<uint32_t>(targetRotation));
631         }
632     }
633     WLOGFI("bounds:[%{public}f %{public}f %{public}f %{public}f],rotation:%{public}d,displayOrientation:%{public}u",
634         property_.GetBounds().rect_.GetLeft(), property_.GetBounds().rect_.GetTop(),
635         property_.GetBounds().rect_.GetWidth(), property_.GetBounds().rect_.GetHeight(),
636         rotation, displayOrientation);
637     ReportNotifyModeChange(displayOrientation);
638 }
639 
UpdatePropertyOnly(RRect bounds, int rotation, FoldDisplayMode foldDisplayMode)640 void ScreenSession::UpdatePropertyOnly(RRect bounds, int rotation, FoldDisplayMode foldDisplayMode)
641 {
642     Rotation targetRotation = ConvertIntToRotation(rotation);
643     DisplayOrientation displayOrientation = CalcDisplayOrientation(targetRotation, foldDisplayMode);
644     property_.SetBounds(bounds);
645     property_.SetRotation(static_cast<float>(rotation));
646     property_.UpdateScreenRotation(targetRotation);
647     property_.SetDisplayOrientation(displayOrientation);
648     WLOGFI("bounds:[%{public}f %{public}f %{public}f %{public}f],rotation:%{public}d,displayOrientation:%{public}u",
649         property_.GetBounds().rect_.GetLeft(), property_.GetBounds().rect_.GetTop(),
650         property_.GetBounds().rect_.GetWidth(), property_.GetBounds().rect_.GetHeight(),
651         rotation, displayOrientation);
652 }
653 
ReportNotifyModeChange(DisplayOrientation displayOrientation)654 void ScreenSession::ReportNotifyModeChange(DisplayOrientation displayOrientation)
655 {
656     int32_t vhMode = 1;
657     if (displayOrientation == DisplayOrientation::PORTRAIT_INVERTED ||
658         displayOrientation == DisplayOrientation::PORTRAIT) {
659         vhMode = 0;
660     }
661     int32_t ret = HiSysEventWrite(
662         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
663         "VH_MODE",
664         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
665         "MODE", vhMode);
666     if (ret != 0) {
667         TLOGE(WmsLogTag::DMS, "ReportNotifyModeChange Write HiSysEvent error, ret: %{public}d", ret);
668     }
669 }
670 
UpdateRotationAfterBoot(bool foldToExpand)671 void ScreenSession::UpdateRotationAfterBoot(bool foldToExpand)
672 {
673     TLOGI(WmsLogTag::DMS, "foldToExpand: %{public}d, Rotation: %{public}f",
674         static_cast<int32_t>(foldToExpand), currentSensorRotation_);
675     if (foldToExpand) {
676         SensorRotationChange(currentSensorRotation_);
677     }
678 }
679 
GetActiveScreenMode() const680 sptr<SupportedScreenModes> ScreenSession::GetActiveScreenMode() const
681 {
682     if (activeIdx_ < 0 || activeIdx_ >= static_cast<int32_t>(modes_.size())) {
683         WLOGW("SCB: ScreenSession::GetActiveScreenMode active mode index is wrong: %{public}d", activeIdx_);
684         return nullptr;
685     }
686     return modes_[activeIdx_];
687 }
688 
GetOrientation() const689 Orientation ScreenSession::GetOrientation() const
690 {
691     return property_.GetOrientation();
692 }
693 
SetOrientation(Orientation orientation)694 void ScreenSession::SetOrientation(Orientation orientation)
695 {
696     property_.SetOrientation(orientation);
697 }
698 
GetRotation() const699 Rotation ScreenSession::GetRotation() const
700 {
701     return property_.GetScreenRotation();
702 }
703 
SetRotation(Rotation rotation)704 void ScreenSession::SetRotation(Rotation rotation)
705 {
706     property_.SetScreenRotation(rotation);
707 }
708 
SetScreenRequestedOrientation(Orientation orientation)709 void ScreenSession::SetScreenRequestedOrientation(Orientation orientation)
710 {
711     property_.SetScreenRequestedOrientation(orientation);
712 }
713 
SetScreenRotationLocked(bool isLocked)714 void ScreenSession::SetScreenRotationLocked(bool isLocked)
715 {
716     isScreenLocked_ = isLocked;
717     for (auto& listener : screenChangeListenerList_) {
718         if (!listener) {
719             continue;
720         }
721         listener->OnScreenRotationLockedChange(isLocked, screenId_);
722     }
723 }
724 
SetScreenRotationLockedFromJs(bool isLocked)725 void ScreenSession::SetScreenRotationLockedFromJs(bool isLocked)
726 {
727     isScreenLocked_ = isLocked;
728 }
729 
IsScreenRotationLocked()730 bool ScreenSession::IsScreenRotationLocked()
731 {
732     return isScreenLocked_;
733 }
734 
SetTouchEnabledFromJs(bool isTouchEnabled)735 void ScreenSession::SetTouchEnabledFromJs(bool isTouchEnabled)
736 {
737     TLOGI(WmsLogTag::WMS_EVENT, "isTouchEnabled:%{public}u", static_cast<uint32_t>(isTouchEnabled));
738     touchEnabled_.store(isTouchEnabled);
739 }
740 
IsTouchEnabled()741 bool ScreenSession::IsTouchEnabled()
742 {
743     return touchEnabled_.load();
744 }
745 
GetScreenRequestedOrientation() const746 Orientation ScreenSession::GetScreenRequestedOrientation() const
747 {
748     return property_.GetScreenRequestedOrientation();
749 }
750 
SetVirtualPixelRatio(float virtualPixelRatio)751 void ScreenSession::SetVirtualPixelRatio(float virtualPixelRatio)
752 {
753     property_.SetVirtualPixelRatio(virtualPixelRatio);
754 }
755 
SetScreenSceneDpiChangeListener(const SetScreenSceneDpiFunc& func)756 void ScreenSession::SetScreenSceneDpiChangeListener(const SetScreenSceneDpiFunc& func)
757 {
758     setScreenSceneDpiCallback_ = func;
759     WLOGFI("SetScreenSceneDpiChangeListener");
760 }
761 
SetScreenSceneDpi(float density)762 void ScreenSession::SetScreenSceneDpi(float density)
763 {
764     if (setScreenSceneDpiCallback_ == nullptr) {
765         WLOGFI("setScreenSceneDpiCallback_ is nullptr");
766         return;
767     }
768     setScreenSceneDpiCallback_(density);
769 }
770 
SetScreenSceneDestroyListener(const DestroyScreenSceneFunc& func)771 void ScreenSession::SetScreenSceneDestroyListener(const DestroyScreenSceneFunc& func)
772 {
773     destroyScreenSceneCallback_  = func;
774     WLOGFI("SetScreenSceneDestroyListener");
775 }
776 
DestroyScreenScene()777 void ScreenSession::DestroyScreenScene()
778 {
779     if (destroyScreenSceneCallback_  == nullptr) {
780         WLOGFI("destroyScreenSceneCallback_  is nullptr");
781         return;
782     }
783     destroyScreenSceneCallback_();
784 }
785 
SetDensityInCurResolution(float densityInCurResolution)786 void ScreenSession::SetDensityInCurResolution(float densityInCurResolution)
787 {
788     property_.SetDensityInCurResolution(densityInCurResolution);
789 }
790 
SetDefaultDensity(float DefaultDensity)791 void ScreenSession::SetDefaultDensity(float DefaultDensity)
792 {
793     property_.SetDefaultDensity(DefaultDensity);
794 }
795 
UpdateVirtualPixelRatio(const RRect& bounds)796 void ScreenSession::UpdateVirtualPixelRatio(const RRect& bounds)
797 {
798     property_.UpdateVirtualPixelRatio(bounds);
799 }
800 
SetScreenType(ScreenType type)801 void ScreenSession::SetScreenType(ScreenType type)
802 {
803     property_.SetScreenType(type);
804 }
805 
CalcRotation(Orientation orientation, FoldDisplayMode foldDisplayMode) const806 Rotation ScreenSession::CalcRotation(Orientation orientation, FoldDisplayMode foldDisplayMode) const
807 {
808     sptr<SupportedScreenModes> info = GetActiveScreenMode();
809     if (info == nullptr) {
810         return Rotation::ROTATION_0;
811     }
812     // vertical: phone(Plugin screen); horizontal: pad & external screen
813     bool isVerticalScreen = info->width_ < info->height_;
814     if (foldDisplayMode != FoldDisplayMode::UNKNOWN &&
815         (g_screenRotationOffSet == ROTATION_90 || g_screenRotationOffSet == ROTATION_270)) {
816         isVerticalScreen = info->width_ > info->height_;
817     }
818     switch (orientation) {
819         case Orientation::UNSPECIFIED: {
820             return Rotation::ROTATION_0;
821         }
822         case Orientation::VERTICAL: {
823             return isVerticalScreen ? Rotation::ROTATION_0 : Rotation::ROTATION_90;
824         }
825         case Orientation::HORIZONTAL: {
826             return isVerticalScreen ? Rotation::ROTATION_90 : Rotation::ROTATION_0;
827         }
828         case Orientation::REVERSE_VERTICAL: {
829             return isVerticalScreen ? Rotation::ROTATION_180 : Rotation::ROTATION_270;
830         }
831         case Orientation::REVERSE_HORIZONTAL: {
832             return isVerticalScreen ? Rotation::ROTATION_270 : Rotation::ROTATION_180;
833         }
834         default: {
835             WLOGE("unknown orientation %{public}u", orientation);
836             return Rotation::ROTATION_0;
837         }
838     }
839 }
840 
CalcDisplayOrientation(Rotation rotation, FoldDisplayMode foldDisplayMode) const841 DisplayOrientation ScreenSession::CalcDisplayOrientation(Rotation rotation, FoldDisplayMode foldDisplayMode) const
842 {
843     DisplayOrientation displayRotation = DisplayOrientation::UNKNOWN;
844     switch (rotation) {
845         case Rotation::ROTATION_0: {
846             displayRotation = DisplayOrientation::PORTRAIT;
847             break;
848         }
849         case Rotation::ROTATION_90: {
850             displayRotation = DisplayOrientation::LANDSCAPE;
851             break;
852         }
853         case Rotation::ROTATION_180: {
854             displayRotation = DisplayOrientation::PORTRAIT_INVERTED;
855             break;
856         }
857         case Rotation::ROTATION_270: {
858             displayRotation = DisplayOrientation::LANDSCAPE_INVERTED;
859             break;
860         }
861         default: {
862             WLOGE("unknown rotation %{public}u", rotation);
863         }
864     }
865     return displayRotation;
866 }
867 
GetSourceMode() const868 ScreenSourceMode ScreenSession::GetSourceMode() const
869 {
870     if (screenId_ == defaultScreenId_) {
871         return ScreenSourceMode::SCREEN_MAIN;
872     }
873     ScreenCombination combination = GetScreenCombination();
874     switch (combination) {
875         case ScreenCombination::SCREEN_MIRROR: {
876             return ScreenSourceMode::SCREEN_MIRROR;
877         }
878         case ScreenCombination::SCREEN_EXPAND: {
879             return ScreenSourceMode::SCREEN_EXTEND;
880         }
881         case ScreenCombination::SCREEN_ALONE: {
882             return ScreenSourceMode::SCREEN_ALONE;
883         }
884         case ScreenCombination::SCREEN_UNIQUE: {
885             return ScreenSourceMode::SCREEN_UNIQUE;
886         }
887         default: {
888             return ScreenSourceMode::SCREEN_ALONE;
889         }
890     }
891 }
892 
SetScreenCombination(ScreenCombination combination)893 void ScreenSession::SetScreenCombination(ScreenCombination combination)
894 {
895     WLOGFI("screenId:%{public}" PRIu64", set combination:%{public}d", screenId_,
896         static_cast<int32_t>(combination));
897     combination_ = combination;
898 }
899 
GetScreenCombination() const900 ScreenCombination ScreenSession::GetScreenCombination() const
901 {
902     return combination_;
903 }
904 
FillScreenInfo(sptr<ScreenInfo> info) const905 void ScreenSession::FillScreenInfo(sptr<ScreenInfo> info) const
906 {
907     if (info == nullptr) {
908         WLOGE("FillScreenInfo failed! info is nullptr");
909         return;
910     }
911     info->SetScreenId(screenId_);
912     info->SetName(name_);
913     info->SetIsExtend(GetIsExtend());
914     uint32_t width = 0;
915     uint32_t height = 0;
916     sptr<SupportedScreenModes> screenSessionModes = GetActiveScreenMode();
917     if (screenSessionModes != nullptr) {
918         height = screenSessionModes->height_;
919         width = screenSessionModes->width_;
920     }
921     float virtualPixelRatio = property_.GetVirtualPixelRatio();
922     // "< 1e-set6" means virtualPixelRatio is 0.
923     if (fabsf(virtualPixelRatio) < 1e-6) {
924         virtualPixelRatio = 1.0f;
925     }
926     ScreenSourceMode sourceMode = GetSourceMode();
927     info->SetVirtualPixelRatio(property_.GetVirtualPixelRatio());
928     info->SetVirtualHeight(height / virtualPixelRatio);
929     info->SetVirtualWidth(width / virtualPixelRatio);
930     info->SetRotation(property_.GetScreenRotation());
931     info->SetOrientation(static_cast<Orientation>(property_.GetDisplayOrientation()));
932     info->SetSourceMode(sourceMode);
933     info->SetType(property_.GetScreenType());
934     info->SetModeId(activeIdx_);
935 
936     info->lastParent_ = lastGroupSmsId_;
937     info->parent_ = groupSmsId_;
938     info->isScreenGroup_ = isScreenGroup_;
939     info->modes_ = modes_;
940 }
941 
ConvertToScreenInfo() const942 sptr<ScreenInfo> ScreenSession::ConvertToScreenInfo() const
943 {
944     sptr<ScreenInfo> info = new(std::nothrow) ScreenInfo();
945     if (info == nullptr) {
946         return nullptr;
947     }
948     FillScreenInfo(info);
949     return info;
950 }
951 
GetScreenColorGamut(ScreenColorGamut& colorGamut)952 DMError ScreenSession::GetScreenColorGamut(ScreenColorGamut& colorGamut)
953 {
954     auto ret = RSInterfaces::GetInstance().GetScreenColorGamut(rsId_, colorGamut);
955     if (ret != StatusCode::SUCCESS) {
956         WLOGE("GetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_);
957         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
958     }
959     WLOGI("GetScreenColorGamut ok! rsId %{public}" PRIu64", colorGamut %{public}u",
960         rsId_, static_cast<uint32_t>(colorGamut));
961     return DMError::DM_OK;
962 }
963 
SetScreenColorGamut(int32_t colorGamutIdx)964 DMError ScreenSession::SetScreenColorGamut(int32_t colorGamutIdx)
965 {
966     std::vector<ScreenColorGamut> colorGamuts;
967     DMError res = GetScreenSupportedColorGamuts(colorGamuts);
968     if (res != DMError::DM_OK) {
969         WLOGE("SetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_);
970         return res;
971     }
972     if (colorGamutIdx < 0 || colorGamutIdx >= static_cast<int32_t>(colorGamuts.size())) {
973         WLOGE("SetScreenColorGamut fail! rsId %{public}" PRIu64" colorGamutIdx %{public}d invalid.",
974             rsId_, colorGamutIdx);
975         return DMError::DM_ERROR_INVALID_PARAM;
976     }
977     auto ret = RSInterfaces::GetInstance().SetScreenColorGamut(rsId_, colorGamutIdx);
978     if (ret != StatusCode::SUCCESS) {
979         WLOGE("SetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_);
980         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
981     }
982     WLOGI("SetScreenColorGamut ok! rsId %{public}" PRIu64", colorGamutIdx %{public}u",
983         rsId_, colorGamutIdx);
984     return DMError::DM_OK;
985 }
986 
GetScreenGamutMap(ScreenGamutMap& gamutMap)987 DMError ScreenSession::GetScreenGamutMap(ScreenGamutMap& gamutMap)
988 {
989     auto ret = RSInterfaces::GetInstance().GetScreenGamutMap(rsId_, gamutMap);
990     if (ret != StatusCode::SUCCESS) {
991         WLOGE("GetScreenGamutMap fail! rsId %{public}" PRIu64"", rsId_);
992         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
993     }
994     WLOGI("GetScreenGamutMap ok! rsId %{public}" PRIu64", gamutMap %{public}u",
995         rsId_, static_cast<uint32_t>(gamutMap));
996     return DMError::DM_OK;
997 }
998 
SetScreenGamutMap(ScreenGamutMap gamutMap)999 DMError ScreenSession::SetScreenGamutMap(ScreenGamutMap gamutMap)
1000 {
1001     if (gamutMap > GAMUT_MAP_HDR_EXTENSION) {
1002         return DMError::DM_ERROR_INVALID_PARAM;
1003     }
1004     auto ret = RSInterfaces::GetInstance().SetScreenGamutMap(rsId_, gamutMap);
1005     if (ret != StatusCode::SUCCESS) {
1006         WLOGE("SetScreenGamutMap fail! rsId %{public}" PRIu64"", rsId_);
1007         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1008     }
1009     WLOGI("SetScreenGamutMap ok! rsId %{public}" PRIu64", gamutMap %{public}u",
1010         rsId_, static_cast<uint32_t>(gamutMap));
1011     return DMError::DM_OK;
1012 }
1013 
SetScreenColorTransform()1014 DMError ScreenSession::SetScreenColorTransform()
1015 {
1016     WLOGI("SetScreenColorTransform ok! rsId %{public}" PRIu64"", rsId_);
1017     return DMError::DM_OK;
1018 }
1019 
GetPixelFormat(GraphicPixelFormat& pixelFormat)1020 DMError ScreenSession::GetPixelFormat(GraphicPixelFormat& pixelFormat)
1021 {
1022     auto ret = RSInterfaces::GetInstance().GetPixelFormat(rsId_, pixelFormat);
1023     if (ret != StatusCode::SUCCESS) {
1024         WLOGE("GetPixelFormat fail! rsId %{public}" PRIu64, rsId_);
1025         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1026     }
1027     WLOGI("GetPixelFormat ok! rsId %{public}" PRIu64 ", pixelFormat %{public}u",
1028         rsId_, static_cast<uint32_t>(pixelFormat));
1029     return DMError::DM_OK;
1030 }
1031 
SetPixelFormat(GraphicPixelFormat pixelFormat)1032 DMError ScreenSession::SetPixelFormat(GraphicPixelFormat pixelFormat)
1033 {
1034     if (pixelFormat > GRAPHIC_PIXEL_FMT_VENDER_MASK) {
1035         return DMError::DM_ERROR_INVALID_PARAM;
1036     }
1037     auto ret = RSInterfaces::GetInstance().SetPixelFormat(rsId_, pixelFormat);
1038     if (ret != StatusCode::SUCCESS) {
1039         WLOGE("SetPixelFormat fail! rsId %{public}" PRIu64, rsId_);
1040         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1041     }
1042     WLOGI("SetPixelFormat ok! rsId %{public}" PRIu64 ", gamutMap %{public}u",
1043         rsId_, static_cast<uint32_t>(pixelFormat));
1044     return DMError::DM_OK;
1045 }
1046 
GetSupportedHDRFormats(std::vector<ScreenHDRFormat>& hdrFormats)1047 DMError ScreenSession::GetSupportedHDRFormats(std::vector<ScreenHDRFormat>& hdrFormats)
1048 {
1049     auto ret = RSInterfaces::GetInstance().GetScreenSupportedHDRFormats(rsId_, hdrFormats);
1050     if (ret != StatusCode::SUCCESS) {
1051         WLOGE("SCB: ScreenSession::GetSupportedHDRFormats fail! rsId %{public}" PRIu64 ", ret:%{public}d",
1052             rsId_, ret);
1053         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1054     }
1055     WLOGI("SCB: ScreenSession::GetSupportedHDRFormats ok! rsId %{public}" PRIu64 ", size %{public}u",
1056         rsId_, static_cast<uint32_t>(hdrFormats.size()));
1057 
1058     return DMError::DM_OK;
1059 }
1060 
GetScreenHDRFormat(ScreenHDRFormat& hdrFormat)1061 DMError ScreenSession::GetScreenHDRFormat(ScreenHDRFormat& hdrFormat)
1062 {
1063     auto ret = RSInterfaces::GetInstance().GetScreenHDRFormat(rsId_, hdrFormat);
1064     if (ret != StatusCode::SUCCESS) {
1065         WLOGE("GetScreenHDRFormat fail! rsId %{public}" PRIu64, rsId_);
1066         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1067     }
1068     WLOGI("GetScreenHDRFormat ok! rsId %{public}" PRIu64 ", colorSpace %{public}u",
1069         rsId_, static_cast<uint32_t>(hdrFormat));
1070     return DMError::DM_OK;
1071 }
1072 
SetScreenHDRFormat(int32_t modeIdx)1073 DMError ScreenSession::SetScreenHDRFormat(int32_t modeIdx)
1074 {
1075     std::vector<ScreenHDRFormat> hdrFormats;
1076     DMError res = GetSupportedHDRFormats(hdrFormats);
1077     if (res != DMError::DM_OK) {
1078         WLOGE("SetScreenHDRFormat fail! rsId %{public}" PRIu64, rsId_);
1079         return res;
1080     }
1081     if (modeIdx < 0 || modeIdx >= static_cast<int32_t>(hdrFormats.size())) {
1082         WLOGE("SetScreenHDRFormat fail! rsId %{public}" PRIu64 " modeIdx %{public}d invalid.",
1083             rsId_, modeIdx);
1084         return DMError::DM_ERROR_INVALID_PARAM;
1085     }
1086     auto ret = RSInterfaces::GetInstance().SetScreenHDRFormat(rsId_, modeIdx);
1087     if (ret != StatusCode::SUCCESS) {
1088         WLOGE("SetScreenHDRFormat fail! rsId %{public}" PRIu64, rsId_);
1089         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1090     }
1091     WLOGI("SetScreenHDRFormat ok! rsId %{public}" PRIu64 ", modeIdx %{public}d",
1092         rsId_, modeIdx);
1093     return DMError::DM_OK;
1094 }
1095 
GetSupportedColorSpaces(std::vector<GraphicCM_ColorSpaceType>& colorSpaces)1096 DMError ScreenSession::GetSupportedColorSpaces(std::vector<GraphicCM_ColorSpaceType>& colorSpaces)
1097 {
1098     auto ret = RSInterfaces::GetInstance().GetScreenSupportedColorSpaces(rsId_, colorSpaces);
1099     if (ret != StatusCode::SUCCESS) {
1100         WLOGE("SCB: ScreenSession::GetSupportedColorSpaces fail! rsId %{public}" PRIu64 ", ret:%{public}d",
1101             rsId_, ret);
1102         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1103     }
1104     WLOGI("SCB: ScreenSession::GetSupportedColorSpaces ok! rsId %{public}" PRIu64 ", size %{public}u",
1105         rsId_, static_cast<uint32_t>(colorSpaces.size()));
1106     return DMError::DM_OK;
1107 }
1108 
GetScreenColorSpace(GraphicCM_ColorSpaceType& colorSpace)1109 DMError ScreenSession::GetScreenColorSpace(GraphicCM_ColorSpaceType& colorSpace)
1110 {
1111     auto ret = RSInterfaces::GetInstance().GetScreenColorSpace(rsId_, colorSpace);
1112     if (ret != StatusCode::SUCCESS) {
1113         WLOGE("GetScreenColorSpace fail! rsId %{public}" PRIu64, rsId_);
1114         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1115     }
1116     WLOGI("GetScreenColorSpace ok! rsId %{public}" PRIu64 ", colorSpace %{public}u",
1117         rsId_, static_cast<uint32_t>(colorSpace));
1118     return DMError::DM_OK;
1119 }
1120 
SetScreenColorSpace(GraphicCM_ColorSpaceType colorSpace)1121 DMError ScreenSession::SetScreenColorSpace(GraphicCM_ColorSpaceType colorSpace)
1122 {
1123     std::vector<GraphicCM_ColorSpaceType> colorSpaces;
1124     DMError res = GetSupportedColorSpaces(colorSpaces);
1125     if (res != DMError::DM_OK) {
1126         WLOGE("SetScreenColorSpace fail! rsId %{public}" PRIu64, rsId_);
1127         return res;
1128     }
1129     if (colorSpace < 0 || static_cast<int32_t>(colorSpace) >= static_cast<int32_t>(colorSpaces.size())) {
1130         WLOGE("SetScreenColorSpace fail! rsId %{public}" PRIu64 " colorSpace %{public}d invalid.",
1131             rsId_, static_cast<int32_t>(colorSpace));
1132         return DMError::DM_ERROR_INVALID_PARAM;
1133     }
1134     auto ret = RSInterfaces::GetInstance().SetScreenColorSpace(rsId_, colorSpace);
1135     if (ret != StatusCode::SUCCESS) {
1136         WLOGE("SetScreenColorSpace fail! rsId %{public}" PRIu64, rsId_);
1137         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1138     }
1139     WLOGI("SetScreenColorSpace ok! rsId %{public}" PRIu64 ", colorSpace %{public}u",
1140         rsId_, static_cast<uint32_t>(colorSpace));
1141     return DMError::DM_OK;
1142 }
1143 
HasPrivateSessionForeground() const1144 bool ScreenSession::HasPrivateSessionForeground() const
1145 {
1146     return hasPrivateWindowForeground_;
1147 }
1148 
SetPrivateSessionForeground(bool hasPrivate)1149 void ScreenSession::SetPrivateSessionForeground(bool hasPrivate)
1150 {
1151     hasPrivateWindowForeground_ = hasPrivate;
1152 }
1153 
InitRSDisplayNode(RSDisplayNodeConfig& config, Point& startPoint)1154 void ScreenSession::InitRSDisplayNode(RSDisplayNodeConfig& config, Point& startPoint)
1155 {
1156     std::unique_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
1157     if (displayNode_ != nullptr) {
1158         displayNode_->SetDisplayNodeMirrorConfig(config);
1159         if (screenId_ == 0 && isFold_) {
1160             WLOGFI("Return InitRSDisplayNode foldScreen0");
1161             return;
1162         }
1163     } else {
1164         std::shared_ptr<RSDisplayNode> rsDisplayNode = RSDisplayNode::Create(config);
1165         if (rsDisplayNode == nullptr) {
1166             WLOGE("fail to add child. create rsDisplayNode fail!");
1167             return;
1168         }
1169         displayNode_ = rsDisplayNode;
1170     }
1171     WLOGFI("SetDisplayOffset: posX:%{public}d, posY:%{public}d", startPoint.posX_, startPoint.posY_);
1172     displayNode_->SetDisplayOffset(startPoint.posX_, startPoint.posY_);
1173     uint32_t width = 0;
1174     uint32_t height = 0;
1175     sptr<SupportedScreenModes> abstractScreenModes = GetActiveScreenMode();
1176     if (abstractScreenModes != nullptr) {
1177         height = abstractScreenModes->height_;
1178         width = abstractScreenModes->width_;
1179     }
1180     RSScreenType screenType;
1181     DmsXcollie dmsXcollie("DMS:InitRSDisplayNode:GetScreenType", XCOLLIE_TIMEOUT_5S);
1182     auto ret = RSInterfaces::GetInstance().GetScreenType(rsId_, screenType);
1183     if (ret == StatusCode::SUCCESS && screenType == RSScreenType::VIRTUAL_TYPE_SCREEN) {
1184         displayNode_->SetSecurityDisplay(true);
1185         WLOGFI("virtualScreen SetSecurityDisplay success");
1186     }
1187     // If setDisplayOffset is not valid for SetFrame/SetBounds
1188     WLOGFI("InitRSDisplayNode screenId:%{public}" PRIu64" width:%{public}u height:%{public}u",
1189         screenId_, width, height);
1190     displayNode_->SetFrame(0, 0, static_cast<float>(width), static_cast<float>(height));
1191     displayNode_->SetBounds(0, 0, static_cast<float>(width), static_cast<float>(height));
1192     auto transactionProxy = RSTransactionProxy::GetInstance();
1193     if (transactionProxy != nullptr) {
1194         transactionProxy->FlushImplicitTransaction();
1195     }
1196 }
1197 
ScreenSessionGroup(ScreenId screenId, ScreenId rsId, std::string name, ScreenCombination combination)1198 ScreenSessionGroup::ScreenSessionGroup(ScreenId screenId, ScreenId rsId,
1199     std::string name, ScreenCombination combination) : combination_(combination)
1200 {
1201     name_ = name;
1202     screenId_ = screenId;
1203     rsId_ = rsId;
1204     SetScreenType(ScreenType::UNDEFINED);
1205     isScreenGroup_ = true;
1206 }
1207 
~ScreenSessionGroup()1208 ScreenSessionGroup::~ScreenSessionGroup()
1209 {
1210     ReleaseDisplayNode();
1211     screenSessionMap_.clear();
1212 }
1213 
GetRSDisplayNodeConfig(sptr<ScreenSession>& screenSession, struct RSDisplayNodeConfig& config, sptr<ScreenSession> defaultScreenSession)1214 bool ScreenSessionGroup::GetRSDisplayNodeConfig(sptr<ScreenSession>& screenSession, struct RSDisplayNodeConfig& config,
1215                                                 sptr<ScreenSession> defaultScreenSession)
1216 {
1217     if (screenSession == nullptr) {
1218         WLOGE("screenSession is nullptr.");
1219         return false;
1220     }
1221     config = { screenSession->rsId_ };
1222     switch (combination_) {
1223         case ScreenCombination::SCREEN_ALONE:
1224             [[fallthrough]];
1225         case ScreenCombination::SCREEN_EXPAND:
1226             break;
1227         case ScreenCombination::SCREEN_UNIQUE:
1228             break;
1229         case ScreenCombination::SCREEN_MIRROR: {
1230             if (GetChildCount() == 0 || mirrorScreenId_ == screenSession->screenId_) {
1231                 WLOGI("SCREEN_MIRROR, config is not mirror");
1232                 break;
1233             }
1234             if (defaultScreenSession == nullptr) {
1235                 WLOGFE("defaultScreenSession is nullptr");
1236                 break;
1237             }
1238             std::shared_ptr<RSDisplayNode> displayNode = defaultScreenSession->GetDisplayNode();
1239             if (displayNode == nullptr) {
1240                 WLOGFE("displayNode is nullptr, cannot get DisplayNode");
1241                 break;
1242             }
1243             NodeId nodeId = displayNode->GetId();
1244             WLOGI("mirrorScreenId_:%{public}" PRIu64", rsId_:%{public}" PRIu64", nodeId:%{public}" PRIu64"",
1245                 mirrorScreenId_, screenSession->rsId_, nodeId);
1246             config = {screenSession->rsId_, true, nodeId, true};
1247             break;
1248         }
1249         default:
1250             WLOGE("fail to add child. invalid group combination:%{public}u", combination_);
1251             return false;
1252     }
1253     return true;
1254 }
1255 
AddChild(sptr<ScreenSession>& smsScreen, Point& startPoint, sptr<ScreenSession> defaultScreenSession)1256 bool ScreenSessionGroup::AddChild(sptr<ScreenSession>& smsScreen, Point& startPoint,
1257                                   sptr<ScreenSession> defaultScreenSession)
1258 {
1259     if (smsScreen == nullptr) {
1260         WLOGE("AddChild, smsScreen is nullptr.");
1261         return false;
1262     }
1263     ScreenId screenId = smsScreen->screenId_;
1264     auto iter = screenSessionMap_.find(screenId);
1265     if (iter != screenSessionMap_.end()) {
1266         WLOGE("AddChild, screenSessionMap_ has smsScreen:%{public}" PRIu64"", screenId);
1267         return false;
1268     }
1269     struct RSDisplayNodeConfig config;
1270     if (!GetRSDisplayNodeConfig(smsScreen, config, defaultScreenSession)) {
1271         return false;
1272     }
1273     smsScreen->InitRSDisplayNode(config, startPoint);
1274     smsScreen->lastGroupSmsId_ = smsScreen->groupSmsId_;
1275     smsScreen->groupSmsId_ = screenId_;
1276     screenSessionMap_.insert(std::make_pair(screenId, std::make_pair(smsScreen, startPoint)));
1277     return true;
1278 }
1279 
AddChildren(std::vector<sptr<ScreenSession>>& smsScreens, std::vector<Point>& startPoints)1280 bool ScreenSessionGroup::AddChildren(std::vector<sptr<ScreenSession>>& smsScreens, std::vector<Point>& startPoints)
1281 {
1282     size_t size = smsScreens.size();
1283     if (size != startPoints.size()) {
1284         WLOGE("AddChildren, unequal size.");
1285         return false;
1286     }
1287     bool res = true;
1288     for (size_t i = 0; i < size; i++) {
1289         res = AddChild(smsScreens[i], startPoints[i], nullptr) && res;
1290     }
1291     return res;
1292 }
1293 
RemoveChild(sptr<ScreenSession>& smsScreen)1294 bool ScreenSessionGroup::RemoveChild(sptr<ScreenSession>& smsScreen)
1295 {
1296     if (smsScreen == nullptr) {
1297         WLOGE("RemoveChild, smsScreen is nullptr.");
1298         return false;
1299     }
1300     ScreenId screenId = smsScreen->screenId_;
1301     smsScreen->lastGroupSmsId_ = smsScreen->groupSmsId_;
1302     smsScreen->groupSmsId_ = SCREEN_ID_INVALID;
1303     std::shared_ptr<RSDisplayNode> displayNode = smsScreen->GetDisplayNode();
1304     if (displayNode != nullptr) {
1305         displayNode->SetDisplayOffset(0, 0);
1306         displayNode->RemoveFromTree();
1307         smsScreen->ReleaseDisplayNode();
1308     }
1309     displayNode = nullptr;
1310     // attention: make sure reference count 0
1311     RSTransaction::FlushImplicitTransaction();
1312     return screenSessionMap_.erase(screenId);
1313 }
1314 
HasChild(ScreenId childScreen) const1315 bool ScreenSessionGroup::HasChild(ScreenId childScreen) const
1316 {
1317     return screenSessionMap_.find(childScreen) != screenSessionMap_.end();
1318 }
1319 
GetChildren() const1320 std::vector<sptr<ScreenSession>> ScreenSessionGroup::GetChildren() const
1321 {
1322     std::vector<sptr<ScreenSession>> res;
1323     for (auto iter = screenSessionMap_.begin(); iter != screenSessionMap_.end(); iter++) {
1324         res.push_back(iter->second.first);
1325     }
1326     return res;
1327 }
1328 
GetChildrenPosition() const1329 std::vector<Point> ScreenSessionGroup::GetChildrenPosition() const
1330 {
1331     std::vector<Point> res;
1332     for (auto iter = screenSessionMap_.begin(); iter != screenSessionMap_.end(); iter++) {
1333         res.push_back(iter->second.second);
1334     }
1335     return res;
1336 }
1337 
GetChildPosition(ScreenId screenId) const1338 Point ScreenSessionGroup::GetChildPosition(ScreenId screenId) const
1339 {
1340     Point point{};
1341     auto iter = screenSessionMap_.find(screenId);
1342     if (iter != screenSessionMap_.end()) {
1343         point = iter->second.second;
1344     }
1345     return point;
1346 }
1347 
GetChildCount() const1348 size_t ScreenSessionGroup::GetChildCount() const
1349 {
1350     return screenSessionMap_.size();
1351 }
1352 
GetScreenCombination() const1353 ScreenCombination ScreenSessionGroup::GetScreenCombination() const
1354 {
1355     return combination_;
1356 }
1357 
ConvertToScreenGroupInfo() const1358 sptr<ScreenGroupInfo> ScreenSessionGroup::ConvertToScreenGroupInfo() const
1359 {
1360     sptr<ScreenGroupInfo> screenGroupInfo = new(std::nothrow) ScreenGroupInfo();
1361     if (screenGroupInfo == nullptr) {
1362         return nullptr;
1363     }
1364     FillScreenInfo(screenGroupInfo);
1365     screenGroupInfo->combination_ = combination_;
1366     for (auto iter = screenSessionMap_.begin(); iter != screenSessionMap_.end(); iter++) {
1367         screenGroupInfo->children_.push_back(iter->first);
1368     }
1369     auto positions = GetChildrenPosition();
1370     screenGroupInfo->position_.insert(screenGroupInfo->position_.end(), positions.begin(), positions.end());
1371     return screenGroupInfo;
1372 }
1373 
SetDisplayBoundary(const RectF& rect, const uint32_t& offsetY)1374 void ScreenSession::SetDisplayBoundary(const RectF& rect, const uint32_t& offsetY)
1375 {
1376     property_.SetOffsetY(static_cast<int32_t>(offsetY));
1377     property_.SetBounds(RRect(rect, 0.0f, 0.0f));
1378 }
1379 
Resize(uint32_t width, uint32_t height)1380 void ScreenSession::Resize(uint32_t width, uint32_t height)
1381 {
1382     sptr<SupportedScreenModes> screenMode = GetActiveScreenMode();
1383     if (screenMode != nullptr) {
1384         screenMode->width_ = width;
1385         screenMode->height_ = height;
1386         UpdatePropertyByActiveMode();
1387         {
1388             std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
1389             displayNode_->SetFrame(0, 0, static_cast<float>(width), static_cast<float>(height));
1390             displayNode_->SetBounds(0, 0, static_cast<float>(width), static_cast<float>(height));
1391         }
1392         RSTransaction::FlushImplicitTransaction();
1393     }
1394 }
1395 
UpdateAvailableArea(DMRect area)1396 bool ScreenSession::UpdateAvailableArea(DMRect area)
1397 {
1398     if (property_.GetAvailableArea() == area) {
1399         return false;
1400     }
1401     property_.SetAvailableArea(area);
1402     return true;
1403 }
1404 
SetAvailableArea(DMRect area)1405 void ScreenSession::SetAvailableArea(DMRect area)
1406 {
1407     property_.SetAvailableArea(area);
1408 }
1409 
GetAvailableArea()1410 DMRect ScreenSession::GetAvailableArea()
1411 {
1412     return property_.GetAvailableArea();
1413 }
1414 
SetFoldScreen(bool isFold)1415 void ScreenSession::SetFoldScreen(bool isFold)
1416 {
1417     WLOGFI("SetFoldScreen %{public}u", isFold);
1418     isFold_ = isFold;
1419 }
1420 
SetHdrFormats(std::vector<uint32_t>&& hdrFormats)1421 void ScreenSession::SetHdrFormats(std::vector<uint32_t>&& hdrFormats)
1422 {
1423     hdrFormats_ = std::move(hdrFormats);
1424 }
1425 
SetColorSpaces(std::vector<uint32_t>&& colorSpaces)1426 void ScreenSession::SetColorSpaces(std::vector<uint32_t>&& colorSpaces)
1427 {
1428     colorSpaces_ = std::move(colorSpaces);
1429 }
1430 
GetScreenSnapshot(float scaleX, float scaleY)1431 std::shared_ptr<Media::PixelMap> ScreenSession::GetScreenSnapshot(float scaleX, float scaleY)
1432 {
1433     {
1434         std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
1435         if (displayNode_ == nullptr) {
1436             WLOGFE("get screen snapshot displayNode_ is null");
1437             return nullptr;
1438         }
1439     }
1440 
1441     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ss:GetScreenSnapshot");
1442     auto callback = std::make_shared<SurfaceCaptureFuture>();
1443     RSSurfaceCaptureConfig config = {
1444         .scaleX = scaleX,
1445         .scaleY = scaleY,
1446     };
1447     {
1448         DmsXcollie dmsXcollie("DMS:GetScreenSnapshot:TakeSurfaceCapture", XCOLLIE_TIMEOUT_5S);
1449         std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
1450         bool ret = RSInterfaces::GetInstance().TakeSurfaceCapture(displayNode_, callback, config);
1451         if (!ret) {
1452             WLOGFE("get screen snapshot TakeSurfaceCapture failed");
1453             return nullptr;
1454         }
1455     }
1456 
1457     auto pixelMap = callback->GetResult(2000); // 2000, default timeout
1458     if (pixelMap != nullptr) {
1459         WLOGFD("save pixelMap WxH = %{public}dx%{public}d", pixelMap->GetWidth(), pixelMap->GetHeight());
1460     } else {
1461         WLOGFE("failed to get pixelMap, return nullptr");
1462     }
1463     return pixelMap;
1464 }
1465 
SetStartPosition(uint32_t startX, uint32_t startY)1466 void ScreenSession::SetStartPosition(uint32_t startX, uint32_t startY)
1467 {
1468     property_.SetStartPosition(startX, startY);
1469 }
1470 } // namespace OHOS::Rosen
1471