1 /*
2 * Copyright (c) 2021-2022 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 "abstract_screen.h"
17
18 #include <cmath>
19 #include "abstract_screen_controller.h"
20 #include "display_manager_service.h"
21 #include "dm_common.h"
22 #include "rs_adapter.h"
23 #include "screen_rotation_controller.h"
24 #include "window_manager_hilog.h"
25
26 namespace OHOS::Rosen {
27 namespace {
28 constexpr float MAX_ZORDER = 100000.0f;
29 }
30
AbstractScreen(sptr<AbstractScreenController> screenController,const std::string & name,ScreenId dmsId,ScreenId rsId)31 AbstractScreen::AbstractScreen(sptr<AbstractScreenController> screenController, const std::string& name, ScreenId dmsId,
32 ScreenId rsId) : dmsId_(dmsId), rsId_(rsId), screenController_(screenController)
33 {
34 if (name != "") {
35 name_ = name;
36 }
37 RSAdapterUtil::InitRSUIDirector(rsUIDirector_, true, true);
38 }
39
~AbstractScreen()40 AbstractScreen::~AbstractScreen()
41 {
42 }
43
GetActiveScreenMode() const44 sptr<SupportedScreenModes> AbstractScreen::GetActiveScreenMode() const
45 {
46 if (activeIdx_ < 0 || activeIdx_ >= static_cast<int32_t>(modes_.size())) {
47 TLOGE(WmsLogTag::DMS, "active mode index is wrong: %{public}d", activeIdx_);
48 return nullptr;
49 }
50 return modes_[activeIdx_];
51 }
52
GetAbstractScreenModes() const53 std::vector<sptr<SupportedScreenModes>> AbstractScreen::GetAbstractScreenModes() const
54 {
55 return modes_;
56 }
57
GetGroup() const58 sptr<AbstractScreenGroup> AbstractScreen::GetGroup() const
59 {
60 if (screenController_ == nullptr) {
61 return nullptr;
62 }
63 return screenController_->GetAbstractScreenGroup(groupDmsId_);
64 }
65
ConvertToScreenInfo() const66 sptr<ScreenInfo> AbstractScreen::ConvertToScreenInfo() const
67 {
68 sptr<ScreenInfo> info = new(std::nothrow) ScreenInfo();
69 if (info == nullptr) {
70 return nullptr;
71 }
72 FillScreenInfo(info);
73 return info;
74 }
75
ConvertScreenInfoToDisplayInfo(const sptr<ScreenInfo> & info) const76 sptr<DisplayInfo> AbstractScreen::ConvertScreenInfoToDisplayInfo(const sptr<ScreenInfo>& info) const
77 {
78 sptr<DisplayInfo> displayInfo = sptr<DisplayInfo>::MakeSptr();
79 if (displayInfo == nullptr) {
80 return nullptr;
81 }
82 FillDisplayInfoByScreenInfo(displayInfo, info);
83 return displayInfo;
84 }
85
FillDisplayInfoByScreenInfo(sptr<DisplayInfo> displayInfo,const sptr<ScreenInfo> & info) const86 void AbstractScreen::FillDisplayInfoByScreenInfo(sptr<DisplayInfo> displayInfo, const sptr<ScreenInfo>& info) const
87 {
88 if (displayInfo == nullptr || info == nullptr) {
89 TLOGE(WmsLogTag::DMS, "displayInfo is nullptr");
90 return;
91 }
92 sptr<SupportedScreenModes> abstractScreenMode = GetActiveScreenMode();
93 if (abstractScreenMode != nullptr) {
94 displayInfo->SetRefreshRate(abstractScreenMode->refreshRate_);
95 std::vector<uint32_t> supportedRefreshRate;
96 supportedRefreshRate.push_back(abstractScreenMode->refreshRate_);
97 displayInfo->SetSupportedRefreshRate(supportedRefreshRate);
98 }
99
100 displayInfo->SetName(info->name_);
101 displayInfo->SetDisplayId(info->id_);
102 displayInfo->SetWidth(info->virtualWidth_);
103 displayInfo->SetHeight(info->virtualHeight_);
104 displayInfo->SetScreenId(info->id_);
105 displayInfo->SetVirtualPixelRatio(info->virtualPixelRatio_);
106 displayInfo->SetDpi(info->virtualPixelRatio_ * DOT_PER_INCH);
107 displayInfo->SetRotation(info->rotation_);
108 displayInfo->SetOrientation(info->orientation_);
109 displayInfo->SetDisplayOrientation(
110 ScreenRotationController::ConvertRotationToDisplayOrientation(info->rotation_));
111 displayInfo->SetDisplaySourceMode(GetDisplaySourceMode());
112 }
113
UpdateRSTree(std::shared_ptr<RSSurfaceNode> & surfaceNode,bool isAdd,bool needToUpdate)114 void AbstractScreen::UpdateRSTree(std::shared_ptr<RSSurfaceNode>& surfaceNode, bool isAdd, bool needToUpdate)
115 {
116 if (rsDisplayNode_ == nullptr || surfaceNode == nullptr) {
117 TLOGE(WmsLogTag::DMS, "node is nullptr");
118 return;
119 }
120 TLOGD(WmsLogTag::DMS, "%{public}s surface: %{public}s, %{public}" PRIu64"", (isAdd ? "add" : "remove"),
121 surfaceNode->GetName().c_str(), surfaceNode->GetId());
122
123 if (isAdd) {
124 RSAdapterUtil::SetRSUIContext(surfaceNode, GetRSUIContext(), true);
125 surfaceNode->SetVisible(true);
126 rsDisplayNode_->AddChild(surfaceNode, -1);
127 } else {
128 rsDisplayNode_->RemoveChild(surfaceNode);
129 }
130
131 if (needToUpdate) {
132 std::lock_guard<std::recursive_mutex> lock(mutex_);
133 if (isAdd) {
134 appSurfaceNodes_.push_back(surfaceNode);
135 } else {
136 auto iter = std::find_if(appSurfaceNodes_.begin(), appSurfaceNodes_.end(),
137 [surfaceNode] (std::shared_ptr<RSSurfaceNode> node) {
138 return surfaceNode->GetId() == node->GetId();
139 });
140 if (iter != appSurfaceNodes_.end()) {
141 appSurfaceNodes_.erase(iter);
142 }
143 }
144 }
145 }
146
AddSurfaceNode(std::shared_ptr<RSSurfaceNode> & surfaceNode,bool onTop,bool needToRecord)147 DMError AbstractScreen::AddSurfaceNode(std::shared_ptr<RSSurfaceNode>& surfaceNode, bool onTop, bool needToRecord)
148 {
149 if (rsDisplayNode_ == nullptr || surfaceNode == nullptr) {
150 TLOGE(WmsLogTag::DMS, "node is nullptr");
151 return DMError::DM_ERROR_NULLPTR;
152 }
153 RSAdapterUtil::SetRSUIContext(surfaceNode, GetRSUIContext(), true);
154 surfaceNode->SetVisible(true);
155 if (onTop) {
156 rsDisplayNode_->AddChild(surfaceNode, -1);
157 surfaceNode->SetPositionZ(MAX_ZORDER);
158 } else {
159 rsDisplayNode_->AddChild(surfaceNode, -1);
160 }
161 if (needToRecord) {
162 std::lock_guard<std::recursive_mutex> lock(mutex_);
163 nativeSurfaceNodes_.push_back(surfaceNode);
164 }
165 RSTransactionAdapter::FlushImplicitTransaction(GetRSUIContext());
166 return DMError::DM_OK;
167 }
168
RemoveSurfaceNode(std::shared_ptr<RSSurfaceNode> & surfaceNode)169 DMError AbstractScreen::RemoveSurfaceNode(std::shared_ptr<RSSurfaceNode>& surfaceNode)
170 {
171 if (rsDisplayNode_ == nullptr || surfaceNode == nullptr) {
172 TLOGE(WmsLogTag::DMS, "Node is nullptr");
173 return DMError::DM_ERROR_NULLPTR;
174 }
175 std::lock_guard<std::recursive_mutex> lock(mutex_);
176 auto iter = std::find_if(nativeSurfaceNodes_.begin(), nativeSurfaceNodes_.end(), [surfaceNode]
177 (std::shared_ptr<RSSurfaceNode> node) {
178 return surfaceNode->GetId() == node->GetId();
179 });
180 if (iter == nativeSurfaceNodes_.end()) {
181 TLOGW(WmsLogTag::DMS, "Child not found");
182 return DMError::DM_ERROR_INVALID_PARAM;
183 }
184 rsDisplayNode_->RemoveChild(*iter);
185 nativeSurfaceNodes_.erase(iter);
186 RSTransactionAdapter::FlushImplicitTransaction(GetRSUIContext());
187 return DMError::DM_OK;
188 }
189
UpdateDisplayGroupRSTree(std::shared_ptr<RSSurfaceNode> & surfaceNode,std::shared_ptr<RSDisplayNode> & parentNode,bool isAdd)190 void AbstractScreen::UpdateDisplayGroupRSTree(
191 std::shared_ptr<RSSurfaceNode>& surfaceNode, std::shared_ptr<RSDisplayNode>& parentNode, bool isAdd)
192 {
193 if (rsDisplayNode_ == nullptr || surfaceNode == nullptr) {
194 TLOGE(WmsLogTag::DMS, "node is nullptr");
195 return;
196 }
197 TLOGI(WmsLogTag::DMS, "%{public}s surface: %{public}s, %{public}" PRIu64"", (isAdd ? "add" : "remove"),
198 surfaceNode->GetName().c_str(), surfaceNode->GetId());
199
200 if (isAdd) {
201 RSAdapterUtil::SetRSUIContext(surfaceNode, GetRSUIContext(), true);
202 surfaceNode->SetVisible(true);
203 rsDisplayNode_->AddCrossParentChild(surfaceNode, -1);
204 } else {
205 rsDisplayNode_->RemoveCrossParentChild(surfaceNode, parentNode);
206 }
207 }
208
SetPropertyForDisplayNode(const std::shared_ptr<RSDisplayNode> & rsDisplayNode,const RSDisplayNodeConfig & config,const Point & startPoint)209 void AbstractScreen::SetPropertyForDisplayNode(const std::shared_ptr<RSDisplayNode>& rsDisplayNode,
210 const RSDisplayNodeConfig& config, const Point& startPoint)
211 {
212 rSDisplayNodeConfig_ = config;
213 startPoint_ = startPoint;
214 TLOGI(WmsLogTag::DMS, "SetScreenOffset: posX:%{public}d, posY:%{public}d", startPoint.posX_, startPoint.posY_);
215 RSInterfaces::GetInstance().SetScreenOffset(rsId_, startPoint.posX_, startPoint.posY_);
216 uint32_t width = 0;
217 uint32_t height = 0;
218 sptr<SupportedScreenModes> abstractScreenModes = GetActiveScreenMode();
219 if (abstractScreenModes != nullptr) {
220 height = abstractScreenModes->height_;
221 width = abstractScreenModes->width_;
222 }
223 RSScreenType screenType;
224 auto ret = RSInterfaces::GetInstance().GetScreenType(rsId_, screenType);
225 if (ret == StatusCode::SUCCESS && screenType == RSScreenType::VIRTUAL_TYPE_SCREEN) {
226 rsDisplayNode->SetSecurityDisplay(true);
227 TLOGI(WmsLogTag::DMS, "virtualScreen SetSecurityDisplay success");
228 }
229 // If SetScreenOffset is not valid for SetFrame/SetBounds
230 rsDisplayNode->SetFrame(0, 0, width, height);
231 rsDisplayNode->SetBounds(0, 0, width, height);
232 }
233
InitRSDisplayNode(const RSDisplayNodeConfig & config,const Point & startPoint)234 void AbstractScreen::InitRSDisplayNode(const RSDisplayNodeConfig& config, const Point& startPoint)
235 {
236 if (rsDisplayNode_ != nullptr) {
237 rsDisplayNode_->SetDisplayNodeMirrorConfig(config);
238 TLOGD(WmsLogTag::DMS, "RSDisplayNode is not null");
239 } else {
240 TLOGD(WmsLogTag::DMS, "Create rsDisplayNode");
241 std::shared_ptr<RSDisplayNode> rsDisplayNode = RSDisplayNode::Create(config, GetRSUIContext());
242 if (rsDisplayNode == nullptr) {
243 TLOGE(WmsLogTag::DMS, "fail to add child. create rsDisplayNode fail!");
244 return;
245 }
246 RSAdapterUtil::SetSkipCheckInMultiInstance(rsDisplayNode, true);
247 rsDisplayNode_ = rsDisplayNode;
248 TLOGD(WmsLogTag::WMS_SCB,
249 "Create RSDisplayNode: %{public}s", RSAdapterUtil::RSNodeToStr(rsDisplayNode_).c_str());
250 }
251 SetPropertyForDisplayNode(rsDisplayNode_, config, startPoint);
252
253 // flush transaction
254 RSTransactionAdapter::FlushImplicitTransaction(GetRSUIContext());
255 TLOGD(WmsLogTag::DMS, "InitRSDisplayNode success");
256 }
257
InitRSDefaultDisplayNode(const RSDisplayNodeConfig & config,const Point & startPoint)258 void AbstractScreen::InitRSDefaultDisplayNode(const RSDisplayNodeConfig& config, const Point& startPoint)
259 {
260 if (rsDisplayNode_ == nullptr) {
261 TLOGD(WmsLogTag::DMS, "RSDisplayNode is nullptr");
262 }
263
264 TLOGD(WmsLogTag::DMS, "Create defaultRSDisplayNode");
265 std::shared_ptr<RSDisplayNode> rsDisplayNode = RSDisplayNode::Create(config, GetRSUIContext());
266 if (rsDisplayNode == nullptr) {
267 TLOGE(WmsLogTag::DMS, "fail to add child. create rsDisplayNode fail!");
268 return;
269 }
270 RSAdapterUtil::SetSkipCheckInMultiInstance(rsDisplayNode, true);
271 rsDisplayNode_ = rsDisplayNode;
272 TLOGD(WmsLogTag::WMS_SCB,
273 "Create RSDisplayNode: %{public}s", RSAdapterUtil::RSNodeToStr(rsDisplayNode_).c_str());
274 SetPropertyForDisplayNode(rsDisplayNode_, config, startPoint);
275
276 std::lock_guard<std::recursive_mutex> lock(mutex_);
277 // update RSTree for default display
278 for (auto node: appSurfaceNodes_) {
279 UpdateRSTree(node, true, false);
280 }
281 for (auto node: nativeSurfaceNodes_) {
282 AddSurfaceNode(node, false, false);
283 }
284
285 // flush transaction
286 RSTransactionAdapter::FlushImplicitTransaction(GetRSUIContext());
287 TLOGD(WmsLogTag::DMS, "InitRSDefaultDisplayNode success");
288 }
289
UpdateRSDisplayNode(Point startPoint,const sptr<AbstractScreen> & absScreen)290 void AbstractScreen::UpdateRSDisplayNode(Point startPoint, const sptr<AbstractScreen>& absScreen)
291 {
292 TLOGD(WmsLogTag::DMS, "update display offset from [%{public}d %{public}d] to [%{public}d %{public}d]",
293 startPoint_.posX_, startPoint_.posY_, startPoint.posX_, startPoint.posY_);
294 if (rsDisplayNode_ == nullptr) {
295 TLOGD(WmsLogTag::DMS, "rsDisplayNode_ is nullptr");
296 return;
297 }
298
299 startPoint_ = startPoint;
300 if (absScreen == nullptr) {
301 TLOGD(WmsLogTag::DMS, "absScreen is nullptr");
302 return;
303 }
304 RSInterfaces::GetInstance().SetScreenOffset(absScreen->rsId_, startPoint.posX_, startPoint.posY_);
305 }
306
GetScreenGroupId() const307 ScreenId AbstractScreen::GetScreenGroupId() const
308 {
309 return groupDmsId_;
310 }
311
GetScreenSupportedColorGamuts(std::vector<ScreenColorGamut> & colorGamuts)312 DMError AbstractScreen::GetScreenSupportedColorGamuts(std::vector<ScreenColorGamut>& colorGamuts)
313 {
314 auto ret = RSInterfaces::GetInstance().GetScreenSupportedColorGamuts(rsId_, colorGamuts);
315 if (ret != StatusCode::SUCCESS) {
316 TLOGE(WmsLogTag::DMS, "GetScreenSupportedColorGamuts fail! rsId %{public}" PRIu64"", rsId_);
317 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
318 }
319 TLOGI(WmsLogTag::DMS, "GetScreenSupportedColorGamuts ok! rsId %{public}" PRIu64", size %{public}u",
320 rsId_, static_cast<uint32_t>(colorGamuts.size()));
321
322 return DMError::DM_OK;
323 }
324
GetScreenColorGamut(ScreenColorGamut & colorGamut)325 DMError AbstractScreen::GetScreenColorGamut(ScreenColorGamut& colorGamut)
326 {
327 auto ret = RSInterfaces::GetInstance().GetScreenColorGamut(rsId_, colorGamut);
328 if (ret != StatusCode::SUCCESS) {
329 TLOGE(WmsLogTag::DMS, "GetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_);
330 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
331 }
332 TLOGI(WmsLogTag::DMS, "GetScreenColorGamut ok! rsId %{public}" PRIu64", colorGamut %{public}u",
333 rsId_, static_cast<uint32_t>(colorGamut));
334
335 return DMError::DM_OK;
336 }
337
SetScreenColorGamut(int32_t colorGamutIdx)338 DMError AbstractScreen::SetScreenColorGamut(int32_t colorGamutIdx)
339 {
340 std::vector<ScreenColorGamut> colorGamuts;
341 DMError res = GetScreenSupportedColorGamuts(colorGamuts);
342 if (res != DMError::DM_OK) {
343 TLOGE(WmsLogTag::DMS, "SetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_);
344 return res;
345 }
346 if (colorGamutIdx < 0 || colorGamutIdx >= static_cast<int32_t>(colorGamuts.size())) {
347 TLOGE(WmsLogTag::DMS, "SetScreenColorGamut fail! rsId %{public}" PRIu64" colorGamutIdx %{public}d invalid.",
348 rsId_, colorGamutIdx);
349 return DMError::DM_ERROR_INVALID_PARAM;
350 }
351 auto ret = RSInterfaces::GetInstance().SetScreenColorGamut(rsId_, colorGamutIdx);
352 if (ret != StatusCode::SUCCESS) {
353 TLOGE(WmsLogTag::DMS, "SetScreenColorGamut fail! rsId %{public}" PRIu64"", rsId_);
354 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
355 }
356 TLOGI(WmsLogTag::DMS, "SetScreenColorGamut ok! rsId %{public}" PRIu64", colorGamutIdx %{public}u",
357 rsId_, colorGamutIdx);
358
359 return DMError::DM_OK;
360 }
361
GetScreenGamutMap(ScreenGamutMap & gamutMap)362 DMError AbstractScreen::GetScreenGamutMap(ScreenGamutMap& gamutMap)
363 {
364 auto ret = RSInterfaces::GetInstance().GetScreenGamutMap(rsId_, gamutMap);
365 if (ret != StatusCode::SUCCESS) {
366 TLOGE(WmsLogTag::DMS, "GetScreenGamutMap fail! rsId %{public}" PRIu64"", rsId_);
367 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
368 }
369 TLOGI(WmsLogTag::DMS, "GetScreenGamutMap ok! rsId %{public}" PRIu64", gamutMap %{public}u",
370 rsId_, static_cast<uint32_t>(gamutMap));
371
372 return DMError::DM_OK;
373 }
374
SetScreenGamutMap(ScreenGamutMap gamutMap)375 DMError AbstractScreen::SetScreenGamutMap(ScreenGamutMap gamutMap)
376 {
377 if (gamutMap > GAMUT_MAP_HDR_EXTENSION) {
378 return DMError::DM_ERROR_INVALID_PARAM;
379 }
380 auto ret = RSInterfaces::GetInstance().SetScreenGamutMap(rsId_, gamutMap);
381 if (ret != StatusCode::SUCCESS) {
382 TLOGE(WmsLogTag::DMS, "SetScreenGamutMap fail! rsId %{public}" PRIu64"", rsId_);
383 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
384 }
385 TLOGI(WmsLogTag::DMS, "SetScreenGamutMap ok! rsId %{public}" PRIu64", gamutMap %{public}u",
386 rsId_, static_cast<uint32_t>(gamutMap));
387
388 return DMError::DM_OK;
389 }
390
SetScreenColorTransform()391 DMError AbstractScreen::SetScreenColorTransform()
392 {
393 TLOGI(WmsLogTag::DMS, "SetScreenColorTransform ok! rsId %{public}" PRIu64"", rsId_);
394
395 return DMError::DM_OK;
396 }
397
FillScreenInfo(sptr<ScreenInfo> info) const398 void AbstractScreen::FillScreenInfo(sptr<ScreenInfo> info) const
399 {
400 if (info == nullptr) {
401 TLOGE(WmsLogTag::DMS, "FillScreenInfo failed! info is nullptr");
402 return;
403 }
404 info->id_ = dmsId_;
405 info->name_ = name_;
406 uint32_t width = 0;
407 uint32_t height = 0;
408 sptr<SupportedScreenModes> abstractScreenModes = GetActiveScreenMode();
409 if (abstractScreenModes != nullptr) {
410 height = abstractScreenModes->height_;
411 width = abstractScreenModes->width_;
412 }
413 float virtualPixelRatio = virtualPixelRatio_;
414 // "< 1e-6" means virtualPixelRatio is 0.
415 if (fabsf(virtualPixelRatio) < 1e-6) {
416 virtualPixelRatio = 1.0f;
417 }
418 ScreenSourceMode sourceMode = GetSourceMode();
419 info->virtualPixelRatio_ = virtualPixelRatio;
420 info->virtualHeight_ = height / virtualPixelRatio;
421 info->virtualWidth_ = width / virtualPixelRatio;
422 info->lastParent_ = lastGroupDmsId_;
423 info->parent_ = groupDmsId_;
424 info->isScreenGroup_ = isScreenGroup_;
425 info->rotation_ = rotation_;
426 info->orientation_ = orientation_;
427 info->sourceMode_ = sourceMode;
428 info->type_ = type_;
429 info->modeId_ = activeIdx_;
430 info->modes_ = modes_;
431 }
432
SetOrientation(Orientation orientation)433 bool AbstractScreen::SetOrientation(Orientation orientation)
434 {
435 orientation_ = orientation;
436 return true;
437 }
438
SetVirtualPixelRatio(float virtualPixelRatio)439 bool AbstractScreen::SetVirtualPixelRatio(float virtualPixelRatio)
440 {
441 virtualPixelRatio_ = virtualPixelRatio;
442 return true;
443 }
444
GetVirtualPixelRatio() const445 float AbstractScreen::GetVirtualPixelRatio() const
446 {
447 return virtualPixelRatio_;
448 }
449
GetSourceMode() const450 ScreenSourceMode AbstractScreen::GetSourceMode() const
451 {
452 sptr<AbstractScreenGroup> abstractScreenGroup = GetGroup();
453 if (abstractScreenGroup == nullptr || screenController_ == nullptr) {
454 return ScreenSourceMode::SCREEN_ALONE;
455 }
456 ScreenId defaultId = screenController_->GetDefaultAbstractScreenId();
457 if (dmsId_ == defaultId) {
458 return ScreenSourceMode::SCREEN_MAIN;
459 }
460 ScreenCombination combination = abstractScreenGroup->GetScreenCombination();
461 switch (combination) {
462 case ScreenCombination::SCREEN_MIRROR: {
463 return ScreenSourceMode::SCREEN_MIRROR;
464 }
465 case ScreenCombination::SCREEN_EXPAND: {
466 return ScreenSourceMode::SCREEN_EXTEND;
467 }
468 case ScreenCombination::SCREEN_ALONE: {
469 return ScreenSourceMode::SCREEN_ALONE;
470 }
471 default: {
472 return ScreenSourceMode::SCREEN_ALONE;
473 }
474 }
475 }
476
CalcRotation(Orientation orientation) const477 Rotation AbstractScreen::CalcRotation(Orientation orientation) const
478 {
479 sptr<SupportedScreenModes> info = GetActiveScreenMode();
480 if (info == nullptr) {
481 return Rotation::ROTATION_0;
482 }
483 // vertical: phone(Plugin screen); horizontal: pad & external screen
484 bool isVerticalScreen = info->width_ < info->height_;
485 switch (orientation) {
486 case Orientation::UNSPECIFIED: {
487 return Rotation::ROTATION_0;
488 }
489 case Orientation::VERTICAL: {
490 return isVerticalScreen ? Rotation::ROTATION_0 : Rotation::ROTATION_90;
491 }
492 case Orientation::HORIZONTAL: {
493 return isVerticalScreen ? Rotation::ROTATION_90 : Rotation::ROTATION_0;
494 }
495 case Orientation::REVERSE_VERTICAL: {
496 return isVerticalScreen ? Rotation::ROTATION_180 : Rotation::ROTATION_270;
497 }
498 case Orientation::REVERSE_HORIZONTAL: {
499 return isVerticalScreen ? Rotation::ROTATION_270 : Rotation::ROTATION_180;
500 }
501 default: {
502 TLOGE(WmsLogTag::DMS, "unknown orientation %{public}u", orientation);
503 return Rotation::ROTATION_0;
504 }
505 }
506 }
507
GetScreenName() const508 const std::string& AbstractScreen::GetScreenName() const
509 {
510 return name_;
511 }
512
SetPhyWidth(uint32_t phyWidth)513 void AbstractScreen::SetPhyWidth(uint32_t phyWidth)
514 {
515 phyWidth_ = phyWidth;
516 }
517
SetPhyHeight(uint32_t phyHeight)518 void AbstractScreen::SetPhyHeight(uint32_t phyHeight)
519 {
520 phyHeight_ = phyHeight;
521 }
522
GetPhyWidth() const523 uint32_t AbstractScreen::GetPhyWidth() const
524 {
525 return phyWidth_;
526 }
527
GetPhyHeight() const528 uint32_t AbstractScreen::GetPhyHeight() const
529 {
530 return phyHeight_;
531 }
532
GetRSUIContext() const533 std::shared_ptr<RSUIContext> AbstractScreen::GetRSUIContext() const
534 {
535 RETURN_IF_RS_CLIENT_MULTI_INSTANCE_DISABLED(nullptr);
536 auto rsUIContext = rsUIDirector_ ? rsUIDirector_->GetRSUIContext() : nullptr;
537 TLOGD(WmsLogTag::WMS_SCB, "%{public}s", RSAdapterUtil::RSUIContextToStr(rsUIContext).c_str());
538 return rsUIContext;
539 }
540
AbstractScreenGroup(sptr<AbstractScreenController> screenController,ScreenId dmsId,ScreenId rsId,std::string name,ScreenCombination combination)541 AbstractScreenGroup::AbstractScreenGroup(sptr<AbstractScreenController> screenController, ScreenId dmsId, ScreenId rsId,
542 std::string name, ScreenCombination combination) : AbstractScreen(screenController, name, dmsId, rsId),
543 combination_(combination)
544 {
545 type_ = ScreenType::UNDEFINED;
546 isScreenGroup_ = true;
547 }
548
~AbstractScreenGroup()549 AbstractScreenGroup::~AbstractScreenGroup()
550 {
551 rsDisplayNode_ = nullptr;
552 }
553
ConvertToScreenGroupInfo() const554 sptr<ScreenGroupInfo> AbstractScreenGroup::ConvertToScreenGroupInfo() const
555 {
556 sptr<ScreenGroupInfo> screenGroupInfo = new(std::nothrow) ScreenGroupInfo();
557 if (screenGroupInfo == nullptr) {
558 return nullptr;
559 }
560 FillScreenInfo(screenGroupInfo);
561 screenGroupInfo->combination_ = combination_;
562 std::lock_guard<std::mutex> lock(screenMapMutex_);
563 for (auto iter = screenMap_.begin(); iter != screenMap_.end(); iter++) {
564 screenGroupInfo->children_.push_back(iter->first);
565 screenGroupInfo->position_.push_back(iter->second->startPoint_);
566 }
567 return screenGroupInfo;
568 }
569
GetRSDisplayNodeConfig(sptr<AbstractScreen> & dmsScreen,struct RSDisplayNodeConfig & config)570 bool AbstractScreenGroup::GetRSDisplayNodeConfig(sptr<AbstractScreen>& dmsScreen, struct RSDisplayNodeConfig& config)
571 {
572 if (dmsScreen == nullptr) {
573 TLOGE(WmsLogTag::DMS, "dmsScreen is nullptr.");
574 return false;
575 }
576 config = { dmsScreen->rsId_ };
577 switch (combination_) {
578 case ScreenCombination::SCREEN_ALONE:
579 [[fallthrough]];
580 case ScreenCombination::SCREEN_EXPAND:
581 break;
582 case ScreenCombination::SCREEN_MIRROR: {
583 if (GetChildCount() == 0 || mirrorScreenId_ == dmsScreen->dmsId_) {
584 TLOGI(WmsLogTag::DMS, "AddChild, SCREEN_MIRROR, config is not mirror");
585 break;
586 }
587 if (screenController_ == nullptr) {
588 return false;
589 }
590 if (mirrorScreenId_ == SCREEN_ID_INVALID || !HasChild(mirrorScreenId_)) {
591 TLOGI(WmsLogTag::DMS, "AddChild, mirrorScreenId_ is invalid, use default screen");
592 mirrorScreenId_ = screenController_->GetDefaultAbstractScreenId();
593 }
594 // Todo displayNode is nullptr
595 std::shared_ptr<RSDisplayNode> displayNode = screenController_->GetRSDisplayNodeByScreenId(mirrorScreenId_);
596 if (displayNode == nullptr) {
597 TLOGE(WmsLogTag::DMS, "AddChild fail, displayNode is nullptr, cannot get DisplayNode");
598 break;
599 }
600 NodeId nodeId = displayNode->GetId();
601 TLOGI(WmsLogTag::DMS, "AddChild, mirrorScreenId_:%{public}" PRIu64", rsId_:%{public}" PRIu64", "
602 "nodeId:%{public}" PRIu64"", mirrorScreenId_, dmsScreen->rsId_, nodeId);
603 config = {dmsScreen->rsId_, true, nodeId};
604 break;
605 }
606 default:
607 TLOGE(WmsLogTag::DMS, "fail to add child. invalid group combination:%{public}u", combination_);
608 return false;
609 }
610 return true;
611 }
612
AddChild(sptr<AbstractScreen> & dmsScreen,Point & startPoint)613 bool AbstractScreenGroup::AddChild(sptr<AbstractScreen>& dmsScreen, Point& startPoint)
614 {
615 if (dmsScreen == nullptr) {
616 TLOGE(WmsLogTag::DMS, "AddChild, dmsScreen is nullptr.");
617 return false;
618 }
619 ScreenId screenId = dmsScreen->dmsId_;
620 TLOGD(WmsLogTag::DMS, "AbstractScreenGroup AddChild dmsScreenId: %{public}" PRIu64"", screenId);
621 {
622 std::lock_guard<std::mutex> lock(screenMapMutex_);
623 auto iter = screenMap_.find(screenId);
624 if (iter != screenMap_.end()) {
625 if (dmsScreen->rsDisplayNode_ != nullptr && dmsScreen->type_ == ScreenType::REAL &&
626 defaultScreenId_ == screenId) {
627 TLOGD(WmsLogTag::DMS, "Add default screen, id: %{public}" PRIu64, screenId);
628 } else {
629 TLOGE(WmsLogTag::DMS, "AddChild, screenMap_ has dmsScreen:%{public}" PRIu64, screenId);
630 return false;
631 }
632 }
633 }
634 struct RSDisplayNodeConfig config;
635 if (!GetRSDisplayNodeConfig(dmsScreen, config)) {
636 return false;
637 }
638 if (dmsScreen->rsDisplayNode_ != nullptr && dmsScreen->type_ == ScreenType::REAL &&
639 defaultScreenId_ == screenId) {
640 TLOGD(WmsLogTag::DMS, "Reconnect default screen, screenId: %{public}" PRIu64"", screenId);
641 dmsScreen->InitRSDefaultDisplayNode(config, startPoint);
642 } else {
643 dmsScreen->InitRSDisplayNode(config, startPoint);
644 dmsScreen->lastGroupDmsId_ = dmsScreen->groupDmsId_;
645 dmsScreen->groupDmsId_ = dmsId_;
646 std::lock_guard<std::mutex> lock(screenMapMutex_);
647 screenMap_.insert(std::make_pair(screenId, dmsScreen));
648 }
649 return true;
650 }
651
AddChildren(std::vector<sptr<AbstractScreen>> & dmsScreens,std::vector<Point> & startPoints)652 bool AbstractScreenGroup::AddChildren(std::vector<sptr<AbstractScreen>>& dmsScreens, std::vector<Point>& startPoints)
653 {
654 size_t size = dmsScreens.size();
655 if (size != startPoints.size()) {
656 TLOGE(WmsLogTag::DMS, "AddChildren, unequal size.");
657 return false;
658 }
659 bool res = true;
660 for (size_t i = 0; i < size; i++) {
661 res = AddChild(dmsScreens[i], startPoints[i]) && res;
662 }
663 return res;
664 }
665
RemoveChild(sptr<AbstractScreen> & dmsScreen)666 bool AbstractScreenGroup::RemoveChild(sptr<AbstractScreen>& dmsScreen)
667 {
668 if (dmsScreen == nullptr) {
669 TLOGE(WmsLogTag::DMS, "RemoveChild, dmsScreen is nullptr.");
670 return false;
671 }
672 ScreenId screenId = dmsScreen->dmsId_;
673 dmsScreen->lastGroupDmsId_ = dmsScreen->groupDmsId_;
674 dmsScreen->groupDmsId_ = SCREEN_ID_INVALID;
675 dmsScreen->startPoint_ = Point();
676 if (dmsScreen->rsDisplayNode_ != nullptr) {
677 RSInterfaces::GetInstance().SetScreenOffset(dmsScreen->rsId_, 0, 0);
678 dmsScreen->rsDisplayNode_->RemoveFromTree();
679 RSTransactionAdapter::FlushImplicitTransaction(dmsScreen->GetRSUIContext());
680 dmsScreen->rsDisplayNode_ = nullptr;
681 }
682 TLOGD(WmsLogTag::DMS, "groupDmsId:%{public}" PRIu64", screenId:%{public}" PRIu64"",
683 dmsScreen->groupDmsId_, screenId);
684 std::lock_guard<std::mutex> lock(screenMapMutex_);
685 return screenMap_.erase(screenId);
686 }
687
RemoveDefaultScreen(const sptr<AbstractScreen> & dmsScreen)688 bool AbstractScreenGroup::RemoveDefaultScreen(const sptr<AbstractScreen>& dmsScreen)
689 {
690 if (dmsScreen == nullptr) {
691 TLOGE(WmsLogTag::DMS, "RemoveChild, dmsScreen is nullptr.");
692 return false;
693 }
694 ScreenId screenId = dmsScreen->dmsId_;
695 dmsScreen->lastGroupDmsId_ = dmsScreen->groupDmsId_;
696 if (dmsScreen->rsDisplayNode_ != nullptr) {
697 RSInterfaces::GetInstance().SetScreenOffset(dmsScreen->rsId_, 0, 0);
698 dmsScreen->rsDisplayNode_->RemoveFromTree();
699 RSTransactionAdapter::FlushImplicitTransaction(dmsScreen->GetRSUIContext());
700 }
701 defaultScreenId_ = screenId;
702 TLOGD(WmsLogTag::DMS, "groupDmsId:%{public}" PRIu64", screenId:%{public}" PRIu64"",
703 dmsScreen->groupDmsId_, screenId);
704 return true;
705 }
706
HasChild(ScreenId childScreen) const707 bool AbstractScreenGroup::HasChild(ScreenId childScreen) const
708 {
709 std::lock_guard<std::mutex> lock(screenMapMutex_);
710 return screenMap_.find(childScreen) != screenMap_.end();
711 }
712
GetChildren() const713 std::vector<sptr<AbstractScreen>> AbstractScreenGroup::GetChildren() const
714 {
715 std::vector<sptr<AbstractScreen>> res;
716 std::lock_guard<std::mutex> lock(screenMapMutex_);
717 for (auto iter = screenMap_.begin(); iter != screenMap_.end(); iter++) {
718 res.push_back(iter->second);
719 }
720 return res;
721 }
722
GetChildrenPosition() const723 std::vector<Point> AbstractScreenGroup::GetChildrenPosition() const
724 {
725 std::vector<Point> res;
726 std::lock_guard<std::mutex> lock(screenMapMutex_);
727 for (auto iter = screenMap_.begin(); iter != screenMap_.end(); iter++) {
728 res.push_back(iter->second->startPoint_);
729 }
730 return res;
731 }
732
GetChildPosition(ScreenId screenId) const733 Point AbstractScreenGroup::GetChildPosition(ScreenId screenId) const
734 {
735 Point point;
736 std::lock_guard<std::mutex> lock(screenMapMutex_);
737 auto iter = screenMap_.find(screenId);
738 if (iter != screenMap_.end()) {
739 point = iter->second->startPoint_;
740 }
741 return point;
742 }
743
GetChildCount() const744 size_t AbstractScreenGroup::GetChildCount() const
745 {
746 std::lock_guard<std::mutex> lock(screenMapMutex_);
747 return screenMap_.size();
748 }
749
GetScreenCombination() const750 ScreenCombination AbstractScreenGroup::GetScreenCombination() const
751 {
752 return combination_;
753 }
754
GetDisplaySourceMode() const755 DisplaySourceMode AbstractScreen::GetDisplaySourceMode() const
756 {
757 TLOGI(WmsLogTag::DMS, "in");
758 sptr<AbstractScreenGroup> abstractScreenGroup = GetGroup();
759 if (abstractScreenGroup == nullptr || screenController_ == nullptr) {
760 TLOGW(WmsLogTag::DMS, "default NONE");
761 return DisplaySourceMode::NONE;
762 }
763 ScreenId defaultId = screenController_->GetDefaultAbstractScreenId();
764 if (dmsId_ == defaultId) {
765 TLOGW(WmsLogTag::DMS, "err MAIN");
766 return DisplaySourceMode::MAIN;
767 }
768 ScreenCombination combination = abstractScreenGroup->GetScreenCombination();
769 switch (combination) {
770 case ScreenCombination::SCREEN_MAIN: {
771 return DisplaySourceMode::MAIN;
772 }
773 case ScreenCombination::SCREEN_MIRROR: {
774 return DisplaySourceMode::MIRROR;
775 }
776 case ScreenCombination::SCREEN_EXPAND:
777 case ScreenCombination::SCREEN_EXTEND: {
778 return DisplaySourceMode::EXTEND;
779 }
780 case ScreenCombination::SCREEN_UNIQUE: {
781 return DisplaySourceMode::ALONE;
782 }
783 case ScreenCombination::SCREEN_ALONE: {
784 return DisplaySourceMode::NONE;
785 }
786 default: {
787 TLOGW(WmsLogTag::DMS, "default NONE");
788 return DisplaySourceMode::NONE;
789 }
790 }
791 }
792 } // namespace OHOS::Rosen
793