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