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