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