• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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