• 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 "screen_cache.h"
20 #include <hitrace_meter.h>
21 #include <surface_capture_future.h>
22 #include <transaction/rs_interfaces.h>
23 #include <transaction/rs_transaction.h>
24 #include "window_manager_hilog.h"
25 #include "dm_common.h"
26 #include "dms_xcollie.h"
27 #include "fold_screen_state_internel.h"
28 #include <parameters.h>
29 #include "sys_cap_util.h"
30 #include <ipc_skeleton.h>
31 
32 namespace OHOS::Rosen {
33 namespace {
34 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "ScreenSession" };
35 static const int32_t g_screenRotationOffSet = system::GetIntParameter<int32_t>("const.fold.screen_rotation.offset", 0);
36 static const int32_t ROTATION_90 = 1;
37 static const int32_t ROTATION_270 = 3;
38 const unsigned int XCOLLIE_TIMEOUT_5S = 5;
39 const static int32_t MAX_INTERVAL_US = 1800000000; //30分钟
40 const int32_t MAP_SIZE = 300;
41 const int32_t NO_EXIT_UID_VERSION = -1;
42 const float FULL_STATUS_WIDTH = 2048;
43 const float GLOBAL_FULL_STATUS_WIDTH = 3184;
44 const float MAIN_STATUS_WIDTH = 1008;
45 const float SCREEN_HEIGHT = 2232;
46 constexpr uint32_t SECONDARY_ROTATION_MOD = 4;
47 constexpr uint32_t SECONDARY_ROTATION_270 = 3;
48 ScreenCache g_uidVersionMap(MAP_SIZE, NO_EXIT_UID_VERSION);
49 }
ScreenSession(const ScreenSessionConfig & config,ScreenSessionReason reason)50 ScreenSession::ScreenSession(const ScreenSessionConfig& config, ScreenSessionReason reason)
51     : name_(config.name), screenId_(config.screenId), rsId_(config.rsId), defaultScreenId_(config.defaultScreenId),
52     property_(config.property), displayNode_(config.displayNode)
53 {
54     TLOGI(WmsLogTag::DMS,
55         "[DPNODE]Create Session, reason: %{public}d, screenId: %{public}" PRIu64", rsId: %{public}" PRIu64"",
56         reason, screenId_, rsId_);
57     TLOGI(WmsLogTag::DMS,
58         "[DPNODE]Config name: %{public}s, defaultId: %{public}" PRIu64", mirrorNodeId: %{public}" PRIu64"",
59         name_.c_str(), defaultScreenId_, config.mirrorNodeId);
60     Rosen::RSDisplayNodeConfig rsConfig;
61     bool isNeedCreateDisplayNode = true;
62     switch (reason) {
63         case ScreenSessionReason::CREATE_SESSION_FOR_CLIENT: {
64             TLOGI(WmsLogTag::DMS, "create screen session for client. noting to do.");
65             return;
66         }
67         case ScreenSessionReason::CREATE_SESSION_FOR_VIRTUAL: {
68             // create virtual screen should use rsid
69             rsConfig.screenId = rsId_;
70             break;
71         }
72         case ScreenSessionReason::CREATE_SESSION_FOR_MIRROR: {
73             rsConfig.screenId = screenId_;
74             rsConfig.isMirrored = true;
75             rsConfig.mirrorNodeId = config.mirrorNodeId;
76             rsConfig.isSync = true;
77             break;
78         }
79         case ScreenSessionReason::CREATE_SESSION_FOR_REAL: {
80             rsConfig.screenId = screenId_;
81             break;
82         }
83         case ScreenSessionReason::CREATE_SESSION_WITHOUT_DISPLAY_NODE: {
84             TLOGI(WmsLogTag::DMS, "screen session no need create displayNode.");
85             isNeedCreateDisplayNode = false;
86             break;
87         }
88         default : {
89             TLOGE(WmsLogTag::DMS, "INVALID invalid screen session config.");
90             break;
91         }
92     }
93     if (isNeedCreateDisplayNode) {
94         CreateDisplayNode(rsConfig);
95     }
96 }
97 
CreateDisplayNode(const Rosen::RSDisplayNodeConfig & config)98 void ScreenSession::CreateDisplayNode(const Rosen::RSDisplayNodeConfig& config)
99 {
100     TLOGI(WmsLogTag::DMS,
101         "[DPNODE]config screenId: %{public}" PRIu64", mirrorNodeId: %{public}" PRIu64", isMirrored: %{public}d",
102         config.screenId, config.mirrorNodeId, static_cast<int32_t>(config.isMirrored));
103     {
104         std::unique_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
105         displayNode_ = Rosen::RSDisplayNode::Create(config);
106         if (displayNode_) {
107             displayNode_->SetFrame(property_.GetBounds().rect_.left_, property_.GetBounds().rect_.top_,
108                 property_.GetBounds().rect_.width_, property_.GetBounds().rect_.height_);
109             displayNode_->SetBounds(property_.GetBounds().rect_.left_, property_.GetBounds().rect_.top_,
110                 property_.GetBounds().rect_.width_, property_.GetBounds().rect_.height_);
111             if (config.isMirrored) {
112                 EnableMirrorScreenRegion();
113             }
114         } else {
115             TLOGE(WmsLogTag::DMS, "Failed to create displayNode, displayNode is null!");
116         }
117     }
118     RSTransaction::FlushImplicitTransaction();
119 }
120 
~ScreenSession()121 ScreenSession::~ScreenSession()
122 {
123     WLOGI("~ScreenSession");
124 }
125 
ScreenSession(ScreenId screenId,ScreenId rsId,const std::string & name,const ScreenProperty & property,const std::shared_ptr<RSDisplayNode> & displayNode)126 ScreenSession::ScreenSession(ScreenId screenId, ScreenId rsId, const std::string& name,
127     const ScreenProperty& property, const std::shared_ptr<RSDisplayNode>& displayNode)
128     : name_(name), screenId_(screenId), rsId_(rsId), property_(property), displayNode_(displayNode)
129 {
130     WLOGFI("Success to create screenSession in constructor_0, screenid is %{public}" PRIu64"", screenId_);
131 }
132 
ScreenSession(ScreenId screenId,const ScreenProperty & property,ScreenId defaultScreenId)133 ScreenSession::ScreenSession(ScreenId screenId, const ScreenProperty& property, ScreenId defaultScreenId)
134     : screenId_(screenId), defaultScreenId_(defaultScreenId), property_(property)
135 {
136     Rosen::RSDisplayNodeConfig config = { .screenId = screenId_ };
137     displayNode_ = Rosen::RSDisplayNode::Create(config);
138     if (displayNode_) {
139         WLOGI("Success to create displayNode in constructor_1, 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(ScreenId screenId,const ScreenProperty & property,NodeId nodeId,ScreenId defaultScreenId)150 ScreenSession::ScreenSession(ScreenId screenId, const ScreenProperty& property,
151     NodeId nodeId, ScreenId defaultScreenId)
152     : screenId_(screenId), defaultScreenId_(defaultScreenId), property_(property)
153 {
154     rsId_ = screenId;
155     Rosen::RSDisplayNodeConfig config = { .screenId = screenId_, .isMirrored = true, .mirrorNodeId = nodeId,
156         .isSync = true};
157     displayNode_ = Rosen::RSDisplayNode::Create(config);
158     if (displayNode_) {
159         WLOGI("Success to create displayNode in constructor_2, screenid is %{public}" PRIu64"", screenId_);
160         displayNode_->SetFrame(property_.GetBounds().rect_.left_, property_.GetBounds().rect_.top_,
161             property_.GetBounds().rect_.width_, property_.GetBounds().rect_.height_);
162         displayNode_->SetBounds(property_.GetBounds().rect_.left_, property_.GetBounds().rect_.top_,
163             property_.GetBounds().rect_.width_, property_.GetBounds().rect_.height_);
164     } else {
165         WLOGFE("Failed to create displayNode, displayNode is null!");
166     }
167     RSTransaction::FlushImplicitTransaction();
168 }
169 
ScreenSession(const std::string & name,ScreenId smsId,ScreenId rsId,ScreenId defaultScreenId)170 ScreenSession::ScreenSession(const std::string& name, ScreenId smsId, ScreenId rsId, ScreenId defaultScreenId)
171     : name_(name), screenId_(smsId), rsId_(rsId), defaultScreenId_(defaultScreenId)
172 {
173     (void)rsId_;
174     // 虚拟屏的screen id和rs id不一致,displayNode的创建应使用rs id
175     Rosen::RSDisplayNodeConfig config = { .screenId = rsId_ };
176     displayNode_ = Rosen::RSDisplayNode::Create(config);
177     if (displayNode_) {
178         WLOGI("Success to create displayNode in constructor_3, rs id is %{public}" PRIu64"", rsId_);
179         displayNode_->SetFrame(property_.GetBounds().rect_.left_, property_.GetBounds().rect_.top_,
180             property_.GetBounds().rect_.width_, property_.GetBounds().rect_.height_);
181         displayNode_->SetBounds(property_.GetBounds().rect_.left_, property_.GetBounds().rect_.top_,
182             property_.GetBounds().rect_.width_, property_.GetBounds().rect_.height_);
183     } else {
184         WLOGFE("Failed to create displayNode, displayNode is null!");
185     }
186     RSTransaction::FlushImplicitTransaction();
187 }
188 
SetMirrorScreenType(MirrorScreenType mirrorType)189 void ScreenSession::SetMirrorScreenType(MirrorScreenType mirrorType)
190 {
191     mirrorScreenType_ = mirrorType;
192 }
193 
GetMirrorScreenType()194 MirrorScreenType ScreenSession::GetMirrorScreenType()
195 {
196     return mirrorScreenType_;
197 }
198 
SetDisplayNodeScreenId(ScreenId screenId)199 void ScreenSession::SetDisplayNodeScreenId(ScreenId screenId)
200 {
201     std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
202     if (displayNode_ != nullptr) {
203         WLOGFI("SetDisplayNodeScreenId %{public}" PRIu64"", screenId);
204         displayNode_->SetScreenId(screenId);
205     }
206 }
207 
RegisterScreenChangeListener(IScreenChangeListener * screenChangeListener)208 void ScreenSession::RegisterScreenChangeListener(IScreenChangeListener* screenChangeListener)
209 {
210     if (screenChangeListener == nullptr) {
211         WLOGFE("Failed to register screen change listener, listener is null!");
212         return;
213     }
214     std::lock_guard<std::mutex> lock(screenChangeListenerListMutex_);
215     if (std::find(screenChangeListenerList_.begin(), screenChangeListenerList_.end(), screenChangeListener) !=
216         screenChangeListenerList_.end()) {
217         WLOGFI("Repeat to register screen change listener!");
218         return;
219     }
220 
221     screenChangeListenerList_.emplace_back(screenChangeListener);
222     if (screenState_ == ScreenState::CONNECTION) {
223         screenChangeListener->OnConnect(screenId_);
224         WLOGFI("Success to call onconnect callback.");
225     }
226     WLOGFI("Success to register screen change listener.");
227 }
228 
UnregisterScreenChangeListener(IScreenChangeListener * screenChangeListener)229 void ScreenSession::UnregisterScreenChangeListener(IScreenChangeListener* screenChangeListener)
230 {
231     if (screenChangeListener == nullptr) {
232         WLOGFE("Failed to unregister screen change listener, listener is null!");
233         return;
234     }
235 
236     screenChangeListenerList_.erase(
237         std::remove_if(screenChangeListenerList_.begin(), screenChangeListenerList_.end(),
238             [screenChangeListener](IScreenChangeListener* listener) { return screenChangeListener == listener; }),
239         screenChangeListenerList_.end());
240 }
241 
SetMirrorScreenRegion(ScreenId screenId,DMRect screenRegion)242 void ScreenSession::SetMirrorScreenRegion(ScreenId screenId, DMRect screenRegion)
243 {
244     std::lock_guard<std::mutex> lock(mirrorScreenRegionMutex_);
245     mirrorScreenRegion_ = std::make_pair(screenId, screenRegion);
246 }
247 
GetMirrorScreenRegion()248 std::pair<ScreenId, DMRect> ScreenSession::GetMirrorScreenRegion()
249 {
250     std::lock_guard<std::mutex> lock(mirrorScreenRegionMutex_);
251     return mirrorScreenRegion_;
252 }
253 
EnableMirrorScreenRegion()254 void ScreenSession::EnableMirrorScreenRegion()
255 {
256     const auto& mirrorScreenRegionPair = GetMirrorScreenRegion();
257     const auto& rect = mirrorScreenRegionPair.second;
258     ScreenId screenId = INVALID_SCREEN_ID;
259     if (isPhysicalMirrorSwitch_) {
260         screenId = screenId_;
261     } else {
262         screenId = rsId_;
263     }
264     int32_t ret = StatusCode::SUCCESS;
265     if (ret != StatusCode::SUCCESS) {
266         WLOGE("ScreenSession::EnableMirrorScreenRegion fail! rsId %{public}" PRIu64", ret:%{public}d," PRIu64
267         ", x:%{public}d y:%{public}d w:%{public}u h:%{public}u", screenId, ret,
268         rect.posX_, rect.posY_, rect.width_, rect.height_);
269     } else {
270         WLOGE("ScreenSession::EnableMirrorScreenRegion success! rsId %{public}" PRIu64", ret:%{public}d," PRIu64
271         ", x:%{public}d y:%{public}d w:%{public}u h:%{public}u", screenId, ret,
272         rect.posX_, rect.posY_, rect.width_, rect.height_);
273     }
274 }
275 
ConvertToDisplayInfo()276 sptr<DisplayInfo> ScreenSession::ConvertToDisplayInfo()
277 {
278     sptr<DisplayInfo> displayInfo = new(std::nothrow) DisplayInfo();
279     if (displayInfo == nullptr) {
280         return displayInfo;
281     }
282     displayInfo->name_ = name_;
283     displayInfo->SetWidth(property_.GetBounds().rect_.GetWidth());
284     displayInfo->SetHeight(property_.GetBounds().rect_.GetHeight());
285     displayInfo->SetPhysicalWidth(property_.GetPhyBounds().rect_.GetWidth());
286     displayInfo->SetPhysicalHeight(property_.GetPhyBounds().rect_.GetHeight());
287     displayInfo->SetScreenId(screenId_);
288     displayInfo->SetDisplayId(screenId_);
289     displayInfo->SetRefreshRate(property_.GetRefreshRate());
290     displayInfo->SetVirtualPixelRatio(property_.GetVirtualPixelRatio());
291     displayInfo->SetDensityInCurResolution(property_.GetDensityInCurResolution());
292     displayInfo->SetDefaultVirtualPixelRatio(property_.GetDefaultDensity());
293     displayInfo->SetXDpi(property_.GetXDpi());
294     displayInfo->SetYDpi(property_.GetYDpi());
295     displayInfo->SetDpi(property_.GetVirtualPixelRatio() * DOT_PER_INCH);
296     int32_t apiVersion = GetApiVersion();
297     if (apiVersion >= 14 || apiVersion == 0) { // 14 is API version
298         displayInfo->SetRotation(property_.GetDeviceRotation());
299         displayInfo->SetDisplayOrientation(property_.GetDeviceOrientation());
300     } else {
301         displayInfo->SetRotation(property_.GetScreenRotation());
302         displayInfo->SetDisplayOrientation(property_.GetDisplayOrientation());
303     }
304     displayInfo->SetOrientation(property_.GetOrientation());
305     displayInfo->SetOffsetX(property_.GetOffsetX());
306     displayInfo->SetOffsetY(property_.GetOffsetY());
307     displayInfo->SetHdrFormats(hdrFormats_);
308     displayInfo->SetColorSpaces(colorSpaces_);
309     displayInfo->SetDisplayState(property_.GetDisplayState());
310     displayInfo->SetDefaultDeviceRotationOffset(property_.GetDefaultDeviceRotationOffset());
311     displayInfo->SetAvailableWidth(property_.GetAvailableArea().width_);
312     displayInfo->SetAvailableHeight(property_.GetAvailableArea().height_);
313     displayInfo->SetScaleX(property_.GetScaleX());
314     displayInfo->SetScaleY(property_.GetScaleY());
315     displayInfo->SetPivotX(property_.GetPivotX());
316     displayInfo->SetPivotY(property_.GetPivotY());
317     displayInfo->SetTranslateX(property_.GetTranslateX());
318     displayInfo->SetTranslateY(property_.GetTranslateY());
319     displayInfo->SetOriginRotation(property_.GetScreenRotation());
320     return displayInfo;
321 }
322 
GetScreenSupportedColorGamuts(std::vector<ScreenColorGamut> & colorGamuts)323 DMError ScreenSession::GetScreenSupportedColorGamuts(std::vector<ScreenColorGamut>& colorGamuts)
324 {
325     auto ret = RSInterfaces::GetInstance().GetScreenSupportedColorGamuts(rsId_, colorGamuts);
326     if (ret != StatusCode::SUCCESS) {
327         WLOGE("SCB: ScreenSession::GetScreenSupportedColorGamuts fail! rsId %{public}" PRIu64", ret:%{public}d",
328             rsId_, ret);
329         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
330     }
331     WLOGI("SCB: ScreenSession::GetScreenSupportedColorGamuts ok! rsId %{public}" PRIu64", size %{public}u",
332         rsId_, static_cast<uint32_t>(colorGamuts.size()));
333 
334     return DMError::DM_OK;
335 }
336 
SetIsExtend(bool isExtend)337 void ScreenSession::SetIsExtend(bool isExtend)
338 {
339     isExtended_ = isExtend;
340 }
341 
GetIsExtend() const342 bool ScreenSession::GetIsExtend() const
343 {
344     return isExtended_;
345 }
346 
SetIsRealScreen(bool isReal)347 void ScreenSession::SetIsRealScreen(bool isReal)
348 {
349     isReal_ = isReal;
350 }
351 
GetIsRealScreen()352 bool ScreenSession::GetIsRealScreen()
353 {
354     return isReal_;
355 }
356 
SetIsInternal(bool isInternal)357 void ScreenSession::SetIsInternal(bool isInternal)
358 {
359     isInternal_ = isInternal;
360 }
361 
GetIsInternal() const362 bool ScreenSession::GetIsInternal() const
363 {
364     return isInternal_;
365 }
366 
GetName()367 std::string ScreenSession::GetName()
368 {
369     return name_;
370 }
371 
SetName(std::string name)372 void ScreenSession::SetName(std::string name)
373 {
374     name_ = name;
375 }
376 
GetScreenId()377 ScreenId ScreenSession::GetScreenId()
378 {
379     return screenId_;
380 }
381 
GetRSScreenId()382 ScreenId ScreenSession::GetRSScreenId()
383 {
384     return rsId_;
385 }
386 
GetScreenProperty() const387 ScreenProperty ScreenSession::GetScreenProperty() const
388 {
389     return property_;
390 }
391 
SetScreenScale(float scaleX,float scaleY,float pivotX,float pivotY,float translateX,float translateY)392 void ScreenSession::SetScreenScale(float scaleX, float scaleY, float pivotX, float pivotY, float translateX,
393                                    float translateY)
394 {
395     property_.SetScaleX(scaleX);
396     property_.SetScaleY(scaleY);
397     property_.SetPivotX(pivotX);
398     property_.SetPivotY(pivotY);
399     property_.SetTranslateX(translateX);
400     property_.SetTranslateY(translateY);
401 }
402 
SetDefaultDeviceRotationOffset(uint32_t defaultRotationOffset)403 void ScreenSession::SetDefaultDeviceRotationOffset(uint32_t defaultRotationOffset)
404 {
405     WLOGFI("set device default rotation offset: %{public}u", defaultRotationOffset);
406     property_.SetDefaultDeviceRotationOffset(defaultRotationOffset);
407 }
408 
UpdatePropertyByActiveMode()409 void ScreenSession::UpdatePropertyByActiveMode()
410 {
411     sptr<SupportedScreenModes> mode = GetActiveScreenMode();
412     if (mode != nullptr) {
413         auto screeBounds = property_.GetBounds();
414         screeBounds.rect_.width_ = mode->width_;
415         screeBounds.rect_.height_ = mode->height_;
416         property_.SetBounds(screeBounds);
417     }
418 }
419 
UpdatePropertyByFoldControl(const ScreenProperty & updatedProperty,FoldDisplayMode foldDisplayMode)420 void ScreenSession::UpdatePropertyByFoldControl(const ScreenProperty& updatedProperty,
421     FoldDisplayMode foldDisplayMode)
422 {
423     property_.SetDpiPhyBounds(updatedProperty.GetPhyWidth(), updatedProperty.GetPhyHeight());
424     property_.SetPhyBounds(updatedProperty.GetPhyBounds());
425     property_.SetBounds(updatedProperty.GetBounds());
426     OptimizeSecondaryDisplayMode(updatedProperty.GetBounds(), foldDisplayMode);
427     UpdateTouchBoundsAndOffset(foldDisplayMode);
428 }
429 
UpdateDisplayState(DisplayState displayState)430 void ScreenSession::UpdateDisplayState(DisplayState displayState)
431 {
432     property_.SetDisplayState(displayState);
433 }
434 
UpdateRefreshRate(uint32_t refreshRate)435 void ScreenSession::UpdateRefreshRate(uint32_t refreshRate)
436 {
437     property_.SetRefreshRate(refreshRate);
438 }
439 
GetRefreshRate()440 uint32_t ScreenSession::GetRefreshRate()
441 {
442     return property_.GetRefreshRate();
443 }
444 
UpdatePropertyByResolution(uint32_t width,uint32_t height)445 void ScreenSession::UpdatePropertyByResolution(uint32_t width, uint32_t height)
446 {
447     auto screenBounds = property_.GetBounds();
448     screenBounds.rect_.width_ = width;
449     screenBounds.rect_.height_ = height;
450     property_.SetBounds(screenBounds);
451 }
452 
GetDisplayNode() const453 std::shared_ptr<RSDisplayNode> ScreenSession::GetDisplayNode() const
454 {
455     std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
456     return displayNode_;
457 }
458 
ReleaseDisplayNode()459 void ScreenSession::ReleaseDisplayNode()
460 {
461     std::unique_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
462     displayNode_ = nullptr;
463     WLOGFI("displayNode_ is released.");
464 }
465 
Connect()466 void ScreenSession::Connect()
467 {
468     std::lock_guard<std::mutex> lock(screenChangeListenerListMutex_);
469     screenState_ = ScreenState::CONNECTION;
470     if (screenChangeListenerList_.empty()) {
471         WLOGFE("screenChangeListenerList is empty.");
472         return;
473     }
474     for (auto& listener : screenChangeListenerList_) {
475         if (!listener) {
476             WLOGFE("screenChangeListener is null.");
477             continue;
478         }
479         listener->OnConnect(screenId_);
480     }
481 }
482 
Disconnect()483 void ScreenSession::Disconnect()
484 {
485     std::lock_guard<std::mutex> lock(screenChangeListenerListMutex_);
486     screenState_ = ScreenState::DISCONNECTION;
487     for (auto& listener : screenChangeListenerList_) {
488         if (!listener) {
489             continue;
490         }
491         listener->OnDisconnect(screenId_);
492     }
493 }
494 
PropertyChange(const ScreenProperty & newProperty,ScreenPropertyChangeReason reason)495 void ScreenSession::PropertyChange(const ScreenProperty& newProperty, ScreenPropertyChangeReason reason)
496 {
497     std::lock_guard<std::mutex> lock(screenChangeListenerListMutex_);
498     property_ = newProperty;
499     for (auto& listener : screenChangeListenerList_) {
500         if (!listener) {
501             continue;
502         }
503         listener->OnPropertyChange(newProperty, reason, screenId_);
504     }
505 }
506 
PowerStatusChange(DisplayPowerEvent event,EventStatus status,PowerStateChangeReason reason)507 void ScreenSession::PowerStatusChange(DisplayPowerEvent event, EventStatus status, PowerStateChangeReason reason)
508 {
509     std::lock_guard<std::mutex> lock(screenChangeListenerListMutex_);
510     for (auto& listener : screenChangeListenerList_) {
511         if (!listener) {
512             continue;
513         }
514         listener->OnPowerStatusChange(event, status, reason);
515     }
516 }
517 
ConvertRotationToFloat(Rotation sensorRotation)518 float ScreenSession::ConvertRotationToFloat(Rotation sensorRotation)
519 {
520     float rotation = 0.f;
521     switch (sensorRotation) {
522         case Rotation::ROTATION_90:
523             rotation = 90.f; // degree 90
524             break;
525         case Rotation::ROTATION_180:
526             rotation = 180.f; // degree 180
527             break;
528         case Rotation::ROTATION_270:
529             rotation = 270.f; // degree 270
530             break;
531         default:
532             rotation = 0.f;
533             break;
534     }
535     return rotation;
536 }
537 
HandleSensorRotation(float sensorRotation)538 void ScreenSession::HandleSensorRotation(float sensorRotation)
539 {
540     SensorRotationChange(sensorRotation);
541 }
542 
SensorRotationChange(Rotation sensorRotation)543 void ScreenSession::SensorRotationChange(Rotation sensorRotation)
544 {
545     float rotation = ConvertRotationToFloat(sensorRotation);
546     SensorRotationChange(rotation);
547 }
548 
SensorRotationChange(float sensorRotation)549 void ScreenSession::SensorRotationChange(float sensorRotation)
550 {
551     std::lock_guard<std::mutex> lock(screenChangeListenerListMutex_);
552     if (sensorRotation >= 0.0f) {
553         currentValidSensorRotation_ = sensorRotation;
554     }
555     currentSensorRotation_ = sensorRotation;
556     for (auto& listener : screenChangeListenerList_) {
557         if (!listener) {
558             WLOGFE("screenChangeListener is null.");
559             continue;
560         }
561         listener->OnSensorRotationChange(sensorRotation, screenId_);
562     }
563 }
564 
GetValidSensorRotation()565 float ScreenSession::GetValidSensorRotation()
566 {
567     return currentValidSensorRotation_;
568 }
569 
HandleHoverStatusChange(int32_t hoverStatus,bool needRotate)570 void ScreenSession::HandleHoverStatusChange(int32_t hoverStatus, bool needRotate)
571 {
572     HoverStatusChange(hoverStatus, needRotate);
573 }
574 
HoverStatusChange(int32_t hoverStatus,bool needRotate)575 void ScreenSession::HoverStatusChange(int32_t hoverStatus, bool needRotate)
576 {
577     std::lock_guard<std::mutex> lock(screenChangeListenerListMutex_);
578     for (auto& listener : screenChangeListenerList_) {
579         if (!listener) {
580             WLOGFE("screenChangeListener is null.");
581             continue;
582         }
583         listener->OnHoverStatusChange(hoverStatus, needRotate, screenId_);
584     }
585 }
586 
HandleCameraBackSelfieChange(bool isCameraBackSelfie)587 void ScreenSession::HandleCameraBackSelfieChange(bool isCameraBackSelfie)
588 {
589     CameraBackSelfieChange(isCameraBackSelfie);
590 }
591 
CameraBackSelfieChange(bool isCameraBackSelfie)592 void ScreenSession::CameraBackSelfieChange(bool isCameraBackSelfie)
593 {
594     std::lock_guard<std::mutex> lock(screenChangeListenerListMutex_);
595     for (auto& listener : screenChangeListenerList_) {
596         if (!listener) {
597             WLOGFE("screenChangeListener is null.");
598             continue;
599         }
600         listener->OnCameraBackSelfieChange(isCameraBackSelfie, screenId_);
601     }
602 }
603 
ScreenOrientationChange(Orientation orientation,FoldDisplayMode foldDisplayMode)604 void ScreenSession::ScreenOrientationChange(Orientation orientation, FoldDisplayMode foldDisplayMode)
605 {
606     Rotation rotationAfter = CalcRotation(orientation, foldDisplayMode);
607     float screenRotation = ConvertRotationToFloat(rotationAfter);
608     ScreenOrientationChange(screenRotation);
609 }
610 
ScreenOrientationChange(float orientation)611 void ScreenSession::ScreenOrientationChange(float orientation)
612 {
613     std::lock_guard<std::mutex> lock(screenChangeListenerListMutex_);
614     for (auto& listener : screenChangeListenerList_) {
615         if (!listener) {
616             WLOGFE("screenChangeListener is null.");
617             continue;
618         }
619         listener->OnScreenOrientationChange(orientation, screenId_);
620     }
621 }
622 
ConvertIntToRotation(int rotation)623 Rotation ScreenSession::ConvertIntToRotation(int rotation)
624 {
625     Rotation targetRotation = Rotation::ROTATION_0;
626     switch (rotation) {
627         case 90: // Rotation 90 degree
628             targetRotation = Rotation::ROTATION_90;
629             break;
630         case 180: // Rotation 180 degree
631             targetRotation = Rotation::ROTATION_180;
632             break;
633         case 270: // Rotation 270 degree
634             targetRotation = Rotation::ROTATION_270;
635             break;
636         default:
637             targetRotation = Rotation::ROTATION_0;
638             break;
639     }
640     return targetRotation;
641 }
642 
SetUpdateToInputManagerCallback(std::function<void (float)> updateToInputManagerCallback)643 void ScreenSession::SetUpdateToInputManagerCallback(std::function<void(float)> updateToInputManagerCallback)
644 {
645     updateToInputManagerCallback_ = updateToInputManagerCallback;
646 }
647 
SetUpdateScreenPivotCallback(std::function<void (float,float)> && updateScreenPivotCallback)648 void ScreenSession::SetUpdateScreenPivotCallback(std::function<void(float, float)>&& updateScreenPivotCallback)
649 {
650     updateScreenPivotCallback_ = std::move(updateScreenPivotCallback);
651 }
652 
GetVirtualScreenFlag()653 VirtualScreenFlag ScreenSession::GetVirtualScreenFlag()
654 {
655     return screenFlag_;
656 }
657 
SetVirtualScreenFlag(VirtualScreenFlag screenFlag)658 void ScreenSession::SetVirtualScreenFlag(VirtualScreenFlag screenFlag)
659 {
660     screenFlag_ = screenFlag;
661 }
662 
UpdateTouchBoundsAndOffset(FoldDisplayMode foldDisplayMode)663 void ScreenSession::UpdateTouchBoundsAndOffset(FoldDisplayMode foldDisplayMode)
664 {
665     WLOGFI("foldDisplayMode:%{public}u", foldDisplayMode);
666     property_.SetPhysicalTouchBounds(FoldScreenStateInternel::IsSecondaryDisplayFoldDevice());
667     property_.SetInputOffsetY(FoldScreenStateInternel::IsSecondaryDisplayFoldDevice(), foldDisplayMode);
668 }
669 
UpdateToInputManager(RRect bounds,int rotation,int deviceRotation,FoldDisplayMode foldDisplayMode)670 void ScreenSession::UpdateToInputManager(RRect bounds, int rotation, int deviceRotation,
671     FoldDisplayMode foldDisplayMode)
672 {
673     OptimizeSecondaryDisplayMode(bounds, foldDisplayMode);
674     bool needUpdateToInputManager = false;
675     if (foldDisplayMode == FoldDisplayMode::FULL && g_screenRotationOffSet == ROTATION_270 &&
676         property_.GetBounds() == bounds && property_.GetRotation() != static_cast<float>(rotation)) {
677         needUpdateToInputManager = true;
678     }
679     Rotation targetRotation = ConvertIntToRotation(rotation);
680     DisplayOrientation displayOrientation = CalcDisplayOrientation(targetRotation, foldDisplayMode);
681     property_.SetBounds(bounds);
682     property_.SetRotation(static_cast<float>(rotation));
683     property_.UpdateScreenRotation(targetRotation);
684     property_.SetDisplayOrientation(displayOrientation);
685     UpdateTouchBoundsAndOffset(foldDisplayMode);
686     Rotation targetDeviceRotation = ConvertIntToRotation(deviceRotation);
687     DisplayOrientation deviceOrientation = CalcDeviceOrientation(targetDeviceRotation, foldDisplayMode);
688     property_.UpdateDeviceRotation(targetDeviceRotation);
689     property_.SetDeviceOrientation(deviceOrientation);
690     if (needUpdateToInputManager && updateToInputManagerCallback_ != nullptr) {
691         // fold phone need fix 90 degree by remainder 360 degree
692         int foldRotation = (rotation + 90) % 360;
693         updateToInputManagerCallback_(static_cast<float>(foldRotation));
694         WLOGFI("updateToInputManagerCallback_:%{public}d", foldRotation);
695     }
696 }
697 
SetPhysicalRotation(int rotation)698 void ScreenSession::SetPhysicalRotation(int rotation)
699 {
700     property_.SetPhysicalRotation(static_cast<float>(rotation));
701     WLOGFI("physicalrotation :%{public}f", property_.GetPhysicalRotation());
702 }
703 
SetScreenComponentRotation(int rotation)704 void ScreenSession::SetScreenComponentRotation(int rotation)
705 {
706     property_.SetScreenComponentRotation(static_cast<float>(rotation));
707     WLOGFI("screenComponentRotation :%{public}f ", property_.GetScreenComponentRotation());
708 }
709 
IsWidthHeightMatch(float width,float height,float targetWidth,float targetHeight)710 bool ScreenSession::IsWidthHeightMatch(float width, float height, float targetWidth, float targetHeight)
711 {
712     return (width == targetWidth && height == targetHeight) || (width == targetHeight && height == targetWidth);
713 }
714 
OptimizeSecondaryDisplayMode(const RRect & bounds,FoldDisplayMode & foldDisplayMode)715 void ScreenSession::OptimizeSecondaryDisplayMode(const RRect &bounds, FoldDisplayMode &foldDisplayMode)
716 {
717     if (!FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
718         return;
719     }
720     if (IsWidthHeightMatch(bounds.rect_.GetWidth(), bounds.rect_.GetHeight(),
721         MAIN_STATUS_WIDTH, SCREEN_HEIGHT)) {
722         foldDisplayMode = FoldDisplayMode::MAIN;
723     } else if (IsWidthHeightMatch(bounds.rect_.GetWidth(), bounds.rect_.GetHeight(),
724         FULL_STATUS_WIDTH, SCREEN_HEIGHT)) {
725         foldDisplayMode = FoldDisplayMode::FULL;
726     } else if (IsWidthHeightMatch(bounds.rect_.GetWidth(), bounds.rect_.GetHeight(),
727         GLOBAL_FULL_STATUS_WIDTH, SCREEN_HEIGHT)) {
728         foldDisplayMode = FoldDisplayMode::GLOBAL_FULL;
729     }
730 }
731 
UpdatePropertyAfterRotation(RRect bounds,int rotation,FoldDisplayMode foldDisplayMode)732 void ScreenSession::UpdatePropertyAfterRotation(RRect bounds, int rotation, FoldDisplayMode foldDisplayMode)
733 {
734     OptimizeSecondaryDisplayMode(bounds, foldDisplayMode);
735     Rotation targetRotation = ConvertIntToRotation(rotation);
736     DisplayOrientation displayOrientation = CalcDisplayOrientation(targetRotation, foldDisplayMode);
737     property_.SetBounds(bounds);
738     property_.SetRotation(static_cast<float>(rotation));
739     property_.UpdateScreenRotation(targetRotation);
740     property_.SetDisplayOrientation(displayOrientation);
741     UpdateTouchBoundsAndOffset(foldDisplayMode);
742     {
743         std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
744         if (!displayNode_) {
745             WLOGFI("update failed since null display node with rotation:%{public}d displayOrientation:%{public}u",
746                 rotation, displayOrientation);
747             return;
748         }
749     }
750     auto transactionProxy = RSTransactionProxy::GetInstance();
751     if (transactionProxy != nullptr) {
752         transactionProxy->Begin();
753         {
754             std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
755             displayNode_->SetScreenRotation(static_cast<uint32_t>(property_.GetDeviceRotation()));
756         }
757         transactionProxy->Commit();
758     } else {
759         {
760             std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
761             displayNode_->SetScreenRotation(static_cast<uint32_t>(property_.GetDeviceRotation()));
762         }
763     }
764     WLOGFI("bounds:[%{public}f %{public}f %{public}f %{public}f],rotation:%{public}d,displayOrientation:%{public}u,\
765         foldDisplayMode:%{public}u",
766         property_.GetBounds().rect_.GetLeft(), property_.GetBounds().rect_.GetTop(),
767         property_.GetBounds().rect_.GetWidth(), property_.GetBounds().rect_.GetHeight(),
768         rotation, displayOrientation, foldDisplayMode);
769     ReportNotifyModeChange(displayOrientation);
770 }
771 
UpdatePropertyOnly(RRect bounds,int rotation,FoldDisplayMode foldDisplayMode)772 void ScreenSession::UpdatePropertyOnly(RRect bounds, int rotation, FoldDisplayMode foldDisplayMode)
773 {
774     OptimizeSecondaryDisplayMode(bounds, foldDisplayMode);
775     Rotation targetRotation = ConvertIntToRotation(rotation);
776     DisplayOrientation displayOrientation = CalcDisplayOrientation(targetRotation, foldDisplayMode);
777     property_.SetBounds(bounds);
778     property_.SetRotation(static_cast<float>(rotation));
779     property_.UpdateScreenRotation(targetRotation);
780     property_.SetDisplayOrientation(displayOrientation);
781     UpdateTouchBoundsAndOffset(foldDisplayMode);
782     WLOGFI("bounds:[%{public}f %{public}f %{public}f %{public}f],rotation:%{public}d,displayOrientation:%{public}u",
783         property_.GetBounds().rect_.GetLeft(), property_.GetBounds().rect_.GetTop(),
784         property_.GetBounds().rect_.GetWidth(), property_.GetBounds().rect_.GetHeight(),
785         rotation, displayOrientation);
786 }
787 
UpdateRotationOrientation(int rotation,FoldDisplayMode foldDisplayMode)788 void ScreenSession::UpdateRotationOrientation(int rotation, FoldDisplayMode foldDisplayMode)
789 {
790     Rotation targetRotation = ConvertIntToRotation(rotation);
791     DisplayOrientation deviceOrientation = CalcDeviceOrientation(targetRotation, foldDisplayMode);
792     property_.UpdateDeviceRotation(targetRotation);
793     property_.SetDeviceOrientation(deviceOrientation);
794     WLOGFI("rotation:%{public}d, orientation:%{public}u", rotation, deviceOrientation);
795 }
796 
ReportNotifyModeChange(DisplayOrientation displayOrientation)797 void ScreenSession::ReportNotifyModeChange(DisplayOrientation displayOrientation)
798 {
799     int32_t vhMode = 1;
800     if (displayOrientation == DisplayOrientation::PORTRAIT_INVERTED ||
801         displayOrientation == DisplayOrientation::PORTRAIT) {
802         vhMode = 0;
803     }
804     int32_t ret = HiSysEventWrite(
805         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
806         "VH_MODE",
807         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
808         "MODE", vhMode);
809     if (ret != 0) {
810         TLOGE(WmsLogTag::DMS, "ReportNotifyModeChange Write HiSysEvent error, ret: %{public}d", ret);
811     }
812 }
813 
UpdateRotationAfterBoot(bool foldToExpand)814 void ScreenSession::UpdateRotationAfterBoot(bool foldToExpand)
815 {
816     TLOGI(WmsLogTag::DMS, "foldToExpand: %{public}d, Rotation: %{public}f",
817         static_cast<int32_t>(foldToExpand), currentSensorRotation_);
818     if (foldToExpand) {
819         SensorRotationChange(currentSensorRotation_);
820     }
821 }
822 
UpdateValidRotationToScb()823 void ScreenSession::UpdateValidRotationToScb()
824 {
825     TLOGI(WmsLogTag::DMS, "Rotation: %{public}f", currentValidSensorRotation_);
826     SensorRotationChange(currentValidSensorRotation_);
827 }
828 
GetActiveScreenMode() const829 sptr<SupportedScreenModes> ScreenSession::GetActiveScreenMode() const
830 {
831     if (activeIdx_ < 0 || activeIdx_ >= static_cast<int32_t>(modes_.size())) {
832         WLOGW("SCB: ScreenSession::GetActiveScreenMode active mode index is wrong: %{public}d", activeIdx_);
833         return nullptr;
834     }
835     return modes_[activeIdx_];
836 }
837 
GetOrientation() const838 Orientation ScreenSession::GetOrientation() const
839 {
840     return property_.GetOrientation();
841 }
842 
SetOrientation(Orientation orientation)843 void ScreenSession::SetOrientation(Orientation orientation)
844 {
845     property_.SetOrientation(orientation);
846 }
847 
GetRotation() const848 Rotation ScreenSession::GetRotation() const
849 {
850     return property_.GetScreenRotation();
851 }
852 
SetRotation(Rotation rotation)853 void ScreenSession::SetRotation(Rotation rotation)
854 {
855     property_.SetScreenRotation(rotation);
856 }
857 
SetRotationAndScreenRotationOnly(Rotation rotation)858 void ScreenSession::SetRotationAndScreenRotationOnly(Rotation rotation)
859 {
860     property_.SetRotationAndScreenRotationOnly(rotation);
861 }
862 
SetScreenRequestedOrientation(Orientation orientation)863 void ScreenSession::SetScreenRequestedOrientation(Orientation orientation)
864 {
865     property_.SetScreenRequestedOrientation(orientation);
866 }
867 
SetScreenRotationLocked(bool isLocked)868 void ScreenSession::SetScreenRotationLocked(bool isLocked)
869 {
870     std::lock_guard<std::mutex> lock(screenChangeListenerListMutex_);
871     isScreenLocked_ = isLocked;
872     for (auto& listener : screenChangeListenerList_) {
873         if (!listener) {
874             continue;
875         }
876         listener->OnScreenRotationLockedChange(isLocked, screenId_);
877     }
878 }
879 
SetScreenRotationLockedFromJs(bool isLocked)880 void ScreenSession::SetScreenRotationLockedFromJs(bool isLocked)
881 {
882     isScreenLocked_ = isLocked;
883 }
884 
IsScreenRotationLocked()885 bool ScreenSession::IsScreenRotationLocked()
886 {
887     return isScreenLocked_;
888 }
889 
SetTouchEnabledFromJs(bool isTouchEnabled)890 void ScreenSession::SetTouchEnabledFromJs(bool isTouchEnabled)
891 {
892     TLOGI(WmsLogTag::WMS_EVENT, "isTouchEnabled:%{public}u", static_cast<uint32_t>(isTouchEnabled));
893     touchEnabled_.store(isTouchEnabled);
894 }
895 
IsTouchEnabled()896 bool ScreenSession::IsTouchEnabled()
897 {
898     return touchEnabled_.load();
899 }
900 
GetScreenRequestedOrientation() const901 Orientation ScreenSession::GetScreenRequestedOrientation() const
902 {
903     return property_.GetScreenRequestedOrientation();
904 }
905 
SetVirtualPixelRatio(float virtualPixelRatio)906 void ScreenSession::SetVirtualPixelRatio(float virtualPixelRatio)
907 {
908     property_.SetVirtualPixelRatio(virtualPixelRatio);
909 }
910 
SetScreenSceneDpiChangeListener(const SetScreenSceneDpiFunc & func)911 void ScreenSession::SetScreenSceneDpiChangeListener(const SetScreenSceneDpiFunc& func)
912 {
913     SetScreenSceneDpiCallback_ = func;
914     TLOGI(WmsLogTag::DMS, "SetScreenSceneDpiChangeListener");
915 }
916 
SetScreenSceneDpi(float density)917 void ScreenSession::SetScreenSceneDpi(float density)
918 {
919     if (SetScreenSceneDpiCallback_ == nullptr) {
920         TLOGI(WmsLogTag::DMS, "SetScreenSceneDpiCallback_ is nullptr");
921         return;
922     }
923     SetScreenSceneDpiCallback_(density);
924 }
925 
SetScreenSceneDestroyListener(const DestroyScreenSceneFunc & func)926 void ScreenSession::SetScreenSceneDestroyListener(const DestroyScreenSceneFunc& func)
927 {
928     destroyScreenSceneCallback_ = func;
929     TLOGI(WmsLogTag::DMS, "SetScreenSceneDestroyListener");
930 }
931 
DestroyScreenScene()932 void ScreenSession::DestroyScreenScene()
933 {
934     if (destroyScreenSceneCallback_ == nullptr) {
935         TLOGI(WmsLogTag::DMS, "destroyScreenSceneCallback_ is nullptr");
936         return;
937     }
938     destroyScreenSceneCallback_();
939 }
940 
SetDensityInCurResolution(float densityInCurResolution)941 void ScreenSession::SetDensityInCurResolution(float densityInCurResolution)
942 {
943     property_.SetDensityInCurResolution(densityInCurResolution);
944 }
945 
SetScreenType(ScreenType type)946 void ScreenSession::SetScreenType(ScreenType type)
947 {
948     property_.SetScreenType(type);
949 }
950 
CalcRotation(Orientation orientation,FoldDisplayMode foldDisplayMode) const951 Rotation ScreenSession::CalcRotation(Orientation orientation, FoldDisplayMode foldDisplayMode) const
952 {
953     sptr<SupportedScreenModes> info = GetActiveScreenMode();
954     if (info == nullptr) {
955         return Rotation::ROTATION_0;
956     }
957     // vertical: phone(Plugin screen); horizontal: pad & external screen
958     bool isVerticalScreen = info->width_ < info->height_;
959     if (foldDisplayMode != FoldDisplayMode::UNKNOWN &&
960         (g_screenRotationOffSet == ROTATION_90 || g_screenRotationOffSet == ROTATION_270)) {
961         isVerticalScreen = info->width_ > info->height_;
962     }
963     switch (orientation) {
964         case Orientation::UNSPECIFIED: {
965             return Rotation::ROTATION_0;
966         }
967         case Orientation::VERTICAL: {
968             return isVerticalScreen ? Rotation::ROTATION_0 : Rotation::ROTATION_90;
969         }
970         case Orientation::HORIZONTAL: {
971             return isVerticalScreen ? Rotation::ROTATION_90 : Rotation::ROTATION_0;
972         }
973         case Orientation::REVERSE_VERTICAL: {
974             return isVerticalScreen ? Rotation::ROTATION_180 : Rotation::ROTATION_270;
975         }
976         case Orientation::REVERSE_HORIZONTAL: {
977             return isVerticalScreen ? Rotation::ROTATION_270 : Rotation::ROTATION_180;
978         }
979         default: {
980             WLOGE("unknown orientation %{public}u", orientation);
981             return Rotation::ROTATION_0;
982         }
983     }
984 }
985 
CalcDisplayOrientation(Rotation rotation,FoldDisplayMode foldDisplayMode) const986 DisplayOrientation ScreenSession::CalcDisplayOrientation(Rotation rotation, FoldDisplayMode foldDisplayMode) const
987 {
988     if (foldDisplayMode == FoldDisplayMode::GLOBAL_FULL) {
989         // deal special scene for G mode, orientation should be 3 when rotation is 0
990         uint32_t temp = (static_cast<uint32_t>(rotation) + SECONDARY_ROTATION_270) % SECONDARY_ROTATION_MOD;
991         rotation = static_cast<Rotation>(temp);
992     }
993     // vertical: phone(Plugin screen); horizontal: pad & external screen
994     bool isVerticalScreen = property_.GetPhyWidth() < property_.GetPhyHeight();
995     if (foldDisplayMode != FoldDisplayMode::UNKNOWN
996         && (g_screenRotationOffSet == ROTATION_90 || g_screenRotationOffSet == ROTATION_270)) {
997         WLOGD("foldDisplay is verticalScreen when width is greater than height");
998         isVerticalScreen = property_.GetPhyWidth() > property_.GetPhyHeight();
999     }
1000     if (FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) {
1001         isVerticalScreen = true;
1002     }
1003     switch (rotation) {
1004         case Rotation::ROTATION_0: {
1005             return isVerticalScreen ? DisplayOrientation::PORTRAIT : DisplayOrientation::LANDSCAPE;
1006         }
1007         case Rotation::ROTATION_90: {
1008             return isVerticalScreen ? DisplayOrientation::LANDSCAPE : DisplayOrientation::PORTRAIT;
1009         }
1010         case Rotation::ROTATION_180: {
1011             return isVerticalScreen ? DisplayOrientation::PORTRAIT_INVERTED : DisplayOrientation::LANDSCAPE_INVERTED;
1012         }
1013         case Rotation::ROTATION_270: {
1014             return isVerticalScreen ? DisplayOrientation::LANDSCAPE_INVERTED : DisplayOrientation::PORTRAIT_INVERTED;
1015         }
1016         default: {
1017             WLOGE("unknown rotation %{public}u", rotation);
1018             return DisplayOrientation::UNKNOWN;
1019         }
1020     }
1021 }
1022 
CalcDeviceOrientation(Rotation rotation,FoldDisplayMode foldDisplayMode) const1023 DisplayOrientation ScreenSession::CalcDeviceOrientation(Rotation rotation, FoldDisplayMode foldDisplayMode) const
1024 {
1025     if (foldDisplayMode == FoldDisplayMode::GLOBAL_FULL) {
1026         uint32_t temp = (static_cast<uint32_t>(rotation) + SECONDARY_ROTATION_270) % SECONDARY_ROTATION_MOD;
1027         rotation = static_cast<Rotation>(temp);
1028     }
1029     DisplayOrientation displayRotation = DisplayOrientation::UNKNOWN;
1030     switch (rotation) {
1031         case Rotation::ROTATION_0: {
1032             displayRotation = DisplayOrientation::PORTRAIT;
1033             break;
1034         }
1035         case Rotation::ROTATION_90: {
1036             displayRotation = DisplayOrientation::LANDSCAPE;
1037             break;
1038         }
1039         case Rotation::ROTATION_180: {
1040             displayRotation = DisplayOrientation::PORTRAIT_INVERTED;
1041             break;
1042         }
1043         case Rotation::ROTATION_270: {
1044             displayRotation = DisplayOrientation::LANDSCAPE_INVERTED;
1045             break;
1046         }
1047         default: {
1048             WLOGE("unknown rotation %{public}u", rotation);
1049         }
1050     }
1051     return displayRotation;
1052 }
1053 
GetSourceMode() const1054 ScreenSourceMode ScreenSession::GetSourceMode() const
1055 {
1056     if (screenId_ == defaultScreenId_) {
1057         return ScreenSourceMode::SCREEN_MAIN;
1058     }
1059     ScreenCombination combination = GetScreenCombination();
1060     switch (combination) {
1061         case ScreenCombination::SCREEN_MIRROR: {
1062             return ScreenSourceMode::SCREEN_MIRROR;
1063         }
1064         case ScreenCombination::SCREEN_EXPAND: {
1065             return ScreenSourceMode::SCREEN_EXTEND;
1066         }
1067         case ScreenCombination::SCREEN_ALONE: {
1068             return ScreenSourceMode::SCREEN_ALONE;
1069         }
1070         case ScreenCombination::SCREEN_UNIQUE: {
1071             return ScreenSourceMode::SCREEN_UNIQUE;
1072         }
1073         default: {
1074             return ScreenSourceMode::SCREEN_ALONE;
1075         }
1076     }
1077 }
1078 
SetScreenCombination(ScreenCombination combination)1079 void ScreenSession::SetScreenCombination(ScreenCombination combination)
1080 {
1081     combination_ = combination;
1082 }
1083 
GetScreenCombination() const1084 ScreenCombination ScreenSession::GetScreenCombination() const
1085 {
1086     return combination_;
1087 }
1088 
FillScreenInfo(sptr<ScreenInfo> info) const1089 void ScreenSession::FillScreenInfo(sptr<ScreenInfo> info) const
1090 {
1091     if (info == nullptr) {
1092         WLOGE("FillScreenInfo failed! info is nullptr");
1093         return;
1094     }
1095     info->SetScreenId(screenId_);
1096     info->SetName(name_);
1097     uint32_t width = 0;
1098     uint32_t height = 0;
1099     sptr<SupportedScreenModes> screenSessionModes = GetActiveScreenMode();
1100     if (screenSessionModes != nullptr) {
1101         height = screenSessionModes->height_;
1102         width = screenSessionModes->width_;
1103     }
1104     float virtualPixelRatio = property_.GetVirtualPixelRatio();
1105     // "< 1e-set6" means virtualPixelRatio is 0.
1106     if (fabsf(virtualPixelRatio) < 1e-6) {
1107         virtualPixelRatio = 1.0f;
1108     }
1109     ScreenSourceMode sourceMode = GetSourceMode();
1110     info->SetVirtualPixelRatio(property_.GetVirtualPixelRatio());
1111     info->SetVirtualHeight(height / virtualPixelRatio);
1112     info->SetVirtualWidth(width / virtualPixelRatio);
1113     info->SetRotation(property_.GetScreenRotation());
1114     info->SetOrientation(static_cast<Orientation>(property_.GetDisplayOrientation()));
1115     info->SetSourceMode(sourceMode);
1116     info->SetType(property_.GetScreenType());
1117     info->SetModeId(activeIdx_);
1118 
1119     info->lastParent_ = lastGroupSmsId_;
1120     info->parent_ = groupSmsId_;
1121     info->isScreenGroup_ = isScreenGroup_;
1122     info->modes_ = modes_;
1123 }
1124 
ConvertToScreenInfo() const1125 sptr<ScreenInfo> ScreenSession::ConvertToScreenInfo() const
1126 {
1127     sptr<ScreenInfo> info = new(std::nothrow) ScreenInfo();
1128     if (info == nullptr) {
1129         return nullptr;
1130     }
1131     FillScreenInfo(info);
1132     return info;
1133 }
1134 
GetScreenColorGamut(ScreenColorGamut & colorGamut)1135 DMError ScreenSession::GetScreenColorGamut(ScreenColorGamut& colorGamut)
1136 {
1137     auto ret = RSInterfaces::GetInstance().GetScreenColorGamut(rsId_, colorGamut);
1138     if (ret != StatusCode::SUCCESS) {
1139         WLOGE("GetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_);
1140         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1141     }
1142     WLOGI("GetScreenColorGamut ok! rsId %{public}" PRIu64", colorGamut %{public}u",
1143         rsId_, static_cast<uint32_t>(colorGamut));
1144     return DMError::DM_OK;
1145 }
1146 
SetScreenColorGamut(int32_t colorGamutIdx)1147 DMError ScreenSession::SetScreenColorGamut(int32_t colorGamutIdx)
1148 {
1149     std::vector<ScreenColorGamut> colorGamuts;
1150     DMError res = GetScreenSupportedColorGamuts(colorGamuts);
1151     if (res != DMError::DM_OK) {
1152         WLOGE("SetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_);
1153         return res;
1154     }
1155     if (colorGamutIdx < 0 || colorGamutIdx >= static_cast<int32_t>(colorGamuts.size())) {
1156         WLOGE("SetScreenColorGamut fail! rsId %{public}" PRIu64" colorGamutIdx %{public}d invalid.",
1157             rsId_, colorGamutIdx);
1158         return DMError::DM_ERROR_INVALID_PARAM;
1159     }
1160     auto ret = RSInterfaces::GetInstance().SetScreenColorGamut(rsId_, colorGamutIdx);
1161     if (ret != StatusCode::SUCCESS) {
1162         WLOGE("SetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_);
1163         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1164     }
1165     WLOGI("SetScreenColorGamut ok! rsId %{public}" PRIu64", colorGamutIdx %{public}u",
1166         rsId_, colorGamutIdx);
1167     return DMError::DM_OK;
1168 }
1169 
GetScreenGamutMap(ScreenGamutMap & gamutMap)1170 DMError ScreenSession::GetScreenGamutMap(ScreenGamutMap& gamutMap)
1171 {
1172     auto ret = RSInterfaces::GetInstance().GetScreenGamutMap(rsId_, gamutMap);
1173     if (ret != StatusCode::SUCCESS) {
1174         WLOGE("GetScreenGamutMap fail! rsId %{public}" PRIu64"", rsId_);
1175         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1176     }
1177     WLOGI("GetScreenGamutMap ok! rsId %{public}" PRIu64", gamutMap %{public}u",
1178         rsId_, static_cast<uint32_t>(gamutMap));
1179     return DMError::DM_OK;
1180 }
1181 
SetScreenGamutMap(ScreenGamutMap gamutMap)1182 DMError ScreenSession::SetScreenGamutMap(ScreenGamutMap gamutMap)
1183 {
1184     if (gamutMap > GAMUT_MAP_HDR_EXTENSION) {
1185         return DMError::DM_ERROR_INVALID_PARAM;
1186     }
1187     auto ret = RSInterfaces::GetInstance().SetScreenGamutMap(rsId_, gamutMap);
1188     if (ret != StatusCode::SUCCESS) {
1189         WLOGE("SetScreenGamutMap fail! rsId %{public}" PRIu64"", rsId_);
1190         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1191     }
1192     WLOGI("SetScreenGamutMap ok! rsId %{public}" PRIu64", gamutMap %{public}u",
1193         rsId_, static_cast<uint32_t>(gamutMap));
1194     return DMError::DM_OK;
1195 }
1196 
SetScreenColorTransform()1197 DMError ScreenSession::SetScreenColorTransform()
1198 {
1199     WLOGI("SetScreenColorTransform ok! rsId %{public}" PRIu64"", rsId_);
1200     return DMError::DM_OK;
1201 }
1202 
GetPixelFormat(GraphicPixelFormat & pixelFormat)1203 DMError ScreenSession::GetPixelFormat(GraphicPixelFormat& pixelFormat)
1204 {
1205     auto ret = RSInterfaces::GetInstance().GetPixelFormat(rsId_, pixelFormat);
1206     if (ret != StatusCode::SUCCESS) {
1207         WLOGE("GetPixelFormat fail! rsId %{public}" PRIu64, rsId_);
1208         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1209     }
1210     WLOGI("GetPixelFormat ok! rsId %{public}" PRIu64 ", pixelFormat %{public}u",
1211         rsId_, static_cast<uint32_t>(pixelFormat));
1212     return DMError::DM_OK;
1213 }
1214 
SetPixelFormat(GraphicPixelFormat pixelFormat)1215 DMError ScreenSession::SetPixelFormat(GraphicPixelFormat pixelFormat)
1216 {
1217     if (pixelFormat > GRAPHIC_PIXEL_FMT_VENDER_MASK) {
1218         return DMError::DM_ERROR_INVALID_PARAM;
1219     }
1220     auto ret = RSInterfaces::GetInstance().SetPixelFormat(rsId_, pixelFormat);
1221     if (ret != StatusCode::SUCCESS) {
1222         WLOGE("SetPixelFormat fail! rsId %{public}" PRIu64, rsId_);
1223         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1224     }
1225     WLOGI("SetPixelFormat ok! rsId %{public}" PRIu64 ", gamutMap %{public}u",
1226         rsId_, static_cast<uint32_t>(pixelFormat));
1227     return DMError::DM_OK;
1228 }
1229 
GetSupportedHDRFormats(std::vector<ScreenHDRFormat> & hdrFormats)1230 DMError ScreenSession::GetSupportedHDRFormats(std::vector<ScreenHDRFormat>& hdrFormats)
1231 {
1232     auto ret = RSInterfaces::GetInstance().GetScreenSupportedHDRFormats(rsId_, hdrFormats);
1233     if (ret != StatusCode::SUCCESS) {
1234         WLOGE("SCB: ScreenSession::GetSupportedHDRFormats fail! rsId %{public}" PRIu64 ", ret:%{public}d",
1235             rsId_, ret);
1236         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1237     }
1238     WLOGI("SCB: ScreenSession::GetSupportedHDRFormats ok! rsId %{public}" PRIu64 ", size %{public}u",
1239         rsId_, static_cast<uint32_t>(hdrFormats.size()));
1240 
1241     return DMError::DM_OK;
1242 }
1243 
GetScreenHDRFormat(ScreenHDRFormat & hdrFormat)1244 DMError ScreenSession::GetScreenHDRFormat(ScreenHDRFormat& hdrFormat)
1245 {
1246     auto ret = RSInterfaces::GetInstance().GetScreenHDRFormat(rsId_, hdrFormat);
1247     if (ret != StatusCode::SUCCESS) {
1248         WLOGE("GetScreenHDRFormat fail! rsId %{public}" PRIu64, rsId_);
1249         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1250     }
1251     WLOGI("GetScreenHDRFormat ok! rsId %{public}" PRIu64 ", colorSpace %{public}u",
1252         rsId_, static_cast<uint32_t>(hdrFormat));
1253     return DMError::DM_OK;
1254 }
1255 
SetScreenHDRFormat(int32_t modeIdx)1256 DMError ScreenSession::SetScreenHDRFormat(int32_t modeIdx)
1257 {
1258     std::vector<ScreenHDRFormat> hdrFormats;
1259     DMError res = GetSupportedHDRFormats(hdrFormats);
1260     if (res != DMError::DM_OK) {
1261         WLOGE("SetScreenHDRFormat fail! rsId %{public}" PRIu64, rsId_);
1262         return res;
1263     }
1264     if (modeIdx < 0 || modeIdx >= static_cast<int32_t>(hdrFormats.size())) {
1265         WLOGE("SetScreenHDRFormat fail! rsId %{public}" PRIu64 " modeIdx %{public}d invalid.",
1266             rsId_, modeIdx);
1267         return DMError::DM_ERROR_INVALID_PARAM;
1268     }
1269     auto ret = RSInterfaces::GetInstance().SetScreenHDRFormat(rsId_, modeIdx);
1270     if (ret != StatusCode::SUCCESS) {
1271         WLOGE("SetScreenHDRFormat fail! rsId %{public}" PRIu64, rsId_);
1272         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1273     }
1274     WLOGI("SetScreenHDRFormat ok! rsId %{public}" PRIu64 ", modeIdx %{public}u",
1275         rsId_, modeIdx);
1276     return DMError::DM_OK;
1277 }
1278 
GetSupportedColorSpaces(std::vector<GraphicCM_ColorSpaceType> & colorSpaces)1279 DMError ScreenSession::GetSupportedColorSpaces(std::vector<GraphicCM_ColorSpaceType>& colorSpaces)
1280 {
1281     auto ret = RSInterfaces::GetInstance().GetScreenSupportedColorSpaces(rsId_, colorSpaces);
1282     if (ret != StatusCode::SUCCESS) {
1283         WLOGE("SCB: ScreenSession::GetSupportedColorSpaces fail! rsId %{public}" PRIu64 ", ret:%{public}d",
1284             rsId_, ret);
1285         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1286     }
1287     WLOGI("SCB: ScreenSession::GetSupportedColorSpaces ok! rsId %{public}" PRIu64 ", size %{public}u",
1288         rsId_, static_cast<uint32_t>(colorSpaces.size()));
1289     return DMError::DM_OK;
1290 }
1291 
GetScreenColorSpace(GraphicCM_ColorSpaceType & colorSpace)1292 DMError ScreenSession::GetScreenColorSpace(GraphicCM_ColorSpaceType& colorSpace)
1293 {
1294     auto ret = RSInterfaces::GetInstance().GetScreenColorSpace(rsId_, colorSpace);
1295     if (ret != StatusCode::SUCCESS) {
1296         WLOGE("GetScreenColorSpace fail! rsId %{public}" PRIu64, rsId_);
1297         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1298     }
1299     WLOGI("GetScreenColorSpace ok! rsId %{public}" PRIu64 ", colorSpace %{public}u",
1300         rsId_, static_cast<uint32_t>(colorSpace));
1301     return DMError::DM_OK;
1302 }
1303 
SetScreenColorSpace(GraphicCM_ColorSpaceType colorSpace)1304 DMError ScreenSession::SetScreenColorSpace(GraphicCM_ColorSpaceType colorSpace)
1305 {
1306     std::vector<GraphicCM_ColorSpaceType> colorSpaces;
1307     DMError res = GetSupportedColorSpaces(colorSpaces);
1308     if (res != DMError::DM_OK) {
1309         WLOGE("SetScreenColorSpace fail! rsId %{public}" PRIu64, rsId_);
1310         return res;
1311     }
1312     if (colorSpace < 0 || static_cast<int32_t>(colorSpace) >= static_cast<int32_t>(colorSpaces.size())) {
1313         WLOGE("SetScreenColorSpace fail! rsId %{public}" PRIu64 " colorSpace %{public}d invalid.",
1314             rsId_, colorSpace);
1315         return DMError::DM_ERROR_INVALID_PARAM;
1316     }
1317     auto ret = RSInterfaces::GetInstance().SetScreenColorSpace(rsId_, colorSpace);
1318     if (ret != StatusCode::SUCCESS) {
1319         WLOGE("SetScreenColorSpace fail! rsId %{public}" PRIu64, rsId_);
1320         return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
1321     }
1322     WLOGI("SetScreenColorSpace ok! rsId %{public}" PRIu64 ", colorSpace %{public}u",
1323         rsId_, colorSpace);
1324     return DMError::DM_OK;
1325 }
1326 
HasPrivateSessionForeground() const1327 bool ScreenSession::HasPrivateSessionForeground() const
1328 {
1329     return hasPrivateWindowForeground_;
1330 }
1331 
SetPrivateSessionForeground(bool hasPrivate)1332 void ScreenSession::SetPrivateSessionForeground(bool hasPrivate)
1333 {
1334     hasPrivateWindowForeground_ = hasPrivate;
1335 }
1336 
InitRSDisplayNode(RSDisplayNodeConfig & config,Point & startPoint)1337 void ScreenSession::InitRSDisplayNode(RSDisplayNodeConfig& config, Point& startPoint)
1338 {
1339     std::unique_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
1340     if (displayNode_ != nullptr) {
1341         displayNode_->SetDisplayNodeMirrorConfig(config);
1342         if (screenId_ == 0 && isFold_) {
1343             WLOGFI("Return InitRSDisplayNode foldScreen0");
1344             return;
1345         }
1346     } else {
1347         std::shared_ptr<RSDisplayNode> rsDisplayNode = RSDisplayNode::Create(config);
1348         if (rsDisplayNode == nullptr) {
1349             WLOGE("fail to add child. create rsDisplayNode fail!");
1350             return;
1351         }
1352         displayNode_ = rsDisplayNode;
1353     }
1354     WLOGFI("SetDisplayOffset: posX:%{public}d, posY:%{public}d", startPoint.posX_, startPoint.posY_);
1355     displayNode_->SetDisplayOffset(startPoint.posX_, startPoint.posY_);
1356     uint32_t width = 0;
1357     uint32_t height = 0;
1358     sptr<SupportedScreenModes> abstractScreenModes = GetActiveScreenMode();
1359     if (abstractScreenModes != nullptr) {
1360         height = abstractScreenModes->height_;
1361         width = abstractScreenModes->width_;
1362     }
1363     RSScreenType screenType;
1364     DmsXcollie dmsXcollie("DMS:InitRSDisplayNode:GetScreenType", XCOLLIE_TIMEOUT_5S);
1365     auto ret = RSInterfaces::GetInstance().GetScreenType(rsId_, screenType);
1366     if (ret == StatusCode::SUCCESS && screenType == RSScreenType::VIRTUAL_TYPE_SCREEN) {
1367         displayNode_->SetSecurityDisplay(true);
1368         WLOGFI("virtualScreen SetSecurityDisplay success");
1369     }
1370     // If setDisplayOffset is not valid for SetFrame/SetBounds
1371     WLOGFI("InitRSDisplayNode screenId:%{public}" PRIu64" width:%{public}u height:%{public}u",
1372         screenId_, width, height);
1373     displayNode_->SetFrame(0, 0, width, height);
1374     displayNode_->SetBounds(0, 0, width, height);
1375     if (config.isMirrored) {
1376         EnableMirrorScreenRegion();
1377     }
1378     auto transactionProxy = RSTransactionProxy::GetInstance();
1379     if (transactionProxy != nullptr) {
1380         transactionProxy->FlushImplicitTransaction();
1381     }
1382 }
1383 
ScreenSessionGroup(ScreenId screenId,ScreenId rsId,std::string name,ScreenCombination combination)1384 ScreenSessionGroup::ScreenSessionGroup(ScreenId screenId, ScreenId rsId,
1385     std::string name, ScreenCombination combination) : combination_(combination)
1386 {
1387     name_ = name;
1388     screenId_ = screenId;
1389     rsId_ = rsId;
1390     SetScreenType(ScreenType::UNDEFINED);
1391     isScreenGroup_ = true;
1392 }
1393 
~ScreenSessionGroup()1394 ScreenSessionGroup::~ScreenSessionGroup()
1395 {
1396     ReleaseDisplayNode();
1397     screenSessionMap_.clear();
1398 }
1399 
GetRSDisplayNodeConfig(sptr<ScreenSession> & screenSession,struct RSDisplayNodeConfig & config,sptr<ScreenSession> defaultScreenSession)1400 bool ScreenSessionGroup::GetRSDisplayNodeConfig(sptr<ScreenSession>& screenSession, struct RSDisplayNodeConfig& config,
1401                                                 sptr<ScreenSession> defaultScreenSession)
1402 {
1403     if (screenSession == nullptr) {
1404         WLOGE("screenSession is nullptr.");
1405         return false;
1406     }
1407     config = { screenSession->rsId_ };
1408     switch (combination_) {
1409         case ScreenCombination::SCREEN_ALONE:
1410             [[fallthrough]];
1411         case ScreenCombination::SCREEN_EXPAND:
1412             break;
1413         case ScreenCombination::SCREEN_UNIQUE:
1414             break;
1415         case ScreenCombination::SCREEN_MIRROR: {
1416             if (GetChildCount() == 0 || mirrorScreenId_ == screenSession->screenId_) {
1417                 WLOGI("SCREEN_MIRROR, config is not mirror");
1418                 break;
1419             }
1420             if (defaultScreenSession == nullptr) {
1421                 WLOGFE("defaultScreenSession is nullptr");
1422                 break;
1423             }
1424             std::shared_ptr<RSDisplayNode> displayNode = defaultScreenSession->GetDisplayNode();
1425             if (displayNode == nullptr) {
1426                 WLOGFE("displayNode is nullptr, cannot get DisplayNode");
1427                 break;
1428             }
1429             NodeId nodeId = displayNode->GetId();
1430             WLOGI("mirrorScreenId_:%{public}" PRIu64", rsId_:%{public}" PRIu64", nodeId:%{public}" PRIu64"",
1431                 mirrorScreenId_, screenSession->rsId_, nodeId);
1432             config = {screenSession->rsId_, true, nodeId, true};
1433             break;
1434         }
1435         default:
1436             WLOGE("fail to add child. invalid group combination:%{public}u", combination_);
1437             return false;
1438     }
1439     return true;
1440 }
1441 
AddChild(sptr<ScreenSession> & smsScreen,Point & startPoint,sptr<ScreenSession> defaultScreenSession)1442 bool ScreenSessionGroup::AddChild(sptr<ScreenSession>& smsScreen, Point& startPoint,
1443                                   sptr<ScreenSession> defaultScreenSession)
1444 {
1445     if (smsScreen == nullptr) {
1446         WLOGE("AddChild, smsScreen is nullptr.");
1447         return false;
1448     }
1449     ScreenId screenId = smsScreen->screenId_;
1450     auto iter = screenSessionMap_.find(screenId);
1451     if (iter != screenSessionMap_.end()) {
1452         WLOGE("AddChild, screenSessionMap_ has smsScreen:%{public}" PRIu64"", screenId);
1453         return false;
1454     }
1455     struct RSDisplayNodeConfig config;
1456     if (!GetRSDisplayNodeConfig(smsScreen, config, defaultScreenSession)) {
1457         return false;
1458     }
1459     smsScreen->InitRSDisplayNode(config, startPoint);
1460     smsScreen->lastGroupSmsId_ = smsScreen->groupSmsId_;
1461     smsScreen->groupSmsId_ = screenId_;
1462     screenSessionMap_.insert(std::make_pair(screenId, std::make_pair(smsScreen, startPoint)));
1463     return true;
1464 }
1465 
AddChildren(std::vector<sptr<ScreenSession>> & smsScreens,std::vector<Point> & startPoints)1466 bool ScreenSessionGroup::AddChildren(std::vector<sptr<ScreenSession>>& smsScreens, std::vector<Point>& startPoints)
1467 {
1468     size_t size = smsScreens.size();
1469     if (size != startPoints.size()) {
1470         WLOGE("AddChildren, unequal size.");
1471         return false;
1472     }
1473     bool res = true;
1474     for (size_t i = 0; i < size; i++) {
1475         res = AddChild(smsScreens[i], startPoints[i], nullptr) && res;
1476     }
1477     return res;
1478 }
1479 
RemoveChild(sptr<ScreenSession> & smsScreen)1480 bool ScreenSessionGroup::RemoveChild(sptr<ScreenSession>& smsScreen)
1481 {
1482     if (smsScreen == nullptr) {
1483         WLOGE("RemoveChild, smsScreen is nullptr.");
1484         return false;
1485     }
1486     ScreenId screenId = smsScreen->screenId_;
1487     smsScreen->lastGroupSmsId_ = smsScreen->groupSmsId_;
1488     smsScreen->groupSmsId_ = SCREEN_ID_INVALID;
1489     std::shared_ptr<RSDisplayNode> displayNode = smsScreen->GetDisplayNode();
1490     if (displayNode != nullptr) {
1491         displayNode->SetDisplayOffset(0, 0);
1492         displayNode->RemoveFromTree();
1493         smsScreen->ReleaseDisplayNode();
1494     }
1495     displayNode = nullptr;
1496     // attention: make sure reference count 0
1497     RSTransaction::FlushImplicitTransaction();
1498     return screenSessionMap_.erase(screenId);
1499 }
1500 
HasChild(ScreenId childScreen) const1501 bool ScreenSessionGroup::HasChild(ScreenId childScreen) const
1502 {
1503     return screenSessionMap_.find(childScreen) != screenSessionMap_.end();
1504 }
1505 
GetChildren() const1506 std::vector<sptr<ScreenSession>> ScreenSessionGroup::GetChildren() const
1507 {
1508     std::vector<sptr<ScreenSession>> res;
1509     for (auto iter = screenSessionMap_.begin(); iter != screenSessionMap_.end(); iter++) {
1510         res.push_back(iter->second.first);
1511     }
1512     return res;
1513 }
1514 
GetChildrenPosition() const1515 std::vector<Point> ScreenSessionGroup::GetChildrenPosition() const
1516 {
1517     std::vector<Point> res;
1518     for (auto iter = screenSessionMap_.begin(); iter != screenSessionMap_.end(); iter++) {
1519         res.push_back(iter->second.second);
1520     }
1521     return res;
1522 }
1523 
GetChildPosition(ScreenId screenId) const1524 Point ScreenSessionGroup::GetChildPosition(ScreenId screenId) const
1525 {
1526     Point point;
1527     auto iter = screenSessionMap_.find(screenId);
1528     if (iter != screenSessionMap_.end()) {
1529         point = iter->second.second;
1530     }
1531     return point;
1532 }
1533 
GetChildCount() const1534 size_t ScreenSessionGroup::GetChildCount() const
1535 {
1536     return screenSessionMap_.size();
1537 }
1538 
GetScreenCombination() const1539 ScreenCombination ScreenSessionGroup::GetScreenCombination() const
1540 {
1541     return combination_;
1542 }
1543 
ConvertToScreenGroupInfo() const1544 sptr<ScreenGroupInfo> ScreenSessionGroup::ConvertToScreenGroupInfo() const
1545 {
1546     sptr<ScreenGroupInfo> screenGroupInfo = new(std::nothrow) ScreenGroupInfo();
1547     if (screenGroupInfo == nullptr) {
1548         return nullptr;
1549     }
1550     FillScreenInfo(screenGroupInfo);
1551     screenGroupInfo->combination_ = combination_;
1552     for (auto iter = screenSessionMap_.begin(); iter != screenSessionMap_.end(); iter++) {
1553         screenGroupInfo->children_.push_back(iter->first);
1554     }
1555     auto positions = GetChildrenPosition();
1556     screenGroupInfo->position_.insert(screenGroupInfo->position_.end(), positions.begin(), positions.end());
1557     return screenGroupInfo;
1558 }
1559 
SetDisplayBoundary(const RectF & rect,const uint32_t & offsetY)1560 void ScreenSession::SetDisplayBoundary(const RectF& rect, const uint32_t& offsetY)
1561 {
1562     property_.SetOffsetY(offsetY);
1563     property_.SetBounds(RRect(rect, 0.0f, 0.0f));
1564 }
1565 
Resize(uint32_t width,uint32_t height)1566 void ScreenSession::Resize(uint32_t width, uint32_t height)
1567 {
1568     sptr<SupportedScreenModes> screenMode = GetActiveScreenMode();
1569     if (screenMode != nullptr) {
1570         screenMode->width_ = width;
1571         screenMode->height_ = height;
1572         UpdatePropertyByActiveMode();
1573         {
1574             std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
1575             if (displayNode_ == nullptr) {
1576                 WLOGFE("displayNode_ is null, resize failed");
1577                 return;
1578             }
1579             displayNode_->SetFrame(0, 0, static_cast<float>(width), static_cast<float>(height));
1580             displayNode_->SetBounds(0, 0, static_cast<float>(width), static_cast<float>(height));
1581         }
1582         RSTransaction::FlushImplicitTransaction();
1583     }
1584 }
1585 
UpdateAvailableArea(DMRect area)1586 bool ScreenSession::UpdateAvailableArea(DMRect area)
1587 {
1588     if (property_.GetAvailableArea() == area) {
1589         return false;
1590     }
1591     property_.SetAvailableArea(area);
1592     return true;
1593 }
1594 
SetAvailableArea(DMRect area)1595 void ScreenSession::SetAvailableArea(DMRect area)
1596 {
1597     property_.SetAvailableArea(area);
1598 }
1599 
GetAvailableArea()1600 DMRect ScreenSession::GetAvailableArea()
1601 {
1602     return property_.GetAvailableArea();
1603 }
1604 
SetFoldScreen(bool isFold)1605 void ScreenSession::SetFoldScreen(bool isFold)
1606 {
1607     WLOGFI("SetFoldScreen %{public}u", isFold);
1608     isFold_ = isFold;
1609 }
1610 
SetHdrFormats(std::vector<uint32_t> && hdrFormats)1611 void ScreenSession::SetHdrFormats(std::vector<uint32_t>&& hdrFormats)
1612 {
1613     hdrFormats_ = std::move(hdrFormats);
1614 }
1615 
SetColorSpaces(std::vector<uint32_t> && colorSpaces)1616 void ScreenSession::SetColorSpaces(std::vector<uint32_t>&& colorSpaces)
1617 {
1618     colorSpaces_ = std::move(colorSpaces);
1619 }
1620 
GetScreenSnapshot(float scaleX,float scaleY)1621 std::shared_ptr<Media::PixelMap> ScreenSession::GetScreenSnapshot(float scaleX, float scaleY)
1622 {
1623     {
1624         std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
1625         if (displayNode_ == nullptr) {
1626             WLOGFE("get screen snapshot displayNode_ is null");
1627             return nullptr;
1628         }
1629     }
1630 
1631     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ss:GetScreenSnapshot");
1632     auto callback = std::make_shared<SurfaceCaptureFuture>();
1633     RSSurfaceCaptureConfig config = {
1634         .scaleX = scaleX,
1635         .scaleY = scaleY,
1636     };
1637     {
1638         DmsXcollie dmsXcollie("DMS:GetScreenSnapshot:TakeSurfaceCapture", XCOLLIE_TIMEOUT_5S);
1639         std::shared_lock<std::shared_mutex> displayNodeLock(displayNodeMutex_);
1640         bool ret = RSInterfaces::GetInstance().TakeSurfaceCapture(displayNode_, callback, config);
1641         if (!ret) {
1642             WLOGFE("get screen snapshot TakeSurfaceCapture failed");
1643             return nullptr;
1644         }
1645     }
1646 
1647     auto pixelMap = callback->GetResult(2000);
1648     if (pixelMap != nullptr) {
1649         WLOGFD("save pixelMap WxH = %{public}dx%{public}d", pixelMap->GetWidth(), pixelMap->GetHeight());
1650     } else {
1651         WLOGFE("failed to get pixelMap, return nullptr");
1652     }
1653     return pixelMap;
1654 }
1655 
ScreenCaptureNotify(ScreenId mainScreenId,int32_t uid,const std::string & clientName)1656 void ScreenSession::ScreenCaptureNotify(ScreenId mainScreenId, int32_t uid, const std::string& clientName)
1657 {
1658     std::lock_guard<std::mutex> lock(screenChangeListenerListMutex_);
1659     for (auto& listener : screenChangeListenerList_) {
1660         if (!listener) {
1661             continue;
1662         }
1663         listener->OnScreenCaptureNotify(mainScreenId, uid, clientName);
1664     }
1665 }
1666 
SecondaryReflexionChange(ScreenId screenId,bool isSecondaryReflexion)1667 void ScreenSession::SecondaryReflexionChange(ScreenId screenId, bool isSecondaryReflexion)
1668 {
1669     std::lock_guard<std::mutex> lock(screenChangeListenerListMutex_);
1670     if (screenChangeListenerList_.empty()) {
1671         WLOGFE("screenChangeListenerList is empty.");
1672         return;
1673     }
1674     for (auto& listener : screenChangeListenerList_) {
1675         if (!listener) {
1676             WLOGFE("screenChangeListener is null.");
1677             continue;
1678         }
1679         listener->OnSecondaryReflexionChange(screenId, isSecondaryReflexion);
1680     }
1681 }
1682 
SetIsPhysicalMirrorSwitch(bool isPhysicalMirrorSwitch)1683 void ScreenSession::SetIsPhysicalMirrorSwitch(bool isPhysicalMirrorSwitch)
1684 {
1685     isPhysicalMirrorSwitch_ = isPhysicalMirrorSwitch;
1686 }
1687 
GetIsPhysicalMirrorSwitch()1688 bool ScreenSession::GetIsPhysicalMirrorSwitch()
1689 {
1690     return isPhysicalMirrorSwitch_;
1691 }
1692 
GetApiVersion()1693 int32_t ScreenSession::GetApiVersion()
1694 {
1695     static std::chrono::steady_clock::time_point lastReauestTime = std::chrono::steady_clock::now();
1696     auto currentTime = std::chrono::steady_clock::now();
1697     auto interval = std::chrono::duration_cast<std::chrono::microseconds>(currentTime - lastReauestTime).count();
1698     int32_t apiVersion = NO_EXIT_UID_VERSION;
1699     int32_t currentPid = IPCSkeleton::GetCallingPid();
1700     if (interval < MAX_INTERVAL_US) {
1701         apiVersion = g_uidVersionMap.Get(currentPid);
1702     }
1703     if (apiVersion == NO_EXIT_UID_VERSION) {
1704         apiVersion = static_cast<int32_t>(SysCapUtil::GetApiCompatibleVersion());
1705         WLOGFI("Get version from IPC");
1706         g_uidVersionMap.Set(currentPid, apiVersion);
1707     }
1708     lastReauestTime = currentTime;
1709     return apiVersion;
1710 }
1711 
SetShareProtect(bool needShareProtect)1712 void ScreenSession::SetShareProtect(bool needShareProtect)
1713 {
1714     needShareProtect_ = needShareProtect;
1715 }
1716 
GetShareProtect()1717 bool ScreenSession::GetShareProtect()
1718 {
1719     return needShareProtect_;
1720 }
1721 } // namespace OHOS::Rosen
1722