• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "rs_screen_manager.h"
17 
18 #include <parameter.h>
19 #include <parameters.h>
20 #include "param/sys_param.h"
21 
22 #include "common/rs_optional_trace.h"
23 #include "common/rs_switching_thread.h"
24 #include "display_engine/rs_color_temperature.h"
25 #include "gfx/first_frame_notifier/rs_first_frame_notifier.h"
26 #include "graphic_feature_param_manager.h"
27 #include "hgm_core.h"
28 #include "pipeline/hardware_thread/rs_hardware_thread.h"
29 #include "pipeline/main_thread/rs_main_thread.h"
30 #include "pipeline/rs_screen_render_node.h"
31 #include "platform/common/rs_log.h"
32 #include "platform/common/rs_system_properties.h"
33 #include "rs_screen.h"
34 #include "rs_trace.h"
35 #include "screen_manager/rs_screen_node_listener.h"
36 #include "vsync_sampler.h"
37 
38 #undef LOG_TAG
39 #define LOG_TAG "RSScreenManager"
40 
41 namespace OHOS {
42 namespace Rosen {
43 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
44 namespace {
45 constexpr float ANGLE_MIN_VAL = 0.0F;
46 constexpr float ANGLE_MAX_VAL = 180.0F;
47 constexpr int32_t SENSOR_SUCCESS = 0;
48 constexpr int32_t POSTURE_INTERVAL = 4000000;
49 constexpr uint16_t SENSOR_EVENT_FIRST_DATA = 0;
50 constexpr float HALF_FOLDED_MAX_THRESHOLD = 140.0F;
51 constexpr float OPEN_HALF_FOLDED_MIN_THRESHOLD = 25.0F;
52 constexpr uint32_t WAIT_FOR_ACTIVE_SCREEN_ID_TIMEOUT = 1000;
53 constexpr uint32_t WAIT_FOR_STATUS_TASK_TIMEOUT = 1000; // 1000ms
54 constexpr uint32_t MAX_VIRTUAL_SCREEN_NUM = 64;
55 constexpr uint32_t MAX_VIRTUAL_SCREEN_WIDTH = 65536;
56 constexpr uint32_t MAX_VIRTUAL_SCREEN_HEIGHT = 65536;
57 constexpr uint32_t MAX_VIRTUAL_SCREEN_REFRESH_RATE = 120;
58 constexpr uint32_t ORIGINAL_FOLD_SCREEN_AMOUNT = 2;
59 constexpr uint32_t MAX_BLACK_LIST_NUM = 1024;
60 const std::string FORCE_REFRESH_ONE_FRAME_TASK_NAME = "ForceRefreshOneFrameIfNoRNV";
SensorPostureDataCallback(SensorEvent * event)61 void SensorPostureDataCallback(SensorEvent* event)
62 {
63     CreateOrGetScreenManager()->HandlePostureData(event);
64 }
65 } // namespace
66 #endif
67 using namespace HiviewDFX;
68 namespace impl {
69 std::once_flag RSScreenManager::createFlag_;
70 sptr<OHOS::Rosen::RSScreenManager> RSScreenManager::instance_ = nullptr;
71 
GetInstance()72 sptr<OHOS::Rosen::RSScreenManager> RSScreenManager::GetInstance() noexcept
73 {
74     std::call_once(createFlag_, []() {
75         instance_ = new RSScreenManager();
76     });
77 
78     return instance_;
79 }
80 
Init()81 bool RSScreenManager::Init() noexcept
82 {
83     composer_ = HdiBackend::GetInstance();
84 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
85     isFoldScreenFlag_ = system::GetParameter("const.window.foldscreen.type", "") != "";
86 #endif
87     if (composer_ == nullptr) {
88         RS_LOGE("%{public}s: Failed to get composer.", __func__);
89         return false;
90     }
91 
92     if (composer_->RegScreenHotplug(&RSScreenManager::OnHotPlug, this) != 0) {
93         RS_LOGE("%{public}s: Failed to register OnHotPlug Func to composer.", __func__);
94         return false;
95     }
96 
97     if (composer_->RegScreenRefresh(&RSScreenManager::OnRefresh, this) != 0) {
98         RS_LOGE("%{public}s: Failed to register OnRefresh Func to composer.", __func__);
99     }
100 
101     if (composer_->RegHwcDeadListener(&RSScreenManager::OnHwcDead, this) != 0) {
102         RS_LOGE("%{public}s: Failed to register OnHwcDead Func to composer.", __func__);
103         return false;
104     }
105 
106     if (composer_->RegScreenVBlankIdleCallback(&RSScreenManager::OnScreenVBlankIdle, this) != 0) {
107         RS_LOGW("%{public}s: Not support register OnScreenVBlankIdle Func to composer.", __func__);
108     }
109 
110     // call ProcessScreenHotPlugEvents() for primary screen immediately in main thread.
111     ProcessScreenHotPlugEvents();
112 
113 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
114     if (isFoldScreenFlag_) {
115         RS_LOGI("%{public}s: FoldScreen need to RegisterSensorCallback.", __func__);
116         RegisterSensorCallback();
117     }
118 #endif
119     RS_LOGI("Init succeed");
120     return true;
121 }
122 
123 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
RegisterSensorCallback()124 void RSScreenManager::RegisterSensorCallback()
125 {
126     user.callback = SensorPostureDataCallback;
127     int32_t subscribeRet;
128     int32_t setBatchRet;
129     int32_t activateRet;
130     int tryCnt = 0;
131     constexpr int tryLimit = 5; // 5 times failure limit
132     do {
133         subscribeRet = SubscribeSensor(SENSOR_TYPE_ID_POSTURE, &user);
134         RS_LOGI("%{public}s: subscribeRet: %{public}d", __func__, subscribeRet);
135         setBatchRet = SetBatch(SENSOR_TYPE_ID_POSTURE, &user, POSTURE_INTERVAL, POSTURE_INTERVAL);
136         RS_LOGI("%{public}s: setBatchRet: %{public}d", __func__, setBatchRet);
137         activateRet = ActivateSensor(SENSOR_TYPE_ID_POSTURE, &user);
138         RS_LOGI("%{public}s: activateRet: %{public}d", __func__, activateRet);
139         if (subscribeRet != SENSOR_SUCCESS || setBatchRet != SENSOR_SUCCESS || activateRet != SENSOR_SUCCESS) {
140             RS_LOGE("%{public}s failed.", __func__);
141             usleep(1000); // wait 1000 us for next try
142             tryCnt++;
143         }
144     } while (tryCnt <= tryLimit && (subscribeRet != SENSOR_SUCCESS || setBatchRet != SENSOR_SUCCESS ||
145         activateRet != SENSOR_SUCCESS));
146     if (tryCnt <= tryLimit) {
147         RS_LOGI("%{public}s success.", __func__);
148     }
149 }
150 
UnRegisterSensorCallback()151 void RSScreenManager::UnRegisterSensorCallback()
152 {
153     int32_t deactivateRet = DeactivateSensor(SENSOR_TYPE_ID_POSTURE, &user);
154     int32_t unsubscribeRet = UnsubscribeSensor(SENSOR_TYPE_ID_POSTURE, &user);
155     if (deactivateRet == SENSOR_SUCCESS && unsubscribeRet == SENSOR_SUCCESS) {
156         RS_LOGI("%{public}s success.", __func__);
157     }
158 }
159 
HandlePostureData(const SensorEvent * const event)160 void RSScreenManager::HandlePostureData(const SensorEvent* const event)
161 {
162     if (event == nullptr) {
163         RS_LOGW("SensorEvent is nullptr.");
164         return;
165     }
166     if (event[SENSOR_EVENT_FIRST_DATA].data == nullptr) {
167         RS_LOGW("SensorEvent[0].data is nullptr.");
168         return;
169     }
170     if (event[SENSOR_EVENT_FIRST_DATA].dataLen < sizeof(PostureData)) {
171         RS_LOGW("SensorEvent dataLen less than posture data size.");
172         return;
173     }
174     PostureData* postureData = reinterpret_cast<PostureData*>(event[SENSOR_EVENT_FIRST_DATA].data);
175     float angle = (*postureData).angle;
176     if (std::isless(angle, ANGLE_MIN_VAL) || std::isgreater(angle, ANGLE_MAX_VAL)) {
177         RS_LOGW("Invalid angle value, angle is %{public}f.", angle);
178         return;
179     }
180     RS_LOGI("angle vlaue in PostureData is: %{public}f.", angle);
181     HandleSensorData(angle);
182 }
183 
HandleSensorData(float angle)184 void RSScreenManager::HandleSensorData(float angle)
185 {
186     std::unique_lock<std::mutex> lock(activeScreenIdAssignedMutex_);
187     FoldState foldState = TransferAngleToScreenState(angle);
188     if (foldState == FoldState::FOLDED) {
189         if (activeScreenId_ != externalScreenId_) {
190             activeScreenId_ = externalScreenId_;
191             RS_LOGI("%{public}s: foldState is FoldState::FOLDED.", __func__);
192         }
193     } else if (activeScreenId_ != innerScreenId_) {
194         activeScreenId_ = innerScreenId_;
195         RS_LOGI("%{public}s: foldState is not FoldState::FOLDED.", __func__);
196     }
197     isPostureSensorDataHandled_ = true;
198     HgmCore::Instance().SetActiveScreenId(activeScreenId_);
199     activeScreenIdAssignedCV_.notify_one();
200 }
201 
TransferAngleToScreenState(float angle)202 FoldState RSScreenManager::TransferAngleToScreenState(float angle)
203 {
204     if (std::isless(angle, ANGLE_MIN_VAL)) {
205         RS_LOGI("%{public}s: angle isless ANGLE_MIN_VAL.", __func__);
206         return FoldState::FOLDED;
207     }
208     if (std::isgreaterequal(angle, HALF_FOLDED_MAX_THRESHOLD)) {
209         RS_LOGI("%{public}s: angle isgreaterequal HALF_FOLDED_MAX_THRESHOLD.", __func__);
210         return FoldState::EXPAND;
211     }
212     FoldState state;
213     if (std::islessequal(angle, OPEN_HALF_FOLDED_MIN_THRESHOLD)) {
214         RS_LOGI("%{public}s: angle islessequal OPEN_HALF_FOLDED_MIN_THRESHOLD.", __func__);
215         state = FoldState::FOLDED;
216     } else {
217         RS_LOGI("%{public}s: angle isgreater HALF_FOLDED_MAX_THRESHOLD.", __func__);
218         state = FoldState::EXPAND;
219     }
220     return state;
221 }
222 
GetActiveScreenId()223 ScreenId RSScreenManager::GetActiveScreenId()
224 {
225     std::unique_lock<std::mutex> lock(activeScreenIdAssignedMutex_);
226     if (!isFoldScreenFlag_) {
227         RS_LOGW("%{public}s: !isFoldScreenFlag_.", __func__);
228         return INVALID_SCREEN_ID;
229     }
230     if (isPostureSensorDataHandled_) {
231         isFirstTimeToGetActiveScreenId_ = false;
232         UnRegisterSensorCallback();
233         RS_LOGW("%{public}s: activeScreenId: %{public}" PRIu64, __func__, activeScreenId_);
234         return activeScreenId_;
235     }
236     activeScreenIdAssignedCV_.wait_until(lock, std::chrono::system_clock::now() +
237         std::chrono::milliseconds(WAIT_FOR_ACTIVE_SCREEN_ID_TIMEOUT), [this]() {
238             return isPostureSensorDataHandled_;
239         });
240     if (isFirstTimeToGetActiveScreenId_) {
241         RS_LOGI("%{public}s: isFirstTimeToGetActiveScreenId_.", __func__);
242         isFirstTimeToGetActiveScreenId_ = false;
243         UnRegisterSensorCallback();
244     }
245     RS_LOGI("%{public}s: activeScreenId: %{public}" PRIu64, __func__, activeScreenId_);
246     return activeScreenId_;
247 }
248 #else
GetActiveScreenId()249 ScreenId RSScreenManager::GetActiveScreenId()
250 {
251     return INVALID_SCREEN_ID;
252 }
253 #endif
254 
IsAllScreensPowerOff() const255 bool RSScreenManager::IsAllScreensPowerOff() const
256 {
257     std::scoped_lock lock(screenMapMutex_, powerStatusMutex_);
258     if (screenPowerStatus_.empty()) {
259         RS_LOGE("%{public}s: screenPowerStatus_ is empty.", __func__);
260         return false;
261     }
262     for (const auto& [id, powerStatus] : screenPowerStatus_) {
263         auto iter = screens_.find(id);
264         if (iter != screens_.end() && iter->second != nullptr && iter->second->IsVirtual()) {
265             continue;
266         }
267         // we also need to consider the AOD mode(POWER_STATUS_SUSPEND)
268         if (powerStatus != ScreenPowerStatus::POWER_STATUS_OFF &&
269             powerStatus != ScreenPowerStatus::POWER_STATUS_SUSPEND) {
270             return false;
271         }
272     }
273     return true;
274 }
275 
PostForceRefreshTask()276 void RSScreenManager::PostForceRefreshTask()
277 {
278     auto mainThread = RSMainThread::Instance();
279     if (mainThread != nullptr && !mainThread->IsRequestedNextVSync()) {
280         mainThread->PostTask([mainThread]() {
281             RS_TRACE_NAME("No RNV, ForceRefreshOneFrame");
282             mainThread->SetDirtyFlag();
283             mainThread->RequestNextVSync();
284         }, FORCE_REFRESH_ONE_FRAME_TASK_NAME, 20); // delay 20ms
285     }
286 }
287 
RemoveForceRefreshTask()288 void RSScreenManager::RemoveForceRefreshTask()
289 {
290     auto mainThread = RSMainThread::Instance();
291     if (mainThread != nullptr) {
292         mainThread->RemoveTask(FORCE_REFRESH_ONE_FRAME_TASK_NAME);
293     }
294 }
295 
OnHotPlug(std::shared_ptr<HdiOutput> & output,bool connected,void * data)296 void RSScreenManager::OnHotPlug(std::shared_ptr<HdiOutput>& output, bool connected, void* data)
297 {
298     if (output == nullptr) {
299         RS_LOGE("%{public}s: output is nullptr.", __func__);
300         return;
301     }
302 
303     RSScreenManager* screenManager = nullptr;
304     if (data != nullptr) {
305         RS_LOGI("%{public}s: data is not nullptr.", __func__);
306         screenManager = static_cast<RSScreenManager*>(data);
307     } else {
308         RS_LOGI("%{public}s: data is nullptr.", __func__);
309         screenManager = static_cast<RSScreenManager*>(RSScreenManager::GetInstance().GetRefPtr());
310     }
311 
312     if (screenManager == nullptr) {
313         RS_LOGE("%{public}s: Failed to find RSScreenManager instance.", __func__);
314         return;
315     }
316 
317     screenManager->OnHotPlugEvent(output, connected);
318 }
319 
OnHotPlugEvent(std::shared_ptr<HdiOutput> & output,bool connected)320 void RSScreenManager::OnHotPlugEvent(std::shared_ptr<HdiOutput>& output, bool connected)
321 {
322     {
323         std::lock_guard<std::mutex> lock(hotPlugAndConnectMutex_);
324 
325         ScreenId id = ToScreenId(output->GetScreenId());
326         if (pendingHotPlugEvents_.find(id) != pendingHotPlugEvents_.end()) {
327             RS_LOGE("%{public}s: screen %{public}" PRIu64 "is covered.", __func__, id);
328         }
329         pendingHotPlugEvents_[id] = ScreenHotPlugEvent{output, connected};
330         RS_LOGI("%{public}s: screen %{public}" PRIu64 "is %{public}s, event has been saved", __func__, id,
331                 connected ? "connected" : "disconnected");
332     }
333 
334     // This func would be called in main thread first time immediately after calling composer_->RegScreenHotplug,
335     // but at this time the RSMainThread object would not be ready to handle this, so we need to call
336     // ProcessScreenHotPlugEvents() after this func in RSScreenManager::Init().
337 
338     // Normally, this func would be called in hdi's hw-ipc threads(but sometimes in main thread, maybe),
339     // so we should notify the RSMainThread to postTask to call ProcessScreenHotPlugEvents().
340     auto mainThread = RSMainThread::Instance();
341     if (mainThread == nullptr) {
342         RS_LOGE("%{public}s: mainThread is nullptr.", __func__);
343         return;
344     }
345     RS_LOGI("%{public}s: mainThread->RequestNextVSync()", __func__);
346     mainThread->RequestNextVSync();
347 }
348 
OnRefresh(ScreenId id,void * data)349 void RSScreenManager::OnRefresh(ScreenId id, void* data)
350 {
351     RSScreenManager* screenManager = nullptr;
352     if (data != nullptr) {
353         screenManager = static_cast<RSScreenManager*>(data);
354     } else {
355         RS_LOGI("%{public}s: data is nullptr.", __func__);
356         screenManager = static_cast<RSScreenManager*>(RSScreenManager::GetInstance().GetRefPtr());
357     }
358 
359     if (screenManager == nullptr) {
360         RS_LOGE("%{public}s: Failed to find RSScreenManager instance.", __func__);
361         return;
362     }
363     screenManager->OnRefreshEvent(id);
364 }
365 
OnRefreshEvent(ScreenId id)366 void RSScreenManager::OnRefreshEvent(ScreenId id)
367 {
368     auto mainThread = RSMainThread::Instance();
369     if (mainThread == nullptr) {
370         RS_LOGE("%{public}s: mainThread is nullptr.", __func__);
371         return;
372     }
373     mainThread->PostTask([mainThread]() {
374         mainThread->SetForceUpdateUniRenderFlag(true);
375         mainThread->RequestNextVSync();
376     });
377 }
378 
OnHwcDead(void * data)379 void RSScreenManager::OnHwcDead(void* data)
380 {
381     RS_LOGW("%{public}s: The composer_host is already dead.", __func__);
382     RSScreenManager* screenManager = static_cast<RSScreenManager*>(RSScreenManager::GetInstance().GetRefPtr());
383     if (screenManager == nullptr) {
384         RS_LOGE("%{public}s: Failed to find RSScreenManager instance.", __func__);
385         return;
386     }
387 
388     // Automatically recover when composer host dies.
389     screenManager->CleanAndReinit();
390 }
391 
OnHwcDeadEvent()392 void RSScreenManager::OnHwcDeadEvent()
393 {
394     // Only clean the physical screen when hwc dead
395     std::map<ScreenId, std::shared_ptr<OHOS::Rosen::RSScreen>> screens;
396     {
397         std::lock_guard<std::mutex> lock(screenMapMutex_);
398         for (auto it = screens_.begin(); it != screens_.end();) {
399             if (it->second && !it->second->IsVirtual()) {
400                 auto node = screens_.extract(it++);
401                 screens.insert(std::move(node));
402             } else {
403                 ++it;
404             }
405         }
406     }
407 #ifdef RS_ENABLE_GPU
408     for (const auto& [_, screen] : screens) {
409         RSHardwareThread::Instance().ClearFrameBuffers(screen->GetOutput());
410     }
411 #endif
412     isHwcDead_ = true;
413     defaultScreenId_ = INVALID_SCREEN_ID;
414 }
415 
OnScreenVBlankIdle(uint32_t devId,uint64_t ns,void * data)416 void RSScreenManager::OnScreenVBlankIdle(uint32_t devId, uint64_t ns, void* data)
417 {
418     RS_LOGI("%{public}s: devId:%{public}u, ns:" RSPUBU64, __func__, devId, ns);
419     RS_TRACE_NAME_FMT("OnScreenVBlankIdle devId:%u, ns:%lu", devId, ns);
420     CreateVSyncSampler()->StartSample(true);
421     RSScreenManager* screenManager = static_cast<RSScreenManager*>(RSScreenManager::GetInstance().GetRefPtr());
422     if (screenManager == nullptr) {
423         RS_LOGE("%{public}s: Failed to find RSScreenManager instance.", __func__);
424         return;
425     }
426     screenManager->OnScreenVBlankIdleEvent(devId, ns);
427 }
428 
OnScreenVBlankIdleEvent(uint32_t devId,uint64_t ns)429 void RSScreenManager::OnScreenVBlankIdleEvent(uint32_t devId, uint64_t ns)
430 {
431     ScreenId screenId = ToScreenId(devId);
432     if (GetScreen(screenId) == nullptr) {
433         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, screenId);
434         return;
435     }
436 #ifdef RS_ENABLE_GPU
437     RSHardwareThread::Instance().PostTask([screenId, ns]() {
438         RSHardwareThread::Instance().OnScreenVBlankIdleCallback(screenId, ns);
439     });
440 #endif
441 }
442 
CleanAndReinit()443 void RSScreenManager::CleanAndReinit()
444 {
445     auto task = [this]() {
446         OnHwcDeadEvent();
447         if (!composer_) {
448             RS_LOGE("CleanAndReinit: Failed to get composer.");
449             return;
450         }
451         composer_->ResetDevice();
452         if (!Init()) {
453             RS_LOGE("CleanAndReinit: Reinit failed");
454             return;
455         }
456     };
457 
458     auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
459     if (renderType != UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
460         RSMainThread::Instance()->PostTask(std::move(task));
461     } else {
462 #ifdef RS_ENABLE_GPU
463         RSHardwareThread::Instance().PostTask(std::move(task));
464 #endif
465     }
466 }
467 
TrySimpleProcessHotPlugEvents()468 bool RSScreenManager::TrySimpleProcessHotPlugEvents()
469 {
470     std::lock_guard<std::mutex> lock(hotPlugAndConnectMutex_);
471     if (!isHwcDead_ && pendingHotPlugEvents_.empty() && pendingConnectedIds_.empty()) {
472         mipiCheckInFirstHotPlugEvent_ = true;
473         return true;
474     }
475     RS_LOGI("%{public}s: isHwcDead_:%{public}d, pendingHotPlugEventsSize:%{public}zu, "
476             "pendingConnectedIdsSize:%{public}zu",
477             __func__, isHwcDead_.load(), pendingHotPlugEvents_.size(), pendingConnectedIds_.size());
478     return false;
479 }
480 
ProcessScreenHotPlugEvents()481 void RSScreenManager::ProcessScreenHotPlugEvents()
482 {
483     std::map<ScreenId, ScreenHotPlugEvent> pendingHotPlugEvents;
484     {
485         std::lock_guard<std::mutex> lock(hotPlugAndConnectMutex_);
486         pendingHotPlugEvents.swap(pendingHotPlugEvents_);
487     }
488     for (auto& [_, event] : pendingHotPlugEvents) {
489         if (event.output == nullptr) {
490             RS_LOGE("%{public}s: output is nullptr.", __func__);
491             continue;
492         }
493         if (event.connected) {
494             ProcessScreenConnected(event.output);
495             AddScreenToHgm(event.output);
496         } else {
497             ProcessScreenDisConnected(event.output);
498             RemoveScreenFromHgm(event.output);
499         }
500     }
501     ProcessPendingConnections();
502     isHwcDead_ = false;
503     mipiCheckInFirstHotPlugEvent_ = true;
504 }
505 
ProcessPendingConnections()506 void RSScreenManager::ProcessPendingConnections()
507 {
508     std::vector<ScreenId> pendingConnectedIds;
509     {
510         std::lock_guard<std::mutex> lock(hotPlugAndConnectMutex_);
511         pendingConnectedIds.swap(pendingConnectedIds_);
512     }
513     for (auto id : pendingConnectedIds) {
514         NotifyScreenNodeChange(id, true);
515         if (!isHwcDead_) {
516             TriggerCallbacks(id, ScreenEvent::CONNECTED);
517         } else if (id != 0 && MultiScreenParam::IsRsReportHwcDead()) {
518             TriggerCallbacks(id, ScreenEvent::CONNECTED, ScreenChangeReason::HWCDEAD);
519         }
520         auto screen = GetScreen(id);
521         if (screen == nullptr) {
522             continue;
523         }
524 
525         ScreenRotation rotation = ScreenRotation::INVALID_SCREEN_ROTATION;
526         int32_t backLightLevel = INVALID_BACKLIGHT_VALUE;
527         {
528             std::shared_lock<std::shared_mutex> lock(backLightAndCorrectionMutex_);
529             if (auto iter = screenCorrection_.find(id); iter != screenCorrection_.end()) {
530                 rotation = iter->second;
531             }
532             if (auto iter = screenBacklight_.find(id); iter != screenBacklight_.end()) {
533                 backLightLevel = static_cast<int32_t>(iter->second);
534             }
535         }
536         if (rotation != ScreenRotation::INVALID_SCREEN_ROTATION) {
537             screen->SetScreenCorrection(rotation);
538         }
539 
540         bool screenPowerOn = false;
541         {
542             std::shared_lock<std::shared_mutex> lock(powerStatusMutex_);
543             auto iter = screenPowerStatus_.find(id);
544             screenPowerOn = (iter == screenPowerStatus_.end() || iter->second == ScreenPowerStatus::POWER_STATUS_ON);
545         }
546         if (backLightLevel != INVALID_BACKLIGHT_VALUE && screenPowerOn) {
547             screen->SetScreenBacklight(static_cast<uint32_t>(backLightLevel));
548             auto mainThread = RSMainThread::Instance();
549             mainThread->PostTask([mainThread]() {
550                 mainThread->SetDirtyFlag();
551             });
552             mainThread->ForceRefreshForUni();
553         }
554     }
555 }
556 
AddScreenToHgm(std::shared_ptr<HdiOutput> & output)557 void RSScreenManager::AddScreenToHgm(std::shared_ptr<HdiOutput>& output)
558 {
559     RS_LOGI("%{public}s in", __func__);
560     HgmTaskHandleThread::Instance().PostSyncTask([this, &output] () {
561         auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
562         ScreenId thisId = ToScreenId(output->GetScreenId());
563         auto screen = GetScreen(thisId);
564         if (screen == nullptr) {
565             RS_LOGE("invalid screen id, screen not found : %{public}" PRIu64, thisId);
566             return;
567         }
568 
569         int32_t initModeId = 0;
570         auto initMode = screen->GetActiveMode();
571         if (!initMode) {
572             RS_LOGE("%{public}s failed to get initial mode", __func__);
573         } else {
574             initModeId = initMode->id;
575         }
576         const auto& capability = screen->GetCapability();
577         ScreenSize screenSize = {screen->Width(), screen->Height(), capability.phyWidth, capability.phyHeight};
578         RS_LOGI("%{public}s: add screen: w * h: [%{public}u * %{public}u], capability w * h: "
579             "[%{public}u * %{public}u]", __func__, screen->Width(), screen->Height(),
580             capability.phyWidth, capability.phyHeight);
581         if (hgmCore.AddScreen(thisId, initModeId, screenSize)) {
582             RS_LOGE("%{public}s failed to add screen : %{public}" PRIu64, __func__, thisId);
583             return;
584         }
585 
586         // for each supported mode, use the index as modeId to add the detailed mode to hgm
587         int32_t modeId = 0;
588         auto supportedModes = screen->GetSupportedModes();
589         for (const auto& mode : supportedModes) {
590             if (hgmCore.AddScreenInfo(thisId, mode.width, mode.height, mode.freshRate, modeId)) {
591                 RS_LOGW("failed to add a screen profile to the screen : %{public}" PRIu64, thisId);
592             }
593             modeId++;
594         }
595     });
596 }
597 
RemoveScreenFromHgm(std::shared_ptr<HdiOutput> & output)598 void RSScreenManager::RemoveScreenFromHgm(std::shared_ptr<HdiOutput>& output)
599 {
600     RS_LOGI("%{public}s in", __func__);
601     HgmTaskHandleThread::Instance().PostTask([id = ToScreenId(output->GetScreenId())] () {
602         auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
603         RS_LOGI("remove screen, id: %{public}" PRIu64, id);
604         if (hgmCore.RemoveScreen(id)) {
605             RS_LOGW("failed to remove screen : %{public}" PRIu64, id);
606         }
607     });
608 }
609 
ProcessScreenConnected(std::shared_ptr<HdiOutput> & output)610 void RSScreenManager::ProcessScreenConnected(std::shared_ptr<HdiOutput>& output)
611 {
612     ScreenId id = ToScreenId(output->GetScreenId());
613     RS_LOGI("%{public}s The screen for id %{public}" PRIu64 " connected.", __func__, id);
614 
615     if (GetScreen(id)) {
616         TriggerCallbacks(id, ScreenEvent::DISCONNECTED);
617         RS_LOGW("%{public}s The screen for id %{public}" PRIu64 " already existed.", __func__, id);
618     }
619     auto screen = std::make_shared<RSScreen>(id, false, output, nullptr);
620 
621     std::unique_lock<std::mutex> lock(screenMapMutex_);
622     screens_[id] = screen;
623     if (isFoldScreenFlag_ && foldScreenIds_.size() < ORIGINAL_FOLD_SCREEN_AMOUNT) {
624         foldScreenIds_[id] = {true, false};
625     }
626     lock.unlock();
627 
628     ScreenId defaultScreenId = defaultScreenId_;
629     if (screen->GetCapability().type == GraphicInterfaceType::GRAPHIC_DISP_INTF_MIPI) {
630         if (!mipiCheckInFirstHotPlugEvent_.exchange(true)) {
631             defaultScreenId = id;
632         }
633     } else if (defaultScreenId == INVALID_SCREEN_ID) {
634         RS_LOGI("%{public}s The screen id %{public}" PRIu64
635                 " is set to defaultScreenId. last defaultScreenId is %{public}" PRIu64 ".",
636                 __func__, id, defaultScreenId);
637         defaultScreenId = id;
638     }
639     defaultScreenId_ = defaultScreenId;
640 
641     uint64_t vsyncEnabledScreenId = JudgeVSyncEnabledScreenWhileHotPlug(id, true);
642     UpdateVsyncEnabledScreenId(vsyncEnabledScreenId);
643     if (vsyncEnabledScreenId == id) {
644         screen->SetScreenVsyncEnabled(true);
645     }
646 
647 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
648     if (isFoldScreenFlag_ && id != 0) {
649         RS_LOGI("%{public}s The externalScreenId_ is set %{public}" PRIu64 ".", __func__, id);
650         externalScreenId_ = id;
651     }
652 #endif
653     std::lock_guard<std::mutex> connectLock(hotPlugAndConnectMutex_);
654     pendingConnectedIds_.emplace_back(id);
655 }
656 
ProcessScreenDisConnected(std::shared_ptr<HdiOutput> & output)657 void RSScreenManager::ProcessScreenDisConnected(std::shared_ptr<HdiOutput>& output)
658 {
659     ScreenId id = ToScreenId(output->GetScreenId());
660     RS_LOGW("%{public}s process screen disconnected, id: %{public}" PRIu64, __func__, id);
661     if (auto screen = GetScreen(id)) {
662         TriggerCallbacks(id, ScreenEvent::DISCONNECTED);
663         NotifyScreenNodeChange(id, false);
664         std::lock_guard<std::mutex> lock(screenMapMutex_);
665         screens_.erase(id);
666         RS_LOGI("%{public}s: Screen(id %{public}" PRIu64 ") disconnected.", __func__, id);
667     } else {
668         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
669     }
670     {
671         std::lock_guard<std::shared_mutex> lock(powerStatusMutex_);
672         screenPowerStatus_.erase(id);
673     }
674     {
675         std::lock_guard<std::shared_mutex> lock(backLightAndCorrectionMutex_);
676         screenBacklight_.erase(id);
677         screenCorrection_.erase(id);
678     }
679     if (id == defaultScreenId_) {
680         HandleDefaultScreenDisConnected();
681     }
682 
683     uint64_t vsyncEnabledScreenId = JudgeVSyncEnabledScreenWhileHotPlug(id, false);
684     UpdateVsyncEnabledScreenId(vsyncEnabledScreenId);
685 }
686 
UpdateVsyncEnabledScreenId(ScreenId screenId)687 void RSScreenManager::UpdateVsyncEnabledScreenId(ScreenId screenId)
688 {
689     std::unique_lock<std::mutex> lock(screenMapMutex_);
690     if (isFoldScreenFlag_ && foldScreenIds_.size() == ORIGINAL_FOLD_SCREEN_AMOUNT) {
691         bool isAllFoldScreenDisconnected = true;
692         for (const auto& [foldScreenId, foldScreenStatus] : foldScreenIds_) {
693             if (foldScreenStatus.isConnected) {
694                 isAllFoldScreenDisconnected = false;
695                 break;
696             }
697         }
698         auto it = foldScreenIds_.find(screenId);
699         if (it == foldScreenIds_.end() && !isAllFoldScreenDisconnected) {
700             return;
701         }
702     }
703     lock.unlock();
704 
705     auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
706     if (renderType != UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
707         RegSetScreenVsyncEnabledCallbackForMainThread(screenId);
708     } else {
709         RegSetScreenVsyncEnabledCallbackForHardwareThread(screenId);
710     }
711 }
712 
RegSetScreenVsyncEnabledCallbackForMainThread(ScreenId vsyncEnabledScreenId)713 void RSScreenManager::RegSetScreenVsyncEnabledCallbackForMainThread(ScreenId vsyncEnabledScreenId)
714 {
715     auto vsyncSampler = CreateVSyncSampler();
716     if (vsyncSampler == nullptr) {
717         RS_LOGE("%{public}s failed, vsyncSampler is null", __func__);
718         return;
719     }
720     vsyncSampler->SetVsyncEnabledScreenId(vsyncEnabledScreenId);
721     vsyncSampler->RegSetScreenVsyncEnabledCallback([this](uint64_t screenId, bool enabled) {
722         auto mainThread = RSMainThread::Instance();
723         if (mainThread == nullptr) {
724             RS_LOGE("%{public}s screenVsyncEnabled:%{public}d set failed, "
725                 "get RSMainThread failed", __func__, enabled);
726             return;
727         }
728         mainThread->PostTask([this, screenId, enabled]() {
729             auto screen = GetScreen(screenId);
730             if (screen == nullptr) {
731                 RS_LOGE("SetScreenVsyncEnabled:%{public}d failed, screen %{public}" PRIu64 " not found",
732                     enabled, screenId);
733                 return;
734             }
735             screen->SetScreenVsyncEnabled(enabled);
736         });
737     });
738 }
739 
RegSetScreenVsyncEnabledCallbackForHardwareThread(ScreenId vsyncEnabledScreenId)740 void RSScreenManager::RegSetScreenVsyncEnabledCallbackForHardwareThread(ScreenId vsyncEnabledScreenId)
741 {
742     auto vsyncSampler = CreateVSyncSampler();
743     if (vsyncSampler == nullptr) {
744         RS_LOGE("%{public}s failed, vsyncSampler is null", __func__);
745         return;
746     }
747     vsyncSampler->SetVsyncEnabledScreenId(vsyncEnabledScreenId);
748 #ifdef RS_ENABLE_GPU
749     vsyncSampler->RegSetScreenVsyncEnabledCallback([this](uint64_t screenId, bool enabled) {
750         RSHardwareThread::Instance().PostTask([this, screenId, enabled]() {
751             auto screen = GetScreen(screenId);
752             if (screen == nullptr) {
753                 RS_LOGE("SetScreenVsyncEnabled:%{public}d failed, screen %{public}" PRIu64 " not found",
754                     enabled, screenId);
755                 return;
756             }
757             screen->SetScreenVsyncEnabled(enabled);
758         });
759     });
760 #endif
761 }
762 
763 // If the previous primary screen disconnected, we traversal the left screens
764 // and find the first physical screen to be the default screen.
765 // If there was no physical screen left, we set the first screen as default, no matter what type it is.
766 // At last, if no screen left, we set Default Screen Id to INVALID_SCREEN_ID.
HandleDefaultScreenDisConnected()767 void RSScreenManager::HandleDefaultScreenDisConnected()
768 {
769     ScreenId defaultScreenId = INVALID_SCREEN_ID;
770     std::lock_guard<std::mutex> lock(screenMapMutex_);
771     auto iter = std::find_if(screens_.cbegin(), screens_.cend(), [](const auto& node) {
772         const auto& screen = node.second;
773         return screen && !screen->IsVirtual();
774     });
775     if (iter != screens_.cend()) {
776         defaultScreenId = iter->first;
777     }
778 
779     if (defaultScreenId == INVALID_SCREEN_ID && !screens_.empty()) {
780         defaultScreenId = screens_.cbegin()->first;
781     }
782     defaultScreenId_ = defaultScreenId;
783 }
784 
UpdateFoldScreenConnectStatusLocked(ScreenId screenId,bool connected)785 void RSScreenManager::UpdateFoldScreenConnectStatusLocked(ScreenId screenId, bool connected)
786 {
787     if (isFoldScreenFlag_) {
788         auto it = foldScreenIds_.find(screenId);
789         if (it != foldScreenIds_.end()) {
790             it->second.isConnected = connected;
791         }
792     }
793 }
794 
JudgeVSyncEnabledScreenWhileHotPlug(ScreenId screenId,bool connected)795 uint64_t RSScreenManager::JudgeVSyncEnabledScreenWhileHotPlug(ScreenId screenId, bool connected)
796 {
797     std::unique_lock<std::mutex> lock(screenMapMutex_);
798     UpdateFoldScreenConnectStatusLocked(screenId, connected);
799 
800     auto vsyncSampler = CreateVSyncSampler();
801     if (vsyncSampler == nullptr) {
802         RS_LOGE("%{public}s failed, vsyncSampler is null", __func__);
803         return screenId;
804     }
805     uint64_t vsyncEnabledScreenId = vsyncSampler->GetVsyncEnabledScreenId();
806     if (connected) { // screen connected
807         if (vsyncEnabledScreenId == INVALID_SCREEN_ID) {
808             return screenId;
809         }
810     } else { // screen disconnected
811         if (vsyncEnabledScreenId != screenId) {
812             return vsyncEnabledScreenId;
813         }
814         vsyncEnabledScreenId = INVALID_SCREEN_ID;
815         auto iter = std::find_if(screens_.cbegin(), screens_.cend(), [](const auto& node) {
816             const auto& screen = node.second;
817             return screen && !screen->IsVirtual();
818         });
819         if (iter != screens_.end()) {
820             vsyncEnabledScreenId = iter->first;
821         }
822     }
823     return vsyncEnabledScreenId;
824 }
825 
JudgeVSyncEnabledScreenWhilePowerStatusChanged(ScreenId screenId,ScreenPowerStatus status)826 uint64_t RSScreenManager::JudgeVSyncEnabledScreenWhilePowerStatusChanged(ScreenId screenId, ScreenPowerStatus status)
827 {
828     std::unique_lock<std::mutex> lock(screenMapMutex_);
829     uint64_t vsyncEnabledScreenId = CreateVSyncSampler()->GetVsyncEnabledScreenId();
830     auto it = foldScreenIds_.find(screenId);
831     if (it == foldScreenIds_.end()) {
832         return vsyncEnabledScreenId;
833     }
834 
835     if (status == ScreenPowerStatus::POWER_STATUS_ON) {
836         it->second.isPowerOn = true;
837         auto vsyncScreenIt = foldScreenIds_.find(vsyncEnabledScreenId);
838         if (vsyncScreenIt == foldScreenIds_.end() || vsyncScreenIt->second.isPowerOn == false) {
839             return screenId;
840         }
841     } else if (status == ScreenPowerStatus::POWER_STATUS_OFF) {
842         it->second.isPowerOn = false;
843         if (screenId != vsyncEnabledScreenId) {
844             return vsyncEnabledScreenId;
845         }
846         for (auto& [foldScreenId, status] : foldScreenIds_) {
847             if (status.isConnected && status.isPowerOn) {
848                 return foldScreenId;
849             }
850         }
851     }
852     return vsyncEnabledScreenId;
853 }
854 
855 // if SetVirtualScreenSurface success, force a refresh of one frame, avoiding prolong black screen
ForceRefreshOneFrame() const856 void RSScreenManager::ForceRefreshOneFrame() const
857 {
858     auto mainThread = RSMainThread::Instance();
859     if (mainThread != nullptr) {
860         mainThread->PostTask([mainThread]() {
861             mainThread->SetDirtyFlag();
862         });
863         mainThread->ForceRefreshForUni();
864     }
865 }
866 
SetDefaultScreenId(ScreenId id)867 void RSScreenManager::SetDefaultScreenId(ScreenId id)
868 {
869     defaultScreenId_ = id;
870 }
871 
GenerateVirtualScreenId()872 ScreenId RSScreenManager::GenerateVirtualScreenId()
873 {
874     std::lock_guard<std::mutex> lock(virtualScreenIdMutex_);
875     if (!freeVirtualScreenIds_.empty()) {
876         ScreenId id = freeVirtualScreenIds_.front();
877         freeVirtualScreenIds_.pop();
878         RS_LOGI("%{public}s: VirtualScreenId is %{public}" PRIu64, __func__, id);
879         return id;
880     }
881 
882     RS_LOGI("%{public}s: freeVirtualScreenIds_ is empty.", __func__);
883     // The left 32 bits is for virtual screen id.
884     return (static_cast<ScreenId>(virtualScreenCount_++) << 32) | 0xffffffffu;
885 }
886 
GetVirtualScreenResolution(ScreenId id,RSVirtualScreenResolution & virtualScreenResolution) const887 void RSScreenManager::GetVirtualScreenResolution(ScreenId id, RSVirtualScreenResolution& virtualScreenResolution) const
888 {
889     auto screen = GetScreen(id);
890     if (screen == nullptr) {
891         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
892         return;
893     }
894 
895     virtualScreenResolution.SetVirtualScreenWidth(static_cast<uint32_t>(screen->Width()));
896     virtualScreenResolution.SetVirtualScreenHeight(static_cast<uint32_t>(screen->Height()));
897 }
898 
GetScreenActiveMode(ScreenId id,RSScreenModeInfo & screenModeInfo) const899 void RSScreenManager::GetScreenActiveMode(ScreenId id, RSScreenModeInfo& screenModeInfo) const
900 {
901     auto screen = GetScreen(id);
902     if (screen == nullptr) {
903         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
904         return;
905     }
906     auto modeInfo = screen->GetActiveMode();
907     if (!modeInfo) {
908         RS_LOGE("%{public}s: Failed to get active mode for screen %{public}" PRIu64, __func__, id);
909         return;
910     }
911 
912     RS_LOGI("%{public}s: screen[%{public}" PRIu64 "] pixel[%{public}d * %{public}d],"
913         "freshRate[%{public}d]", __func__, id, modeInfo->width, modeInfo->height, modeInfo->freshRate);
914     screenModeInfo.SetScreenWidth(modeInfo->width);
915     screenModeInfo.SetScreenHeight(modeInfo->height);
916     screenModeInfo.SetScreenRefreshRate(modeInfo->freshRate);
917     screenModeInfo.SetScreenModeId(screen->GetActiveModePosByModeId(modeInfo->id));
918 }
919 
GetScreenSupportedModes(ScreenId id) const920 std::vector<RSScreenModeInfo> RSScreenManager::GetScreenSupportedModes(ScreenId id) const
921 {
922     auto screen = GetScreen(id);
923     if (screen == nullptr) {
924         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
925         return {};
926     }
927 
928     const auto& displaySupportedModes = screen->GetSupportedModes();
929     std::vector<RSScreenModeInfo> screenSupportedModes(displaySupportedModes.size());
930     std::transform(displaySupportedModes.cbegin(), displaySupportedModes.cend(), screenSupportedModes.begin(),
931         [](const auto& node) { return RSScreenModeInfo(node.width, node.height, node.freshRate, node.id); });
932     return screenSupportedModes;
933 }
934 
GetScreenCapability(ScreenId id) const935 RSScreenCapability RSScreenManager::GetScreenCapability(ScreenId id) const
936 {
937     RSScreenCapability screenCapability;
938     auto screen = GetScreen(id);
939     if (screen == nullptr) {
940         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
941         return screenCapability;
942     }
943 
944     if (screen->IsVirtual()) {
945         RS_LOGW("%{public}s: only name attribute is valid for virtual screen.", __func__);
946         screenCapability.SetName(screen->Name());
947         return screenCapability;
948     }
949 
950     const auto& capability = screen->GetCapability();
951     std::vector<RSScreenProps> props(capability.props.size());
952     std::transform(capability.props.cbegin(), capability.props.cend(), props.begin(), [](const auto& node) {
953         return RSScreenProps(node.name, node.propId, node.value);
954     });
955     screenCapability.SetName(capability.name);
956     screenCapability.SetType(static_cast<ScreenInterfaceType>(capability.type));
957     screenCapability.SetPhyWidth(capability.phyWidth);
958     screenCapability.SetPhyHeight(capability.phyHeight);
959     screenCapability.SetSupportLayers(capability.supportLayers);
960     screenCapability.SetVirtualDispCount(capability.virtualDispCount);
961     screenCapability.SetSupportWriteBack(capability.supportWriteBack);
962     screenCapability.SetProps(std::move(props));
963     return screenCapability;
964 }
965 
GetScreenPowerStatus(ScreenId id) const966 ScreenPowerStatus RSScreenManager::GetScreenPowerStatus(ScreenId id) const
967 {
968     if (!RSSystemProperties::IsSmallFoldDevice()) {
969         auto screen = GetScreen(id);
970         if (screen == nullptr) {
971             RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
972             return INVALID_POWER_STATUS;
973         }
974 
975         ScreenPowerStatus status = static_cast<ScreenPowerStatus>(screen->GetPowerStatus());
976         return status;
977     }
978 
979     ScreenPowerStatus status = ScreenPowerStatus::INVALID_POWER_STATUS;
980     RSSwitchingThread::Instance().PostSyncTask([id, &status, this]() {
981         auto screen = GetScreen(id);
982         if (screen == nullptr) {
983             RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
984             status = INVALID_POWER_STATUS;
985             return;
986         }
987 
988         status = static_cast<ScreenPowerStatus>(screen->GetPowerStatus());
989     });
990 
991     return status;
992 }
993 
GetScreenCorrection(ScreenId id) const994 ScreenRotation RSScreenManager::GetScreenCorrection(ScreenId id) const
995 {
996     auto screen = GetScreen(id);
997     if (screen == nullptr) {
998         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
999         return ScreenRotation::INVALID_SCREEN_ROTATION;
1000     }
1001 
1002     return screen->GetScreenCorrection();
1003 }
1004 
GetDefaultScreenId() const1005 ScreenId RSScreenManager::GetDefaultScreenId() const
1006 {
1007     return defaultScreenId_;
1008 }
1009 
GetAllScreenIds() const1010 std::vector<ScreenId> RSScreenManager::GetAllScreenIds() const
1011 {
1012     std::lock_guard<std::mutex> lock(screenMapMutex_);
1013     std::vector<ScreenId> ids;
1014     for (auto iter = screens_.begin(); iter != screens_.end(); ++iter) {
1015         ids.emplace_back(iter->first);
1016     }
1017     return ids;
1018 }
1019 
CreateVirtualScreen(const std::string & name,uint32_t width,uint32_t height,sptr<Surface> surface,ScreenId mirrorId,int32_t flags,std::vector<NodeId> whiteList)1020 ScreenId RSScreenManager::CreateVirtualScreen(
1021     const std::string& name,
1022     uint32_t width,
1023     uint32_t height,
1024     sptr<Surface> surface,
1025     ScreenId mirrorId,
1026     int32_t flags,
1027     std::vector<NodeId> whiteList)
1028 {
1029     if (currentVirtualScreenNum_ >= MAX_VIRTUAL_SCREEN_NUM) {
1030         RS_LOGW("%{public}s: virtual screens num %{public}" PRIu32 " has reached the maximum limit!",
1031             __func__, currentVirtualScreenNum_.load());
1032         return INVALID_SCREEN_ID;
1033     }
1034     if (width > MAX_VIRTUAL_SCREEN_WIDTH || height > MAX_VIRTUAL_SCREEN_HEIGHT) {
1035         RS_LOGW("%{public}s: width %{public}" PRIu32 " or height %{public}" PRIu32 " has reached"
1036             " the maximum limit!", __func__, width, height);
1037         return INVALID_SCREEN_ID;
1038     }
1039     if (surface != nullptr) {
1040         uint64_t surfaceId = surface->GetUniqueId();
1041         auto func = [surfaceId](const ScreenNode& node) {
1042             const auto& screen = node.second;
1043             return screen && screen->IsVirtual() && screen->GetProducerSurface() &&
1044                 screen->GetProducerSurface()->GetUniqueId() == surfaceId;
1045         };
1046         if (AnyScreenFits(func)) {
1047             RS_LOGW("%{public}s: surface %{public}" PRIu64 " is used, create virtual"
1048                 " screen failed!", __func__, surfaceId);
1049             return INVALID_SCREEN_ID;
1050         }
1051     } else {
1052         RS_LOGW("%{public}s: surface is nullptr.", __func__);
1053     }
1054 
1055     VirtualScreenConfigs configs;
1056     ScreenId newId = GenerateVirtualScreenId();
1057     configs.id = newId;
1058     configs.mirrorId = mirrorId;
1059     configs.name = name;
1060     configs.width = width;
1061     configs.height = height;
1062     configs.surface = surface;
1063     configs.flags = flags;
1064     configs.whiteList = std::unordered_set<NodeId>(whiteList.begin(), whiteList.end());
1065 
1066     {
1067         std::lock_guard<std::mutex> lock(screenMapMutex_);
1068         screens_[newId] = std::make_shared<RSScreen>(configs);
1069     }
1070     ++currentVirtualScreenNum_;
1071     NotifyScreenNodeChange(newId, true);
1072     RS_LOGI("%{public}s: create virtual screen(id %{public}" PRIu64 "), width %{public}u, height %{public}u.",
1073         __func__, newId, width, height);
1074     return newId;
1075 }
1076 
GetBlackListVirtualScreenByNode(uint64_t nodeId)1077 std::unordered_set<uint64_t> RSScreenManager::GetBlackListVirtualScreenByNode(uint64_t nodeId)
1078 {
1079     std::unordered_set<uint64_t> virtualScreens = {};
1080     std::scoped_lock lock(screenMapMutex_, blackListMutex_);
1081     if (blackListInVirtualScreen_.find(nodeId) != blackListInVirtualScreen_.end()) {
1082         virtualScreens = blackListInVirtualScreen_[nodeId];
1083     }
1084     if (castScreenBlackList_.find(nodeId) != castScreenBlackList_.end()) {
1085         // nodeId in castScreenBlackList, return its cast virtual screen
1086         for (const auto& [screenId, screen] : screens_) {
1087             if (screen && screen->IsVirtual() && screen->GetCastScreenEnableSkipWindow()) {
1088                 virtualScreens.insert(screenId);
1089             }
1090         }
1091     }
1092     return virtualScreens;
1093 }
1094 
SetVirtualScreenBlackList(ScreenId id,const std::vector<uint64_t> & blackList)1095 int32_t RSScreenManager::SetVirtualScreenBlackList(ScreenId id, const std::vector<uint64_t>& blackList)
1096 {
1097     std::unordered_set<NodeId> screenBlackList(blackList.begin(), blackList.end());
1098     if (id == INVALID_SCREEN_ID) {
1099         RS_LOGI("%{public}s: Cast screen blacklists for id %{public}" PRIu64, __func__, id);
1100         std::lock_guard<std::mutex> lock(blackListMutex_);
1101         castScreenBlackList_ = std::move(screenBlackList);
1102         return SUCCESS;
1103     }
1104     auto virtualScreen = GetScreen(id);
1105     if (virtualScreen == nullptr) {
1106         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1107         return SCREEN_NOT_FOUND;
1108     }
1109     RS_LOGI("%{public}s: Record screen blacklists for id %{public}" PRIu64, __func__, id);
1110     virtualScreen->SetBlackList(screenBlackList);
1111     {
1112         std::lock_guard<std::mutex> lock(blackListMutex_);
1113         for (const auto& [nodeId, screenIdSet] : blackListInVirtualScreen_) {
1114             if (screenIdSet.find(id) != screenIdSet.end()) {
1115                 blackListInVirtualScreen_[nodeId].erase(id);
1116             }
1117         }
1118         for (const auto& nodeId : screenBlackList) {
1119             blackListInVirtualScreen_[nodeId].insert(id);
1120         }
1121     }
1122 
1123     ScreenId mainId = GetDefaultScreenId();
1124     if (mainId != id) {
1125         auto mainScreen = GetScreen(mainId);
1126         if (mainScreen == nullptr) {
1127             RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, mainId);
1128             return SCREEN_NOT_FOUND;
1129         }
1130         mainScreen->SetBlackList(screenBlackList);
1131     }
1132     return SUCCESS;
1133 }
1134 
SetVirtualScreenTypeBlackList(ScreenId id,const std::vector<uint8_t> & typeBlackList)1135 int32_t RSScreenManager::SetVirtualScreenTypeBlackList(ScreenId id, const std::vector<uint8_t>& typeBlackList)
1136 {
1137     std::unordered_set<NodeType> screenTypeBlackList(typeBlackList.begin(), typeBlackList.end());
1138     if (id == INVALID_SCREEN_ID) {
1139         RS_LOGI("%{public}s: Cast screen typeblacklists for id %{public}" PRIu64, __func__, id);
1140         std::lock_guard<std::mutex> lock(typeBlackListMutex_);
1141         castScreenTypeBlackList_ = std::move(screenTypeBlackList);
1142         return SUCCESS;
1143     }
1144     auto virtualScreen = GetScreen(id);
1145     if (virtualScreen == nullptr) {
1146         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1147         return SCREEN_NOT_FOUND;
1148     }
1149     RS_LOGI("%{public}s: Record screen typeblacklists for id %{public}" PRIu64, __func__, id);
1150     virtualScreen->SetTypeBlackList(screenTypeBlackList);
1151     return SUCCESS;
1152 }
1153 
IsBlackListExceeded(const std::vector<uint64_t> & blackList,const std::unordered_set<uint64_t> & screenBlacklist)1154 static inline bool IsBlackListExceeded(const std::vector<uint64_t>& blackList,
1155     const std::unordered_set<uint64_t>& screenBlacklist)
1156 {
1157     return blackList.size() + screenBlacklist.size() > MAX_BLACK_LIST_NUM;
1158 }
1159 
AddVirtualScreenBlackList(ScreenId id,const std::vector<uint64_t> & blackList)1160 int32_t RSScreenManager::AddVirtualScreenBlackList(ScreenId id, const std::vector<uint64_t>& blackList)
1161 {
1162     if (id == INVALID_SCREEN_ID) {
1163         std::lock_guard<std::mutex> lock(blackListMutex_);
1164         if (IsBlackListExceeded(blackList, castScreenBlackList_)) {
1165             RS_LOGW("%{public}s: blacklist is over max size!", __func__);
1166             return INVALID_ARGUMENTS;
1167         }
1168         RS_LOGI("%{public}s: Cast screen blacklists", __func__);
1169         castScreenBlackList_.insert(blackList.cbegin(), blackList.cend());
1170         return SUCCESS;
1171     }
1172     auto virtualScreen = GetScreen(id);
1173     if (virtualScreen == nullptr) {
1174         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1175         return SCREEN_NOT_FOUND;
1176     }
1177     if (IsBlackListExceeded(blackList, virtualScreen->GetBlackList())) {
1178         RS_LOGW("%{public}s: blacklist is over max size!", __func__);
1179         return INVALID_ARGUMENTS;
1180     }
1181     RS_LOGI("%{public}s: Record screen blacklists for id %{public}" PRIu64, __func__, id);
1182     virtualScreen->AddBlackList(blackList);
1183     {
1184         std::lock_guard<std::mutex> lock(blackListMutex_);
1185         for (const auto& nodeId : blackList) {
1186             blackListInVirtualScreen_[nodeId].insert(id);
1187         }
1188     }
1189 
1190     ScreenId mainId = GetDefaultScreenId();
1191     if (mainId != id) {
1192         auto mainScreen = GetScreen(mainId);
1193         if (mainScreen == nullptr) {
1194             RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, mainId);
1195             return SCREEN_NOT_FOUND;
1196         }
1197         if (IsBlackListExceeded(blackList, mainScreen->GetBlackList())) {
1198             RS_LOGW("%{public}s: blacklist is over max size!", __func__);
1199             return INVALID_ARGUMENTS;
1200         }
1201         mainScreen->AddBlackList(blackList);
1202     }
1203     return SUCCESS;
1204 }
1205 
RemoveVirtualScreenBlackList(ScreenId id,const std::vector<uint64_t> & blackList)1206 int32_t RSScreenManager::RemoveVirtualScreenBlackList(ScreenId id, const std::vector<uint64_t>& blackList)
1207 {
1208     if (id == INVALID_SCREEN_ID) {
1209         RS_LOGI("%{public}s: Cast screen blacklists", __func__);
1210         std::lock_guard<std::mutex> lock(blackListMutex_);
1211         for (const auto& list : blackList) {
1212             castScreenBlackList_.erase(list);
1213         }
1214         return SUCCESS;
1215     }
1216     auto virtualScreen = GetScreen(id);
1217     if (virtualScreen == nullptr) {
1218         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1219         return SCREEN_NOT_FOUND;
1220     }
1221     RS_LOGI("%{public}s: Record screen blacklists for id %{public}" PRIu64, __func__, id);
1222     virtualScreen->RemoveBlackList(blackList);
1223     {
1224         std::lock_guard<std::mutex> lock(blackListMutex_);
1225         for (const auto& nodeId : blackList) {
1226             blackListInVirtualScreen_[nodeId].erase(id);
1227         }
1228     }
1229 
1230     ScreenId mainId = GetDefaultScreenId();
1231     if (mainId != id) {
1232         auto mainScreen = GetScreen(mainId);
1233         if (mainScreen == nullptr) {
1234             RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, mainId);
1235             return SCREEN_NOT_FOUND;
1236         }
1237         mainScreen->RemoveBlackList(blackList);
1238     }
1239     return SUCCESS;
1240 }
1241 
SetVirtualScreenSecurityExemptionList(ScreenId id,const std::vector<uint64_t> & securityExemptionList)1242 int32_t RSScreenManager::SetVirtualScreenSecurityExemptionList(
1243     ScreenId id,
1244     const std::vector<uint64_t>& securityExemptionList)
1245 {
1246     if (id == INVALID_SCREEN_ID) {
1247         RS_LOGW("%{public}s: INVALID_SCREEN_ID.", __func__);
1248         return INVALID_ARGUMENTS;
1249     }
1250     auto virtualScreen = GetScreen(id);
1251     if (virtualScreen == nullptr) {
1252         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1253         return SCREEN_NOT_FOUND;
1254     }
1255 
1256     if (!virtualScreen->IsVirtual()) {
1257         RS_LOGW("%{public}s: not virtual screen for id %{public}" PRIu64, __func__, id);
1258         return INVALID_ARGUMENTS;
1259     }
1260     virtualScreen->SetSecurityExemptionList(securityExemptionList);
1261     for (const auto& exemption : securityExemptionList) {
1262         RS_LOGW("%{public}s: virtual screen(id %{public}" PRIu64 "), nodeId %{public}" PRIu64,
1263             __func__, id, exemption);
1264     }
1265     return SUCCESS;
1266 }
1267 
GetVirtualScreenSecurityExemptionList(ScreenId id) const1268 const std::vector<uint64_t> RSScreenManager::GetVirtualScreenSecurityExemptionList(ScreenId id) const
1269 {
1270     auto virtualScreen = GetScreen(id);
1271     if (virtualScreen == nullptr) {
1272         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1273         return {};
1274     }
1275 
1276     return virtualScreen->GetSecurityExemptionList();
1277 }
1278 
SetScreenSecurityMask(ScreenId id,std::shared_ptr<Media::PixelMap> securityMask)1279 int32_t RSScreenManager::SetScreenSecurityMask(ScreenId id, std::shared_ptr<Media::PixelMap> securityMask)
1280 {
1281     if (id == INVALID_SCREEN_ID) {
1282         RS_LOGW("%{public}s: INVALID_SCREEN_ID.", __func__);
1283         return INVALID_ARGUMENTS;
1284     }
1285     auto screen = GetScreen(id);
1286     if (screen == nullptr) {
1287         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1288         return SCREEN_NOT_FOUND;
1289     }
1290 
1291     return screen->SetSecurityMask(securityMask);
1292 }
1293 
GetScreenSecurityMask(ScreenId id) const1294 std::shared_ptr<Media::PixelMap> RSScreenManager::GetScreenSecurityMask(ScreenId id) const
1295 {
1296     auto screen = GetScreen(id);
1297     if (screen == nullptr) {
1298         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1299         return nullptr;
1300     }
1301     return screen->GetSecurityMask();
1302 }
1303 
GetVirtualScreenSecLayerOption(ScreenId id) const1304 int32_t RSScreenManager::GetVirtualScreenSecLayerOption(ScreenId id) const
1305 {
1306     if (id == INVALID_SCREEN_ID) {
1307         RS_LOGW("%{public}s: INVALID_SCREEN_ID.", __func__);
1308         return INVALID_ARGUMENTS;
1309     }
1310     auto virtualScreen = GetScreen(id);
1311     if (virtualScreen == nullptr || !virtualScreen->IsVirtual()) {
1312         RS_LOGW("%{public}s: There is no virtual screen for id %{public}" PRIu64, __func__, id);
1313         return SCREEN_NOT_FOUND;
1314     }
1315     return virtualScreen->GetVirtualSecLayerOption();
1316 }
1317 
SetMirrorScreenVisibleRect(ScreenId id,const Rect & mainScreenRect,bool supportRotation)1318 int32_t RSScreenManager::SetMirrorScreenVisibleRect(ScreenId id, const Rect& mainScreenRect, bool supportRotation)
1319 {
1320     if (id == INVALID_SCREEN_ID) {
1321         RS_LOGW("%{public}s: INVALID_SCREEN_ID.", __func__);
1322         return INVALID_ARGUMENTS;
1323     }
1324     auto mainScreen = GetScreen(id);
1325     if (mainScreen == nullptr) {
1326         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1327         return SCREEN_NOT_FOUND;
1328     }
1329 
1330     // zero Rect means disable visible rect
1331     static Rect ZERO = {0, 0, 0, 0};
1332     mainScreen->SetEnableVisibleRect(mainScreenRect != ZERO);
1333     mainScreen->SetMainScreenVisibleRect(mainScreenRect);
1334     mainScreen->SetVisibleRectSupportRotation(supportRotation);
1335     RS_LOGI("%{public}s: mirror screen(id %{public}" PRIu64 "), "
1336         "visible rect[%{public}d, %{public}d, %{public}d, %{public}d], supportRotation: %{public}d",
1337         __func__, id, mainScreenRect.x, mainScreenRect.y, mainScreenRect.w, mainScreenRect.h, supportRotation);
1338     return SUCCESS;
1339 }
1340 
GetMirrorScreenVisibleRect(ScreenId id) const1341 Rect RSScreenManager::GetMirrorScreenVisibleRect(ScreenId id) const
1342 {
1343     auto mirrorScreen = GetScreen(id);
1344     if (mirrorScreen == nullptr) {
1345         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1346         return {};
1347     }
1348 
1349     return mirrorScreen->GetMainScreenVisibleRect();
1350 }
1351 
SetCastScreenEnableSkipWindow(ScreenId id,bool enable)1352 int32_t RSScreenManager::SetCastScreenEnableSkipWindow(ScreenId id, bool enable)
1353 {
1354     auto virtualScreen = GetScreen(id);
1355     if (virtualScreen == nullptr) {
1356         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1357         return SCREEN_NOT_FOUND;
1358     }
1359     virtualScreen->SetCastScreenEnableSkipWindow(enable);
1360     RS_LOGW("%{public}s: screen id %{public}" PRIu64 " set %{public}d success.", __func__, id, enable);
1361     return SUCCESS;
1362 }
1363 
GetVirtualScreenBlackList(ScreenId id) const1364 const std::unordered_set<NodeId> RSScreenManager::GetVirtualScreenBlackList(ScreenId id) const
1365 {
1366     auto virtualScreen = GetScreen(id);
1367     if (virtualScreen == nullptr) {
1368         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1369         return {};
1370     }
1371     std::unordered_set<uint64_t> virtualScreenBlackList = virtualScreen->GetBlackList();
1372     // if the skipWindow flag is enabled, the global blacklist takes effect in addition
1373     if (virtualScreen->GetCastScreenEnableSkipWindow()) {
1374         RS_LOGD("%{public}s: Cast screen blacklists for id %{public}" PRIu64, __func__, id);
1375         std::lock_guard<std::mutex> lock(blackListMutex_);
1376         virtualScreenBlackList.insert(castScreenBlackList_.begin(), castScreenBlackList_.end());
1377     }
1378     RS_LOGD("%{public}s: Record screen blacklists for id %{public}" PRIu64, __func__, id);
1379     return virtualScreenBlackList;
1380 }
1381 
GetVirtualScreenTypeBlackList(ScreenId id) const1382 const std::unordered_set<NodeType> RSScreenManager::GetVirtualScreenTypeBlackList(ScreenId id) const
1383 {
1384     auto virtualScreen = GetScreen(id);
1385     if (virtualScreen == nullptr) {
1386         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1387         return {};
1388     }
1389     if (virtualScreen->GetCastScreenEnableSkipWindow()) {
1390         RS_LOGD("%{public}s: Cast screen typeblacklists for id %{public}" PRIu64, __func__, id);
1391         std::lock_guard<std::mutex> lock(typeBlackListMutex_);
1392         return castScreenTypeBlackList_;
1393     }
1394     RS_LOGD("%{public}s: Record screen typeblacklists for id %{public}" PRIu64, __func__, id);
1395     return virtualScreen->GetTypeBlackList();
1396 }
1397 
GetAllBlackList() const1398 std::unordered_set<uint64_t> RSScreenManager::GetAllBlackList() const
1399 {
1400     std::unordered_set<uint64_t> allBlackList;
1401     std::scoped_lock lock(screenMapMutex_, blackListMutex_);
1402     for (const auto& [_, screen] : screens_) {
1403         if (screen == nullptr) {
1404             continue;
1405         }
1406         if (screen->GetCastScreenEnableSkipWindow()) {
1407             allBlackList.insert(castScreenBlackList_.cbegin(), castScreenBlackList_.cend());
1408         } else {
1409             const auto blackList = screen->GetBlackList();
1410             allBlackList.insert(blackList.cbegin(), blackList.cend());
1411         }
1412     }
1413     return allBlackList;
1414 }
1415 
GetAllWhiteList()1416 std::unordered_set<uint64_t> RSScreenManager::GetAllWhiteList()
1417 {
1418     std::lock_guard<std::mutex> lock(screenMapMutex_);
1419     std::unordered_set<uint64_t> allWhiteList;
1420     for (const auto& [id, screen] : screens_) {
1421         if (screen == nullptr) {
1422             continue;
1423         }
1424         const auto& whiteList = screen->GetWhiteList();
1425         if (!whiteList.empty()) {
1426             allWhiteList.insert(whiteList.begin(), whiteList.end());
1427             std::lock_guard<std::mutex> lock(whiteListMutex_);
1428             screenWhiteList_[id] = whiteList;
1429         }
1430     }
1431     return allWhiteList;
1432 }
1433 
GetScreenWhiteList() const1434 std::unordered_map<ScreenId, std::unordered_set<uint64_t>> RSScreenManager::GetScreenWhiteList() const
1435 {
1436     std::lock_guard<std::mutex> lock(whiteListMutex_);
1437     return screenWhiteList_;
1438 }
1439 
SetVirtualScreenSurface(ScreenId id,sptr<Surface> surface)1440 int32_t RSScreenManager::SetVirtualScreenSurface(ScreenId id, sptr<Surface> surface)
1441 {
1442     if (surface == nullptr) {
1443         RS_LOGW("%{public}s: screenId:%{public}" PRIu64 " surface is null.", __func__, id);
1444         return INVALID_ARGUMENTS;
1445     }
1446     auto screen = GetScreen(id);
1447     if (screen == nullptr) {
1448         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1449         return SCREEN_NOT_FOUND;
1450     }
1451     if (!screen->IsVirtual()) {
1452         RS_LOGW("%{public}s: The screen is not virtual, id %{public}" PRIu64, __func__, id);
1453         return INVALID_ARGUMENTS;
1454     }
1455     uint64_t surfaceId = surface->GetUniqueId();
1456 
1457     auto func = [id, surfaceId](const ScreenNode& node) -> bool {
1458         const auto& [screenId, screen] = node;
1459         return screen && screen->IsVirtual() && screenId != id && screen->GetProducerSurface() &&
1460             screen->GetProducerSurface()->GetUniqueId() == surfaceId;
1461     };
1462     if (AnyScreenFits(func)) {
1463         RS_LOGE("%{public}s: surface %{public}" PRIu64 " is used, set surface failed!", __func__, surfaceId);
1464         return SURFACE_NOT_UNIQUE;
1465     }
1466 
1467     screen->SetProducerSurface(surface);
1468     RS_LOGI("%{public}s: set virtual screen surface success!", __func__);
1469     RS_TRACE_NAME("RSScreenManager::SetVirtualScreenSurface, ForceRefreshOneFrame.");
1470     ForceRefreshOneFrame();
1471     screen->SetPSurfaceChange(true);
1472     return SUCCESS;
1473 }
1474 
1475 // only used in dirtyRegion
CheckPSurfaceChanged(ScreenId id)1476 bool RSScreenManager::CheckPSurfaceChanged(ScreenId id)
1477 {
1478     auto screen = GetScreen(id);
1479     if (screen == nullptr) {
1480         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1481         return false;
1482     }
1483     if (!screen->IsVirtual()) {
1484         return false;
1485     }
1486     return screen->GetAndResetPSurfaceChange();
1487 }
1488 
GetAndResetVirtualSurfaceUpdateFlag(ScreenId id) const1489 bool RSScreenManager::GetAndResetVirtualSurfaceUpdateFlag(ScreenId id) const
1490 {
1491     auto virtualScreen = GetScreen(id);
1492     if (virtualScreen == nullptr) {
1493         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1494         return false;
1495     }
1496     return virtualScreen->GetAndResetVirtualSurfaceUpdateFlag();
1497 }
1498 
RemoveVirtualScreen(ScreenId id)1499 void RSScreenManager::RemoveVirtualScreen(ScreenId id)
1500 {
1501     {
1502         std::lock_guard<std::mutex> lock(screenMapMutex_);
1503         auto iter = screens_.find(id);
1504         if (iter == screens_.end() || iter->second == nullptr) {
1505             RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1506             return;
1507         }
1508         if (!iter->second->IsVirtual()) {
1509             RS_LOGW("%{public}s: The screen is not virtual, id %{public}" PRIu64, __func__, id);
1510             return;
1511         }
1512 
1513         screens_.erase(iter);
1514         --currentVirtualScreenNum_;
1515         RS_LOGI("%{public}s: remove virtual screen(id %{public}" PRIu64 ").", __func__, id);
1516     }
1517     {
1518         std::lock_guard<std::mutex> lock(virtualScreenIdMutex_);
1519         freeVirtualScreenIds_.push(id);
1520     }
1521     NotifyScreenNodeChange(id, false);
1522 
1523     // when virtual screen doesn't exist no more, render control can be recovered.
1524     {
1525         std::lock_guard<std::mutex> lock(renderControlMutex_);
1526         disableRenderControlScreens_.erase(id);
1527     }
1528 }
1529 
GetCurrentVirtualScreenNum()1530 uint32_t RSScreenManager::GetCurrentVirtualScreenNum()
1531 {
1532     return currentVirtualScreenNum_;
1533 }
1534 
SetScreenActiveMode(ScreenId id,uint32_t modeId)1535 uint32_t RSScreenManager::SetScreenActiveMode(ScreenId id, uint32_t modeId)
1536 {
1537     auto screen = GetScreen(id);
1538     if (screen == nullptr) {
1539         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1540         return StatusCode::SCREEN_NOT_FOUND;
1541     }
1542     return screen->SetActiveMode(modeId);
1543 }
1544 
SetScreenActiveRect(ScreenId id,const GraphicIRect & activeRect)1545 uint32_t RSScreenManager::SetScreenActiveRect(ScreenId id, const GraphicIRect& activeRect)
1546 {
1547     auto screen = GetScreen(id);
1548     if (screen == nullptr) {
1549         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1550         return StatusCode::SCREEN_NOT_FOUND;
1551     }
1552 
1553     RSHardwareThread::Instance().ScheduleTask([screen, activeRect, id]() {
1554         if (screen->SetScreenActiveRect(activeRect) != StatusCode::SUCCESS) {
1555             RS_LOGW("%{public}s: Invalid param", __func__);
1556             return;
1557         }
1558 
1559         if (auto output = screen->GetOutput()) {
1560             output->SetActiveRectSwitchStatus(true);
1561         }
1562     }).wait();
1563     return StatusCode::SUCCESS;
1564 }
1565 
SetPhysicalScreenResolution(ScreenId id,uint32_t width,uint32_t height)1566 int32_t RSScreenManager::SetPhysicalScreenResolution(ScreenId id, uint32_t width, uint32_t height)
1567 {
1568     auto screen = GetScreen(id);
1569     if (screen == nullptr) {
1570         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1571         return SCREEN_NOT_FOUND;
1572     }
1573     return screen->SetResolution(width, height);
1574 }
1575 
SetVirtualScreenResolution(ScreenId id,uint32_t width,uint32_t height)1576 int32_t RSScreenManager::SetVirtualScreenResolution(ScreenId id, uint32_t width, uint32_t height)
1577 {
1578     if (width > MAX_VIRTUAL_SCREEN_WIDTH || height > MAX_VIRTUAL_SCREEN_HEIGHT) {
1579         RS_LOGW("%{public}s: width %{public}" PRIu32 " or height %{public}" PRIu32 " has reached "
1580             "the maximum limit!", __func__, width, height);
1581         return INVALID_ARGUMENTS;
1582     }
1583     auto screen = GetScreen(id);
1584     if (screen == nullptr) {
1585         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1586         return SCREEN_NOT_FOUND;
1587     }
1588     screen->SetResolution(width, height);
1589     RS_LOGI("%{public}s: set virtual screen resolution success", __func__);
1590     RS_OPTIONAL_TRACE_NAME("RSScreenManager::SetVirtualScreenResolution, ForceRefreshOneFrame.");
1591     ForceRefreshOneFrame();
1592     return SUCCESS;
1593 }
1594 
SetRogScreenResolution(ScreenId id,uint32_t width,uint32_t height)1595 int32_t RSScreenManager::SetRogScreenResolution(ScreenId id, uint32_t width, uint32_t height)
1596 {
1597     auto screen = GetScreen(id);
1598     if (screen == nullptr) {
1599         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1600         return SCREEN_NOT_FOUND;
1601     }
1602     screen->SetRogResolution(width, height);
1603     return SUCCESS;
1604 }
1605 
ProcessVSyncScreenIdWhilePowerStatusChanged(ScreenId id,ScreenPowerStatus status)1606 void RSScreenManager::ProcessVSyncScreenIdWhilePowerStatusChanged(ScreenId id, ScreenPowerStatus status)
1607 {
1608     auto vsyncSampler = CreateVSyncSampler();
1609     if (vsyncSampler == nullptr) {
1610         RS_LOGE("%{public}s failed, vsyncSampler is null.", __func__);
1611         return;
1612     }
1613     RS_TRACE_NAME_FMT("%s, id:%lu, status:%d, isPowerOff:%d, isSuspend:%d", __func__, id, status,
1614         (status == ScreenPowerStatus::POWER_STATUS_OFF), (status == ScreenPowerStatus::POWER_STATUS_SUSPEND));
1615     if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND) {
1616         vsyncSampler->SetScreenVsyncEnabledInRSMainThread(id, false);
1617     }
1618     if (isFoldScreenFlag_) {
1619         uint64_t vsyncEnabledScreenId = JudgeVSyncEnabledScreenWhilePowerStatusChanged(id, status);
1620         uint64_t lastVsyncEnabledScreenId = vsyncSampler->GetVsyncEnabledScreenId();
1621         if (vsyncEnabledScreenId != lastVsyncEnabledScreenId) {
1622             RS_TRACE_NAME_FMT("vsyncEnabledScreenId has changed, need disable lastVsyncEnabledScreenId vsync, "
1623                 "vsyncEnabledScreenId:%lu, lastVsyncEnabledScreenId:%lu",
1624                 vsyncEnabledScreenId, lastVsyncEnabledScreenId);
1625             vsyncSampler->SetScreenVsyncEnabledInRSMainThread(lastVsyncEnabledScreenId, false);
1626         }
1627         UpdateVsyncEnabledScreenId(vsyncEnabledScreenId);
1628     }
1629 }
1630 
UpdateScreenPowerStatus(ScreenId id,ScreenPowerStatus status)1631 void RSScreenManager::UpdateScreenPowerStatus(ScreenId id, ScreenPowerStatus status)
1632 {
1633     auto screen = GetScreen(id);
1634     if (screen == nullptr) {
1635         RS_LOGW("[UL_POWER] %{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1636         return;
1637     }
1638 
1639     isScreenPoweringOn_ =
1640         (status == ScreenPowerStatus::POWER_STATUS_ON || status == ScreenPowerStatus::POWER_STATUS_ON_ADVANCED);
1641     auto ret = screen->SetPowerStatus(static_cast<uint32_t>(status));
1642     isScreenPoweringOn_ = false;
1643     if (ret != static_cast<int32_t>(StatusCode::SUCCESS)) {
1644         RS_LOGE("[UL_POWER] %{public}s: Failed to set power status of id %{public}" PRIu64, __func__, id);
1645         return;
1646     }
1647 
1648     ProcessVSyncScreenIdWhilePowerStatusChanged(id, status);
1649 
1650     /*
1651      * If app adds the first frame when power on the screen, delete the code
1652      */
1653     if (status == ScreenPowerStatus::POWER_STATUS_ON ||
1654         status == ScreenPowerStatus::POWER_STATUS_ON_ADVANCED) {
1655         RSFirstFrameNotifier::GetInstance().AddFirstFrameCommitScreen(id);
1656         auto mainThread = RSMainThread::Instance();
1657         if (mainThread == nullptr) {
1658             RS_LOGE("[UL_POWER] %{public}s: mainThread is nullptr", __func__);
1659             return;
1660         }
1661         mainThread->PostTask([mainThread]() {
1662             mainThread->SetDirtyFlag();
1663             mainThread->SetScreenPowerOnChanged(true);
1664         });
1665         std::shared_lock<std::shared_mutex> lock(powerStatusMutex_);
1666         if (screenPowerStatus_.count(id) == 0 ||
1667             screenPowerStatus_[id] == ScreenPowerStatus::POWER_STATUS_OFF ||
1668             screenPowerStatus_[id] == ScreenPowerStatus::POWER_STATUS_OFF_FAKE ||
1669             screenPowerStatus_[id] == ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED) {
1670             mainThread->ForceRefreshForUni();
1671         } else {
1672             mainThread->RequestNextVSync();
1673         }
1674 
1675         RS_LOGI("[UL_POWER] %{public}s: PowerStatus %{public}d, request a frame", __func__, status);
1676     }
1677     RSColorTemperature::Get().UpdateScreenStatus(id, status);
1678     std::lock_guard<std::shared_mutex> lock(powerStatusMutex_);
1679     screenPowerStatus_[id] = status;
1680 }
1681 
SetScreenPowerStatus(ScreenId id,ScreenPowerStatus status)1682 void RSScreenManager::SetScreenPowerStatus(ScreenId id, ScreenPowerStatus status)
1683 {
1684     if (!RSSystemProperties::IsSmallFoldDevice()) {
1685         UpdateScreenPowerStatus(id, status);
1686         return;
1687     }
1688 
1689     ResetScreenPowerStatusTask();
1690     RSSwitchingThread::Instance().PostTask([id, status, this]() {
1691         if (status == ScreenPowerStatus::POWER_STATUS_OFF) {
1692             std::lock_guard<std::shared_mutex> lock(powerStatusMutex_);
1693             isScreenPoweringOff_.insert(id);
1694         }
1695 
1696         UpdateScreenPowerStatus(id, status);
1697 
1698         {
1699             std::lock_guard<std::shared_mutex> lock(powerStatusMutex_);
1700             isScreenPoweringOff_.erase(id);
1701         }
1702 
1703         std::unique_lock<std::mutex> taskLock(syncTaskMutex_);
1704         statusTaskEndFlag_ = true;
1705         statusTaskCV_.notify_all();
1706     });
1707 }
1708 
ResetScreenPowerStatusTask()1709 void RSScreenManager::ResetScreenPowerStatusTask()
1710 {
1711     if (!RSSystemProperties::IsSmallFoldDevice()) {
1712         return;
1713     }
1714 
1715     std::unique_lock<std::mutex> taskLock(syncTaskMutex_);
1716     statusTaskEndFlag_ = false;
1717 }
1718 
WaitScreenPowerStatusTask()1719 void RSScreenManager::WaitScreenPowerStatusTask()
1720 {
1721     if (!RSSystemProperties::IsSmallFoldDevice()) {
1722         return;
1723     }
1724 
1725     std::unique_lock<std::mutex> taskLock(syncTaskMutex_);
1726     if (!statusTaskCV_.wait_for(taskLock, std::chrono::milliseconds(WAIT_FOR_STATUS_TASK_TIMEOUT), [this]() {
1727         return statusTaskEndFlag_;
1728     })) {
1729         RS_LOGW("[UL_POWER] %{public}s: wait screen power status task timeout", __func__);
1730     }
1731 }
1732 
IsScreenPoweringOn() const1733 bool RSScreenManager::IsScreenPoweringOn() const
1734 {
1735     return isScreenPoweringOn_;
1736 }
1737 
IsScreenPoweringOff(ScreenId id) const1738 bool RSScreenManager::IsScreenPoweringOff(ScreenId id) const
1739 {
1740     std::shared_lock<std::shared_mutex> lock(powerStatusMutex_);
1741     return isScreenPoweringOff_.count(id) != 0;
1742 }
1743 
SetVirtualMirrorScreenCanvasRotation(ScreenId id,bool canvasRotation)1744 bool RSScreenManager::SetVirtualMirrorScreenCanvasRotation(ScreenId id, bool canvasRotation)
1745 {
1746     auto screen = GetScreen(id);
1747     if (screen == nullptr) {
1748         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1749         return false;
1750     }
1751 
1752     RS_LOGI("%{public}s: canvasRotation: %{public}d", __func__, canvasRotation);
1753     return screen->SetVirtualMirrorScreenCanvasRotation(canvasRotation);
1754 }
1755 
SetVirtualScreenAutoRotation(ScreenId id,bool isAutoRotation)1756 int32_t RSScreenManager::SetVirtualScreenAutoRotation(ScreenId id, bool isAutoRotation)
1757 {
1758     auto screen = GetScreen(id);
1759     if (screen == nullptr) {
1760         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1761         return StatusCode::SCREEN_NOT_FOUND;
1762     }
1763 
1764     RS_LOGI("%{public}s: screenId: %{public}" PRIu64 " isAutoRotation: %{public}d", __func__, id, isAutoRotation);
1765     return screen->SetVirtualScreenAutoRotation(isAutoRotation);
1766 }
1767 
SetVirtualMirrorScreenScaleMode(ScreenId id,ScreenScaleMode scaleMode)1768 bool RSScreenManager::SetVirtualMirrorScreenScaleMode(ScreenId id, ScreenScaleMode scaleMode)
1769 {
1770     auto screen = GetScreen(id);
1771     if (screen == nullptr) {
1772         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1773         return false;
1774     }
1775 
1776     RS_LOGI("%{public}s: scaleMode: %{public}d", __func__, scaleMode);
1777     return screen->SetVirtualMirrorScreenScaleMode(scaleMode);
1778 }
1779 
GetDefaultScreenActiveMode(RSScreenModeInfo & screenModeInfo) const1780 void RSScreenManager::GetDefaultScreenActiveMode(RSScreenModeInfo& screenModeInfo) const
1781 {
1782     GetScreenActiveMode(defaultScreenId_, screenModeInfo);
1783 }
1784 
ReleaseScreenDmaBuffer(ScreenId screenId)1785 void RSScreenManager::ReleaseScreenDmaBuffer(ScreenId screenId)
1786 {
1787 #ifdef RS_ENABLE_GPU
1788     RSHardwareThread::Instance().PostTask([this, screenId]() {
1789         RS_TRACE_NAME("RSScreenManager ReleaseScreenDmaBuffer");
1790         auto output = GetOutput(screenId);
1791         if (output == nullptr) {
1792             RS_LOGE("ReleaseScreenDmaBuffer: HdiOutput is nullptr!");
1793             return;
1794         }
1795         std::vector<LayerInfoPtr> layer;
1796         output->SetLayerInfo(layer);
1797     });
1798 #endif
1799 }
1800 
1801 /* only used for mock tests */
MockHdiScreenConnected(std::shared_ptr<OHOS::Rosen::RSScreen> rsScreen)1802 void RSScreenManager::MockHdiScreenConnected(std::shared_ptr<OHOS::Rosen::RSScreen> rsScreen)
1803 {
1804     if (rsScreen == nullptr) {
1805         return;
1806     }
1807     screens_[rsScreen->Id()] = rsScreen;
1808 }
1809 
GetScreenData(ScreenId id) const1810 RSScreenData RSScreenManager::GetScreenData(ScreenId id) const
1811 {
1812     RSScreenData screenData;
1813     if (GetScreen(id) == nullptr) {
1814         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1815         return screenData;
1816     }
1817     RSScreenCapability capability = GetScreenCapability(id);
1818     RSScreenModeInfo activeMode;
1819     GetScreenActiveMode(id, activeMode);
1820     std::vector<RSScreenModeInfo> supportModes = GetScreenSupportedModes(id);
1821     ScreenPowerStatus powerStatus = GetScreenPowerStatus(id);
1822     screenData.SetCapability(capability);
1823     screenData.SetActivityModeInfo(activeMode);
1824     screenData.SetSupportModeInfo(supportModes);
1825     screenData.SetPowerStatus(powerStatus);
1826     return screenData;
1827 }
1828 
ResizeVirtualScreen(ScreenId id,uint32_t width,uint32_t height)1829 int32_t RSScreenManager::ResizeVirtualScreen(ScreenId id, uint32_t width, uint32_t height)
1830 {
1831     if (width > MAX_VIRTUAL_SCREEN_WIDTH || height > MAX_VIRTUAL_SCREEN_HEIGHT) {
1832         RS_LOGW("%{public}s: width %{public}" PRIu32 " or height %{public}" PRIu32 " has reached"
1833             " the maximum limit!", __func__, width, height);
1834         return INVALID_ARGUMENTS;
1835     }
1836     auto screen = GetScreen(id);
1837     if (screen == nullptr) {
1838         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1839         return SCREEN_NOT_FOUND;
1840     }
1841     screen->ResizeVirtualScreen(width, height);
1842     RS_LOGI("%{public}s: resize virtual screen success, width:%{public}u, height:%{public}u",
1843         __func__, width, height);
1844 
1845     return SUCCESS;
1846 }
1847 
GetScreenBacklight(ScreenId id) const1848 int32_t RSScreenManager::GetScreenBacklight(ScreenId id) const
1849 {
1850     auto screen = GetScreen(id);
1851     if (screen == nullptr) {
1852         RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1853         return INVALID_BACKLIGHT_VALUE;
1854     }
1855     return screen->GetScreenBacklight();
1856 }
1857 
SetScreenBacklight(ScreenId id,uint32_t level)1858 void RSScreenManager::SetScreenBacklight(ScreenId id, uint32_t level)
1859 {
1860     auto screen = GetScreen(id);
1861     if (screen == nullptr) {
1862         RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1863         return;
1864     }
1865     screen->SetScreenBacklight(level);
1866 
1867     std::lock_guard<std::shared_mutex> lock(backLightAndCorrectionMutex_);
1868     if (screenBacklight_[id] == level) {
1869         RS_LOGD("%{public}s: repeat backlight screenId: %{public}" PRIu64 " newLevel: %d", __func__, id, level);
1870         return;
1871     }
1872     screenBacklight_[id] = level;
1873 }
1874 
QueryDefaultScreenInfo() const1875 ScreenInfo RSScreenManager::QueryDefaultScreenInfo() const
1876 {
1877     return QueryScreenInfo(defaultScreenId_);
1878 }
1879 
QueryScreenInfo(ScreenId id) const1880 ScreenInfo RSScreenManager::QueryScreenInfo(ScreenId id) const
1881 {
1882     ScreenInfo info;
1883     auto screen = GetScreen(id);
1884     if (screen == nullptr) {
1885         RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1886         return info;
1887     }
1888 
1889     info.id = id;
1890     info.width = screen->Width();
1891     info.height = screen->Height();
1892     info.phyWidth = screen->PhyWidth() ? screen->PhyWidth() : screen->Width();
1893     info.phyHeight = screen->PhyHeight() ? screen->PhyHeight() : screen->Height();
1894     info.offsetX = screen->GetOffsetX();
1895     info.offsetY = screen->GetOffsetY();
1896     info.isSamplingOn = screen->IsSamplingOn();
1897     info.samplingTranslateX = screen->GetSamplingTranslateX();
1898     info.samplingTranslateY = screen->GetSamplingTranslateY();
1899     info.samplingScale = screen->GetSamplingScale();
1900     auto ret = screen->GetScreenColorGamut(info.colorGamut);
1901     if (ret != StatusCode::SUCCESS) {
1902         info.colorGamut = COLOR_GAMUT_SRGB;
1903     }
1904 
1905     if (!screen->IsEnable()) {
1906         info.state = ScreenState::DISABLED;
1907     } else if (!screen->IsVirtual()) {
1908         info.state = ScreenState::HDI_OUTPUT_ENABLE;
1909     } else {
1910         info.state = ScreenState::SOFTWARE_OUTPUT_ENABLE;
1911     }
1912     info.skipFrameInterval = screen->GetScreenSkipFrameInterval();
1913     info.expectedRefreshRate = screen->GetScreenExpectedRefreshRate();
1914     info.skipFrameStrategy = screen->GetScreenSkipFrameStrategy();
1915     info.isEqualVsyncPeriod = screen->GetEqualVsyncPeriod();
1916     screen->GetPixelFormat(info.pixelFormat);
1917     screen->GetScreenHDRFormat(info.hdrFormat);
1918     info.whiteList = screen->GetWhiteList();
1919     info.enableVisibleRect = screen->GetEnableVisibleRect();
1920     info.activeRect = screen->GetActiveRect();
1921     info.maskRect = screen->GetMaskRect();
1922     info.reviseRect = screen->GetReviseRect();
1923     return info;
1924 }
1925 
GetCanvasRotation(ScreenId id) const1926 bool RSScreenManager::GetCanvasRotation(ScreenId id) const
1927 {
1928     auto screen = GetScreen(id);
1929     if (screen == nullptr) {
1930         RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1931         return false;
1932     }
1933     return screen->GetCanvasRotation();
1934 }
1935 
GetVirtualScreenAutoRotation(ScreenId id) const1936 bool RSScreenManager::GetVirtualScreenAutoRotation(ScreenId id) const
1937 {
1938     auto screen = GetScreen(id);
1939     if (screen == nullptr) {
1940         RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1941         return false;
1942     }
1943     return screen->GetVirtualScreenAutoRotation();
1944 }
1945 
GetScaleMode(ScreenId id) const1946 ScreenScaleMode RSScreenManager::GetScaleMode(ScreenId id) const
1947 {
1948     auto screen = GetScreen(id);
1949     if (screen == nullptr) {
1950         RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1951         return ScreenScaleMode::INVALID_MODE;
1952     }
1953     auto scaleModeDFX = static_cast<ScreenScaleMode>(
1954         RSSystemProperties::GetVirtualScreenScaleModeDFX());
1955     // Support mode can be configured for maintenance and testing before
1956     // upper layer application adaptation
1957     return (scaleModeDFX == ScreenScaleMode::INVALID_MODE) ? screen->GetScaleMode() : scaleModeDFX;
1958 }
1959 
GetProducerSurface(ScreenId id) const1960 sptr<Surface> RSScreenManager::GetProducerSurface(ScreenId id) const
1961 {
1962     auto screen = GetScreen(id);
1963     if (screen == nullptr) {
1964         RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1965         return nullptr;
1966     }
1967     return screen->GetProducerSurface();
1968 }
1969 
GetOutput(ScreenId id) const1970 std::shared_ptr<HdiOutput> RSScreenManager::GetOutput(ScreenId id) const
1971 {
1972     auto screen = GetScreen(id);
1973     if (screen == nullptr) {
1974         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1975         return nullptr;
1976     }
1977     return screen->GetOutput();
1978 }
1979 
AddScreenChangeCallback(const sptr<RSIScreenChangeCallback> & callback)1980 int32_t RSScreenManager::AddScreenChangeCallback(const sptr<RSIScreenChangeCallback>& callback)
1981 {
1982     if (callback == nullptr) {
1983         RS_LOGE("%{public}s: callback is NULL.", __func__);
1984         return INVALID_ARGUMENTS;
1985     }
1986 
1987     {
1988         std::lock_guard<std::mutex> lock(screenMapMutex_);
1989         // when the callback first registered, maybe there were some physical screens already connected,
1990         // so notify to remote immediately.
1991         for (const auto& [id, screen] : screens_) {
1992             if (screen == nullptr) {
1993                 RS_LOGW("%{public}s: screen %{public}" PRIu64 " not found", __func__, id);
1994                 continue;
1995             }
1996             if (!screen->IsVirtual()) {
1997                 callback->OnScreenChanged(id, ScreenEvent::CONNECTED);
1998             }
1999         }
2000     }
2001 
2002     std::lock_guard<std::shared_mutex> lock(screenChangeCallbackMutex_);
2003     screenChangeCallbacks_.push_back(callback);
2004     RS_LOGI("%{public}s: add a remote callback succeed.", __func__);
2005     return SUCCESS;
2006 }
2007 
RemoveScreenChangeCallback(const sptr<RSIScreenChangeCallback> & callback)2008 void RSScreenManager::RemoveScreenChangeCallback(const sptr<RSIScreenChangeCallback>& callback)
2009 {
2010     std::lock_guard<std::shared_mutex> lock(screenChangeCallbackMutex_);
2011     auto iter = std::find(screenChangeCallbacks_.cbegin(), screenChangeCallbacks_.cend(), callback);
2012     if (iter == screenChangeCallbacks_.cend()) {
2013         RS_LOGW("%{public}s: The remote callback is not in screenChangeCallbacks_", __func__);
2014         return;
2015     }
2016     screenChangeCallbacks_.erase(iter);
2017     RS_LOGI("%{public}s: remove a remote callback succeed.", __func__);
2018 }
2019 
SetScreenSwitchingNotifyCallback(const sptr<RSIScreenSwitchingNotifyCallback> & callback)2020 int32_t RSScreenManager::SetScreenSwitchingNotifyCallback(const sptr<RSIScreenSwitchingNotifyCallback>& callback)
2021 {
2022     std::lock_guard<std::shared_mutex> lock(screenSwitchingNotifyCallbackMutex_);
2023     screenSwitchingNotifyCallback_ = callback;
2024     RS_LOGI("%{public}s: set screen switching notify callback succeed.", __func__);
2025     return SUCCESS;
2026 }
2027 
RegisterScreenNodeListener(std::shared_ptr<RSIScreenNodeListener> listener)2028 void RSScreenManager::RegisterScreenNodeListener(std::shared_ptr<RSIScreenNodeListener> listener)
2029 {
2030     if (listener == nullptr) {
2031         RS_LOGE("%{public}s: callback is null", __func__);
2032         return;
2033     }
2034 
2035     {
2036         std::lock_guard<std::mutex> lock(screenMapMutex_);
2037         for (const auto& [id, screen] : screens_) {
2038             if (screen == nullptr) {
2039                 RS_LOGW("%{public}s: screen %{public}" PRIu64 " not found", __func__, id);
2040                 continue;
2041             }
2042             listener->OnScreenConnect(id);
2043         }
2044     }
2045 
2046     std::lock_guard<std::shared_mutex> lock(screenChangeCallbackMutex_);
2047     screenNodeListener_ = listener;
2048 }
2049 
DisplayDump(std::string & dumpString)2050 void RSScreenManager::DisplayDump(std::string& dumpString)
2051 {
2052     std::lock_guard<std::mutex> lock(screenMapMutex_);
2053     int32_t index = 0;
2054     for (const auto& [id, screen] : screens_) {
2055         if (screen == nullptr) {
2056             RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2057             continue;
2058         }
2059         screen->DisplayDump(index, dumpString);
2060         index++;
2061     }
2062     if (isFoldScreenFlag_) {
2063         dumpString += "===================\n";
2064         dumpString += "foldScreenIds_ size is " + std::to_string(foldScreenIds_.size()) + "\n";
2065         for (auto& [screenId, status] : foldScreenIds_) {
2066             dumpString += "foldScreenId:" + std::to_string(screenId) +
2067                 ", isConnected:" + std::to_string(status.isConnected) +
2068                 ", isPowerOn:" + std::to_string(status.isPowerOn) + "\n";
2069         }
2070     }
2071 }
2072 
SurfaceDump(std::string & dumpString)2073 void RSScreenManager::SurfaceDump(std::string& dumpString)
2074 {
2075     std::lock_guard<std::mutex> lock(screenMapMutex_);
2076     int32_t index = 0;
2077     for (const auto& [id, screen] : screens_) {
2078         if (screen == nullptr) {
2079             RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2080             continue;
2081         }
2082         screen->SurfaceDump(index, dumpString);
2083         index++;
2084     }
2085 }
2086 
DumpCurrentFrameLayers()2087 void RSScreenManager::DumpCurrentFrameLayers()
2088 {
2089     std::lock_guard<std::mutex> lock(screenMapMutex_);
2090     for (const auto &[id, screen] : screens_) {
2091         if (screen == nullptr) {
2092             RS_LOGE("RSScreenManager %{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2093             continue;
2094         }
2095         screen->DumpCurrentFrameLayers();
2096     }
2097 }
2098 
FpsDump(std::string & dumpString,std::string & arg)2099 void RSScreenManager::FpsDump(std::string& dumpString, std::string& arg)
2100 {
2101     std::lock_guard<std::mutex> lock(screenMapMutex_);
2102     int32_t index = 0;
2103     dumpString += "\n-- The recently fps records info of screens:\n";
2104     for (const auto& [id, screen] : screens_) {
2105         if (screen == nullptr) {
2106             RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2107             continue;
2108         }
2109         screen->FpsDump(index, dumpString, arg);
2110         index++;
2111     }
2112 }
2113 
ClearFpsDump(std::string & dumpString,std::string & arg)2114 void RSScreenManager::ClearFpsDump(std::string& dumpString, std::string& arg)
2115 {
2116     std::lock_guard<std::mutex> lock(screenMapMutex_);
2117     int32_t index = 0;
2118     dumpString += "\n-- Clear fps records info of screens:\n";
2119     for (const auto& [id, screen] : screens_) {
2120         if (screen == nullptr) {
2121             RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2122             continue;
2123         }
2124         screen->ClearFpsDump(index, dumpString, arg);
2125         index++;
2126     }
2127 }
2128 
ClearFrameBufferIfNeed()2129 void RSScreenManager::ClearFrameBufferIfNeed()
2130 {
2131 #ifdef RS_ENABLE_GPU
2132     RSHardwareThread::Instance().PostTask([this]() {
2133         std::lock_guard<std::mutex> lock(screenMapMutex_);
2134         for (const auto& [id, screen] : screens_) {
2135             if (!screen || !screen->GetOutput()) {
2136                 RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2137                 continue;
2138             }
2139             if (screen->GetHasProtectedLayer()) {
2140                 RS_TRACE_NAME_FMT("screen Id:%lu has protected layer.", id);
2141                 continue;
2142             }
2143             if (screen->GetOutput()->GetBufferCacheSize() > 0) {
2144                 RS_LOGI("%{public}s: screen %{public}" PRIu64 " ClearFrameBuffers.", __func__, id);
2145                 RSHardwareThread::Instance().ClearFrameBuffers(screen->GetOutput());
2146             }
2147         }
2148     });
2149 #endif
2150 }
2151 
SetScreenConstraint(ScreenId id,uint64_t timestamp,ScreenConstraintType type)2152 int32_t RSScreenManager::SetScreenConstraint(ScreenId id, uint64_t timestamp, ScreenConstraintType type)
2153 {
2154     frameId_++;
2155     auto screen = GetScreen(id);
2156     if (screen == nullptr) {
2157         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2158         return StatusCode::SCREEN_NOT_FOUND;
2159     }
2160     RS_TRACE_NAME_FMT("SetScreenConstraint frameId:%lu timestamp:%lu type:%d", frameId_, timestamp, type);
2161     return screen->SetScreenConstraint(frameId_, timestamp, type);
2162 }
2163 
HitchsDump(std::string & dumpString,std::string & arg)2164 void RSScreenManager::HitchsDump(std::string& dumpString, std::string& arg)
2165 {
2166     std::lock_guard<std::mutex> lock(screenMapMutex_);
2167     int32_t index = 0;
2168     dumpString += "\n-- The recently window hitchs records info of screens:\n";
2169     for (const auto& [id, screen] : screens_) {
2170         if (screen == nullptr) {
2171             RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2172             continue;
2173         }
2174         screen->HitchsDump(index, dumpString, arg);
2175         index++;
2176     }
2177 }
2178 
GetScreenSupportedColorGamuts(ScreenId id,std::vector<ScreenColorGamut> & mode) const2179 int32_t RSScreenManager::GetScreenSupportedColorGamuts(ScreenId id, std::vector<ScreenColorGamut>& mode) const
2180 {
2181     auto screen = GetScreen(id);
2182     if (screen == nullptr) {
2183         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2184         return StatusCode::SCREEN_NOT_FOUND;
2185     }
2186     return screen->GetScreenSupportedColorGamuts(mode);
2187 }
2188 
GetScreenSupportedMetaDataKeys(ScreenId id,std::vector<ScreenHDRMetadataKey> & keys) const2189 int32_t RSScreenManager::GetScreenSupportedMetaDataKeys(ScreenId id, std::vector<ScreenHDRMetadataKey>& keys) const
2190 {
2191     auto screen = GetScreen(id);
2192     if (screen == nullptr) {
2193         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2194         return StatusCode::SCREEN_NOT_FOUND;
2195     }
2196     return screen->GetScreenSupportedMetaDataKeys(keys);
2197 }
2198 
GetScreenColorGamut(ScreenId id,ScreenColorGamut & mode) const2199 int32_t RSScreenManager::GetScreenColorGamut(ScreenId id, ScreenColorGamut& mode) const
2200 {
2201     auto screen = GetScreen(id);
2202     if (screen == nullptr) {
2203         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2204         return StatusCode::SCREEN_NOT_FOUND;
2205     }
2206     return screen->GetScreenColorGamut(mode);
2207 }
2208 
SetScreenColorGamut(ScreenId id,int32_t modeIdx)2209 int32_t RSScreenManager::SetScreenColorGamut(ScreenId id, int32_t modeIdx)
2210 {
2211     auto screen = GetScreen(id);
2212     if (screen == nullptr) {
2213         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2214         return StatusCode::SCREEN_NOT_FOUND;
2215     }
2216     return screen->SetScreenColorGamut(modeIdx);
2217 }
2218 
SetScreenGamutMap(ScreenId id,ScreenGamutMap mode)2219 int32_t RSScreenManager::SetScreenGamutMap(ScreenId id, ScreenGamutMap mode)
2220 {
2221     auto screen = GetScreen(id);
2222     if (screen == nullptr) {
2223         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2224         return StatusCode::SCREEN_NOT_FOUND;
2225     }
2226     RS_OPTIONAL_TRACE_NAME("RSScreenManager::SetScreenGamutMapLocked, ForceRefreshOneFrame.");
2227     ForceRefreshOneFrame();
2228     return screen->SetScreenGamutMap(mode);
2229 }
2230 
SetScreenCorrection(ScreenId id,ScreenRotation screenRotation)2231 int32_t RSScreenManager::SetScreenCorrection(ScreenId id, ScreenRotation screenRotation)
2232 {
2233     auto screen = GetScreen(id);
2234     if (screen == nullptr) {
2235         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2236         return StatusCode::SCREEN_NOT_FOUND;
2237     }
2238     screen->SetScreenCorrection(screenRotation);
2239 
2240     std::lock_guard<std::shared_mutex> lock(backLightAndCorrectionMutex_);
2241     screenCorrection_[id] = screenRotation;
2242     return StatusCode::SUCCESS;
2243 }
2244 
GetScreenGamutMap(ScreenId id,ScreenGamutMap & mode) const2245 int32_t RSScreenManager::GetScreenGamutMap(ScreenId id, ScreenGamutMap& mode) const
2246 {
2247     auto screen = GetScreen(id);
2248     if (screen == nullptr) {
2249         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2250         return StatusCode::SCREEN_NOT_FOUND;
2251     }
2252     return screen->GetScreenGamutMap(mode);
2253 }
2254 
GetScreenHDRCapability(ScreenId id,RSScreenHDRCapability & screenHdrCapability) const2255 int32_t RSScreenManager::GetScreenHDRCapability(ScreenId id, RSScreenHDRCapability& screenHdrCapability) const
2256 {
2257     auto screen = GetScreen(id);
2258     if (screen == nullptr) {
2259         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2260         return StatusCode::SCREEN_NOT_FOUND;
2261     }
2262 
2263     GraphicHDRCapability hdrCapability = screen->GetHDRCapability();
2264     std::vector<ScreenHDRFormat> hdrFormats(hdrCapability.formats.size());
2265     std::transform(hdrCapability.formats.cbegin(), hdrCapability.formats.cend(), hdrFormats.begin(),
2266         [](const auto& node) { return static_cast<ScreenHDRFormat>(node); }
2267     );
2268 
2269     screenHdrCapability.SetMaxLum(hdrCapability.maxLum);
2270     screenHdrCapability.SetMaxAverageLum(hdrCapability.maxAverageLum);
2271     screenHdrCapability.SetMinLum(hdrCapability.minLum);
2272     screenHdrCapability.SetHdrFormats(std::move(hdrFormats));
2273     return StatusCode::SUCCESS;
2274 }
2275 
GetScreenType(ScreenId id,RSScreenType & type) const2276 int32_t RSScreenManager::GetScreenType(ScreenId id, RSScreenType& type) const
2277 {
2278     auto screen = GetScreen(id);
2279     if (screen == nullptr) {
2280         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2281         return StatusCode::SCREEN_NOT_FOUND;
2282     }
2283 
2284     type = screen->GetScreenType();
2285     return StatusCode::SUCCESS;
2286 }
2287 
SetScreenSkipFrameInterval(ScreenId id,uint32_t skipFrameInterval)2288 int32_t RSScreenManager::SetScreenSkipFrameInterval(ScreenId id, uint32_t skipFrameInterval)
2289 {
2290     auto screen = GetScreen(id);
2291     if (screen == nullptr) {
2292         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2293         return StatusCode::SCREEN_NOT_FOUND;
2294     }
2295     RSScreenModeInfo screenModeInfo;
2296     // use the refresh rate of the physical screen as the maximum refresh rate
2297     GetDefaultScreenActiveMode(screenModeInfo);
2298     // guaranteed screen refresh rate at least 1
2299     if (skipFrameInterval == 0 || (skipFrameInterval > screenModeInfo.GetScreenRefreshRate())) {
2300         RS_LOGE("%{public}s: screen %{public}" PRIu64 " is INVALID_ARGUMENTS.", __func__, id);
2301         return INVALID_ARGUMENTS;
2302     }
2303     screen->SetScreenSkipFrameInterval(skipFrameInterval);
2304     screen->SetEqualVsyncPeriod(skipFrameInterval == 1);
2305     RS_LOGI("%{public}s: screen(id %{public}" PRIu64 "), skipFrameInterval(%{public}d).",
2306         __func__, id, skipFrameInterval);
2307     return StatusCode::SUCCESS;
2308 }
2309 
SetVirtualScreenRefreshRate(ScreenId id,uint32_t maxRefreshRate,uint32_t & actualRefreshRate)2310 int32_t RSScreenManager::SetVirtualScreenRefreshRate(ScreenId id, uint32_t maxRefreshRate, uint32_t& actualRefreshRate)
2311 {
2312     auto screen = GetScreen(id);
2313     if (screen == nullptr) {
2314         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2315         return StatusCode::SCREEN_NOT_FOUND;
2316     }
2317     if (!screen->IsVirtual()) {
2318         RS_LOGW("%{public}s: Not Support for screen:%{public}" PRIu64, __func__, id);
2319         return StatusCode::SCREEN_NOT_FOUND;
2320     }
2321     if (maxRefreshRate == 0) {
2322         RS_LOGW("%{public}s: Invalid maxRefreshRate:%{public}u.", __func__, maxRefreshRate);
2323         return StatusCode::INVALID_ARGUMENTS;
2324     }
2325     if (maxRefreshRate > MAX_VIRTUAL_SCREEN_REFRESH_RATE) {
2326         maxRefreshRate = MAX_VIRTUAL_SCREEN_REFRESH_RATE;
2327     }
2328     screen->SetScreenExpectedRefreshRate(maxRefreshRate);
2329     RS_LOGI("%{public}s: screen(id %{public}" PRIu64 "), maxRefreshRate(%{public}d).",
2330         __func__, id, maxRefreshRate);
2331     actualRefreshRate = maxRefreshRate;
2332     return StatusCode::SUCCESS;
2333 }
2334 
SetEqualVsyncPeriod(ScreenId id,bool isEqualVsyncPeriod)2335 void RSScreenManager::SetEqualVsyncPeriod(ScreenId id, bool isEqualVsyncPeriod)
2336 {
2337     auto screen = GetScreen(id);
2338     if (screen == nullptr) {
2339         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2340         return;
2341     }
2342     screen->SetEqualVsyncPeriod(isEqualVsyncPeriod);
2343     return;
2344 }
2345 
GetDisplayIdentificationData(ScreenId id,uint8_t & outPort,std::vector<uint8_t> & edidData) const2346 int32_t RSScreenManager::GetDisplayIdentificationData(ScreenId id, uint8_t& outPort,
2347     std::vector<uint8_t>& edidData) const
2348 {
2349     auto screen = GetScreen(id);
2350     if (screen == nullptr) {
2351         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2352         return SCREEN_NOT_FOUND;
2353     }
2354 
2355     return screen->GetDisplayIdentificationData(outPort, edidData);
2356 }
2357 
GetPixelFormat(ScreenId id,GraphicPixelFormat & pixelFormat) const2358 int32_t RSScreenManager::GetPixelFormat(ScreenId id, GraphicPixelFormat& pixelFormat) const
2359 {
2360     auto screen = GetScreen(id);
2361     if (screen == nullptr) {
2362         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2363         return StatusCode::SCREEN_NOT_FOUND;
2364     }
2365     return screen->GetPixelFormat(pixelFormat);
2366 }
2367 
SetPixelFormat(ScreenId id,GraphicPixelFormat pixelFormat)2368 int32_t RSScreenManager::SetPixelFormat(ScreenId id, GraphicPixelFormat pixelFormat)
2369 {
2370     auto screen = GetScreen(id);
2371     if (screen == nullptr) {
2372         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2373         return StatusCode::SCREEN_NOT_FOUND;
2374     }
2375     return screen->SetPixelFormat(pixelFormat);
2376 }
2377 
GetScreenSupportedHDRFormats(ScreenId id,std::vector<ScreenHDRFormat> & hdrFormats) const2378 int32_t RSScreenManager::GetScreenSupportedHDRFormats(ScreenId id, std::vector<ScreenHDRFormat>& hdrFormats) const
2379 {
2380     auto screen = GetScreen(id);
2381     if (screen == nullptr) {
2382         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2383         return StatusCode::SCREEN_NOT_FOUND;
2384     }
2385     return screen->GetScreenSupportedHDRFormats(hdrFormats);
2386 }
2387 
GetScreenHDRFormat(ScreenId id,ScreenHDRFormat & hdrFormat) const2388 int32_t RSScreenManager::GetScreenHDRFormat(ScreenId id, ScreenHDRFormat& hdrFormat) const
2389 {
2390     auto screen = GetScreen(id);
2391     if (screen == nullptr) {
2392         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2393         return StatusCode::SCREEN_NOT_FOUND;
2394     }
2395     return screen->GetScreenHDRFormat(hdrFormat);
2396 }
2397 
SetScreenHDRFormat(ScreenId id,int32_t modeIdx)2398 int32_t RSScreenManager::SetScreenHDRFormat(ScreenId id, int32_t modeIdx)
2399 {
2400     auto screen = GetScreen(id);
2401     if (screen == nullptr) {
2402         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2403         return StatusCode::SCREEN_NOT_FOUND;
2404     }
2405     return screen->SetScreenHDRFormat(modeIdx);
2406 }
2407 
GetScreenSupportedColorSpaces(ScreenId id,std::vector<GraphicCM_ColorSpaceType> & colorSpaces) const2408 int32_t RSScreenManager::GetScreenSupportedColorSpaces(
2409     ScreenId id, std::vector<GraphicCM_ColorSpaceType>& colorSpaces) const
2410 {
2411     auto screen = GetScreen(id);
2412     if (screen == nullptr) {
2413         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2414         return StatusCode::SCREEN_NOT_FOUND;
2415     }
2416     return screen->GetScreenSupportedColorSpaces(colorSpaces);
2417 }
2418 
GetScreenColorSpace(ScreenId id,GraphicCM_ColorSpaceType & colorSpace) const2419 int32_t RSScreenManager::GetScreenColorSpace(ScreenId id, GraphicCM_ColorSpaceType& colorSpace) const
2420 {
2421     auto screen = GetScreen(id);
2422     if (screen == nullptr) {
2423         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2424         return StatusCode::SCREEN_NOT_FOUND;
2425     }
2426     return screen->GetScreenColorSpace(colorSpace);
2427 }
2428 
SetScreenColorSpace(ScreenId id,GraphicCM_ColorSpaceType colorSpace)2429 int32_t RSScreenManager::SetScreenColorSpace(ScreenId id, GraphicCM_ColorSpaceType colorSpace)
2430 {
2431     auto screen = GetScreen(id);
2432     if (screen == nullptr) {
2433         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2434         return StatusCode::SCREEN_NOT_FOUND;
2435     }
2436     return screen->SetScreenColorSpace(colorSpace);
2437 }
2438 
GetActualScreenMaxResolution() const2439 ScreenInfo RSScreenManager::GetActualScreenMaxResolution() const
2440 {
2441     ScreenId maxScreenId = INVALID_SCREEN_ID;
2442     {
2443         std::lock_guard<std::mutex> lock(screenMapMutex_);
2444         uint32_t maxResolution = 0;
2445         for (const auto& [id, screen] : screens_) {
2446             if (!screen || screen->IsVirtual()) {
2447                 RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2448                 continue;
2449             }
2450             uint32_t resolution = screen->PhyWidth() * screen->PhyHeight();
2451             if (resolution > maxResolution) {
2452                 maxScreenId = id;
2453                 maxResolution = resolution;
2454             }
2455         }
2456     }
2457 
2458     return QueryScreenInfo(maxScreenId);
2459 }
2460 
MarkPowerOffNeedProcessOneFrame()2461 void RSScreenManager::MarkPowerOffNeedProcessOneFrame()
2462 {
2463     powerOffNeedProcessOneFrame_ = true;
2464 }
2465 
ResetPowerOffNeedProcessOneFrame()2466 void RSScreenManager::ResetPowerOffNeedProcessOneFrame()
2467 {
2468     powerOffNeedProcessOneFrame_ = false;
2469 }
2470 
GetPowerOffNeedProcessOneFrame() const2471 bool RSScreenManager::GetPowerOffNeedProcessOneFrame() const
2472 {
2473     return powerOffNeedProcessOneFrame_;
2474 }
2475 
IsScreenPowerOff(ScreenId id) const2476 bool RSScreenManager::IsScreenPowerOff(ScreenId id) const
2477 {
2478     std::shared_lock<std::shared_mutex> lock(powerStatusMutex_);
2479     if (screenPowerStatus_.count(id) == 0) {
2480         RS_LOGD("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2481         return false;
2482     }
2483     return screenPowerStatus_.at(id) == GraphicDispPowerStatus::GRAPHIC_POWER_STATUS_SUSPEND ||
2484         screenPowerStatus_.at(id) == GraphicDispPowerStatus::GRAPHIC_POWER_STATUS_OFF;
2485 }
2486 
DisablePowerOffRenderControl(ScreenId id)2487 void RSScreenManager::DisablePowerOffRenderControl(ScreenId id)
2488 {
2489     auto screen = GetScreen(id);
2490     if (screen == nullptr) {
2491         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2492         return;
2493     }
2494     std::lock_guard<std::mutex> lock(renderControlMutex_);
2495     RS_LOGI("%{public}s: Add Screen_%{public}" PRIu64 " for disable power-off render control.", __func__, id);
2496     disableRenderControlScreens_.insert(id);
2497 }
2498 
GetDisableRenderControlScreensCount() const2499 int RSScreenManager::GetDisableRenderControlScreensCount() const
2500 {
2501     std::lock_guard<std::mutex> lock(renderControlMutex_);
2502     return disableRenderControlScreens_.size();
2503 }
2504 
SetVirtualScreenStatus(ScreenId id,VirtualScreenStatus screenStatus)2505 bool RSScreenManager::SetVirtualScreenStatus(ScreenId id, VirtualScreenStatus screenStatus)
2506 {
2507     auto screen = GetScreen(id);
2508     if (screen == nullptr) {
2509         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2510         return false;
2511     }
2512     RS_LOGW("%{public}s: id %{public}" PRIu64 " status:%{public}d", __func__, id, screenStatus);
2513     return screen->SetVirtualScreenStatus(screenStatus);
2514 }
2515 
GetVirtualScreenStatus(ScreenId id) const2516 VirtualScreenStatus RSScreenManager::GetVirtualScreenStatus(ScreenId id) const
2517 {
2518     auto screen = GetScreen(id);
2519     if (screen == nullptr) {
2520         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2521         return VirtualScreenStatus::VIRTUAL_SCREEN_INVALID_STATUS;
2522     }
2523     return screen->GetVirtualScreenStatus();
2524 }
2525 
GetDisplayPropertyForHardCursor(uint32_t screenId)2526 bool RSScreenManager::GetDisplayPropertyForHardCursor(uint32_t screenId)
2527 {
2528     auto screen = GetScreen(screenId);
2529     if (screen == nullptr) {
2530         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu32, __func__, screenId);
2531         return false;
2532     }
2533     return screen->GetDisplayPropertyForHardCursor();
2534 }
2535 
SetScreenHasProtectedLayer(ScreenId id,bool hasProtectedLayer)2536 void RSScreenManager::SetScreenHasProtectedLayer(ScreenId id, bool hasProtectedLayer)
2537 {
2538     auto screen = GetScreen(id);
2539     if (screen == nullptr) {
2540         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2541         return;
2542     }
2543     screen->SetHasProtectedLayer(hasProtectedLayer);
2544 }
2545 
SetScreenSwitchStatus(bool flag)2546 void RSScreenManager::SetScreenSwitchStatus(bool flag)
2547 {
2548     RS_LOGI("%{public}s: set isScreenSwitching_ = %{public}d", __func__, flag);
2549     isScreenSwitching_ = flag;
2550     if (!flag) {
2551         NotifySwitchingCallback(flag);
2552     }
2553 }
2554 
IsScreenSwitching() const2555 bool RSScreenManager::IsScreenSwitching() const
2556 {
2557     return isScreenSwitching_;
2558 }
2559 
SetScreenLinearMatrix(ScreenId id,const std::vector<float> & matrix)2560 int32_t RSScreenManager::SetScreenLinearMatrix(ScreenId id, const std::vector<float>& matrix)
2561 {
2562     auto task = [this, id, matrix]() -> void {
2563         auto screen = GetScreen(id);
2564         if (screen == nullptr) {
2565             RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2566             return;
2567         }
2568         screen->SetScreenLinearMatrix(matrix);
2569     };
2570     // SetScreenLinearMatrix is SMQ API, which can only be executed in RSHardwareThread.
2571     RSHardwareThread::Instance().PostTask(task);
2572     return StatusCode::SUCCESS;
2573 }
2574 
IsVisibleRectSupportRotation(ScreenId id)2575 bool RSScreenManager::IsVisibleRectSupportRotation(ScreenId id)
2576 {
2577     auto screen = GetScreen(id);
2578     if (screen == nullptr) {
2579         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2580         return false;
2581     }
2582 
2583     return screen->GetVisibleRectSupportRotation();
2584 }
2585 
SetScreenOffset(ScreenId id,int32_t offsetX,int32_t offsetY)2586 void RSScreenManager::SetScreenOffset(ScreenId id, int32_t offsetX, int32_t offsetY)
2587 {
2588     auto screen = GetScreen(id);
2589     if (screen == nullptr) {
2590         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2591         return;
2592     }
2593     screen->SetScreenOffset(offsetX, offsetY);
2594 }
2595 
AnyScreenFits(std::function<bool (const ScreenNode &)> func) const2596 bool RSScreenManager::AnyScreenFits(std::function<bool(const ScreenNode&)> func) const
2597 {
2598     std::lock_guard<std::mutex> lock(screenMapMutex_);
2599     return std::any_of(screens_.cbegin(), screens_.cend(), func);
2600 }
2601 
TriggerCallbacks(ScreenId id,ScreenEvent event,ScreenChangeReason reason) const2602 void RSScreenManager::TriggerCallbacks(ScreenId id, ScreenEvent event, ScreenChangeReason reason) const
2603 {
2604     std::shared_lock<std::shared_mutex> lock(screenChangeCallbackMutex_);
2605     RS_LOGI("%{public}s: id %{public}" PRIu64
2606             "event %{public}u reason %{public}u screenChangeCallbacks_.size() %{public}zu",
2607             __func__, id, static_cast<uint8_t>(event), static_cast<uint8_t>(reason), screenChangeCallbacks_.size());
2608     for (const auto& cb : screenChangeCallbacks_) {
2609         cb->OnScreenChanged(id, event, reason);
2610     }
2611 }
2612 
NotifyScreenNodeChange(ScreenId id,bool connected) const2613 void RSScreenManager::NotifyScreenNodeChange(ScreenId id, bool connected) const
2614 {
2615     std::shared_lock<std::shared_mutex> lock(screenChangeCallbackMutex_);
2616     if (screenNodeListener_ == nullptr) {
2617         RS_LOGE("%{public}s: screenNodeListener_ is nullptr!", __func__);
2618         return;
2619     }
2620 
2621     if (connected) {
2622         screenNodeListener_->OnScreenConnect(id);
2623     } else {
2624         screenNodeListener_->OnScreenDisconnect(id);
2625     }
2626 }
2627 
NotifySwitchingCallback(bool status) const2628 void RSScreenManager::NotifySwitchingCallback(bool status) const
2629 {
2630     std::shared_lock<std::shared_mutex> lock(screenSwitchingNotifyCallbackMutex_);
2631     if (screenSwitchingNotifyCallback_ == nullptr) {
2632         RS_LOGE("%{public}s: screenSwitchingNotifyCallback_ is nullptr! status: %{public}d", __func__, status);
2633         return;
2634     }
2635 
2636     RS_LOGI("%{public}s: status: %{public}d", __func__, status);
2637     screenSwitchingNotifyCallback_->OnScreenSwitchingNotify(status);
2638 }
2639 
GetScreen(ScreenId id) const2640 std::shared_ptr<OHOS::Rosen::RSScreen> RSScreenManager::GetScreen(ScreenId id) const
2641 {
2642     std::lock_guard<std::mutex> lock(screenMapMutex_);
2643     auto iter = screens_.find(id);
2644     if (iter == screens_.end() || iter->second == nullptr) {
2645         return nullptr;
2646     }
2647     return iter->second;
2648 }
2649 } // namespace impl
2650 
CreateOrGetScreenManager()2651 sptr<RSScreenManager> CreateOrGetScreenManager()
2652 {
2653     return impl::RSScreenManager::GetInstance();
2654 }
2655 } // namespace Rosen
2656 } // namespace OHOS
2657