• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "rs_screen_manager.h"
17 #include "pipeline/rs_main_thread.h"
18 
19 namespace OHOS {
20 namespace Rosen {
21 using namespace HiviewDFX;
22 namespace impl {
23 std::once_flag RSScreenManager::createFlag_;
24 sptr<OHOS::Rosen::RSScreenManager> RSScreenManager::instance_ = nullptr;
25 
GetInstance()26 sptr<OHOS::Rosen::RSScreenManager> RSScreenManager::GetInstance() noexcept
27 {
28     std::call_once(createFlag_, []() {
29         instance_ = new RSScreenManager();
30     });
31 
32     return instance_;
33 }
34 
RSScreenManager()35 RSScreenManager::RSScreenManager()
36 {
37 }
38 
~RSScreenManager()39 RSScreenManager::~RSScreenManager() noexcept
40 {
41 }
42 
Init()43 bool RSScreenManager::Init() noexcept
44 {
45     composer_ = HdiBackend::GetInstance();
46     if (composer_ == nullptr) {
47         HiLog::Error(LOG_LABEL, "%{public}s: Failed to get composer.", __func__);
48         return false;
49     }
50 
51     if (composer_->RegScreenHotplug(&RSScreenManager::OnHotPlug, this) == -1) {
52         HiLog::Error(LOG_LABEL, "%{public}s: Failed to register OnHotPlug Func to composer.", __func__);
53         return false;
54     }
55 
56     // call ProcessScreenHotPlugEvents() for primary screen immediately in main thread.
57     ProcessScreenHotPlugEvents();
58 
59     return true;
60 }
61 
OnHotPlug(std::shared_ptr<HdiOutput> & output,bool connected,void * data)62 void RSScreenManager::OnHotPlug(std::shared_ptr<HdiOutput> &output, bool connected, void *data)
63 {
64     if (output == nullptr) {
65         HiLog::Error(LOG_LABEL, "%{public}s: output is nullptr.", __func__);
66         return;
67     }
68 
69     RSScreenManager *screenManager = nullptr;
70     if (data != nullptr) {
71         screenManager = static_cast<RSScreenManager *>(data);
72     } else {
73         screenManager = static_cast<RSScreenManager *>(RSScreenManager::GetInstance().GetRefPtr());
74     }
75 
76     if (screenManager == nullptr) {
77         HiLog::Error(LOG_LABEL, "%{public}s: Failed to find RSScreenManager instance.", __func__);
78         return;
79     }
80 
81     screenManager->OnHotPlugEvent(output, connected);
82 }
83 
OnHotPlugEvent(std::shared_ptr<HdiOutput> & output,bool connected)84 void RSScreenManager::OnHotPlugEvent(std::shared_ptr<HdiOutput> &output, bool connected)
85 {
86     {
87         std::lock_guard<std::mutex> lock(mutex_);
88         pendingHotPlugEvents_.emplace_back(ScreenHotPlugEvent{output, connected});
89     }
90 
91     // This func would be called in main thread first time immediately after calling composer_->RegScreenHotplug,
92     // but at this time the RSMainThread object would not be ready to handle this, so we need to call
93     // ProcessScreenHotPlugEvents() after this func in RSScreenManager::Init().
94 
95     // Normally, this func would be called in hdi's hw-ipc threads(but sometimes in main thread, maybe),
96     // so we should notify the RSMainThread to postTask to call ProcessScreenHotPlugEvents().
97     auto mainThread = RSMainThread::Instance();
98     if (mainThread == nullptr) {
99         return;
100     }
101     mainThread->RequestNextVSync();
102 }
103 
ProcessScreenHotPlugEvents()104 void RSScreenManager::ProcessScreenHotPlugEvents()
105 {
106     std::lock_guard<std::mutex> lock(mutex_);
107     for (auto &event : pendingHotPlugEvents_) {
108         if (event.connected) {
109             ProcessScreenConnectedLocked(event.output);
110         } else {
111             ProcessScreenDisConnectedLocked(event.output);
112         }
113     }
114 
115     pendingHotPlugEvents_.clear();
116 }
117 
ProcessScreenConnectedLocked(std::shared_ptr<HdiOutput> & output)118 void RSScreenManager::ProcessScreenConnectedLocked(std::shared_ptr<HdiOutput> &output)
119 {
120     if (output == nullptr) {
121         HiLog::Error(LOG_LABEL, "%{public}s: output is nullptr.", __func__);
122         return;
123     }
124 
125     bool isVirtual = false;
126     ScreenId id = ToScreenId(output->GetScreenId());
127     if (defaultScreenId_ == INVALID_SCREEN_ID) {
128         defaultScreenId_ = id;
129     }
130 
131     if (screens_.count(id) == 1) {
132         HiLog::Warn(LOG_LABEL, "%{public}s: The screen for id %{public}" PRIu64 " already existed.", __func__, id);
133 
134         // [PLANNING]: should we erase it and create a new one?
135         for (auto &cb : screenChangeCallbacks_) {
136             cb->OnScreenChanged(id, ScreenEvent::DISCONNECTED);
137         }
138         screens_.erase(id);
139     }
140 
141     screens_[id] = std::make_unique<RSScreen>(id, isVirtual, output, nullptr);
142     HiLog::Info(LOG_LABEL, "%{public}s: A new screen(id %{public}" PRIu64 ") connected.", __func__, id);
143     for (auto &cb : screenChangeCallbacks_) {
144         cb->OnScreenChanged(id, ScreenEvent::CONNECTED);
145     }
146 }
147 
ProcessScreenDisConnectedLocked(std::shared_ptr<HdiOutput> & output)148 void RSScreenManager::ProcessScreenDisConnectedLocked(std::shared_ptr<HdiOutput> &output)
149 {
150     ScreenId id = ToScreenId(output->GetScreenId());
151 
152     if (screens_.count(id) == 0) {
153         HiLog::Warn(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
154     } else {
155         for (auto &cb : screenChangeCallbacks_) {
156             cb->OnScreenChanged(id, ScreenEvent::DISCONNECTED);
157         }
158         screens_.erase(id);
159         HiLog::Info(LOG_LABEL, "%{public}s: Screen(id %{public}" PRIu64 ") disconnected.", __func__, id);
160     }
161 
162     if (id == defaultScreenId_) {
163         HandleDefaultScreenDisConnectedLocked();
164     }
165 }
166 
167 // If the previous primary screen disconnected, we traversal the left screens
168 // and find the first physical screen to be the default screen.
169 // If there was no physical screen left, we set the first screen as default, no matter what type it is.
170 // At last, if no screen left, we set Default Screen Id to INVALID_SCREEN_ID.
HandleDefaultScreenDisConnectedLocked()171 void RSScreenManager::HandleDefaultScreenDisConnectedLocked()
172 {
173     defaultScreenId_ = INVALID_SCREEN_ID;
174     for (const auto &[id, screen] : screens_) {
175         if (!screen->IsVirtual()) {
176             defaultScreenId_ = id;
177             break;
178         }
179     }
180 
181     if (defaultScreenId_ == INVALID_SCREEN_ID) {
182         if (!screens_.empty()) {
183             defaultScreenId_ = screens_.cbegin()->first;
184         }
185     }
186 }
187 
SetDefaultScreenId(ScreenId id)188 void RSScreenManager::SetDefaultScreenId(ScreenId id)
189 {
190     std::lock_guard<std::mutex> lock(mutex_);
191     defaultScreenId_ = id;
192 }
193 
SetScreenMirror(ScreenId id,ScreenId toMirror)194 void RSScreenManager::SetScreenMirror(ScreenId id, ScreenId toMirror)
195 {
196     std::lock_guard<std::mutex> lock(mutex_);
197 
198     if (screens_.count(id) == 0) {
199         HiLog::Warn(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
200         return;
201     }
202 
203     screens_[id]->SetMirror(toMirror);
204 }
205 
GenerateVirtualScreenIdLocked()206 ScreenId RSScreenManager::GenerateVirtualScreenIdLocked()
207 {
208     if (!freeVirtualScreenIds_.empty()) {
209         ScreenId id = freeVirtualScreenIds_.front();
210         freeVirtualScreenIds_.pop();
211         return id;
212     }
213 
214     // The left 32 bits is for virtual screen id.
215     return (static_cast<ScreenId>(maxVirtualScreenNum_++) << 32) | 0xffffffffu;
216 }
217 
ReuseVirtualScreenIdLocked(ScreenId id)218 void RSScreenManager::ReuseVirtualScreenIdLocked(ScreenId id)
219 {
220     freeVirtualScreenIds_.push(id);
221 }
222 
GetScreenActiveModeLocked(ScreenId id,RSScreenModeInfo & screenModeInfo) const223 void RSScreenManager::GetScreenActiveModeLocked(ScreenId id, RSScreenModeInfo& screenModeInfo) const
224 {
225     if (screens_.count(id) == 0) {
226         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
227         return;
228     }
229 
230     auto modeInfo = screens_.at(id)->GetActiveMode();
231     if (!modeInfo) {
232         HiLog::Error(LOG_LABEL, "%{public}s: Failed to get active mode for screen %{public}" PRIu64 ".", __func__, id);
233         return;
234     }
235 
236     screenModeInfo.SetScreenWidth(modeInfo->width);
237     screenModeInfo.SetScreenHeight(modeInfo->height);
238     screenModeInfo.SetScreenRefreshRate(modeInfo->freshRate);
239     screenModeInfo.SetScreenModeId(screens_.at(id)->GetActiveModePosByModeId(modeInfo->id));
240 }
241 
GetScreenSupportedModesLocked(ScreenId id) const242 std::vector<RSScreenModeInfo> RSScreenManager::GetScreenSupportedModesLocked(ScreenId id) const
243 {
244     std::vector<RSScreenModeInfo> screenSupportedModes;
245     if (screens_.count(id) == 0) {
246         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
247         return screenSupportedModes;
248     }
249 
250     const auto& displaySupportedModes = screens_.at(id)->GetSupportedModes();
251     screenSupportedModes.resize(displaySupportedModes.size());
252     for (decltype(displaySupportedModes.size()) idx = 0; idx < displaySupportedModes.size(); ++idx) {
253         screenSupportedModes[idx].SetScreenWidth(displaySupportedModes[idx].width);
254         screenSupportedModes[idx].SetScreenHeight(displaySupportedModes[idx].height);
255         screenSupportedModes[idx].SetScreenRefreshRate(displaySupportedModes[idx].freshRate);
256         screenSupportedModes[idx].SetScreenModeId(displaySupportedModes[idx].id);
257     }
258     return screenSupportedModes;
259 }
260 
GetScreenCapabilityLocked(ScreenId id) const261 RSScreenCapability RSScreenManager::GetScreenCapabilityLocked(ScreenId id) const
262 {
263     RSScreenCapability screenCapability;
264     if (screens_.count(id) == 0) {
265         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
266         return screenCapability;
267     }
268     if (screens_.at(id)->IsVirtual()) {
269         HiLog::Warn(LOG_LABEL, "%{public}s: only name attribute is valid for virtual screen.\n", __func__);
270         screenCapability.SetName(screens_.at(id)->Name());
271         return screenCapability;
272     }
273 
274     const auto& capability = screens_.at(id)->GetCapability();
275     std::vector<RSScreenProps> props;
276     uint32_t propCount = capability.propertyCount;
277     props.resize(propCount);
278     for (uint32_t propIndex = 0; propIndex < propCount; propIndex++) {
279         props[propIndex] = RSScreenProps(capability.props[propIndex].name, capability.props[propIndex].propId,
280             capability.props[propIndex].value);
281     }
282     screenCapability.SetName(capability.name);
283     screenCapability.SetType(static_cast<ScreenInterfaceType>(capability.type));
284     screenCapability.SetPhyWidth(capability.phyWidth);
285     screenCapability.SetPhyHeight(capability.phyHeight);
286     screenCapability.SetSupportLayers(capability.supportLayers);
287     screenCapability.SetVirtualDispCount(capability.virtualDispCount);
288     screenCapability.SetSupportWriteback(capability.supportWriteBack);
289     screenCapability.SetProps(props);
290     return screenCapability;
291 }
292 
GetScreenPowerStatuslocked(ScreenId id) const293 ScreenPowerStatus RSScreenManager::GetScreenPowerStatuslocked(ScreenId id) const
294 {
295     if (screens_.count(id) == 0) {
296         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
297         return INVALID_POWER_STATUS;
298     }
299 
300     ScreenPowerStatus status = static_cast<ScreenPowerStatus>(screens_.at(id)->GetPowerStatus());
301     return status;
302 }
303 
CreateVirtualScreen(const std::string & name,uint32_t width,uint32_t height,sptr<Surface> surface,ScreenId mirrorId,int32_t flags)304 ScreenId RSScreenManager::CreateVirtualScreen(
305     const std::string &name,
306     uint32_t width,
307     uint32_t height,
308     sptr<Surface> surface,
309     ScreenId mirrorId,
310     int32_t flags
311     )
312 {
313     std::lock_guard<std::mutex> lock(mutex_);
314 
315     if (surface != nullptr) {
316         uint64_t surfaceId = surface->GetUniqueId();
317         for (auto &[_, screen] : screens_) {
318             if (!screen->IsVirtual()) {
319                 continue;
320             }
321             auto screenSurface = screen->GetProducerSurface();
322             if (screenSurface == nullptr) {
323                 continue;
324             }
325             if (screenSurface->GetUniqueId() == surfaceId) {
326                 HiLog::Error(LOG_LABEL, "surface %{public}" PRIu64 " is used, create virtualscreen failed!", surfaceId);
327                 return INVALID_SCREEN_ID;
328             }
329         }
330     } else {
331         HiLog::Debug(LOG_LABEL, "%{public}s: surface is nullptr.\n", __func__);
332     }
333 
334     VirtualScreenConfigs configs;
335     ScreenId newId = GenerateVirtualScreenIdLocked();
336     configs.id = newId;
337     configs.mirrorId = mirrorId;
338     configs.name = name;
339     configs.width = width;
340     configs.height = height;
341     configs.surface = surface;
342     configs.flags = flags;
343 
344     screens_[newId] = std::make_unique<RSScreen>(configs);
345     HiLog::Debug(LOG_LABEL, "%{public}s: create virtual screen(id %{public}" PRIu64 ").\n", __func__, newId);
346     return newId;
347 }
348 
SetVirtualScreenSurface(ScreenId id,sptr<Surface> surface)349 int32_t RSScreenManager::SetVirtualScreenSurface(ScreenId id, sptr<Surface> surface)
350 {
351     uint64_t surfaceId = surface->GetUniqueId();
352     for (auto &[screenId, screen] : screens_) {
353         if (!screen->IsVirtual() || screenId == id) {
354             continue;
355         }
356         auto screenSurface = screen->GetProducerSurface();
357         if (screenSurface == nullptr) {
358             continue;
359         }
360         if (screenSurface->GetUniqueId() == surface->GetUniqueId()) {
361             HiLog::Error(LOG_LABEL, "surface %{public}" PRIu64 " is used, set surface failed!", surfaceId);
362             return SURFACE_NOT_UNIQUE;
363         }
364     }
365     screens_.at(id)->SetProducerSurface(surface);
366     HiLog::Debug(LOG_LABEL, "%{public}s:  set virtual screen surface success! \n", __func__);
367     return SUCCESS;
368 }
369 
RemoveVirtualScreen(ScreenId id)370 void RSScreenManager::RemoveVirtualScreen(ScreenId id)
371 {
372     std::lock_guard<std::mutex> lock(mutex_);
373 
374     RemoveVirtualScreenLocked(id);
375 }
376 
RemoveVirtualScreenLocked(ScreenId id)377 void RSScreenManager::RemoveVirtualScreenLocked(ScreenId id)
378 {
379     if (screens_.count(id) == 0) {
380         HiLog::Warn(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
381         return;
382     }
383 
384     screens_.erase(id);
385 
386     // Update other screens' mirrorId.
387     for (auto &[id, screen] : screens_) {
388         if (screen->MirrorId() == id) {
389             screen->SetMirror(INVALID_SCREEN_ID);
390         }
391     }
392     HiLog::Debug(LOG_LABEL, "%{public}s: remove virtual screen(id %{public}" PRIu64 ").\n", __func__, id);
393 
394     ReuseVirtualScreenIdLocked(id);
395 }
396 
SetScreenActiveMode(ScreenId id,uint32_t modeId)397 void RSScreenManager::SetScreenActiveMode(ScreenId id, uint32_t modeId)
398 {
399     std::lock_guard<std::mutex> lock(mutex_);
400 
401     if (screens_.count(id) == 0) {
402         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
403         return;
404     }
405     screens_.at(id)->SetActiveMode(modeId);
406 }
407 
SetScreenPowerStatus(ScreenId id,ScreenPowerStatus status)408 void RSScreenManager::SetScreenPowerStatus(ScreenId id, ScreenPowerStatus status)
409 {
410     std::lock_guard<std::mutex> lock(mutex_);
411 
412     if (screens_.count(id) == 0) {
413         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
414         return;
415     }
416     screens_.at(id)->SetPowerStatus(static_cast<uint32_t>(status));
417 
418     /*
419      * If app adds the first frame when power on the screen, delete the code
420      */
421     if (status == ScreenPowerStatus::POWER_STATUS_ON) {
422         auto mainThread = RSMainThread::Instance();
423         if (mainThread == nullptr) {
424             return;
425         }
426         mainThread->RequestNextVSync();
427         HiLog::Info(LOG_LABEL, "Set system power on, request a frame");
428     }
429 }
430 
GetScreenActiveMode(ScreenId id,RSScreenModeInfo & screenModeInfo) const431 void RSScreenManager::GetScreenActiveMode(ScreenId id, RSScreenModeInfo& screenModeInfo) const
432 {
433     std::lock_guard<std::mutex> lock(mutex_);
434 
435     GetScreenActiveModeLocked(id, screenModeInfo);
436 }
437 
GetScreenSupportedModes(ScreenId id) const438 std::vector<RSScreenModeInfo> RSScreenManager::GetScreenSupportedModes(ScreenId id) const
439 {
440     std::lock_guard<std::mutex> lock(mutex_);
441 
442     return GetScreenSupportedModesLocked(id);
443 }
444 
GetScreenCapability(ScreenId id) const445 RSScreenCapability RSScreenManager::GetScreenCapability(ScreenId id) const
446 {
447     std::lock_guard<std::mutex> lock(mutex_);
448 
449     return GetScreenCapabilityLocked(id);
450 }
451 
GetScreenPowerStatus(ScreenId id) const452 ScreenPowerStatus RSScreenManager::GetScreenPowerStatus(ScreenId id) const
453 {
454     std::lock_guard<std::mutex> lock(mutex_);
455 
456     return GetScreenPowerStatuslocked(id);
457 }
458 
GetScreenData(ScreenId id) const459 RSScreenData RSScreenManager::GetScreenData(ScreenId id) const
460 {
461     std::lock_guard<std::mutex> lock(mutex_);
462     RSScreenData screenData;
463     if (screens_.count(id) == 0) {
464         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
465         return screenData;
466     }
467     RSScreenCapability capability = GetScreenCapabilityLocked(id);
468     RSScreenModeInfo activeMode;
469     GetScreenActiveModeLocked(id, activeMode);
470     std::vector<RSScreenModeInfo> supportModes = GetScreenSupportedModesLocked(id);
471     ScreenPowerStatus powerStatus = GetScreenPowerStatuslocked(id);
472     screenData.SetCapability(capability);
473     screenData.SetActivityModeInfo(activeMode);
474     screenData.SetSupportModeInfo(supportModes);
475     screenData.SetPowerStatus(powerStatus);
476     return screenData;
477 }
478 
GetScreenBacklight(ScreenId id)479 int32_t RSScreenManager::GetScreenBacklight(ScreenId id)
480 {
481     std::lock_guard<std::mutex> lock(mutex_);
482     return GetScreenBacklightlocked(id);
483 }
484 
GetScreenBacklightlocked(ScreenId id) const485 int32_t RSScreenManager::GetScreenBacklightlocked(ScreenId id) const
486 {
487     if (screens_.count(id) == 0) {
488         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
489         return INVALID_BACKLIGHT_VALUE;
490     }
491 
492     int32_t level = screens_.at(id)->GetScreenBacklight();
493     return level;
494 }
495 
SetScreenBacklight(ScreenId id,uint32_t level)496 void RSScreenManager::SetScreenBacklight(ScreenId id, uint32_t level)
497 {
498     std::lock_guard<std::mutex> lock(mutex_);
499     if (screens_.count(id) == 0) {
500         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
501         return;
502     }
503     screens_.at(id)->SetScreenBacklight(level);
504 }
505 
QueryScreenInfo(ScreenId id) const506 ScreenInfo RSScreenManager::QueryScreenInfo(ScreenId id) const
507 {
508     std::lock_guard<std::mutex> lock(mutex_);
509 
510     ScreenInfo info;
511     if (screens_.count(id) == 0) {
512         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
513         return info;
514     }
515 
516     const auto &screen = screens_.at(id);
517 
518     info.width = screen->Width();
519     info.height = screen->Height();
520     (void)screen->GetScreenColorGamut(info.colorGamut);
521 
522     if (!screen->IsEnable()) {
523         info.state = ScreenState::DISABLED;
524     } else if (!screen->IsVirtual()) {
525         info.state = ScreenState::HDI_OUTPUT_ENABLE;
526     } else {
527         info.state = ScreenState::PRODUCER_SURFACE_ENABLE;
528     }
529     info.rotationMatrix = screen->GetRotationMatrix();
530 
531     return info;
532 }
533 
GetProducerSurface(ScreenId id) const534 sptr<Surface> RSScreenManager::GetProducerSurface(ScreenId id) const
535 {
536     std::lock_guard<std::mutex> lock(mutex_);
537 
538     // assert screens_.count(id) == 1
539     return screens_.at(id)->GetProducerSurface();
540 }
541 
GetOutput(ScreenId id) const542 std::shared_ptr<HdiOutput> RSScreenManager::GetOutput(ScreenId id) const
543 {
544     std::lock_guard<std::mutex> lock(mutex_);
545 
546     // assert screens_.count(id) == 1
547     return screens_.at(id)->GetOutput();
548 }
549 
AddScreenChangeCallback(const sptr<RSIScreenChangeCallback> & callback)550 int32_t RSScreenManager::AddScreenChangeCallback(const sptr<RSIScreenChangeCallback> &callback)
551 {
552     if (callback == nullptr) {
553         HiLog::Error(LOG_LABEL, "%{public}s: callback is NULL.", __func__);
554         return INVALID_ARGUMENTS;
555     }
556 
557     std::lock_guard<std::mutex> lock(mutex_);
558     // when the callback first registered, maybe there were some physical screens already connected,
559     // so notify to remote immediately.
560     for (const auto &[id, screen] : screens_) {
561         if (!screen->IsVirtual()) {
562             callback->OnScreenChanged(id, ScreenEvent::CONNECTED);
563         }
564     }
565     screenChangeCallbacks_.push_back(callback);
566     HiLog::Debug(LOG_LABEL, "%{public}s: add a remote callback succeed.", __func__);
567     return SUCCESS;
568 }
569 
RemoveScreenChangeCallback(const sptr<RSIScreenChangeCallback> & callback)570 void RSScreenManager::RemoveScreenChangeCallback(const sptr<RSIScreenChangeCallback> &callback)
571 {
572     std::lock_guard<std::mutex> lock(mutex_);
573     for (auto it = screenChangeCallbacks_.begin(); it != screenChangeCallbacks_.end(); it++) {
574         if (*it == callback) {
575             screenChangeCallbacks_.erase(it);
576             HiLog::Debug(LOG_LABEL, "%{public}s: remove a remote callback succeed.", __func__);
577             break;
578         }
579     }
580 }
581 
DisplayDump(std::string & dumpString)582 void RSScreenManager::DisplayDump(std::string& dumpString)
583 {
584     int32_t index = 0;
585     for (const auto &[id, screen] : screens_) {
586         screen->DisplayDump(index, dumpString);
587         index++;
588     }
589 }
590 
SurfaceDump(std::string & dumpString)591 void RSScreenManager::SurfaceDump(std::string& dumpString)
592 {
593     int32_t index = 0;
594     for (const auto &[id, screen] : screens_) {
595         screen->SurfaceDump(index, dumpString);
596         index++;
597     }
598 }
599 
FpsDump(std::string & dumpString,std::string & arg)600 void RSScreenManager::FpsDump(std::string& dumpString, std::string& arg)
601 {
602     int32_t index = 0;
603     for (const auto &[id, screen] : screens_) {
604         screen->FpsDump(index, dumpString, arg);
605         index++;
606     }
607 }
608 
GetScreenSupportedColorGamutsLocked(ScreenId id,std::vector<ScreenColorGamut> & mode) const609 int32_t RSScreenManager::GetScreenSupportedColorGamutsLocked(ScreenId id, std::vector<ScreenColorGamut>& mode) const
610 {
611     if (screens_.count(id) == 0) {
612         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
613         return StatusCode::SCREEN_NOT_FOUND;
614     }
615     return screens_.at(id)->GetScreenSupportedColorGamuts(mode);
616 }
617 
GetScreenColorGamutLocked(ScreenId id,ScreenColorGamut & mode) const618 int32_t RSScreenManager::GetScreenColorGamutLocked(ScreenId id, ScreenColorGamut& mode) const
619 {
620     if (screens_.count(id) == 0) {
621         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
622         return StatusCode::SCREEN_NOT_FOUND;
623     }
624     return screens_.at(id)->GetScreenColorGamut(mode);
625 }
626 
SetScreenColorGamutLocked(ScreenId id,int32_t modeIdx)627 int32_t RSScreenManager::SetScreenColorGamutLocked(ScreenId id, int32_t modeIdx)
628 {
629     if (screens_.count(id) == 0) {
630         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
631         return StatusCode::SCREEN_NOT_FOUND;
632     }
633     return screens_.at(id)->SetScreenColorGamut(modeIdx);
634 }
635 
SetScreenGamutMapLocked(ScreenId id,ScreenGamutMap mode)636 int32_t RSScreenManager::SetScreenGamutMapLocked(ScreenId id, ScreenGamutMap mode)
637 {
638     if (screens_.count(id) == 0) {
639         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
640         return StatusCode::SCREEN_NOT_FOUND;
641     }
642     return screens_.at(id)->SetScreenGamutMap(mode);
643 }
644 
GetScreenGamutMapLocked(ScreenId id,ScreenGamutMap & mode) const645 int32_t RSScreenManager::GetScreenGamutMapLocked(ScreenId id, ScreenGamutMap &mode) const
646 {
647     if (screens_.count(id) == 0) {
648         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
649         return StatusCode::SCREEN_NOT_FOUND;
650     }
651     return screens_.at(id)->GetScreenGamutMap(mode);
652 }
653 
RequestRotationLocked(ScreenId id,ScreenRotation rotation)654 bool RSScreenManager::RequestRotationLocked(ScreenId id, ScreenRotation rotation)
655 {
656     auto iter = screens_.find(id);
657     if (iter == screens_.end()) {
658         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
659         return false;
660     }
661     return iter->second->SetRotation(rotation);
662 }
663 
GetRotationLocked(ScreenId id) const664 ScreenRotation RSScreenManager::GetRotationLocked(ScreenId id) const
665 {
666     auto iter = screens_.find(id);
667     if (iter == screens_.end()) {
668         HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
669         return ScreenRotation::INVALID_SCREEN_ROTATION;
670     }
671     return iter->second->GetRotation();
672 }
673 
GetScreenSupportedColorGamuts(ScreenId id,std::vector<ScreenColorGamut> & mode) const674 int32_t RSScreenManager::GetScreenSupportedColorGamuts(ScreenId id, std::vector<ScreenColorGamut>& mode) const
675 {
676     std::lock_guard<std::mutex> lock(mutex_);
677     return GetScreenSupportedColorGamutsLocked(id, mode);
678 }
679 
GetScreenColorGamut(ScreenId id,ScreenColorGamut & mode) const680 int32_t RSScreenManager::GetScreenColorGamut(ScreenId id, ScreenColorGamut &mode) const
681 {
682     std::lock_guard<std::mutex> lock(mutex_);
683     return GetScreenColorGamutLocked(id, mode);
684 }
685 
SetScreenColorGamut(ScreenId id,int32_t modeIdx)686 int32_t RSScreenManager::SetScreenColorGamut(ScreenId id, int32_t modeIdx)
687 {
688     std::lock_guard<std::mutex> lock(mutex_);
689     return SetScreenColorGamutLocked(id, modeIdx);
690 }
691 
SetScreenGamutMap(ScreenId id,ScreenGamutMap mode)692 int32_t RSScreenManager::SetScreenGamutMap(ScreenId id, ScreenGamutMap mode)
693 {
694     std::lock_guard<std::mutex> lock(mutex_);
695     return SetScreenGamutMapLocked(id, mode);
696 }
697 
GetScreenGamutMap(ScreenId id,ScreenGamutMap & mode) const698 int32_t RSScreenManager::GetScreenGamutMap(ScreenId id, ScreenGamutMap &mode) const
699 {
700     std::lock_guard<std::mutex> lock(mutex_);
701     return GetScreenGamutMapLocked(id, mode);
702 }
703 
RequestRotation(ScreenId id,ScreenRotation rotation)704 bool RSScreenManager::RequestRotation(ScreenId id, ScreenRotation rotation)
705 {
706     std::lock_guard<std::mutex> lock(mutex_);
707     return RequestRotationLocked(id, rotation);
708 }
709 
GetRotation(ScreenId id) const710 ScreenRotation RSScreenManager::GetRotation(ScreenId id) const
711 {
712     std::lock_guard<std::mutex> lock(mutex_);
713     return GetRotationLocked(id);
714 }
715 } // namespace impl
716 
CreateOrGetScreenManager()717 sptr<RSScreenManager> CreateOrGetScreenManager()
718 {
719     return impl::RSScreenManager::GetInstance();
720 }
721 } // namespace Rosen
722 } // namespace OHOS
723