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_controller.h"
17
18 #include <cinttypes>
19 #include <screen_manager/rs_screen_mode_info.h>
20 #include <screen_manager/screen_types.h>
21 #include <sstream>
22 #include <surface.h>
23 #include <thread>
24
25 #include "display_manager_agent_controller.h"
26 #include "display_manager_service.h"
27 #include "event_runner.h"
28 #include "window_manager_hilog.h"
29 #include "wm_trace.h"
30
31 namespace OHOS::Rosen {
32 namespace {
33 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "AbstractScreenController"};
34 const std::string CONTROLLER_THREAD_ID = "abstract_screen_controller_thread";
35 }
36
AbstractScreenController(std::recursive_mutex & mutex)37 AbstractScreenController::AbstractScreenController(std::recursive_mutex& mutex)
38 : mutex_(mutex), rsInterface_(RSInterfaces::GetInstance())
39 {
40 auto runner = AppExecFwk::EventRunner::Create(CONTROLLER_THREAD_ID);
41 controllerHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
42 }
43
~AbstractScreenController()44 AbstractScreenController::~AbstractScreenController()
45 {
46 }
47
Init()48 void AbstractScreenController::Init()
49 {
50 WLOGFD("screen controller init");
51 RegisterRsScreenConnectionChangeListener();
52 }
53
RegisterRsScreenConnectionChangeListener()54 void AbstractScreenController::RegisterRsScreenConnectionChangeListener()
55 {
56 WLOGFD("RegisterRsScreenConnectionChangeListener");
57 auto res = rsInterface_.SetScreenChangeCallback(
58 std::bind(&AbstractScreenController::OnRsScreenConnectionChange,
59 this, std::placeholders::_1, std::placeholders::_2));
60 if (res != StatusCode::SUCCESS) {
61 auto task = [this] {
62 RegisterRsScreenConnectionChangeListener();
63 };
64 // posk task after 50 ms.
65 controllerHandler_->PostTask(task, 50, AppExecFwk::EventQueue::Priority::HIGH);
66 }
67 }
68
GetAllScreenIds() const69 std::vector<ScreenId> AbstractScreenController::GetAllScreenIds() const
70 {
71 std::lock_guard<std::recursive_mutex> lock(mutex_);
72 std::vector<ScreenId> res;
73 for (auto iter = dmsScreenMap_.begin(); iter != dmsScreenMap_.end(); iter++) {
74 res.push_back(iter->first);
75 }
76 return res;
77 }
78
GetShotScreenIds(std::vector<ScreenId> mirrorScreenIds) const79 std::vector<ScreenId> AbstractScreenController::GetShotScreenIds(std::vector<ScreenId> mirrorScreenIds) const
80 {
81 WLOGI("GetShotScreenIds");
82 std::lock_guard<std::recursive_mutex> lock(mutex_);
83 std::vector<ScreenId> screenIds;
84 for (ScreenId screenId : mirrorScreenIds) {
85 auto iter = std::find(screenIds.begin(), screenIds.end(), screenId);
86 if (iter != screenIds.end()) {
87 continue;
88 }
89 auto dmsScreenIter = dmsScreenMap_.find(screenId);
90 if (screenIdManager_.HasDmsScreenId(screenId) && dmsScreenIter == dmsScreenMap_.end()) {
91 screenIds.emplace_back(screenId);
92 WLOGI("GetShotScreenIds: screenId: %{public}" PRIu64"", screenId);
93 }
94 }
95 return screenIds;
96 }
97
GetAllExpandOrMirrorScreenIds(std::vector<ScreenId> mirrorScreenIds) const98 std::vector<ScreenId> AbstractScreenController::GetAllExpandOrMirrorScreenIds(
99 std::vector<ScreenId> mirrorScreenIds) const
100 {
101 std::lock_guard<std::recursive_mutex> lock(mutex_);
102 std::vector<ScreenId> screenIds;
103 for (ScreenId screenId : mirrorScreenIds) {
104 auto screenIdIter = std::find(screenIds.begin(), screenIds.end(), screenId);
105 if (screenIdIter != screenIds.end()) {
106 continue;
107 }
108 auto iter = dmsScreenMap_.find(screenId);
109 if (iter != dmsScreenMap_.end()) {
110 screenIds.emplace_back(screenId);
111 }
112 }
113 if (screenIds.empty()) {
114 WLOGI("GetAllExpandOrMirrorScreenIds, screenIds is empty");
115 return screenIds;
116 }
117 for (auto iter = dmsScreenMap_.begin(); iter != dmsScreenMap_.end(); iter++) {
118 if (iter->second->type_ != ScreenType::REAL) {
119 continue;
120 }
121 auto screenIdIter = std::find(screenIds.begin(), screenIds.end(), iter->first);
122 if (screenIdIter == screenIds.end()) {
123 screenIds.emplace_back(iter->first);
124 WLOGI("GetAllExpandOrMirrorScreenIds: screenId: %{public}" PRIu64"", iter->first);
125 }
126 }
127 return screenIds;
128 }
129
GetRSDisplayNodeByScreenId(ScreenId dmsScreenId) const130 std::shared_ptr<RSDisplayNode> AbstractScreenController::GetRSDisplayNodeByScreenId(ScreenId dmsScreenId) const
131 {
132 sptr<AbstractScreen> screen = GetAbstractScreen(dmsScreenId);
133 if (screen == nullptr) {
134 return nullptr;
135 }
136 WLOGI("GetRSDisplayNodeByScreenId: screen: %{public}" PRIu64", nodeId: %{public}" PRIu64" ",
137 screen->dmsId_, screen->rsDisplayNode_->GetId());
138 return screen->rsDisplayNode_;
139 }
140
UpdateRSTree(ScreenId dmsScreenId,std::shared_ptr<RSSurfaceNode> & surfaceNode,bool isAdd)141 void AbstractScreenController::UpdateRSTree(ScreenId dmsScreenId, std::shared_ptr<RSSurfaceNode>& surfaceNode,
142 bool isAdd)
143 {
144 sptr<AbstractScreen> abstractScreen = GetAbstractScreen(dmsScreenId);
145 if (abstractScreen == nullptr) {
146 WLOGE("AbstractScreenController::UpdateRSTree can not find abstractScreen");
147 return;
148 }
149 abstractScreen->UpdateRSTree(surfaceNode, isAdd);
150 }
151
GetAbstractScreen(ScreenId dmsScreenId) const152 sptr<AbstractScreen> AbstractScreenController::GetAbstractScreen(ScreenId dmsScreenId) const
153 {
154 WLOGI("GetAbstractScreen: screenId: %{public}" PRIu64"", dmsScreenId);
155 std::lock_guard<std::recursive_mutex> lock(mutex_);
156 auto iter = dmsScreenMap_.find(dmsScreenId);
157 if (iter == dmsScreenMap_.end()) {
158 WLOGE("did not find screen:%{public}" PRIu64"", dmsScreenId);
159 return nullptr;
160 }
161 return iter->second;
162 }
163
GetAbstractScreenGroup(ScreenId dmsScreenId)164 sptr<AbstractScreenGroup> AbstractScreenController::GetAbstractScreenGroup(ScreenId dmsScreenId)
165 {
166 std::lock_guard<std::recursive_mutex> lock(mutex_);
167 auto iter = dmsScreenGroupMap_.find(dmsScreenId);
168 if (iter == dmsScreenGroupMap_.end()) {
169 WLOGE("didnot find screen:%{public}" PRIu64"", dmsScreenId);
170 return nullptr;
171 }
172 return iter->second;
173 }
174
GetDefaultAbstractScreenId()175 ScreenId AbstractScreenController::GetDefaultAbstractScreenId()
176 {
177 std::lock_guard<std::recursive_mutex> lock(mutex_);
178 ScreenId rsDefaultId = rsInterface_.GetDefaultScreenId();
179 if (rsDefaultId == SCREEN_ID_INVALID) {
180 WLOGFW("GetDefaultAbstractScreenId, rsDefaultId is invalid.");
181 return SCREEN_ID_INVALID;
182 }
183 ScreenId defaultDmsScreenId;
184 if (screenIdManager_.ConvertToDmsScreenId(rsDefaultId, defaultDmsScreenId)) {
185 WLOGI("GetDefaultAbstractScreenId, screen:%{public}" PRIu64"", defaultDmsScreenId);
186 return defaultDmsScreenId;
187 }
188 WLOGFI("GetDefaultAbstractScreenId, default screen is null, try to get.");
189 ProcessScreenConnected(rsDefaultId);
190 return screenIdManager_.ConvertToDmsScreenId(rsDefaultId);
191 }
192
ConvertToRsScreenId(ScreenId dmsScreenId) const193 ScreenId AbstractScreenController::ConvertToRsScreenId(ScreenId dmsScreenId) const
194 {
195 std::lock_guard<std::recursive_mutex> lock(mutex_);
196 return screenIdManager_.ConvertToRsScreenId(dmsScreenId);
197 }
198
ConvertToDmsScreenId(ScreenId rsScreenId) const199 ScreenId AbstractScreenController::ConvertToDmsScreenId(ScreenId rsScreenId) const
200 {
201 std::lock_guard<std::recursive_mutex> lock(mutex_);
202 return screenIdManager_.ConvertToDmsScreenId(rsScreenId);
203 }
204
RegisterAbstractScreenCallback(sptr<AbstractScreenCallback> cb)205 void AbstractScreenController::RegisterAbstractScreenCallback(sptr<AbstractScreenCallback> cb)
206 {
207 std::lock_guard<std::recursive_mutex> lock(mutex_);
208 abstractScreenCallback_ = cb;
209 }
210
OnRsScreenConnectionChange(ScreenId rsScreenId,ScreenEvent screenEvent)211 void AbstractScreenController::OnRsScreenConnectionChange(ScreenId rsScreenId, ScreenEvent screenEvent)
212 {
213 WLOGFI("rs screen event. id:%{public}" PRIu64", event:%{public}u", rsScreenId, static_cast<uint32_t>(screenEvent));
214 if (screenEvent == ScreenEvent::CONNECTED) {
215 ProcessScreenConnected(rsScreenId);
216 auto task = [this, rsScreenId] {
217 ProcessScreenConnected(rsScreenId);
218 };
219 controllerHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::HIGH);
220 } else if (screenEvent == ScreenEvent::DISCONNECTED) {
221 auto task = [this, rsScreenId] {
222 ProcessScreenDisconnected(rsScreenId);
223 };
224 controllerHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::HIGH);
225 } else {
226 WLOGE("unknown message:%{public}ud", static_cast<uint8_t>(screenEvent));
227 }
228 }
229
ScreenConnectionInDisplayInit(sptr<AbstractScreenCallback> abstractScreenCallback)230 void AbstractScreenController::ScreenConnectionInDisplayInit(sptr<AbstractScreenCallback> abstractScreenCallback)
231 {
232 std::map<ScreenId, sptr<AbstractScreen>> dmsScreenMap;
233 {
234 std::lock_guard<std::recursive_mutex> lock(mutex_);
235 dmsScreenMap = dmsScreenMap_;
236 if (dmsScreenMap_.empty()) {
237 return;
238 }
239 }
240
241 for (auto& iter : dmsScreenMap) {
242 if (iter.second != nullptr && abstractScreenCallback != nullptr) {
243 WLOGFI("dmsScreenId :%{public}" PRIu64"", iter.first);
244 abstractScreenCallback->onConnect_(iter.second);
245 }
246 }
247 }
248
ProcessScreenConnected(ScreenId rsScreenId)249 void AbstractScreenController::ProcessScreenConnected(ScreenId rsScreenId)
250 {
251 std::lock_guard<std::recursive_mutex> lock(mutex_);
252 if (!screenIdManager_.HasRsScreenId(rsScreenId)) {
253 WLOGFD("connect new screen");
254 auto absScreen = InitAndGetScreen(rsScreenId);
255 if (absScreen == nullptr) {
256 return;
257 }
258 sptr<AbstractScreenGroup> screenGroup = AddToGroupLocked(absScreen);
259 if (screenGroup != nullptr) {
260 NotifyScreenGroupChanged(absScreen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
261 }
262 if (screenGroup != nullptr && abstractScreenCallback_ != nullptr) {
263 abstractScreenCallback_->onConnect_(absScreen);
264 }
265 } else {
266 WLOGE("reconnect screen, screenId=%{public}" PRIu64"", rsScreenId);
267 }
268 }
269
InitAndGetScreen(ScreenId rsScreenId)270 sptr<AbstractScreen> AbstractScreenController::InitAndGetScreen(ScreenId rsScreenId)
271 {
272 ScreenId dmsScreenId = screenIdManager_.CreateAndGetNewScreenId(rsScreenId);
273 std::ostringstream buffer;
274 buffer<<DEFAULT_SCREEN_NAME<<"_"<<dmsScreenId;
275 std::string name = buffer.str();
276 sptr<AbstractScreen> absScreen =
277 new(std::nothrow) AbstractScreen(this, name, dmsScreenId, rsScreenId);
278 if (absScreen == nullptr) {
279 WLOGFE("new AbstractScreen failed.");
280 screenIdManager_.DeleteScreenId(dmsScreenId);
281 return nullptr;
282 }
283 if (!FillAbstractScreen(absScreen, rsScreenId)) {
284 screenIdManager_.DeleteScreenId(dmsScreenId);
285 WLOGFE("InitAndGetScreen failed.");
286 return nullptr;
287 }
288 dmsScreenMap_.insert(std::make_pair(dmsScreenId, absScreen));
289 NotifyScreenConnected(absScreen->ConvertToScreenInfo());
290 return absScreen;
291 }
292
ProcessScreenDisconnected(ScreenId rsScreenId)293 void AbstractScreenController::ProcessScreenDisconnected(ScreenId rsScreenId)
294 {
295 WLOGFI("disconnect screen, screenId=%{public}" PRIu64"", rsScreenId);
296 ScreenId dmsScreenId;
297 std::lock_guard<std::recursive_mutex> lock(mutex_);
298 if (!screenIdManager_.ConvertToDmsScreenId(rsScreenId, dmsScreenId)) {
299 WLOGFE("disconnect screen, screenId=%{public}" PRIu64" is not in rs2DmsScreenIdMap_", rsScreenId);
300 return;
301 }
302 auto dmsScreenMapIter = dmsScreenMap_.find(dmsScreenId);
303 sptr<AbstractScreenGroup> screenGroup;
304 if (dmsScreenMapIter != dmsScreenMap_.end()) {
305 auto screen = dmsScreenMapIter->second;
306 if (abstractScreenCallback_ != nullptr && CheckScreenInScreenGroup(screen)) {
307 abstractScreenCallback_->onDisconnect_(screen);
308 }
309 screenGroup = RemoveFromGroupLocked(screen);
310 if (screenGroup != nullptr) {
311 NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
312 }
313 dmsScreenMap_.erase(dmsScreenMapIter);
314 NotifyScreenDisconnected(dmsScreenId);
315 if (screenGroup != nullptr && screenGroup->combination_ == ScreenCombination::SCREEN_MIRROR &&
316 screen->dmsId_ == screenGroup->mirrorScreenId_ && screenGroup->GetChildCount() != 0) {
317 auto defaultScreenId = GetDefaultAbstractScreenId();
318 std::vector<ScreenId> screens;
319 for (auto screen : screenGroup->GetChildren()) {
320 if (screen->dmsId_ != defaultScreenId) {
321 screens.emplace_back(screen->dmsId_);
322 }
323 }
324 MakeMirror(defaultScreenId, screens);
325 }
326 }
327 screenIdManager_.DeleteScreenId(dmsScreenId);
328 }
329
FillAbstractScreen(sptr<AbstractScreen> & absScreen,ScreenId rsScreenId)330 bool AbstractScreenController::FillAbstractScreen(sptr<AbstractScreen>& absScreen, ScreenId rsScreenId)
331 {
332 std::vector<RSScreenModeInfo> allModes = rsInterface_.GetScreenSupportedModes(rsScreenId);
333 if (allModes.size() == 0) {
334 WLOGE("supported screen mode is 0, screenId=%{public}" PRIu64"", rsScreenId);
335 return false;
336 }
337 for (RSScreenModeInfo rsScreenModeInfo : allModes) {
338 sptr<SupportedScreenModes> info = new SupportedScreenModes();
339 info->width_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenWidth());
340 info->height_ = static_cast<uint32_t>(rsScreenModeInfo.GetScreenHeight());
341 info->refreshRate_ = rsScreenModeInfo.GetScreenFreshRate();
342 absScreen->modes_.push_back(info);
343 WLOGD("fill screen w/h:%{public}d/%{public}d", info->width_, info->height_);
344 }
345 int32_t activeModeId = rsInterface_.GetScreenActiveMode(rsScreenId).GetScreenModeId();
346 WLOGD("fill screen activeModeId:%{public}d", activeModeId);
347 if (static_cast<std::size_t>(activeModeId) >= allModes.size()) {
348 WLOGE("activeModeId exceed, screenId=%{public}" PRIu64", activeModeId:%{public}d/%{public}ud",
349 rsScreenId, activeModeId, static_cast<uint32_t>(allModes.size()));
350 return false;
351 }
352 absScreen->activeIdx_ = activeModeId;
353 return true;
354 }
355
AddToGroupLocked(sptr<AbstractScreen> newScreen)356 sptr<AbstractScreenGroup> AbstractScreenController::AddToGroupLocked(sptr<AbstractScreen> newScreen)
357 {
358 sptr<AbstractScreenGroup> res;
359 if (dmsScreenGroupMap_.empty()) {
360 WLOGI("connect the first screen");
361 res = AddAsFirstScreenLocked(newScreen);
362 } else {
363 res = AddAsSuccedentScreenLocked(newScreen);
364 }
365 return res;
366 }
367
RemoveFromGroupLocked(sptr<AbstractScreen> screen)368 sptr<AbstractScreenGroup> AbstractScreenController::RemoveFromGroupLocked(sptr<AbstractScreen> screen)
369 {
370 WLOGI("RemoveFromGroupLocked.");
371 auto groupDmsId = screen->groupDmsId_;
372 auto iter = dmsScreenGroupMap_.find(groupDmsId);
373 if (iter == dmsScreenGroupMap_.end()) {
374 WLOGE("RemoveFromGroupLocked. groupDmsId:%{public}" PRIu64"is not in dmsScreenGroupMap_.", groupDmsId);
375 return nullptr;
376 }
377 sptr<AbstractScreenGroup> screenGroup = iter->second;
378 if (!RemoveChildFromGroup(screen, screenGroup)) {
379 return nullptr;
380 }
381 return screenGroup;
382 }
383
RemoveChildFromGroup(sptr<AbstractScreen> screen,sptr<AbstractScreenGroup> screenGroup)384 bool AbstractScreenController::RemoveChildFromGroup(sptr<AbstractScreen> screen, sptr<AbstractScreenGroup> screenGroup)
385 {
386 bool res = screenGroup->RemoveChild(screen);
387 if (!res) {
388 WLOGE("RemoveFromGroupLocked. remove screen:%{public}" PRIu64" failed from screenGroup:%{public}" PRIu64".",
389 screen->dmsId_, screen->groupDmsId_);
390 return false;
391 }
392 if (screenGroup->GetChildCount() == 0) {
393 // Group removed, need to do something.
394 dmsScreenGroupMap_.erase(screenGroup->dmsId_);
395 dmsScreenMap_.erase(screenGroup->dmsId_);
396 }
397 return true;
398 }
399
CheckScreenInScreenGroup(sptr<AbstractScreen> screen) const400 bool AbstractScreenController::CheckScreenInScreenGroup(sptr<AbstractScreen> screen) const
401 {
402 WLOGI("CheckScreenInScreenGroup.");
403 auto groupDmsId = screen->groupDmsId_;
404 auto iter = dmsScreenGroupMap_.find(groupDmsId);
405 if (iter == dmsScreenGroupMap_.end()) {
406 WLOGE("CheckScreenInScreenGroup. groupDmsId:%{public}" PRIu64"is not in dmsScreenGroupMap_.", groupDmsId);
407 return false;
408 }
409 sptr<AbstractScreenGroup> screenGroup = iter->second;
410 return screenGroup->HasChild(screen->dmsId_);
411 }
412
AddAsFirstScreenLocked(sptr<AbstractScreen> newScreen)413 sptr<AbstractScreenGroup> AbstractScreenController::AddAsFirstScreenLocked(sptr<AbstractScreen> newScreen)
414 {
415 ScreenId dmsGroupScreenId = screenIdManager_.CreateAndGetNewScreenId(SCREEN_ID_INVALID);
416 std::ostringstream buffer;
417 buffer<<"ScreenGroup_"<<dmsGroupScreenId;
418 std::string name = buffer.str();
419 sptr<AbstractScreenGroup> screenGroup = new(std::nothrow) AbstractScreenGroup(this, dmsGroupScreenId,
420 SCREEN_ID_INVALID, name, ScreenCombination::SCREEN_MIRROR);
421 if (screenGroup == nullptr) {
422 WLOGE("new AbstractScreenGroup failed");
423 screenIdManager_.DeleteScreenId(dmsGroupScreenId);
424 return nullptr;
425 }
426 Point point;
427 if (!screenGroup->AddChild(newScreen, point)) {
428 WLOGE("fail to add screen to group. screen=%{public}" PRIu64"", newScreen->dmsId_);
429 screenIdManager_.DeleteScreenId(dmsGroupScreenId);
430 return nullptr;
431 }
432 auto iter = dmsScreenGroupMap_.find(dmsGroupScreenId);
433 if (iter != dmsScreenGroupMap_.end()) {
434 WLOGE("group screen existed. id=%{public}" PRIu64"", dmsGroupScreenId);
435 dmsScreenGroupMap_.erase(iter);
436 }
437 dmsScreenGroupMap_.insert(std::make_pair(dmsGroupScreenId, screenGroup));
438 dmsScreenMap_.insert(std::make_pair(dmsGroupScreenId, screenGroup));
439 screenGroup->mirrorScreenId_ = newScreen->dmsId_;
440 WLOGI("connect new group screen. id=%{public}" PRIu64"/%{public}" PRIu64", combination:%{public}u",
441 newScreen->dmsId_, dmsGroupScreenId, newScreen->type_);
442 return screenGroup;
443 }
444
AddAsSuccedentScreenLocked(sptr<AbstractScreen> newScreen)445 sptr<AbstractScreenGroup> AbstractScreenController::AddAsSuccedentScreenLocked(sptr<AbstractScreen> newScreen)
446 {
447 ScreenId defaultScreenId = GetDefaultAbstractScreenId();
448 auto iter = dmsScreenMap_.find(defaultScreenId);
449 if (iter == dmsScreenMap_.end()) {
450 WLOGE("AddAsSuccedentScreenLocked. defaultScreenId:%{public}" PRIu64" is not in dmsScreenMap_.",
451 defaultScreenId);
452 return nullptr;
453 }
454 auto screen = iter->second;
455 auto screenGroupIter = dmsScreenGroupMap_.find(screen->groupDmsId_);
456 if (screenGroupIter == dmsScreenGroupMap_.end()) {
457 WLOGE("AddAsSuccedentScreenLocked. groupDmsId:%{public}" PRIu64" is not in dmsScreenGroupMap_.",
458 screen->groupDmsId_);
459 return nullptr;
460 }
461 auto screenGroup = screenGroupIter->second;
462 Point point;
463 screenGroup->AddChild(newScreen, point);
464 return screenGroup;
465 }
466
CreateVirtualScreen(VirtualScreenOption option)467 ScreenId AbstractScreenController::CreateVirtualScreen(VirtualScreenOption option)
468 {
469 ScreenId rsId = rsInterface_.CreateVirtualScreen(option.name_, option.width_,
470 option.height_, option.surface_, SCREEN_ID_INVALID, option.flags_);
471 WLOGFI("id: %{public}" PRIu64"", rsId);
472 if (rsId == SCREEN_ID_INVALID) {
473 return SCREEN_ID_INVALID;
474 }
475 std::lock_guard<std::recursive_mutex> lock(mutex_);
476 ScreenId dmsScreenId = SCREEN_ID_INVALID;
477 if (!screenIdManager_.ConvertToDmsScreenId(rsId, dmsScreenId)) {
478 dmsScreenId = screenIdManager_.CreateAndGetNewScreenId(rsId);
479 if (!option.isForShot_) {
480 WLOGI("CreateVirtualScreen is not shot");
481 sptr<AbstractScreen> absScreen = new(std::nothrow) AbstractScreen(this, option.name_, dmsScreenId, rsId);
482 sptr<SupportedScreenModes> info = new(std::nothrow) SupportedScreenModes();
483 if (absScreen == nullptr || info == nullptr) {
484 WLOGFI("new AbstractScreen or SupportedScreenModes failed");
485 screenIdManager_.DeleteScreenId(dmsScreenId);
486 return SCREEN_ID_INVALID;
487 }
488 info->width_ = option.width_;
489 info->height_ = option.height_;
490 auto defaultScreen = GetAbstractScreen(GetDefaultAbstractScreenId());
491 if (defaultScreen != nullptr && defaultScreen->GetActiveScreenMode() != nullptr) {
492 info->refreshRate_ = defaultScreen->GetActiveScreenMode()->refreshRate_;
493 }
494 absScreen->modes_.push_back(info);
495 absScreen->activeIdx_ = 0;
496 absScreen->type_ = ScreenType::VIRTUAL;
497 dmsScreenMap_.insert(std::make_pair(dmsScreenId, absScreen));
498 NotifyScreenConnected(absScreen->ConvertToScreenInfo());
499 } else {
500 WLOGI("CreateVirtualScreen is shot");
501 }
502 } else {
503 WLOGFI("id: %{public}" PRIu64" appears in screenIdManager_. ", rsId);
504 }
505 return dmsScreenId;
506 }
507
DestroyVirtualScreen(ScreenId screenId)508 DMError AbstractScreenController::DestroyVirtualScreen(ScreenId screenId)
509 {
510 WLOGFI("AbstractScreenController::DestroyVirtualScreen");
511 std::lock_guard<std::recursive_mutex> lock(mutex_);
512 ScreenId rsScreenId = SCREEN_ID_INVALID;
513 screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId);
514 if (rsScreenId != SCREEN_ID_INVALID && GetAbstractScreen(screenId) != nullptr) {
515 ProcessScreenDisconnected(rsScreenId);
516 }
517 screenIdManager_.DeleteScreenId(screenId);
518 if (rsScreenId != SCREEN_ID_INVALID) {
519 rsInterface_.RemoveVirtualScreen(rsScreenId);
520 }
521 WLOGFI("DumpScreenInfo after Destroy VirtualScreen");
522 DumpScreenInfo();
523 return DMError::DM_OK;
524 }
525
SetVirtualScreenSurface(ScreenId screenId,sptr<Surface> surface)526 DMError AbstractScreenController::SetVirtualScreenSurface(ScreenId screenId, sptr<Surface> surface)
527 {
528 WLOGFI("AbstractScreenController::SetVirtualScreenSurface");
529 int32_t res = -1;
530 ScreenId rsScreenId;
531 if (screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
532 res = rsInterface_.SetVirtualScreenSurface(rsScreenId, surface);
533 }
534 if (res != 0) {
535 WLOGE("SetVirtualScreenSurface failed in RenderService");
536 return DMError::DM_ERROR_RENDER_SERVICE_FAILED;
537 }
538 return DMError::DM_OK;
539 }
540
SetOrientation(ScreenId screenId,Orientation newOrientation,bool isFromWindow)541 bool AbstractScreenController::SetOrientation(ScreenId screenId, Orientation newOrientation, bool isFromWindow)
542 {
543 WLOGD("set orientation. screen %{public}" PRIu64" orientation %{public}u", screenId, newOrientation);
544 auto screen = GetAbstractScreen(screenId);
545 if (screen == nullptr) {
546 WLOGFE("fail to set orientation, cannot find screen %{public}" PRIu64"", screenId);
547 return false;
548 }
549 if (screen->isScreenGroup_) {
550 WLOGE("cannot set orientation to the combination. screen: %{public}" PRIu64"", screenId);
551 return false;
552 }
553 if (isFromWindow) {
554 if (newOrientation == Orientation::UNSPECIFIED) {
555 newOrientation = screen->screenRequestedOrientation_;
556 }
557 } else {
558 screen->screenRequestedOrientation_ = newOrientation;
559 }
560 if (screen->orientation_ == newOrientation) {
561 WLOGI("skip setting orientation. screen %{public}" PRIu64" orientation %{public}u", screenId, newOrientation);
562 return true;
563 }
564
565 Rotation rotationAfter = screen->CalcRotation(newOrientation);
566 if (rotationAfter != screen->rotation_) {
567 WLOGI("set orientation. roatiton %{public}u", rotationAfter);
568 if (!rsInterface_.RequestRotation(screenId, static_cast<ScreenRotation>(rotationAfter))) {
569 WLOGE("rotate screen fail. %{public}" PRIu64"", screenId);
570 return false;
571 }
572 } else {
573 WLOGI("rotation not changed. screen %{public}" PRIu64" rotation %{public}u", screenId, rotationAfter);
574 }
575 if (!screen->SetOrientation(newOrientation)) {
576 WLOGE("fail to set orientation, screen %{public}" PRIu64"", screenId);
577 return false;
578 }
579 screen->rotation_ = rotationAfter;
580
581 // Notify rotation event to ScreenManager
582 NotifyScreenChanged(screen->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ORIENTATION);
583 // Notify rotation event to AbstractDisplayController
584 if (abstractScreenCallback_ != nullptr) {
585 abstractScreenCallback_->onChange_(screen, DisplayChangeEvent::UPDATE_ORIENTATION);
586 }
587 return true;
588 }
589
GetScreenSupportedColorGamuts(ScreenId screenId,std::vector<ScreenColorGamut> & colorGamuts)590 DMError AbstractScreenController::GetScreenSupportedColorGamuts(ScreenId screenId,
591 std::vector<ScreenColorGamut>& colorGamuts)
592 {
593 sptr<AbstractScreen> screen = GetAbstractScreen(screenId);
594 if (screen == nullptr) {
595 return DMError::DM_ERROR_INVALID_PARAM;
596 }
597 return screen->GetScreenSupportedColorGamuts(colorGamuts);
598 }
599
GetScreenColorGamut(ScreenId screenId,ScreenColorGamut & colorGamut)600 DMError AbstractScreenController::GetScreenColorGamut(ScreenId screenId, ScreenColorGamut& colorGamut)
601 {
602 sptr<AbstractScreen> screen = GetAbstractScreen(screenId);
603 if (screen == nullptr) {
604 return DMError::DM_ERROR_INVALID_PARAM;
605 }
606 return screen->GetScreenColorGamut(colorGamut);
607 }
608
SetScreenColorGamut(ScreenId screenId,int32_t colorGamutIdx)609 DMError AbstractScreenController::SetScreenColorGamut(ScreenId screenId, int32_t colorGamutIdx)
610 {
611 sptr<AbstractScreen> screen = GetAbstractScreen(screenId);
612 if (screen == nullptr) {
613 return DMError::DM_ERROR_INVALID_PARAM;
614 }
615 return screen->SetScreenColorGamut(colorGamutIdx);
616 }
617
GetScreenGamutMap(ScreenId screenId,ScreenGamutMap & gamutMap)618 DMError AbstractScreenController::GetScreenGamutMap(ScreenId screenId, ScreenGamutMap& gamutMap)
619 {
620 sptr<AbstractScreen> screen = GetAbstractScreen(screenId);
621 if (screen == nullptr) {
622 return DMError::DM_ERROR_INVALID_PARAM;
623 }
624 return screen->GetScreenGamutMap(gamutMap);
625 }
626
SetScreenGamutMap(ScreenId screenId,ScreenGamutMap gamutMap)627 DMError AbstractScreenController::SetScreenGamutMap(ScreenId screenId, ScreenGamutMap gamutMap)
628 {
629 sptr<AbstractScreen> screen = GetAbstractScreen(screenId);
630 if (screen == nullptr) {
631 return DMError::DM_ERROR_INVALID_PARAM;
632 }
633 return screen->SetScreenGamutMap(gamutMap);
634 }
635
SetScreenColorTransform(ScreenId screenId)636 DMError AbstractScreenController::SetScreenColorTransform(ScreenId screenId)
637 {
638 sptr<AbstractScreen> screen = GetAbstractScreen(screenId);
639 if (screen == nullptr) {
640 return DMError::DM_ERROR_INVALID_PARAM;
641 }
642 return screen->SetScreenColorTransform();
643 }
644
SetScreenActiveMode(ScreenId screenId,uint32_t modeId)645 bool AbstractScreenController::SetScreenActiveMode(ScreenId screenId, uint32_t modeId)
646 {
647 WLOGI("SetScreenActiveMode: RsScreenId: %{public}" PRIu64", modeId: %{public}u", screenId, modeId);
648 if (screenId == SCREEN_ID_INVALID) {
649 WLOGFE("SetScreenActiveMode: invalid screenId");
650 return false;
651 }
652 uint32_t usedModeId = 0;
653 {
654 std::lock_guard<std::recursive_mutex> lock(mutex_);
655 ScreenId rsScreenId = SCREEN_ID_INVALID;
656 if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) {
657 WLOGFE("SetScreenActiveMode: No corresponding rsId");
658 return false;
659 }
660 rsInterface_.SetScreenActiveMode(rsScreenId, modeId);
661 auto screen = GetAbstractScreen(screenId);
662 if (screen == nullptr) {
663 WLOGFE("SetScreenActiveMode: Get AbstractScreen failed");
664 return false;
665 }
666 usedModeId = static_cast<uint32_t>(screen->activeIdx_);
667 screen->activeIdx_ = static_cast<int32_t>(modeId);
668 }
669 // add thread to process mode change sync event
670 if (usedModeId != modeId) {
671 WLOGI("SetScreenActiveMode: modeId: %{public}u -> %{public}u", usedModeId, modeId);
672 auto func = [=]() {
673 ProcessScreenModeChanged(screenId);
674 return;
675 };
676 controllerHandler_->PostTask(func, AppExecFwk::EventQueue::Priority::HIGH);
677 }
678 return true;
679 }
680
ProcessScreenModeChanged(ScreenId dmsScreenId)681 void AbstractScreenController::ProcessScreenModeChanged(ScreenId dmsScreenId)
682 {
683 WM_SCOPED_TRACE("dms:ProcessScreenModeChanged(%" PRIu64")", dmsScreenId);
684 sptr<AbstractScreen> absScreen = nullptr;
685 sptr<AbstractScreenCallback> absScreenCallback = nullptr;
686 {
687 std::lock_guard<std::recursive_mutex> lock(mutex_);
688 auto dmsScreenMapIter = dmsScreenMap_.find(dmsScreenId);
689 if (dmsScreenMapIter == dmsScreenMap_.end()) {
690 WLOGFE("dmsScreenId=%{public}" PRIu64" is not in dmsScreenMap", dmsScreenId);
691 return;
692 }
693 absScreen = GetAbstractScreen(dmsScreenId);
694 if (absScreen == nullptr) {
695 WLOGFE("screen is nullptr. dmsScreenId=%{public}" PRIu64"", dmsScreenId);
696 return;
697 }
698 absScreenCallback = abstractScreenCallback_;
699 }
700
701 if (absScreenCallback != nullptr) {
702 absScreenCallback->onChange_(absScreen, DisplayChangeEvent::DISPLAY_SIZE_CHANGED);
703 }
704 NotifyScreenChanged(absScreen->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE);
705 }
706
MakeMirror(ScreenId screenId,std::vector<ScreenId> screens)707 bool AbstractScreenController::MakeMirror(ScreenId screenId, std::vector<ScreenId> screens)
708 {
709 WLOGI("MakeMirror, screenId:%{public}" PRIu64"", screenId);
710 sptr<AbstractScreen> screen = GetAbstractScreen(screenId);
711 if (screen == nullptr || screen->type_ != ScreenType::REAL) {
712 WLOGFE("screen is nullptr, or screenType is not real.");
713 return false;
714 }
715 WLOGFI("GetAbstractScreenGroup start");
716 auto group = GetAbstractScreenGroup(screen->groupDmsId_);
717 if (group == nullptr) {
718 std::lock_guard<std::recursive_mutex> lock(mutex_);
719 sptr<AbstractScreenGroup> group = AddToGroupLocked(screen);
720 if (group == nullptr) {
721 WLOGFE("group is nullptr");
722 return false;
723 }
724 NotifyScreenGroupChanged(screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP);
725 if (group != nullptr && abstractScreenCallback_ != nullptr) {
726 abstractScreenCallback_->onConnect_(screen);
727 }
728 }
729 WLOGFI("GetAbstractScreenGroup end");
730 Point point;
731 std::vector<Point> startPoints;
732 startPoints.insert(startPoints.begin(), screens.size(), point);
733 bool filterMirroredScreen =
734 group->combination_ == ScreenCombination::SCREEN_MIRROR && group->mirrorScreenId_ == screen->dmsId_;
735 group->mirrorScreenId_ = screen->dmsId_;
736 ChangeScreenGroup(group, screens, startPoints, filterMirroredScreen, ScreenCombination::SCREEN_MIRROR);
737 WLOGFI("MakeMirror success");
738 return true;
739 }
740
ChangeScreenGroup(sptr<AbstractScreenGroup> group,const std::vector<ScreenId> & screens,const std::vector<Point> & startPoints,bool filterScreen,ScreenCombination combination)741 void AbstractScreenController::ChangeScreenGroup(sptr<AbstractScreenGroup> group, const std::vector<ScreenId>& screens,
742 const std::vector<Point>& startPoints, bool filterScreen, ScreenCombination combination)
743 {
744 std::map<ScreenId, bool> removeChildResMap;
745 std::vector<ScreenId> addScreens;
746 std::vector<Point> addChildPos;
747 std::lock_guard<std::recursive_mutex> lock(mutex_);
748 for (uint64_t i = 0; i != screens.size(); i++) {
749 ScreenId screenId = screens[i];
750 WLOGFI("ChangeScreenGroup: screenId: %{public}" PRIu64"", screenId);
751 auto screen = GetAbstractScreen(screenId);
752 if (screen == nullptr) {
753 WLOGFE("screen:%{public}" PRIu64" is nullptr", screenId);
754 continue;
755 }
756 WLOGFI("ChangeScreenGroup: screen->groupDmsId_: %{public}" PRIu64"", screen->groupDmsId_);
757 if (filterScreen && screen->groupDmsId_ == group->dmsId_ && group->HasChild(screen->dmsId_)) {
758 continue;
759 }
760 if (abstractScreenCallback_ != nullptr && CheckScreenInScreenGroup(screen)) {
761 abstractScreenCallback_->onDisconnect_(screen);
762 }
763 auto originGroup = RemoveFromGroupLocked(screen);
764 addChildPos.emplace_back(startPoints[i]);
765 removeChildResMap[screenId] = originGroup != nullptr;
766 addScreens.emplace_back(screenId);
767 }
768 group->combination_ = combination;
769 AddScreenToGroup(group, addScreens, addChildPos, removeChildResMap);
770 }
771
AddScreenToGroup(sptr<AbstractScreenGroup> group,const std::vector<ScreenId> & addScreens,const std::vector<Point> & addChildPos,std::map<ScreenId,bool> & removeChildResMap)772 void AbstractScreenController::AddScreenToGroup(sptr<AbstractScreenGroup> group,
773 const std::vector<ScreenId>& addScreens, const std::vector<Point>& addChildPos,
774 std::map<ScreenId, bool>& removeChildResMap)
775 {
776 std::vector<sptr<ScreenInfo>> addToGroup;
777 std::vector<sptr<ScreenInfo>> removeFromGroup;
778 std::vector<sptr<ScreenInfo>> changeGroup;
779 for (uint64_t i = 0; i != addScreens.size(); i++) {
780 ScreenId screenId = addScreens[i];
781 sptr<AbstractScreen> screen = GetAbstractScreen(screenId);
782 if (screen == nullptr) {
783 continue;
784 }
785 Point expandPoint = addChildPos[i];
786 WLOGFI("screenId: %{public}" PRIu64", Point: %{public}d, %{public}d",
787 screen->dmsId_, expandPoint.posX_, expandPoint.posY_);
788 bool addChildRes = group->AddChild(screen, expandPoint);
789 if (removeChildResMap[screenId] && addChildRes) {
790 changeGroup.emplace_back(screen->ConvertToScreenInfo());
791 WLOGFI("changeGroup");
792 } else if (removeChildResMap[screenId]) {
793 WLOGFI("removeChild");
794 removeFromGroup.emplace_back(screen->ConvertToScreenInfo());
795 } else if (addChildRes) {
796 WLOGFI("AddChild");
797 addToGroup.emplace_back(screen->ConvertToScreenInfo());
798 } else {
799 WLOGFI("default, AddChild failed");
800 }
801 if (group != nullptr && abstractScreenCallback_ != nullptr) {
802 abstractScreenCallback_->onConnect_(screen);
803 }
804 }
805 NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
806 NotifyScreenGroupChanged(changeGroup, ScreenGroupChangeEvent::CHANGE_GROUP);
807 NotifyScreenGroupChanged(addToGroup, ScreenGroupChangeEvent::ADD_TO_GROUP);
808 }
809
MakeExpand(std::vector<ScreenId> screenIds,std::vector<Point> startPoints)810 bool AbstractScreenController::MakeExpand(std::vector<ScreenId> screenIds, std::vector<Point> startPoints)
811 {
812 ScreenId defaultScreenId = GetDefaultAbstractScreenId();
813 WLOGI("MakeExpand, defaultScreenId:%{public}" PRIu64"", defaultScreenId);
814 auto defaultScreen = GetAbstractScreen(defaultScreenId);
815 if (defaultScreen == nullptr) {
816 return false;
817 }
818 auto group = GetAbstractScreenGroup(defaultScreen->groupDmsId_);
819 if (group == nullptr) {
820 return false;
821 }
822 bool filterExpandScreen = group->combination_ == ScreenCombination::SCREEN_EXPAND;
823 ChangeScreenGroup(group, screenIds, startPoints, filterExpandScreen, ScreenCombination::SCREEN_EXPAND);
824 WLOGFI("MakeExpand success");
825 return true;
826 }
827
RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)828 void AbstractScreenController::RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)
829 {
830 if (screens.empty()) {
831 return;
832 }
833 std::vector<sptr<ScreenInfo>> removeFromGroup;
834 for (ScreenId screenId : screens) {
835 auto screen = GetAbstractScreen(screenId);
836 if (screen == nullptr || screen->type_ != ScreenType::VIRTUAL) {
837 continue;
838 }
839 auto originGroup = GetAbstractScreenGroup(screen->groupDmsId_);
840 if (originGroup == nullptr) {
841 continue;
842 }
843 if (!originGroup->HasChild(screenId)) {
844 continue;
845 }
846 removeFromGroup.emplace_back(screen->ConvertToScreenInfo());
847 if (abstractScreenCallback_ != nullptr && CheckScreenInScreenGroup(screen)) {
848 abstractScreenCallback_->onDisconnect_(screen);
849 }
850 RemoveFromGroupLocked(screen);
851 }
852 NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP);
853 }
854
DumpScreenInfo() const855 void AbstractScreenController::DumpScreenInfo() const
856 {
857 std::lock_guard<std::recursive_mutex> lock(mutex_);
858 WLOGI("-------- dump screen info begin---------");
859 WLOGI("-------- the Screen Id Map Info---------");
860 WLOGI(" DmsScreenId RsScreenId");
861 screenIdManager_.DumpScreenIdInfo();
862 WLOGI("-------- the Screen Info ---------");
863 WLOGI(" dmsId rsId groupDmsId "
864 "isGroup type NodeId isMirrored mirrorNodeId");
865 for (auto iter = dmsScreenMap_.begin(); iter != dmsScreenMap_.end(); iter++) {
866 auto screen = iter->second;
867 std::string screenType;
868 if (screen->type_ == ScreenType::UNDEFINE) {
869 screenType = "UNDEFINE";
870 } else if (screen->type_ == ScreenType::REAL) {
871 screenType = "REAL";
872 } else {
873 screenType = "VIRTUAL";
874 }
875 std::string isMirrored = screen->rSDisplayNodeConfig_.isMirrored ? "true" : "false";
876 std::string isGroup = (dmsScreenGroupMap_.find(screen->dmsId_) != dmsScreenGroupMap_.end()) ? "true" : "false";
877 NodeId nodeId = (screen->rsDisplayNode_ == nullptr) ? SCREEN_ID_INVALID : screen->rsDisplayNode_->GetId();
878 WLOGI("%{public}20" PRIu64" %{public}20" PRIu64" %{public}20" PRIu64" %{public}10s %{public}10s %{public}20"
879 PRIu64" %{public}10s %{public}20" PRIu64" ", screen->dmsId_, screen->rsId_, screen->groupDmsId_,
880 isGroup.c_str(), screenType.c_str(), nodeId, isMirrored.c_str(), screen->rSDisplayNodeConfig_.mirrorNodeId);
881 }
882 DumpScreenGroupInfo();
883 }
884
DumpScreenGroupInfo() const885 void AbstractScreenController::DumpScreenGroupInfo() const
886 {
887 WLOGI("-------- the ScreenGroup Info ---------");
888 WLOGI(" isGroup dmsId rsId groupDmsId type "
889 "NodeId isMirrored mirrorNodeId");
890 for (auto iter = dmsScreenGroupMap_.begin(); iter != dmsScreenGroupMap_.end(); iter++) {
891 auto screenGroup = iter->second;
892 std::string isMirrored = "false";
893 std::string isGroup = "true";
894 std::string screenType = "UNDEFINE";
895 NodeId nodeId = (screenGroup->rsDisplayNode_ == nullptr) ? 0 : screenGroup->rsDisplayNode_->GetId();
896 WLOGI("%{public}10s %{public}20" PRIu64" %{public}20" PRIu64" %{public}20" PRIu64" %{public}10s %{public}20"
897 PRIu64" %{public}10s %{public}20" PRIu64" ", isGroup.c_str(), screenGroup->dmsId_, screenGroup->rsId_,
898 screenGroup->groupDmsId_, screenType.c_str(), nodeId,
899 isMirrored.c_str(), screenGroup->rSDisplayNodeConfig_.mirrorNodeId);
900 auto childrenScreen = screenGroup->GetChildren();
901 for (auto screen : childrenScreen) {
902 std::string isGroup =
903 (dmsScreenGroupMap_.find(screen->dmsId_) != dmsScreenGroupMap_.end()) ? "true" : "false";
904 if (screen->type_ == ScreenType::UNDEFINE) {
905 screenType = "UNDEFINE";
906 } else if (screen->type_ == ScreenType::REAL) {
907 screenType = "REAL";
908 } else {
909 screenType = "VIRTUAL";
910 }
911 isMirrored = screen->rSDisplayNodeConfig_.isMirrored ? "true" : "false";
912 nodeId = (screen->rsDisplayNode_ == nullptr) ? 0 : screen->rsDisplayNode_->GetId();
913 WLOGI("%{public}10s %{public}20" PRIu64" %{public}20" PRIu64" %{public}20" PRIu64" %{public}10s %{public}20"
914 PRIu64" %{public}10s %{public}20" PRIu64" ", isGroup.c_str(), screen->dmsId_, screen->rsId_,
915 screen->groupDmsId_, screenType.c_str(), nodeId,
916 isMirrored.c_str(), screen->rSDisplayNodeConfig_.mirrorNodeId);
917 }
918 }
919 }
920
DumpScreenIdInfo() const921 void AbstractScreenController::ScreenIdManager::DumpScreenIdInfo() const
922 {
923 for (auto& pair : dms2RsScreenIdMap_) {
924 WLOGI("%{public}20" PRIu64" %{public}20" PRIu64"", pair.first, pair.second);
925 }
926 };
927
CreateAndGetNewScreenId(ScreenId rsScreenId)928 ScreenId AbstractScreenController::ScreenIdManager::CreateAndGetNewScreenId(ScreenId rsScreenId)
929 {
930 ScreenId dmsScreenId = dmsScreenCount_++;
931 if (dms2RsScreenIdMap_.find(dmsScreenId) != dms2RsScreenIdMap_.end()) {
932 WLOGFW("dmsScreenId: %{public}" PRIu64" exit in dms2RsScreenIdMap_, warning.", dmsScreenId);
933 }
934 dms2RsScreenIdMap_[dmsScreenId] = rsScreenId;
935 if (rsScreenId == SCREEN_ID_INVALID) {
936 return dmsScreenId;
937 }
938 if (rs2DmsScreenIdMap_.find(rsScreenId) != rs2DmsScreenIdMap_.end()) {
939 WLOGFW("rsScreenId: %{public}" PRIu64" exit in rs2DmsScreenIdMap_, warning.", rsScreenId);
940 }
941 rs2DmsScreenIdMap_[rsScreenId] = dmsScreenId;
942 return dmsScreenId;
943 }
944
DeleteScreenId(ScreenId dmsScreenId)945 bool AbstractScreenController::ScreenIdManager::DeleteScreenId(ScreenId dmsScreenId)
946 {
947 auto iter = dms2RsScreenIdMap_.find(dmsScreenId);
948 if (iter == dms2RsScreenIdMap_.end()) {
949 return false;
950 }
951 ScreenId rsScreenId = iter->second;
952 dms2RsScreenIdMap_.erase(dmsScreenId);
953 rs2DmsScreenIdMap_.erase(rsScreenId);
954 return true;
955 }
956
HasDmsScreenId(ScreenId dmsScreenId) const957 bool AbstractScreenController::ScreenIdManager::HasDmsScreenId(ScreenId dmsScreenId) const
958 {
959 return dms2RsScreenIdMap_.find(dmsScreenId) != dms2RsScreenIdMap_.end();
960 }
961
HasRsScreenId(ScreenId dmsScreenId) const962 bool AbstractScreenController::ScreenIdManager::HasRsScreenId(ScreenId dmsScreenId) const
963 {
964 return rs2DmsScreenIdMap_.find(dmsScreenId) != rs2DmsScreenIdMap_.end();
965 }
966
ConvertToRsScreenId(ScreenId dmsScreenId,ScreenId & rsScreenId) const967 bool AbstractScreenController::ScreenIdManager::ConvertToRsScreenId(ScreenId dmsScreenId, ScreenId& rsScreenId) const
968 {
969 auto iter = dms2RsScreenIdMap_.find(dmsScreenId);
970 if (iter == dms2RsScreenIdMap_.end()) {
971 return false;
972 }
973 rsScreenId = iter->second;
974 return true;
975 }
976
ConvertToRsScreenId(ScreenId dmsScreenId) const977 ScreenId AbstractScreenController::ScreenIdManager::ConvertToRsScreenId(ScreenId dmsScreenId) const
978 {
979 ScreenId rsScreenId = SCREEN_ID_INVALID;
980 ConvertToRsScreenId(dmsScreenId, rsScreenId);
981 return rsScreenId;
982 }
983
ConvertToDmsScreenId(ScreenId rsScreenId,ScreenId & dmsScreenId) const984 bool AbstractScreenController::ScreenIdManager::ConvertToDmsScreenId(ScreenId rsScreenId, ScreenId& dmsScreenId) const
985 {
986 auto iter = rs2DmsScreenIdMap_.find(rsScreenId);
987 if (iter == rs2DmsScreenIdMap_.end()) {
988 return false;
989 }
990 dmsScreenId = iter->second;
991 return true;
992 }
993
ConvertToDmsScreenId(ScreenId rsScreenId) const994 ScreenId AbstractScreenController::ScreenIdManager::ConvertToDmsScreenId(ScreenId rsScreenId) const
995 {
996 ScreenId dmsScreenId = SCREEN_ID_INVALID;
997 ConvertToDmsScreenId(dmsScreenId, dmsScreenId);
998 return dmsScreenId;
999 }
1000
NotifyScreenConnected(sptr<ScreenInfo> screenInfo) const1001 void AbstractScreenController::NotifyScreenConnected(sptr<ScreenInfo> screenInfo) const
1002 {
1003 if (screenInfo == nullptr) {
1004 WLOGFE("NotifyScreenConnected error, screenInfo is nullptr.");
1005 return;
1006 }
1007 auto task = [=] {
1008 WLOGFI("NotifyScreenConnected, screenId:%{public}" PRIu64"", screenInfo->GetScreenId());
1009 DisplayManagerAgentController::GetInstance().OnScreenConnect(screenInfo);
1010 };
1011 controllerHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::HIGH);
1012 }
1013
NotifyScreenDisconnected(ScreenId screenId) const1014 void AbstractScreenController::NotifyScreenDisconnected(ScreenId screenId) const
1015 {
1016 auto task = [=] {
1017 WLOGFI("NotifyScreenDisconnected, screenId:%{public}" PRIu64"", screenId);
1018 DisplayManagerAgentController::GetInstance().OnScreenDisconnect(screenId);
1019 };
1020 controllerHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::HIGH);
1021 }
1022
NotifyScreenChanged(sptr<ScreenInfo> screenInfo,ScreenChangeEvent event) const1023 void AbstractScreenController::NotifyScreenChanged(sptr<ScreenInfo> screenInfo, ScreenChangeEvent event) const
1024 {
1025 if (screenInfo == nullptr) {
1026 WLOGFE("NotifyScreenChanged error, screenInfo is nullptr.");
1027 return;
1028 }
1029 auto task = [=] {
1030 WLOGFI("NotifyScreenChanged, screenId:%{public}" PRIu64"", screenInfo->GetScreenId());
1031 DisplayManagerAgentController::GetInstance().OnScreenChange(screenInfo, event);
1032 };
1033 controllerHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::HIGH);
1034 }
1035
NotifyScreenGroupChanged(const sptr<ScreenInfo> & screenInfo,ScreenGroupChangeEvent event) const1036 void AbstractScreenController::NotifyScreenGroupChanged(
1037 const sptr<ScreenInfo>& screenInfo, ScreenGroupChangeEvent event) const
1038 {
1039 if (screenInfo == nullptr) {
1040 WLOGFE("NotifyScreenGroupChanged error, screenInfo is nullptr.");
1041 return;
1042 }
1043 auto task = [=] {
1044 WLOGFI("NotifyScreenGroupChanged, screenId:%{public}" PRIu64"", screenInfo->GetScreenId());
1045 DisplayManagerAgentController::GetInstance().OnScreenGroupChange(screenInfo, event);
1046 };
1047 controllerHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::HIGH);
1048 }
1049
NotifyScreenGroupChanged(const std::vector<sptr<ScreenInfo>> & screenInfo,ScreenGroupChangeEvent event) const1050 void AbstractScreenController::NotifyScreenGroupChanged(
1051 const std::vector<sptr<ScreenInfo>>& screenInfo, ScreenGroupChangeEvent event) const
1052 {
1053 if (screenInfo.empty()) {
1054 return;
1055 }
1056 auto task = [=] {
1057 WLOGFI("NotifyScreenGroupChanged");
1058 DisplayManagerAgentController::GetInstance().OnScreenGroupChange(screenInfo, event);
1059 };
1060 controllerHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::HIGH);
1061 }
1062
SetScreenPowerForAll(ScreenPowerState state,PowerStateChangeReason reason) const1063 bool AbstractScreenController::SetScreenPowerForAll(ScreenPowerState state, PowerStateChangeReason reason) const
1064 {
1065 WLOGFI("state:%{public}u, reason:%{public}u", state, reason);
1066 auto screenIds = GetAllScreenIds();
1067 if (screenIds.empty()) {
1068 WLOGFI("no screen info");
1069 return false;
1070 }
1071
1072 ScreenPowerStatus status;
1073 switch (state) {
1074 case ScreenPowerState::POWER_ON: {
1075 status = ScreenPowerStatus::POWER_STATUS_ON;
1076 break;
1077 }
1078 case ScreenPowerState::POWER_OFF: {
1079 status = ScreenPowerStatus::POWER_STATUS_OFF;
1080 break;
1081 }
1082 default: {
1083 WLOGFW("SetScreenPowerStatus state not support");
1084 return false;
1085 }
1086 }
1087
1088 bool hasSetScreenPower = false;
1089 for (auto screenId : screenIds) {
1090 auto screen = GetAbstractScreen(screenId);
1091 if (screen->type_ != ScreenType::REAL) {
1092 WLOGD("skip virtual screen %{public}" PRIu64"", screen->dmsId_);
1093 continue;
1094 }
1095 RSInterfaces::GetInstance().SetScreenPowerStatus(screen->rsId_, status);
1096 WLOGI("set screen power status. rsscreen %{public}" PRIu64", status %{public}u", screen->rsId_, status);
1097 hasSetScreenPower = true;
1098 }
1099 WLOGFI("SetScreenPowerStatus end");
1100 if (!hasSetScreenPower) {
1101 WLOGFI("no real screen");
1102 return false;
1103 }
1104 return DisplayManagerAgentController::GetInstance().NotifyDisplayPowerEvent(
1105 state == ScreenPowerState::POWER_ON ? DisplayPowerEvent::DISPLAY_ON :
1106 DisplayPowerEvent::DISPLAY_OFF, EventStatus::END);
1107 }
1108
GetScreenPower(ScreenId dmsScreenId) const1109 ScreenPowerState AbstractScreenController::GetScreenPower(ScreenId dmsScreenId) const
1110 {
1111 auto screenIds = GetAllScreenIds();
1112 if (screenIds.empty()) {
1113 WLOGFE("no screen info");
1114 return ScreenPowerState::INVALID_STATE;
1115 }
1116 ScreenId rsId = SCREEN_ID_INVALID;
1117 for (ScreenId screenId : screenIds) {
1118 if (screenId == dmsScreenId) {
1119 rsId = ConvertToRsScreenId(screenId);
1120 break;
1121 }
1122 }
1123 if (rsId == SCREEN_ID_INVALID) {
1124 WLOGFE("cannot find screen %{public}" PRIu64"", dmsScreenId);
1125 return ScreenPowerState::INVALID_STATE;
1126 }
1127 ScreenPowerState state = static_cast<ScreenPowerState>(RSInterfaces::GetInstance().GetScreenPowerStatus(rsId));
1128 WLOGFI("GetScreenPower:%{public}u, rsscreen:%{public}" PRIu64".", state, rsId);
1129 return state;
1130 }
1131 } // namespace OHOS::Rosen